]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.1.9-2.6.18.patch
- spaces->tab
[packages/kernel.git] / grsecurity-2.1.9-2.6.18.patch
1 diff -urNp linux-2.6.18/arch/alpha/kernel/module.c linux-2.6.18/arch/alpha/kernel/module.c
2 --- linux-2.6.18/arch/alpha/kernel/module.c     2006-09-19 23:42:06.000000000 -0400
3 +++ linux-2.6.18/arch/alpha/kernel/module.c     2006-09-22 20:45:03.000000000 -0400
4 @@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, 
5  
6         /* The small sections were sorted to the end of the segment.
7            The following should definitely cover them.  */
8 -       gp = (u64)me->module_core + me->core_size - 0x8000;
9 +       gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
10         got = sechdrs[me->arch.gotsecindex].sh_addr;
11  
12         for (i = 0; i < n; i++) {
13 diff -urNp linux-2.6.18/arch/alpha/kernel/osf_sys.c linux-2.6.18/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.18/arch/alpha/kernel/osf_sys.c    2006-09-19 23:42:06.000000000 -0400
15 +++ linux-2.6.18/arch/alpha/kernel/osf_sys.c    2006-09-22 20:45:03.000000000 -0400
16 @@ -1273,6 +1273,10 @@ arch_get_unmapped_area(struct file *filp
17            merely specific addresses, but regions of memory -- perhaps
18            this feature should be incorporated into all ports?  */
19  
20 +#ifdef CONFIG_PAX_RANDMMAP
21 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
22 +#endif
23 +
24         if (addr) {
25                 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
26                 if (addr != (unsigned long) -ENOMEM)
27 @@ -1280,8 +1284,8 @@ arch_get_unmapped_area(struct file *filp
28         }
29  
30         /* Next, try allocating at TASK_UNMAPPED_BASE.  */
31 -       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
32 -                                        len, limit);
33 +       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
34 +
35         if (addr != (unsigned long) -ENOMEM)
36                 return addr;
37  
38 diff -urNp linux-2.6.18/arch/alpha/kernel/ptrace.c linux-2.6.18/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.18/arch/alpha/kernel/ptrace.c     2006-09-19 23:42:06.000000000 -0400
40 +++ linux-2.6.18/arch/alpha/kernel/ptrace.c     2006-09-22 20:04:35.000000000 -0400
41 @@ -15,6 +15,7 @@
42  #include <linux/slab.h>
43  #include <linux/security.h>
44  #include <linux/signal.h>
45 +#include <linux/grsecurity.h>
46  
47  #include <asm/uaccess.h>
48  #include <asm/pgtable.h>
49 @@ -283,6 +284,9 @@ do_sys_ptrace(long request, long pid, lo
50                 goto out_notsk;
51         }
52  
53 +       if (gr_handle_ptrace(child, request))
54 +               goto out;
55 +
56         if (request == PTRACE_ATTACH) {
57                 ret = ptrace_attach(child);
58                 goto out;
59 diff -urNp linux-2.6.18/arch/alpha/mm/fault.c linux-2.6.18/arch/alpha/mm/fault.c
60 --- linux-2.6.18/arch/alpha/mm/fault.c  2006-09-19 23:42:06.000000000 -0400
61 +++ linux-2.6.18/arch/alpha/mm/fault.c  2006-09-22 20:45:03.000000000 -0400
62 @@ -24,6 +24,7 @@
63  #include <linux/smp_lock.h>
64  #include <linux/interrupt.h>
65  #include <linux/module.h>
66 +#include <linux/binfmts.h>
67  
68  #include <asm/system.h>
69  #include <asm/uaccess.h>
70 @@ -55,6 +56,124 @@ __load_new_mm_context(struct mm_struct *
71         __reload_thread(pcb);
72  }
73  
74 +#ifdef CONFIG_PAX_PAGEEXEC
75 +/*
76 + * PaX: decide what to do with offenders (regs->pc = fault address)
77 + *
78 + * returns 1 when task should be killed
79 + *         2 when patched PLT trampoline was detected
80 + *         3 when unpatched PLT trampoline was detected
81 + */
82 +static int pax_handle_fetch_fault(struct pt_regs *regs)
83 +{
84 +
85 +#ifdef CONFIG_PAX_EMUPLT
86 +       int err;
87 +
88 +       do { /* PaX: patched PLT emulation #1 */
89 +               unsigned int ldah, ldq, jmp;
90 +
91 +               err = get_user(ldah, (unsigned int *)regs->pc);
92 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
93 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
94 +
95 +               if (err)
96 +                       break;
97 +
98 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
99 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
100 +                   jmp == 0x6BFB0000U)
101 +               {
102 +                       unsigned long r27, addr;
103 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
104 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
105 +
106 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
107 +                       err = get_user(r27, (unsigned long*)addr);
108 +                       if (err)
109 +                               break;
110 +
111 +                       regs->r27 = r27;
112 +                       regs->pc = r27;
113 +                       return 2;
114 +               }
115 +       } while (0);
116 +
117 +       do { /* PaX: patched PLT emulation #2 */
118 +               unsigned int ldah, lda, br;
119 +
120 +               err = get_user(ldah, (unsigned int *)regs->pc);
121 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
122 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
123 +
124 +               if (err)
125 +                       break;
126 +
127 +               if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
128 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
129 +                   (br & 0xFFE00000U) == 0xC3E00000U)
130 +               {
131 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
132 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
133 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
134 +
135 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
136 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
137 +                       return 2;
138 +               }
139 +       } while (0);
140 +
141 +       do { /* PaX: unpatched PLT emulation */
142 +               unsigned int br;
143 +
144 +               err = get_user(br, (unsigned int *)regs->pc);
145 +
146 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
147 +                       unsigned int br2, ldq, nop, jmp;
148 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
149 +
150 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
151 +                       err = get_user(br2, (unsigned int *)addr);
152 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
153 +                       err |= get_user(nop, (unsigned int *)(addr+8));
154 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
155 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
156 +
157 +                       if (err)
158 +                               break;
159 +
160 +                       if (br2 == 0xC3600000U &&
161 +                           ldq == 0xA77B000CU &&
162 +                           nop == 0x47FF041FU &&
163 +                           jmp == 0x6B7B0000U)
164 +                       {
165 +                               regs->r28 = regs->pc+4;
166 +                               regs->r27 = addr+16;
167 +                               regs->pc = resolver;
168 +                               return 3;
169 +                       }
170 +               }
171 +       } while (0);
172 +#endif
173 +
174 +       return 1;
175 +}
176 +
177 +void pax_report_insns(void *pc, void *sp)
178 +{
179 +       unsigned long i;
180 +
181 +       printk(KERN_ERR "PAX: bytes at PC: ");
182 +       for (i = 0; i < 5; i++) {
183 +               unsigned int c;
184 +               if (get_user(c, (unsigned int*)pc+i))
185 +                       printk("???????? ");
186 +               else
187 +                       printk("%08x ", c);
188 +       }
189 +       printk("\n");
190 +}
191 +#endif
192  
193  /*
194   * This routine handles page faults.  It determines the address,
195 @@ -132,8 +251,29 @@ do_page_fault(unsigned long address, uns
196   good_area:
197         si_code = SEGV_ACCERR;
198         if (cause < 0) {
199 -               if (!(vma->vm_flags & VM_EXEC))
200 +               if (!(vma->vm_flags & VM_EXEC)) {
201 +
202 +#ifdef CONFIG_PAX_PAGEEXEC
203 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
204 +                               goto bad_area;
205 +
206 +                       up_read(&mm->mmap_sem);
207 +                       switch(pax_handle_fetch_fault(regs)) {
208 +
209 +#ifdef CONFIG_PAX_EMUPLT
210 +                       case 2:
211 +                       case 3:
212 +                               return;
213 +#endif
214 +
215 +                       }
216 +                       pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
217 +                       do_exit(SIGKILL);
218 +#else
219                         goto bad_area;
220 +#endif
221 +
222 +               }
223         } else if (!cause) {
224                 /* Allow reads even for write-only mappings */
225                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
226 diff -urNp linux-2.6.18/arch/arm/mm/mmap.c linux-2.6.18/arch/arm/mm/mmap.c
227 --- linux-2.6.18/arch/arm/mm/mmap.c     2006-09-19 23:42:06.000000000 -0400
228 +++ linux-2.6.18/arch/arm/mm/mmap.c     2006-09-22 20:45:03.000000000 -0400
229 @@ -61,6 +61,10 @@ arch_get_unmapped_area(struct file *filp
230         if (len > TASK_SIZE)
231                 return -ENOMEM;
232  
233 +#ifdef CONFIG_PAX_RANDMMAP
234 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
235 +#endif
236 +
237         if (addr) {
238                 if (do_align)
239                         addr = COLOUR_ALIGN(addr, pgoff);
240 @@ -75,7 +79,7 @@ arch_get_unmapped_area(struct file *filp
241         if (len > mm->cached_hole_size) {
242                 start_addr = addr = mm->free_area_cache;
243         } else {
244 -               start_addr = addr = TASK_UNMAPPED_BASE;
245 +               start_addr = addr = mm->mmap_base;
246                 mm->cached_hole_size = 0;
247         }
248  
249 @@ -92,8 +96,8 @@ full_search:
250                          * Start a new search - just in case we missed
251                          * some holes.
252                          */
253 -                       if (start_addr != TASK_UNMAPPED_BASE) {
254 -                               start_addr = addr = TASK_UNMAPPED_BASE;
255 +                       if (start_addr != mm->mmap_base) {
256 +                               start_addr = addr = mm->mmap_base;
257                                 mm->cached_hole_size = 0;
258                                 goto full_search;
259                         }
260 diff -urNp linux-2.6.18/arch/i386/boot/compressed/head.S linux-2.6.18/arch/i386/boot/compressed/head.S
261 --- linux-2.6.18/arch/i386/boot/compressed/head.S       2006-09-19 23:42:06.000000000 -0400
262 +++ linux-2.6.18/arch/i386/boot/compressed/head.S       2006-09-22 20:45:03.000000000 -0400
263 @@ -39,11 +39,13 @@ startup_32:
264         movl %eax,%gs
265  
266         lss stack_start,%esp
267 +       movl 0x000000,%ecx
268         xorl %eax,%eax
269  1:     incl %eax               # check that A20 really IS enabled
270         movl %eax,0x000000      # loop forever if it isn't
271         cmpl %eax,0x100000
272         je 1b
273 +       movl %ecx,0x000000
274  
275  /*
276   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
277 diff -urNp linux-2.6.18/arch/i386/Kconfig linux-2.6.18/arch/i386/Kconfig
278 --- linux-2.6.18/arch/i386/Kconfig      2006-09-19 23:42:06.000000000 -0400
279 +++ linux-2.6.18/arch/i386/Kconfig      2006-09-22 20:45:03.000000000 -0400
280 @@ -793,7 +793,7 @@ config HOTPLUG_CPU
281  
282  config COMPAT_VDSO
283         bool "Compat VDSO support"
284 -       default y
285 +       default n
286         help
287           Map the VDSO to the predictable old-style address too.
288         ---help---
289 @@ -988,7 +988,7 @@ config PCI
290  choice
291         prompt "PCI access mode"
292         depends on PCI && !X86_VISWS
293 -       default PCI_GOANY
294 +       default PCI_GODIRECT
295         ---help---
296           On PCI systems, the BIOS can be used to detect the PCI devices and
297           determine their configuration. However, some old PCI motherboards
298 @@ -1020,7 +1020,7 @@ endchoice
299  
300  config PCI_BIOS
301         bool
302 -       depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
303 +       depends on !X86_VISWS && PCI && PCI_GOBIOS
304         default y
305  
306  config PCI_DIRECT
307 diff -urNp linux-2.6.18/arch/i386/Kconfig.cpu linux-2.6.18/arch/i386/Kconfig.cpu
308 --- linux-2.6.18/arch/i386/Kconfig.cpu  2006-09-19 23:42:06.000000000 -0400
309 +++ linux-2.6.18/arch/i386/Kconfig.cpu  2006-09-22 20:45:03.000000000 -0400
310 @@ -251,7 +251,7 @@ config X86_PPRO_FENCE
311  
312  config X86_F00F_BUG
313         bool
314 -       depends on M586MMX || M586TSC || M586 || M486 || M386
315 +       depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
316         default y
317  
318  config X86_WP_WORKS_OK
319 @@ -281,7 +281,7 @@ config X86_CMPXCHG64
320  
321  config X86_ALIGNMENT_16
322         bool
323 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
324 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
325         default y
326  
327  config X86_GOOD_APIC
328 diff -urNp linux-2.6.18/arch/i386/Kconfig.debug linux-2.6.18/arch/i386/Kconfig.debug
329 --- linux-2.6.18/arch/i386/Kconfig.debug        2006-09-19 23:42:06.000000000 -0400
330 +++ linux-2.6.18/arch/i386/Kconfig.debug        2006-09-22 20:45:03.000000000 -0400
331 @@ -48,7 +48,7 @@ config DEBUG_PAGEALLOC
332  
333  config DEBUG_RODATA
334         bool "Write protect kernel read-only data structures"
335 -       depends on DEBUG_KERNEL
336 +       depends on DEBUG_KERNEL && 0
337         help
338           Mark the kernel read-only data as write-protected in the pagetables,
339           in order to catch accidental (and incorrect) writes to such const
340 diff -urNp linux-2.6.18/arch/i386/kernel/alternative.c linux-2.6.18/arch/i386/kernel/alternative.c
341 --- linux-2.6.18/arch/i386/kernel/alternative.c 2006-09-19 23:42:06.000000000 -0400
342 +++ linux-2.6.18/arch/i386/kernel/alternative.c 2006-09-22 20:45:03.000000000 -0400
343 @@ -3,6 +3,7 @@
344  #include <linux/list.h>
345  #include <asm/alternative.h>
346  #include <asm/sections.h>
347 +#include <asm/desc.h>
348  
349  static int no_replacement    = 0;
350  static int smp_alt_once      = 0;
351 @@ -142,6 +143,12 @@ void apply_alternatives(struct alt_instr
352         u8 *instr;
353         int diff, i, k;
354  
355 +#ifdef CONFIG_PAX_KERNEXEC
356 +       unsigned long cr0;
357 +
358 +       pax_open_kernel(cr0);
359 +#endif
360 +
361         DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
362         for (a = start; a < end; a++) {
363                 BUG_ON(a->replacementlen > a->instrlen);
364 @@ -156,16 +163,21 @@ void apply_alternatives(struct alt_instr
365                                 __FUNCTION__, a->instr, instr);
366                 }
367  #endif
368 -               memcpy(instr, a->replacement, a->replacementlen);
369 +               memcpy(instr + __KERNEL_TEXT_OFFSET, a->replacement, a->replacementlen);
370                 diff = a->instrlen - a->replacementlen;
371                 /* Pad the rest with nops */
372                 for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
373                         k = diff;
374                         if (k > ASM_NOP_MAX)
375                                 k = ASM_NOP_MAX;
376 -                       memcpy(a->instr + i, noptable[k], k);
377 +                       memcpy(a->instr + i + __KERNEL_TEXT_OFFSET, noptable[k], k);
378                 }
379         }
380 +
381 +#ifdef CONFIG_PAX_KERNEXEC
382 +       pax_close_kernel(cr0);
383 +#endif
384 +
385  }
386  
387  #ifdef CONFIG_SMP
388 @@ -174,50 +186,96 @@ static void alternatives_smp_save(struct
389  {
390         struct alt_instr *a;
391  
392 +#ifdef CONFIG_PAX_KERNEXEC
393 +       unsigned long cr0;
394 +
395 +       pax_open_kernel(cr0);
396 +#endif
397 +
398         DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
399         for (a = start; a < end; a++) {
400                 memcpy(a->replacement + a->replacementlen,
401 -                      a->instr,
402 +                      a->instr + __KERNEL_TEXT_OFFSET,
403                        a->instrlen);
404         }
405 +
406 +#ifdef CONFIG_PAX_KERNEXEC
407 +       pax_close_kernel(cr0);
408 +#endif
409 +
410  }
411  
412  static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
413  {
414         struct alt_instr *a;
415  
416 +#ifdef CONFIG_PAX_KERNEXEC
417 +       unsigned long cr0;
418 +
419 +       pax_open_kernel(cr0);
420 +#endif
421 +
422         for (a = start; a < end; a++) {
423 -               memcpy(a->instr,
424 +               memcpy(a->instr + __KERNEL_TEXT_OFFSET,
425                        a->replacement + a->replacementlen,
426                        a->instrlen);
427         }
428 +
429 +#ifdef CONFIG_PAX_KERNEXEC
430 +       pax_close_kernel(cr0);
431 +#endif
432 +
433  }
434  
435  static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
436  {
437 -       u8 **ptr;
438 +       u8 *ptr;
439 +
440 +#ifdef CONFIG_PAX_KERNEXEC
441 +       unsigned long cr0;
442  
443 -       for (ptr = start; ptr < end; ptr++) {
444 -               if (*ptr < text)
445 +       pax_open_kernel(cr0);
446 +#endif
447 +
448 +       for (; start < end; start++) {
449 +               ptr = *start + __KERNEL_TEXT_OFFSET;
450 +               if (ptr < text)
451                         continue;
452 -               if (*ptr > text_end)
453 +               if (ptr > text_end)
454                         continue;
455 -               **ptr = 0xf0; /* lock prefix */
456 +               *ptr = 0xf0; /* lock prefix */
457         };
458 +
459 +#ifdef CONFIG_PAX_KERNEXEC
460 +       pax_close_kernel(cr0);
461 +#endif
462 +
463  }
464  
465  static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
466  {
467         unsigned char **noptable = find_nop_table();
468 -       u8 **ptr;
469 +       u8 *ptr;
470 +
471 +#ifdef CONFIG_PAX_KERNEXEC
472 +       unsigned long cr0;
473 +
474 +       pax_open_kernel(cr0);
475 +#endif
476  
477 -       for (ptr = start; ptr < end; ptr++) {
478 -               if (*ptr < text)
479 +       for (; start < end; start++) {
480 +               ptr = *start + __KERNEL_TEXT_OFFSET;
481 +               if (ptr < text)
482                         continue;
483 -               if (*ptr > text_end)
484 +               if (ptr > text_end)
485                         continue;
486 -               **ptr = noptable[1][0];
487 +               *ptr = noptable[1][0];
488         };
489 +
490 +#ifdef CONFIG_PAX_KERNEXEC
491 +       pax_close_kernel(cr0);
492 +#endif
493 +
494  }
495  
496  struct smp_alt_module {
497 diff -urNp linux-2.6.18/arch/i386/kernel/apic.c linux-2.6.18/arch/i386/kernel/apic.c
498 --- linux-2.6.18/arch/i386/kernel/apic.c        2006-09-19 23:42:06.000000000 -0400
499 +++ linux-2.6.18/arch/i386/kernel/apic.c        2006-09-22 20:45:03.000000000 -0400
500 @@ -1187,7 +1187,7 @@ inline void smp_local_timer_interrupt(st
501  {
502         profile_tick(CPU_PROFILING, regs);
503  #ifdef CONFIG_SMP
504 -       update_process_times(user_mode_vm(regs));
505 +       update_process_times(user_mode(regs));
506  #endif
507  
508         /*
509 diff -urNp linux-2.6.18/arch/i386/kernel/apm.c linux-2.6.18/arch/i386/kernel/apm.c
510 --- linux-2.6.18/arch/i386/kernel/apm.c 2006-09-19 23:42:06.000000000 -0400
511 +++ linux-2.6.18/arch/i386/kernel/apm.c 2006-09-22 20:45:03.000000000 -0400
512 @@ -234,7 +234,7 @@
513  #include "io_ports.h"
514  
515  extern unsigned long get_cmos_time(void);
516 -extern void machine_real_restart(unsigned char *, int);
517 +extern void machine_real_restart(const unsigned char *, unsigned int);
518  
519  #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
520  extern int (*console_blank_hook)(int);
521 @@ -588,9 +588,18 @@ static u8 apm_bios_call(u32 func, u32 eb
522         struct desc_struct      save_desc_40;
523         struct desc_struct      *gdt;
524  
525 +#ifdef CONFIG_PAX_KERNEXEC
526 +       unsigned long           cr0;
527 +#endif
528 +
529         cpus = apm_save_cpus();
530         
531         cpu = get_cpu();
532 +
533 +#ifdef CONFIG_PAX_KERNEXEC
534 +       pax_open_kernel(cr0);
535 +#endif
536 +
537         gdt = get_cpu_gdt_table(cpu);
538         save_desc_40 = gdt[0x40 / 8];
539         gdt[0x40 / 8] = bad_bios_desc;
540 @@ -602,6 +611,11 @@ static u8 apm_bios_call(u32 func, u32 eb
541         APM_DO_RESTORE_SEGS;
542         local_irq_restore(flags);
543         gdt[0x40 / 8] = save_desc_40;
544 +
545 +#ifdef CONFIG_PAX_KERNEXEC
546 +       pax_close_kernel(cr0);
547 +#endif
548 +
549         put_cpu();
550         apm_restore_cpus(cpus);
551         
552 @@ -632,9 +646,18 @@ static u8 apm_bios_call_simple(u32 func,
553         struct desc_struct      save_desc_40;
554         struct desc_struct      *gdt;
555  
556 +#ifdef CONFIG_PAX_KERNEXEC
557 +       unsigned long           cr0;
558 +#endif
559 +
560         cpus = apm_save_cpus();
561         
562         cpu = get_cpu();
563 +
564 +#ifdef CONFIG_PAX_KERNEXEC
565 +       pax_open_kernel(cr0);
566 +#endif
567 +
568         gdt = get_cpu_gdt_table(cpu);
569         save_desc_40 = gdt[0x40 / 8];
570         gdt[0x40 / 8] = bad_bios_desc;
571 @@ -646,6 +669,11 @@ static u8 apm_bios_call_simple(u32 func,
572         APM_DO_RESTORE_SEGS;
573         local_irq_restore(flags);
574         gdt[0x40 / 8] = save_desc_40;
575 +
576 +#ifdef CONFIG_PAX_KERNEXEC
577 +       pax_close_kernel(cr0);
578 +#endif
579 +
580         put_cpu();
581         apm_restore_cpus(cpus);
582         return error;
583 @@ -909,7 +937,7 @@ recalc:
584   
585  static void apm_power_off(void)
586  {
587 -       unsigned char   po_bios_call[] = {
588 +       const unsigned char     po_bios_call[] = {
589                 0xb8, 0x00, 0x10,       /* movw  $0x1000,ax  */
590                 0x8e, 0xd0,             /* movw  ax,ss       */
591                 0xbc, 0x00, 0xf0,       /* movw  $0xf000,sp  */
592 diff -urNp linux-2.6.18/arch/i386/kernel/asm-offsets.c linux-2.6.18/arch/i386/kernel/asm-offsets.c
593 --- linux-2.6.18/arch/i386/kernel/asm-offsets.c 2006-09-19 23:42:06.000000000 -0400
594 +++ linux-2.6.18/arch/i386/kernel/asm-offsets.c 2006-09-22 20:45:03.000000000 -0400
595 @@ -71,6 +71,7 @@ void foo(void)
596                  sizeof(struct tss_struct));
597  
598         DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
599 +       DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
600         DEFINE(VDSO_PRELINK, VDSO_PRELINK);
601  
602         OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
603 diff -urNp linux-2.6.18/arch/i386/kernel/cpu/common.c linux-2.6.18/arch/i386/kernel/cpu/common.c
604 --- linux-2.6.18/arch/i386/kernel/cpu/common.c  2006-09-19 23:42:06.000000000 -0400
605 +++ linux-2.6.18/arch/i386/kernel/cpu/common.c  2006-09-22 20:45:03.000000000 -0400
606 @@ -4,7 +4,6 @@
607  #include <linux/smp.h>
608  #include <linux/module.h>
609  #include <linux/percpu.h>
610 -#include <linux/bootmem.h>
611  #include <asm/semaphore.h>
612  #include <asm/processor.h>
613  #include <asm/i387.h>
614 @@ -21,16 +20,18 @@
615  
616  #include "cpu.h"
617  
618 -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
619 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
620 -
621  DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
622  EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
623  
624  static int cachesize_override __cpuinitdata = -1;
625  static int disable_x86_fxsr __cpuinitdata;
626  static int disable_x86_serial_nr __cpuinitdata = 1;
627 +
628 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC)
629 +static int disable_x86_sep __cpuinitdata = 1;
630 +#else
631  static int disable_x86_sep __cpuinitdata;
632 +#endif
633  
634  struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
635  
636 @@ -591,11 +592,10 @@ void __init early_cpu_init(void)
637  void __cpuinit cpu_init(void)
638  {
639         int cpu = smp_processor_id();
640 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
641 +       struct tss_struct * t = init_tss + cpu;
642         struct thread_struct *thread = &current->thread;
643 -       struct desc_struct *gdt;
644 +       struct desc_struct *gdt = get_cpu_gdt_table(cpu);
645         __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
646 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
647  
648         if (cpu_test_and_set(cpu, cpu_initialized)) {
649                 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
650 @@ -612,36 +612,12 @@ void __cpuinit cpu_init(void)
651                 set_in_cr4(X86_CR4_TSD);
652         }
653  
654 -       /* The CPU hotplug case */
655 -       if (cpu_gdt_descr->address) {
656 -               gdt = (struct desc_struct *)cpu_gdt_descr->address;
657 -               memset(gdt, 0, PAGE_SIZE);
658 -               goto old_gdt;
659 -       }
660 -       /*
661 -        * This is a horrible hack to allocate the GDT.  The problem
662 -        * is that cpu_init() is called really early for the boot CPU
663 -        * (and hence needs bootmem) but much later for the secondary
664 -        * CPUs, when bootmem will have gone away
665 -        */
666 -       if (NODE_DATA(0)->bdata->node_bootmem_map) {
667 -               gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
668 -               /* alloc_bootmem_pages panics on failure, so no check */
669 -               memset(gdt, 0, PAGE_SIZE);
670 -       } else {
671 -               gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
672 -               if (unlikely(!gdt)) {
673 -                       printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
674 -                       for (;;)
675 -                               local_irq_enable();
676 -               }
677 -       }
678 -old_gdt:
679         /*
680          * Initialize the per-CPU GDT with the boot GDT,
681          * and set up the GDT descriptor:
682          */
683 -       memcpy(gdt, cpu_gdt_table, GDT_SIZE);
684 +       if (cpu)
685 +               memcpy(gdt, cpu_gdt_table, GDT_SIZE);
686  
687         /* Set up GDT entry for 16bit stack */
688         *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
689 @@ -649,10 +625,10 @@ old_gdt:
690                 ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
691                 (CPU_16BIT_STACK_SIZE - 1);
692  
693 -       cpu_gdt_descr->size = GDT_SIZE - 1;
694 -       cpu_gdt_descr->address = (unsigned long)gdt;
695 +       cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
696 +       cpu_gdt_descr[cpu].address = (unsigned long)gdt;
697  
698 -       load_gdt(cpu_gdt_descr);
699 +       load_gdt(&cpu_gdt_descr[cpu]);
700         load_idt(&idt_descr);
701  
702         /*
703 @@ -667,7 +643,7 @@ old_gdt:
704         load_esp0(t, thread);
705         set_tss_desc(cpu,t);
706         load_TR_desc();
707 -       load_LDT(&init_mm.context);
708 +       _load_LDT(&init_mm.context);
709  
710  #ifdef CONFIG_DOUBLEFAULT
711         /* Set up doublefault TSS pointer in the GDT */
712 @@ -675,7 +651,7 @@ old_gdt:
713  #endif
714  
715         /* Clear %fs and %gs. */
716 -       asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
717 +       asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r"(0));
718  
719         /* Clear all 6 debug registers: */
720         set_debugreg(0, 0);
721 diff -urNp linux-2.6.18/arch/i386/kernel/crash.c linux-2.6.18/arch/i386/kernel/crash.c
722 --- linux-2.6.18/arch/i386/kernel/crash.c       2006-09-19 23:42:06.000000000 -0400
723 +++ linux-2.6.18/arch/i386/kernel/crash.c       2006-09-22 20:45:03.000000000 -0400
724 @@ -105,7 +105,7 @@ static int crash_nmi_callback(struct pt_
725                 return 1;
726         local_irq_disable();
727  
728 -       if (!user_mode_vm(regs)) {
729 +       if (!user_mode(regs)) {
730                 crash_fixup_ss_esp(&fixed_regs, regs);
731                 regs = &fixed_regs;
732         }
733 diff -urNp linux-2.6.18/arch/i386/kernel/doublefault.c linux-2.6.18/arch/i386/kernel/doublefault.c
734 --- linux-2.6.18/arch/i386/kernel/doublefault.c 2006-09-19 23:42:06.000000000 -0400
735 +++ linux-2.6.18/arch/i386/kernel/doublefault.c 2006-09-22 20:45:03.000000000 -0400
736 @@ -11,7 +11,7 @@
737  
738  #define DOUBLEFAULT_STACKSIZE (1024)
739  static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
740 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
741 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
742  
743  #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
744  
745 @@ -57,10 +57,10 @@ struct tss_struct doublefault_tss __cach
746         .eip            = (unsigned long) doublefault_fn,
747         .eflags         = X86_EFLAGS_SF | 0x2,  /* 0x2 bit is always set */
748         .esp            = STACK_START,
749 -       .es             = __USER_DS,
750 +       .es             = __KERNEL_DS,
751         .cs             = __KERNEL_CS,
752         .ss             = __KERNEL_DS,
753 -       .ds             = __USER_DS,
754 +       .ds             = __KERNEL_DS,
755  
756         .__cr3          = __pa(swapper_pg_dir)
757  };
758 diff -urNp linux-2.6.18/arch/i386/kernel/efi.c linux-2.6.18/arch/i386/kernel/efi.c
759 --- linux-2.6.18/arch/i386/kernel/efi.c 2006-09-19 23:42:06.000000000 -0400
760 +++ linux-2.6.18/arch/i386/kernel/efi.c 2006-09-22 20:45:03.000000000 -0400
761 @@ -63,82 +63,43 @@ extern void * boot_ioremap(unsigned long
762  
763  static unsigned long efi_rt_eflags;
764  static DEFINE_SPINLOCK(efi_rt_lock);
765 -static pgd_t efi_bak_pg_dir_pointer[2];
766 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
767  
768 -static void efi_call_phys_prelog(void)
769 +static void __init efi_call_phys_prelog(void)
770  {
771 -       unsigned long cr4;
772 -       unsigned long temp;
773 -       struct Xgt_desc_struct *cpu_gdt_descr;
774 -
775         spin_lock(&efi_rt_lock);
776         local_irq_save(efi_rt_eflags);
777  
778 -       cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
779 -
780 -       /*
781 -        * If I don't have PSE, I should just duplicate two entries in page
782 -        * directory. If I have PSE, I just need to duplicate one entry in
783 -        * page directory.
784 -        */
785 -       cr4 = read_cr4();
786 -
787 -       if (cr4 & X86_CR4_PSE) {
788 -               efi_bak_pg_dir_pointer[0].pgd =
789 -                   swapper_pg_dir[pgd_index(0)].pgd;
790 -               swapper_pg_dir[0].pgd =
791 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
792 -       } else {
793 -               efi_bak_pg_dir_pointer[0].pgd =
794 -                   swapper_pg_dir[pgd_index(0)].pgd;
795 -               efi_bak_pg_dir_pointer[1].pgd =
796 -                   swapper_pg_dir[pgd_index(0x400000)].pgd;
797 -               swapper_pg_dir[pgd_index(0)].pgd =
798 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
799 -               temp = PAGE_OFFSET + 0x400000;
800 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
801 -                   swapper_pg_dir[pgd_index(temp)].pgd;
802 -       }
803 +       clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
804 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
805 +                       USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
806  
807         /*
808          * After the lock is released, the original page table is restored.
809          */
810 -       local_flush_tlb();
811 +       __flush_tlb_all();
812  
813 -       cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
814 -       load_gdt(cpu_gdt_descr);
815 +       cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
816 +       load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
817  }
818  
819 -static void efi_call_phys_epilog(void)
820 +static void __init efi_call_phys_epilog(void)
821  {
822 -       unsigned long cr4;
823 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
824 -
825 -       cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address);
826 -       load_gdt(cpu_gdt_descr);
827 +       cpu_gdt_descr[0].address = (unsigned long) __va(cpu_gdt_descr[0].address);
828 +       load_gdt(&cpu_gdt_descr[0]);
829  
830 -       cr4 = read_cr4();
831 -
832 -       if (cr4 & X86_CR4_PSE) {
833 -               swapper_pg_dir[pgd_index(0)].pgd =
834 -                   efi_bak_pg_dir_pointer[0].pgd;
835 -       } else {
836 -               swapper_pg_dir[pgd_index(0)].pgd =
837 -                   efi_bak_pg_dir_pointer[0].pgd;
838 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
839 -                   efi_bak_pg_dir_pointer[1].pgd;
840 -       }
841 +       clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
842  
843         /*
844          * After the lock is released, the original page table is restored.
845          */
846 -       local_flush_tlb();
847 +       __flush_tlb_all();
848  
849         local_irq_restore(efi_rt_eflags);
850         spin_unlock(&efi_rt_lock);
851  }
852  
853 -static efi_status_t
854 +static efi_status_t __init
855  phys_efi_set_virtual_address_map(unsigned long memory_map_size,
856                                  unsigned long descriptor_size,
857                                  u32 descriptor_version,
858 @@ -154,7 +115,7 @@ phys_efi_set_virtual_address_map(unsigne
859         return status;
860  }
861  
862 -static efi_status_t
863 +static efi_status_t __init
864  phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
865  {
866         efi_status_t status;
867 diff -urNp linux-2.6.18/arch/i386/kernel/efi_stub.S linux-2.6.18/arch/i386/kernel/efi_stub.S
868 --- linux-2.6.18/arch/i386/kernel/efi_stub.S    2006-09-19 23:42:06.000000000 -0400
869 +++ linux-2.6.18/arch/i386/kernel/efi_stub.S    2006-09-22 20:45:03.000000000 -0400
870 @@ -6,6 +6,7 @@
871   */
872  
873  #include <linux/linkage.h>
874 +#include <linux/init.h>
875  #include <asm/page.h>
876  #include <asm/pgtable.h>
877  
878 @@ -21,7 +22,7 @@
879   * service functions will comply with gcc calling convention, too.
880   */
881  
882 -.text
883 +__INIT
884  ENTRY(efi_call_phys)
885         /*
886          * 0. The function can only be called in Linux kernel. So CS has been
887 @@ -37,9 +38,7 @@ ENTRY(efi_call_phys)
888          * The mapping of lower virtual memory has been created in prelog and
889          * epilog.
890          */
891 -       movl    $1f, %edx
892 -       subl    $__PAGE_OFFSET, %edx
893 -       jmp     *%edx
894 +       jmp     1f-__PAGE_OFFSET
895  1:
896  
897         /*
898 @@ -48,14 +47,8 @@ ENTRY(efi_call_phys)
899          * parameter 2, ..., param n. To make things easy, we save the return
900          * address of efi_call_phys in a global variable.
901          */
902 -       popl    %edx
903 -       movl    %edx, saved_return_addr
904 -       /* get the function pointer into ECX*/
905 -       popl    %ecx
906 -       movl    %ecx, efi_rt_function_ptr
907 -       movl    $2f, %edx
908 -       subl    $__PAGE_OFFSET, %edx
909 -       pushl   %edx
910 +       popl    (saved_return_addr)
911 +       popl    (efi_rt_function_ptr)
912  
913         /*
914          * 3. Clear PG bit in %CR0.
915 @@ -74,9 +67,8 @@ ENTRY(efi_call_phys)
916         /*
917          * 5. Call the physical function.
918          */
919 -       jmp     *%ecx
920 +       call    *(efi_rt_function_ptr-__PAGE_OFFSET)
921  
922 -2:
923         /*
924          * 6. After EFI runtime service returns, control will return to
925          * following instruction. We'd better readjust stack pointer first.
926 @@ -86,37 +78,29 @@ ENTRY(efi_call_phys)
927         /*
928          * 7. Restore PG bit
929          */
930 -       movl    %cr0, %edx
931 -       orl     $0x80000000, %edx
932 -       movl    %edx, %cr0
933 -       jmp     1f
934 -1:
935         /*
936          * 8. Now restore the virtual mode from flat mode by
937          * adding EIP with PAGE_OFFSET.
938          */
939 -       movl    $1f, %edx
940 -       jmp     *%edx
941 +       movl    %cr0, %edx
942 +       orl     $0x80000000, %edx
943 +       movl    %edx, %cr0
944 +       jmp     1f+__PAGE_OFFSET
945  1:
946  
947         /*
948          * 9. Balance the stack. And because EAX contain the return value,
949          * we'd better not clobber it.
950          */
951 -       leal    efi_rt_function_ptr, %edx
952 -       movl    (%edx), %ecx
953 -       pushl   %ecx
954 +       pushl   (efi_rt_function_ptr)
955  
956         /*
957 -        * 10. Push the saved return address onto the stack and return.
958 +        * 10. Return to the saved return address.
959          */
960 -       leal    saved_return_addr, %edx
961 -       movl    (%edx), %ecx
962 -       pushl   %ecx
963 -       ret
964 +       jmpl    *(saved_return_addr)
965  .previous
966  
967 -.data
968 +__INITDATA
969  saved_return_addr:
970         .long 0
971  efi_rt_function_ptr:
972 diff -urNp linux-2.6.18/arch/i386/kernel/entry.S linux-2.6.18/arch/i386/kernel/entry.S
973 --- linux-2.6.18/arch/i386/kernel/entry.S       2006-09-19 23:42:06.000000000 -0400
974 +++ linux-2.6.18/arch/i386/kernel/entry.S       2006-09-22 20:45:03.000000000 -0400
975 @@ -98,7 +98,7 @@ VM_MASK               = 0x00020000
976  #define resume_userspace_sig   resume_userspace
977  #endif
978  
979 -#define SAVE_ALL \
980 +#define __SAVE_ALL(_DS) \
981         cld; \
982         pushl %es; \
983         CFI_ADJUST_CFA_OFFSET 4;\
984 @@ -127,10 +127,24 @@ VM_MASK           = 0x00020000
985         pushl %ebx; \
986         CFI_ADJUST_CFA_OFFSET 4;\
987         CFI_REL_OFFSET ebx, 0;\
988 -       movl $(__USER_DS), %edx; \
989 +       movl $(_DS), %edx; \
990         movl %edx, %ds; \
991         movl %edx, %es;
992  
993 +#ifdef CONFIG_PAX_KERNEXEC
994 +#define SAVE_ALL \
995 +       __SAVE_ALL(__KERNEL_DS) \
996 +       movl %cr0, %edx; \
997 +       movl %edx, %esi; \
998 +       orl $0x10000, %edx; \
999 +       xorl %edx, %esi; \
1000 +       movl %edx, %cr0;
1001 +#elif defined(CONFIG_COMPAT_VDSO)
1002 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
1003 +#else
1004 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1005 +#endif
1006 +
1007  #define RESTORE_INT_REGS \
1008         popl %ebx;      \
1009         CFI_ADJUST_CFA_OFFSET -4;\
1010 @@ -234,7 +248,19 @@ check_userspace:
1011         movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
1012         movb CS(%esp), %al
1013         testl $(VM_MASK | 3), %eax
1014 +
1015 +#ifdef CONFIG_PAX_KERNEXEC
1016 +       jnz resume_userspace
1017 +
1018 +       movl %cr0, %edx
1019 +       xorl %esi, %edx
1020 +       movl %edx, %cr0
1021 +       jmp resume_kernel
1022 +#else
1023         jz resume_kernel
1024 +#endif
1025 +
1026 +
1027  ENTRY(resume_userspace)
1028         cli                             # make sure we don't miss an interrupt
1029                                         # setting need_resched or sigpending
1030 @@ -289,10 +315,9 @@ sysenter_past_esp:
1031         /*CFI_REL_OFFSET cs, 0*/
1032         /*
1033          * Push current_thread_info()->sysenter_return to the stack.
1034 -        * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
1035 -        * pushed above; +8 corresponds to copy_thread's esp0 setting.
1036          */
1037 -       pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
1038 +       GET_THREAD_INFO(%ebp)
1039 +       pushl TI_sysenter_return(%esp)
1040         CFI_ADJUST_CFA_OFFSET 4
1041         CFI_REL_OFFSET eip, 0
1042  
1043 @@ -300,9 +325,20 @@ sysenter_past_esp:
1044   * Load the potential sixth argument from user stack.
1045   * Careful about security.
1046   */
1047 +       movl 12(%esp),%ebp
1048 +
1049 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1050 +       pushl $(__USER_DS)
1051 +       CFI_ADJUST_CFA_OFFSET 4
1052 +       pop %ds
1053 +       CFI_ADJUST_CFA_OFFSET -4
1054 +1:     movl %ds:(%ebp),%ebp
1055 +#else
1056         cmpl $__PAGE_OFFSET-3,%ebp
1057         jae syscall_fault
1058  1:     movl (%ebp),%ebp
1059 +#endif
1060 +
1061  .section __ex_table,"a"
1062         .align 4
1063         .long 1b,syscall_fault
1064 @@ -325,15 +361,37 @@ sysenter_past_esp:
1065         movl TI_flags(%ebp), %ecx
1066         testw $_TIF_ALLWORK_MASK, %cx
1067         jne syscall_exit_work
1068 +
1069 +#ifdef CONFIG_PAX_RANDKSTACK
1070 +       pushl %eax
1071 +       CFI_ADJUST_CFA_OFFSET 4
1072 +       call pax_randomize_kstack
1073 +       popl %eax
1074 +       CFI_ADJUST_CFA_OFFSET -4
1075 +#endif
1076 +
1077  /* if something modifies registers it must also disable sysexit */
1078         movl EIP(%esp), %edx
1079         movl OLDESP(%esp), %ecx
1080 +1:     mov DS(%esp), %ds
1081 +2:     mov ES(%esp), %es
1082         xorl %ebp,%ebp
1083         TRACE_IRQS_ON
1084         sti
1085         sysexit
1086         CFI_ENDPROC
1087  
1088 +.section .fixup,"ax"
1089 +3:     movl $0,DS(%esp)
1090 +       jmp 1b
1091 +4:     movl $0,ES(%esp)
1092 +       jmp 2b
1093 +.previous
1094 +.section __ex_table,"a"
1095 +       .align 4
1096 +       .long 1b,3b
1097 +       .long 2b,4b
1098 +.previous
1099  
1100         # system call handler stub
1101  ENTRY(system_call)
1102 @@ -364,6 +422,10 @@ syscall_exit:
1103         testw $_TIF_ALLWORK_MASK, %cx   # current->work
1104         jne syscall_exit_work
1105  
1106 +#ifdef CONFIG_PAX_RANDKSTACK
1107 +       call pax_randomize_kstack
1108 +#endif
1109 +
1110  restore_all:
1111         movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
1112         # Warning: OLDSS(%esp) contains the wrong/random values if we
1113 @@ -542,7 +604,7 @@ syscall_badsys:
1114   * Build the entry stubs and pointer table with
1115   * some assembler magic.
1116   */
1117 -.data
1118 +.section .rodata,"a",@progbits
1119  ENTRY(interrupt)
1120  .text
1121  
1122 @@ -557,7 +619,7 @@ ENTRY(irq_entries_start)
1123  1:     pushl $~(vector)
1124         CFI_ADJUST_CFA_OFFSET 4
1125         jmp common_interrupt
1126 -.data
1127 +.section .rodata,"a",@progbits
1128         .long 1b
1129  .text
1130  vector=vector+1
1131 @@ -638,10 +700,19 @@ error_code:
1132         movl %eax, ORIG_EAX(%esp)
1133         movl %ecx, ES(%esp)
1134         /*CFI_REL_OFFSET es, ES*/
1135 -       movl $(__USER_DS), %ecx
1136 +       movl $(__KERNEL_DS), %ecx
1137         movl %ecx, %ds
1138         movl %ecx, %es
1139         movl %esp,%eax                  # pt_regs pointer
1140 +
1141 +#ifdef CONFIG_PAX_KERNEXEC
1142 +       movl %cr0, %ecx
1143 +       movl %ecx, %esi
1144 +       orl $0x10000, %ecx
1145 +       xorl %ecx, %esi
1146 +       movl %ecx, %cr0
1147 +#endif
1148 +
1149         call *%edi
1150         jmp ret_from_exception
1151         CFI_ENDPROC
1152 @@ -760,6 +831,13 @@ nmi_stack_correct:
1153         xorl %edx,%edx          # zero error code
1154         movl %esp,%eax          # pt_regs pointer
1155         call do_nmi
1156 +
1157 +#ifdef CONFIG_PAX_KERNEXEC
1158 +       movl %cr0, %edx
1159 +       xorl %esi, %edx
1160 +       movl %edx, %cr0
1161 +#endif
1162 +
1163         jmp restore_nocheck_notrace
1164         CFI_ENDPROC
1165  
1166 @@ -797,6 +875,13 @@ nmi_16bit_stack:
1167         CFI_ADJUST_CFA_OFFSET -20       # the frame has now moved
1168         xorl %edx,%edx                  # zero error code
1169         call do_nmi
1170 +
1171 +#ifdef CONFIG_PAX_KERNEXEC
1172 +       movl %cr0, %edx
1173 +       xorl %esi, %edx
1174 +       movl %edx, %cr0
1175 +#endif
1176 +
1177         RESTORE_REGS
1178         lss 12+4(%esp), %esp            # back to 16bit stack
1179  1:     iret
1180 @@ -932,8 +1017,8 @@ ENTRY(arch_unwind_init_running)
1181         movl    %edi, EDI(%edx)
1182         movl    %ebp, EBP(%edx)
1183         movl    %ebx, EAX(%edx)
1184 -       movl    $__USER_DS, DS(%edx)
1185 -       movl    $__USER_DS, ES(%edx)
1186 +       movl    $__KERNEL_DS, DS(%edx)
1187 +       movl    $__KERNEL_DS, ES(%edx)
1188         movl    %ebx, ORIG_EAX(%edx)
1189         movl    %ecx, EIP(%edx)
1190         movl    12(%esp), %ecx
1191 @@ -949,7 +1034,6 @@ ENTRY(arch_unwind_init_running)
1192  ENDPROC(arch_unwind_init_running)
1193  #endif
1194  
1195 -.section .rodata,"a"
1196  #include "syscall_table.S"
1197  
1198  syscall_table_size=(.-sys_call_table)
1199 diff -urNp linux-2.6.18/arch/i386/kernel/head.S linux-2.6.18/arch/i386/kernel/head.S
1200 --- linux-2.6.18/arch/i386/kernel/head.S        2006-09-19 23:42:06.000000000 -0400
1201 +++ linux-2.6.18/arch/i386/kernel/head.S        2006-09-22 20:45:03.000000000 -0400
1202 @@ -45,6 +45,16 @@
1203   */
1204  #define INIT_MAP_BEYOND_END    (128*1024)
1205  
1206 +#ifdef CONFIG_PAX_KERNEXEC
1207 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1208 +.fill 4096,1,0xcc
1209 +#endif
1210 +
1211 +/*
1212 + * Real beginning of normal "text" segment
1213 + */
1214 +ENTRY(stext)
1215 +ENTRY(_stext)
1216  
1217  /*
1218   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
1219 @@ -66,6 +76,26 @@ ENTRY(startup_32)
1220         movl %eax,%fs
1221         movl %eax,%gs
1222  
1223 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1224 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1225 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1226 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0f300),%eax
1227 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_DEFAULT_USER_DS * 8 + 4)
1228 +#endif
1229 +
1230 +#ifdef CONFIG_PAX_KERNEXEC
1231 +       movl $ __KERNEL_TEXT_OFFSET,%eax
1232 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1233 +       rorl $16,%eax
1234 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1235 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1236 +
1237 +       movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
1238 +       movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
1239 +       rorl $16,%eax
1240 +       movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
1241 +#endif
1242 +
1243  /*
1244   * Clear BSS first so that there are no surprises...
1245   * No need to cld as DF is already clear from cld above...
1246 @@ -113,24 +143,42 @@ ENTRY(startup_32)
1247   * Warning: don't use %esi or the stack in this code.  However, %esp
1248   * can be used as a GPR if you really need it...
1249   */
1250 -page_pde_offset = (__PAGE_OFFSET >> 20);
1251 -
1252 +#ifdef CONFIG_X86_PAE
1253 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
1254 +#else
1255 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
1256 +#endif
1257         movl $(pg0 - __PAGE_OFFSET), %edi
1258 +#ifdef CONFIG_X86_PAE
1259 +       movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1260 +#else
1261         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1262 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
1263 +#endif
1264 +       movl $0x063, %eax                       /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1265  10:
1266 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
1267 +       leal 0x063(%edi),%ecx                   /* Create PDE entry */
1268         movl %ecx,(%edx)                        /* Store identity PDE entry */
1269         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
1270 +#ifdef CONFIG_X86_PAE
1271 +       movl $0,4(%edx)
1272 +       movl $0,page_pde_offset+4(%edx)
1273 +       addl $8,%edx
1274 +       movl $512, %ecx
1275 +#else
1276         addl $4,%edx
1277         movl $1024, %ecx
1278 +#endif
1279  11:
1280         stosl
1281 +#ifdef CONFIG_X86_PAE
1282 +       movl $0,(%edi)
1283 +       addl $4,%edi
1284 +#endif
1285         addl $0x1000,%eax
1286         loop 11b
1287         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1288 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1289 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1290 +       /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1291 +       leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1292         cmpl %ebp,%eax
1293         jb 10b
1294         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1295 @@ -153,6 +201,11 @@ ENTRY(startup_32_smp)
1296         movl %eax,%fs
1297         movl %eax,%gs
1298  
1299 +       /* This is a secondary processor (AP) */
1300 +       xorl %ebx,%ebx
1301 +       incl %ebx
1302 +#endif /* CONFIG_SMP */
1303 +
1304  /*
1305   *     New page tables may be in 4Mbyte page mode and may
1306   *     be using the global pages. 
1307 @@ -168,26 +221,27 @@ ENTRY(startup_32_smp)
1308   *     not yet offset PAGE_OFFSET..
1309   */
1310  #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1311 +3:
1312         movl cr4_bits,%edx
1313         andl %edx,%edx
1314 -       jz 6f
1315 +       jz 5f
1316         movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
1317         orl %edx,%eax
1318         movl %eax,%cr4
1319  
1320 -       btl $5, %eax            # check if PAE is enabled
1321 -       jnc 6f
1322 +#ifdef CONFIG_X86_PAE
1323 +       movl %ebx,%edi
1324  
1325         /* Check if extended functions are implemented */
1326         movl $0x80000000, %eax
1327         cpuid
1328         cmpl $0x80000000, %eax
1329 -       jbe 6f
1330 +       jbe 4f
1331         mov $0x80000001, %eax
1332         cpuid
1333         /* Execute Disable bit supported? */
1334         btl $20, %edx
1335 -       jnc 6f
1336 +       jnc 4f
1337  
1338         /* Setup EFER (Extended Feature Enable Register) */
1339         movl $0xc0000080, %ecx
1340 @@ -196,14 +250,12 @@ ENTRY(startup_32_smp)
1341         btsl $11, %eax
1342         /* Make changes effective */
1343         wrmsr
1344 +       btsl $63,__supported_pte_mask-__PAGE_OFFSET
1345  
1346 -6:
1347 -       /* This is a secondary processor (AP) */
1348 -       xorl %ebx,%ebx
1349 -       incl %ebx
1350 -
1351 -3:
1352 -#endif /* CONFIG_SMP */
1353 +4:
1354 +       movl %edi,%ebx
1355 +#endif
1356 +5:
1357  
1358  /*
1359   * Enable paging
1360 @@ -228,9 +280,7 @@ ENTRY(startup_32_smp)
1361  
1362  #ifdef CONFIG_SMP
1363         andl %ebx,%ebx
1364 -       jz  1f                          /* Initial CPU cleans BSS */
1365 -       jmp checkCPUtype
1366 -1:
1367 +       jnz checkCPUtype        /* Initial CPU cleans BSS */
1368  #endif /* CONFIG_SMP */
1369  
1370  /*
1371 @@ -307,8 +357,6 @@ is386:      movl $2,%ecx            # set MP
1372         ljmp $(__KERNEL_CS),$1f
1373  1:     movl $(__KERNEL_DS),%eax        # reload all the segment registers
1374         movl %eax,%ss                   # after changing gdt.
1375 -
1376 -       movl $(__USER_DS),%eax          # DS/ES contains default USER segment
1377         movl %eax,%ds
1378         movl %eax,%es
1379  
1380 @@ -376,63 +424,71 @@ rp_sidt:
1381  /* This is the default interrupt "handler" :-) */
1382         ALIGN
1383  ignore_int:
1384 -       cld
1385  #ifdef CONFIG_PRINTK
1386 -       pushl %eax
1387 -       pushl %ecx
1388 -       pushl %edx
1389 -       pushl %es
1390 -       pushl %ds
1391 +       cld
1392         movl $(__KERNEL_DS),%eax
1393         movl %eax,%ds
1394         movl %eax,%es
1395 -       pushl 16(%esp)
1396 -       pushl 24(%esp)
1397 -       pushl 32(%esp)
1398 -       pushl 40(%esp)
1399 +       pushl 12(%esp)
1400 +       pushl 12(%esp)
1401 +       pushl 12(%esp)
1402 +       pushl 12(%esp)
1403         pushl $int_msg
1404  #ifdef CONFIG_EARLY_PRINTK
1405         call early_printk
1406  #else
1407         call printk
1408  #endif
1409 -       addl $(5*4),%esp
1410 -       popl %ds
1411 -       popl %es
1412 -       popl %edx
1413 -       popl %ecx
1414 -       popl %eax
1415  #endif
1416 -       iret
1417 +1:     hlt
1418 +       jmp 1b
1419  
1420 -/*
1421 - * Real beginning of normal "text" segment
1422 - */
1423 -ENTRY(stext)
1424 -ENTRY(_stext)
1425 -
1426 -/*
1427 - * BSS section
1428 - */
1429 -.section ".bss.page_aligned","w"
1430 +.section .swapper_pg_dir,"a",@progbits
1431  ENTRY(swapper_pg_dir)
1432 +#ifdef CONFIG_X86_PAE
1433 +       .long swapper_pm_dir-__PAGE_OFFSET+1
1434 +       .long 0
1435 +       .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1436 +       .long 0
1437 +       .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1438 +       .long 0
1439 +       .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1440 +       .long 0
1441 +#else
1442         .fill 1024,4,0
1443 +#endif
1444 +
1445 +#ifdef CONFIG_X86_PAE
1446 +.section .swapper_pm_dir,"a",@progbits
1447 +ENTRY(swapper_pm_dir)
1448 +       .fill 512,8,0
1449 +       .fill 512,8,0
1450 +       .fill 512,8,0
1451 +       .fill 512,8,0
1452 +#endif
1453 +
1454 +.section .empty_zero_page,"a",@progbits
1455  ENTRY(empty_zero_page)
1456         .fill 4096,1,0
1457  
1458  /*
1459 - * This starts the data section.
1460 - */
1461 -.data
1462 + * The IDT has to be page-aligned to simplify the Pentium
1463 + * F0 0F bug workaround.. We have a special link segment
1464 + * for this.
1465 + */
1466 +.section .idt,"a",@progbits
1467 +ENTRY(idt_table)
1468 +       .fill 256,8,0
1469 +
1470 +.section .rodata,"a",@progbits
1471 +ready: .byte 0
1472  
1473  ENTRY(stack_start)
1474 -       .long init_thread_union+THREAD_SIZE
1475 +       .long init_thread_union+THREAD_SIZE-8
1476         .long __BOOT_DS
1477  
1478 -ready: .byte 0
1479 -
1480  int_msg:
1481 -       .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
1482 +       .asciz "Unknown interrupt, stack: %p %p %p %p\n"
1483  
1484  /*
1485   * The IDT and GDT 'descriptors' are a strange 48-bit object
1486 @@ -458,10 +514,12 @@ idt_descr:
1487  
1488  # boot GDT descriptor (later on used by CPU#0):
1489         .word 0                         # 32 bit align gdt_desc.address
1490 -cpu_gdt_descr:
1491 +ENTRY(cpu_gdt_descr)
1492         .word GDT_ENTRIES*8-1
1493         .long cpu_gdt_table
1494  
1495 +       .fill NR_CPUS*8-6,1,0           # space for the other GDT descriptors
1496 +
1497  /*
1498   * The boot_gdt_table must mirror the equivalent in setup.S and is
1499   * used only for booting.
1500 @@ -469,13 +527,13 @@ cpu_gdt_descr:
1501         .align L1_CACHE_BYTES
1502  ENTRY(boot_gdt_table)
1503         .fill GDT_ENTRY_BOOT_CS,8,0
1504 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
1505 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
1506 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
1507 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
1508  
1509  /*
1510   * The Global Descriptor Table contains 28 quadwords, per-CPU.
1511   */
1512 -       .align L1_CACHE_BYTES
1513 +       .align PAGE_SIZE_asm
1514  ENTRY(cpu_gdt_table)
1515         .quad 0x0000000000000000        /* NULL descriptor */
1516         .quad 0x0000000000000000        /* 0x0b reserved */
1517 @@ -490,10 +548,10 @@ ENTRY(cpu_gdt_table)
1518         .quad 0x0000000000000000        /* 0x53 reserved */
1519         .quad 0x0000000000000000        /* 0x5b reserved */
1520  
1521 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1522 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1523 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1524 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1525 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1526 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1527 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1528 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1529  
1530         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
1531         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
1532 @@ -503,24 +561,30 @@ ENTRY(cpu_gdt_table)
1533          * They code segments and data segments have fixed 64k limits,
1534          * the transfer segment sizes are set at run time.
1535          */
1536 -       .quad 0x00409a000000ffff        /* 0x90 32-bit code */
1537 -       .quad 0x00009a000000ffff        /* 0x98 16-bit code */
1538 -       .quad 0x000092000000ffff        /* 0xa0 16-bit data */
1539 -       .quad 0x0000920000000000        /* 0xa8 16-bit data */
1540 -       .quad 0x0000920000000000        /* 0xb0 16-bit data */
1541 +       .quad 0x00409b000000ffff        /* 0x90 32-bit code */
1542 +       .quad 0x00009b000000ffff        /* 0x98 16-bit code */
1543 +       .quad 0x000093000000ffff        /* 0xa0 16-bit data */
1544 +       .quad 0x0000930000000000        /* 0xa8 16-bit data */
1545 +       .quad 0x0000930000000000        /* 0xb0 16-bit data */
1546  
1547         /*
1548          * The APM segments have byte granularity and their bases
1549          * are set at run time.  All have 64k limits.
1550          */
1551 -       .quad 0x00409a000000ffff        /* 0xb8 APM CS    code */
1552 -       .quad 0x00009a000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1553 -       .quad 0x004092000000ffff        /* 0xc8 APM DS    data */
1554 +       .quad 0x00409b000000ffff        /* 0xb8 APM CS    code */
1555 +       .quad 0x00009b000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1556 +       .quad 0x004093000000ffff        /* 0xc8 APM DS    data */
1557  
1558 -       .quad 0x0000920000000000        /* 0xd0 - ESPFIX 16-bit SS */
1559 +       .quad 0x0000930000000000        /* 0xd0 - ESPFIX 16-bit SS */
1560         .quad 0x0000000000000000        /* 0xd8 - unused */
1561         .quad 0x0000000000000000        /* 0xe0 - unused */
1562         .quad 0x0000000000000000        /* 0xe8 - unused */
1563         .quad 0x0000000000000000        /* 0xf0 - unused */
1564         .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
1565  
1566 +       /* Be sure this is zeroed to avoid false validations in Xen */
1567 +       .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
1568 +
1569 +#ifdef CONFIG_SMP
1570 +       .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
1571 +#endif
1572 diff -urNp linux-2.6.18/arch/i386/kernel/i386_ksyms.c linux-2.6.18/arch/i386/kernel/i386_ksyms.c
1573 --- linux-2.6.18/arch/i386/kernel/i386_ksyms.c  2006-09-19 23:42:06.000000000 -0400
1574 +++ linux-2.6.18/arch/i386/kernel/i386_ksyms.c  2006-09-22 20:45:03.000000000 -0400
1575 @@ -2,12 +2,16 @@
1576  #include <asm/checksum.h>
1577  #include <asm/desc.h>
1578  
1579 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
1580 +
1581  EXPORT_SYMBOL(__down_failed);
1582  EXPORT_SYMBOL(__down_failed_interruptible);
1583  EXPORT_SYMBOL(__down_failed_trylock);
1584  EXPORT_SYMBOL(__up_wakeup);
1585  /* Networking helper routines. */
1586  EXPORT_SYMBOL(csum_partial_copy_generic);
1587 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
1588 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
1589  
1590  EXPORT_SYMBOL(__get_user_1);
1591  EXPORT_SYMBOL(__get_user_2);
1592 diff -urNp linux-2.6.18/arch/i386/kernel/init_task.c linux-2.6.18/arch/i386/kernel/init_task.c
1593 --- linux-2.6.18/arch/i386/kernel/init_task.c   2006-09-19 23:42:06.000000000 -0400
1594 +++ linux-2.6.18/arch/i386/kernel/init_task.c   2006-09-22 20:45:03.000000000 -0400
1595 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
1596   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
1597   * no more per-task TSS's.
1598   */ 
1599 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
1600 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
1601  
1602 diff -urNp linux-2.6.18/arch/i386/kernel/io_apic.c linux-2.6.18/arch/i386/kernel/io_apic.c
1603 --- linux-2.6.18/arch/i386/kernel/io_apic.c     2006-09-19 23:42:06.000000000 -0400
1604 +++ linux-2.6.18/arch/i386/kernel/io_apic.c     2006-09-22 20:45:03.000000000 -0400
1605 @@ -272,8 +272,8 @@ static void set_ioapic_affinity_irq(unsi
1606  #  define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
1607  #  define Dprintk(x...) do { TDprintk(x); } while (0)
1608  # else
1609 -#  define TDprintk(x...) 
1610 -#  define Dprintk(x...) 
1611 +#  define TDprintk(x...) do {} while (0)
1612 +#  define Dprintk(x...) do {} while (0)
1613  # endif
1614  
1615  #define IRQBALANCE_CHECK_ARCH -999
1616 diff -urNp linux-2.6.18/arch/i386/kernel/ioport.c linux-2.6.18/arch/i386/kernel/ioport.c
1617 --- linux-2.6.18/arch/i386/kernel/ioport.c      2006-09-19 23:42:06.000000000 -0400
1618 +++ linux-2.6.18/arch/i386/kernel/ioport.c      2006-09-22 20:45:03.000000000 -0400
1619 @@ -16,6 +16,7 @@
1620  #include <linux/stddef.h>
1621  #include <linux/slab.h>
1622  #include <linux/thread_info.h>
1623 +#include <linux/grsecurity.h>
1624  
1625  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
1626  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
1627 @@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
1628  
1629         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
1630                 return -EINVAL;
1631 +#ifdef CONFIG_GRKERNSEC_IO
1632 +       if (turn_on) {
1633 +               gr_handle_ioperm();
1634 +#else
1635         if (turn_on && !capable(CAP_SYS_RAWIO))
1636 +#endif
1637                 return -EPERM;
1638 -
1639 +#ifdef CONFIG_GRKERNSEC_IO
1640 +       }
1641 +#endif
1642         /*
1643          * If it's the first ioperm() call in this thread's lifetime, set the
1644          * IO bitmap up. ioperm() is much less timing critical than clone(),
1645 @@ -89,7 +97,7 @@ asmlinkage long sys_ioperm(unsigned long
1646          * because the ->io_bitmap_max value must match the bitmap
1647          * contents:
1648          */
1649 -       tss = &per_cpu(init_tss, get_cpu());
1650 +       tss = init_tss + get_cpu();
1651  
1652         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
1653  
1654 @@ -143,8 +151,13 @@ asmlinkage long sys_iopl(unsigned long u
1655                 return -EINVAL;
1656         /* Trying to gain more privileges? */
1657         if (level > old) {
1658 +#ifdef CONFIG_GRKERNSEC_IO
1659 +               gr_handle_iopl();
1660 +               return -EPERM;
1661 +#else
1662                 if (!capable(CAP_SYS_RAWIO))
1663                         return -EPERM;
1664 +#endif
1665         }
1666         t->iopl = level << 12;
1667         regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
1668 diff -urNp linux-2.6.18/arch/i386/kernel/irq.c linux-2.6.18/arch/i386/kernel/irq.c
1669 --- linux-2.6.18/arch/i386/kernel/irq.c 2006-09-19 23:42:06.000000000 -0400
1670 +++ linux-2.6.18/arch/i386/kernel/irq.c 2006-09-22 20:45:03.000000000 -0400
1671 @@ -97,7 +97,7 @@ fastcall unsigned int do_IRQ(struct pt_r
1672                 int arg1, arg2, ebx;
1673  
1674                 /* build the stack frame on the IRQ stack */
1675 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1676 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1677                 irqctx->tinfo.task = curctx->tinfo.task;
1678                 irqctx->tinfo.previous_esp = current_stack_pointer;
1679  
1680 @@ -133,10 +133,10 @@ fastcall unsigned int do_IRQ(struct pt_r
1681   * gcc's 3.0 and earlier don't handle that correctly.
1682   */
1683  static char softirq_stack[NR_CPUS * THREAD_SIZE]
1684 -               __attribute__((__aligned__(THREAD_SIZE)));
1685 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1686  
1687  static char hardirq_stack[NR_CPUS * THREAD_SIZE]
1688 -               __attribute__((__aligned__(THREAD_SIZE)));
1689 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1690  
1691  /*
1692   * allocate per-cpu stacks for hardirq and for softirq processing
1693 @@ -196,7 +196,7 @@ asmlinkage void do_softirq(void)
1694                 irqctx->tinfo.previous_esp = current_stack_pointer;
1695  
1696                 /* build the stack frame on the softirq stack */
1697 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1698 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1699  
1700                 asm volatile(
1701                         "       xchgl   %%ebx,%%esp     \n"
1702 diff -urNp linux-2.6.18/arch/i386/kernel/kprobes.c linux-2.6.18/arch/i386/kernel/kprobes.c
1703 --- linux-2.6.18/arch/i386/kernel/kprobes.c     2006-09-19 23:42:06.000000000 -0400
1704 +++ linux-2.6.18/arch/i386/kernel/kprobes.c     2006-09-22 20:45:03.000000000 -0400
1705 @@ -648,7 +648,7 @@ int __kprobes kprobe_exceptions_notify(s
1706         struct die_args *args = (struct die_args *)data;
1707         int ret = NOTIFY_DONE;
1708  
1709 -       if (args->regs && user_mode_vm(args->regs))
1710 +       if (args->regs && user_mode(args->regs))
1711                 return ret;
1712  
1713         switch (val) {
1714 diff -urNp linux-2.6.18/arch/i386/kernel/ldt.c linux-2.6.18/arch/i386/kernel/ldt.c
1715 --- linux-2.6.18/arch/i386/kernel/ldt.c 2006-09-19 23:42:06.000000000 -0400
1716 +++ linux-2.6.18/arch/i386/kernel/ldt.c 2006-09-22 20:45:03.000000000 -0400
1717 @@ -103,6 +103,19 @@ int init_new_context(struct task_struct 
1718                 retval = copy_ldt(&mm->context, &old_mm->context);
1719                 up(&old_mm->context.sem);
1720         }
1721 +
1722 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1723 +       if (!mm->context.user_cs_limit) {
1724 +               mm->context.user_cs_base = 0UL;
1725 +               mm->context.user_cs_limit = ~0UL;
1726 +
1727 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
1728 +               cpus_clear(mm->context.cpu_user_cs_mask);
1729 +#endif
1730 +
1731 +       }
1732 +#endif
1733 +
1734         return retval;
1735  }
1736  
1737 @@ -160,7 +173,7 @@ static int read_default_ldt(void __user 
1738  {
1739         int err;
1740         unsigned long size;
1741 -       void *address;
1742 +       const void *address;
1743  
1744         err = 0;
1745         address = &default_ldt[0];
1746 @@ -215,6 +228,13 @@ static int write_ldt(void __user * ptr, 
1747                 }
1748         }
1749  
1750 +#ifdef CONFIG_PAX_SEGMEXEC
1751 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
1752 +               error = -EINVAL;
1753 +               goto out_unlock;
1754 +       }
1755 +#endif
1756 +
1757         entry_1 = LDT_entry_a(&ldt_info);
1758         entry_2 = LDT_entry_b(&ldt_info);
1759         if (oldmode)
1760 diff -urNp linux-2.6.18/arch/i386/kernel/module.c linux-2.6.18/arch/i386/kernel/module.c
1761 --- linux-2.6.18/arch/i386/kernel/module.c      2006-09-19 23:42:06.000000000 -0400
1762 +++ linux-2.6.18/arch/i386/kernel/module.c      2006-09-22 20:45:03.000000000 -0400
1763 @@ -21,6 +21,7 @@
1764  #include <linux/fs.h>
1765  #include <linux/string.h>
1766  #include <linux/kernel.h>
1767 +#include <asm/desc.h>
1768  
1769  #if 0
1770  #define DEBUGP printk
1771 @@ -32,9 +33,30 @@ void *module_alloc(unsigned long size)
1772  {
1773         if (size == 0)
1774                 return NULL;
1775 +
1776 +#ifdef CONFIG_PAX_KERNEXEC
1777 +       return vmalloc(size);
1778 +#else
1779         return vmalloc_exec(size);
1780 +#endif
1781 +
1782  }
1783  
1784 +#ifdef CONFIG_PAX_KERNEXEC
1785 +void *module_alloc_exec(unsigned long size)
1786 +{
1787 +       struct vm_struct *area;
1788 +
1789 +       if (size == 0)
1790 +               return NULL;
1791 +
1792 +       area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
1793 +       if (area)
1794 +               return area->addr;
1795 +
1796 +       return NULL;
1797 +}
1798 +#endif
1799  
1800  /* Free memory returned from module_alloc */
1801  void module_free(struct module *mod, void *module_region)
1802 @@ -44,6 +66,45 @@ void module_free(struct module *mod, voi
1803             table entries. */
1804  }
1805  
1806 +#ifdef CONFIG_PAX_KERNEXEC
1807 +void module_free_exec(struct module *mod, void *module_region)
1808 +{
1809 +       struct vm_struct **p, *tmp;
1810 +
1811 +       if (!module_region)
1812 +               return;
1813 +
1814 +       if ((PAGE_SIZE-1) & (unsigned long)module_region) {
1815 +               printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
1816 +               WARN_ON(1);
1817 +               return;
1818 +       }
1819 +
1820 +       write_lock(&vmlist_lock);
1821 +       for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
1822 +                if (tmp->addr == module_region)
1823 +                       break;
1824 +
1825 +       if (tmp) {
1826 +               unsigned long cr0;
1827 +
1828 +               pax_open_kernel(cr0);
1829 +               memset(tmp->addr, 0xCC, tmp->size);
1830 +               pax_close_kernel(cr0);
1831 +
1832 +               *p = tmp->next;
1833 +               kfree(tmp);
1834 +       }
1835 +       write_unlock(&vmlist_lock);
1836 +
1837 +       if (!tmp) {
1838 +               printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
1839 +                               module_region);
1840 +               WARN_ON(1);
1841 +       }
1842 +}
1843 +#endif
1844 +
1845  /* We don't need anything special. */
1846  int module_frob_arch_sections(Elf_Ehdr *hdr,
1847                               Elf_Shdr *sechdrs,
1848 @@ -62,14 +123,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1849         unsigned int i;
1850         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
1851         Elf32_Sym *sym;
1852 -       uint32_t *location;
1853 +       uint32_t *plocation, location;
1854  
1855         DEBUGP("Applying relocate section %u to %u\n", relsec,
1856                sechdrs[relsec].sh_info);
1857         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
1858                 /* This is where to make the change */
1859 -               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
1860 -                       + rel[i].r_offset;
1861 +               plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
1862 +               location = (uint32_t)plocation;
1863 +               if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
1864 +                       plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
1865                 /* This is the symbol it is referring to.  Note that all
1866                    undefined symbols have been resolved.  */
1867                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
1868 @@ -78,11 +141,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1869                 switch (ELF32_R_TYPE(rel[i].r_info)) {
1870                 case R_386_32:
1871                         /* We add the value into the location given */
1872 -                       *location += sym->st_value;
1873 +                       *plocation += sym->st_value;
1874                         break;
1875                 case R_386_PC32:
1876                         /* Add the value, subtract its postition */
1877 -                       *location += sym->st_value - (uint32_t)location;
1878 +                       *plocation += sym->st_value - location;
1879                         break;
1880                 default:
1881                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
1882 diff -urNp linux-2.6.18/arch/i386/kernel/process.c linux-2.6.18/arch/i386/kernel/process.c
1883 --- linux-2.6.18/arch/i386/kernel/process.c     2006-09-19 23:42:06.000000000 -0400
1884 +++ linux-2.6.18/arch/i386/kernel/process.c     2006-09-22 20:45:03.000000000 -0400
1885 @@ -68,7 +68,7 @@ EXPORT_SYMBOL(boot_option_idle_override)
1886   */
1887  unsigned long thread_saved_pc(struct task_struct *tsk)
1888  {
1889 -       return ((unsigned long *)tsk->thread.esp)[3];
1890 +       return tsk->thread.eip;
1891  }
1892  
1893  /*
1894 @@ -293,7 +293,7 @@ void show_regs(struct pt_regs * regs)
1895         printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
1896         print_symbol("EIP is at %s\n", regs->eip);
1897  
1898 -       if (user_mode_vm(regs))
1899 +       if (user_mode(regs))
1900                 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
1901         printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
1902                regs->eflags, print_tainted(), system_utsname.release,
1903 @@ -342,8 +342,8 @@ int kernel_thread(int (*fn)(void *), voi
1904         regs.ebx = (unsigned long) fn;
1905         regs.edx = (unsigned long) arg;
1906  
1907 -       regs.xds = __USER_DS;
1908 -       regs.xes = __USER_DS;
1909 +       regs.xds = __KERNEL_DS;
1910 +       regs.xes = __KERNEL_DS;
1911         regs.orig_eax = -1;
1912         regs.eip = (unsigned long) kernel_thread_helper;
1913         regs.xcs = __KERNEL_CS;
1914 @@ -364,7 +364,7 @@ void exit_thread(void)
1915                 struct task_struct *tsk = current;
1916                 struct thread_struct *t = &tsk->thread;
1917                 int cpu = get_cpu();
1918 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
1919 +               struct tss_struct *tss = init_tss + cpu;
1920  
1921                 kfree(t->io_bitmap_ptr);
1922                 t->io_bitmap_ptr = NULL;
1923 @@ -385,6 +385,9 @@ void flush_thread(void)
1924  {
1925         struct task_struct *tsk = current;
1926  
1927 +       __asm__("mov %0,%%fs\n"
1928 +               "mov %0,%%gs\n"
1929 +               : : "r" (0) : "memory");
1930         memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
1931         memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
1932         clear_tsk_thread_flag(tsk, TIF_DEBUG);
1933 @@ -418,7 +421,7 @@ int copy_thread(int nr, unsigned long cl
1934         struct task_struct *tsk;
1935         int err;
1936  
1937 -       childregs = task_pt_regs(p);
1938 +       childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
1939         *childregs = *regs;
1940         childregs->eax = 0;
1941         childregs->esp = esp;
1942 @@ -462,6 +465,11 @@ int copy_thread(int nr, unsigned long cl
1943                 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1944                         goto out;
1945  
1946 +#ifdef CONFIG_PAX_SEGMEXEC
1947 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1948 +                       goto out;
1949 +#endif
1950 +
1951                 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
1952                 desc->a = LDT_entry_a(&info);
1953                 desc->b = LDT_entry_b(&info);
1954 @@ -641,7 +649,11 @@ struct task_struct fastcall * __switch_t
1955         struct thread_struct *prev = &prev_p->thread,
1956                                  *next = &next_p->thread;
1957         int cpu = smp_processor_id();
1958 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1959 +       struct tss_struct *tss = init_tss + cpu;
1960 +
1961 +#ifdef CONFIG_PAX_KERNEXEC
1962 +       unsigned long cr0;
1963 +#endif
1964  
1965         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
1966  
1967 @@ -664,11 +676,23 @@ struct task_struct fastcall * __switch_t
1968         savesegment(fs, prev->fs);
1969         savesegment(gs, prev->gs);
1970  
1971 +#ifdef CONFIG_PAX_KERNEXEC
1972 +       pax_open_kernel(cr0);
1973 +#endif
1974 +
1975 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1976 +       __set_fs(get_fs(), cpu);
1977 +#endif
1978 +
1979         /*
1980          * Load the per-thread Thread-Local Storage descriptor.
1981          */
1982         load_TLS(next, cpu);
1983  
1984 +#ifdef CONFIG_PAX_KERNEXEC
1985 +       pax_close_kernel(cr0);
1986 +#endif
1987 +
1988         /*
1989          * Restore %fs and %gs if needed.
1990          *
1991 @@ -813,8 +837,18 @@ asmlinkage int sys_set_thread_area(struc
1992         struct desc_struct *desc;
1993         int cpu, idx;
1994  
1995 +#ifdef CONFIG_PAX_KERNEXEC
1996 +       unsigned long cr0;
1997 +#endif
1998 +
1999         if (copy_from_user(&info, u_info, sizeof(info)))
2000                 return -EFAULT;
2001 +
2002 +#ifdef CONFIG_PAX_SEGMEXEC
2003 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2004 +               return -EINVAL;
2005 +#endif
2006 +
2007         idx = info.entry_number;
2008  
2009         /*
2010 @@ -846,8 +880,17 @@ asmlinkage int sys_set_thread_area(struc
2011                 desc->a = LDT_entry_a(&info);
2012                 desc->b = LDT_entry_b(&info);
2013         }
2014 +
2015 +#ifdef CONFIG_PAX_KERNEXEC
2016 +       pax_open_kernel(cr0);
2017 +#endif
2018 +
2019         load_TLS(t, cpu);
2020  
2021 +#ifdef CONFIG_PAX_KERNEXEC
2022 +       pax_close_kernel(cr0);
2023 +#endif
2024 +
2025         put_cpu();
2026  
2027         return 0;
2028 @@ -903,9 +946,27 @@ asmlinkage int sys_get_thread_area(struc
2029         return 0;
2030  }
2031  
2032 -unsigned long arch_align_stack(unsigned long sp)
2033 +#ifdef CONFIG_PAX_RANDKSTACK
2034 +asmlinkage void pax_randomize_kstack(void)
2035  {
2036 -       if (randomize_va_space)
2037 -               sp -= get_random_int() % 8192;
2038 -       return sp & ~0xf;
2039 +       struct tss_struct *tss = init_tss + smp_processor_id();
2040 +       unsigned long time;
2041 +
2042 +       if (!randomize_va_space)
2043 +               return;
2044 +
2045 +       rdtscl(time);
2046 +
2047 +       /* P4 seems to return a 0 LSB, ignore it */
2048 +#ifdef CONFIG_MPENTIUM4
2049 +       time &= 0x1EUL;
2050 +       time <<= 2;
2051 +#else
2052 +       time &= 0xFUL;
2053 +       time <<= 3;
2054 +#endif
2055 +
2056 +       tss->esp0 ^= time;
2057 +       current->thread.esp0 = tss->esp0;
2058  }
2059 +#endif
2060 diff -urNp linux-2.6.18/arch/i386/kernel/ptrace.c linux-2.6.18/arch/i386/kernel/ptrace.c
2061 --- linux-2.6.18/arch/i386/kernel/ptrace.c      2006-09-19 23:42:06.000000000 -0400
2062 +++ linux-2.6.18/arch/i386/kernel/ptrace.c      2006-09-22 20:45:03.000000000 -0400
2063 @@ -17,6 +17,7 @@
2064  #include <linux/audit.h>
2065  #include <linux/seccomp.h>
2066  #include <linux/signal.h>
2067 +#include <linux/grsecurity.h>
2068  
2069  #include <asm/uaccess.h>
2070  #include <asm/pgtable.h>
2071 @@ -342,6 +343,11 @@ ptrace_set_thread_area(struct task_struc
2072         if (copy_from_user(&info, user_desc, sizeof(info)))
2073                 return -EFAULT;
2074  
2075 +#ifdef CONFIG_PAX_SEGMEXEC
2076 +       if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2077 +               return -EINVAL;
2078 +#endif
2079 +
2080         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2081                 return -EINVAL;
2082  
2083 @@ -432,6 +438,17 @@ long arch_ptrace(struct task_struct *chi
2084                           if(addr == (long) &dummy->u_debugreg[5]) break;
2085                           if(addr < (long) &dummy->u_debugreg[4] &&
2086                              ((unsigned long) data) >= TASK_SIZE-3) break;
2087 +
2088 +#ifdef CONFIG_GRKERNSEC
2089 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
2090 +                            addr <= (long) &dummy->u_debugreg[3]){
2091 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
2092 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
2093 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
2094 +                               if((type & 1) && (data & align))
2095 +                                       break;
2096 +                         }
2097 +#endif
2098                           
2099                           /* Sanity-check data. Take one half-byte at once with
2100                            * check = (val >> (16 + 4*i)) & 0xf. It contains the
2101 @@ -648,7 +665,7 @@ void send_sigtrap(struct task_struct *ts
2102         info.si_code = TRAP_BRKPT;
2103  
2104         /* User-mode eip? */
2105 -       info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2106 +       info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2107  
2108         /* Send us the fakey SIGTRAP */
2109         force_sig_info(SIGTRAP, &info, tsk);
2110 diff -urNp linux-2.6.18/arch/i386/kernel/reboot.c linux-2.6.18/arch/i386/kernel/reboot.c
2111 --- linux-2.6.18/arch/i386/kernel/reboot.c      2006-09-19 23:42:06.000000000 -0400
2112 +++ linux-2.6.18/arch/i386/kernel/reboot.c      2006-09-22 20:45:03.000000000 -0400
2113 @@ -24,7 +24,7 @@
2114  void (*pm_power_off)(void);
2115  EXPORT_SYMBOL(pm_power_off);
2116  
2117 -static int reboot_mode;
2118 +static unsigned short reboot_mode;
2119  static int reboot_thru_bios;
2120  
2121  #ifdef CONFIG_SMP
2122 @@ -137,18 +137,18 @@ core_initcall(reboot_init);
2123     doesn't work with at least one type of 486 motherboard.  It is easy
2124     to stop this code working; hence the copious comments. */
2125  
2126 -static unsigned long long
2127 +static const unsigned long long
2128  real_mode_gdt_entries [3] =
2129  {
2130         0x0000000000000000ULL,  /* Null descriptor */
2131 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
2132 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
2133 +       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
2134 +       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
2135  };
2136  
2137  static struct
2138  {
2139         unsigned short       size __attribute__ ((packed));
2140 -       unsigned long long * base __attribute__ ((packed));
2141 +       const unsigned long long * base __attribute__ ((packed));
2142  }
2143  real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
2144  real_mode_idt = { 0x3ff, NULL },
2145 @@ -174,7 +174,7 @@ no_idt = { 0, NULL };
2146     More could be done here to set up the registers as if a CPU reset had
2147     occurred; hopefully real BIOSs don't assume much. */
2148  
2149 -static unsigned char real_mode_switch [] =
2150 +static const unsigned char real_mode_switch [] =
2151  {
2152         0x66, 0x0f, 0x20, 0xc0,                 /*    movl  %cr0,%eax        */
2153         0x66, 0x83, 0xe0, 0x11,                 /*    andl  $0x00000011,%eax */
2154 @@ -188,7 +188,7 @@ static unsigned char real_mode_switch []
2155         0x24, 0x10,                             /* f: andb  $0x10,al         */
2156         0x66, 0x0f, 0x22, 0xc0                  /*    movl  %eax,%cr0        */
2157  };
2158 -static unsigned char jump_to_bios [] =
2159 +static const unsigned char jump_to_bios [] =
2160  {
2161         0xea, 0x00, 0x00, 0xff, 0xff            /*    ljmp  $0xffff,$0x0000  */
2162  };
2163 @@ -198,10 +198,14 @@ static unsigned char jump_to_bios [] =
2164   * specified by the code and length parameters.
2165   * We assume that length will aways be less that 100!
2166   */
2167 -void machine_real_restart(unsigned char *code, int length)
2168 +void machine_real_restart(const unsigned char *code, unsigned int length)
2169  {
2170         unsigned long flags;
2171  
2172 +#ifdef CONFIG_PAX_KERNEXEC
2173 +       unsigned long cr0;
2174 +#endif
2175 +
2176         local_irq_disable();
2177  
2178         /* Write zero to CMOS register number 0x0f, which the BIOS POST
2179 @@ -222,8 +226,16 @@ void machine_real_restart(unsigned char 
2180            from the kernel segment.  This assumes the kernel segment starts at
2181            virtual address PAGE_OFFSET. */
2182  
2183 -       memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2184 -               sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2185 +#ifdef CONFIG_PAX_KERNEXEC
2186 +       pax_open_kernel(cr0);
2187 +#endif
2188 +
2189 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2190 +                       USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
2191 +
2192 +#ifdef CONFIG_PAX_KERNEXEC
2193 +       pax_close_kernel(cr0);
2194 +#endif
2195  
2196         /*
2197          * Use `swapper_pg_dir' as our page directory.
2198 @@ -236,7 +248,7 @@ void machine_real_restart(unsigned char 
2199            REBOOT.COM programs, and the previous reset routine did this
2200            too. */
2201  
2202 -       *((unsigned short *)0x472) = reboot_mode;
2203 +       __put_user(reboot_mode, (unsigned short __user *)0x472);
2204  
2205         /* For the switch to real mode, copy some code to low memory.  It has
2206            to be in the first 64k because it is running in 16-bit mode, and it
2207 @@ -244,9 +256,9 @@ void machine_real_restart(unsigned char 
2208            off paging.  Copy it near the end of the first page, out of the way
2209            of BIOS variables. */
2210  
2211 -       memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
2212 +       flags = __copy_to_user ((void __user *) (0x1000 - sizeof (real_mode_switch) - 100),
2213                 real_mode_switch, sizeof (real_mode_switch));
2214 -       memcpy ((void *) (0x1000 - 100), code, length);
2215 +       flags = __copy_to_user ((void __user *) (0x1000 - 100), code, length);
2216  
2217         /* Set up the IDT for real mode. */
2218  
2219 @@ -328,7 +340,7 @@ void machine_emergency_restart(void)
2220                         __asm__ __volatile__("int3");
2221                 }
2222                 /* rebooting needs to touch the page at absolute addr 0 */
2223 -               *((unsigned short *)__va(0x472)) = reboot_mode;
2224 +               __put_user(reboot_mode, (unsigned short __user *)0x472);
2225                 for (;;) {
2226                         mach_reboot_fixups(); /* for board specific fixups */
2227                         mach_reboot();
2228 diff -urNp linux-2.6.18/arch/i386/kernel/setup.c linux-2.6.18/arch/i386/kernel/setup.c
2229 --- linux-2.6.18/arch/i386/kernel/setup.c       2006-09-19 23:42:06.000000000 -0400
2230 +++ linux-2.6.18/arch/i386/kernel/setup.c       2006-09-22 20:45:03.000000000 -0400
2231 @@ -87,7 +87,11 @@ struct cpuinfo_x86 new_cpu_data __initda
2232  struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2233  EXPORT_SYMBOL(boot_cpu_data);
2234  
2235 +#ifdef CONFIG_X86_PAE
2236 +unsigned long mmu_cr4_features = X86_CR4_PAE;
2237 +#else
2238  unsigned long mmu_cr4_features;
2239 +#endif
2240  
2241  #ifdef CONFIG_ACPI
2242         int acpi_disabled = 0;
2243 @@ -1489,14 +1493,14 @@ void __init setup_arch(char **cmdline_p)
2244  
2245         if (!MOUNT_ROOT_RDONLY)
2246                 root_mountflags &= ~MS_RDONLY;
2247 -       init_mm.start_code = (unsigned long) _text;
2248 -       init_mm.end_code = (unsigned long) _etext;
2249 +       init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2250 +       init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2251         init_mm.end_data = (unsigned long) _edata;
2252         init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2253  
2254 -       code_resource.start = virt_to_phys(_text);
2255 -       code_resource.end = virt_to_phys(_etext)-1;
2256 -       data_resource.start = virt_to_phys(_etext);
2257 +       code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
2258 +       code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
2259 +       data_resource.start = virt_to_phys(_data);
2260         data_resource.end = virt_to_phys(_edata)-1;
2261  
2262         parse_cmdline_early(cmdline_p);
2263 diff -urNp linux-2.6.18/arch/i386/kernel/signal.c linux-2.6.18/arch/i386/kernel/signal.c
2264 --- linux-2.6.18/arch/i386/kernel/signal.c      2006-09-19 23:42:06.000000000 -0400
2265 +++ linux-2.6.18/arch/i386/kernel/signal.c      2006-09-22 20:45:03.000000000 -0400
2266 @@ -447,6 +447,7 @@ static int setup_rt_frame(int sig, struc
2267                 goto give_sigsegv;
2268  
2269         /* Set up to return from userspace.  */
2270 +
2271         restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
2272         if (ka->sa.sa_flags & SA_RESTORER)
2273                 restorer = ka->sa.sa_restorer;
2274 @@ -580,7 +581,7 @@ static void fastcall do_signal(struct pt
2275          * before reaching here, so testing against kernel
2276          * CS suffices.
2277          */
2278 -       if (!user_mode(regs))
2279 +       if (!user_mode_novm(regs))
2280                 return;
2281  
2282         if (test_thread_flag(TIF_RESTORE_SIGMASK))
2283 diff -urNp linux-2.6.18/arch/i386/kernel/smpboot.c linux-2.6.18/arch/i386/kernel/smpboot.c
2284 --- linux-2.6.18/arch/i386/kernel/smpboot.c     2006-09-19 23:42:06.000000000 -0400
2285 +++ linux-2.6.18/arch/i386/kernel/smpboot.c     2006-09-22 20:45:03.000000000 -0400
2286 @@ -1055,7 +1055,6 @@ static int __cpuinit __smp_prepare_cpu(i
2287         struct warm_boot_cpu_info info;
2288         struct work_struct task;
2289         int     apicid, ret;
2290 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
2291  
2292         apicid = x86_cpu_to_apicid[cpu];
2293         if (apicid == BAD_APICID) {
2294 @@ -1067,13 +1066,7 @@ static int __cpuinit __smp_prepare_cpu(i
2295          * the CPU isn't initialized at boot time, allocate gdt table here.
2296          * cpu_init will initialize it
2297          */
2298 -       if (!cpu_gdt_descr->address) {
2299 -               cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL);
2300 -               if (!cpu_gdt_descr->address)
2301 -                       printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
2302 -                       ret = -ENOMEM;
2303 -                       goto exit;
2304 -       }
2305 +       cpu_gdt_descr[cpu].address = get_cpu_gdt_table(cpu);
2306  
2307         info.complete = &done;
2308         info.apicid = apicid;
2309 @@ -1084,7 +1077,7 @@ static int __cpuinit __smp_prepare_cpu(i
2310  
2311         /* init low mem mapping */
2312         clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2313 -                       KERNEL_PGD_PTRS);
2314 +                       USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
2315         flush_tlb_all();
2316         schedule_work(&task);
2317         wait_for_completion(&done);
2318 diff -urNp linux-2.6.18/arch/i386/kernel/syscall_table.S linux-2.6.18/arch/i386/kernel/syscall_table.S
2319 --- linux-2.6.18/arch/i386/kernel/syscall_table.S       2006-09-19 23:42:06.000000000 -0400
2320 +++ linux-2.6.18/arch/i386/kernel/syscall_table.S       2006-09-22 20:45:03.000000000 -0400
2321 @@ -1,3 +1,4 @@
2322 +.section .rodata,"a",@progbits
2323  ENTRY(sys_call_table)
2324         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
2325         .long sys_exit
2326 diff -urNp linux-2.6.18/arch/i386/kernel/sysenter.c linux-2.6.18/arch/i386/kernel/sysenter.c
2327 --- linux-2.6.18/arch/i386/kernel/sysenter.c    2006-09-19 23:42:06.000000000 -0400
2328 +++ linux-2.6.18/arch/i386/kernel/sysenter.c    2006-09-22 20:45:03.000000000 -0400
2329 @@ -45,7 +45,7 @@ extern asmlinkage void sysenter_entry(vo
2330  void enable_sep_cpu(void)
2331  {
2332         int cpu = get_cpu();
2333 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2334 +       struct tss_struct *tss = init_tss + cpu;
2335  
2336         if (!boot_cpu_has(X86_FEATURE_SEP)) {
2337                 put_cpu();
2338 @@ -125,16 +125,36 @@ int arch_setup_additional_pages(struct l
2339         unsigned long addr;
2340         int ret;
2341  
2342 +#ifdef CONFIG_PAX_SEGMEXEC
2343 +       struct vm_area_struct *vma_m = NULL;
2344 +#endif
2345 +
2346 +       vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
2347 +       if (!vma)
2348 +               return -ENOMEM;
2349 +
2350 +#ifdef CONFIG_PAX_SEGMEXEC
2351 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
2352 +               vma_m = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
2353 +               if (!vma_m) {
2354 +                       kmem_cache_free(vm_area_cachep, vma);
2355 +                       return -ENOMEM;
2356 +               }
2357 +       }
2358 +#endif
2359 +
2360         down_write(&mm->mmap_sem);
2361 -       addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
2362 +       addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
2363         if (IS_ERR_VALUE(addr)) {
2364                 ret = addr;
2365 -               goto up_fail;
2366 -       }
2367  
2368 -       vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
2369 -       if (!vma) {
2370 -               ret = -ENOMEM;
2371 +               kmem_cache_free(vm_area_cachep, vma);
2372 +
2373 +#ifdef CONFIG_PAX_SEGMEXEC
2374 +               if (vma_m)
2375 +                       kmem_cache_free(vm_area_cachep, vma_m);
2376 +#endif
2377 +
2378                 goto up_fail;
2379         }
2380  
2381 @@ -142,17 +162,48 @@ int arch_setup_additional_pages(struct l
2382         vma->vm_end = addr + PAGE_SIZE;
2383         /* MAYWRITE to allow gdb to COW and set breakpoints */
2384         vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
2385 +
2386 +#ifdef CONFIG_PAX_MPROTECT
2387 +       if (mm->pax_flags & MF_PAX_MPROTECT)
2388 +               vma->vm_flags &= ~VM_MAYWRITE;
2389 +#endif
2390 +
2391         vma->vm_flags |= mm->def_flags;
2392 -       vma->vm_page_prot = protection_map[vma->vm_flags & 7];
2393 +       vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
2394         vma->vm_ops = &syscall_vm_ops;
2395         vma->vm_mm = mm;
2396  
2397         ret = insert_vm_struct(mm, vma);
2398         if (unlikely(ret)) {
2399                 kmem_cache_free(vm_area_cachep, vma);
2400 +
2401 +#ifdef CONFIG_PAX_SEGMEXEC
2402 +               if (vma_m)
2403 +                       kmem_cache_free(vm_area_cachep, vma_m);
2404 +#endif
2405 +
2406                 goto up_fail;
2407         }
2408  
2409 +#ifdef CONFIG_PAX_SEGMEXEC
2410 +       if (vma_m) {
2411 +               *vma_m = *vma;
2412 +               vma_m->vm_start += SEGMEXEC_TASK_SIZE;
2413 +               vma_m->vm_end += SEGMEXEC_TASK_SIZE;
2414 +               ret = insert_vm_struct(mm, vma_m);
2415 +               if (unlikely(ret)) {
2416 +                       kmem_cache_free(vm_area_cachep, vma_m);
2417 +                       goto up_fail;
2418 +               }
2419 +               vma_m->vm_flags |= VM_MIRROR;
2420 +               vma->vm_flags |= VM_MIRROR;
2421 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
2422 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
2423 +               vma_m->vm_pgoff = vma->vm_pgoff;
2424 +               mm->total_vm++;
2425 +       }
2426 +#endif
2427 +
2428         current->mm->context.vdso = (void *)addr;
2429         current_thread_info()->sysenter_return =
2430                                     (void *)VDSO_SYM(&SYSENTER_RETURN);
2431 @@ -164,8 +215,17 @@ up_fail:
2432  
2433  const char *arch_vma_name(struct vm_area_struct *vma)
2434  {
2435 -       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
2436 +       if (vma->vm_start == (unsigned long)vma->vm_mm->context.vdso)
2437                 return "[vdso]";
2438 +
2439 +#ifdef CONFIG_PAX_SEGMEXEC
2440 +       if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_MIRROR))
2441 +               return NULL;
2442 +
2443 +       if (vma->vm_start + vma->vm_mirror == (unsigned long)vma->vm_mm->context.vdso)
2444 +               return "[vdso]";
2445 +#endif
2446 +
2447         return NULL;
2448  }
2449  
2450 diff -urNp linux-2.6.18/arch/i386/kernel/sys_i386.c linux-2.6.18/arch/i386/kernel/sys_i386.c
2451 --- linux-2.6.18/arch/i386/kernel/sys_i386.c    2006-09-19 23:42:06.000000000 -0400
2452 +++ linux-2.6.18/arch/i386/kernel/sys_i386.c    2006-09-22 20:45:03.000000000 -0400
2453 @@ -99,6 +99,191 @@ out:
2454         return err;
2455  }
2456  
2457 +unsigned long
2458 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
2459 +               unsigned long len, unsigned long pgoff, unsigned long flags)
2460 +{
2461 +       struct mm_struct *mm = current->mm;
2462 +       struct vm_area_struct *vma;
2463 +       unsigned long start_addr, task_size = TASK_SIZE;
2464 +
2465 +#ifdef CONFIG_PAX_SEGMEXEC
2466 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
2467 +               task_size = SEGMEXEC_TASK_SIZE;
2468 +#endif
2469 +
2470 +       if (len > task_size)
2471 +               return -ENOMEM;
2472 +
2473 +#ifdef CONFIG_PAX_RANDMMAP
2474 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2475 +#endif
2476 +
2477 +       if (addr) {
2478 +               addr = PAGE_ALIGN(addr);
2479 +               vma = find_vma(mm, addr);
2480 +               if (task_size - len >= addr &&
2481 +                   (!vma || addr + len <= vma->vm_start))
2482 +                       return addr;
2483 +       }
2484 +       if (len > mm->cached_hole_size) {
2485 +               start_addr = addr = mm->free_area_cache;
2486 +       } else {
2487 +               start_addr = addr = mm->mmap_base;
2488 +               mm->cached_hole_size = 0;
2489 +       }
2490 +
2491 +#ifdef CONFIG_PAX_PAGEEXEC
2492 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
2493 +               start_addr = 0x00110000UL;
2494 +
2495 +#ifdef CONFIG_PAX_RANDMMAP
2496 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
2497 +                       start_addr += mm->delta_mmap & 0x03FFF000UL;
2498 +#endif
2499 +
2500 +               if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
2501 +                       start_addr = addr = mm->mmap_base;
2502 +               else
2503 +                       addr = start_addr;
2504 +       }
2505 +#endif
2506 +
2507 +full_search:
2508 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2509 +               /* At this point:  (!vma || addr < vma->vm_end). */
2510 +               if (task_size - len < addr) {
2511 +                       /*
2512 +                        * Start a new search - just in case we missed
2513 +                        * some holes.
2514 +                        */
2515 +                       if (start_addr != mm->mmap_base) {
2516 +                               start_addr = addr = mm->mmap_base;
2517 +                               mm->cached_hole_size = 0;
2518 +                               goto full_search;
2519 +                       }
2520 +                       return -ENOMEM;
2521 +               }
2522 +               if (!vma || addr + len <= vma->vm_start) {
2523 +                       /*
2524 +                        * Remember the place where we stopped the search:
2525 +                        */
2526 +                       mm->free_area_cache = addr + len;
2527 +                       return addr;
2528 +               }
2529 +               if (addr + mm->cached_hole_size < vma->vm_start)
2530 +                       mm->cached_hole_size = vma->vm_start - addr;
2531 +               addr = vma->vm_end;
2532 +               if (mm->start_brk <= addr && addr < mm->mmap_base) {
2533 +                       start_addr = addr = mm->mmap_base;
2534 +                       goto full_search;
2535 +               }
2536 +       }
2537 +}
2538 +
2539 +unsigned long
2540 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
2541 +                         const unsigned long len, const unsigned long pgoff,
2542 +                         const unsigned long flags)
2543 +{
2544 +       struct vm_area_struct *vma;
2545 +       struct mm_struct *mm = current->mm;
2546 +       unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
2547 +
2548 +#ifdef CONFIG_PAX_SEGMEXEC
2549 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
2550 +               task_size = SEGMEXEC_TASK_SIZE;
2551 +#endif
2552 +
2553 +       /* requested length too big for entire address space */
2554 +       if (len > task_size)
2555 +               return -ENOMEM;
2556 +
2557 +#ifdef CONFIG_PAX_PAGEEXEC
2558 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
2559 +               goto bottomup;
2560 +#endif
2561 +
2562 +#ifdef CONFIG_PAX_RANDMMAP
2563 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2564 +#endif
2565 +
2566 +       /* requesting a specific address */
2567 +       if (addr) {
2568 +               addr = PAGE_ALIGN(addr);
2569 +               vma = find_vma(mm, addr);
2570 +               if (task_size - len >= addr &&
2571 +                               (!vma || addr + len <= vma->vm_start))
2572 +                       return addr;
2573 +       }
2574 +
2575 +       /* check if free_area_cache is useful for us */
2576 +       if (len <= mm->cached_hole_size) {
2577 +               mm->cached_hole_size = 0;
2578 +               mm->free_area_cache = mm->mmap_base;
2579 +       }
2580 +
2581 +       /* either no address requested or can't fit in requested address hole */
2582 +       addr = mm->free_area_cache;
2583 +
2584 +       /* make sure it can fit in the remaining address space */
2585 +       if (addr > len) {
2586 +               vma = find_vma(mm, addr-len);
2587 +               if (!vma || addr <= vma->vm_start)
2588 +                       /* remember the address as a hint for next time */
2589 +                       return (mm->free_area_cache = addr-len);
2590 +       }
2591 +
2592 +       if (mm->mmap_base < len)
2593 +               goto bottomup;
2594 +
2595 +       addr = mm->mmap_base-len;
2596 +
2597 +       do {
2598 +               /*
2599 +                * Lookup failure means no vma is above this address,
2600 +                * else if new region fits below vma->vm_start,
2601 +                * return with success:
2602 +                */
2603 +               vma = find_vma(mm, addr);
2604 +               if (!vma || addr+len <= vma->vm_start)
2605 +                       /* remember the address as a hint for next time */
2606 +                       return (mm->free_area_cache = addr);
2607 +
2608 +               /* remember the largest hole we saw so far */
2609 +               if (addr + mm->cached_hole_size < vma->vm_start)
2610 +                       mm->cached_hole_size = vma->vm_start - addr;
2611 +
2612 +               /* try just below the current vma->vm_start */
2613 +               addr = vma->vm_start-len;
2614 +       } while (len < vma->vm_start);
2615 +
2616 +bottomup:
2617 +       /*
2618 +        * A failed mmap() very likely causes application failure,
2619 +        * so fall back to the bottom-up function here. This scenario
2620 +        * can happen with large stack limits and large mmap()
2621 +        * allocations.
2622 +        */
2623 +       mm->mmap_base = TASK_UNMAPPED_BASE;
2624 +
2625 +#ifdef CONFIG_PAX_RANDMMAP
2626 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
2627 +               mm->mmap_base += mm->delta_mmap;
2628 +#endif
2629 +
2630 +       mm->free_area_cache = mm->mmap_base;
2631 +       mm->cached_hole_size = ~0UL;
2632 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
2633 +       /*
2634 +        * Restore the topdown base:
2635 +        */
2636 +       mm->mmap_base = base;
2637 +       mm->free_area_cache = base;
2638 +       mm->cached_hole_size = ~0UL;
2639 +
2640 +       return addr;
2641 +}
2642  
2643  struct sel_arg_struct {
2644         unsigned long n;
2645 diff -urNp linux-2.6.18/arch/i386/kernel/time.c linux-2.6.18/arch/i386/kernel/time.c
2646 --- linux-2.6.18/arch/i386/kernel/time.c        2006-09-19 23:42:06.000000000 -0400
2647 +++ linux-2.6.18/arch/i386/kernel/time.c        2006-09-22 20:45:03.000000000 -0400
2648 @@ -135,7 +135,7 @@ unsigned long profile_pc(struct pt_regs 
2649  {
2650         unsigned long pc = instruction_pointer(regs);
2651  
2652 -       if (!user_mode_vm(regs) && in_lock_functions(pc))
2653 +       if (!user_mode(regs) && in_lock_functions(pc))
2654                 return *(unsigned long *)(regs->ebp + 4);
2655  
2656         return pc;
2657 diff -urNp linux-2.6.18/arch/i386/kernel/traps.c linux-2.6.18/arch/i386/kernel/traps.c
2658 --- linux-2.6.18/arch/i386/kernel/traps.c       2006-09-19 23:42:06.000000000 -0400
2659 +++ linux-2.6.18/arch/i386/kernel/traps.c       2006-09-22 20:45:03.000000000 -0400
2660 @@ -28,6 +28,7 @@
2661  #include <linux/kprobes.h>
2662  #include <linux/kexec.h>
2663  #include <linux/unwind.h>
2664 +#include <linux/binfmts.h>
2665  
2666  #ifdef CONFIG_EISA
2667  #include <linux/ioport.h>
2668 @@ -58,18 +59,13 @@
2669  
2670  asmlinkage int system_call(void);
2671  
2672 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2673 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2674                 { 0, 0 }, { 0, 0 } };
2675  
2676  /* Do we ignore FPU interrupts ? */
2677  char ignore_fpu_irq = 0;
2678  
2679 -/*
2680 - * The IDT has to be page-aligned to simplify the Pentium
2681 - * F0 0F bug workaround.. We have a special link segment
2682 - * for this.
2683 - */
2684 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
2685 +extern struct desc_struct idt_table[256];
2686  
2687  asmlinkage void divide_error(void);
2688  asmlinkage void debug(void);
2689 @@ -149,7 +145,7 @@ static inline unsigned long print_contex
2690  #else
2691         while (valid_stack_ptr(tinfo, stack)) {
2692                 addr = *stack++;
2693 -               if (__kernel_text_address(addr))
2694 +               if (__kernel_text_address(addr + __KERNEL_TEXT_OFFSET))
2695                         print_addr_and_symbol(addr, log_lvl);
2696         }
2697  #endif
2698 @@ -285,7 +281,7 @@ void show_registers(struct pt_regs *regs
2699  
2700         esp = (unsigned long) (&regs->esp);
2701         savesegment(ss, ss);
2702 -       if (user_mode_vm(regs)) {
2703 +       if (user_mode(regs)) {
2704                 in_kernel = 0;
2705                 esp = regs->esp;
2706                 ss = regs->xss & 0xffff;
2707 @@ -313,13 +309,15 @@ void show_registers(struct pt_regs *regs
2708          */
2709         if (in_kernel) {
2710                 u8 __user *eip;
2711 +               mm_segment_t old_fs = get_fs();
2712  
2713                 printk("\n" KERN_EMERG "Stack: ");
2714                 show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
2715  
2716                 printk(KERN_EMERG "Code: ");
2717  
2718 -               eip = (u8 __user *)regs->eip - 43;
2719 +               set_fs(KERNEL_DS);
2720 +               eip = (u8 __user *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
2721                 for (i = 0; i < 64; i++, eip++) {
2722                         unsigned char c;
2723  
2724 @@ -327,26 +325,29 @@ void show_registers(struct pt_regs *regs
2725                                 printk(" Bad EIP value.");
2726                                 break;
2727                         }
2728 -                       if (eip == (u8 __user *)regs->eip)
2729 +                       if (eip == (u8 __user *)regs->eip + __KERNEL_TEXT_OFFSET)
2730                                 printk("<%02x> ", c);
2731                         else
2732                                 printk("%02x ", c);
2733                 }
2734 +               set_fs(old_fs);
2735         }
2736         printk("\n");
2737  }      
2738  
2739  static void handle_BUG(struct pt_regs *regs)
2740  {
2741 -       unsigned long eip = regs->eip;
2742 +       unsigned long eip = regs->eip + __KERNEL_TEXT_OFFSET;
2743         unsigned short ud2;
2744 +       mm_segment_t old_fs = get_fs();
2745  
2746 +       set_fs(KERNEL_DS);
2747         if (eip < PAGE_OFFSET)
2748 -               return;
2749 +               goto out;
2750         if (__get_user(ud2, (unsigned short __user *)eip))
2751 -               return;
2752 +               goto out;
2753         if (ud2 != 0x0b0f)
2754 -               return;
2755 +               goto out;
2756  
2757         printk(KERN_EMERG "------------[ cut here ]------------\n");
2758  
2759 @@ -356,17 +357,22 @@ static void handle_BUG(struct pt_regs *r
2760                 char *file;
2761                 char c;
2762  
2763 -               if (__get_user(line, (unsigned short __user *)(eip + 2)))
2764 +               if (__get_user(line, (unsigned short __user *)(eip + 7)))
2765 +                       break;
2766 +               if (__get_user(file, (char * __user *)(eip + 3)) ||
2767 +                   file < _text + __KERNEL_TEXT_OFFSET)
2768                         break;
2769 -               if (__get_user(file, (char * __user *)(eip + 4)) ||
2770 -                   (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
2771 +               if (__get_user(c, file))
2772                         file = "<bad filename>";
2773  
2774                 printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
2775 -               return;
2776 +               goto out;
2777         } while (0);
2778  #endif
2779         printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n");
2780 +
2781 +out:
2782 +       set_fs(old_fs);
2783  }
2784  
2785  /* This is gone through when something in the kernel
2786 @@ -465,7 +471,7 @@ void die(const char * str, struct pt_reg
2787  
2788  static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
2789  {
2790 -       if (!user_mode_vm(regs))
2791 +       if (!user_mode(regs))
2792                 die(str, regs, err);
2793  }
2794  
2795 @@ -483,7 +489,7 @@ static void __kprobes do_trap(int trapnr
2796                 goto trap_signal;
2797         }
2798  
2799 -       if (!user_mode(regs))
2800 +       if (!user_mode_novm(regs))
2801                 goto kernel_trap;
2802  
2803         trap_signal: {
2804 @@ -571,7 +577,7 @@ fastcall void __kprobes do_general_prote
2805                                               long error_code)
2806  {
2807         int cpu = get_cpu();
2808 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2809 +       struct tss_struct *tss = &init_tss[cpu];
2810         struct thread_struct *thread = &current->thread;
2811  
2812         /*
2813 @@ -607,9 +613,25 @@ fastcall void __kprobes do_general_prote
2814         if (regs->eflags & VM_MASK)
2815                 goto gp_in_vm86;
2816  
2817 -       if (!user_mode(regs))
2818 +       if (!user_mode_novm(regs))
2819                 goto gp_in_kernel;
2820  
2821 +#ifdef CONFIG_PAX_PAGEEXEC
2822 +       if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
2823 +               struct mm_struct *mm = current->mm;
2824 +               unsigned long limit;
2825 +
2826 +               down_write(&mm->mmap_sem);
2827 +               limit = mm->context.user_cs_limit;
2828 +               if (limit < TASK_SIZE) {
2829 +                       track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
2830 +                       up_write(&mm->mmap_sem);
2831 +                       return;
2832 +               }
2833 +               up_write(&mm->mmap_sem);
2834 +       }
2835 +#endif
2836 +
2837         current->thread.error_code = error_code;
2838         current->thread.trap_no = 13;
2839         force_sig(SIGSEGV, current);
2840 @@ -625,6 +647,13 @@ gp_in_kernel:
2841                 if (notify_die(DIE_GPF, "general protection fault", regs,
2842                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
2843                         return;
2844 +
2845 +#ifdef CONFIG_PAX_KERNEXEC
2846 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
2847 +                       die("PAX: suspicious general protection fault", regs, error_code);
2848 +               else
2849 +#endif
2850 +
2851                 die("general protection fault", regs, error_code);
2852         }
2853  }
2854 @@ -698,7 +727,7 @@ void die_nmi (struct pt_regs *regs, cons
2855         /* If we are in kernel we are probably nested up pretty bad
2856          * and might aswell get out now while we still can.
2857         */
2858 -       if (!user_mode_vm(regs)) {
2859 +       if (!user_mode(regs)) {
2860                 current->thread.trap_no = 2;
2861                 crash_kexec(regs);
2862         }
2863 @@ -851,7 +880,7 @@ fastcall void __kprobes do_debug(struct 
2864                  * check for kernel mode by just checking the CPL
2865                  * of CS.
2866                  */
2867 -               if (!user_mode(regs))
2868 +               if (!user_mode_novm(regs))
2869                         goto clear_TF_reenable;
2870         }
2871  
2872 @@ -1141,7 +1170,19 @@ do { \
2873   */
2874  void set_intr_gate(unsigned int n, void *addr)
2875  {
2876 +
2877 +#ifdef CONFIG_PAX_KERNEXEC
2878 +       unsigned long cr0;
2879 +
2880 +       pax_open_kernel(cr0);
2881 +#endif
2882 +
2883         _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
2884 +
2885 +#ifdef CONFIG_PAX_KERNEXEC
2886 +       pax_close_kernel(cr0);
2887 +#endif
2888 +
2889  }
2890  
2891  /*
2892 diff -urNp linux-2.6.18/arch/i386/kernel/vm86.c linux-2.6.18/arch/i386/kernel/vm86.c
2893 --- linux-2.6.18/arch/i386/kernel/vm86.c        2006-09-19 23:42:06.000000000 -0400
2894 +++ linux-2.6.18/arch/i386/kernel/vm86.c        2006-09-22 20:45:03.000000000 -0400
2895 @@ -122,7 +122,7 @@ struct pt_regs * fastcall save_v86_state
2896                 do_exit(SIGSEGV);
2897         }
2898  
2899 -       tss = &per_cpu(init_tss, get_cpu());
2900 +       tss = init_tss + get_cpu();
2901         current->thread.esp0 = current->thread.saved_esp0;
2902         current->thread.sysenter_cs = __KERNEL_CS;
2903         load_esp0(tss, &current->thread);
2904 @@ -296,7 +296,7 @@ static void do_sys_vm86(struct kernel_vm
2905         savesegment(fs, tsk->thread.saved_fs);
2906         savesegment(gs, tsk->thread.saved_gs);
2907  
2908 -       tss = &per_cpu(init_tss, get_cpu());
2909 +       tss = init_tss + get_cpu();
2910         tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
2911         if (cpu_has_sep)
2912                 tsk->thread.sysenter_cs = 0;
2913 diff -urNp linux-2.6.18/arch/i386/kernel/vmlinux.lds.S linux-2.6.18/arch/i386/kernel/vmlinux.lds.S
2914 --- linux-2.6.18/arch/i386/kernel/vmlinux.lds.S 2006-09-19 23:42:06.000000000 -0400
2915 +++ linux-2.6.18/arch/i386/kernel/vmlinux.lds.S 2006-09-22 20:45:03.000000000 -0400
2916 @@ -4,10 +4,19 @@
2917  
2918  #define LOAD_OFFSET __PAGE_OFFSET
2919  
2920 +#include <linux/config.h>
2921 +
2922  #include <asm-generic/vmlinux.lds.h>
2923  #include <asm/thread_info.h>
2924  #include <asm/page.h>
2925  #include <asm/cache.h>
2926 +#include <asm/segment.h>
2927 +
2928 +#ifdef CONFIG_X86_PAE
2929 +#define PMD_SHIFT 21
2930 +#else
2931 +#define PMD_SHIFT 22
2932 +#endif
2933  
2934  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2935  OUTPUT_ARCH(i386)
2936 @@ -16,75 +25,14 @@ jiffies = jiffies_64;
2937  SECTIONS
2938  {
2939    . = __KERNEL_START;
2940 -  phys_startup_32 = startup_32 - LOAD_OFFSET;
2941 -  /* read-only */
2942 -  _text = .;                   /* Text and read-only data */
2943 -  .text : AT(ADDR(.text) - LOAD_OFFSET) {
2944 -       *(.text)
2945 -       SCHED_TEXT
2946 -       LOCK_TEXT
2947 -       KPROBES_TEXT
2948 -       *(.fixup)
2949 -       *(.gnu.warning)
2950 -       } = 0x9090
2951 -
2952 -  _etext = .;                  /* End of text section */
2953 -
2954 -  . = ALIGN(16);               /* Exception table */
2955 -  __start___ex_table = .;
2956 -  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2957 -  __stop___ex_table = .;
2958 -
2959 -  RODATA
2960 +  phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
2961  
2962 -  . = ALIGN(4);
2963 -  __tracedata_start = .;
2964 -  .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
2965 -       *(.tracedata)
2966 -  }
2967 -  __tracedata_end = .;
2968 -
2969 -  /* writeable */
2970 -  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2971 -       *(.data)
2972 -       CONSTRUCTORS
2973 +  .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
2974 +       BYTE(0xEA) /* jmp far */
2975 +       LONG(phys_startup_32)
2976 +       SHORT(__BOOT_CS)
2977         }
2978  
2979 -  . = ALIGN(4096);
2980 -  __nosave_begin = .;
2981 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2982 -  . = ALIGN(4096);
2983 -  __nosave_end = .;
2984 -
2985 -  . = ALIGN(4096);
2986 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
2987 -       *(.data.idt)
2988 -  }
2989 -
2990 -  . = ALIGN(32);
2991 -  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2992 -       *(.data.cacheline_aligned)
2993 -  }
2994 -
2995 -  /* rarely changed data like cpu maps */
2996 -  . = ALIGN(32);
2997 -  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2998 -  _edata = .;                  /* End of data section */
2999 -
3000 -#ifdef CONFIG_STACK_UNWIND
3001 -  . = ALIGN(4);
3002 -  .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) {
3003 -       __start_unwind = .;
3004 -       *(.eh_frame)
3005 -       __end_unwind = .;
3006 -  }
3007 -#endif
3008 -
3009 -  . = ALIGN(THREAD_SIZE);      /* init_task */
3010 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
3011 -       *(.data.init_task)
3012 -  }
3013 -
3014    /* might get freed after init */
3015    . = ALIGN(4096);
3016    __smp_alt_begin = .;
3017 @@ -108,11 +56,6 @@ SECTIONS
3018    /* will be freed after init */
3019    . = ALIGN(4096);             /* Init code and data */
3020    __init_begin = .;
3021 -  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
3022 -       _sinittext = .;
3023 -       *(.init.text)
3024 -       _einittext = .;
3025 -  }
3026    .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
3027    . = ALIGN(16);
3028    __setup_start = .;
3029 @@ -144,9 +87,7 @@ SECTIONS
3030    .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
3031         *(.altinstr_replacement)
3032    }
3033 -  /* .exit.text is discard at runtime, not link time, to deal with references
3034 -     from .altinstructions and .eh_frame */
3035 -  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
3036 +
3037    .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
3038    . = ALIGN(4096);
3039    __initramfs_start = .;
3040 @@ -156,10 +97,124 @@ SECTIONS
3041    __per_cpu_start = .;
3042    .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
3043    __per_cpu_end = .;
3044 +
3045 +  /* read-only */
3046 +
3047    . = ALIGN(4096);
3048 -  __init_end = .;
3049 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3050 +       _sinittext = .;
3051 +       *(.init.text)
3052 +       _einittext = .;
3053 +  }
3054 +
3055 +  /* .exit.text is discard at runtime, not link time, to deal with references
3056 +     from .altinstructions and .eh_frame */
3057 +  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
3058 +
3059 +#ifdef CONFIG_PAX_KERNEXEC
3060 +  .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3061 +       . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
3062 +       BYTE(0)
3063 +  }
3064 +#else
3065 +  . = ALIGN(4096);
3066 +#endif
3067 +
3068 +  __init_end = . + __KERNEL_TEXT_OFFSET;
3069    /* freed after init ends here */
3070 -       
3071 +
3072 +  _text = .;                   /* Text and read-only data */
3073 +  .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3074 +       *(.text)
3075 +       SCHED_TEXT
3076 +       LOCK_TEXT
3077 +       KPROBES_TEXT
3078 +       *(.fixup)
3079 +       *(.gnu.warning)
3080 +       } = 0x9090
3081 +
3082 +  _etext = .;                  /* End of text section */
3083 +  . += __KERNEL_TEXT_OFFSET;
3084 +  . = ALIGN(16);               /* Exception table */
3085 +  __start___ex_table = .;
3086 +  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
3087 +  __stop___ex_table = .;
3088 +
3089 +  . = ALIGN(4096);
3090 +  .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
3091 +       *(.empty_zero_page)
3092 +
3093 +#ifdef CONFIG_X86_PAE
3094 +       *(.swapper_pm_dir)
3095 +#endif
3096 +
3097 +       *(.swapper_pg_dir)
3098 +       *(.idt)
3099 +       }
3100 +
3101 +  RODATA
3102 +
3103 +  . = ALIGN(4);
3104 +  __tracedata_start = .;
3105 +  .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
3106 +       *(.tracedata)
3107 +  }
3108 +  __tracedata_end = .;
3109 +
3110 +#ifdef CONFIG_PAX_KERNEXEC
3111 +  . = ALIGN(4096);
3112 +  MODULES_VADDR = .;
3113 +
3114 +  .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
3115 +       . += (4 * 1024 * 1024);
3116 +       . = ALIGN(1 << PMD_SHIFT) - 1;
3117 +       BYTE(0)
3118 +  }
3119 +
3120 +  MODULES_END = .;
3121 +#else
3122 +  . = ALIGN(32);
3123 +#endif
3124 +
3125 +  /* writeable */
3126 +  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
3127 +       _data = .;
3128 +       *(.data)
3129 +       CONSTRUCTORS
3130 +       }
3131 +
3132 +  . = ALIGN(4096);
3133 +  __nosave_begin = .;
3134 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
3135 +  . = ALIGN(4096);
3136 +  __nosave_end = .;
3137 +
3138 +  . = ALIGN(32);
3139 +  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
3140 +       *(.data.cacheline_aligned)
3141 +  }
3142 +
3143 +  /* rarely changed data like cpu maps */
3144 +  . = ALIGN(32);
3145 +  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
3146 +
3147 +#ifdef CONFIG_STACK_UNWIND
3148 +  . = ALIGN(4);
3149 +  .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) {
3150 +       __start_unwind = .;
3151 +       *(.eh_frame)
3152 +       __end_unwind = .;
3153 +  }
3154 +#endif
3155 +
3156 +  . = ALIGN(THREAD_SIZE);      /* init_task */
3157 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
3158 +       *(.data.init_task)
3159 +  }
3160 +
3161 +  _edata = .;                  /* End of data section */
3162 +
3163 +  . = ALIGN(4096);
3164    __bss_start = .;             /* BSS */
3165    .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
3166         *(.bss.page_aligned)
3167 diff -urNp linux-2.6.18/arch/i386/lib/checksum.S linux-2.6.18/arch/i386/lib/checksum.S
3168 --- linux-2.6.18/arch/i386/lib/checksum.S       2006-09-19 23:42:06.000000000 -0400
3169 +++ linux-2.6.18/arch/i386/lib/checksum.S       2006-09-22 20:45:03.000000000 -0400
3170 @@ -26,7 +26,8 @@
3171   */
3172  
3173  #include <asm/errno.h>
3174 -                               
3175 +#include <asm/segment.h>
3176 +
3177  /*
3178   * computes a partial checksum, e.g. for TCP/UDP fragments
3179   */
3180 @@ -280,12 +281,23 @@ unsigned int csum_partial_copy_generic (
3181  
3182  .align 4
3183  .globl csum_partial_copy_generic
3184 -                               
3185 +.globl csum_partial_copy_generic_to_user
3186 +.globl csum_partial_copy_generic_from_user
3187 +
3188  #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
3189  
3190  #define ARGBASE 16             
3191  #define FP             12
3192 -               
3193 +
3194 +csum_partial_copy_generic_to_user:
3195 +       pushl $(__USER_DS)
3196 +       popl %es
3197 +       jmp csum_partial_copy_generic
3198 +
3199 +csum_partial_copy_generic_from_user:
3200 +       pushl $(__USER_DS)
3201 +       popl %ds
3202 +
3203  csum_partial_copy_generic:
3204         subl  $4,%esp   
3205         pushl %edi
3206 @@ -304,7 +316,7 @@ csum_partial_copy_generic:
3207         jmp 4f
3208  SRC(1: movw (%esi), %bx        )
3209         addl $2, %esi
3210 -DST(   movw %bx, (%edi)        )
3211 +DST(   movw %bx, %es:(%edi)    )
3212         addl $2, %edi
3213         addw %bx, %ax   
3214         adcl $0, %eax
3215 @@ -316,30 +328,30 @@ DST(      movw %bx, (%edi)        )
3216  SRC(1: movl (%esi), %ebx       )
3217  SRC(   movl 4(%esi), %edx      )
3218         adcl %ebx, %eax
3219 -DST(   movl %ebx, (%edi)       )
3220 +DST(   movl %ebx, %es:(%edi)   )
3221         adcl %edx, %eax
3222 -DST(   movl %edx, 4(%edi)      )
3223 +DST(   movl %edx, %es:4(%edi)  )
3224  
3225  SRC(   movl 8(%esi), %ebx      )
3226  SRC(   movl 12(%esi), %edx     )
3227         adcl %ebx, %eax
3228 -DST(   movl %ebx, 8(%edi)      )
3229 +DST(   movl %ebx, %es:8(%edi)  )
3230         adcl %edx, %eax
3231 -DST(   movl %edx, 12(%edi)     )
3232 +DST(   movl %edx, %es:12(%edi) )
3233  
3234  SRC(   movl 16(%esi), %ebx     )
3235  SRC(   movl 20(%esi), %edx     )
3236         adcl %ebx, %eax
3237 -DST(   movl %ebx, 16(%edi)     )
3238 +DST(   movl %ebx, %es:16(%edi) )
3239         adcl %edx, %eax
3240 -DST(   movl %edx, 20(%edi)     )
3241 +DST(   movl %edx, %es:20(%edi) )
3242  
3243  SRC(   movl 24(%esi), %ebx     )
3244  SRC(   movl 28(%esi), %edx     )
3245         adcl %ebx, %eax
3246 -DST(   movl %ebx, 24(%edi)     )
3247 +DST(   movl %ebx, %es:24(%edi) )
3248         adcl %edx, %eax
3249 -DST(   movl %edx, 28(%edi)     )
3250 +DST(   movl %edx, %es:28(%edi) )
3251  
3252         lea 32(%esi), %esi
3253         lea 32(%edi), %edi
3254 @@ -353,7 +365,7 @@ DST(        movl %edx, 28(%edi)     )
3255         shrl $2, %edx                   # This clears CF
3256  SRC(3: movl (%esi), %ebx       )
3257         adcl %ebx, %eax
3258 -DST(   movl %ebx, (%edi)       )
3259 +DST(   movl %ebx, %es:(%edi)   )
3260         lea 4(%esi), %esi
3261         lea 4(%edi), %edi
3262         dec %edx
3263 @@ -365,12 +377,12 @@ DST(      movl %ebx, (%edi)       )
3264         jb 5f
3265  SRC(   movw (%esi), %cx        )
3266         leal 2(%esi), %esi
3267 -DST(   movw %cx, (%edi)        )
3268 +DST(   movw %cx, %es:(%edi)    )
3269         leal 2(%edi), %edi
3270         je 6f
3271         shll $16,%ecx
3272  SRC(5: movb (%esi), %cl        )
3273 -DST(   movb %cl, (%edi)        )
3274 +DST(   movb %cl, %es:(%edi)    )
3275  6:     addl %ecx, %eax
3276         adcl $0, %eax
3277  7:
3278 @@ -381,7 +393,7 @@ DST(        movb %cl, (%edi)        )
3279  
3280  6001:
3281         movl ARGBASE+20(%esp), %ebx     # src_err_ptr
3282 -       movl $-EFAULT, (%ebx)
3283 +       movl $-EFAULT, %ss:(%ebx)
3284  
3285         # zero the complete destination - computing the rest
3286         # is too much work 
3287 @@ -394,11 +406,15 @@ DST(      movb %cl, (%edi)        )
3288  
3289  6002:
3290         movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
3291 -       movl $-EFAULT,(%ebx)
3292 +       movl $-EFAULT,%ss:(%ebx)
3293         jmp 5000b
3294  
3295  .previous
3296  
3297 +       pushl %ss
3298 +       popl %ds
3299 +       pushl %ss
3300 +       popl %es
3301         popl %ebx
3302         popl %esi
3303         popl %edi
3304 @@ -410,17 +426,28 @@ DST(      movb %cl, (%edi)        )
3305  /* Version for PentiumII/PPro */
3306  
3307  #define ROUND1(x) \
3308 +       nop; nop; nop;                          \
3309         SRC(movl x(%esi), %ebx  )       ;       \
3310         addl %ebx, %eax                 ;       \
3311 -       DST(movl %ebx, x(%edi)  )       ; 
3312 +       DST(movl %ebx, %es:x(%edi));
3313  
3314  #define ROUND(x) \
3315 +       nop; nop; nop;                          \
3316         SRC(movl x(%esi), %ebx  )       ;       \
3317         adcl %ebx, %eax                 ;       \
3318 -       DST(movl %ebx, x(%edi)  )       ;
3319 +       DST(movl %ebx, %es:x(%edi));
3320  
3321  #define ARGBASE 12
3322 -               
3323 +
3324 +csum_partial_copy_generic_to_user:
3325 +       pushl $(__USER_DS)
3326 +       popl %es
3327 +       jmp csum_partial_copy_generic
3328 +
3329 +csum_partial_copy_generic_from_user:
3330 +       pushl $(__USER_DS)
3331 +       popl %ds
3332 +
3333  csum_partial_copy_generic:
3334         pushl %ebx
3335         pushl %edi
3336 @@ -439,7 +466,7 @@ csum_partial_copy_generic:
3337         subl %ebx, %edi  
3338         lea  -1(%esi),%edx
3339         andl $-32,%edx
3340 -       lea 3f(%ebx,%ebx), %ebx
3341 +       lea 3f(%ebx,%ebx,2), %ebx
3342         testl %esi, %esi 
3343         jmp *%ebx
3344  1:     addl $64,%esi
3345 @@ -460,19 +487,19 @@ csum_partial_copy_generic:
3346         jb 5f
3347  SRC(   movw (%esi), %dx         )
3348         leal 2(%esi), %esi
3349 -DST(   movw %dx, (%edi)         )
3350 +DST(   movw %dx, %es:(%edi)     )
3351         leal 2(%edi), %edi
3352         je 6f
3353         shll $16,%edx
3354  5:
3355  SRC(   movb (%esi), %dl         )
3356 -DST(   movb %dl, (%edi)         )
3357 +DST(   movb %dl, %es:(%edi)     )
3358  6:     addl %edx, %eax
3359         adcl $0, %eax
3360  7:
3361  .section .fixup, "ax"
3362  6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
3363 -       movl $-EFAULT, (%ebx)
3364 +       movl $-EFAULT, %ss:(%ebx)
3365         # zero the complete destination (computing the rest is too much work)
3366         movl ARGBASE+8(%esp),%edi       # dst
3367         movl ARGBASE+12(%esp),%ecx      # len
3368 @@ -480,10 +507,14 @@ DST(      movb %dl, (%edi)         )
3369         rep; stosb
3370         jmp 7b
3371  6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
3372 -       movl $-EFAULT, (%ebx)
3373 +       movl $-EFAULT, %ss:(%ebx)
3374         jmp  7b                 
3375  .previous                              
3376  
3377 +       pushl %ss
3378 +       popl %ds
3379 +       pushl %ss
3380 +       popl %es
3381         popl %esi
3382         popl %edi
3383         popl %ebx
3384 diff -urNp linux-2.6.18/arch/i386/lib/getuser.S linux-2.6.18/arch/i386/lib/getuser.S
3385 --- linux-2.6.18/arch/i386/lib/getuser.S        2006-09-19 23:42:06.000000000 -0400
3386 +++ linux-2.6.18/arch/i386/lib/getuser.S        2006-09-22 20:45:03.000000000 -0400
3387 @@ -9,6 +9,7 @@
3388   * return value.
3389   */
3390  #include <asm/thread_info.h>
3391 +#include <asm/segment.h>
3392  
3393  
3394  /*
3395 @@ -30,8 +31,12 @@ __get_user_1:
3396         GET_THREAD_INFO(%edx)
3397         cmpl TI_addr_limit(%edx),%eax
3398         jae bad_get_user
3399 +       pushl $(__USER_DS)
3400 +       popl %ds
3401  1:     movzbl (%eax),%edx
3402         xorl %eax,%eax
3403 +       pushl %ss
3404 +       pop %ds
3405         ret
3406  
3407  .align 4
3408 @@ -42,7 +47,11 @@ __get_user_2:
3409         GET_THREAD_INFO(%edx)
3410         cmpl TI_addr_limit(%edx),%eax
3411         jae bad_get_user
3412 +       pushl $(__USER_DS)
3413 +       popl %ds
3414  2:     movzwl -1(%eax),%edx
3415 +       pushl %ss
3416 +       pop %ds
3417         xorl %eax,%eax
3418         ret
3419  
3420 @@ -54,11 +63,17 @@ __get_user_4:
3421         GET_THREAD_INFO(%edx)
3422         cmpl TI_addr_limit(%edx),%eax
3423         jae bad_get_user
3424 +       pushl $(__USER_DS)
3425 +       popl %ds
3426  3:     movl -3(%eax),%edx
3427 +       pushl %ss
3428 +       pop %ds
3429         xorl %eax,%eax
3430         ret
3431  
3432  bad_get_user:
3433 +       pushl %ss
3434 +       pop %ds
3435         xorl %edx,%edx
3436         movl $-14,%eax
3437         ret
3438 diff -urNp linux-2.6.18/arch/i386/lib/mmx.c linux-2.6.18/arch/i386/lib/mmx.c
3439 --- linux-2.6.18/arch/i386/lib/mmx.c    2006-09-19 23:42:06.000000000 -0400
3440 +++ linux-2.6.18/arch/i386/lib/mmx.c    2006-09-22 20:45:03.000000000 -0400
3441 @@ -47,14 +47,30 @@ void *_mmx_memcpy(void *to, const void *
3442                 "   prefetch 256(%0)\n"
3443                 "2:  \n"
3444                 ".section .fixup, \"ax\"\n"
3445 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3446 +               "3:  \n"
3447 +
3448 +#ifdef CONFIG_PAX_KERNEXEC
3449 +               "   cli\n"
3450 +               "   movl %%cr0, %%eax\n"
3451 +               "   andl $0xFFFEFFFF, %%eax\n"
3452 +               "   movl %%eax, %%cr0\n"
3453 +#endif
3454 +
3455 +               " movw $0x1AEB, 1b\n"   /* jmp on 26 bytes */
3456 +
3457 +#ifdef CONFIG_PAX_KERNEXEC
3458 +               "   orl $0x00010000, %%eax\n"
3459 +               "   movl %%eax, %%cr0\n"
3460 +               "   sti\n"
3461 +#endif
3462 +
3463                 "   jmp 2b\n"
3464                 ".previous\n"
3465                 ".section __ex_table,\"a\"\n"
3466                 "       .align 4\n"
3467                 "       .long 1b, 3b\n"
3468                 ".previous"
3469 -               : : "r" (from) );
3470 +               : : "r" (from) : "ax");
3471                 
3472         
3473         for(; i>5; i--)
3474 @@ -78,14 +94,30 @@ void *_mmx_memcpy(void *to, const void *
3475                 "  movq %%mm2, 48(%1)\n"
3476                 "  movq %%mm3, 56(%1)\n"
3477                 ".section .fixup, \"ax\"\n"
3478 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3479 +               "3:\n"
3480 +
3481 +#ifdef CONFIG_PAX_KERNEXEC
3482 +               "  cli\n"
3483 +               "  movl %%cr0, %%eax\n"
3484 +               "  andl $0xFFFEFFFF, %%eax\n"
3485 +               "  movl %%eax, %%cr0\n"
3486 +#endif
3487 +
3488 +               "  movw $0x05EB, 1b\n"  /* jmp on 5 bytes */
3489 +
3490 +#ifdef CONFIG_PAX_KERNEXEC
3491 +               "  orl $0x00010000, %%eax\n"
3492 +               "  movl %%eax, %%cr0\n"
3493 +               "  sti\n"
3494 +#endif
3495 +
3496                 "   jmp 2b\n"
3497                 ".previous\n"
3498                 ".section __ex_table,\"a\"\n"
3499                 "       .align 4\n"
3500                 "       .long 1b, 3b\n"
3501                 ".previous"
3502 -               : : "r" (from), "r" (to) : "memory");
3503 +               : : "r" (from), "r" (to) : "memory", "ax");
3504                 from+=64;
3505                 to+=64;
3506         }
3507 @@ -178,14 +210,30 @@ static void fast_copy_page(void *to, voi
3508                 "   prefetch 256(%0)\n"
3509                 "2:  \n"
3510                 ".section .fixup, \"ax\"\n"
3511 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3512 +               "3:  \n"
3513 +
3514 +#ifdef CONFIG_PAX_KERNEXEC
3515 +               "   cli\n"
3516 +               "   movl %%cr0, %%eax\n"
3517 +               "   andl $0xFFFEFFFF, %%eax\n"
3518 +               "   movl %%eax, %%cr0\n"
3519 +#endif
3520 +
3521 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3522 +
3523 +#ifdef CONFIG_PAX_KERNEXEC
3524 +               "   orl $0x00010000, %%eax\n"
3525 +               "   movl %%eax, %%cr0\n"
3526 +               "   sti\n"
3527 +#endif
3528 +
3529                 "   jmp 2b\n"
3530                 ".previous\n"
3531                 ".section __ex_table,\"a\"\n"
3532                 "       .align 4\n"
3533                 "       .long 1b, 3b\n"
3534                 ".previous"
3535 -               : : "r" (from) );
3536 +               : : "r" (from) : "ax");
3537  
3538         for(i=0; i<(4096-320)/64; i++)
3539         {
3540 @@ -208,14 +256,30 @@ static void fast_copy_page(void *to, voi
3541                 "   movq 56(%0), %%mm7\n"
3542                 "   movntq %%mm7, 56(%1)\n"
3543                 ".section .fixup, \"ax\"\n"
3544 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3545 +               "3:\n"
3546 +
3547 +#ifdef CONFIG_PAX_KERNEXEC
3548 +               "   cli\n"
3549 +               "   movl %%cr0, %%eax\n"
3550 +               "   andl $0xFFFEFFFF, %%eax\n"
3551 +               "   movl %%eax, %%cr0\n"
3552 +#endif
3553 +
3554 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3555 +
3556 +#ifdef CONFIG_PAX_KERNEXEC
3557 +               "   orl $0x00010000, %%eax\n"
3558 +               "   movl %%eax, %%cr0\n"
3559 +               "   sti\n"
3560 +#endif
3561 +
3562                 "   jmp 2b\n"
3563                 ".previous\n"
3564                 ".section __ex_table,\"a\"\n"
3565                 "       .align 4\n"
3566                 "       .long 1b, 3b\n"
3567                 ".previous"
3568 -               : : "r" (from), "r" (to) : "memory");
3569 +               : : "r" (from), "r" (to) : "memory", "ax");
3570                 from+=64;
3571                 to+=64;
3572         }
3573 @@ -308,14 +372,30 @@ static void fast_copy_page(void *to, voi
3574                 "   prefetch 256(%0)\n"
3575                 "2:  \n"
3576                 ".section .fixup, \"ax\"\n"
3577 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3578 +               "3:  \n"
3579 +
3580 +#ifdef CONFIG_PAX_KERNEXEC
3581 +               "   cli\n"
3582 +               "   movl %%cr0, %%eax\n"
3583 +               "   andl $0xFFFEFFFF, %%eax\n"
3584 +               "   movl %%eax, %%cr0\n"
3585 +#endif
3586 +
3587 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3588 +
3589 +#ifdef CONFIG_PAX_KERNEXEC
3590 +               "   orl $0x00010000, %%eax\n"
3591 +               "   movl %%eax, %%cr0\n"
3592 +               "   sti\n"
3593 +#endif
3594 +
3595                 "   jmp 2b\n"
3596                 ".previous\n"
3597                 ".section __ex_table,\"a\"\n"
3598                 "       .align 4\n"
3599                 "       .long 1b, 3b\n"
3600                 ".previous"
3601 -               : : "r" (from) );
3602 +               : : "r" (from) : "ax");
3603  
3604         for(i=0; i<4096/64; i++)
3605         {
3606 @@ -338,14 +418,30 @@ static void fast_copy_page(void *to, voi
3607                 "   movq %%mm2, 48(%1)\n"
3608                 "   movq %%mm3, 56(%1)\n"
3609                 ".section .fixup, \"ax\"\n"
3610 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3611 +               "3:\n"
3612 +
3613 +#ifdef CONFIG_PAX_KERNEXEC
3614 +               "   cli\n"
3615 +               "   movl %%cr0, %%eax\n"
3616 +               "   andl $0xFFFEFFFF, %%eax\n"
3617 +               "   movl %%eax, %%cr0\n"
3618 +#endif
3619 +
3620 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3621 +
3622 +#ifdef CONFIG_PAX_KERNEXEC
3623 +               "   orl $0x00010000, %%eax\n"
3624 +               "   movl %%eax, %%cr0\n"
3625 +               "   sti\n"
3626 +#endif
3627 +
3628                 "   jmp 2b\n"
3629                 ".previous\n"
3630                 ".section __ex_table,\"a\"\n"
3631                 "       .align 4\n"
3632                 "       .long 1b, 3b\n"
3633                 ".previous"
3634 -               : : "r" (from), "r" (to) : "memory");
3635 +               : : "r" (from), "r" (to) : "memory", "ax");
3636                 from+=64;
3637                 to+=64;
3638         }
3639 diff -urNp linux-2.6.18/arch/i386/lib/putuser.S linux-2.6.18/arch/i386/lib/putuser.S
3640 --- linux-2.6.18/arch/i386/lib/putuser.S        2006-09-19 23:42:06.000000000 -0400
3641 +++ linux-2.6.18/arch/i386/lib/putuser.S        2006-09-22 20:45:03.000000000 -0400
3642 @@ -9,6 +9,7 @@
3643   * return value.
3644   */
3645  #include <asm/thread_info.h>
3646 +#include <asm/segment.h>
3647  
3648  
3649  /*
3650 @@ -33,7 +34,11 @@ __put_user_1:
3651         ENTER
3652         cmpl TI_addr_limit(%ebx),%ecx
3653         jae bad_put_user
3654 +       pushl $(__USER_DS)
3655 +       popl %ds
3656  1:     movb %al,(%ecx)
3657 +       pushl %ss
3658 +       popl %ds
3659         xorl %eax,%eax
3660         EXIT
3661  
3662 @@ -45,7 +50,11 @@ __put_user_2:
3663         subl $1,%ebx
3664         cmpl %ebx,%ecx
3665         jae bad_put_user
3666 +       pushl $(__USER_DS)
3667 +       popl %ds
3668  2:     movw %ax,(%ecx)
3669 +       pushl %ss
3670 +       popl %ds
3671         xorl %eax,%eax
3672         EXIT
3673  
3674 @@ -57,7 +66,11 @@ __put_user_4:
3675         subl $3,%ebx
3676         cmpl %ebx,%ecx
3677         jae bad_put_user
3678 +       pushl $(__USER_DS)
3679 +       popl %ds
3680  3:     movl %eax,(%ecx)
3681 +       pushl %ss
3682 +       popl %ds
3683         xorl %eax,%eax
3684         EXIT
3685  
3686 @@ -69,12 +82,18 @@ __put_user_8:
3687         subl $7,%ebx
3688         cmpl %ebx,%ecx
3689         jae bad_put_user
3690 +       pushl $(__USER_DS)
3691 +       popl %ds
3692  4:     movl %eax,(%ecx)
3693  5:     movl %edx,4(%ecx)
3694 +       pushl %ss
3695 +       popl %ds
3696         xorl %eax,%eax
3697         EXIT
3698  
3699  bad_put_user:
3700 +       pushl %ss
3701 +       popl %ds
3702         movl $-14,%eax
3703         EXIT
3704  
3705 diff -urNp linux-2.6.18/arch/i386/lib/usercopy.c linux-2.6.18/arch/i386/lib/usercopy.c
3706 --- linux-2.6.18/arch/i386/lib/usercopy.c       2006-09-19 23:42:06.000000000 -0400
3707 +++ linux-2.6.18/arch/i386/lib/usercopy.c       2006-09-22 20:45:03.000000000 -0400
3708 @@ -32,6 +32,7 @@ do {                                                                     \
3709         int __d0, __d1, __d2;                                              \
3710         might_sleep();                                                     \
3711         __asm__ __volatile__(                                              \
3712 +               "       movw %w10,%%ds\n"                                  \
3713                 "       testl %1,%1\n"                                     \
3714                 "       jz 2f\n"                                           \
3715                 "0:     lodsb\n"                                           \
3716 @@ -42,6 +43,8 @@ do {                                                                     \
3717                 "       jnz 0b\n"                                          \
3718                 "1:     subl %1,%0\n"                                      \
3719                 "2:\n"                                                     \
3720 +               "       pushl %%ss\n"                                      \
3721 +               "       popl %%ds\n"                                       \
3722                 ".section .fixup,\"ax\"\n"                                 \
3723                 "3:     movl %5,%0\n"                                      \
3724                 "       jmp 2b\n"                                          \
3725 @@ -52,7 +55,8 @@ do {                                                                     \
3726                 ".previous"                                                \
3727                 : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
3728                   "=&D" (__d2)                                             \
3729 -               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
3730 +               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),\
3731 +                 "r"(__USER_DS)                                           \
3732                 : "memory");                                               \
3733  } while (0)
3734  
3735 @@ -122,10 +126,13 @@ do {                                                                      \
3736         int __d0;                                                       \
3737         might_sleep();                                                  \
3738         __asm__ __volatile__(                                           \
3739 +               "       movw %w6,%%es\n"                                \
3740                 "0:     rep; stosl\n"                                   \
3741                 "       movl %2,%0\n"                                   \
3742                 "1:     rep; stosb\n"                                   \
3743                 "2:\n"                                                  \
3744 +               "       pushl %%ss\n"                                   \
3745 +               "       popl %%es\n"                                    \
3746                 ".section .fixup,\"ax\"\n"                              \
3747                 "3:     lea 0(%2,%0,4),%0\n"                            \
3748                 "       jmp 2b\n"                                       \
3749 @@ -136,7 +143,8 @@ do {                                                                        \
3750                 "       .long 1b,2b\n"                                  \
3751                 ".previous"                                             \
3752                 : "=&c"(size), "=&D" (__d0)                             \
3753 -               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
3754 +               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),      \
3755 +                 "r"(__USER_DS));                                      \
3756  } while (0)
3757  
3758  /**
3759 @@ -197,14 +205,17 @@ long strnlen_user(const char __user *s, 
3760         might_sleep();
3761  
3762         __asm__ __volatile__(
3763 +               "       movw %w8,%%es\n"
3764                 "       testl %0, %0\n"
3765                 "       jz 3f\n"
3766 -               "       andl %0,%%ecx\n"
3767 +               "       movl %0,%%ecx\n"
3768                 "0:     repne; scasb\n"
3769                 "       setne %%al\n"
3770                 "       subl %%ecx,%0\n"
3771                 "       addl %0,%%eax\n"
3772                 "1:\n"
3773 +               "       pushl %%ss\n"
3774 +               "       popl %%es\n"
3775                 ".section .fixup,\"ax\"\n"
3776                 "2:     xorl %%eax,%%eax\n"
3777                 "       jmp 1b\n"
3778 @@ -216,7 +227,7 @@ long strnlen_user(const char __user *s, 
3779                 "       .long 0b,2b\n"
3780                 ".previous"
3781                 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
3782 -               :"0" (n), "1" (s), "2" (0), "3" (mask)
3783 +               :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
3784                 :"cc");
3785         return res & mask;
3786  }
3787 @@ -228,6 +239,7 @@ __copy_user_intel(void __user *to, const
3788  {
3789         int d0, d1;
3790         __asm__ __volatile__(
3791 +                      "       movw %w6, %%es\n"
3792                        "       .align 2,0x90\n"
3793                        "1:     movl 32(%4), %%eax\n"
3794                        "       cmpl $67, %0\n"
3795 @@ -236,36 +248,36 @@ __copy_user_intel(void __user *to, const
3796                        "       .align 2,0x90\n"
3797                        "3:     movl 0(%4), %%eax\n"
3798                        "4:     movl 4(%4), %%edx\n"
3799 -                      "5:     movl %%eax, 0(%3)\n"
3800 -                      "6:     movl %%edx, 4(%3)\n"
3801 +                      "5:     movl %%eax, %%es:0(%3)\n"
3802 +                      "6:     movl %%edx, %%es:4(%3)\n"
3803                        "7:     movl 8(%4), %%eax\n"
3804                        "8:     movl 12(%4),%%edx\n"
3805 -                      "9:     movl %%eax, 8(%3)\n"
3806 -                      "10:    movl %%edx, 12(%3)\n"
3807 +                      "9:     movl %%eax, %%es:8(%3)\n"
3808 +                      "10:    movl %%edx, %%es:12(%3)\n"
3809                        "11:    movl 16(%4), %%eax\n"
3810                        "12:    movl 20(%4), %%edx\n"
3811 -                      "13:    movl %%eax, 16(%3)\n"
3812 -                      "14:    movl %%edx, 20(%3)\n"
3813 +                      "13:    movl %%eax, %%es:16(%3)\n"
3814 +                      "14:    movl %%edx, %%es:20(%3)\n"
3815                        "15:    movl 24(%4), %%eax\n"
3816                        "16:    movl 28(%4), %%edx\n"
3817 -                      "17:    movl %%eax, 24(%3)\n"
3818 -                      "18:    movl %%edx, 28(%3)\n"
3819 +                      "17:    movl %%eax, %%es:24(%3)\n"
3820 +                      "18:    movl %%edx, %%es:28(%3)\n"
3821                        "19:    movl 32(%4), %%eax\n"
3822                        "20:    movl 36(%4), %%edx\n"
3823 -                      "21:    movl %%eax, 32(%3)\n"
3824 -                      "22:    movl %%edx, 36(%3)\n"
3825 +                      "21:    movl %%eax, %%es:32(%3)\n"
3826 +                      "22:    movl %%edx, %%es:36(%3)\n"
3827                        "23:    movl 40(%4), %%eax\n"
3828                        "24:    movl 44(%4), %%edx\n"
3829 -                      "25:    movl %%eax, 40(%3)\n"
3830 -                      "26:    movl %%edx, 44(%3)\n"
3831 +                      "25:    movl %%eax, %%es:40(%3)\n"
3832 +                      "26:    movl %%edx, %%es:44(%3)\n"
3833                        "27:    movl 48(%4), %%eax\n"
3834                        "28:    movl 52(%4), %%edx\n"
3835 -                      "29:    movl %%eax, 48(%3)\n"
3836 -                      "30:    movl %%edx, 52(%3)\n"
3837 +                      "29:    movl %%eax, %%es:48(%3)\n"
3838 +                      "30:    movl %%edx, %%es:52(%3)\n"
3839                        "31:    movl 56(%4), %%eax\n"
3840                        "32:    movl 60(%4), %%edx\n"
3841 -                      "33:    movl %%eax, 56(%3)\n"
3842 -                      "34:    movl %%edx, 60(%3)\n"
3843 +                      "33:    movl %%eax, %%es:56(%3)\n"
3844 +                      "34:    movl %%edx, %%es:60(%3)\n"
3845                        "       addl $-64, %0\n"
3846                        "       addl $64, %4\n"
3847                        "       addl $64, %3\n"
3848 @@ -279,6 +291,8 @@ __copy_user_intel(void __user *to, const
3849                        "36:    movl %%eax, %0\n"
3850                        "37:    rep; movsb\n"
3851                        "100:\n"
3852 +                      "       pushl %%ss\n"
3853 +                      "       popl %%es\n"
3854                        ".section .fixup,\"ax\"\n"
3855                        "101:   lea 0(%%eax,%0,4),%0\n"
3856                        "       jmp 100b\n"
3857 @@ -325,7 +339,7 @@ __copy_user_intel(void __user *to, const
3858                        "       .long 99b,101b\n"
3859                        ".previous"
3860                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
3861 -                      :  "1"(to), "2"(from), "0"(size)
3862 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3863                        : "eax", "edx", "memory");
3864         return size;
3865  }
3866 @@ -335,6 +349,7 @@ __copy_user_zeroing_intel(void *to, cons
3867  {
3868         int d0, d1;
3869         __asm__ __volatile__(
3870 +                      "        movw %w6, %%ds\n"
3871                        "        .align 2,0x90\n"
3872                        "0:      movl 32(%4), %%eax\n"
3873                        "        cmpl $67, %0\n"      
3874 @@ -343,36 +358,36 @@ __copy_user_zeroing_intel(void *to, cons
3875                        "        .align 2,0x90\n"     
3876                        "2:      movl 0(%4), %%eax\n" 
3877                        "21:     movl 4(%4), %%edx\n" 
3878 -                      "        movl %%eax, 0(%3)\n" 
3879 -                      "        movl %%edx, 4(%3)\n" 
3880 +                      "        movl %%eax, %%es:0(%3)\n" 
3881 +                      "        movl %%edx, %%es:4(%3)\n" 
3882                        "3:      movl 8(%4), %%eax\n" 
3883                        "31:     movl 12(%4),%%edx\n" 
3884 -                      "        movl %%eax, 8(%3)\n" 
3885 -                      "        movl %%edx, 12(%3)\n"
3886 +                      "        movl %%eax, %%es:8(%3)\n" 
3887 +                      "        movl %%edx, %%es:12(%3)\n"
3888                        "4:      movl 16(%4), %%eax\n"
3889                        "41:     movl 20(%4), %%edx\n"
3890 -                      "        movl %%eax, 16(%3)\n"
3891 -                      "        movl %%edx, 20(%3)\n"
3892 +                      "        movl %%eax, %%es:16(%3)\n"
3893 +                      "        movl %%edx, %%es:20(%3)\n"
3894                        "10:     movl 24(%4), %%eax\n"
3895                        "51:     movl 28(%4), %%edx\n"
3896 -                      "        movl %%eax, 24(%3)\n"
3897 -                      "        movl %%edx, 28(%3)\n"
3898 +                      "        movl %%eax, %%es:24(%3)\n"
3899 +                      "        movl %%edx, %%es:28(%3)\n"
3900                        "11:     movl 32(%4), %%eax\n"
3901                        "61:     movl 36(%4), %%edx\n"
3902 -                      "        movl %%eax, 32(%3)\n"
3903 -                      "        movl %%edx, 36(%3)\n"
3904 +                      "        movl %%eax, %%es:32(%3)\n"
3905 +                      "        movl %%edx, %%es:36(%3)\n"
3906                        "12:     movl 40(%4), %%eax\n"
3907                        "71:     movl 44(%4), %%edx\n"
3908 -                      "        movl %%eax, 40(%3)\n"
3909 -                      "        movl %%edx, 44(%3)\n"
3910 +                      "        movl %%eax, %%es:40(%3)\n"
3911 +                      "        movl %%edx, %%es:44(%3)\n"
3912                        "13:     movl 48(%4), %%eax\n"
3913                        "81:     movl 52(%4), %%edx\n"
3914 -                      "        movl %%eax, 48(%3)\n"
3915 -                      "        movl %%edx, 52(%3)\n"
3916 +                      "        movl %%eax, %%es:48(%3)\n"
3917 +                      "        movl %%edx, %%es:52(%3)\n"
3918                        "14:     movl 56(%4), %%eax\n"
3919                        "91:     movl 60(%4), %%edx\n"
3920 -                      "        movl %%eax, 56(%3)\n"
3921 -                      "        movl %%edx, 60(%3)\n"
3922 +                      "        movl %%eax, %%es:56(%3)\n"
3923 +                      "        movl %%edx, %%es:60(%3)\n"
3924                        "        addl $-64, %0\n"     
3925                        "        addl $64, %4\n"      
3926                        "        addl $64, %3\n"      
3927 @@ -386,6 +401,8 @@ __copy_user_zeroing_intel(void *to, cons
3928                        "        movl %%eax,%0\n"
3929                        "7:      rep; movsb\n"   
3930                        "8:\n"                   
3931 +                      "        pushl %%ss\n"
3932 +                      "        popl %%ds\n"
3933                        ".section .fixup,\"ax\"\n"
3934                        "9:      lea 0(%%eax,%0,4),%0\n" 
3935                        "16:     pushl %0\n"     
3936 @@ -420,7 +437,7 @@ __copy_user_zeroing_intel(void *to, cons
3937                        "        .long 7b,16b\n" 
3938                        ".previous"              
3939                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
3940 -                      :  "1"(to), "2"(from), "0"(size)
3941 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3942                        : "eax", "edx", "memory");
3943         return size;
3944  }
3945 @@ -436,6 +453,7 @@ static unsigned long __copy_user_zeroing
3946          int d0, d1;
3947  
3948         __asm__ __volatile__(
3949 +              "        movw %w6, %%ds\n"
3950                "        .align 2,0x90\n"
3951                "0:      movl 32(%4), %%eax\n"
3952                "        cmpl $67, %0\n"
3953 @@ -444,36 +462,36 @@ static unsigned long __copy_user_zeroing
3954                "        .align 2,0x90\n"
3955                "2:      movl 0(%4), %%eax\n"
3956                "21:     movl 4(%4), %%edx\n"
3957 -              "        movnti %%eax, 0(%3)\n"
3958 -              "        movnti %%edx, 4(%3)\n"
3959 +              "        movnti %%eax, %%es:0(%3)\n"
3960 +              "        movnti %%edx, %%es:4(%3)\n"
3961                "3:      movl 8(%4), %%eax\n"
3962                "31:     movl 12(%4),%%edx\n"
3963 -              "        movnti %%eax, 8(%3)\n"
3964 -              "        movnti %%edx, 12(%3)\n"
3965 +              "        movnti %%eax, %%es:8(%3)\n"
3966 +              "        movnti %%edx, %%es:12(%3)\n"
3967                "4:      movl 16(%4), %%eax\n"
3968                "41:     movl 20(%4), %%edx\n"
3969 -              "        movnti %%eax, 16(%3)\n"
3970 -              "        movnti %%edx, 20(%3)\n"
3971 +              "        movnti %%eax, %%es:16(%3)\n"
3972 +              "        movnti %%edx, %%es:20(%3)\n"
3973                "10:     movl 24(%4), %%eax\n"
3974                "51:     movl 28(%4), %%edx\n"
3975 -              "        movnti %%eax, 24(%3)\n"
3976 -              "        movnti %%edx, 28(%3)\n"
3977 +              "        movnti %%eax, %%es:24(%3)\n"
3978 +              "        movnti %%edx, %%es:28(%3)\n"
3979                "11:     movl 32(%4), %%eax\n"
3980                "61:     movl 36(%4), %%edx\n"
3981 -              "        movnti %%eax, 32(%3)\n"
3982 -              "        movnti %%edx, 36(%3)\n"
3983 +              "        movnti %%eax, %%es:32(%3)\n"
3984 +              "        movnti %%edx, %%es:36(%3)\n"
3985                "12:     movl 40(%4), %%eax\n"
3986                "71:     movl 44(%4), %%edx\n"
3987 -              "        movnti %%eax, 40(%3)\n"
3988 -              "        movnti %%edx, 44(%3)\n"
3989 +              "        movnti %%eax, %%es:40(%3)\n"
3990 +              "        movnti %%edx, %%es:44(%3)\n"
3991                "13:     movl 48(%4), %%eax\n"
3992                "81:     movl 52(%4), %%edx\n"
3993 -              "        movnti %%eax, 48(%3)\n"
3994 -              "        movnti %%edx, 52(%3)\n"
3995 +              "        movnti %%eax, %%es:48(%3)\n"
3996 +              "        movnti %%edx, %%es:52(%3)\n"
3997                "14:     movl 56(%4), %%eax\n"
3998                "91:     movl 60(%4), %%edx\n"
3999 -              "        movnti %%eax, 56(%3)\n"
4000 -              "        movnti %%edx, 60(%3)\n"
4001 +              "        movnti %%eax, %%es:56(%3)\n"
4002 +              "        movnti %%edx, %%es:60(%3)\n"
4003                "        addl $-64, %0\n"
4004                "        addl $64, %4\n"
4005                "        addl $64, %3\n"
4006 @@ -488,6 +506,8 @@ static unsigned long __copy_user_zeroing
4007                "        movl %%eax,%0\n"
4008                "7:      rep; movsb\n"
4009                "8:\n"
4010 +              "        pushl %%ss\n"
4011 +              "        popl %%ds\n"
4012                ".section .fixup,\"ax\"\n"
4013                "9:      lea 0(%%eax,%0,4),%0\n"
4014                "16:     pushl %0\n"
4015 @@ -522,7 +542,7 @@ static unsigned long __copy_user_zeroing
4016                "        .long 7b,16b\n"
4017                ".previous"
4018                : "=&c"(size), "=&D" (d0), "=&S" (d1)
4019 -              :  "1"(to), "2"(from), "0"(size)
4020 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4021                : "eax", "edx", "memory");
4022         return size;
4023  }
4024 @@ -533,6 +553,7 @@ static unsigned long __copy_user_intel_n
4025          int d0, d1;
4026  
4027         __asm__ __volatile__(
4028 +              "        movw %w6, %%ds\n"
4029                "        .align 2,0x90\n"
4030                "0:      movl 32(%4), %%eax\n"
4031                "        cmpl $67, %0\n"
4032 @@ -541,36 +562,36 @@ static unsigned long __copy_user_intel_n
4033                "        .align 2,0x90\n"
4034                "2:      movl 0(%4), %%eax\n"
4035                "21:     movl 4(%4), %%edx\n"
4036 -              "        movnti %%eax, 0(%3)\n"
4037 -              "        movnti %%edx, 4(%3)\n"
4038 +              "        movnti %%eax, %%es:0(%3)\n"
4039 +              "        movnti %%edx, %%es:4(%3)\n"
4040                "3:      movl 8(%4), %%eax\n"
4041                "31:     movl 12(%4),%%edx\n"
4042 -              "        movnti %%eax, 8(%3)\n"
4043 -              "        movnti %%edx, 12(%3)\n"
4044 +              "        movnti %%eax, %%es:8(%3)\n"
4045 +              "        movnti %%edx, %%es:12(%3)\n"
4046                "4:      movl 16(%4), %%eax\n"
4047                "41:     movl 20(%4), %%edx\n"
4048 -              "        movnti %%eax, 16(%3)\n"
4049 -              "        movnti %%edx, 20(%3)\n"
4050 +              "        movnti %%eax, %%es:16(%3)\n"
4051 +              "        movnti %%edx, %%es:20(%3)\n"
4052                "10:     movl 24(%4), %%eax\n"
4053                "51:     movl 28(%4), %%edx\n"
4054 -              "        movnti %%eax, 24(%3)\n"
4055 -              "        movnti %%edx, 28(%3)\n"
4056 +              "        movnti %%eax, %%es:24(%3)\n"
4057 +              "        movnti %%edx, %%es:28(%3)\n"
4058                "11:     movl 32(%4), %%eax\n"
4059                "61:     movl 36(%4), %%edx\n"
4060 -              "        movnti %%eax, 32(%3)\n"
4061 -              "        movnti %%edx, 36(%3)\n"
4062 +              "        movnti %%eax, %%es:32(%3)\n"
4063 +              "        movnti %%edx, %%es:36(%3)\n"
4064                "12:     movl 40(%4), %%eax\n"
4065                "71:     movl 44(%4), %%edx\n"
4066 -              "        movnti %%eax, 40(%3)\n"
4067 -              "        movnti %%edx, 44(%3)\n"
4068 +              "        movnti %%eax, %%es:40(%3)\n"
4069 +              "        movnti %%edx, %%es:44(%3)\n"
4070                "13:     movl 48(%4), %%eax\n"
4071                "81:     movl 52(%4), %%edx\n"
4072 -              "        movnti %%eax, 48(%3)\n"
4073 -              "        movnti %%edx, 52(%3)\n"
4074 +              "        movnti %%eax, %%es:48(%3)\n"
4075 +              "        movnti %%edx, %%es:52(%3)\n"
4076                "14:     movl 56(%4), %%eax\n"
4077                "91:     movl 60(%4), %%edx\n"
4078 -              "        movnti %%eax, 56(%3)\n"
4079 -              "        movnti %%edx, 60(%3)\n"
4080 +              "        movnti %%eax, %%es:56(%3)\n"
4081 +              "        movnti %%edx, %%es:60(%3)\n"
4082                "        addl $-64, %0\n"
4083                "        addl $64, %4\n"
4084                "        addl $64, %3\n"
4085 @@ -585,6 +606,8 @@ static unsigned long __copy_user_intel_n
4086                "        movl %%eax,%0\n"
4087                "7:      rep; movsb\n"
4088                "8:\n"
4089 +              "        pushl %%ss\n"
4090 +              "        popl %%ds\n"
4091                ".section .fixup,\"ax\"\n"
4092                "9:      lea 0(%%eax,%0,4),%0\n"
4093                "16:     jmp 8b\n"
4094 @@ -613,7 +636,7 @@ static unsigned long __copy_user_intel_n
4095                "        .long 7b,16b\n"
4096                ".previous"
4097                : "=&c"(size), "=&D" (d0), "=&S" (d1)
4098 -              :  "1"(to), "2"(from), "0"(size)
4099 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4100                : "eax", "edx", "memory");
4101         return size;
4102  }
4103 @@ -637,6 +660,7 @@ unsigned long __copy_user_zeroing_intel_
4104  do {                                                                   \
4105         int __d0, __d1, __d2;                                           \
4106         __asm__ __volatile__(                                           \
4107 +               "       movw %w8,%%es\n"                                \
4108                 "       cmp  $7,%0\n"                                   \
4109                 "       jbe  1f\n"                                      \
4110                 "       movl %1,%0\n"                                   \
4111 @@ -652,6 +676,8 @@ do {                                                                        \
4112                 "       movl %3,%0\n"                                   \
4113                 "1:     rep; movsb\n"                                   \
4114                 "2:\n"                                                  \
4115 +               "       pushl %%ss\n"                                   \
4116 +               "       popl %%es\n"                                    \
4117                 ".section .fixup,\"ax\"\n"                              \
4118                 "5:     addl %3,%0\n"                                   \
4119                 "       jmp 2b\n"                                       \
4120 @@ -665,7 +691,7 @@ do {                                                                        \
4121                 "       .long 1b,2b\n"                                  \
4122                 ".previous"                                             \
4123                 : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
4124 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
4125 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)\
4126                 : "memory");                                            \
4127  } while (0)
4128  
4129 @@ -673,6 +699,7 @@ do {                                                                        \
4130  do {                                                                   \
4131         int __d0, __d1, __d2;                                           \
4132         __asm__ __volatile__(                                           \
4133 +               "       movw %w8,%%ds\n"                                \
4134                 "       cmp  $7,%0\n"                                   \
4135                 "       jbe  1f\n"                                      \
4136                 "       movl %1,%0\n"                                   \
4137 @@ -688,6 +715,8 @@ do {                                                                        \
4138                 "       movl %3,%0\n"                                   \
4139                 "1:     rep; movsb\n"                                   \
4140                 "2:\n"                                                  \
4141 +               "       pushl %%ss\n"                                   \
4142 +               "       popl %%ds\n"                                    \
4143                 ".section .fixup,\"ax\"\n"                              \
4144                 "5:     addl %3,%0\n"                                   \
4145                 "       jmp 6f\n"                                       \
4146 @@ -707,7 +736,7 @@ do {                                                                        \
4147                 "       .long 1b,6b\n"                                  \
4148                 ".previous"                                             \
4149                 : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
4150 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
4151 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)\
4152                 : "memory");                                            \
4153  } while (0)
4154  
4155 @@ -877,3 +906,45 @@ copy_from_user(void *to, const void __us
4156         return n;
4157  }
4158  EXPORT_SYMBOL(copy_from_user);
4159 +
4160 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4161 +void __set_fs(mm_segment_t x, int cpu)
4162 +{
4163 +       unsigned long limit = x.seg;
4164 +
4165 +       current_thread_info()->addr_limit = x;
4166 +       if (likely(limit)) {
4167 +               limit -= 1UL;
4168 +               limit >>= 12;
4169 +       }
4170 +
4171 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].a = (limit & 0xFFFFUL);
4172 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].b = (limit & 0xF0000UL) | 0xC0F300UL;
4173 +}
4174 +
4175 +void set_fs(mm_segment_t x)
4176 +{
4177 +       int cpu = get_cpu();
4178 +
4179 +#ifdef CONFIG_PAX_KERNEXEC
4180 +       unsigned long cr0;
4181 +
4182 +       pax_open_kernel(cr0);
4183 +#endif
4184 +
4185 +       __set_fs(x, cpu);
4186 +
4187 +#ifdef CONFIG_PAX_KERNEXEC
4188 +       pax_close_kernel(cr0);
4189 +#endif
4190 +
4191 +       put_cpu_no_resched();
4192 +}
4193 +#else
4194 +void set_fs(mm_segment_t x)
4195 +{
4196 +       current_thread_info()->addr_limit = x;
4197 +}
4198 +#endif
4199 +
4200 +EXPORT_SYMBOL(set_fs);
4201 diff -urNp linux-2.6.18/arch/i386/mach-voyager/voyager_smp.c linux-2.6.18/arch/i386/mach-voyager/voyager_smp.c
4202 --- linux-2.6.18/arch/i386/mach-voyager/voyager_smp.c   2006-09-19 23:42:06.000000000 -0400
4203 +++ linux-2.6.18/arch/i386/mach-voyager/voyager_smp.c   2006-09-22 20:45:03.000000000 -0400
4204 @@ -1295,7 +1295,7 @@ smp_local_timer_interrupt(struct pt_regs
4205                                                 per_cpu(prof_counter, cpu);
4206                 }
4207  
4208 -               update_process_times(user_mode_vm(regs));
4209 +               update_process_times(user_mode(regs));
4210         }
4211  
4212         if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
4213 diff -urNp linux-2.6.18/arch/i386/mm/boot_ioremap.c linux-2.6.18/arch/i386/mm/boot_ioremap.c
4214 --- linux-2.6.18/arch/i386/mm/boot_ioremap.c    2006-09-19 23:42:06.000000000 -0400
4215 +++ linux-2.6.18/arch/i386/mm/boot_ioremap.c    2006-09-22 20:45:03.000000000 -0400
4216 @@ -7,53 +7,36 @@
4217   * Written by Dave Hansen <haveblue@us.ibm.com>
4218   */
4219  
4220 -
4221 -/*
4222 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
4223 - * keeps that from happenning.  If anyone has a better way, I'm listening.
4224 - *
4225 - * boot_pte_t is defined only if this all works correctly
4226 - */
4227 -
4228 -#undef CONFIG_X86_PAE
4229  #include <asm/page.h>
4230  #include <asm/pgtable.h>
4231  #include <asm/tlbflush.h>
4232  #include <linux/init.h>
4233  #include <linux/stddef.h>
4234  
4235 -/* 
4236 - * I'm cheating here.  It is known that the two boot PTE pages are 
4237 - * allocated next to each other.  I'm pretending that they're just
4238 - * one big array. 
4239 - */
4240 -
4241 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
4242 -#define boot_pte_index(address) \
4243 -            (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
4244 -
4245 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
4246 -{
4247 -       boot_pte_t* boot_pg = (boot_pte_t*)pg0;
4248 -       return &boot_pg[boot_pte_index((unsigned long)address)];
4249 -}
4250 -
4251  /*
4252   * This is only for a caller who is clever enough to page-align
4253   * phys_addr and virtual_source, and who also has a preference
4254   * about which virtual address from which to steal ptes
4255   */
4256 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
4257 -                   void* virtual_source)
4258 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
4259 +                   char* virtual_source)
4260  {
4261 -       boot_pte_t* pte;
4262 -       int i;
4263 -       char *vaddr = virtual_source;
4264 +       pgd_t *pgd;
4265 +       pud_t *pud;
4266 +       pmd_t *pmd;
4267 +       pte_t* pte;
4268 +       unsigned int i;
4269 +       unsigned long vaddr = (unsigned long)virtual_source;
4270 +
4271 +       pgd = pgd_offset_k(vaddr);
4272 +       pud = pud_offset(pgd, vaddr);
4273 +       pmd = pmd_offset(pud, vaddr);
4274 +       pte = pte_offset_kernel(pmd, vaddr);
4275  
4276         pte = boot_vaddr_to_pte(virtual_source);
4277         for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
4278                 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
4279 -               __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
4280 +               __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
4281         }
4282  }
4283  
4284 diff -urNp linux-2.6.18/arch/i386/mm/extable.c linux-2.6.18/arch/i386/mm/extable.c
4285 --- linux-2.6.18/arch/i386/mm/extable.c 2006-09-19 23:42:06.000000000 -0400
4286 +++ linux-2.6.18/arch/i386/mm/extable.c 2006-09-22 20:45:03.000000000 -0400
4287 @@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs
4288         const struct exception_table_entry *fixup;
4289  
4290  #ifdef CONFIG_PNPBIOS
4291 -       if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
4292 +       if (unlikely(!(regs->eflags & VM_MASK) && ((regs->xcs & 0xFFFCU) == PNP_CS32 || (regs->xcs & 0xFFFCU) == PNP_CS16)))
4293         {
4294                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
4295                 extern u32 pnp_bios_is_utter_crap;
4296 diff -urNp linux-2.6.18/arch/i386/mm/fault.c linux-2.6.18/arch/i386/mm/fault.c
4297 --- linux-2.6.18/arch/i386/mm/fault.c   2006-09-19 23:42:06.000000000 -0400
4298 +++ linux-2.6.18/arch/i386/mm/fault.c   2006-09-23 00:26:29.000000000 -0400
4299 @@ -22,6 +22,9 @@
4300  #include <linux/highmem.h>
4301  #include <linux/module.h>
4302  #include <linux/kprobes.h>
4303 +#include <linux/unistd.h>
4304 +#include <linux/compiler.h>
4305 +#include <linux/binfmts.h>
4306  
4307  #include <asm/system.h>
4308  #include <asm/uaccess.h>
4309 @@ -122,9 +125,12 @@ static inline unsigned long get_segment_
4310         *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg;
4311         
4312         /* By far the most common cases. */
4313 -       if (likely(seg == __USER_CS || seg == __KERNEL_CS))
4314 +       if (likely(seg == __USER_CS))
4315                 return eip;
4316  
4317 +       if (likely(seg == __KERNEL_CS))
4318 +               return eip + __KERNEL_TEXT_OFFSET;
4319 +
4320         /* Check the segment exists, is within the current LDT/GDT size,
4321            that kernel/user (ring 0..3) has the appropriate privilege,
4322            that it's a code segment, and get the limit. */
4323 @@ -251,6 +257,30 @@ static noinline void force_sig_info_faul
4324  
4325  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
4326  
4327 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4328 +static int pax_handle_fetch_fault(struct pt_regs *regs);
4329 +#endif
4330 +
4331 +#ifdef CONFIG_PAX_PAGEEXEC
4332 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
4333 +{
4334 +       pgd_t *pgd;
4335 +       pud_t *pud;
4336 +       pmd_t *pmd;
4337 +
4338 +       pgd = pgd_offset(mm, address);
4339 +       if (!pgd_present(*pgd))
4340 +               return NULL;
4341 +       pud = pud_offset(pgd, address);
4342 +       if (!pud_present(*pud))
4343 +               return NULL;
4344 +       pmd = pmd_offset(pud, address);
4345 +       if (!pmd_present(*pmd))
4346 +               return NULL;
4347 +       return pmd;
4348 +}
4349 +#endif
4350 +
4351  static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
4352  {
4353         unsigned index = pgd_index(address);
4354 @@ -332,13 +362,20 @@ fastcall void __kprobes do_page_fault(st
4355         struct mm_struct *mm;
4356         struct vm_area_struct * vma;
4357         unsigned long address;
4358 -       unsigned long page;
4359         int write, si_code;
4360  
4361 +#ifdef CONFIG_PAX_PAGEEXEC
4362 +       pmd_t *pmd;
4363 +       pte_t *pte;
4364 +       spinlock_t *ptl;
4365 +       unsigned char pte_mask;
4366 +#endif
4367 +
4368         /* get the address */
4369          address = read_cr2();
4370  
4371         tsk = current;
4372 +       mm = tsk->mm;
4373  
4374         si_code = SEGV_MAPERR;
4375  
4376 @@ -377,14 +414,12 @@ fastcall void __kprobes do_page_fault(st
4377         if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
4378                 local_irq_enable();
4379  
4380 -       mm = tsk->mm;
4381 -
4382         /*
4383          * If we're in an interrupt, have no user context or are running in an
4384          * atomic region then we must not take the fault..
4385          */
4386         if (in_atomic() || !mm)
4387 -               goto bad_area_nosemaphore;
4388 +               goto bad_area_nopax;
4389  
4390         /* When running in the kernel we expect faults to occur only to
4391          * addresses in user space.  All other faults represent errors in the
4392 @@ -404,10 +439,101 @@ fastcall void __kprobes do_page_fault(st
4393         if (!down_read_trylock(&mm->mmap_sem)) {
4394                 if ((error_code & 4) == 0 &&
4395                     !search_exception_tables(regs->eip))
4396 -                       goto bad_area_nosemaphore;
4397 +                       goto bad_area_nopax;
4398                 down_read(&mm->mmap_sem);
4399         }
4400  
4401 +#ifdef CONFIG_PAX_PAGEEXEC
4402 +       if (unlikely((error_code & 5) != 5 ||
4403 +                    (regs->eflags & X86_EFLAGS_VM) ||
4404 +                    !(mm->pax_flags & MF_PAX_PAGEEXEC)))
4405 +               goto not_pax_fault;
4406 +
4407 +       /* PaX: it's our fault, let's handle it if we can */
4408 +
4409 +       /* PaX: take a look at read faults before acquiring any locks */
4410 +       if (unlikely(!(error_code & 2) && (regs->eip == address))) {
4411 +               /* instruction fetch attempt from a protected page in user mode */
4412 +               up_read(&mm->mmap_sem);
4413 +               switch (pax_handle_fetch_fault(regs)) {
4414 +
4415 +#ifdef CONFIG_PAX_EMUTRAMP
4416 +               case 2:
4417 +                       return;
4418 +#endif
4419 +
4420 +               }
4421 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4422 +               do_exit(SIGKILL);
4423 +       }
4424 +
4425 +       pmd = pax_get_pmd(mm, address);
4426 +       if (unlikely(!pmd))
4427 +               goto not_pax_fault;
4428 +
4429 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
4430 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
4431 +               pte_unmap_unlock(pte, ptl);
4432 +               goto not_pax_fault;
4433 +       }
4434 +
4435 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
4436 +               /* write attempt to a protected page in user mode */
4437 +               pte_unmap_unlock(pte, ptl);
4438 +               goto not_pax_fault;
4439 +       }
4440 +
4441 +#ifdef CONFIG_SMP
4442 +       if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
4443 +#else
4444 +       if (likely(address > get_limit(regs->xcs)))
4445 +#endif
4446 +       {
4447 +               set_pte(pte, pte_mkread(*pte));
4448 +               __flush_tlb_one(address);
4449 +               pte_unmap_unlock(pte, ptl);
4450 +               up_read(&mm->mmap_sem);
4451 +               return;
4452 +       }
4453 +
4454 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
4455 +
4456 +       /*
4457 +        * PaX: fill DTLB with user rights and retry
4458 +        */
4459 +       __asm__ __volatile__ (
4460 +               "movw %w4,%%ds\n"
4461 +               "orb %2,%%ss:(%1)\n"
4462 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
4463 +/*
4464 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
4465 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
4466 + * page fault when examined during a TLB load attempt. this is true not only
4467 + * for PTEs holding a non-present entry but also present entries that will
4468 + * raise a page fault (such as those set up by PaX, or the copy-on-write
4469 + * mechanism). in effect it means that we do *not* need to flush the TLBs
4470 + * for our target pages since their PTEs are simply not in the TLBs at all.
4471 +
4472 + * the best thing in omitting it is that we gain around 15-20% speed in the
4473 + * fast path of the page fault handler and can get rid of tracing since we
4474 + * can no longer flush unintended entries.
4475 + */
4476 +               "invlpg (%0)\n"
4477 +#endif
4478 +               "testb $0,(%0)\n"
4479 +               "xorb %3,%%ss:(%1)\n"
4480 +               "pushl %%ss\n"
4481 +               "popl %%ds\n"
4482 +               :
4483 +               : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
4484 +               : "memory", "cc");
4485 +       pte_unmap_unlock(pte, ptl);
4486 +       up_read(&mm->mmap_sem);
4487 +       return;
4488 +
4489 +not_pax_fault:
4490 +#endif
4491 +
4492         vma = find_vma(mm, address);
4493         if (!vma)
4494                 goto bad_area;
4495 @@ -493,6 +619,37 @@ bad_area:
4496         up_read(&mm->mmap_sem);
4497  
4498  bad_area_nosemaphore:
4499 +
4500 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4501 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
4502 +
4503 +#ifdef CONFIG_PAX_PAGEEXEC
4504 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
4505 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4506 +                       do_exit(SIGKILL);
4507 +               }
4508 +#endif
4509 +
4510 +#ifdef CONFIG_PAX_SEGMEXEC
4511 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
4512 +
4513 +                       switch (pax_handle_fetch_fault(regs)) {
4514 +
4515 +#ifdef CONFIG_PAX_EMUTRAMP
4516 +                       case 2:
4517 +                               return;
4518 +#endif
4519 +
4520 +                       }
4521 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4522 +                       do_exit(SIGKILL);
4523 +               }
4524 +#endif
4525 +
4526 +       }
4527 +#endif
4528 +
4529 +bad_area_nopax:
4530         /* User mode accesses just cause a SIGSEGV */
4531         if (error_code & 4) {
4532                 /* 
4533 @@ -560,6 +717,21 @@ no_context:
4534                 if (address < PAGE_SIZE)
4535                         printk(KERN_ALERT "BUG: unable to handle kernel NULL "
4536                                         "pointer dereference");
4537 +
4538 +#ifdef CONFIG_PAX_KERNEXEC
4539 +#ifdef CONFIG_MODULES
4540 +               else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
4541 +#else
4542 +               else if (init_mm.start_code <= address && address < init_mm.end_code)
4543 +#endif
4544 +                       if (tsk->signal->curr_ip)
4545 +                               printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
4546 +                                                NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
4547 +                       else
4548 +                               printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
4549 +                                                tsk->comm, tsk->pid, tsk->uid, tsk->euid);
4550 +#endif
4551 +
4552                 else
4553                         printk(KERN_ALERT "BUG: unable to handle kernel paging"
4554                                         " request");
4555 @@ -567,24 +739,34 @@ no_context:
4556                 printk(KERN_ALERT " printing eip:\n");
4557                 printk("%08lx\n", regs->eip);
4558         }
4559 -       page = read_cr3();
4560 -       page = ((unsigned long *) __va(page))[address >> 22];
4561 -       if (oops_may_print())
4562 -               printk(KERN_ALERT "*pde = %08lx\n", page);
4563 -       /*
4564 -        * We must not directly access the pte in the highpte
4565 -        * case, the page table might be allocated in highmem.
4566 -        * And lets rather not kmap-atomic the pte, just in case
4567 -        * it's allocated already.
4568 -        */
4569 +
4570 +       if (oops_may_print()) {
4571 +               unsigned long index = pgd_index(address);
4572 +               pgd_t *pgd;
4573 +               pud_t *pud;
4574 +               pmd_t *pmd;
4575 +               pte_t *pte;
4576 +
4577 +               pgd = index + (pgd_t *)__va(read_cr3());
4578 +               printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
4579 +               if (pgd_present(*pgd)) {
4580 +                       pud = pud_offset(pgd, address);
4581 +                       pmd = pmd_offset(pud, address);
4582 +                       printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
4583 +                       /*
4584 +                        * We must not directly access the pte in the highpte
4585 +                        * case, the page table might be allocated in highmem.
4586 +                        * And lets rather not kmap-atomic the pte, just in case
4587 +                        * it's allocated already.
4588 +                        */
4589  #ifndef CONFIG_HIGHPTE
4590 -       if ((page & 1) && oops_may_print()) {
4591 -               page &= PAGE_MASK;
4592 -               address &= 0x003ff000;
4593 -               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
4594 -               printk(KERN_ALERT "*pte = %08lx\n", page);
4595 -       }
4596 +                       if (pmd_present(*pmd) && !pmd_large(*pmd)) {
4597 +                               pte = pte_offset_kernel(pmd, address);
4598 +                               printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
4599 +                       }
4600  #endif
4601 +               }
4602 +       }
4603         tsk->thread.cr2 = address;
4604         tsk->thread.trap_no = 14;
4605         tsk->thread.error_code = error_code;
4606 @@ -661,3 +843,105 @@ void vmalloc_sync_all(void)
4607         }
4608  }
4609  #endif
4610 +
4611 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4612 +/*
4613 + * PaX: decide what to do with offenders (regs->eip = fault address)
4614 + *
4615 + * returns 1 when task should be killed
4616 + *         2 when gcc trampoline was detected
4617 + */
4618 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4619 +{
4620 +
4621 +#ifdef CONFIG_PAX_EMUTRAMP
4622 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
4623 +       int err;
4624 +#endif
4625 +
4626 +       if (regs->eflags & X86_EFLAGS_VM)
4627 +               return 1;
4628 +
4629 +#ifdef CONFIG_PAX_EMUTRAMP
4630 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
4631 +               return 1;
4632 +
4633 +       do { /* PaX: gcc trampoline emulation #1 */
4634 +               unsigned char mov1, mov2;
4635 +               unsigned short jmp;
4636 +               unsigned long addr1, addr2;
4637 +
4638 +               err = get_user(mov1, (unsigned char __user *)regs->eip);
4639 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
4640 +               err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
4641 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
4642 +               err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
4643 +
4644 +               if (err)
4645 +                       break;
4646 +
4647 +               if ((mov1 & 0xF8) == 0xB8 &&
4648 +                   (mov2 & 0xF8) == 0xB8 &&
4649 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
4650 +                   (jmp & 0xF8FF) == 0xE0FF &&
4651 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07))
4652 +               {
4653 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
4654 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
4655 +                       regs->eip = addr2;
4656 +                       return 2;
4657 +               }
4658 +       } while (0);
4659 +
4660 +       do { /* PaX: gcc trampoline emulation #2 */
4661 +               unsigned char mov, jmp;
4662 +               unsigned long addr1, addr2;
4663 +
4664 +               err = get_user(mov, (unsigned char __user *)regs->eip);
4665 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
4666 +               err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
4667 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
4668 +
4669 +               if (err)
4670 +                       break;
4671 +
4672 +               if ((mov & 0xF8) == 0xB8 &&
4673 +                   jmp == 0xE9)
4674 +               {
4675 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
4676 +                       regs->eip += addr2 + 10;
4677 +                       return 2;
4678 +               }
4679 +       } while (0);
4680 +#endif
4681 +
4682 +       return 1; /* PaX in action */
4683 +}
4684 +#endif
4685 +
4686 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4687 +void pax_report_insns(void *pc, void *sp)
4688 +{
4689 +       long i;
4690 +
4691 +       printk(KERN_ERR "PAX: bytes at PC: ");
4692 +       for (i = 0; i < 20; i++) {
4693 +               unsigned char c;
4694 +               if (get_user(c, (unsigned char __user *)pc+i))
4695 +                       printk("?? ");
4696 +               else
4697 +                       printk("%02x ", c);
4698 +       }
4699 +       printk("\n");
4700 +
4701 +       printk(KERN_ERR "PAX: bytes at SP-4: ");
4702 +       for (i = -1; i < 20; i++) {
4703 +               unsigned long c;
4704 +               if (get_user(c, (unsigned long __user *)sp+i))
4705 +                       printk("???????? ");
4706 +               else
4707 +                       printk("%08lx ", c);
4708 +       }
4709 +       printk("\n");
4710 +}
4711 +#endif
4712 diff -urNp linux-2.6.18/arch/i386/mm/hugetlbpage.c linux-2.6.18/arch/i386/mm/hugetlbpage.c
4713 --- linux-2.6.18/arch/i386/mm/hugetlbpage.c     2006-09-19 23:42:06.000000000 -0400
4714 +++ linux-2.6.18/arch/i386/mm/hugetlbpage.c     2006-09-22 20:45:03.000000000 -0400
4715 @@ -120,7 +120,12 @@ static unsigned long hugetlb_get_unmappe
4716  {
4717         struct mm_struct *mm = current->mm;
4718         struct vm_area_struct *vma;
4719 -       unsigned long start_addr;
4720 +       unsigned long start_addr, task_size = TASK_SIZE;
4721 +
4722 +#ifdef CONFIG_PAX_SEGMEXEC
4723 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
4724 +               task_size = SEGMEXEC_TASK_SIZE;
4725 +#endif
4726  
4727         if (len > mm->cached_hole_size) {
4728                 start_addr = mm->free_area_cache;
4729 @@ -134,7 +139,7 @@ full_search:
4730  
4731         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
4732                 /* At this point:  (!vma || addr < vma->vm_end). */
4733 -               if (TASK_SIZE - len < addr) {
4734 +               if (task_size - len < addr) {
4735                         /*
4736                          * Start a new search - just in case we missed
4737                          * some holes.
4738 @@ -162,9 +167,8 @@ static unsigned long hugetlb_get_unmappe
4739  {
4740         struct mm_struct *mm = current->mm;
4741         struct vm_area_struct *vma, *prev_vma;
4742 -       unsigned long base = mm->mmap_base, addr = addr0;
4743 +       unsigned long base = mm->mmap_base, addr;
4744         unsigned long largest_hole = mm->cached_hole_size;
4745 -       int first_time = 1;
4746  
4747         /* don't allow allocations above current base */
4748         if (mm->free_area_cache > base)
4749 @@ -174,7 +178,7 @@ static unsigned long hugetlb_get_unmappe
4750                 largest_hole = 0;
4751                 mm->free_area_cache  = base;
4752         }
4753 -try_again:
4754 +
4755         /* make sure it can fit in the remaining address space */
4756         if (mm->free_area_cache < len)
4757                 goto fail;
4758 @@ -216,16 +220,6 @@ try_again:
4759  
4760  fail:
4761         /*
4762 -        * if hint left us with no space for the requested
4763 -        * mapping then try again:
4764 -        */
4765 -       if (first_time) {
4766 -               mm->free_area_cache = base;
4767 -               largest_hole = 0;
4768 -               first_time = 0;
4769 -               goto try_again;
4770 -       }
4771 -       /*
4772          * A failed mmap() very likely causes application failure,
4773          * so fall back to the bottom-up function here. This scenario
4774          * can happen with large stack limits and large mmap()
4775 @@ -251,16 +245,23 @@ hugetlb_get_unmapped_area(struct file *f
4776  {
4777         struct mm_struct *mm = current->mm;
4778         struct vm_area_struct *vma;
4779 +       unsigned long task_size = TASK_SIZE;
4780  
4781         if (len & ~HPAGE_MASK)
4782                 return -EINVAL;
4783 -       if (len > TASK_SIZE)
4784 +
4785 +#ifdef CONFIG_PAX_SEGMEXEC
4786 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
4787 +               task_size = SEGMEXEC_TASK_SIZE;
4788 +#endif
4789 +
4790 +       if (len > task_size || addr > task_size - len)
4791                 return -ENOMEM;
4792  
4793         if (addr) {
4794                 addr = ALIGN(addr, HPAGE_SIZE);
4795                 vma = find_vma(mm, addr);
4796 -               if (TASK_SIZE - len >= addr &&
4797 +               if (task_size - len >= addr &&
4798                     (!vma || addr + len <= vma->vm_start))
4799                         return addr;
4800         }
4801 diff -urNp linux-2.6.18/arch/i386/mm/init.c linux-2.6.18/arch/i386/mm/init.c
4802 --- linux-2.6.18/arch/i386/mm/init.c    2006-09-19 23:42:06.000000000 -0400
4803 +++ linux-2.6.18/arch/i386/mm/init.c    2006-09-22 20:45:03.000000000 -0400
4804 @@ -42,6 +42,7 @@
4805  #include <asm/tlb.h>
4806  #include <asm/tlbflush.h>
4807  #include <asm/sections.h>
4808 +#include <asm/desc.h>
4809  
4810  unsigned int __VMALLOC_RESERVE = 128 << 20;
4811  
4812 @@ -51,30 +52,6 @@ unsigned long highstart_pfn, highend_pfn
4813  static int noinline do_test_wp_bit(void);
4814  
4815  /*
4816 - * Creates a middle page table and puts a pointer to it in the
4817 - * given global directory entry. This only returns the gd entry
4818 - * in non-PAE compilation mode, since the middle layer is folded.
4819 - */
4820 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
4821 -{
4822 -       pud_t *pud;
4823 -       pmd_t *pmd_table;
4824 -               
4825 -#ifdef CONFIG_X86_PAE
4826 -       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
4827 -       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
4828 -       pud = pud_offset(pgd, 0);
4829 -       if (pmd_table != pmd_offset(pud, 0)) 
4830 -               BUG();
4831 -#else
4832 -       pud = pud_offset(pgd, 0);
4833 -       pmd_table = pmd_offset(pud, 0);
4834 -#endif
4835 -
4836 -       return pmd_table;
4837 -}
4838 -
4839 -/*
4840   * Create a page table and place a pointer to it in a middle page
4841   * directory entry.
4842   */
4843 @@ -82,7 +59,11 @@ static pte_t * __init one_page_table_ini
4844  {
4845         if (pmd_none(*pmd)) {
4846                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
4847 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4848 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
4849 +#else
4850                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
4851 +#endif
4852                 if (page_table != pte_offset_kernel(pmd, 0))
4853                         BUG();  
4854  
4855 @@ -117,8 +98,6 @@ static void __init page_table_range_init
4856         pgd = pgd_base + pgd_idx;
4857  
4858         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
4859 -               if (pgd_none(*pgd)) 
4860 -                       one_md_table_init(pgd);
4861                 pud = pud_offset(pgd, vaddr);
4862                 pmd = pmd_offset(pud, vaddr);
4863                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
4864 @@ -131,11 +110,22 @@ static void __init page_table_range_init
4865         }
4866  }
4867  
4868 -static inline int is_kernel_text(unsigned long addr)
4869 +static inline int is_kernel_text(unsigned long start, unsigned long end)
4870  {
4871 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
4872 -               return 1;
4873 -       return 0;
4874 +       unsigned long etext;
4875 +
4876 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
4877 +       etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
4878 +#else
4879 +       etext = (unsigned long)&_etext;
4880 +#endif
4881 +
4882 +       if ((start > etext + __KERNEL_TEXT_OFFSET ||
4883 +            end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
4884 +           (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
4885 +            end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
4886 +               return 0;
4887 +       return 1;
4888  }
4889  
4890  /*
4891 @@ -147,26 +137,24 @@ static void __init kernel_physical_mappi
4892  {
4893         unsigned long pfn;
4894         pgd_t *pgd;
4895 +       pud_t *pud;
4896         pmd_t *pmd;
4897         pte_t *pte;
4898 -       int pgd_idx, pmd_idx, pte_ofs;
4899 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
4900  
4901         pgd_idx = pgd_index(PAGE_OFFSET);
4902         pgd = pgd_base + pgd_idx;
4903         pfn = 0;
4904  
4905 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
4906 -               pmd = one_md_table_init(pgd);
4907 -               if (pfn >= max_low_pfn)
4908 -                       continue;
4909 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
4910 +               pud = pud_offset(pgd, 0);
4911 +               pmd = pmd_offset(pud, 0);
4912                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
4913 -                       unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
4914 +                       unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
4915  
4916                         /* Map with big pages if possible, otherwise create normal page tables. */
4917                         if (cpu_has_pse) {
4918 -                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
4919 -
4920 -                               if (is_kernel_text(address) || is_kernel_text(address2))
4921 +                               if (is_kernel_text(address, address + PMD_SIZE))
4922                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
4923                                 else
4924                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
4925 @@ -175,7 +163,7 @@ static void __init kernel_physical_mappi
4926                                 pte = one_page_table_init(pmd);
4927  
4928                                 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
4929 -                                               if (is_kernel_text(address))
4930 +                                               if (is_kernel_text(address, address + PAGE_SIZE))
4931                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
4932                                                 else
4933                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
4934 @@ -342,13 +330,6 @@ static void __init pagetable_init (void)
4935         unsigned long vaddr;
4936         pgd_t *pgd_base = swapper_pg_dir;
4937  
4938 -#ifdef CONFIG_X86_PAE
4939 -       int i;
4940 -       /* Init entries of the first-level page table to the zero page */
4941 -       for (i = 0; i < PTRS_PER_PGD; i++)
4942 -               set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
4943 -#endif
4944 -
4945         /* Enable PSE if available */
4946         if (cpu_has_pse) {
4947                 set_in_cr4(X86_CR4_PSE);
4948 @@ -372,17 +353,6 @@ static void __init pagetable_init (void)
4949         page_table_range_init(vaddr, 0, pgd_base);
4950  
4951         permanent_kmaps_init(pgd_base);
4952 -
4953 -#ifdef CONFIG_X86_PAE
4954 -       /*
4955 -        * Add low memory identity-mappings - SMP needs it when
4956 -        * starting up on an AP from real-mode. In the non-PAE
4957 -        * case we already have these mappings through head.S.
4958 -        * All user-space mappings are explicitly cleared after
4959 -        * SMP startup.
4960 -        */
4961 -       set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
4962 -#endif
4963  }
4964  
4965  #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP)
4966 @@ -424,7 +394,6 @@ void zap_low_mappings (void)
4967         flush_tlb_all();
4968  }
4969  
4970 -static int disable_nx __initdata = 0;
4971  u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
4972  
4973  /*
4974 @@ -438,11 +407,9 @@ u64 __supported_pte_mask __read_mostly =
4975  void __init noexec_setup(const char *str)
4976  {
4977         if (!strncmp(str, "on",2) && cpu_has_nx) {
4978 -               __supported_pte_mask |= _PAGE_NX;
4979 -               disable_nx = 0;
4980 +               nx_enabled = 1;
4981         } else if (!strncmp(str,"off",3)) {
4982 -               disable_nx = 1;
4983 -               __supported_pte_mask &= ~_PAGE_NX;
4984 +               nx_enabled = 0;
4985         }
4986  }
4987  
4988 @@ -451,17 +418,13 @@ int nx_enabled = 0;
4989  
4990  static void __init set_nx(void)
4991  {
4992 -       unsigned int v[4], l, h;
4993 +       if (!nx_enabled && cpu_has_nx) {
4994 +               unsigned l, h;
4995  
4996 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
4997 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
4998 -               if ((v[3] & (1 << 20)) && !disable_nx) {
4999 -                       rdmsr(MSR_EFER, l, h);
5000 -                       l |= EFER_NX;
5001 -                       wrmsr(MSR_EFER, l, h);
5002 -                       nx_enabled = 1;
5003 -                       __supported_pte_mask |= _PAGE_NX;
5004 -               }
5005 +               __supported_pte_mask &= ~_PAGE_NX;
5006 +               rdmsr(MSR_EFER, l, h);
5007 +               l &= ~EFER_NX;
5008 +               wrmsr(MSR_EFER, l, h);
5009         }
5010  }
5011  
5012 @@ -513,14 +476,6 @@ void __init paging_init(void)
5013  
5014         load_cr3(swapper_pg_dir);
5015  
5016 -#ifdef CONFIG_X86_PAE
5017 -       /*
5018 -        * We will bail out later - printk doesn't work right now so
5019 -        * the user would just see a hanging kernel.
5020 -        */
5021 -       if (cpu_has_pae)
5022 -               set_in_cr4(X86_CR4_PAE);
5023 -#endif
5024         __flush_tlb_all();
5025  
5026         kmap_init();
5027 @@ -612,7 +567,7 @@ void __init mem_init(void)
5028         set_highmem_pages_init(bad_ppro);
5029  
5030         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
5031 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
5032 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
5033         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
5034  
5035         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
5036 @@ -629,10 +584,6 @@ void __init mem_init(void)
5037                 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
5038                );
5039  
5040 -#ifdef CONFIG_X86_PAE
5041 -       if (!cpu_has_pae)
5042 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
5043 -#endif
5044         if (boot_cpu_data.wp_works_ok < 0)
5045                 test_wp_bit();
5046  
5047 @@ -761,6 +712,37 @@ void free_init_pages(char *what, unsigne
5048  
5049  void free_initmem(void)
5050  {
5051 +
5052 +#ifdef CONFIG_PAX_KERNEXEC
5053 +       /* PaX: limit KERNEL_CS to actual size */
5054 +       unsigned long addr, limit;
5055 +       int cpu;
5056 +       pgd_t *pgd;
5057 +       pud_t *pud;
5058 +       pmd_t *pmd;
5059 +
5060 +#ifdef CONFIG_MODULES
5061 +       limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
5062 +#else
5063 +       limit = (unsigned long)&_etext;
5064 +#endif
5065 +       limit = (limit - 1UL) >> PAGE_SHIFT;
5066 +
5067 +       for (cpu = 0; cpu < NR_CPUS; cpu++) {
5068 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
5069 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
5070 +       }
5071 +
5072 +       /* PaX: make KERNEL_CS read-only */
5073 +       for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
5074 +               pgd = pgd_offset_k(addr);
5075 +               pud = pud_offset(pgd, addr);
5076 +               pmd = pmd_offset(pud, addr);
5077 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
5078 +       }
5079 +       flush_tlb_all();
5080 +#endif
5081 +
5082         free_init_pages("unused kernel memory",
5083                         (unsigned long)(&__init_begin),
5084                         (unsigned long)(&__init_end));
5085 diff -urNp linux-2.6.18/arch/i386/mm/mmap.c linux-2.6.18/arch/i386/mm/mmap.c
5086 --- linux-2.6.18/arch/i386/mm/mmap.c    2006-09-19 23:42:06.000000000 -0400
5087 +++ linux-2.6.18/arch/i386/mm/mmap.c    2006-09-22 20:45:03.000000000 -0400
5088 @@ -34,12 +34,18 @@
5089   * Leave an at least ~128 MB hole.
5090   */
5091  #define MIN_GAP (128*1024*1024)
5092 -#define MAX_GAP (TASK_SIZE/6*5)
5093 +#define MAX_GAP (task_size/6*5)
5094  
5095  static inline unsigned long mmap_base(struct mm_struct *mm)
5096  {
5097         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
5098         unsigned long random_factor = 0;
5099 +       unsigned long task_size = TASK_SIZE;
5100 +
5101 +#ifdef CONFIG_PAX_SEGMEXEC
5102 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
5103 +               task_size = SEGMEXEC_TASK_SIZE;
5104 +#endif
5105  
5106         if (current->flags & PF_RANDOMIZE)
5107                 random_factor = get_random_int() % (1024*1024);
5108 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
5109         else if (gap > MAX_GAP)
5110                 gap = MAX_GAP;
5111  
5112 -       return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
5113 +       return PAGE_ALIGN(task_size - gap - random_factor);
5114  }
5115  
5116  /*
5117 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
5118                         (current->personality & ADDR_COMPAT_LAYOUT) ||
5119                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
5120                 mm->mmap_base = TASK_UNMAPPED_BASE;
5121 +
5122 +#ifdef CONFIG_PAX_RANDMMAP
5123 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5124 +                       mm->mmap_base += mm->delta_mmap;
5125 +#endif
5126 +
5127                 mm->get_unmapped_area = arch_get_unmapped_area;
5128                 mm->unmap_area = arch_unmap_area;
5129         } else {
5130                 mm->mmap_base = mmap_base(mm);
5131 +
5132 +#ifdef CONFIG_PAX_RANDMMAP
5133 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5134 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
5135 +#endif
5136 +
5137                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
5138                 mm->unmap_area = arch_unmap_area_topdown;
5139         }
5140 diff -urNp linux-2.6.18/arch/i386/mm/pageattr.c linux-2.6.18/arch/i386/mm/pageattr.c
5141 --- linux-2.6.18/arch/i386/mm/pageattr.c        2006-09-19 23:42:06.000000000 -0400
5142 +++ linux-2.6.18/arch/i386/mm/pageattr.c        2006-09-22 20:45:03.000000000 -0400
5143 @@ -13,6 +13,7 @@
5144  #include <asm/tlbflush.h>
5145  #include <asm/pgalloc.h>
5146  #include <asm/sections.h>
5147 +#include <asm/desc.h>
5148  
5149  static DEFINE_SPINLOCK(cpa_lock);
5150  static struct list_head df_list = LIST_HEAD_INIT(df_list);
5151 @@ -83,7 +84,18 @@ static void set_pmd_pte(pte_t *kpte, uns
5152         struct page *page;
5153         unsigned long flags;
5154  
5155 +#ifdef CONFIG_PAX_KERNEXEC
5156 +       unsigned long cr0;
5157 +
5158 +       pax_open_kernel(cr0);
5159 +#endif
5160 +
5161         set_pte_atomic(kpte, pte);      /* change init_mm */
5162 +
5163 +#ifdef CONFIG_PAX_KERNEXEC
5164 +       pax_close_kernel(cr0);
5165 +#endif
5166 +
5167         if (PTRS_PER_PMD > 1)
5168                 return;
5169  
5170 @@ -110,7 +122,7 @@ static inline void revert_page(struct pa
5171         pte_t *linear;
5172  
5173         ref_prot =
5174 -       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
5175 +       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
5176                 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
5177  
5178         linear = (pte_t *)
5179 @@ -142,7 +154,7 @@ __change_page_attr(struct page *page, pg
5180                         struct page *split;
5181  
5182                         ref_prot =
5183 -                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
5184 +                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
5185                                 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
5186                         split = split_large_page(address, prot, ref_prot);
5187                         if (!split)
5188 diff -urNp linux-2.6.18/arch/i386/oprofile/backtrace.c linux-2.6.18/arch/i386/oprofile/backtrace.c
5189 --- linux-2.6.18/arch/i386/oprofile/backtrace.c 2006-09-19 23:42:06.000000000 -0400
5190 +++ linux-2.6.18/arch/i386/oprofile/backtrace.c 2006-09-22 20:45:03.000000000 -0400
5191 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
5192         head = (struct frame_head *)regs->ebp;
5193  #endif
5194  
5195 -       if (!user_mode_vm(regs)) {
5196 +       if (!user_mode(regs)) {
5197                 while (depth-- && valid_kernel_stack(head, regs))
5198                         head = dump_kernel_backtrace(head);
5199                 return;
5200 diff -urNp linux-2.6.18/arch/i386/oprofile/op_model_p4.c linux-2.6.18/arch/i386/oprofile/op_model_p4.c
5201 --- linux-2.6.18/arch/i386/oprofile/op_model_p4.c       2006-09-19 23:42:06.000000000 -0400
5202 +++ linux-2.6.18/arch/i386/oprofile/op_model_p4.c       2006-09-22 20:45:03.000000000 -0400
5203 @@ -45,7 +45,7 @@ static inline void setup_num_counters(vo
5204  #endif
5205  }
5206  
5207 -static int inline addr_increment(void)
5208 +static inline int addr_increment(void)
5209  {
5210  #ifdef CONFIG_SMP
5211         return smp_num_siblings == 2 ? 2 : 1;
5212 diff -urNp linux-2.6.18/arch/i386/power/cpu.c linux-2.6.18/arch/i386/power/cpu.c
5213 --- linux-2.6.18/arch/i386/power/cpu.c  2006-09-19 23:42:06.000000000 -0400
5214 +++ linux-2.6.18/arch/i386/power/cpu.c  2006-09-22 20:45:03.000000000 -0400
5215 @@ -63,7 +63,7 @@ static void do_fpu_end(void)
5216  static void fix_processor_context(void)
5217  {
5218         int cpu = smp_processor_id();
5219 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
5220 +       struct tss_struct * t = init_tss + cpu;
5221  
5222         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. */
5223  
5224 diff -urNp linux-2.6.18/arch/ia64/ia32/binfmt_elf32.c linux-2.6.18/arch/ia64/ia32/binfmt_elf32.c
5225 --- linux-2.6.18/arch/ia64/ia32/binfmt_elf32.c  2006-09-19 23:42:06.000000000 -0400
5226 +++ linux-2.6.18/arch/ia64/ia32/binfmt_elf32.c  2006-09-22 20:45:03.000000000 -0400
5227 @@ -45,6 +45,17 @@ randomize_stack_top(unsigned long stack_
5228  
5229  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
5230  
5231 +#ifdef CONFIG_PAX_ASLR
5232 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
5233 +
5234 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
5235 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5236 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
5237 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5238 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
5239 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5240 +#endif
5241 +
5242  /* Ugly but avoids duplication */
5243  #include "../../../fs/binfmt_elf.c"
5244  
5245 diff -urNp linux-2.6.18/arch/ia64/ia32/ia32priv.h linux-2.6.18/arch/ia64/ia32/ia32priv.h
5246 --- linux-2.6.18/arch/ia64/ia32/ia32priv.h      2006-09-19 23:42:06.000000000 -0400
5247 +++ linux-2.6.18/arch/ia64/ia32/ia32priv.h      2006-09-22 20:45:03.000000000 -0400
5248 @@ -304,7 +304,14 @@ struct old_linux32_dirent {
5249  #define ELF_DATA       ELFDATA2LSB
5250  #define ELF_ARCH       EM_386
5251  
5252 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
5253 +#ifdef CONFIG_PAX_RANDUSTACK
5254 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
5255 +#else
5256 +#define __IA32_DELTA_STACK     0UL
5257 +#endif
5258 +
5259 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
5260 +
5261  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
5262  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
5263  
5264 diff -urNp linux-2.6.18/arch/ia64/kernel/module.c linux-2.6.18/arch/ia64/kernel/module.c
5265 --- linux-2.6.18/arch/ia64/kernel/module.c      2006-09-19 23:42:06.000000000 -0400
5266 +++ linux-2.6.18/arch/ia64/kernel/module.c      2006-09-22 20:45:03.000000000 -0400
5267 @@ -321,7 +321,7 @@ module_alloc (unsigned long size)
5268  void
5269  module_free (struct module *mod, void *module_region)
5270  {
5271 -       if (mod->arch.init_unw_table && module_region == mod->module_init) {
5272 +       if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
5273                 unw_remove_unwind_table(mod->arch.init_unw_table);
5274                 mod->arch.init_unw_table = NULL;
5275         }
5276 @@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
5277  }
5278  
5279  static inline int
5280 +in_init_rx (const struct module *mod, uint64_t addr)
5281 +{
5282 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
5283 +}
5284 +
5285 +static inline int
5286 +in_init_rw (const struct module *mod, uint64_t addr)
5287 +{
5288 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
5289 +}
5290 +
5291 +static inline int
5292  in_init (const struct module *mod, uint64_t addr)
5293  {
5294 -       return addr - (uint64_t) mod->module_init < mod->init_size;
5295 +       return in_init_rx(mod, value) || in_init_rw(mod, value);
5296 +}
5297 +
5298 +static inline int
5299 +in_core_rx (const struct module *mod, uint64_t addr)
5300 +{
5301 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
5302 +}
5303 +
5304 +static inline int
5305 +in_core_rw (const struct module *mod, uint64_t addr)
5306 +{
5307 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
5308  }
5309  
5310  static inline int
5311  in_core (const struct module *mod, uint64_t addr)
5312  {
5313 -       return addr - (uint64_t) mod->module_core < mod->core_size;
5314 +       return in_core_rx(mod, value) || in_core_rw(mod, value);
5315  }
5316  
5317  static inline int
5318 @@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
5319                 break;
5320  
5321               case RV_BDREL:
5322 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
5323 +               if (in_init_rx(mod, val))
5324 +                       val -= (uint64_t) mod->module_init_rx;
5325 +               else if (in_init_rw(mod, val))
5326 +                       val -= (uint64_t) mod->module_init_rw;
5327 +               else if (in_core_rx(mod, val))
5328 +                       val -= (uint64_t) mod->module_core_rx;
5329 +               else if (in_core_rw(mod, val))
5330 +                       val -= (uint64_t) mod->module_core_rw;
5331                 break;
5332  
5333               case RV_LTV:
5334 @@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
5335                  *     addresses have been selected...
5336                  */
5337                 uint64_t gp;
5338 -               if (mod->core_size > MAX_LTOFF)
5339 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
5340                         /*
5341                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
5342                          * at the end of the module.
5343                          */
5344 -                       gp = mod->core_size - MAX_LTOFF / 2;
5345 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
5346                 else
5347 -                       gp = mod->core_size / 2;
5348 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
5349 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
5350 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
5351                 mod->arch.gp = gp;
5352                 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
5353         }
5354 diff -urNp linux-2.6.18/arch/ia64/kernel/ptrace.c linux-2.6.18/arch/ia64/kernel/ptrace.c
5355 --- linux-2.6.18/arch/ia64/kernel/ptrace.c      2006-09-19 23:42:06.000000000 -0400
5356 +++ linux-2.6.18/arch/ia64/kernel/ptrace.c      2006-09-22 20:04:35.000000000 -0400
5357 @@ -17,6 +17,7 @@
5358  #include <linux/security.h>
5359  #include <linux/audit.h>
5360  #include <linux/signal.h>
5361 +#include <linux/grsecurity.h>
5362  
5363  #include <asm/pgtable.h>
5364  #include <asm/processor.h>
5365 @@ -1446,6 +1447,9 @@ sys_ptrace (long request, pid_t pid, uns
5366         if (pid == 1)           /* no messing around with init! */
5367                 goto out_tsk;
5368  
5369 +       if (gr_handle_ptrace(child, request))
5370 +               goto out_tsk;
5371 +
5372         if (request == PTRACE_ATTACH) {
5373                 ret = ptrace_attach(child);
5374                 goto out_tsk;
5375 diff -urNp linux-2.6.18/arch/ia64/kernel/sys_ia64.c linux-2.6.18/arch/ia64/kernel/sys_ia64.c
5376 --- linux-2.6.18/arch/ia64/kernel/sys_ia64.c    2006-09-19 23:42:06.000000000 -0400
5377 +++ linux-2.6.18/arch/ia64/kernel/sys_ia64.c    2006-09-22 20:45:03.000000000 -0400
5378 @@ -37,6 +37,13 @@ arch_get_unmapped_area (struct file *fil
5379         if (REGION_NUMBER(addr) == RGN_HPAGE)
5380                 addr = 0;
5381  #endif
5382 +
5383 +#ifdef CONFIG_PAX_RANDMMAP
5384 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
5385 +               addr = mm->free_area_cache;
5386 +       else
5387 +#endif
5388 +
5389         if (!addr)
5390                 addr = mm->free_area_cache;
5391  
5392 @@ -55,9 +62,9 @@ arch_get_unmapped_area (struct file *fil
5393         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
5394                 /* At this point:  (!vma || addr < vma->vm_end). */
5395                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
5396 -                       if (start_addr != TASK_UNMAPPED_BASE) {
5397 +                       if (start_addr != mm->mmap_base) {
5398                                 /* Start a new search --- just in case we missed some holes.  */
5399 -                               addr = TASK_UNMAPPED_BASE;
5400 +                               addr = mm->mmap_base;
5401                                 goto full_search;
5402                         }
5403                         return -ENOMEM;
5404 diff -urNp linux-2.6.18/arch/ia64/mm/fault.c linux-2.6.18/arch/ia64/mm/fault.c
5405 --- linux-2.6.18/arch/ia64/mm/fault.c   2006-09-19 23:42:06.000000000 -0400
5406 +++ linux-2.6.18/arch/ia64/mm/fault.c   2006-09-22 20:45:03.000000000 -0400
5407 @@ -10,6 +10,7 @@
5408  #include <linux/smp_lock.h>
5409  #include <linux/interrupt.h>
5410  #include <linux/kprobes.h>
5411 +#include <linux/binfmts.h>
5412  
5413  #include <asm/pgtable.h>
5414  #include <asm/processor.h>
5415 @@ -85,6 +86,23 @@ mapped_kernel_page_is_present (unsigned 
5416         return pte_present(pte);
5417  }
5418  
5419 +#ifdef CONFIG_PAX_PAGEEXEC
5420 +void pax_report_insns(void *pc, void *sp)
5421 +{
5422 +       unsigned long i;
5423 +
5424 +       printk(KERN_ERR "PAX: bytes at PC: ");
5425 +       for (i = 0; i < 8; i++) {
5426 +               unsigned int c;
5427 +               if (get_user(c, (unsigned int*)pc+i))
5428 +                       printk("???????? ");
5429 +               else
5430 +                       printk("%08x ", c);
5431 +       }
5432 +       printk("\n");
5433 +}
5434 +#endif
5435 +
5436  void __kprobes
5437  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
5438  {
5439 @@ -150,9 +168,23 @@ ia64_do_page_fault (unsigned long addres
5440                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
5441                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
5442  
5443 -       if ((vma->vm_flags & mask) != mask)
5444 +       if ((vma->vm_flags & mask) != mask) {
5445 +
5446 +#ifdef CONFIG_PAX_PAGEEXEC
5447 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
5448 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
5449 +                               goto bad_area;
5450 +
5451 +                       up_read(&mm->mmap_sem);
5452 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
5453 +                       do_exit(SIGKILL);
5454 +               }
5455 +#endif
5456 +
5457                 goto bad_area;
5458  
5459 +       }
5460 +
5461    survive:
5462         /*
5463          * If for any reason at all we couldn't handle the fault, make
5464 diff -urNp linux-2.6.18/arch/ia64/mm/init.c linux-2.6.18/arch/ia64/mm/init.c
5465 --- linux-2.6.18/arch/ia64/mm/init.c    2006-09-19 23:42:06.000000000 -0400
5466 +++ linux-2.6.18/arch/ia64/mm/init.c    2006-09-22 20:45:03.000000000 -0400
5467 @@ -19,8 +19,8 @@
5468  #include <linux/swap.h>
5469  #include <linux/proc_fs.h>
5470  #include <linux/bitops.h>
5471 +#include <linux/a.out.h>
5472  
5473 -#include <asm/a.out.h>
5474  #include <asm/dma.h>
5475  #include <asm/ia32.h>
5476  #include <asm/io.h>
5477 diff -urNp linux-2.6.18/arch/mips/kernel/binfmt_elfn32.c linux-2.6.18/arch/mips/kernel/binfmt_elfn32.c
5478 --- linux-2.6.18/arch/mips/kernel/binfmt_elfn32.c       2006-09-19 23:42:06.000000000 -0400
5479 +++ linux-2.6.18/arch/mips/kernel/binfmt_elfn32.c       2006-09-22 20:45:03.000000000 -0400
5480 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
5481  #undef ELF_ET_DYN_BASE
5482  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
5483  
5484 +#ifdef CONFIG_PAX_ASLR
5485 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5486 +
5487 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5488 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5489 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5490 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5491 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5492 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5493 +#endif
5494 +
5495  #include <asm/processor.h>
5496  #include <linux/module.h>
5497  #include <linux/elfcore.h>
5498 diff -urNp linux-2.6.18/arch/mips/kernel/binfmt_elfo32.c linux-2.6.18/arch/mips/kernel/binfmt_elfo32.c
5499 --- linux-2.6.18/arch/mips/kernel/binfmt_elfo32.c       2006-09-19 23:42:06.000000000 -0400
5500 +++ linux-2.6.18/arch/mips/kernel/binfmt_elfo32.c       2006-09-22 20:45:03.000000000 -0400
5501 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
5502  #undef ELF_ET_DYN_BASE
5503  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
5504  
5505 +#ifdef CONFIG_PAX_ASLR
5506 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5507 +
5508 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5509 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5510 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5511 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5512 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5513 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5514 +#endif
5515 +
5516  #include <asm/processor.h>
5517  #include <linux/module.h>
5518  #include <linux/elfcore.h>
5519 diff -urNp linux-2.6.18/arch/mips/kernel/syscall.c linux-2.6.18/arch/mips/kernel/syscall.c
5520 --- linux-2.6.18/arch/mips/kernel/syscall.c     2006-09-19 23:42:06.000000000 -0400
5521 +++ linux-2.6.18/arch/mips/kernel/syscall.c     2006-09-22 20:45:03.000000000 -0400
5522 @@ -88,6 +88,11 @@ unsigned long arch_get_unmapped_area(str
5523         do_color_align = 0;
5524         if (filp || (flags & MAP_SHARED))
5525                 do_color_align = 1;
5526 +
5527 +#ifdef CONFIG_PAX_RANDMMAP
5528 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5529 +#endif
5530 +
5531         if (addr) {
5532                 if (do_color_align)
5533                         addr = COLOUR_ALIGN(addr, pgoff);
5534 @@ -98,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
5535                     (!vmm || addr + len <= vmm->vm_start))
5536                         return addr;
5537         }
5538 -       addr = TASK_UNMAPPED_BASE;
5539 +       addr = current->mm->mmap_base;
5540         if (do_color_align)
5541                 addr = COLOUR_ALIGN(addr, pgoff);
5542         else
5543 diff -urNp linux-2.6.18/arch/mips/mm/fault.c linux-2.6.18/arch/mips/mm/fault.c
5544 --- linux-2.6.18/arch/mips/mm/fault.c   2006-09-19 23:42:06.000000000 -0400
5545 +++ linux-2.6.18/arch/mips/mm/fault.c   2006-09-22 20:45:03.000000000 -0400
5546 @@ -27,6 +27,23 @@
5547  #include <asm/ptrace.h>
5548  #include <asm/highmem.h>               /* For VMALLOC_END */
5549  
5550 +#ifdef CONFIG_PAX_PAGEEXEC
5551 +void pax_report_insns(void *pc)
5552 +{
5553 +       unsigned long i;
5554 +
5555 +       printk(KERN_ERR "PAX: bytes at PC: ");
5556 +       for (i = 0; i < 5; i++) {
5557 +               unsigned int c;
5558 +               if (get_user(c, (unsigned int*)pc+i))
5559 +                       printk("???????? ");
5560 +               else
5561 +                       printk("%08x ", c);
5562 +       }
5563 +       printk("\n");
5564 +}
5565 +#endif
5566 +
5567  /*
5568   * This routine handles page faults.  It determines the address,
5569   * and the problem, and then passes it off to one of the appropriate
5570 diff -urNp linux-2.6.18/arch/parisc/kernel/module.c linux-2.6.18/arch/parisc/kernel/module.c
5571 --- linux-2.6.18/arch/parisc/kernel/module.c    2006-09-19 23:42:06.000000000 -0400
5572 +++ linux-2.6.18/arch/parisc/kernel/module.c    2006-09-22 20:45:03.000000000 -0400
5573 @@ -72,16 +72,38 @@
5574  
5575  /* three functions to determine where in the module core
5576   * or init pieces the location is */
5577 +static inline int is_init_rx(struct module *me, void *loc)
5578 +{
5579 +       return (loc >= me->module_init_rx &&
5580 +               loc < (me->module_init_rx + me->init_size_rx));
5581 +}
5582 +
5583 +static inline int is_init_rw(struct module *me, void *loc)
5584 +{
5585 +       return (loc >= me->module_init_rw &&
5586 +               loc < (me->module_init_rw + me->init_size_rw));
5587 +}
5588 +
5589  static inline int is_init(struct module *me, void *loc)
5590  {
5591 -       return (loc >= me->module_init &&
5592 -               loc <= (me->module_init + me->init_size));
5593 +       return is_init_rx(me, loc) || is_init_rw(me, loc);
5594 +}
5595 +
5596 +static inline int is_core_rx(struct module *me, void *loc)
5597 +{
5598 +       return (loc >= me->module_core_rx &&
5599 +               loc < (me->module_core_rx + me->core_size_rx));
5600 +}
5601 +
5602 +static inline int is_core_rw(struct module *me, void *loc)
5603 +{
5604 +       return (loc >= me->module_core_rw &&
5605 +               loc < (me->module_core_rw + me->core_size_rw));
5606  }
5607  
5608  static inline int is_core(struct module *me, void *loc)
5609  {
5610 -       return (loc >= me->module_core &&
5611 -               loc <= (me->module_core + me->core_size));
5612 +       return is_core_rx(me, loc) || is_core_rw(me, loc);
5613  }
5614  
5615  static inline int is_local(struct module *me, void *loc)
5616 @@ -295,21 +317,21 @@ int module_frob_arch_sections(CONST Elf_
5617         }
5618  
5619         /* align things a bit */
5620 -       me->core_size = ALIGN(me->core_size, 16);
5621 -       me->arch.got_offset = me->core_size;
5622 -       me->core_size += gots * sizeof(struct got_entry);
5623 -
5624 -       me->core_size = ALIGN(me->core_size, 16);
5625 -       me->arch.fdesc_offset = me->core_size;
5626 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
5627 -
5628 -       me->core_size = ALIGN(me->core_size, 16);
5629 -       me->arch.stub_offset = me->core_size;
5630 -       me->core_size += stubs * sizeof(struct stub_entry);
5631 -
5632 -       me->init_size = ALIGN(me->init_size, 16);
5633 -       me->arch.init_stub_offset = me->init_size;
5634 -       me->init_size += init_stubs * sizeof(struct stub_entry);
5635 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
5636 +       me->arch.got_offset = me->core_size_rw;
5637 +       me->core_size_rw += gots * sizeof(struct got_entry);
5638 +
5639 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
5640 +       me->arch.fdesc_offset = me->core_size_rw;
5641 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
5642 +
5643 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
5644 +       me->arch.stub_offset = me->core_size_rx;
5645 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
5646 +
5647 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
5648 +       me->arch.init_stub_offset = me->init_size_rx;
5649 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
5650  
5651         me->arch.got_max = gots;
5652         me->arch.fdesc_max = fdescs;
5653 @@ -329,7 +351,7 @@ static Elf64_Word get_got(struct module 
5654  
5655         BUG_ON(value == 0);
5656  
5657 -       got = me->module_core + me->arch.got_offset;
5658 +       got = me->module_core_rw + me->arch.got_offset;
5659         for (i = 0; got[i].addr; i++)
5660                 if (got[i].addr == value)
5661                         goto out;
5662 @@ -347,7 +369,7 @@ static Elf64_Word get_got(struct module 
5663  #ifdef __LP64__
5664  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
5665  {
5666 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
5667 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
5668  
5669         if (!value) {
5670                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
5671 @@ -365,7 +387,7 @@ static Elf_Addr get_fdesc(struct module 
5672  
5673         /* Create new one */
5674         fdesc->addr = value;
5675 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
5676 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
5677         return (Elf_Addr)fdesc;
5678  }
5679  #endif /* __LP64__ */
5680 @@ -385,12 +407,12 @@ static Elf_Addr get_stub(struct module *
5681         if(init_section) {
5682                 i = me->arch.init_stub_count++;
5683                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
5684 -               stub = me->module_init + me->arch.init_stub_offset + 
5685 +               stub = me->module_init_rx + me->arch.init_stub_offset + 
5686                         i * sizeof(struct stub_entry);
5687         } else {
5688                 i = me->arch.stub_count++;
5689                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
5690 -               stub = me->module_core + me->arch.stub_offset + 
5691 +               stub = me->module_core_rx + me->arch.stub_offset + 
5692                         i * sizeof(struct stub_entry);
5693         }
5694  
5695 @@ -758,7 +780,7 @@ register_unwind_table(struct module *me,
5696  
5697         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
5698         end = table + sechdrs[me->arch.unwind_section].sh_size;
5699 -       gp = (Elf_Addr)me->module_core + me->arch.got_offset;
5700 +       gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
5701  
5702         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
5703                me->arch.unwind_section, table, end, gp);
5704 diff -urNp linux-2.6.18/arch/parisc/kernel/ptrace.c linux-2.6.18/arch/parisc/kernel/ptrace.c
5705 --- linux-2.6.18/arch/parisc/kernel/ptrace.c    2006-09-19 23:42:06.000000000 -0400
5706 +++ linux-2.6.18/arch/parisc/kernel/ptrace.c    2006-09-22 20:04:35.000000000 -0400
5707 @@ -18,6 +18,7 @@
5708  #include <linux/security.h>
5709  #include <linux/compat.h>
5710  #include <linux/signal.h>
5711 +#include <linux/grsecurity.h>
5712  
5713  #include <asm/uaccess.h>
5714  #include <asm/pgtable.h>
5715 diff -urNp linux-2.6.18/arch/parisc/kernel/sys_parisc.c linux-2.6.18/arch/parisc/kernel/sys_parisc.c
5716 --- linux-2.6.18/arch/parisc/kernel/sys_parisc.c        2006-09-19 23:42:06.000000000 -0400
5717 +++ linux-2.6.18/arch/parisc/kernel/sys_parisc.c        2006-09-22 20:45:03.000000000 -0400
5718 @@ -105,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
5719         if (len > TASK_SIZE)
5720                 return -ENOMEM;
5721         if (!addr)
5722 -               addr = TASK_UNMAPPED_BASE;
5723 +               addr = current->mm->mmap_base;
5724  
5725         if (filp) {
5726                 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
5727 diff -urNp linux-2.6.18/arch/parisc/kernel/traps.c linux-2.6.18/arch/parisc/kernel/traps.c
5728 --- linux-2.6.18/arch/parisc/kernel/traps.c     2006-09-19 23:42:06.000000000 -0400
5729 +++ linux-2.6.18/arch/parisc/kernel/traps.c     2006-09-22 20:45:03.000000000 -0400
5730 @@ -706,9 +706,7 @@ void handle_interruption(int code, struc
5731  
5732                         down_read(&current->mm->mmap_sem);
5733                         vma = find_vma(current->mm,regs->iaoq[0]);
5734 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
5735 -                               && (vma->vm_flags & VM_EXEC)) {
5736 -
5737 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
5738                                 fault_address = regs->iaoq[0];
5739                                 fault_space = regs->iasq[0];
5740  
5741 diff -urNp linux-2.6.18/arch/parisc/mm/fault.c linux-2.6.18/arch/parisc/mm/fault.c
5742 --- linux-2.6.18/arch/parisc/mm/fault.c 2006-09-19 23:42:06.000000000 -0400
5743 +++ linux-2.6.18/arch/parisc/mm/fault.c 2006-09-22 20:45:03.000000000 -0400
5744 @@ -16,6 +16,8 @@
5745  #include <linux/sched.h>
5746  #include <linux/interrupt.h>
5747  #include <linux/module.h>
5748 +#include <linux/unistd.h>
5749 +#include <linux/binfmts.h>
5750  
5751  #include <asm/uaccess.h>
5752  #include <asm/traps.h>
5753 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
5754  static unsigned long
5755  parisc_acctyp(unsigned long code, unsigned int inst)
5756  {
5757 -       if (code == 6 || code == 16)
5758 +       if (code == 6 || code == 7 || code == 16)
5759             return VM_EXEC;
5760  
5761         switch (inst & 0xf0000000) {
5762 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
5763                         }
5764  #endif
5765  
5766 +#ifdef CONFIG_PAX_PAGEEXEC
5767 +/*
5768 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
5769 + *
5770 + * returns 1 when task should be killed
5771 + *         2 when rt_sigreturn trampoline was detected
5772 + *         3 when unpatched PLT trampoline was detected
5773 + */
5774 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5775 +{
5776 +
5777 +#ifdef CONFIG_PAX_EMUPLT
5778 +       int err;
5779 +
5780 +       do { /* PaX: unpatched PLT emulation */
5781 +               unsigned int bl, depwi;
5782 +
5783 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
5784 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
5785 +
5786 +               if (err)
5787 +                       break;
5788 +
5789 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
5790 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
5791 +
5792 +                       err = get_user(ldw, (unsigned int*)addr);
5793 +                       err |= get_user(bv, (unsigned int*)(addr+4));
5794 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
5795 +
5796 +                       if (err)
5797 +                               break;
5798 +
5799 +                       if (ldw == 0x0E801096U &&
5800 +                           bv == 0xEAC0C000U &&
5801 +                           ldw2 == 0x0E881095U)
5802 +                       {
5803 +                               unsigned int resolver, map;
5804 +
5805 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
5806 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
5807 +                               if (err)
5808 +                                       break;
5809 +
5810 +                               regs->gr[20] = instruction_pointer(regs)+8;
5811 +                               regs->gr[21] = map;
5812 +                               regs->gr[22] = resolver;
5813 +                               regs->iaoq[0] = resolver | 3UL;
5814 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
5815 +                               return 3;
5816 +                       }
5817 +               }
5818 +       } while (0);
5819 +#endif
5820 +
5821 +#ifdef CONFIG_PAX_EMUTRAMP
5822 +
5823 +#ifndef CONFIG_PAX_EMUSIGRT
5824 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
5825 +               return 1;
5826 +#endif
5827 +
5828 +       do { /* PaX: rt_sigreturn emulation */
5829 +               unsigned int ldi1, ldi2, bel, nop;
5830 +
5831 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
5832 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
5833 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
5834 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
5835 +
5836 +               if (err)
5837 +                       break;
5838 +
5839 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
5840 +                   ldi2 == 0x3414015AU &&
5841 +                   bel == 0xE4008200U &&
5842 +                   nop == 0x08000240U)
5843 +               {
5844 +                       regs->gr[25] = (ldi1 & 2) >> 1;
5845 +                       regs->gr[20] = __NR_rt_sigreturn;
5846 +                       regs->gr[31] = regs->iaoq[1] + 16;
5847 +                       regs->sr[0] = regs->iasq[1];
5848 +                       regs->iaoq[0] = 0x100UL;
5849 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
5850 +                       regs->iasq[0] = regs->sr[2];
5851 +                       regs->iasq[1] = regs->sr[2];
5852 +                       return 2;
5853 +               }
5854 +       } while (0);
5855 +#endif
5856 +
5857 +       return 1;
5858 +}
5859 +
5860 +void pax_report_insns(void *pc, void *sp)
5861 +{
5862 +       unsigned long i;
5863 +
5864 +       printk(KERN_ERR "PAX: bytes at PC: ");
5865 +       for (i = 0; i < 5; i++) {
5866 +               unsigned int c;
5867 +               if (get_user(c, (unsigned int*)pc+i))
5868 +                       printk("???????? ");
5869 +               else
5870 +                       printk("%08x ", c);
5871 +       }
5872 +       printk("\n");
5873 +}
5874 +#endif
5875 +
5876  void do_page_fault(struct pt_regs *regs, unsigned long code,
5877                               unsigned long address)
5878  {
5879 @@ -168,8 +280,33 @@ good_area:
5880  
5881         acc_type = parisc_acctyp(code,regs->iir);
5882  
5883 -       if ((vma->vm_flags & acc_type) != acc_type)
5884 +       if ((vma->vm_flags & acc_type) != acc_type) {
5885 +
5886 +#ifdef CONFIG_PAX_PAGEEXEC
5887 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
5888 +                   (address & ~3UL) == instruction_pointer(regs))
5889 +               {
5890 +                       up_read(&mm->mmap_sem);
5891 +                       switch(pax_handle_fetch_fault(regs)) {
5892 +
5893 +#ifdef CONFIG_PAX_EMUPLT
5894 +                       case 3:
5895 +                               return;
5896 +#endif
5897 +
5898 +#ifdef CONFIG_PAX_EMUTRAMP
5899 +                       case 2:
5900 +                               return;
5901 +#endif
5902 +
5903 +                       }
5904 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
5905 +                       do_exit(SIGKILL);
5906 +               }
5907 +#endif
5908 +
5909                 goto bad_area;
5910 +       }
5911  
5912         /*
5913          * If for any reason at all we couldn't handle the fault, make
5914 diff -urNp linux-2.6.18/arch/powerpc/kernel/module_32.c linux-2.6.18/arch/powerpc/kernel/module_32.c
5915 --- linux-2.6.18/arch/powerpc/kernel/module_32.c        2006-09-19 23:42:06.000000000 -0400
5916 +++ linux-2.6.18/arch/powerpc/kernel/module_32.c        2006-09-22 20:45:03.000000000 -0400
5917 @@ -123,7 +123,7 @@ int module_frob_arch_sections(Elf32_Ehdr
5918                         me->arch.core_plt_section = i;
5919         }
5920         if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
5921 -               printk("Module doesn't contain .plt or .init.plt sections.\n");
5922 +               printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
5923                 return -ENOEXEC;
5924         }
5925  
5926 @@ -164,11 +164,16 @@ static uint32_t do_plt_call(void *locati
5927  
5928         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
5929         /* Init, or core PLT? */
5930 -       if (location >= mod->module_core
5931 -           && location < mod->module_core + mod->core_size)
5932 +       if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
5933 +           (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
5934                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
5935 -       else
5936 +       else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
5937 +                (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
5938                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
5939 +       else {
5940 +               printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
5941 +               return ~0UL;
5942 +       }
5943  
5944         /* Find this entry, or if that fails, the next avail. entry */
5945         while (entry->jump[0]) {
5946 diff -urNp linux-2.6.18/arch/powerpc/kernel/vdso.c linux-2.6.18/arch/powerpc/kernel/vdso.c
5947 --- linux-2.6.18/arch/powerpc/kernel/vdso.c     2006-09-19 23:42:06.000000000 -0400
5948 +++ linux-2.6.18/arch/powerpc/kernel/vdso.c     2006-09-22 20:45:03.000000000 -0400
5949 @@ -254,7 +254,7 @@ int arch_setup_additional_pages(struct l
5950          */
5951         down_write(&mm->mmap_sem);
5952         vdso_base = get_unmapped_area(NULL, vdso_base,
5953 -                                     vdso_pages << PAGE_SHIFT, 0, 0);
5954 +                                     vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
5955         if (IS_ERR_VALUE(vdso_base)) {
5956                 rc = vdso_base;
5957                 goto fail_mmapsem;
5958 diff -urNp linux-2.6.18/arch/powerpc/mm/fault.c linux-2.6.18/arch/powerpc/mm/fault.c
5959 --- linux-2.6.18/arch/powerpc/mm/fault.c        2006-09-19 23:42:06.000000000 -0400
5960 +++ linux-2.6.18/arch/powerpc/mm/fault.c        2006-09-22 20:45:03.000000000 -0400
5961 @@ -28,6 +28,12 @@
5962  #include <linux/highmem.h>
5963  #include <linux/module.h>
5964  #include <linux/kprobes.h>
5965 +#include <linux/binfmts.h>
5966 +#include <linux/slab.h>
5967 +#include <linux/pagemap.h>
5968 +#include <linux/compiler.h>
5969 +#include <linux/binfmts.h>
5970 +#include <linux/unistd.h>
5971  
5972  #include <asm/page.h>
5973  #include <asm/pgtable.h>
5974 @@ -73,6 +79,364 @@ static inline int notify_page_fault(enum
5975  }
5976  #endif
5977  
5978 +#ifdef CONFIG_PAX_EMUSIGRT
5979 +void pax_syscall_close(struct vm_area_struct * vma)
5980 +{
5981 +       vma->vm_mm->call_syscall = 0UL;
5982 +}
5983 +
5984 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
5985 +{
5986 +       struct page* page;
5987 +       unsigned int *kaddr;
5988 +
5989 +       page = alloc_page(GFP_HIGHUSER);
5990 +       if (!page)
5991 +               return NOPAGE_OOM;
5992 +
5993 +       kaddr = kmap(page);
5994 +       memset(kaddr, 0, PAGE_SIZE);
5995 +       kaddr[0] = 0x44000002U; /* sc */
5996 +       __flush_dcache_icache(kaddr);
5997 +       kunmap(page);
5998 +       if (type)
5999 +               *type = VM_FAULT_MAJOR;
6000 +       return page;
6001 +}
6002 +
6003 +static struct vm_operations_struct pax_vm_ops = {
6004 +       .close = pax_syscall_close,
6005 +       .nopage = pax_syscall_nopage,
6006 +};
6007 +
6008 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6009 +{
6010 +       int ret;
6011 +
6012 +       memset(vma, 0, sizeof(*vma));
6013 +       vma->vm_mm = current->mm;
6014 +       vma->vm_start = addr;
6015 +       vma->vm_end = addr + PAGE_SIZE;
6016 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6017 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6018 +       vma->vm_ops = &pax_vm_ops;
6019 +
6020 +       ret = insert_vm_struct(current->mm, vma);
6021 +       if (ret)
6022 +               return ret;
6023 +
6024 +       ++current->mm->total_vm;
6025 +       return 0;
6026 +}
6027 +#endif
6028 +
6029 +#ifdef CONFIG_PAX_PAGEEXEC
6030 +/*
6031 + * PaX: decide what to do with offenders (regs->nip = fault address)
6032 + *
6033 + * returns 1 when task should be killed
6034 + *         2 when patched GOT trampoline was detected
6035 + *         3 when patched PLT trampoline was detected
6036 + *         4 when unpatched PLT trampoline was detected
6037 + *         5 when sigreturn trampoline was detected
6038 + *         7 when rt_sigreturn trampoline was detected
6039 + */
6040 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6041 +{
6042 +
6043 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
6044 +       int err;
6045 +#endif
6046 +
6047 +#ifdef CONFIG_PAX_EMUPLT
6048 +       do { /* PaX: patched GOT emulation */
6049 +               unsigned int blrl;
6050 +
6051 +               err = get_user(blrl, (unsigned int*)regs->nip);
6052 +
6053 +               if (!err && blrl == 0x4E800021U) {
6054 +                       unsigned long temp = regs->nip;
6055 +
6056 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
6057 +                       regs->link = temp + 4UL;
6058 +                       return 2;
6059 +               }
6060 +       } while (0);
6061 +
6062 +       do { /* PaX: patched PLT emulation #1 */
6063 +               unsigned int b;
6064 +
6065 +               err = get_user(b, (unsigned int *)regs->nip);
6066 +
6067 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
6068 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
6069 +                       return 3;
6070 +               }
6071 +       } while (0);
6072 +
6073 +       do { /* PaX: unpatched PLT emulation #1 */
6074 +               unsigned int li, b;
6075 +
6076 +               err = get_user(li, (unsigned int *)regs->nip);
6077 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
6078 +
6079 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6080 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6081 +                       unsigned long addr = b | 0xFC000000UL;
6082 +
6083 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6084 +                       err = get_user(rlwinm, (unsigned int*)addr);
6085 +                       err |= get_user(add, (unsigned int*)(addr+4));
6086 +                       err |= get_user(li2, (unsigned int*)(addr+8));
6087 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
6088 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
6089 +                       err |= get_user(li3, (unsigned int*)(addr+20));
6090 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
6091 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
6092 +
6093 +                       if (err)
6094 +                               break;
6095 +
6096 +                       if (rlwinm == 0x556C083CU &&
6097 +                           add == 0x7D6C5A14U &&
6098 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
6099 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6100 +                           mtctr == 0x7D8903A6U &&
6101 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
6102 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6103 +                           bctr == 0x4E800420U)
6104 +                       {
6105 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6106 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6107 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6108 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6109 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
6110 +                               regs->nip = regs->ctr;
6111 +                               return 4;
6112 +                       }
6113 +               }
6114 +       } while (0);
6115 +
6116 +#if 0
6117 +       do { /* PaX: unpatched PLT emulation #2 */
6118 +               unsigned int lis, lwzu, b, bctr;
6119 +
6120 +               err = get_user(lis, (unsigned int *)regs->nip);
6121 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
6122 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
6123 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
6124 +
6125 +               if (err)
6126 +                       break;
6127 +
6128 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
6129 +                   (lwzu & 0xU) == 0xU &&
6130 +                   (b & 0xFC000003U) == 0x48000000U &&
6131 +                   bctr == 0x4E800420U)
6132 +               {
6133 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6134 +                       unsigned long addr = b | 0xFC000000UL;
6135 +
6136 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6137 +                       err = get_user(addis, (unsigned int*)addr);
6138 +                       err |= get_user(addi, (unsigned int*)(addr+4));
6139 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
6140 +                       err |= get_user(add, (unsigned int*)(addr+12));
6141 +                       err |= get_user(li2, (unsigned int*)(addr+16));
6142 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
6143 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
6144 +                       err |= get_user(li3, (unsigned int*)(addr+28));
6145 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
6146 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
6147 +
6148 +                       if (err)
6149 +                               break;
6150 +
6151 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6152 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
6153 +                           rlwinm == 0x556C083CU &&
6154 +                           add == 0x7D6C5A14U &&
6155 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
6156 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6157 +                           mtctr == 0x7D8903A6U &&
6158 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
6159 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6160 +                           bctr == 0x4E800420U)
6161 +                       {
6162 +                               regs->gpr[PT_R11] = 
6163 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6164 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6165 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6166 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6167 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
6168 +                               regs->nip = regs->ctr;
6169 +                               return 4;
6170 +                       }
6171 +               }
6172 +       } while (0);
6173 +#endif
6174 +
6175 +       do { /* PaX: unpatched PLT emulation #3 */
6176 +               unsigned int li, b;
6177 +
6178 +               err = get_user(li, (unsigned int *)regs->nip);
6179 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
6180 +
6181 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6182 +                       unsigned int addis, lwz, mtctr, bctr;
6183 +                       unsigned long addr = b | 0xFC000000UL;
6184 +
6185 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6186 +                       err = get_user(addis, (unsigned int*)addr);
6187 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
6188 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
6189 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
6190 +
6191 +                       if (err)
6192 +                               break;
6193 +
6194 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6195 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
6196 +                           mtctr == 0x7D6903A6U &&
6197 +                           bctr == 0x4E800420U)
6198 +                       {
6199 +                               unsigned int r11;
6200 +
6201 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6202 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6203 +
6204 +                               err = get_user(r11, (unsigned int*)addr);
6205 +                               if (err)
6206 +                                       break;
6207 +
6208 +                               regs->gpr[PT_R11] = r11;
6209 +                               regs->ctr = r11;
6210 +                               regs->nip = r11;
6211 +                               return 4;
6212 +                       }
6213 +               }
6214 +       } while (0);
6215 +#endif
6216 +
6217 +#ifdef CONFIG_PAX_EMUSIGRT
6218 +       do { /* PaX: sigreturn emulation */
6219 +               unsigned int li, sc;
6220 +
6221 +               err = get_user(li, (unsigned int *)regs->nip);
6222 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
6223 +
6224 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
6225 +                       struct vm_area_struct *vma;
6226 +                       unsigned long call_syscall;
6227 +
6228 +                       down_read(&current->mm->mmap_sem);
6229 +                       call_syscall = current->mm->call_syscall;
6230 +                       up_read(&current->mm->mmap_sem);
6231 +                       if (likely(call_syscall))
6232 +                               goto emulate;
6233 +
6234 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6235 +
6236 +                       down_write(&current->mm->mmap_sem);
6237 +                       if (current->mm->call_syscall) {
6238 +                               call_syscall = current->mm->call_syscall;
6239 +                               up_write(&current->mm->mmap_sem);
6240 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6241 +                               goto emulate;
6242 +                       }
6243 +
6244 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6245 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
6246 +                               up_write(&current->mm->mmap_sem);
6247 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6248 +                               return 1;
6249 +                       }
6250 +
6251 +                       if (pax_insert_vma(vma, call_syscall)) {
6252 +                               up_write(&current->mm->mmap_sem);
6253 +                               kmem_cache_free(vm_area_cachep, vma);
6254 +                               return 1;
6255 +                       }
6256 +
6257 +                       current->mm->call_syscall = call_syscall;
6258 +                       up_write(&current->mm->mmap_sem);
6259 +
6260 +emulate:
6261 +                       regs->gpr[PT_R0] = __NR_sigreturn;
6262 +                       regs->nip = call_syscall;
6263 +                       return 5;
6264 +               }
6265 +       } while (0);
6266 +
6267 +       do { /* PaX: rt_sigreturn emulation */
6268 +               unsigned int li, sc;
6269 +
6270 +               err = get_user(li, (unsigned int *)regs->nip);
6271 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
6272 +
6273 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
6274 +                       struct vm_area_struct *vma;
6275 +                       unsigned int call_syscall;
6276 +
6277 +                       down_read(&current->mm->mmap_sem);
6278 +                       call_syscall = current->mm->call_syscall;
6279 +                       up_read(&current->mm->mmap_sem);
6280 +                       if (likely(call_syscall))
6281 +                               goto rt_emulate;
6282 +
6283 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6284 +
6285 +                       down_write(&current->mm->mmap_sem);
6286 +                       if (current->mm->call_syscall) {
6287 +                               call_syscall = current->mm->call_syscall;
6288 +                               up_write(&current->mm->mmap_sem);
6289 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6290 +                               goto rt_emulate;
6291 +                       }
6292 +
6293 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6294 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
6295 +                               up_write(&current->mm->mmap_sem);
6296 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6297 +                               return 1;
6298 +                       }
6299 +
6300 +                       if (pax_insert_vma(vma, call_syscall)) {
6301 +                               up_write(&current->mm->mmap_sem);
6302 +                               kmem_cache_free(vm_area_cachep, vma);
6303 +                               return 1;
6304 +                       }
6305 +
6306 +                       current->mm->call_syscall = call_syscall;
6307 +                       up_write(&current->mm->mmap_sem);
6308 +
6309 +rt_emulate:
6310 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
6311 +                       regs->nip = call_syscall;
6312 +                       return 6;
6313 +               }
6314 +       } while (0);
6315 +#endif
6316 +
6317 +       return 1;
6318 +}
6319 +
6320 +void pax_report_insns(void *pc, void *sp)
6321 +{
6322 +       unsigned long i;
6323 +
6324 +       printk(KERN_ERR "PAX: bytes at PC: ");
6325 +       for (i = 0; i < 5; i++) {
6326 +               unsigned int c;
6327 +               if (get_user(c, (unsigned int*)pc+i))
6328 +                       printk("???????? ");
6329 +               else
6330 +                       printk("%08x ", c);
6331 +       }
6332 +       printk("\n");
6333 +}
6334 +#endif
6335 +
6336  /*
6337   * Check whether the instruction at regs->nip is a store using
6338   * an update addressing form which will update r1.
6339 @@ -168,7 +532,7 @@ int __kprobes do_page_fault(struct pt_re
6340          * indicate errors in DSISR but can validly be set in SRR1.
6341          */
6342         if (trap == 0x400)
6343 -               error_code &= 0x48200000;
6344 +               error_code &= 0x58200000;
6345         else
6346                 is_write = error_code & DSISR_ISSTORE;
6347  #else
6348 @@ -295,9 +659,9 @@ good_area:
6349                 /* protection fault */
6350                 if (error_code & DSISR_PROTFAULT)
6351                         goto bad_area;
6352 +#endif
6353                 if (!(vma->vm_flags & VM_EXEC))
6354                         goto bad_area;
6355 -#endif
6356  #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
6357                 pte_t *ptep;
6358                 pmd_t *pmdp;
6359 @@ -368,6 +732,37 @@ bad_area:
6360  bad_area_nosemaphore:
6361         /* User mode accesses cause a SIGSEGV */
6362         if (user_mode(regs)) {
6363 +
6364 +#ifdef CONFIG_PAX_PAGEEXEC
6365 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
6366 +#ifdef CONFIG_PPC64
6367 +                       if (is_exec && (error_code & DSISR_PROTFAULT)) {
6368 +#else
6369 +                       if (is_exec && regs->nip == address) {
6370 +#endif
6371 +                               switch (pax_handle_fetch_fault(regs)) {
6372 +
6373 +#ifdef CONFIG_PAX_EMUPLT
6374 +                               case 2:
6375 +                               case 3:
6376 +                               case 4:
6377 +                                       return 0;
6378 +#endif
6379 +
6380 +#ifdef CONFIG_PAX_EMUSIGRT
6381 +                               case 5:
6382 +                               case 6:
6383 +                                       return 0;
6384 +#endif
6385 +
6386 +                               }
6387 +
6388 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
6389 +                               do_exit(SIGKILL);
6390 +                       }
6391 +               }
6392 +#endif
6393 +
6394                 _exception(SIGSEGV, regs, code, address);
6395                 return 0;
6396         }
6397 diff -urNp linux-2.6.18/arch/powerpc/mm/hugetlbpage.c linux-2.6.18/arch/powerpc/mm/hugetlbpage.c
6398 --- linux-2.6.18/arch/powerpc/mm/hugetlbpage.c  2006-09-19 23:42:06.000000000 -0400
6399 +++ linux-2.6.18/arch/powerpc/mm/hugetlbpage.c  2006-09-22 20:45:03.000000000 -0400
6400 @@ -562,6 +562,10 @@ unsigned long arch_get_unmapped_area(str
6401         if (len > TASK_SIZE)
6402                 return -ENOMEM;
6403  
6404 +#ifdef CONFIG_PAX_RANDMMAP
6405 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6406 +#endif
6407 +
6408         if (addr) {
6409                 addr = PAGE_ALIGN(addr);
6410                 vma = find_vma(mm, addr);
6411 @@ -573,7 +577,7 @@ unsigned long arch_get_unmapped_area(str
6412         if (len > mm->cached_hole_size) {
6413                 start_addr = addr = mm->free_area_cache;
6414         } else {
6415 -               start_addr = addr = TASK_UNMAPPED_BASE;
6416 +               start_addr = addr = mm->mmap_base;
6417                 mm->cached_hole_size = 0;
6418         }
6419  
6420 @@ -606,8 +610,8 @@ full_search:
6421         }
6422  
6423         /* Make sure we didn't miss any holes */
6424 -       if (start_addr != TASK_UNMAPPED_BASE) {
6425 -               start_addr = addr = TASK_UNMAPPED_BASE;
6426 +       if (start_addr != mm->mmap_base) {
6427 +               start_addr = addr = mm->mmap_base;
6428                 mm->cached_hole_size = 0;
6429                 goto full_search;
6430         }
6431 @@ -642,6 +646,11 @@ arch_get_unmapped_area_topdown(struct fi
6432                 mm->free_area_cache = base;
6433  
6434         /* requesting a specific address */
6435 +
6436 +#ifdef CONFIG_PAX_RANDMMAP
6437 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6438 +#endif
6439 +
6440         if (addr) {
6441                 addr = PAGE_ALIGN(addr);
6442                 vma = find_vma(mm, addr);
6443 @@ -721,12 +730,20 @@ fail:
6444          * can happen with large stack limits and large mmap()
6445          * allocations.
6446          */
6447 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
6448 +       mm->mmap_base = TASK_UNMAPPED_BASE;
6449 +
6450 +#ifdef CONFIG_PAX_RANDMMAP
6451 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
6452 +               mm->mmap_base += mm->delta_mmap;
6453 +#endif
6454 +
6455 +       mm->free_area_cache = mm->mmap_base;
6456         mm->cached_hole_size = ~0UL;
6457         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6458         /*
6459          * Restore the topdown base:
6460          */
6461 +       mm->mmap_base = base;
6462         mm->free_area_cache = base;
6463         mm->cached_hole_size = ~0UL;
6464  
6465 diff -urNp linux-2.6.18/arch/powerpc/mm/mmap.c linux-2.6.18/arch/powerpc/mm/mmap.c
6466 --- linux-2.6.18/arch/powerpc/mm/mmap.c 2006-09-19 23:42:06.000000000 -0400
6467 +++ linux-2.6.18/arch/powerpc/mm/mmap.c 2006-09-22 20:45:03.000000000 -0400
6468 @@ -74,10 +74,22 @@ void arch_pick_mmap_layout(struct mm_str
6469          */
6470         if (mmap_is_legacy()) {
6471                 mm->mmap_base = TASK_UNMAPPED_BASE;
6472 +
6473 +#ifdef CONFIG_PAX_RANDMMAP
6474 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6475 +                       mm->mmap_base += mm->delta_mmap;
6476 +#endif
6477 +
6478                 mm->get_unmapped_area = arch_get_unmapped_area;
6479                 mm->unmap_area = arch_unmap_area;
6480         } else {
6481                 mm->mmap_base = mmap_base();
6482 +
6483 +#ifdef CONFIG_PAX_RANDMMAP
6484 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6485 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
6486 +#endif
6487 +
6488                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
6489                 mm->unmap_area = arch_unmap_area_topdown;
6490         }
6491 diff -urNp linux-2.6.18/arch/ppc/mm/fault.c linux-2.6.18/arch/ppc/mm/fault.c
6492 --- linux-2.6.18/arch/ppc/mm/fault.c    2006-09-19 23:42:06.000000000 -0400
6493 +++ linux-2.6.18/arch/ppc/mm/fault.c    2006-09-22 20:45:03.000000000 -0400
6494 @@ -25,6 +25,11 @@
6495  #include <linux/interrupt.h>
6496  #include <linux/highmem.h>
6497  #include <linux/module.h>
6498 +#include <linux/slab.h>
6499 +#include <linux/pagemap.h>
6500 +#include <linux/compiler.h>
6501 +#include <linux/binfmts.h>
6502 +#include <linux/unistd.h>
6503  
6504  #include <asm/page.h>
6505  #include <asm/pgtable.h>
6506 @@ -48,6 +53,379 @@ unsigned long pte_misses;   /* updated by 
6507  unsigned long pte_errors;      /* updated by do_page_fault() */
6508  unsigned int probingmem;
6509  
6510 +#ifdef CONFIG_PAX_EMUSIGRT
6511 +void pax_syscall_close(struct vm_area_struct * vma)
6512 +{
6513 +       vma->vm_mm->call_syscall = 0UL;
6514 +}
6515 +
6516 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6517 +{
6518 +       struct page* page;
6519 +       unsigned int *kaddr;
6520 +
6521 +       page = alloc_page(GFP_HIGHUSER);
6522 +       if (!page)
6523 +               return NOPAGE_OOM;
6524 +
6525 +       kaddr = kmap(page);
6526 +       memset(kaddr, 0, PAGE_SIZE);
6527 +       kaddr[0] = 0x44000002U; /* sc */
6528 +       __flush_dcache_icache(kaddr);
6529 +       kunmap(page);
6530 +       if (type)
6531 +               *type = VM_FAULT_MAJOR;
6532 +       return page;
6533 +}
6534 +
6535 +static struct vm_operations_struct pax_vm_ops = {
6536 +       .close = pax_syscall_close,
6537 +       .nopage = pax_syscall_nopage,
6538 +};
6539 +
6540 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6541 +{
6542 +       int ret;
6543 +
6544 +       memset(vma, 0, sizeof(*vma));
6545 +       vma->vm_mm = current->mm;
6546 +       vma->vm_start = addr;
6547 +       vma->vm_end = addr + PAGE_SIZE;
6548 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6549 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6550 +       vma->vm_ops = &pax_vm_ops;
6551 +
6552 +       ret = insert_vm_struct(current->mm, vma);
6553 +       if (ret)
6554 +               return ret;
6555 +
6556 +       ++current->mm->total_vm;
6557 +       return 0;
6558 +}
6559 +#endif
6560 +
6561 +#ifdef CONFIG_PAX_PAGEEXEC
6562 +/*
6563 + * PaX: decide what to do with offenders (regs->nip = fault address)
6564 + *
6565 + * returns 1 when task should be killed
6566 + *         2 when patched GOT trampoline was detected
6567 + *         3 when patched PLT trampoline was detected
6568 + *         4 when unpatched PLT trampoline was detected
6569 + *         5 when sigreturn trampoline was detected
6570 + *         7 when rt_sigreturn trampoline was detected
6571 + */
6572 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6573 +{
6574 +
6575 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
6576 +       int err;
6577 +#endif
6578 +
6579 +#ifdef CONFIG_PAX_EMUPLT
6580 +       do { /* PaX: patched GOT emulation */
6581 +               unsigned int blrl;
6582 +
6583 +               err = get_user(blrl, (unsigned int*)regs->nip);
6584 +
6585 +               if (!err && blrl == 0x4E800021U) {
6586 +                       unsigned long temp = regs->nip;
6587 +
6588 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
6589 +                       regs->link = temp + 4UL;
6590 +                       return 2;
6591 +               }
6592 +       } while (0);
6593 +
6594 +       do { /* PaX: patched PLT emulation #1 */
6595 +               unsigned int b;
6596 +
6597 +               err = get_user(b, (unsigned int *)regs->nip);
6598 +
6599 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
6600 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
6601 +                       return 3;
6602 +               }
6603 +       } while (0);
6604 +
6605 +       do { /* PaX: unpatched PLT emulation #1 */
6606 +               unsigned int li, b;
6607 +
6608 +               err = get_user(li, (unsigned int *)regs->nip);
6609 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
6610 +
6611 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6612 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6613 +                       unsigned long addr = b | 0xFC000000UL;
6614 +
6615 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6616 +                       err = get_user(rlwinm, (unsigned int*)addr);
6617 +                       err |= get_user(add, (unsigned int*)(addr+4));
6618 +                       err |= get_user(li2, (unsigned int*)(addr+8));
6619 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
6620 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
6621 +                       err |= get_user(li3, (unsigned int*)(addr+20));
6622 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
6623 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
6624 +
6625 +                       if (err)
6626 +                               break;
6627 +
6628 +                       if (rlwinm == 0x556C083CU &&
6629 +                           add == 0x7D6C5A14U &&
6630 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
6631 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6632 +                           mtctr == 0x7D8903A6U &&
6633 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
6634 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6635 +                           bctr == 0x4E800420U)
6636 +                       {
6637 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6638 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6639 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6640 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6641 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
6642 +                               regs->nip = regs->ctr;
6643 +                               return 4;
6644 +                       }
6645 +               }
6646 +       } while (0);
6647 +
6648 +#if 0
6649 +       do { /* PaX: unpatched PLT emulation #2 */
6650 +               unsigned int lis, lwzu, b, bctr;
6651 +
6652 +               err = get_user(lis, (unsigned int *)regs->nip);
6653 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
6654 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
6655 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
6656 +
6657 +               if (err)
6658 +                       break;
6659 +
6660 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
6661 +                   (lwzu & 0xU) == 0xU &&
6662 +                   (b & 0xFC000003U) == 0x48000000U &&
6663 +                   bctr == 0x4E800420U)
6664 +               {
6665 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6666 +                       unsigned long addr = b | 0xFC000000UL;
6667 +
6668 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6669 +                       err = get_user(addis, (unsigned int*)addr);
6670 +                       err |= get_user(addi, (unsigned int*)(addr+4));
6671 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
6672 +                       err |= get_user(add, (unsigned int*)(addr+12));
6673 +                       err |= get_user(li2, (unsigned int*)(addr+16));
6674 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
6675 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
6676 +                       err |= get_user(li3, (unsigned int*)(addr+28));
6677 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
6678 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
6679 +
6680 +                       if (err)
6681 +                               break;
6682 +
6683 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6684 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
6685 +                           rlwinm == 0x556C083CU &&
6686 +                           add == 0x7D6C5A14U &&
6687 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
6688 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6689 +                           mtctr == 0x7D8903A6U &&
6690 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
6691 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6692 +                           bctr == 0x4E800420U)
6693 +                       {
6694 +                               regs->gpr[PT_R11] = 
6695 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6696 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6697 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6698 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6699 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
6700 +                               regs->nip = regs->ctr;
6701 +                               return 4;
6702 +                       }
6703 +               }
6704 +       } while (0);
6705 +#endif
6706 +
6707 +       do { /* PaX: unpatched PLT emulation #3 */
6708 +               unsigned int li, b;
6709 +
6710 +               err = get_user(li, (unsigned int *)regs->nip);
6711 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
6712 +
6713 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6714 +                       unsigned int addis, lwz, mtctr, bctr;
6715 +                       unsigned long addr = b | 0xFC000000UL;
6716 +
6717 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6718 +                       err = get_user(addis, (unsigned int*)addr);
6719 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
6720 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
6721 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
6722 +
6723 +                       if (err)
6724 +                               break;
6725 +
6726 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6727 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
6728 +                           mtctr == 0x7D6903A6U &&
6729 +                           bctr == 0x4E800420U)
6730 +                       {
6731 +                               unsigned int r11;
6732 +
6733 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6734 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6735 +
6736 +                               err = get_user(r11, (unsigned int*)addr);
6737 +                               if (err)
6738 +                                       break;
6739 +
6740 +                               regs->gpr[PT_R11] = r11;
6741 +                               regs->ctr = r11;
6742 +                               regs->nip = r11;
6743 +                               return 4;
6744 +                       }
6745 +               }
6746 +       } while (0);
6747 +#endif
6748 +
6749 +#ifdef CONFIG_PAX_EMUSIGRT
6750 +       do { /* PaX: sigreturn emulation */
6751 +               unsigned int li, sc;
6752 +
6753 +               err = get_user(li, (unsigned int *)regs->nip);
6754 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
6755 +
6756 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
6757 +                       struct vm_area_struct *vma;
6758 +                       unsigned long call_syscall;
6759 +
6760 +                       down_read(&current->mm->mmap_sem);
6761 +                       call_syscall = current->mm->call_syscall;
6762 +                       up_read(&current->mm->mmap_sem);
6763 +                       if (likely(call_syscall))
6764 +                               goto emulate;
6765 +
6766 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6767 +
6768 +                       down_write(&current->mm->mmap_sem);
6769 +                       if (current->mm->call_syscall) {
6770 +                               call_syscall = current->mm->call_syscall;
6771 +                               up_write(&current->mm->mmap_sem);
6772 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6773 +                               goto emulate;
6774 +                       }
6775 +
6776 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6777 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
6778 +                               up_write(&current->mm->mmap_sem);
6779 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6780 +                               return 1;
6781 +                       }
6782 +
6783 +                       if (pax_insert_vma(vma, call_syscall)) {
6784 +                               up_write(&current->mm->mmap_sem);
6785 +                               kmem_cache_free(vm_area_cachep, vma);
6786 +                               return 1;
6787 +                       }
6788 +
6789 +                       current->mm->call_syscall = call_syscall;
6790 +                       up_write(&current->mm->mmap_sem);
6791 +
6792 +emulate:
6793 +                       regs->gpr[PT_R0] = __NR_sigreturn;
6794 +                       regs->nip = call_syscall;
6795 +                       return 5;
6796 +               }
6797 +       } while (0);
6798 +
6799 +       do { /* PaX: rt_sigreturn emulation */
6800 +               unsigned int li, sc;
6801 +
6802 +               err = get_user(li, (unsigned int *)regs->nip);
6803 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
6804 +
6805 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
6806 +                       struct vm_area_struct *vma;
6807 +                       unsigned int call_syscall;
6808 +
6809 +                       down_read(&current->mm->mmap_sem);
6810 +                       call_syscall = current->mm->call_syscall;
6811 +                       up_read(&current->mm->mmap_sem);
6812 +                       if (likely(call_syscall))
6813 +                               goto rt_emulate;
6814 +
6815 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6816 +
6817 +                       down_write(&current->mm->mmap_sem);
6818 +                       if (current->mm->call_syscall) {
6819 +                               call_syscall = current->mm->call_syscall;
6820 +                               up_write(&current->mm->mmap_sem);
6821 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6822 +                               goto rt_emulate;
6823 +                       }
6824 +
6825 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6826 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
6827 +                               up_write(&current->mm->mmap_sem);
6828 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6829 +                               return 1;
6830 +                       }
6831 +
6832 +                       if (pax_insert_vma(vma, call_syscall)) {
6833 +                               up_write(&current->mm->mmap_sem);
6834 +                               kmem_cache_free(vm_area_cachep, vma);
6835 +                               return 1;
6836 +                       }
6837 +
6838 +                       current->mm->call_syscall = call_syscall;
6839 +                       up_write(&current->mm->mmap_sem);
6840 +
6841 +rt_emulate:
6842 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
6843 +                       regs->nip = call_syscall;
6844 +                       return 6;
6845 +               }
6846 +       } while (0);
6847 +#endif
6848 +
6849 +       return 1;
6850 +}
6851 +
6852 +/*
6853 + * PaX: decide what to do with offenders (regs->nip = fault address)
6854 + *
6855 + * returns 1 when task should be killed
6856 + */
6857 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6858 +{
6859 +
6860 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
6861 +       int err;
6862 +#endif
6863 +
6864 +       return 1;
6865 +}
6866 +
6867 +void pax_report_insns(void *pc, void *sp)
6868 +{
6869 +       unsigned long i;
6870 +
6871 +       printk(KERN_ERR "PAX: bytes at PC: ");
6872 +       for (i = 0; i < 5; i++) {
6873 +               unsigned int c;
6874 +               if (get_user(c, (unsigned int*)pc+i))
6875 +                       printk("???????? ");
6876 +               else
6877 +                       printk("%08x ", c);
6878 +       }
6879 +       printk("\n");
6880 +}
6881 +#endif
6882 +
6883  /*
6884   * Check whether the instruction at regs->nip is a store using
6885   * an update addressing form which will update r1.
6886 @@ -108,7 +486,7 @@ int do_page_fault(struct pt_regs *regs, 
6887          * indicate errors in DSISR but can validly be set in SRR1.
6888          */
6889         if (TRAP(regs) == 0x400)
6890 -               error_code &= 0x48200000;
6891 +               error_code &= 0x58200000;
6892         else
6893                 is_write = error_code & 0x02000000;
6894  #endif /* CONFIG_4xx || CONFIG_BOOKE */
6895 @@ -203,15 +581,14 @@ good_area:
6896                 pte_t *ptep;
6897                 pmd_t *pmdp;
6898  
6899 -#if 0
6900 +#if 1
6901                 /* It would be nice to actually enforce the VM execute
6902                    permission on CPUs which can do so, but far too
6903                    much stuff in userspace doesn't get the permissions
6904                    right, so we let any page be executed for now. */
6905                 if (! (vma->vm_flags & VM_EXEC))
6906                         goto bad_area;
6907 -#endif
6908 -
6909 +#else
6910                 /* Since 4xx/Book-E supports per-page execute permission,
6911                  * we lazily flush dcache to icache. */
6912                 ptep = NULL;
6913 @@ -234,6 +611,7 @@ good_area:
6914                         pte_unmap_unlock(ptep, ptl);
6915                 }
6916  #endif
6917 +#endif
6918         /* a read */
6919         } else {
6920                 /* protection fault */
6921 @@ -279,6 +657,33 @@ bad_area:
6922  
6923         /* User mode accesses cause a SIGSEGV */
6924         if (user_mode(regs)) {
6925 +
6926 +#ifdef CONFIG_PAX_PAGEEXEC
6927 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
6928 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
6929 +                               switch (pax_handle_fetch_fault(regs)) {
6930 +
6931 +#ifdef CONFIG_PAX_EMUPLT
6932 +                               case 2:
6933 +                               case 3:
6934 +                               case 4:
6935 +                                       return 0;
6936 +#endif
6937 +
6938 +#ifdef CONFIG_PAX_EMUSIGRT
6939 +                               case 5:
6940 +                               case 6:
6941 +                                       return 0;
6942 +#endif
6943 +
6944 +                               }
6945 +
6946 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
6947 +                               do_exit(SIGKILL);
6948 +                       }
6949 +               }
6950 +#endif
6951 +
6952                 _exception(SIGSEGV, regs, code, address);
6953                 return 0;
6954         }
6955 diff -urNp linux-2.6.18/arch/s390/kernel/module.c linux-2.6.18/arch/s390/kernel/module.c
6956 --- linux-2.6.18/arch/s390/kernel/module.c      2006-09-19 23:42:06.000000000 -0400
6957 +++ linux-2.6.18/arch/s390/kernel/module.c      2006-09-22 20:45:03.000000000 -0400
6958 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
6959  
6960         /* Increase core size by size of got & plt and set start
6961            offsets for got and plt. */
6962 -       me->core_size = ALIGN(me->core_size, 4);
6963 -       me->arch.got_offset = me->core_size;
6964 -       me->core_size += me->arch.got_size;
6965 -       me->arch.plt_offset = me->core_size;
6966 -       me->core_size += me->arch.plt_size;
6967 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
6968 +       me->arch.got_offset = me->core_size_rw;
6969 +       me->core_size_rw += me->arch.got_size;
6970 +       me->arch.plt_offset = me->core_size_rx;
6971 +       me->core_size_rx += me->arch.plt_size;
6972         return 0;
6973  }
6974  
6975 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6976                 if (info->got_initialized == 0) {
6977                         Elf_Addr *gotent;
6978  
6979 -                       gotent = me->module_core + me->arch.got_offset +
6980 +                       gotent = me->module_core_rw + me->arch.got_offset +
6981                                 info->got_offset;
6982                         *gotent = val;
6983                         info->got_initialized = 1;
6984 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6985                 else if (r_type == R_390_GOTENT ||
6986                          r_type == R_390_GOTPLTENT)
6987                         *(unsigned int *) loc =
6988 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
6989 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
6990                 else if (r_type == R_390_GOT64 ||
6991                          r_type == R_390_GOTPLT64)
6992                         *(unsigned long *) loc = val;
6993 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6994         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
6995                 if (info->plt_initialized == 0) {
6996                         unsigned int *ip;
6997 -                       ip = me->module_core + me->arch.plt_offset +
6998 +                       ip = me->module_core_rx + me->arch.plt_offset +
6999                                 info->plt_offset;
7000  #ifndef CONFIG_64BIT
7001                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
7002 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7003                         val = me->arch.plt_offset - me->arch.got_offset +
7004                                 info->plt_offset + rela->r_addend;
7005                 else
7006 -                       val =  (Elf_Addr) me->module_core +
7007 +                       val =  (Elf_Addr) me->module_core_rx +
7008                                 me->arch.plt_offset + info->plt_offset + 
7009                                 rela->r_addend - loc;
7010                 if (r_type == R_390_PLT16DBL)
7011 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7012         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
7013         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
7014                 val = val + rela->r_addend -
7015 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
7016 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
7017                 if (r_type == R_390_GOTOFF16)
7018                         *(unsigned short *) loc = val;
7019                 else if (r_type == R_390_GOTOFF32)
7020 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7021                 break;
7022         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
7023         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
7024 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
7025 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
7026                         rela->r_addend - loc;
7027                 if (r_type == R_390_GOTPC)
7028                         *(unsigned int *) loc = val;
7029 diff -urNp linux-2.6.18/arch/sparc/kernel/ptrace.c linux-2.6.18/arch/sparc/kernel/ptrace.c
7030 --- linux-2.6.18/arch/sparc/kernel/ptrace.c     2006-09-19 23:42:06.000000000 -0400
7031 +++ linux-2.6.18/arch/sparc/kernel/ptrace.c     2006-09-22 20:04:35.000000000 -0400
7032 @@ -19,6 +19,7 @@
7033  #include <linux/smp_lock.h>
7034  #include <linux/security.h>
7035  #include <linux/signal.h>
7036 +#include <linux/grsecurity.h>
7037  
7038  #include <asm/pgtable.h>
7039  #include <asm/system.h>
7040 @@ -300,6 +301,11 @@ asmlinkage void do_ptrace(struct pt_regs
7041                 goto out;
7042         }
7043  
7044 +       if (gr_handle_ptrace(child, request)) {
7045 +               pt_error_return(regs, EPERM);
7046 +               goto out_tsk;
7047 +       }
7048 +
7049         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
7050             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
7051                 if (ptrace_attach(child)) {
7052 diff -urNp linux-2.6.18/arch/sparc/kernel/sys_sparc.c linux-2.6.18/arch/sparc/kernel/sys_sparc.c
7053 --- linux-2.6.18/arch/sparc/kernel/sys_sparc.c  2006-09-19 23:42:06.000000000 -0400
7054 +++ linux-2.6.18/arch/sparc/kernel/sys_sparc.c  2006-09-22 20:45:03.000000000 -0400
7055 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
7056         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
7057                 return -ENOMEM;
7058         if (!addr)
7059 -               addr = TASK_UNMAPPED_BASE;
7060 +               addr = current->mm->mmap_base;
7061  
7062         if (flags & MAP_SHARED)
7063                 addr = COLOUR_ALIGN(addr);
7064 diff -urNp linux-2.6.18/arch/sparc/Makefile linux-2.6.18/arch/sparc/Makefile
7065 --- linux-2.6.18/arch/sparc/Makefile    2006-09-19 23:42:06.000000000 -0400
7066 +++ linux-2.6.18/arch/sparc/Makefile    2006-09-22 20:04:35.000000000 -0400
7067 @@ -34,7 +34,7 @@ libs-y += arch/sparc/prom/ arch/sparc/li
7068  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
7069  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
7070  CORE_Y         := $(core-y)
7071 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
7072 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
7073  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
7074  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
7075  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
7076 diff -urNp linux-2.6.18/arch/sparc/mm/fault.c linux-2.6.18/arch/sparc/mm/fault.c
7077 --- linux-2.6.18/arch/sparc/mm/fault.c  2006-09-19 23:42:06.000000000 -0400
7078 +++ linux-2.6.18/arch/sparc/mm/fault.c  2006-09-22 20:45:03.000000000 -0400
7079 @@ -21,6 +21,10 @@
7080  #include <linux/smp_lock.h>
7081  #include <linux/interrupt.h>
7082  #include <linux/module.h>
7083 +#include <linux/slab.h>
7084 +#include <linux/pagemap.h>
7085 +#include <linux/compiler.h>
7086 +#include <linux/binfmts.h>
7087  
7088  #include <asm/system.h>
7089  #include <asm/page.h>
7090 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
7091         return safe_compute_effective_address(regs, insn);
7092  }
7093  
7094 +#ifdef CONFIG_PAX_PAGEEXEC
7095 +void pax_emuplt_close(struct vm_area_struct * vma)
7096 +{
7097 +       vma->vm_mm->call_dl_resolve = 0UL;
7098 +}
7099 +
7100 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7101 +{
7102 +       struct page* page;
7103 +       unsigned int *kaddr;
7104 +
7105 +       page = alloc_page(GFP_HIGHUSER);
7106 +       if (!page)
7107 +               return NOPAGE_OOM;
7108 +
7109 +       kaddr = kmap(page);
7110 +       memset(kaddr, 0, PAGE_SIZE);
7111 +       kaddr[0] = 0x9DE3BFA8U; /* save */
7112 +       flush_dcache_page(page);
7113 +       kunmap(page);
7114 +       if (type)
7115 +               *type = VM_FAULT_MAJOR;
7116 +
7117 +       return page;
7118 +}
7119 +
7120 +static struct vm_operations_struct pax_vm_ops = {
7121 +       .close = pax_emuplt_close,
7122 +       .nopage = pax_emuplt_nopage,
7123 +};
7124 +
7125 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7126 +{
7127 +       int ret;
7128 +
7129 +       memset(vma, 0, sizeof(*vma));
7130 +       vma->vm_mm = current->mm;
7131 +       vma->vm_start = addr;
7132 +       vma->vm_end = addr + PAGE_SIZE;
7133 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7134 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
7135 +       vma->vm_ops = &pax_vm_ops;
7136 +
7137 +       ret = insert_vm_struct(current->mm, vma);
7138 +       if (ret)
7139 +               return ret;
7140 +
7141 +       ++current->mm->total_vm;
7142 +       return 0;
7143 +}
7144 +
7145 +/*
7146 + * PaX: decide what to do with offenders (regs->pc = fault address)
7147 + *
7148 + * returns 1 when task should be killed
7149 + *         2 when patched PLT trampoline was detected
7150 + *         3 when unpatched PLT trampoline was detected
7151 + */
7152 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7153 +{
7154 +
7155 +#ifdef CONFIG_PAX_EMUPLT
7156 +       int err;
7157 +
7158 +       do { /* PaX: patched PLT emulation #1 */
7159 +               unsigned int sethi1, sethi2, jmpl;
7160 +
7161 +               err = get_user(sethi1, (unsigned int*)regs->pc);
7162 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
7163 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
7164 +
7165 +               if (err)
7166 +                       break;
7167 +
7168 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
7169 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
7170 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
7171 +               {
7172 +                       unsigned int addr;
7173 +
7174 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
7175 +                       addr = regs->u_regs[UREG_G1];
7176 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7177 +                       regs->pc = addr;
7178 +                       regs->npc = addr+4;
7179 +                       return 2;
7180 +               }
7181 +       } while (0);
7182 +
7183 +       { /* PaX: patched PLT emulation #2 */
7184 +               unsigned int ba;
7185 +
7186 +               err = get_user(ba, (unsigned int*)regs->pc);
7187 +
7188 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
7189 +                       unsigned int addr;
7190 +
7191 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7192 +                       regs->pc = addr;
7193 +                       regs->npc = addr+4;
7194 +                       return 2;
7195 +               }
7196 +       }
7197 +
7198 +       do { /* PaX: patched PLT emulation #3 */
7199 +               unsigned int sethi, jmpl, nop;
7200 +
7201 +               err = get_user(sethi, (unsigned int*)regs->pc);
7202 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
7203 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
7204 +
7205 +               if (err)
7206 +                       break;
7207 +
7208 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
7209 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
7210 +                   nop == 0x01000000U)
7211 +               {
7212 +                       unsigned int addr;
7213 +
7214 +                       addr = (sethi & 0x003FFFFFU) << 10;
7215 +                       regs->u_regs[UREG_G1] = addr;
7216 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7217 +                       regs->pc = addr;
7218 +                       regs->npc = addr+4;
7219 +                       return 2;
7220 +               }
7221 +       } while (0);
7222 +
7223 +       do { /* PaX: unpatched PLT emulation step 1 */
7224 +               unsigned int sethi, ba, nop;
7225 +
7226 +               err = get_user(sethi, (unsigned int*)regs->pc);
7227 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
7228 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
7229 +
7230 +               if (err)
7231 +                       break;
7232 +
7233 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
7234 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
7235 +                   nop == 0x01000000U)
7236 +               {
7237 +                       unsigned int addr, save, call;
7238 +
7239 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
7240 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7241 +                       else
7242 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
7243 +
7244 +                       err = get_user(save, (unsigned int*)addr);
7245 +                       err |= get_user(call, (unsigned int*)(addr+4));
7246 +                       err |= get_user(nop, (unsigned int*)(addr+8));
7247 +                       if (err)
7248 +                               break;
7249 +
7250 +                       if (save == 0x9DE3BFA8U &&
7251 +                           (call & 0xC0000000U) == 0x40000000U &&
7252 +                           nop == 0x01000000U)
7253 +                       {
7254 +                               struct vm_area_struct *vma;
7255 +                               unsigned long call_dl_resolve;
7256 +
7257 +                               down_read(&current->mm->mmap_sem);
7258 +                               call_dl_resolve = current->mm->call_dl_resolve;
7259 +                               up_read(&current->mm->mmap_sem);
7260 +                               if (likely(call_dl_resolve))
7261 +                                       goto emulate;
7262 +
7263 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7264 +
7265 +                               down_write(&current->mm->mmap_sem);
7266 +                               if (current->mm->call_dl_resolve) {
7267 +                                       call_dl_resolve = current->mm->call_dl_resolve;
7268 +                                       up_write(&current->mm->mmap_sem);
7269 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
7270 +                                       goto emulate;
7271 +                               }
7272 +
7273 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7274 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
7275 +                                       up_write(&current->mm->mmap_sem);
7276 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
7277 +                                       return 1;
7278 +                               }
7279 +
7280 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
7281 +                                       up_write(&current->mm->mmap_sem);
7282 +                                       kmem_cache_free(vm_area_cachep, vma);
7283 +                                       return 1;
7284 +                               }
7285 +
7286 +                               current->mm->call_dl_resolve = call_dl_resolve;
7287 +                               up_write(&current->mm->mmap_sem);
7288 +
7289 +emulate:
7290 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
7291 +                               regs->pc = call_dl_resolve;
7292 +                               regs->npc = addr+4;
7293 +                               return 3;
7294 +                       }
7295 +               }
7296 +       } while (0);
7297 +
7298 +       do { /* PaX: unpatched PLT emulation step 2 */
7299 +               unsigned int save, call, nop;
7300 +
7301 +               err = get_user(save, (unsigned int*)(regs->pc-4));
7302 +               err |= get_user(call, (unsigned int*)regs->pc);
7303 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
7304 +               if (err)
7305 +                       break;
7306 +
7307 +               if (save == 0x9DE3BFA8U &&
7308 +                   (call & 0xC0000000U) == 0x40000000U &&
7309 +                   nop == 0x01000000U)
7310 +               {
7311 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
7312 +
7313 +                       regs->u_regs[UREG_RETPC] = regs->pc;
7314 +                       regs->pc = dl_resolve;
7315 +                       regs->npc = dl_resolve+4;
7316 +                       return 3;
7317 +               }
7318 +       } while (0);
7319 +#endif
7320 +
7321 +       return 1;
7322 +}
7323 +
7324 +void pax_report_insns(void *pc, void *sp)
7325 +{
7326 +       unsigned long i;
7327 +
7328 +       printk(KERN_ERR "PAX: bytes at PC: ");
7329 +       for (i = 0; i < 5; i++) {
7330 +               unsigned int c;
7331 +               if (get_user(c, (unsigned int*)pc+i))
7332 +                       printk("???????? ");
7333 +               else
7334 +                       printk("%08x ", c);
7335 +       }
7336 +       printk("\n");
7337 +}
7338 +#endif
7339 +
7340  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
7341                                unsigned long address)
7342  {
7343 @@ -280,6 +530,24 @@ good_area:
7344                 if(!(vma->vm_flags & VM_WRITE))
7345                         goto bad_area;
7346         } else {
7347 +
7348 +#ifdef CONFIG_PAX_PAGEEXEC
7349 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
7350 +                       up_read(&mm->mmap_sem);
7351 +                       switch (pax_handle_fetch_fault(regs)) {
7352 +
7353 +#ifdef CONFIG_PAX_EMUPLT
7354 +                       case 2:
7355 +                       case 3:
7356 +                               return;
7357 +#endif
7358 +
7359 +                       }
7360 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
7361 +                       do_exit(SIGKILL);
7362 +               }
7363 +#endif
7364 +
7365                 /* Allow reads even for write-only mappings */
7366                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
7367                         goto bad_area;
7368 diff -urNp linux-2.6.18/arch/sparc/mm/init.c linux-2.6.18/arch/sparc/mm/init.c
7369 --- linux-2.6.18/arch/sparc/mm/init.c   2006-09-19 23:42:06.000000000 -0400
7370 +++ linux-2.6.18/arch/sparc/mm/init.c   2006-09-22 20:45:03.000000000 -0400
7371 @@ -333,17 +333,17 @@ void __init paging_init(void)
7372  
7373         /* Initialize the protection map with non-constant, MMU dependent values. */
7374         protection_map[0] = PAGE_NONE;
7375 -       protection_map[1] = PAGE_READONLY;
7376 -       protection_map[2] = PAGE_COPY;
7377 -       protection_map[3] = PAGE_COPY;
7378 +       protection_map[1] = PAGE_READONLY_NOEXEC;
7379 +       protection_map[2] = PAGE_COPY_NOEXEC;
7380 +       protection_map[3] = PAGE_COPY_NOEXEC;
7381         protection_map[4] = PAGE_READONLY;
7382         protection_map[5] = PAGE_READONLY;
7383         protection_map[6] = PAGE_COPY;
7384         protection_map[7] = PAGE_COPY;
7385         protection_map[8] = PAGE_NONE;
7386 -       protection_map[9] = PAGE_READONLY;
7387 -       protection_map[10] = PAGE_SHARED;
7388 -       protection_map[11] = PAGE_SHARED;
7389 +       protection_map[9] = PAGE_READONLY_NOEXEC;
7390 +       protection_map[10] = PAGE_SHARED_NOEXEC;
7391 +       protection_map[11] = PAGE_SHARED_NOEXEC;
7392         protection_map[12] = PAGE_READONLY;
7393         protection_map[13] = PAGE_READONLY;
7394         protection_map[14] = PAGE_SHARED;
7395 diff -urNp linux-2.6.18/arch/sparc/mm/srmmu.c linux-2.6.18/arch/sparc/mm/srmmu.c
7396 --- linux-2.6.18/arch/sparc/mm/srmmu.c  2006-09-19 23:42:06.000000000 -0400
7397 +++ linux-2.6.18/arch/sparc/mm/srmmu.c  2006-09-22 20:45:03.000000000 -0400
7398 @@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
7399         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
7400         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
7401         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
7402 +
7403 +#ifdef CONFIG_PAX_PAGEEXEC
7404 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
7405 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
7406 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
7407 +#endif
7408 +
7409         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
7410         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
7411  
7412 diff -urNp linux-2.6.18/arch/sparc64/kernel/ptrace.c linux-2.6.18/arch/sparc64/kernel/ptrace.c
7413 --- linux-2.6.18/arch/sparc64/kernel/ptrace.c   2006-09-19 23:42:06.000000000 -0400
7414 +++ linux-2.6.18/arch/sparc64/kernel/ptrace.c   2006-09-22 20:04:35.000000000 -0400
7415 @@ -22,6 +22,7 @@
7416  #include <linux/seccomp.h>
7417  #include <linux/audit.h>
7418  #include <linux/signal.h>
7419 +#include <linux/grsecurity.h>
7420  
7421  #include <asm/asi.h>
7422  #include <asm/pgtable.h>
7423 @@ -213,6 +214,11 @@ asmlinkage void do_ptrace(struct pt_regs
7424                 goto out;
7425         }
7426  
7427 +       if (gr_handle_ptrace(child, (long)request)) {
7428 +               pt_error_return(regs, EPERM);
7429 +               goto out_tsk;
7430 +       }
7431 +
7432         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
7433             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
7434                 if (ptrace_attach(child)) {
7435 diff -urNp linux-2.6.18/arch/sparc64/kernel/sys_sparc.c linux-2.6.18/arch/sparc64/kernel/sys_sparc.c
7436 --- linux-2.6.18/arch/sparc64/kernel/sys_sparc.c        2006-09-19 23:42:06.000000000 -0400
7437 +++ linux-2.6.18/arch/sparc64/kernel/sys_sparc.c        2006-09-22 20:45:03.000000000 -0400
7438 @@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
7439         if (filp || (flags & MAP_SHARED))
7440                 do_color_align = 1;
7441  
7442 +#ifdef CONFIG_PAX_RANDMMAP
7443 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7444 +#endif
7445 +
7446         if (addr) {
7447                 if (do_color_align)
7448                         addr = COLOUR_ALIGN(addr, pgoff);
7449 @@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
7450         }
7451  
7452         if (len > mm->cached_hole_size) {
7453 -               start_addr = addr = mm->free_area_cache;
7454 +               start_addr = addr = mm->free_area_cache;
7455         } else {
7456 -               start_addr = addr = TASK_UNMAPPED_BASE;
7457 +               start_addr = addr = mm->mmap_base;
7458                 mm->cached_hole_size = 0;
7459         }
7460  
7461 @@ -174,8 +178,8 @@ full_search:
7462                         vma = find_vma(mm, VA_EXCLUDE_END);
7463                 }
7464                 if (unlikely(task_size < addr)) {
7465 -                       if (start_addr != TASK_UNMAPPED_BASE) {
7466 -                               start_addr = addr = TASK_UNMAPPED_BASE;
7467 +                       if (start_addr != mm->mmap_base) {
7468 +                               start_addr = addr = mm->mmap_base;
7469                                 mm->cached_hole_size = 0;
7470                                 goto full_search;
7471                         }
7472 @@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
7473             current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
7474             sysctl_legacy_va_layout) {
7475                 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
7476 +
7477 +#ifdef CONFIG_PAX_RANDMMAP
7478 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7479 +                       mm->mmap_base += mm->delta_mmap;
7480 +#endif
7481 +
7482                 mm->get_unmapped_area = arch_get_unmapped_area;
7483                 mm->unmap_area = arch_unmap_area;
7484         } else {
7485 @@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
7486                         gap = (task_size / 6 * 5);
7487  
7488                 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
7489 +
7490 +#ifdef CONFIG_PAX_RANDMMAP
7491 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7492 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7493 +#endif
7494 +
7495                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7496                 mm->unmap_area = arch_unmap_area_topdown;
7497         }
7498 diff -urNp linux-2.6.18/arch/sparc64/mm/fault.c linux-2.6.18/arch/sparc64/mm/fault.c
7499 --- linux-2.6.18/arch/sparc64/mm/fault.c        2006-09-19 23:42:06.000000000 -0400
7500 +++ linux-2.6.18/arch/sparc64/mm/fault.c        2006-09-22 20:45:03.000000000 -0400
7501 @@ -20,6 +20,10 @@
7502  #include <linux/interrupt.h>
7503  #include <linux/kprobes.h>
7504  #include <linux/kallsyms.h>
7505 +#include <linux/slab.h>
7506 +#include <linux/pagemap.h>
7507 +#include <linux/compiler.h>
7508 +#include <linux/binfmts.h>
7509  
7510  #include <asm/page.h>
7511  #include <asm/pgtable.h>
7512 @@ -290,6 +294,369 @@ cannot_handle:
7513         unhandled_fault (address, current, regs);
7514  }
7515  
7516 +#ifdef CONFIG_PAX_PAGEEXEC
7517 +#ifdef CONFIG_PAX_EMUPLT
7518 +static void pax_emuplt_close(struct vm_area_struct * vma)
7519 +{
7520 +       vma->vm_mm->call_dl_resolve = 0UL;
7521 +}
7522 +
7523 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7524 +{
7525 +       struct page* page;
7526 +       unsigned int *kaddr;
7527 +
7528 +       page = alloc_page(GFP_HIGHUSER);
7529 +       if (!page)
7530 +               return NOPAGE_OOM;
7531 +
7532 +       kaddr = kmap(page);
7533 +       memset(kaddr, 0, PAGE_SIZE);
7534 +       kaddr[0] = 0x9DE3BFA8U; /* save */
7535 +       flush_dcache_page(page);
7536 +       kunmap(page);
7537 +       if (type)
7538 +               *type = VM_FAULT_MAJOR;
7539 +       return page;
7540 +}
7541 +
7542 +static struct vm_operations_struct pax_vm_ops = {
7543 +       .close = pax_emuplt_close,
7544 +       .nopage = pax_emuplt_nopage,
7545 +};
7546 +
7547 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7548 +{
7549 +       int ret;
7550 +
7551 +       memset(vma, 0, sizeof(*vma));
7552 +       vma->vm_mm = current->mm;
7553 +       vma->vm_start = addr;
7554 +       vma->vm_end = addr + PAGE_SIZE;
7555 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7556 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
7557 +       vma->vm_ops = &pax_vm_ops;
7558 +
7559 +       ret = insert_vm_struct(current->mm, vma);
7560 +       if (ret)
7561 +               return ret;
7562 +
7563 +       ++current->mm->total_vm;
7564 +       return 0;
7565 +}
7566 +#endif
7567 +
7568 +/*
7569 + * PaX: decide what to do with offenders (regs->tpc = fault address)
7570 + *
7571 + * returns 1 when task should be killed
7572 + *         2 when patched PLT trampoline was detected
7573 + *         3 when unpatched PLT trampoline was detected
7574 + */
7575 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7576 +{
7577 +
7578 +#ifdef CONFIG_PAX_EMUPLT
7579 +       int err;
7580 +
7581 +       do { /* PaX: patched PLT emulation #1 */
7582 +               unsigned int sethi1, sethi2, jmpl;
7583 +
7584 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
7585 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
7586 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
7587 +
7588 +               if (err)
7589 +                       break;
7590 +
7591 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
7592 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
7593 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
7594 +               {
7595 +                       unsigned long addr;
7596 +
7597 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
7598 +                       addr = regs->u_regs[UREG_G1];
7599 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
7600 +                       regs->tpc = addr;
7601 +                       regs->tnpc = addr+4;
7602 +                       return 2;
7603 +               }
7604 +       } while (0);
7605 +
7606 +       { /* PaX: patched PLT emulation #2 */
7607 +               unsigned int ba;
7608 +
7609 +               err = get_user(ba, (unsigned int*)regs->tpc);
7610 +
7611 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
7612 +                       unsigned long addr;
7613 +
7614 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
7615 +                       regs->tpc = addr;
7616 +                       regs->tnpc = addr+4;
7617 +                       return 2;
7618 +               }
7619 +       }
7620 +
7621 +       do { /* PaX: patched PLT emulation #3 */
7622 +               unsigned int sethi, jmpl, nop;
7623 +
7624 +               err = get_user(sethi, (unsigned int*)regs->tpc);
7625 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
7626 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
7627 +
7628 +               if (err)
7629 +                       break;
7630 +
7631 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
7632 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
7633 +                   nop == 0x01000000U)
7634 +               {
7635 +                       unsigned long addr;
7636 +
7637 +                       addr = (sethi & 0x003FFFFFU) << 10;
7638 +                       regs->u_regs[UREG_G1] = addr;
7639 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
7640 +                       regs->tpc = addr;
7641 +                       regs->tnpc = addr+4;
7642 +                       return 2;
7643 +               }
7644 +       } while (0);
7645 +
7646 +       do { /* PaX: patched PLT emulation #4 */
7647 +               unsigned int mov1, call, mov2;
7648 +
7649 +               err = get_user(mov1, (unsigned int*)regs->tpc);
7650 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
7651 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
7652 +
7653 +               if (err)
7654 +                       break;
7655 +
7656 +               if (mov1 == 0x8210000FU &&
7657 +                   (call & 0xC0000000U) == 0x40000000U &&
7658 +                   mov2 == 0x9E100001U)
7659 +               {
7660 +                       unsigned long addr;
7661 +
7662 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
7663 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
7664 +                       regs->tpc = addr;
7665 +                       regs->tnpc = addr+4;
7666 +                       return 2;
7667 +               }
7668 +       } while (0);
7669 +
7670 +       do { /* PaX: patched PLT emulation #5 */
7671 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
7672 +
7673 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
7674 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
7675 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
7676 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
7677 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
7678 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
7679 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
7680 +
7681 +               if (err)
7682 +                       break;
7683 +
7684 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
7685 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
7686 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
7687 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
7688 +                   sllx == 0x83287020 &&
7689 +                   jmpl == 0x81C04005U &&
7690 +                   nop == 0x01000000U)
7691 +               {
7692 +                       unsigned long addr;
7693 +
7694 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
7695 +                       regs->u_regs[UREG_G1] <<= 32;
7696 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
7697 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
7698 +                       regs->tpc = addr;
7699 +                       regs->tnpc = addr+4;
7700 +                       return 2;
7701 +               }
7702 +       } while (0);
7703 +
7704 +       do { /* PaX: patched PLT emulation #6 */
7705 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
7706 +
7707 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
7708 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
7709 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
7710 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
7711 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
7712 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
7713 +
7714 +               if (err)
7715 +                       break;
7716 +
7717 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
7718 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
7719 +                   sllx == 0x83287020 &&
7720 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
7721 +                   jmpl == 0x81C04005U &&
7722 +                   nop == 0x01000000U)
7723 +               {
7724 +                       unsigned long addr;
7725 +
7726 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
7727 +                       regs->u_regs[UREG_G1] <<= 32;
7728 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
7729 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
7730 +                       regs->tpc = addr;
7731 +                       regs->tnpc = addr+4;
7732 +                       return 2;
7733 +               }
7734 +       } while (0);
7735 +
7736 +       do { /* PaX: patched PLT emulation #7 */
7737 +               unsigned int sethi, ba, nop;
7738 +
7739 +               err = get_user(sethi, (unsigned int*)regs->tpc);
7740 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
7741 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
7742 +
7743 +               if (err)
7744 +                       break;
7745 +
7746 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
7747 +                   (ba & 0xFFF00000U) == 0x30600000U &&
7748 +                   nop == 0x01000000U)
7749 +               {
7750 +                       unsigned long addr;
7751 +
7752 +                       addr = (sethi & 0x003FFFFFU) << 10;
7753 +                       regs->u_regs[UREG_G1] = addr;
7754 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
7755 +                       regs->tpc = addr;
7756 +                       regs->tnpc = addr+4;
7757 +                       return 2;
7758 +               }
7759 +       } while (0);
7760 +
7761 +       do { /* PaX: unpatched PLT emulation step 1 */
7762 +               unsigned int sethi, ba, nop;
7763 +
7764 +               err = get_user(sethi, (unsigned int*)regs->tpc);
7765 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
7766 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
7767 +
7768 +               if (err)
7769 +                       break;
7770 +
7771 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
7772 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
7773 +                   nop == 0x01000000U)
7774 +               {
7775 +                       unsigned long addr;
7776 +                       unsigned int save, call;
7777 +
7778 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
7779 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
7780 +                       else
7781 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
7782 +
7783 +                       err = get_user(save, (unsigned int*)addr);
7784 +                       err |= get_user(call, (unsigned int*)(addr+4));
7785 +                       err |= get_user(nop, (unsigned int*)(addr+8));
7786 +                       if (err)
7787 +                               break;
7788 +
7789 +                       if (save == 0x9DE3BFA8U &&
7790 +                           (call & 0xC0000000U) == 0x40000000U &&
7791 +                           nop == 0x01000000U)
7792 +                       {
7793 +                               struct vm_area_struct *vma;
7794 +                               unsigned long call_dl_resolve;
7795 +
7796 +                               down_read(&current->mm->mmap_sem);
7797 +                               call_dl_resolve = current->mm->call_dl_resolve;
7798 +                               up_read(&current->mm->mmap_sem);
7799 +                               if (likely(call_dl_resolve))
7800 +                                       goto emulate;
7801 +
7802 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7803 +
7804 +                               down_write(&current->mm->mmap_sem);
7805 +                               if (current->mm->call_dl_resolve) {
7806 +                                       call_dl_resolve = current->mm->call_dl_resolve;
7807 +                                       up_write(&current->mm->mmap_sem);
7808 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
7809 +                                       goto emulate;
7810 +                               }
7811 +
7812 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7813 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
7814 +                                       up_write(&current->mm->mmap_sem);
7815 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
7816 +                                       return 1;
7817 +                               }
7818 +
7819 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
7820 +                                       up_write(&current->mm->mmap_sem);
7821 +                                       kmem_cache_free(vm_area_cachep, vma);
7822 +                                       return 1;
7823 +                               }
7824 +
7825 +                               current->mm->call_dl_resolve = call_dl_resolve;
7826 +                               up_write(&current->mm->mmap_sem);
7827 +
7828 +emulate:
7829 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
7830 +                               regs->tpc = call_dl_resolve;
7831 +                               regs->tnpc = addr+4;
7832 +                               return 3;
7833 +                       }
7834 +               }
7835 +       } while (0);
7836 +
7837 +       do { /* PaX: unpatched PLT emulation step 2 */
7838 +               unsigned int save, call, nop;
7839 +
7840 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
7841 +               err |= get_user(call, (unsigned int*)regs->tpc);
7842 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
7843 +               if (err)
7844 +                       break;
7845 +
7846 +               if (save == 0x9DE3BFA8U &&
7847 +                   (call & 0xC0000000U) == 0x40000000U &&
7848 +                   nop == 0x01000000U)
7849 +               {
7850 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
7851 +
7852 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
7853 +                       regs->tpc = dl_resolve;
7854 +                       regs->tnpc = dl_resolve+4;
7855 +                       return 3;
7856 +               }
7857 +       } while (0);
7858 +#endif
7859 +
7860 +       return 1;
7861 +}
7862 +
7863 +void pax_report_insns(void *pc, void *sp)
7864 +{
7865 +       unsigned long i;
7866 +
7867 +       printk(KERN_ERR "PAX: bytes at PC: ");
7868 +       for (i = 0; i < 5; i++) {
7869 +               unsigned int c;
7870 +               if (get_user(c, (unsigned int*)pc+i))
7871 +                       printk("???????? ");
7872 +               else
7873 +                       printk("%08x ", c);
7874 +       }
7875 +       printk("\n");
7876 +}
7877 +#endif
7878 +
7879  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
7880  {
7881         struct mm_struct *mm = current->mm;
7882 @@ -332,8 +699,10 @@ asmlinkage void __kprobes do_sparc64_fau
7883                 goto intr_or_no_mm;
7884  
7885         if (test_thread_flag(TIF_32BIT)) {
7886 -               if (!(regs->tstate & TSTATE_PRIV))
7887 +               if (!(regs->tstate & TSTATE_PRIV)) {
7888                         regs->tpc &= 0xffffffff;
7889 +                       regs->tnpc &= 0xffffffff;
7890 +               }
7891                 address &= 0xffffffff;
7892         }
7893  
7894 @@ -350,6 +719,29 @@ asmlinkage void __kprobes do_sparc64_fau
7895         if (!vma)
7896                 goto bad_area;
7897  
7898 +#ifdef CONFIG_PAX_PAGEEXEC
7899 +       /* PaX: detect ITLB misses on non-exec pages */
7900 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
7901 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
7902 +       {
7903 +               if (address != regs->tpc)
7904 +                       goto good_area;
7905 +
7906 +               up_read(&mm->mmap_sem);
7907 +               switch (pax_handle_fetch_fault(regs)) {
7908 +
7909 +#ifdef CONFIG_PAX_EMUPLT
7910 +               case 2:
7911 +               case 3:
7912 +                       return;
7913 +#endif
7914 +
7915 +               }
7916 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
7917 +               do_exit(SIGKILL);
7918 +       }
7919 +#endif
7920 +
7921         /* Pure DTLB misses do not tell us whether the fault causing
7922          * load/store/atomic was a write or not, it only says that there
7923          * was no match.  So in such a case we (carefully) read the
7924 diff -urNp linux-2.6.18/arch/v850/kernel/module.c linux-2.6.18/arch/v850/kernel/module.c
7925 --- linux-2.6.18/arch/v850/kernel/module.c      2006-09-19 23:42:06.000000000 -0400
7926 +++ linux-2.6.18/arch/v850/kernel/module.c      2006-09-22 20:45:03.000000000 -0400
7927 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
7928         tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
7929  
7930         /* Init, or core PLT? */
7931 -       if (location >= mod->module_core
7932 -           && location < mod->module_core + mod->core_size)
7933 +       if (location >= mod->module_core_rx
7934 +           && location < mod->module_core_rx + mod->core_size_rx)
7935                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
7936         else
7937                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
7938 diff -urNp linux-2.6.18/arch/x86_64/boot/compressed/head.S linux-2.6.18/arch/x86_64/boot/compressed/head.S
7939 --- linux-2.6.18/arch/x86_64/boot/compressed/head.S     2006-09-19 23:42:06.000000000 -0400
7940 +++ linux-2.6.18/arch/x86_64/boot/compressed/head.S     2006-09-22 20:45:04.000000000 -0400
7941 @@ -41,11 +41,13 @@ startup_32:
7942         movl %eax,%gs
7943  
7944         lss stack_start,%esp
7945 +       movl 0x000000,%ecx
7946         xorl %eax,%eax
7947  1:     incl %eax               # check that A20 really IS enabled
7948         movl %eax,0x000000      # loop forever if it isn't
7949         cmpl %eax,0x100000
7950         je 1b
7951 +       movl %ecx,0x000000
7952  
7953  /*
7954   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
7955 diff -urNp linux-2.6.18/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.18/arch/x86_64/ia32/ia32_binfmt.c
7956 --- linux-2.6.18/arch/x86_64/ia32/ia32_binfmt.c 2006-09-19 23:42:06.000000000 -0400
7957 +++ linux-2.6.18/arch/x86_64/ia32/ia32_binfmt.c 2006-09-22 20:45:04.000000000 -0400
7958 @@ -191,6 +191,17 @@ struct elf_prpsinfo
7959  //#include <asm/ia32.h>
7960  #include <linux/elf.h>
7961  
7962 +#ifdef CONFIG_PAX_ASLR
7963 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
7964 +
7965 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
7966 +#define PAX_DELTA_MMAP_LEN(tsk)                16
7967 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
7968 +#define PAX_DELTA_EXEC_LEN(tsk)                16
7969 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
7970 +#define PAX_DELTA_STACK_LEN(tsk)       16
7971 +#endif
7972 +
7973  typedef struct user_i387_ia32_struct elf_fpregset_t;
7974  typedef struct user32_fxsr_struct elf_fpxregset_t;
7975  
7976 diff -urNp linux-2.6.18/arch/x86_64/ia32/mmap32.c linux-2.6.18/arch/x86_64/ia32/mmap32.c
7977 --- linux-2.6.18/arch/x86_64/ia32/mmap32.c      2006-09-19 23:42:06.000000000 -0400
7978 +++ linux-2.6.18/arch/x86_64/ia32/mmap32.c      2006-09-22 20:45:04.000000000 -0400
7979 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
7980                         (current->personality & ADDR_COMPAT_LAYOUT) ||
7981                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
7982                 mm->mmap_base = TASK_UNMAPPED_BASE;
7983 +
7984 +#ifdef CONFIG_PAX_RANDMMAP
7985 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7986 +                       mm->mmap_base += mm->delta_mmap;
7987 +#endif
7988 +
7989                 mm->get_unmapped_area = arch_get_unmapped_area;
7990                 mm->unmap_area = arch_unmap_area;
7991         } else {
7992                 mm->mmap_base = mmap_base(mm);
7993 +
7994 +#ifdef CONFIG_PAX_RANDMMAP
7995 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7996 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7997 +#endif
7998 +
7999                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8000                 mm->unmap_area = arch_unmap_area_topdown;
8001         }
8002 diff -urNp linux-2.6.18/arch/x86_64/ia32/syscall32.c linux-2.6.18/arch/x86_64/ia32/syscall32.c
8003 --- linux-2.6.18/arch/x86_64/ia32/syscall32.c   2006-09-19 23:42:06.000000000 -0400
8004 +++ linux-2.6.18/arch/x86_64/ia32/syscall32.c   2006-09-22 20:45:04.000000000 -0400
8005 @@ -49,11 +49,10 @@ int syscall32_setup_pages(struct linux_b
8006         struct mm_struct *mm = current->mm;
8007         int ret;
8008  
8009 -       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8010 +       vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
8011         if (!vma)
8012                 return -ENOMEM;
8013  
8014 -       memset(vma, 0, sizeof(struct vm_area_struct));
8015         /* Could randomize here */
8016         vma->vm_start = VSYSCALL32_BASE;
8017         vma->vm_end = VSYSCALL32_END;
8018 diff -urNp linux-2.6.18/arch/x86_64/kernel/process.c linux-2.6.18/arch/x86_64/kernel/process.c
8019 --- linux-2.6.18/arch/x86_64/kernel/process.c   2006-09-19 23:42:06.000000000 -0400
8020 +++ linux-2.6.18/arch/x86_64/kernel/process.c   2006-09-22 20:45:04.000000000 -0400
8021 @@ -832,9 +832,3 @@ int dump_task_regs(struct task_struct *t
8022         return 1;
8023  }
8024  
8025 -unsigned long arch_align_stack(unsigned long sp)
8026 -{
8027 -       if (randomize_va_space)
8028 -               sp -= get_random_int() % 8192;
8029 -       return sp & ~0xf;
8030 -}
8031 diff -urNp linux-2.6.18/arch/x86_64/kernel/ptrace.c linux-2.6.18/arch/x86_64/kernel/ptrace.c
8032 --- linux-2.6.18/arch/x86_64/kernel/ptrace.c    2006-09-19 23:42:06.000000000 -0400
8033 +++ linux-2.6.18/arch/x86_64/kernel/ptrace.c    2006-09-22 20:04:35.000000000 -0400
8034 @@ -19,6 +19,7 @@
8035  #include <linux/audit.h>
8036  #include <linux/seccomp.h>
8037  #include <linux/signal.h>
8038 +#include <linux/grsecurity.h>
8039  
8040  #include <asm/uaccess.h>
8041  #include <asm/pgtable.h>
8042 diff -urNp linux-2.6.18/arch/x86_64/kernel/setup64.c linux-2.6.18/arch/x86_64/kernel/setup64.c
8043 --- linux-2.6.18/arch/x86_64/kernel/setup64.c   2006-09-19 23:42:06.000000000 -0400
8044 +++ linux-2.6.18/arch/x86_64/kernel/setup64.c   2006-09-22 20:45:04.000000000 -0400
8045 @@ -38,7 +38,6 @@ char boot_cpu_stack[IRQSTACKSIZE] __attr
8046  
8047  unsigned long __supported_pte_mask __read_mostly = ~0UL;
8048  EXPORT_SYMBOL(__supported_pte_mask);
8049 -static int do_not_nx __cpuinitdata = 0;
8050  
8051  /* noexec=on|off
8052  Control non executable mappings for 64bit processes.
8053 @@ -50,16 +49,14 @@ int __init nonx_setup(char *str)
8054  {
8055         if (!strncmp(str, "on", 2)) {
8056                  __supported_pte_mask |= _PAGE_NX; 
8057 -               do_not_nx = 0; 
8058         } else if (!strncmp(str, "off", 3)) {
8059 -               do_not_nx = 1;
8060                 __supported_pte_mask &= ~_PAGE_NX;
8061          }
8062         return 1;
8063  } 
8064  __setup("noexec=", nonx_setup);        /* parsed early actually */
8065  
8066 -int force_personality32 = 0; 
8067 +int force_personality32;
8068  
8069  /* noexec32=on|off
8070  Control non executable heap for 32bit processes.
8071 @@ -173,7 +170,7 @@ void __cpuinit check_efer(void)
8072         unsigned long efer;
8073  
8074         rdmsrl(MSR_EFER, efer); 
8075 -        if (!(efer & EFER_NX) || do_not_nx) { 
8076 +        if (!(efer & EFER_NX)) { 
8077                  __supported_pte_mask &= ~_PAGE_NX; 
8078          }       
8079  }
8080 diff -urNp linux-2.6.18/arch/x86_64/kernel/sys_x86_64.c linux-2.6.18/arch/x86_64/kernel/sys_x86_64.c
8081 --- linux-2.6.18/arch/x86_64/kernel/sys_x86_64.c        2006-09-19 23:42:06.000000000 -0400
8082 +++ linux-2.6.18/arch/x86_64/kernel/sys_x86_64.c        2006-09-22 20:45:04.000000000 -0400
8083 @@ -65,8 +65,8 @@ out:
8084         return error;
8085  }
8086  
8087 -static void find_start_end(unsigned long flags, unsigned long *begin,
8088 -                          unsigned long *end)
8089 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
8090 +                          unsigned long *begin, unsigned long *end)
8091  {
8092         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
8093                 /* This is usually used needed to map code in small
8094 @@ -79,7 +79,7 @@ static void find_start_end(unsigned long
8095                 *begin = 0x40000000; 
8096                 *end = 0x80000000;              
8097         } else {
8098 -               *begin = TASK_UNMAPPED_BASE;
8099 +               *begin = mm->mmap_base;
8100                 *end = TASK_SIZE; 
8101         }
8102  } 
8103 @@ -93,11 +93,15 @@ arch_get_unmapped_area(struct file *filp
8104         unsigned long start_addr;
8105         unsigned long begin, end;
8106         
8107 -       find_start_end(flags, &begin, &end); 
8108 +       find_start_end(mm, flags, &begin, &end); 
8109  
8110         if (len > end)
8111                 return -ENOMEM;
8112  
8113 +#ifdef CONFIG_PAX_RANDMMAP
8114 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8115 +#endif
8116 +
8117         if (addr) {
8118                 addr = PAGE_ALIGN(addr);
8119                 vma = find_vma(mm, addr);
8120 diff -urNp linux-2.6.18/arch/x86_64/mm/fault.c linux-2.6.18/arch/x86_64/mm/fault.c
8121 --- linux-2.6.18/arch/x86_64/mm/fault.c 2006-09-19 23:42:06.000000000 -0400
8122 +++ linux-2.6.18/arch/x86_64/mm/fault.c 2006-09-22 20:45:04.000000000 -0400
8123 @@ -23,6 +23,7 @@
8124  #include <linux/compiler.h>
8125  #include <linux/module.h>
8126  #include <linux/kprobes.h>
8127 +#include <linux/binfmts.h>
8128  
8129  #include <asm/system.h>
8130  #include <asm/uaccess.h>
8131 @@ -328,6 +329,33 @@ static int vmalloc_fault(unsigned long a
8132         return 0;
8133  }
8134  
8135 +#ifdef CONFIG_PAX_PAGEEXEC
8136 +void pax_report_insns(void *pc, void *sp)
8137 +{
8138 +       long i;
8139 +
8140 +       printk(KERN_ERR "PAX: bytes at PC: ");
8141 +       for (i = 0; i < 20; i++) {
8142 +               unsigned char c;
8143 +               if (get_user(c, (unsigned char __user *)pc+i))
8144 +                       printk("?? ");
8145 +               else
8146 +                       printk("%02x ", c);
8147 +       }
8148 +       printk("\n");
8149 +
8150 +       printk(KERN_ERR "PAX: bytes at SP-8: ");
8151 +       for (i = -1; i < 10; i++) {
8152 +               unsigned long c;
8153 +               if (get_user(c, (unsigned long __user *)sp+i))
8154 +                       printk("???????????????? ");
8155 +               else
8156 +                       printk("%016lx ", c);
8157 +       }
8158 +       printk("\n");
8159 +}
8160 +#endif
8161 +
8162  int page_fault_trace = 0;
8163  int exception_trace = 1;
8164  
8165 @@ -459,6 +487,8 @@ asmlinkage void __kprobes do_page_fault(
8166  good_area:
8167         info.si_code = SEGV_ACCERR;
8168         write = 0;
8169 +       if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
8170 +               goto bad_area;
8171         switch (error_code & (PF_PROT|PF_WRITE)) {
8172                 default:        /* 3: write, present */
8173                         /* fall through */
8174 @@ -525,7 +555,14 @@ bad_area_nosemaphore:
8175                                         tsk->comm, tsk->pid, address, regs->rip,
8176                                         regs->rsp, error_code);
8177                 }
8178 -       
8179 +
8180 +#ifdef CONFIG_PAX_PAGEEXEC
8181 +               if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
8182 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
8183 +                       do_exit(SIGKILL);
8184 +               }
8185 +#endif
8186 +
8187                 tsk->thread.cr2 = address;
8188                 /* Kernel addresses are always protection faults */
8189                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
8190 diff -urNp linux-2.6.18/arch/x86_64/mm/mmap.c linux-2.6.18/arch/x86_64/mm/mmap.c
8191 --- linux-2.6.18/arch/x86_64/mm/mmap.c  2006-09-19 23:42:06.000000000 -0400
8192 +++ linux-2.6.18/arch/x86_64/mm/mmap.c  2006-09-22 20:45:04.000000000 -0400
8193 @@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
8194                 unsigned rnd = get_random_int() & 0xfffffff;
8195                 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
8196         }
8197 +
8198 +#ifdef CONFIG_PAX_RANDMMAP
8199 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
8200 +               mm->mmap_base += mm->delta_mmap;
8201 +#endif
8202 +
8203         mm->get_unmapped_area = arch_get_unmapped_area;
8204         mm->unmap_area = arch_unmap_area;
8205  }
8206 diff -urNp linux-2.6.18/Documentation/dontdiff linux-2.6.18/Documentation/dontdiff
8207 --- linux-2.6.18/Documentation/dontdiff 2006-09-19 23:42:06.000000000 -0400
8208 +++ linux-2.6.18/Documentation/dontdiff 2006-09-22 20:45:03.000000000 -0400
8209 @@ -55,7 +55,7 @@ aic7*seq.h*
8210  aicasm
8211  aicdb.h*
8212  asm
8213 -asm-offsets.*
8214 +asm-offsets.h
8215  asm_offsets.*
8216  autoconf.h*
8217  bbootsect
8218 @@ -115,6 +115,7 @@ mkdep
8219  mktables
8220  modpost
8221  modversions.h*
8222 +netfilter*
8223  offset.h
8224  offsets.h
8225  oui.c*
8226 @@ -142,4 +143,5 @@ vmlinux.lds
8227  vsyscall.lds
8228  wanxlfw.inc
8229  uImage
8230 +utsrelease.h
8231  zImage
8232 diff -urNp linux-2.6.18/drivers/acpi/glue.c linux-2.6.18/drivers/acpi/glue.c
8233 --- linux-2.6.18/drivers/acpi/glue.c    2006-09-19 23:42:06.000000000 -0400
8234 +++ linux-2.6.18/drivers/acpi/glue.c    2006-09-22 20:45:04.000000000 -0400
8235 @@ -16,7 +16,7 @@
8236  #if ACPI_GLUE_DEBUG
8237  #define DBG(x...) printk(PREFIX x)
8238  #else
8239 -#define DBG(x...)
8240 +#define DBG(x...) do {} while (0)
8241  #endif
8242  static LIST_HEAD(bus_type_list);
8243  static DECLARE_RWSEM(bus_type_sem);
8244 diff -urNp linux-2.6.18/drivers/acpi/processor_core.c linux-2.6.18/drivers/acpi/processor_core.c
8245 --- linux-2.6.18/drivers/acpi/processor_core.c  2006-09-19 23:42:06.000000000 -0400
8246 +++ linux-2.6.18/drivers/acpi/processor_core.c  2006-09-22 20:45:04.000000000 -0400
8247 @@ -534,7 +534,7 @@ static int acpi_processor_start(struct a
8248                 return 0;
8249         }
8250  
8251 -       BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
8252 +       BUG_ON(pr->id >= NR_CPUS);
8253  
8254         /*
8255          * Buggy BIOS check
8256 diff -urNp linux-2.6.18/drivers/char/agp/frontend.c linux-2.6.18/drivers/char/agp/frontend.c
8257 --- linux-2.6.18/drivers/char/agp/frontend.c    2006-09-19 23:42:06.000000000 -0400
8258 +++ linux-2.6.18/drivers/char/agp/frontend.c    2006-09-22 20:45:04.000000000 -0400
8259 @@ -841,7 +841,7 @@ static int agpioc_reserve_wrap(struct ag
8260         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
8261                 return -EFAULT;
8262  
8263 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
8264 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
8265                 return -EFAULT;
8266  
8267         client = agp_find_client_by_pid(reserve.pid);
8268 diff -urNp linux-2.6.18/drivers/char/keyboard.c linux-2.6.18/drivers/char/keyboard.c
8269 --- linux-2.6.18/drivers/char/keyboard.c        2006-09-19 23:42:06.000000000 -0400
8270 +++ linux-2.6.18/drivers/char/keyboard.c        2006-09-22 20:45:04.000000000 -0400
8271 @@ -198,7 +198,7 @@ int setkeycode(unsigned int scancode, un
8272  
8273         if (scancode >= dev->keycodemax)
8274                 return -EINVAL;
8275 -       if (keycode < 0 || keycode > KEY_MAX)
8276 +       if (keycode > KEY_MAX)
8277                 return -EINVAL;
8278         if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
8279                 return -EINVAL;
8280 @@ -618,6 +618,16 @@ static void k_spec(struct vc_data *vc, u
8281              kbd->kbdmode == VC_MEDIUMRAW) &&
8282              value != KVAL(K_SAK))
8283                 return;         /* SAK is allowed even in raw mode */
8284 +
8285 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
8286 +       {
8287 +               void *func = fn_handler[value];
8288 +               if (func == fn_show_state || func == fn_show_ptregs ||
8289 +                   func == fn_show_mem)
8290 +                       return;
8291 +       }
8292 +#endif
8293 +
8294         fn_handler[value](vc, regs);
8295  }
8296  
8297 diff -urNp linux-2.6.18/drivers/char/mem.c linux-2.6.18/drivers/char/mem.c
8298 --- linux-2.6.18/drivers/char/mem.c     2006-09-19 23:42:06.000000000 -0400
8299 +++ linux-2.6.18/drivers/char/mem.c     2006-09-22 20:45:04.000000000 -0400
8300 @@ -26,6 +26,7 @@
8301  #include <linux/backing-dev.h>
8302  #include <linux/bootmem.h>
8303  #include <linux/pipe_fs_i.h>
8304 +#include <linux/grsecurity.h>
8305  
8306  #include <asm/uaccess.h>
8307  #include <asm/io.h>
8308 @@ -34,6 +35,10 @@
8309  # include <linux/efi.h>
8310  #endif
8311  
8312 +#ifdef CONFIG_GRKERNSEC
8313 +extern struct file_operations grsec_fops;
8314 +#endif
8315 +
8316  /*
8317   * Architectures vary in how they handle caching for addresses
8318   * outside of main memory.
8319 @@ -173,6 +178,11 @@ static ssize_t write_mem(struct file * f
8320         if (!valid_phys_addr_range(p, count))
8321                 return -EFAULT;
8322  
8323 +#ifdef CONFIG_GRKERNSEC_KMEM
8324 +       gr_handle_mem_write();
8325 +       return -EPERM;
8326 +#endif
8327 +
8328         written = 0;
8329  
8330  #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
8331 @@ -249,6 +259,11 @@ static int mmap_mem(struct file * file, 
8332                                                  size,
8333                                                  vma->vm_page_prot);
8334  
8335 +#ifdef CONFIG_GRKERNSEC_KMEM
8336 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
8337 +               return -EPERM;
8338 +#endif
8339 +
8340         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
8341         if (remap_pfn_range(vma,
8342                             vma->vm_start,
8343 @@ -476,6 +491,11 @@ static ssize_t write_kmem(struct file * 
8344         ssize_t written;
8345         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
8346  
8347 +#ifdef CONFIG_GRKERNSEC_KMEM
8348 +       gr_handle_kmem_write();
8349 +       return -EPERM;
8350 +#endif
8351 +
8352         if (p < (unsigned long) high_memory) {
8353  
8354                 wrote = count;
8355 @@ -616,7 +636,23 @@ static inline size_t read_zero_pagealign
8356                         count = size;
8357  
8358                 zap_page_range(vma, addr, count, NULL);
8359 -               zeromap_page_range(vma, addr, count, PAGE_COPY);
8360 +               zeromap_page_range(vma, addr, count, vma->vm_page_prot);
8361 +
8362 +#ifdef CONFIG_PAX_SEGMEXEC
8363 +               if (vma->vm_flags & VM_MIRROR) {
8364 +                       unsigned long addr_m;
8365 +                       struct vm_area_struct * vma_m;
8366 +
8367 +                       addr_m = vma->vm_start + vma->vm_mirror;
8368 +                       vma_m = find_vma(mm, addr_m);
8369 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
8370 +                               addr_m = addr + vma->vm_mirror;
8371 +                               zap_page_range(vma_m, addr_m, count, NULL);
8372 +                       } else
8373 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
8374 +                                      addr, vma->vm_start);
8375 +               }
8376 +#endif
8377  
8378                 size -= count;
8379                 buf += count;
8380 @@ -765,6 +801,16 @@ static loff_t memory_lseek(struct file *
8381  
8382  static int open_port(struct inode * inode, struct file * filp)
8383  {
8384 +#ifdef CONFIG_GRKERNSEC_KMEM
8385 +       gr_handle_open_port();
8386 +       return -EPERM;
8387 +#endif
8388 +
8389 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
8390 +}
8391 +
8392 +static int open_mem(struct inode * inode, struct file * filp)
8393 +{
8394         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
8395  }
8396  
8397 @@ -772,7 +818,6 @@ static int open_port(struct inode * inod
8398  #define full_lseek      null_lseek
8399  #define write_zero     write_null
8400  #define read_full       read_zero
8401 -#define open_mem       open_port
8402  #define open_kmem      open_mem
8403  #define open_oldmem    open_mem
8404  
8405 @@ -895,6 +940,11 @@ static int memory_open(struct inode * in
8406                         filp->f_op = &oldmem_fops;
8407                         break;
8408  #endif
8409 +#ifdef CONFIG_GRKERNSEC
8410 +               case 13:
8411 +                       filp->f_op = &grsec_fops;
8412 +                       break;
8413 +#endif
8414                 default:
8415                         return -ENXIO;
8416         }
8417 @@ -927,6 +977,9 @@ static const struct {
8418  #ifdef CONFIG_CRASH_DUMP
8419         {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
8420  #endif
8421 +#ifdef CONFIG_GRKERNSEC
8422 +       {13,"grsec",    S_IRUSR | S_IWUGO,          &grsec_fops},
8423 +#endif
8424  };
8425  
8426  static struct class *mem_class;
8427 diff -urNp linux-2.6.18/drivers/char/random.c linux-2.6.18/drivers/char/random.c
8428 --- linux-2.6.18/drivers/char/random.c  2006-09-19 23:42:06.000000000 -0400
8429 +++ linux-2.6.18/drivers/char/random.c  2006-09-22 20:45:04.000000000 -0400
8430 @@ -248,8 +248,13 @@
8431  /*
8432   * Configuration information
8433   */
8434 +#ifdef CONFIG_GRKERNSEC_RANDNET
8435 +#define INPUT_POOL_WORDS 512
8436 +#define OUTPUT_POOL_WORDS 128
8437 +#else
8438  #define INPUT_POOL_WORDS 128
8439  #define OUTPUT_POOL_WORDS 32
8440 +#endif
8441  #define SEC_XFER_SIZE 512
8442  
8443  /*
8444 @@ -286,10 +291,17 @@ static struct poolinfo {
8445         int poolwords;
8446         int tap1, tap2, tap3, tap4, tap5;
8447  } poolinfo_table[] = {
8448 +#ifdef CONFIG_GRKERNSEC_RANDNET
8449 +       /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
8450 +       { 512,  411,    308,    208,    104,    1 },
8451 +       /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
8452 +       { 128,  103,    76,     51,     25,     1 },
8453 +#else
8454         /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
8455         { 128,  103,    76,     51,     25,     1 },
8456         /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
8457         { 32,   26,     20,     14,     7,      1 },
8458 +#endif
8459  #if 0
8460         /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
8461         { 2048, 1638,   1231,   819,    411,    1 },
8462 @@ -1657,3 +1669,25 @@ randomize_range(unsigned long start, uns
8463                 return 0;
8464         return PAGE_ALIGN(get_random_int() % range + start);
8465  }
8466 +
8467 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
8468 +unsigned long pax_get_random_long(void)
8469 +{
8470 +       static time_t   rekey_time;
8471 +       static __u32    secret[12];
8472 +       time_t          t;
8473 +
8474 +       /*
8475 +        * Pick a random secret every REKEY_INTERVAL seconds.
8476 +        */
8477 +       t = get_seconds();
8478 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
8479 +               rekey_time = t;
8480 +               get_random_bytes(secret, sizeof(secret));
8481 +       }
8482 +
8483 +       secret[1] = half_md4_transform(secret+8, secret);
8484 +       secret[0] = half_md4_transform(secret+8, secret);
8485 +       return *(unsigned long *)secret;
8486 +}
8487 +#endif
8488 diff -urNp linux-2.6.18/drivers/char/vt_ioctl.c linux-2.6.18/drivers/char/vt_ioctl.c
8489 --- linux-2.6.18/drivers/char/vt_ioctl.c        2006-09-19 23:42:06.000000000 -0400
8490 +++ linux-2.6.18/drivers/char/vt_ioctl.c        2006-09-22 20:04:35.000000000 -0400
8491 @@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
8492         case KDSKBENT:
8493                 if (!perm)
8494                         return -EPERM;
8495 +
8496 +#ifdef CONFIG_GRKERNSEC
8497 +               if (!capable(CAP_SYS_TTY_CONFIG))
8498 +                       return -EPERM;
8499 +#endif
8500 +
8501                 if (!i && v == K_NOSUCHMAP) {
8502                         /* disallocate map */
8503                         key_map = key_maps[s];
8504 @@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
8505                         goto reterr;
8506                 }
8507  
8508 +#ifdef CONFIG_GRKERNSEC
8509 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
8510 +                       ret = -EPERM;
8511 +                       goto reterr;
8512 +               }
8513 +#endif
8514 +
8515                 q = func_table[i];
8516                 first_free = funcbufptr + (funcbufsize - funcbufleft);
8517                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
8518 diff -urNp linux-2.6.18/drivers/edac/edac_mc.h linux-2.6.18/drivers/edac/edac_mc.h
8519 --- linux-2.6.18/drivers/edac/edac_mc.h 2006-09-19 23:42:06.000000000 -0400
8520 +++ linux-2.6.18/drivers/edac/edac_mc.h 2006-09-22 20:45:04.000000000 -0400
8521 @@ -71,11 +71,11 @@ extern int edac_debug_level;
8522  
8523  #else  /* !CONFIG_EDAC_DEBUG */
8524  
8525 -#define debugf0( ... )
8526 -#define debugf1( ... )
8527 -#define debugf2( ... )
8528 -#define debugf3( ... )
8529 -#define debugf4( ... )
8530 +#define debugf0( ... ) do {} while (0)
8531 +#define debugf1( ... ) do {} while (0)
8532 +#define debugf2( ... ) do {} while (0)
8533 +#define debugf3( ... ) do {} while (0)
8534 +#define debugf4( ... ) do {} while (0)
8535  
8536  #endif  /* !CONFIG_EDAC_DEBUG */
8537  
8538 diff -urNp linux-2.6.18/drivers/hwmon/fscpos.c linux-2.6.18/drivers/hwmon/fscpos.c
8539 --- linux-2.6.18/drivers/hwmon/fscpos.c 2006-09-19 23:42:06.000000000 -0400
8540 +++ linux-2.6.18/drivers/hwmon/fscpos.c 2006-09-22 20:45:04.000000000 -0400
8541 @@ -230,7 +230,6 @@ static ssize_t set_pwm(struct i2c_client
8542         unsigned long v = simple_strtoul(buf, NULL, 10);
8543  
8544         /* Range: 0..255 */
8545 -       if (v < 0) v = 0;
8546         if (v > 255) v = 255;
8547  
8548         mutex_lock(&data->update_lock);
8549 diff -urNp linux-2.6.18/drivers/hwmon/w83791d.c linux-2.6.18/drivers/hwmon/w83791d.c
8550 --- linux-2.6.18/drivers/hwmon/w83791d.c        2006-09-19 23:42:06.000000000 -0400
8551 +++ linux-2.6.18/drivers/hwmon/w83791d.c        2006-09-22 20:45:04.000000000 -0400
8552 @@ -290,8 +290,8 @@ static int w83791d_attach_adapter(struct
8553  static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
8554  static int w83791d_detach_client(struct i2c_client *client);
8555  
8556 -static int w83791d_read(struct i2c_client *client, u8 register);
8557 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
8558 +static int w83791d_read(struct i2c_client *client, u8 reg);
8559 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
8560  static struct w83791d_data *w83791d_update_device(struct device *dev);
8561  
8562  #ifdef DEBUG
8563 diff -urNp linux-2.6.18/drivers/ide/ide-cd.c linux-2.6.18/drivers/ide/ide-cd.c
8564 --- linux-2.6.18/drivers/ide/ide-cd.c   2006-09-19 23:42:06.000000000 -0400
8565 +++ linux-2.6.18/drivers/ide/ide-cd.c   2006-09-22 20:45:04.000000000 -0400
8566 @@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
8567                         sector &= ~(bio_sectors -1);
8568                         valid = (sector - failed_command->sector) << 9;
8569  
8570 -                       if (valid < 0)
8571 -                               valid = 0;
8572                         if (sector < get_capacity(info->disk) &&
8573                                 drive->probed_capacity - sector < 4 * 75) {
8574                                 set_capacity(info->disk, sector);
8575 diff -urNp linux-2.6.18/drivers/ieee1394/dv1394.c linux-2.6.18/drivers/ieee1394/dv1394.c
8576 --- linux-2.6.18/drivers/ieee1394/dv1394.c      2006-09-19 23:42:06.000000000 -0400
8577 +++ linux-2.6.18/drivers/ieee1394/dv1394.c      2006-09-22 20:45:04.000000000 -0400
8578 @@ -142,7 +142,7 @@
8579  #if DV1394_DEBUG_LEVEL >= 1
8580  #define debug_printk( args... ) printk( args)
8581  #else
8582 -#define debug_printk( args... )
8583 +#define debug_printk( args... ) do {} while (0)
8584  #endif
8585  
8586  /* issue a dummy PCI read to force the preceding write
8587 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
8588         based upon DIF section and sequence
8589  */
8590  
8591 -static void inline
8592 +static inline void
8593  frame_put_packet (struct frame *f, struct packet *p)
8594  {
8595         int section_type = p->data[0] >> 5;           /* section type is in bits 5 - 7 */
8596 @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
8597                 /* default SYT offset is 3 cycles */
8598                 init->syt_offset = 3;
8599  
8600 -       if ( (init->channel > 63) || (init->channel < 0) )
8601 +       if (init->channel > 63)
8602                 init->channel = 63;
8603  
8604         chan_mask = (u64)1 << init->channel;
8605 diff -urNp linux-2.6.18/drivers/ieee1394/hosts.c linux-2.6.18/drivers/ieee1394/hosts.c
8606 --- linux-2.6.18/drivers/ieee1394/hosts.c       2006-09-19 23:42:06.000000000 -0400
8607 +++ linux-2.6.18/drivers/ieee1394/hosts.c       2006-09-22 20:45:04.000000000 -0400
8608 @@ -75,6 +75,7 @@ static int dummy_isoctl(struct hpsb_iso 
8609  }
8610  
8611  static struct hpsb_host_driver dummy_driver = {
8612 +       .name =            "dummy",
8613         .transmit_packet = dummy_transmit_packet,
8614         .devctl =          dummy_devctl,
8615         .isoctl =          dummy_isoctl
8616 diff -urNp linux-2.6.18/drivers/ieee1394/ohci1394.c linux-2.6.18/drivers/ieee1394/ohci1394.c
8617 --- linux-2.6.18/drivers/ieee1394/ohci1394.c    2006-09-19 23:42:06.000000000 -0400
8618 +++ linux-2.6.18/drivers/ieee1394/ohci1394.c    2006-09-22 20:45:04.000000000 -0400
8619 @@ -136,7 +136,7 @@
8620  #define DBGMSG(fmt, args...) \
8621  printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
8622  #else
8623 -#define DBGMSG(fmt, args...)
8624 +#define DBGMSG(fmt, args...) do {} while (0)
8625  #endif
8626  
8627  #ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
8628 @@ -161,9 +161,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
8629  printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
8630  
8631  /* Module Parameters */
8632 -static int phys_dma = 1;
8633 +static int phys_dma = 0;
8634  module_param(phys_dma, int, 0444);
8635 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
8636 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
8637  
8638  static void dma_trm_tasklet(unsigned long data);
8639  static void dma_trm_reset(struct dma_trm_ctx *d);
8640 diff -urNp linux-2.6.18/drivers/ieee1394/video1394.c linux-2.6.18/drivers/ieee1394/video1394.c
8641 --- linux-2.6.18/drivers/ieee1394/video1394.c   2006-09-19 23:42:06.000000000 -0400
8642 +++ linux-2.6.18/drivers/ieee1394/video1394.c   2006-09-22 20:45:04.000000000 -0400
8643 @@ -890,7 +890,7 @@ static int __video1394_ioctl(struct file
8644                 d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
8645                 if (d == NULL) return -EFAULT;
8646  
8647 -               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
8648 +               if (v.buffer>=d->num_desc - 1) {
8649                         PRINT(KERN_ERR, ohci->host->id,
8650                               "Buffer %d out of range",v.buffer);
8651                         return -EINVAL;
8652 @@ -955,7 +955,7 @@ static int __video1394_ioctl(struct file
8653                 d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
8654                 if (d == NULL) return -EFAULT;
8655  
8656 -               if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) {
8657 +               if (v.buffer>d->num_desc - 1) {
8658                         PRINT(KERN_ERR, ohci->host->id,
8659                               "Buffer %d out of range",v.buffer);
8660                         return -EINVAL;
8661 @@ -1026,7 +1026,7 @@ static int __video1394_ioctl(struct file
8662                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
8663                 if (d == NULL) return -EFAULT;
8664  
8665 -               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
8666 +               if (v.buffer>=d->num_desc - 1) {
8667                         PRINT(KERN_ERR, ohci->host->id,
8668                               "Buffer %d out of range",v.buffer);
8669                         return -EINVAL;
8670 @@ -1128,7 +1128,7 @@ static int __video1394_ioctl(struct file
8671                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
8672                 if (d == NULL) return -EFAULT;
8673  
8674 -               if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
8675 +               if (v.buffer>=d->num_desc-1) {
8676                         PRINT(KERN_ERR, ohci->host->id,
8677                               "Buffer %d out of range",v.buffer);
8678                         return -EINVAL;
8679 diff -urNp linux-2.6.18/drivers/md/bitmap.c linux-2.6.18/drivers/md/bitmap.c
8680 --- linux-2.6.18/drivers/md/bitmap.c    2006-09-19 23:42:06.000000000 -0400
8681 +++ linux-2.6.18/drivers/md/bitmap.c    2006-09-22 20:45:04.000000000 -0400
8682 @@ -57,7 +57,7 @@
8683  #  if DEBUG > 0
8684  #    define PRINTK(x...) printk(KERN_DEBUG x)
8685  #  else
8686 -#    define PRINTK(x...)
8687 +#    define PRINTK(x...) do {} while (0)
8688  #  endif
8689  #endif
8690  
8691 diff -urNp linux-2.6.18/drivers/mtd/devices/doc2001.c linux-2.6.18/drivers/mtd/devices/doc2001.c
8692 --- linux-2.6.18/drivers/mtd/devices/doc2001.c  2006-09-19 23:42:06.000000000 -0400
8693 +++ linux-2.6.18/drivers/mtd/devices/doc2001.c  2006-09-22 20:04:35.000000000 -0400
8694 @@ -401,6 +401,8 @@ static int doc_read (struct mtd_info *mt
8695         /* Don't allow read past end of device */
8696         if (from >= this->totlen)
8697                 return -EINVAL;
8698 +       if (!len)
8699 +               return -EINVAL;
8700  
8701         /* Don't allow a single read to cross a 512-byte block boundary */
8702         if (from + len > ((from | 0x1ff) + 1))
8703 diff -urNp linux-2.6.18/drivers/net/eepro100.c linux-2.6.18/drivers/net/eepro100.c
8704 --- linux-2.6.18/drivers/net/eepro100.c 2006-09-19 23:42:06.000000000 -0400
8705 +++ linux-2.6.18/drivers/net/eepro100.c 2006-09-22 20:45:04.000000000 -0400
8706 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
8707  # define rx_align(skb)         skb_reserve((skb), 2)
8708  # define RxFD_ALIGNMENT                __attribute__ ((aligned (2), packed))
8709  #else
8710 -# define rx_align(skb)
8711 +# define rx_align(skb) do {} while (0)
8712  # define RxFD_ALIGNMENT
8713  #endif
8714  
8715 diff -urNp linux-2.6.18/drivers/net/pcnet32.c linux-2.6.18/drivers/net/pcnet32.c
8716 --- linux-2.6.18/drivers/net/pcnet32.c  2006-09-19 23:42:06.000000000 -0400
8717 +++ linux-2.6.18/drivers/net/pcnet32.c  2006-09-22 20:45:04.000000000 -0400
8718 @@ -78,7 +78,7 @@ static int cards_found;
8719  /*
8720   * VLB I/O addresses
8721   */
8722 -static unsigned int pcnet32_portlist[] __initdata =
8723 +static unsigned int pcnet32_portlist[] __devinitdata =
8724      { 0x300, 0x320, 0x340, 0x360, 0 };
8725  
8726  static int pcnet32_debug = 0;
8727 diff -urNp linux-2.6.18/drivers/pci/proc.c linux-2.6.18/drivers/pci/proc.c
8728 --- linux-2.6.18/drivers/pci/proc.c     2006-09-19 23:42:06.000000000 -0400
8729 +++ linux-2.6.18/drivers/pci/proc.c     2006-09-22 20:04:35.000000000 -0400
8730 @@ -467,7 +467,15 @@ static int __init pci_proc_init(void)
8731  {
8732         struct proc_dir_entry *entry;
8733         struct pci_dev *dev = NULL;
8734 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8735 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8736 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
8737 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
8738 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
8739 +#endif
8740 +#else
8741         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
8742 +#endif
8743         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
8744         if (entry)
8745                 entry->proc_fops = &proc_bus_pci_dev_operations;
8746 diff -urNp linux-2.6.18/drivers/pnp/pnpbios/bioscalls.c linux-2.6.18/drivers/pnp/pnpbios/bioscalls.c
8747 --- linux-2.6.18/drivers/pnp/pnpbios/bioscalls.c        2006-09-19 23:42:06.000000000 -0400
8748 +++ linux-2.6.18/drivers/pnp/pnpbios/bioscalls.c        2006-09-22 20:45:04.000000000 -0400
8749 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
8750  set_limit(gdt[(selname) >> 3], size); \
8751  } while(0)
8752  
8753 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
8754 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
8755  
8756  /*
8757   * At some point we want to use this stack frame pointer to unwind
8758 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
8759         struct desc_struct save_desc_40;
8760         int cpu;
8761  
8762 +#ifdef CONFIG_PAX_KERNEXEC
8763 +       unsigned long cr0;
8764 +#endif
8765 +
8766         /*
8767          * PnP BIOSes are generally not terribly re-entrant.
8768          * Also, don't rely on them to save everything correctly.
8769 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
8770         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
8771         spin_lock_irqsave(&pnp_bios_lock, flags);
8772  
8773 +#ifdef CONFIG_PAX_KERNEXEC
8774 +       pax_open_kernel(cr0);
8775 +#endif
8776 +
8777         /* The lock prevents us bouncing CPU here */
8778         if (ts1_size)
8779                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
8780 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
8781                   "i" (0)
8782                 : "memory"
8783         );
8784 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
8785  
8786         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
8787 +
8788 +#ifdef CONFIG_PAX_KERNEXEC
8789 +       pax_close_kernel(cr0);
8790 +#endif
8791 +
8792 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
8793         put_cpu();
8794  
8795         /* If we get here and this is set then the PnP BIOS faulted on us. */
8796 diff -urNp linux-2.6.18/drivers/pnp/resource.c linux-2.6.18/drivers/pnp/resource.c
8797 --- linux-2.6.18/drivers/pnp/resource.c 2006-09-19 23:42:06.000000000 -0400
8798 +++ linux-2.6.18/drivers/pnp/resource.c 2006-09-22 20:45:04.000000000 -0400
8799 @@ -364,7 +364,7 @@ int pnp_check_irq(struct pnp_dev * dev, 
8800                 return 1;
8801  
8802         /* check if the resource is valid */
8803 -       if (*irq < 0 || *irq > 15)
8804 +       if (*irq > 15)
8805                 return 0;
8806  
8807         /* check if the resource is reserved */
8808 @@ -430,7 +430,7 @@ int pnp_check_dma(struct pnp_dev * dev, 
8809                 return 1;
8810  
8811         /* check if the resource is valid */
8812 -       if (*dma < 0 || *dma == 4 || *dma > 7)
8813 +       if (*dma == 4 || *dma > 7)
8814                 return 0;
8815  
8816         /* check if the resource is reserved */
8817 diff -urNp linux-2.6.18/drivers/rtc/rtc-v3020.c linux-2.6.18/drivers/rtc/rtc-v3020.c
8818 --- linux-2.6.18/drivers/rtc/rtc-v3020.c        2006-09-19 23:42:06.000000000 -0400
8819 +++ linux-2.6.18/drivers/rtc/rtc-v3020.c        2006-09-22 20:45:04.000000000 -0400
8820 @@ -198,9 +198,9 @@ static int rtc_probe(struct platform_dev
8821          * are all disabled */
8822         v3020_set_reg(chip, V3020_STATUS_0, 0x0);
8823  
8824 -       dev_info(&pdev->dev, "Chip available at physical address 0x%p,"
8825 +       dev_info(&pdev->dev, "Chip available at physical address 0x%Lx,"
8826                 "data connected to D%d\n",
8827 -               (void*)pdev->resource[0].start,
8828 +               pdev->resource[0].start,
8829                 chip->leftshift);
8830  
8831         platform_set_drvdata(pdev, chip);
8832 diff -urNp linux-2.6.18/drivers/scsi/scsi_logging.h linux-2.6.18/drivers/scsi/scsi_logging.h
8833 --- linux-2.6.18/drivers/scsi/scsi_logging.h    2006-09-19 23:42:06.000000000 -0400
8834 +++ linux-2.6.18/drivers/scsi/scsi_logging.h    2006-09-22 20:45:04.000000000 -0400
8835 @@ -51,7 +51,7 @@ do {                                                          \
8836                 } while (0);                                    \
8837  } while (0)
8838  #else
8839 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
8840 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
8841  #endif /* CONFIG_SCSI_LOGGING */
8842  
8843  /*
8844 diff -urNp linux-2.6.18/drivers/usb/storage/debug.h linux-2.6.18/drivers/usb/storage/debug.h
8845 --- linux-2.6.18/drivers/usb/storage/debug.h    2006-09-19 23:42:06.000000000 -0400
8846 +++ linux-2.6.18/drivers/usb/storage/debug.h    2006-09-22 20:45:04.000000000 -0400
8847 @@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char 
8848  #define US_DEBUGPX(x...) printk( x )
8849  #define US_DEBUG(x) x 
8850  #else
8851 -#define US_DEBUGP(x...)
8852 -#define US_DEBUGPX(x...)
8853 -#define US_DEBUG(x)
8854 +#define US_DEBUGP(x...) do {} while (0)
8855 +#define US_DEBUGPX(x...) do {} while (0)
8856 +#define US_DEBUG(x) do {} while (0)
8857  #endif
8858  
8859  #endif
8860 diff -urNp linux-2.6.18/drivers/video/fbcmap.c linux-2.6.18/drivers/video/fbcmap.c
8861 --- linux-2.6.18/drivers/video/fbcmap.c 2006-09-19 23:42:06.000000000 -0400
8862 +++ linux-2.6.18/drivers/video/fbcmap.c 2006-09-22 20:45:04.000000000 -0400
8863 @@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
8864         int rc, size = cmap->len * sizeof(u16);
8865         struct fb_cmap umap;
8866  
8867 -       if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
8868 -                               !info->fbops->fb_setcmap))
8869 +       if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
8870                 return -EINVAL;
8871  
8872         memset(&umap, 0, sizeof(struct fb_cmap));
8873 diff -urNp linux-2.6.18/drivers/video/fbmem.c linux-2.6.18/drivers/video/fbmem.c
8874 --- linux-2.6.18/drivers/video/fbmem.c  2006-09-19 23:42:06.000000000 -0400
8875 +++ linux-2.6.18/drivers/video/fbmem.c  2006-09-22 20:45:04.000000000 -0400
8876 @@ -935,9 +935,9 @@ fb_ioctl(struct inode *inode, struct fil
8877         case FBIOPUT_CON2FBMAP:
8878                 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
8879                         return - EFAULT;
8880 -               if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
8881 +               if (con2fb.console > MAX_NR_CONSOLES)
8882                     return -EINVAL;
8883 -               if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
8884 +               if (con2fb.framebuffer >= FB_MAX)
8885                     return -EINVAL;
8886  #ifdef CONFIG_KMOD
8887                 if (!registered_fb[con2fb.framebuffer])
8888 diff -urNp linux-2.6.18/drivers/video/fbmon.c linux-2.6.18/drivers/video/fbmon.c
8889 --- linux-2.6.18/drivers/video/fbmon.c  2006-09-19 23:42:06.000000000 -0400
8890 +++ linux-2.6.18/drivers/video/fbmon.c  2006-09-22 20:45:04.000000000 -0400
8891 @@ -45,7 +45,7 @@
8892  #ifdef DEBUG
8893  #define DPRINTK(fmt, args...) printk(fmt,## args)
8894  #else
8895 -#define DPRINTK(fmt, args...)
8896 +#define DPRINTK(fmt, args...) do {} while (0)
8897  #endif
8898  
8899  #define FBMON_FIX_HEADER 1
8900 diff -urNp linux-2.6.18/drivers/video/i810/i810_main.c linux-2.6.18/drivers/video/i810/i810_main.c
8901 --- linux-2.6.18/drivers/video/i810/i810_main.c 2006-09-19 23:42:06.000000000 -0400
8902 +++ linux-2.6.18/drivers/video/i810/i810_main.c 2006-09-22 20:04:35.000000000 -0400
8903 @@ -1506,7 +1506,7 @@ static int i810fb_cursor(struct fb_info 
8904                 int size = ((cursor->image.width + 7) >> 3) *
8905                         cursor->image.height;
8906                 int i;
8907 -               u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
8908 +               u8 *data = kmalloc(64 * 8, GFP_KERNEL);
8909  
8910                 if (data == NULL)
8911                         return -ENOMEM;
8912 diff -urNp linux-2.6.18/drivers/video/vesafb.c linux-2.6.18/drivers/video/vesafb.c
8913 --- linux-2.6.18/drivers/video/vesafb.c 2006-09-19 23:42:06.000000000 -0400
8914 +++ linux-2.6.18/drivers/video/vesafb.c 2006-09-22 20:45:04.000000000 -0400
8915 @@ -267,7 +267,7 @@ static int __init vesafb_probe(struct pl
8916                 size_remap = size_total;
8917         vesafb_fix.smem_len = size_remap;
8918  
8919 -#ifndef __i386__
8920 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
8921         screen_info.vesapm_seg = 0;
8922  #endif
8923  
8924 diff -urNp linux-2.6.18/fs/binfmt_aout.c linux-2.6.18/fs/binfmt_aout.c
8925 --- linux-2.6.18/fs/binfmt_aout.c       2006-09-19 23:42:06.000000000 -0400
8926 +++ linux-2.6.18/fs/binfmt_aout.c       2006-09-22 20:45:04.000000000 -0400
8927 @@ -24,6 +24,7 @@
8928  #include <linux/binfmts.h>
8929  #include <linux/personality.h>
8930  #include <linux/init.h>
8931 +#include <linux/grsecurity.h>
8932  
8933  #include <asm/system.h>
8934  #include <asm/uaccess.h>
8935 @@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
8936  /* If the size of the dump file exceeds the rlimit, then see what would happen
8937     if we wrote the stack, but not the data area.  */
8938  #ifdef __sparc__
8939 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
8940         if ((dump.u_dsize+dump.u_ssize) >
8941             current->signal->rlim[RLIMIT_CORE].rlim_cur)
8942                 dump.u_dsize = 0;
8943  #else
8944 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
8945         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
8946             current->signal->rlim[RLIMIT_CORE].rlim_cur)
8947                 dump.u_dsize = 0;
8948 @@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
8949  
8950  /* Make sure we have enough room to write the stack and data areas. */
8951  #ifdef __sparc__
8952 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
8953         if ((dump.u_ssize) >
8954             current->signal->rlim[RLIMIT_CORE].rlim_cur)
8955                 dump.u_ssize = 0;
8956  #else
8957 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
8958         if ((dump.u_ssize+1) * PAGE_SIZE >
8959             current->signal->rlim[RLIMIT_CORE].rlim_cur)
8960                 dump.u_ssize = 0;
8961 @@ -287,6 +292,8 @@ static int load_aout_binary(struct linux
8962         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
8963         if (rlim >= RLIM_INFINITY)
8964                 rlim = ~0;
8965 +
8966 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
8967         if (ex.a_data + ex.a_bss > rlim)
8968                 return -ENOMEM;
8969  
8970 @@ -319,6 +326,28 @@ static int load_aout_binary(struct linux
8971         current->mm->mmap = NULL;
8972         compute_creds(bprm);
8973         current->flags &= ~PF_FORKNOEXEC;
8974 +
8975 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
8976 +       current->mm->pax_flags = 0UL;
8977 +#endif
8978 +
8979 +#ifdef CONFIG_PAX_PAGEEXEC
8980 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
8981 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
8982 +
8983 +#ifdef CONFIG_PAX_EMUTRAMP
8984 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
8985 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
8986 +#endif
8987 +
8988 +#ifdef CONFIG_PAX_MPROTECT
8989 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
8990 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
8991 +#endif
8992 +
8993 +       }
8994 +#endif
8995 +
8996  #ifdef __sparc__
8997         if (N_MAGIC(ex) == NMAGIC) {
8998                 loff_t pos = fd_offset;
8999 @@ -414,7 +443,7 @@ static int load_aout_binary(struct linux
9000  
9001                 down_write(&current->mm->mmap_sem);
9002                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
9003 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
9004 +                               PROT_READ | PROT_WRITE,
9005                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
9006                                 fd_offset + ex.a_text);
9007                 up_write(&current->mm->mmap_sem);
9008 diff -urNp linux-2.6.18/fs/binfmt_elf.c linux-2.6.18/fs/binfmt_elf.c
9009 --- linux-2.6.18/fs/binfmt_elf.c        2006-09-19 23:42:06.000000000 -0400
9010 +++ linux-2.6.18/fs/binfmt_elf.c        2006-09-22 20:45:04.000000000 -0400
9011 @@ -39,10 +39,16 @@
9012  #include <linux/syscalls.h>
9013  #include <linux/random.h>
9014  #include <linux/elf.h>
9015 +#include <linux/grsecurity.h>
9016 +
9017  #include <asm/uaccess.h>
9018  #include <asm/param.h>
9019  #include <asm/page.h>
9020  
9021 +#ifdef CONFIG_PAX_SEGMEXEC
9022 +#include <asm/desc.h>
9023 +#endif
9024 +
9025  static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
9026  static int load_elf_library(struct file *);
9027  static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
9028 @@ -88,6 +94,8 @@ static struct linux_binfmt elf_format = 
9029  
9030  static int set_brk(unsigned long start, unsigned long end)
9031  {
9032 +       unsigned long e = end;
9033 +
9034         start = ELF_PAGEALIGN(start);
9035         end = ELF_PAGEALIGN(end);
9036         if (end > start) {
9037 @@ -98,7 +106,7 @@ static int set_brk(unsigned long start, 
9038                 if (BAD_ADDR(addr))
9039                         return addr;
9040         }
9041 -       current->mm->start_brk = current->mm->brk = end;
9042 +       current->mm->start_brk = current->mm->brk = e;
9043         return 0;
9044  }
9045  
9046 @@ -316,10 +324,9 @@ static unsigned long load_elf_interp(str
9047  {
9048         struct elf_phdr *elf_phdata;
9049         struct elf_phdr *eppnt;
9050 -       unsigned long load_addr = 0;
9051 -       int load_addr_set = 0;
9052 +       unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
9053         unsigned long last_bss = 0, elf_bss = 0;
9054 -       unsigned long error = ~0UL;
9055 +       unsigned long error = -EINVAL;
9056         int retval, i, size;
9057  
9058         /* First of all, some simple consistency checks */
9059 @@ -358,66 +365,86 @@ static unsigned long load_elf_interp(str
9060                 goto out_close;
9061         }
9062  
9063 +#ifdef CONFIG_PAX_SEGMEXEC
9064 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
9065 +               task_size = SEGMEXEC_TASK_SIZE;
9066 +#endif
9067 +
9068         eppnt = elf_phdata;
9069 +       min_addr = task_size;
9070 +       max_addr = 0;
9071 +       error = -ENOMEM;
9072 +
9073         for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
9074 -               if (eppnt->p_type == PT_LOAD) {
9075 -                       int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
9076 -                       int elf_prot = 0;
9077 -                       unsigned long vaddr = 0;
9078 -                       unsigned long k, map_addr;
9079 -
9080 -                       if (eppnt->p_flags & PF_R)
9081 -                               elf_prot = PROT_READ;
9082 -                       if (eppnt->p_flags & PF_W)
9083 -                               elf_prot |= PROT_WRITE;
9084 -                       if (eppnt->p_flags & PF_X)
9085 -                               elf_prot |= PROT_EXEC;
9086 -                       vaddr = eppnt->p_vaddr;
9087 -                       if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
9088 -                               elf_type |= MAP_FIXED;
9089 -
9090 -                       map_addr = elf_map(interpreter, load_addr + vaddr,
9091 -                                          eppnt, elf_prot, elf_type);
9092 -                       error = map_addr;
9093 -                       if (BAD_ADDR(map_addr))
9094 -                               goto out_close;
9095 -
9096 -                       if (!load_addr_set &&
9097 -                           interp_elf_ex->e_type == ET_DYN) {
9098 -                               load_addr = map_addr - ELF_PAGESTART(vaddr);
9099 -                               load_addr_set = 1;
9100 -                       }
9101 +               if (eppnt->p_type != PT_LOAD)
9102 +                       continue;
9103  
9104 -                       /*
9105 -                        * Check to see if the section's size will overflow the
9106 -                        * allowed task size. Note that p_filesz must always be
9107 -                        * <= p_memsize so it's only necessary to check p_memsz.
9108 -                        */
9109 -                       k = load_addr + eppnt->p_vaddr;
9110 -                       if (BAD_ADDR(k) ||
9111 -                           eppnt->p_filesz > eppnt->p_memsz ||
9112 -                           eppnt->p_memsz > TASK_SIZE ||
9113 -                           TASK_SIZE - eppnt->p_memsz < k) {
9114 -                               error = -ENOMEM;
9115 -                               goto out_close;
9116 -                       }
9117 +               /*
9118 +                * Check to see if the section's size will overflow the
9119 +                * allowed task size. Note that p_filesz must always be
9120 +                * <= p_memsize so it is only necessary to check p_memsz.
9121 +                */
9122 +               if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
9123 +                       goto out_close;
9124  
9125 -                       /*
9126 -                        * Find the end of the file mapping for this phdr, and
9127 -                        * keep track of the largest address we see for this.
9128 -                        */
9129 -                       k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
9130 -                       if (k > elf_bss)
9131 -                               elf_bss = k;
9132 +               if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
9133 +                       min_addr = ELF_PAGESTART(eppnt->p_vaddr);
9134 +               if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
9135 +                       max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
9136 +       }
9137 +       if (min_addr >= max_addr || max_addr > task_size)
9138 +               goto out_close;
9139  
9140 -                       /*
9141 -                        * Do the same thing for the memory mapping - between
9142 -                        * elf_bss and last_bss is the bss section.
9143 -                        */
9144 -                       k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
9145 -                       if (k > last_bss)
9146 -                               last_bss = k;
9147 -               }
9148 +       if (interp_elf_ex->e_type == ET_DYN) {
9149 +               load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
9150 +
9151 +               if (load_addr >= task_size)
9152 +                       goto out_close;
9153 +
9154 +               load_addr -= min_addr;
9155 +       }
9156 +
9157 +       eppnt = elf_phdata;
9158 +       for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
9159 +               int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
9160 +               int elf_prot = 0;
9161 +               unsigned long vaddr = 0;
9162 +               unsigned long k, map_addr;
9163 +
9164 +               if (eppnt->p_type != PT_LOAD)
9165 +                       continue;
9166 +
9167 +               if (eppnt->p_flags & PF_R)
9168 +                       elf_prot = PROT_READ;
9169 +               if (eppnt->p_flags & PF_W)
9170 +                       elf_prot |= PROT_WRITE;
9171 +               if (eppnt->p_flags & PF_X)
9172 +                       elf_prot |= PROT_EXEC;
9173 +               vaddr = eppnt->p_vaddr;
9174 +
9175 +               map_addr = elf_map(interpreter, load_addr + vaddr,
9176 +                                  eppnt, elf_prot, elf_type);
9177 +               error = map_addr;
9178 +               if (BAD_ADDR(map_addr))
9179 +                       goto out_close;
9180 +
9181 +               k = load_addr + eppnt->p_vaddr;
9182 +
9183 +               /*
9184 +                * Find the end of the file mapping for this phdr, and
9185 +                * keep track of the largest address we see for this.
9186 +                */
9187 +               k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
9188 +               if (k > elf_bss)
9189 +                       elf_bss = k;
9190 +
9191 +               /*
9192 +                * Do the same thing for the memory mapping - between
9193 +                * elf_bss and last_bss is the bss section.
9194 +                */
9195 +               k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
9196 +               if (k > last_bss)
9197 +                       last_bss = k;
9198         }
9199  
9200         /*
9201 @@ -445,6 +472,8 @@ static unsigned long load_elf_interp(str
9202  
9203         *interp_load_addr = load_addr;
9204         error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
9205 +       if (BAD_ADDR(error))
9206 +               error = -EFAULT;
9207  
9208  out_close:
9209         kfree(elf_phdata);
9210 @@ -455,7 +484,7 @@ out:
9211  static unsigned long load_aout_interp(struct exec *interp_ex,
9212                 struct file *interpreter)
9213  {
9214 -       unsigned long text_data, elf_entry = ~0UL;
9215 +       unsigned long text_data, elf_entry = -EINVAL;
9216         char __user * addr;
9217         loff_t offset;
9218  
9219 @@ -498,6 +527,180 @@ out:
9220         return elf_entry;
9221  }
9222  
9223 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
9224 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
9225 +{
9226 +       unsigned long pax_flags = 0UL;
9227 +
9228 +#ifdef CONFIG_PAX_PAGEEXEC
9229 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
9230 +               pax_flags |= MF_PAX_PAGEEXEC;
9231 +#endif
9232 +
9233 +#ifdef CONFIG_PAX_SEGMEXEC
9234 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
9235 +               pax_flags |= MF_PAX_SEGMEXEC;
9236 +#endif
9237 +
9238 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9239 +       if (pax_flags & MF_PAX_PAGEEXEC)
9240 +               pax_flags &= ~MF_PAX_SEGMEXEC;
9241 +#endif
9242 +
9243 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9244 +       if (pax_flags & MF_PAX_SEGMEXEC)
9245 +               pax_flags &= ~MF_PAX_PAGEEXEC;
9246 +#endif
9247 +
9248 +#ifdef CONFIG_PAX_EMUTRAMP
9249 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
9250 +               pax_flags |= MF_PAX_EMUTRAMP;
9251 +#endif
9252 +
9253 +#ifdef CONFIG_PAX_MPROTECT
9254 +       if (elf_phdata->p_flags & PF_MPROTECT)
9255 +               pax_flags |= MF_PAX_MPROTECT;
9256 +#endif
9257 +
9258 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
9259 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
9260 +               pax_flags |= MF_PAX_RANDMMAP;
9261 +#endif
9262 +
9263 +       return pax_flags;
9264 +}
9265 +#endif
9266 +
9267 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
9268 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
9269 +{
9270 +       unsigned long pax_flags = 0UL;
9271 +
9272 +#ifdef CONFIG_PAX_PAGEEXEC
9273 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
9274 +               pax_flags |= MF_PAX_PAGEEXEC;
9275 +#endif
9276 +
9277 +#ifdef CONFIG_PAX_SEGMEXEC
9278 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
9279 +               pax_flags |= MF_PAX_SEGMEXEC;
9280 +#endif
9281 +
9282 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9283 +       if (pax_flags & MF_PAX_PAGEEXEC)
9284 +               pax_flags &= ~MF_PAX_SEGMEXEC;
9285 +#endif
9286 +
9287 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9288 +       if (pax_flags & MF_PAX_SEGMEXEC)
9289 +               pax_flags &= ~MF_PAX_PAGEEXEC;
9290 +#endif
9291 +
9292 +#ifdef CONFIG_PAX_EMUTRAMP
9293 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
9294 +               pax_flags |= MF_PAX_EMUTRAMP;
9295 +#endif
9296 +
9297 +#ifdef CONFIG_PAX_MPROTECT
9298 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
9299 +               pax_flags |= MF_PAX_MPROTECT;
9300 +#endif
9301 +
9302 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
9303 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
9304 +               pax_flags |= MF_PAX_RANDMMAP;
9305 +#endif
9306 +
9307 +       return pax_flags;
9308 +}
9309 +#endif
9310 +
9311 +#ifdef CONFIG_PAX_EI_PAX
9312 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
9313 +{
9314 +       unsigned long pax_flags = 0UL;
9315 +
9316 +#ifdef CONFIG_PAX_PAGEEXEC
9317 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
9318 +               pax_flags |= MF_PAX_PAGEEXEC;
9319 +#endif
9320 +
9321 +#ifdef CONFIG_PAX_SEGMEXEC
9322 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
9323 +               pax_flags |= MF_PAX_SEGMEXEC;
9324 +#endif
9325 +
9326 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9327 +       if (pax_flags & MF_PAX_PAGEEXEC)
9328 +               pax_flags &= ~MF_PAX_SEGMEXEC;
9329 +#endif
9330 +
9331 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9332 +       if (pax_flags & MF_PAX_SEGMEXEC)
9333 +               pax_flags &= ~MF_PAX_PAGEEXEC;
9334 +#endif
9335 +
9336 +#ifdef CONFIG_PAX_EMUTRAMP
9337 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
9338 +               pax_flags |= MF_PAX_EMUTRAMP;
9339 +#endif
9340 +
9341 +#ifdef CONFIG_PAX_MPROTECT
9342 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
9343 +               pax_flags |= MF_PAX_MPROTECT;
9344 +#endif
9345 +
9346 +#ifdef CONFIG_PAX_ASLR
9347 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
9348 +               pax_flags |= MF_PAX_RANDMMAP;
9349 +#endif
9350 +
9351 +       return pax_flags;
9352 +}
9353 +#endif
9354 +
9355 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
9356 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
9357 +{
9358 +       unsigned long pax_flags = 0UL;
9359 +
9360 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
9361 +       unsigned long i;
9362 +#endif
9363 +
9364 +#ifdef CONFIG_PAX_EI_PAX
9365 +       pax_flags = pax_parse_ei_pax(elf_ex);
9366 +#endif
9367 +
9368 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
9369 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
9370 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
9371 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
9372 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
9373 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
9374 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
9375 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
9376 +                               return -EINVAL;
9377 +
9378 +#ifdef CONFIG_PAX_SOFTMODE
9379 +                       if (pax_softmode)
9380 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
9381 +                       else
9382 +#endif
9383 +
9384 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
9385 +                       break;
9386 +               }
9387 +#endif
9388 +
9389 +       if (0 > pax_check_flags(&pax_flags))
9390 +               return -EINVAL;
9391 +
9392 +       current->mm->pax_flags = pax_flags;
9393 +       return 0;
9394 +}
9395 +#endif
9396 +
9397  /*
9398   * These are the functions used to load ELF style executables and shared
9399   * libraries.  There is no binary dependent code anywhere else.
9400 @@ -534,7 +737,7 @@ static int load_elf_binary(struct linux_
9401         char * elf_interpreter = NULL;
9402         unsigned int interpreter_type = INTERPRETER_NONE;
9403         unsigned char ibcs2_interpreter = 0;
9404 -       unsigned long error;
9405 +       unsigned long error = 0;
9406         struct elf_phdr *elf_ppnt, *elf_phdata;
9407         unsigned long elf_bss, elf_brk;
9408         int elf_exec_fileno;
9409 @@ -552,6 +755,7 @@ static int load_elf_binary(struct linux_
9410                 struct elfhdr interp_elf_ex;
9411                 struct exec interp_ex;
9412         } *loc;
9413 +       unsigned long task_size = TASK_SIZE;
9414  
9415         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
9416         if (!loc) {
9417 @@ -774,14 +978,88 @@ static int load_elf_binary(struct linux_
9418         current->mm->end_code = 0;
9419         current->mm->mmap = NULL;
9420         current->flags &= ~PF_FORKNOEXEC;
9421 +
9422 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9423 +       current->mm->pax_flags = 0UL;
9424 +#endif
9425 +
9426 +#ifdef CONFIG_PAX_DLRESOLVE
9427 +       current->mm->call_dl_resolve = 0UL;
9428 +#endif
9429 +
9430 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
9431 +       current->mm->call_syscall = 0UL;
9432 +#endif
9433 +
9434 +#ifdef CONFIG_PAX_ASLR
9435 +       current->mm->delta_mmap = 0UL;
9436 +       current->mm->delta_exec = 0UL;
9437 +       current->mm->delta_stack = 0UL;
9438 +#endif
9439 +
9440         current->mm->def_flags = def_flags;
9441  
9442 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
9443 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
9444 +               send_sig(SIGKILL, current, 0);
9445 +               goto out_free_dentry;
9446 +       }
9447 +#endif
9448 +
9449 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
9450 +       pax_set_initial_flags(bprm);
9451 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
9452 +       if (pax_set_initial_flags_func)
9453 +               (pax_set_initial_flags_func)(bprm);
9454 +#endif
9455 +
9456 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
9457 +       if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
9458 +               current->mm->context.user_cs_limit = PAGE_SIZE;
9459 +#endif
9460 +
9461 +#ifdef CONFIG_PAX_SEGMEXEC
9462 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
9463 +               int cpu = get_cpu();
9464 +
9465 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
9466 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
9467 +               set_user_cs(current->mm, cpu);
9468 +               put_cpu();
9469 +               task_size = SEGMEXEC_TASK_SIZE;
9470 +       }
9471 +#endif
9472 +
9473 +#ifdef CONFIG_PAX_ASLR
9474 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
9475 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
9476 +
9477 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
9478 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
9479 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
9480 +       }
9481 +#endif
9482 +
9483 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
9484 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
9485 +               executable_stack = EXSTACK_DEFAULT;
9486 +#endif
9487 +
9488         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
9489            may depend on the personality.  */
9490         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
9491 +
9492 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
9493 +       if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
9494 +#endif
9495 +
9496         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
9497                 current->personality |= READ_IMPLIES_EXEC;
9498  
9499 +#ifdef CONFIG_PAX_ASLR
9500 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
9501 +#endif
9502 +
9503         if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
9504                 current->flags |= PF_RANDOMIZE;
9505         arch_pick_mmap_layout(current->mm);
9506 @@ -857,6 +1135,15 @@ static int load_elf_binary(struct linux_
9507                          * might try to exec.  This is because the brk will
9508                          * follow the loader, and is not movable.  */
9509                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
9510 +
9511 +#ifdef CONFIG_PAX_RANDMMAP
9512 +                       /* PaX: randomize base address at the default exe base if requested */
9513 +                       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
9514 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
9515 +                               elf_flags |= MAP_FIXED;
9516 +                       }
9517 +#endif
9518 +
9519                 }
9520  
9521                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
9522 @@ -887,9 +1174,9 @@ static int load_elf_binary(struct linux_
9523                  * allowed task size. Note that p_filesz must always be
9524                  * <= p_memsz so it is only necessary to check p_memsz.
9525                  */
9526 -               if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
9527 -                   elf_ppnt->p_memsz > TASK_SIZE ||
9528 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
9529 +               if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
9530 +                   elf_ppnt->p_memsz > task_size ||
9531 +                   task_size - elf_ppnt->p_memsz < k) {
9532                         /* set_brk can never work. Avoid overflows. */
9533                         send_sig(SIGKILL, current, 0);
9534                         goto out_free_dentry;
9535 @@ -916,6 +1203,12 @@ static int load_elf_binary(struct linux_
9536         start_data += load_bias;
9537         end_data += load_bias;
9538  
9539 +#ifdef CONFIG_PAX_RANDMMAP
9540 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP)
9541 +               elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
9542 +#undef pax_delta_mask
9543 +#endif
9544 +
9545         /* Calling set_brk effectively mmaps the pages that we need
9546          * for the bss and break sections.  We must do this before
9547          * mapping in the interpreter, to make sure it doesn't wind
9548 @@ -1168,7 +1461,7 @@ static int dump_seek(struct file *file, 
9549   *
9550   * I think we should skip something. But I am not sure how. H.J.
9551   */
9552 -static int maydump(struct vm_area_struct *vma)
9553 +static int maydump(struct vm_area_struct *vma, long signr)
9554  {
9555         /* Do not dump I/O mapped devices or special mappings */
9556         if (vma->vm_flags & (VM_IO | VM_RESERVED))
9557 @@ -1179,7 +1472,7 @@ static int maydump(struct vm_area_struct
9558                 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
9559  
9560         /* If it hasn't been written to, don't write it out */
9561 -       if (!vma->anon_vma)
9562 +       if (signr != SIGKILL && !vma->anon_vma)
9563                 return 0;
9564  
9565         return 1;
9566 @@ -1231,8 +1524,11 @@ static int writenote(struct memelfnote *
9567  #undef DUMP_SEEK
9568  
9569  #define DUMP_WRITE(addr, nr)   \
9570 +       do { \
9571 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
9572         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
9573 -               goto end_coredump;
9574 +               goto end_coredump; \
9575 +       } while (0);
9576  #define DUMP_SEEK(off) \
9577         if (!dump_seek(file, (off))) \
9578                 goto end_coredump;
9579 @@ -1586,7 +1882,7 @@ static int elf_core_dump(long signr, str
9580                 phdr.p_offset = offset;
9581                 phdr.p_vaddr = vma->vm_start;
9582                 phdr.p_paddr = 0;
9583 -               phdr.p_filesz = maydump(vma) ? sz : 0;
9584 +               phdr.p_filesz = maydump(vma, signr) ? sz : 0;
9585                 phdr.p_memsz = sz;
9586                 offset += phdr.p_filesz;
9587                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
9588 @@ -1623,7 +1919,7 @@ static int elf_core_dump(long signr, str
9589         for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
9590                 unsigned long addr;
9591  
9592 -               if (!maydump(vma))
9593 +               if (!maydump(vma, signr))
9594                         continue;
9595  
9596                 for (addr = vma->vm_start;
9597 @@ -1643,6 +1939,7 @@ static int elf_core_dump(long signr, str
9598                                         flush_cache_page(vma, addr,
9599                                                          page_to_pfn(page));
9600                                         kaddr = kmap(page);
9601 +                                       gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
9602                                         if ((size += PAGE_SIZE) > limit ||
9603                                             !dump_write(file, kaddr,
9604                                             PAGE_SIZE)) {
9605 diff -urNp linux-2.6.18/fs/binfmt_flat.c linux-2.6.18/fs/binfmt_flat.c
9606 --- linux-2.6.18/fs/binfmt_flat.c       2006-09-19 23:42:06.000000000 -0400
9607 +++ linux-2.6.18/fs/binfmt_flat.c       2006-09-22 20:45:04.000000000 -0400
9608 @@ -551,7 +551,9 @@ static int load_flat_file(struct linux_b
9609                                 realdatastart = (unsigned long) -ENOMEM;
9610                         printk("Unable to allocate RAM for process data, errno %d\n",
9611                                         (int)-datapos);
9612 +                       down_write(&current->mm->mmap_sem);
9613                         do_munmap(current->mm, textpos, text_len);
9614 +                       up_write(&current->mm->mmap_sem);
9615                         ret = realdatastart;
9616                         goto err;
9617                 }
9618 @@ -573,8 +575,10 @@ static int load_flat_file(struct linux_b
9619                 }
9620                 if (result >= (unsigned long)-4096) {
9621                         printk("Unable to read data+bss, errno %d\n", (int)-result);
9622 +                       down_write(&current->mm->mmap_sem);
9623                         do_munmap(current->mm, textpos, text_len);
9624                         do_munmap(current->mm, realdatastart, data_len + extra);
9625 +                       up_write(&current->mm->mmap_sem);
9626                         ret = result;
9627                         goto err;
9628                 }
9629 @@ -638,8 +642,10 @@ static int load_flat_file(struct linux_b
9630                 }
9631                 if (result >= (unsigned long)-4096) {
9632                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
9633 +                       down_write(&current->mm->mmap_sem);
9634                         do_munmap(current->mm, textpos, text_len + data_len + extra +
9635                                 MAX_SHARED_LIBS * sizeof(unsigned long));
9636 +                       up_write(&current->mm->mmap_sem);
9637                         ret = result;
9638                         goto err;
9639                 }
9640 diff -urNp linux-2.6.18/fs/binfmt_misc.c linux-2.6.18/fs/binfmt_misc.c
9641 --- linux-2.6.18/fs/binfmt_misc.c       2006-09-19 23:42:06.000000000 -0400
9642 +++ linux-2.6.18/fs/binfmt_misc.c       2006-09-22 20:45:04.000000000 -0400
9643 @@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
9644         struct files_struct *files = NULL;
9645  
9646         retval = -ENOEXEC;
9647 -       if (!enabled)
9648 +       if (!enabled || bprm->misc)
9649                 goto _ret;
9650  
9651 +       bprm->misc++;
9652 +
9653         /* to keep locking time low, we copy the interpreter string */
9654         read_lock(&entries_lock);
9655         fmt = check_file(bprm);
9656 diff -urNp linux-2.6.18/fs/buffer.c linux-2.6.18/fs/buffer.c
9657 --- linux-2.6.18/fs/buffer.c    2006-09-19 23:42:06.000000000 -0400
9658 +++ linux-2.6.18/fs/buffer.c    2006-09-22 20:04:35.000000000 -0400
9659 @@ -41,6 +41,7 @@
9660  #include <linux/bitops.h>
9661  #include <linux/mpage.h>
9662  #include <linux/bit_spinlock.h>
9663 +#include <linux/grsecurity.h>
9664  
9665  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
9666  static void invalidate_bh_lrus(void);
9667 @@ -2164,6 +2165,7 @@ static int __generic_cont_expand(struct 
9668  
9669         err = -EFBIG;
9670          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
9671 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
9672         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
9673                 send_sig(SIGXFSZ, current, 0);
9674                 goto out;
9675 diff -urNp linux-2.6.18/fs/cifs/smbdes.c linux-2.6.18/fs/cifs/smbdes.c
9676 --- linux-2.6.18/fs/cifs/smbdes.c       2006-09-19 23:42:06.000000000 -0400
9677 +++ linux-2.6.18/fs/cifs/smbdes.c       2006-09-22 20:45:04.000000000 -0400
9678 @@ -196,15 +196,18 @@ dohash(char *out, char *in, char *key, i
9679         char c[28];
9680         char d[28];
9681         char *cd;
9682 -       char ki[16][48];
9683 +       char *ki;
9684         char *pd1;
9685         char l[32], r[32];
9686         char *rl;
9687 +       char *er;  /* er[48]  */
9688  
9689         /* Have to reduce stack usage */
9690 -       pk1 = kmalloc(56+56+64+64,GFP_KERNEL);
9691 -       if(pk1 == NULL)
9692 -               return;
9693 +       pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
9694 +       ki = kmalloc(16*48, GFP_KERNEL);
9695 +       er = kmalloc(48+48+32+32+32, GFP_KERNEL);
9696 +       if (!pk1 || !ki || !er)
9697 +               goto free;
9698  
9699         cd = pk1 + 56;
9700         pd1= cd  + 56;
9701 @@ -222,7 +225,7 @@ dohash(char *out, char *in, char *key, i
9702                 lshift(d, sc[i], 28);
9703  
9704                 concat(cd, c, d, 28, 28);
9705 -               permute(ki[i], cd, perm2, 48);
9706 +               permute(ki+48*i, cd, perm2, 48);
9707         }
9708  
9709         permute(pd1, in, perm3, 64);
9710 @@ -233,18 +236,12 @@ dohash(char *out, char *in, char *key, i
9711         }
9712  
9713         for (i = 0; i < 16; i++) {
9714 -               char *er;  /* er[48]  */
9715                 char *erk; /* erk[48] */
9716                 char b[8][6];
9717                 char *cb;  /* cb[32]  */
9718                 char *pcb; /* pcb[32] */
9719                 char *r2;  /* r2[32]  */
9720  
9721 -               er = kmalloc(48+48+32+32+32, GFP_KERNEL);
9722 -               if(er == NULL) {
9723 -                       kfree(pk1);
9724 -                       return;
9725 -               }
9726                 erk = er+48;
9727                 cb  = erk+48;
9728                 pcb = cb+32;
9729 @@ -252,7 +249,7 @@ dohash(char *out, char *in, char *key, i
9730  
9731                 permute(er, r, perm4, 48);
9732  
9733 -               xor(erk, er, ki[forw ? i : 15 - i], 48);
9734 +               xor(erk, er, ki+48*(forw ? i : 15 - i), 48);
9735  
9736                 for (j = 0; j < 8; j++)
9737                         for (k = 0; k < 6; k++)
9738 @@ -282,13 +279,15 @@ dohash(char *out, char *in, char *key, i
9739  
9740                 for (j = 0; j < 32; j++)
9741                         r[j] = r2[j];
9742 -
9743 -               kfree(er);
9744         }
9745  
9746         concat(rl, r, l, 32, 32);
9747  
9748         permute(out, rl, perm6, 64);
9749 +
9750 +free:
9751 +       kfree(er);
9752 +       kfree(ki);
9753         kfree(pk1);
9754  }
9755  
9756 diff -urNp linux-2.6.18/fs/compat.c linux-2.6.18/fs/compat.c
9757 --- linux-2.6.18/fs/compat.c    2006-09-19 23:42:06.000000000 -0400
9758 +++ linux-2.6.18/fs/compat.c    2006-09-22 20:04:35.000000000 -0400
9759 @@ -46,6 +46,7 @@
9760  #include <linux/rwsem.h>
9761  #include <linux/acct.h>
9762  #include <linux/mm.h>
9763 +#include <linux/grsecurity.h>
9764  
9765  #include <net/sock.h>          /* siocdevprivate_ioctl */
9766  
9767 @@ -1512,6 +1513,11 @@ int compat_do_execve(char * filename,
9768         struct file *file;
9769         int retval;
9770         int i;
9771 +#ifdef CONFIG_GRKERNSEC
9772 +       struct file *old_exec_file;
9773 +       struct acl_subject_label *old_acl;
9774 +       struct rlimit old_rlim[RLIM_NLIMITS];
9775 +#endif
9776  
9777         retval = -ENOMEM;
9778         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
9779 @@ -1529,6 +1535,15 @@ int compat_do_execve(char * filename,
9780         bprm->file = file;
9781         bprm->filename = filename;
9782         bprm->interp = filename;
9783 +
9784 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
9785 +       retval = -EAGAIN;
9786 +       if (gr_handle_nproc())
9787 +               goto out_file;
9788 +       retval = -EACCES;
9789 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
9790 +               goto out_file;
9791 +
9792         bprm->mm = mm_alloc();
9793         retval = -ENOMEM;
9794         if (!bprm->mm)
9795 @@ -1567,10 +1582,39 @@ int compat_do_execve(char * filename,
9796         if (retval < 0)
9797                 goto out;
9798  
9799 +       if (!gr_tpe_allow(file)) {
9800 +               retval = -EACCES;
9801 +               goto out;
9802 +       }
9803 +
9804 +       if (gr_check_crash_exec(file)) {
9805 +               retval = -EACCES;
9806 +               goto out;
9807 +       }
9808 +
9809 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
9810 +
9811 +       gr_handle_exec_args(bprm, (char __user * __user *)argv);
9812 +
9813 +#ifdef CONFIG_GRKERNSEC
9814 +       old_acl = current->acl;
9815 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
9816 +       old_exec_file = current->exec_file;
9817 +       get_file(file);
9818 +       current->exec_file = file;
9819 +#endif
9820 +
9821 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
9822 +
9823         retval = search_binary_handler(bprm, regs);
9824         if (retval >= 0) {
9825                 free_arg_pages(bprm);
9826  
9827 +#ifdef CONFIG_GRKERNSEC
9828 +               if (old_exec_file)
9829 +                       fput(old_exec_file);
9830 +#endif
9831 +
9832                 /* execve success */
9833                 security_bprm_free(bprm);
9834                 acct_update_integrals(current);
9835 @@ -1578,6 +1622,13 @@ int compat_do_execve(char * filename,
9836                 return retval;
9837         }
9838  
9839 +#ifdef CONFIG_GRKERNSEC
9840 +       current->acl = old_acl;
9841 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
9842 +       fput(current->exec_file);
9843 +       current->exec_file = old_exec_file;
9844 +#endif
9845 +
9846  out:
9847         /* Something went wrong, return the inode and free the argument pages*/
9848         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
9849 diff -urNp linux-2.6.18/fs/dcache.c linux-2.6.18/fs/dcache.c
9850 --- linux-2.6.18/fs/dcache.c    2006-09-19 23:42:06.000000000 -0400
9851 +++ linux-2.6.18/fs/dcache.c    2006-09-22 20:04:35.000000000 -0400
9852 @@ -1402,7 +1402,7 @@ already_unhashed:
9853   *
9854   * "buflen" should be positive. Caller holds the dcache_lock.
9855   */
9856 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
9857 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
9858                         struct dentry *root, struct vfsmount *rootmnt,
9859                         char *buffer, int buflen)
9860  {
9861 diff -urNp linux-2.6.18/fs/exec.c linux-2.6.18/fs/exec.c
9862 --- linux-2.6.18/fs/exec.c      2006-09-19 23:42:06.000000000 -0400
9863 +++ linux-2.6.18/fs/exec.c      2006-09-22 22:13:47.000000000 -0400
9864 @@ -49,6 +49,8 @@
9865  #include <linux/acct.h>
9866  #include <linux/cn_proc.h>
9867  #include <linux/audit.h>
9868 +#include <linux/random.h>
9869 +#include <linux/grsecurity.h>
9870  
9871  #include <asm/uaccess.h>
9872  #include <asm/mmu_context.h>
9873 @@ -67,6 +69,15 @@ EXPORT_SYMBOL(suid_dumpable);
9874  static struct linux_binfmt *formats;
9875  static DEFINE_RWLOCK(binfmt_lock);
9876  
9877 +#ifdef CONFIG_PAX_SOFTMODE
9878 +unsigned int pax_softmode;
9879 +#endif
9880 +
9881 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
9882 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
9883 +EXPORT_SYMBOL(pax_set_initial_flags_func);
9884 +#endif
9885 +
9886  int register_binfmt(struct linux_binfmt * fmt)
9887  {
9888         struct linux_binfmt ** tmp = &formats;
9889 @@ -312,6 +323,10 @@ void install_arg_page(struct vm_area_str
9890         if (unlikely(anon_vma_prepare(vma)))
9891                 goto out;
9892  
9893 +#ifdef CONFIG_PAX_SEGMEXEC
9894 +       if (page_count(page) == 1)
9895 +#endif
9896 +
9897         flush_dcache_page(page);
9898         pte = get_locked_pte(mm, address, &ptl);
9899         if (!pte)
9900 @@ -321,9 +336,21 @@ void install_arg_page(struct vm_area_str
9901                 goto out;
9902         }
9903         inc_mm_counter(mm, anon_rss);
9904 +
9905 +#ifdef CONFIG_PAX_SEGMEXEC
9906 +       if (page_count(page) == 1)
9907 +#endif
9908 +
9909         lru_cache_add_active(page);
9910         set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
9911                                         page, vma->vm_page_prot))));
9912 +
9913 +#ifdef CONFIG_PAX_SEGMEXEC
9914 +       if (page_count(page) != 1)
9915 +               page_add_anon_rmap(page, vma, address);
9916 +       else
9917 +#endif
9918 +
9919         page_add_new_anon_rmap(page, vma, address);
9920         pte_unmap_unlock(pte, ptl);
9921  
9922 @@ -346,6 +373,10 @@ int setup_arg_pages(struct linux_binprm 
9923         int i, ret;
9924         long arg_size;
9925  
9926 +#ifdef CONFIG_PAX_SEGMEXEC
9927 +       struct vm_area_struct *mpnt_m = NULL;
9928 +#endif
9929 +
9930  #ifdef CONFIG_STACK_GROWSUP
9931         /* Move the argument and environment strings to the bottom of the
9932          * stack space.
9933 @@ -404,11 +435,19 @@ int setup_arg_pages(struct linux_binprm 
9934                 bprm->loader += stack_base;
9935         bprm->exec += stack_base;
9936  
9937 -       mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
9938 +       mpnt = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
9939         if (!mpnt)
9940                 return -ENOMEM;
9941  
9942 -       memset(mpnt, 0, sizeof(*mpnt));
9943 +#ifdef CONFIG_PAX_SEGMEXEC
9944 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
9945 +               mpnt_m = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
9946 +               if (!mpnt_m) {
9947 +                       kmem_cache_free(vm_area_cachep, mpnt);
9948 +                       return -ENOMEM;
9949 +               }
9950 +       }
9951 +#endif
9952  
9953         down_write(&mm->mmap_sem);
9954         {
9955 @@ -430,13 +469,50 @@ int setup_arg_pages(struct linux_binprm 
9956                 else
9957                         mpnt->vm_flags = VM_STACK_FLAGS;
9958                 mpnt->vm_flags |= mm->def_flags;
9959 -               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
9960 +
9961 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
9962 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
9963 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
9964 +               else
9965 +#endif
9966 +
9967 +               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
9968                 if ((ret = insert_vm_struct(mm, mpnt))) {
9969                         up_write(&mm->mmap_sem);
9970                         kmem_cache_free(vm_area_cachep, mpnt);
9971 +
9972 +#ifdef CONFIG_PAX_SEGMEXEC
9973 +                       if (mpnt_m)
9974 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
9975 +#endif
9976 +
9977                         return ret;
9978                 }
9979                 mm->stack_vm = mm->total_vm = vma_pages(mpnt);
9980 +
9981 +#ifdef CONFIG_PAX_SEGMEXEC
9982 +               if (mpnt_m) {
9983 +                       *mpnt_m = *mpnt;
9984 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
9985 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
9986 +                               mpnt_m->vm_page_prot = PAGE_NONE;
9987 +                       }
9988 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
9989 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
9990 +                       if ((ret = insert_vm_struct(mm, mpnt_m))) {
9991 +                               up_write(&mm->mmap_sem);
9992 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
9993 +                               return ret;
9994 +                       }
9995 +                       mpnt_m->vm_flags |= VM_MIRROR;
9996 +                       mpnt->vm_flags |= VM_MIRROR;
9997 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
9998 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
9999 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
10000 +                       mm->total_vm += vma_pages(mpnt_m);
10001 +               }
10002 +#endif
10003 +
10004         }
10005  
10006         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10007 @@ -444,6 +520,14 @@ int setup_arg_pages(struct linux_binprm 
10008                 if (page) {
10009                         bprm->page[i] = NULL;
10010                         install_arg_page(mpnt, page, stack_base);
10011 +
10012 +#ifdef CONFIG_PAX_SEGMEXEC
10013 +                       if (mpnt_m) {
10014 +                               page_cache_get(page);
10015 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
10016 +                       }
10017 +#endif
10018 +
10019                 }
10020                 stack_base += PAGE_SIZE;
10021         }
10022 @@ -1132,6 +1216,11 @@ int do_execve(char * filename,
10023         struct file *file;
10024         int retval;
10025         int i;
10026 +#ifdef CONFIG_GRKERNSEC
10027 +       struct file *old_exec_file;
10028 +       struct acl_subject_label *old_acl;
10029 +       struct rlimit old_rlim[RLIM_NLIMITS];
10030 +#endif
10031  
10032         retval = -ENOMEM;
10033         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
10034 @@ -1143,10 +1232,29 @@ int do_execve(char * filename,
10035         if (IS_ERR(file))
10036                 goto out_kfree;
10037  
10038 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
10039 +
10040 +       if (gr_handle_nproc()) {
10041 +               allow_write_access(file);
10042 +               fput(file);
10043 +               return -EAGAIN;
10044 +       }
10045 +
10046 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
10047 +               allow_write_access(file);
10048 +               fput(file);
10049 +               return -EACCES;
10050 +       }
10051 +
10052         sched_exec();
10053  
10054         bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
10055  
10056 +#ifdef CONFIG_PAX_RANDUSTACK
10057 +       if (randomize_va_space)
10058 +               bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
10059 +#endif
10060 +
10061         bprm->file = file;
10062         bprm->filename = filename;
10063         bprm->interp = filename;
10064 @@ -1188,8 +1296,38 @@ int do_execve(char * filename,
10065         if (retval < 0)
10066                 goto out;
10067  
10068 +       if (!gr_tpe_allow(file)) {
10069 +               retval = -EACCES;
10070 +               goto out;
10071 +       }
10072 +
10073 +       if (gr_check_crash_exec(file)) {
10074 +               retval = -EACCES;
10075 +               goto out;
10076 +       }
10077 +
10078 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
10079 +
10080 +       gr_handle_exec_args(bprm, argv);
10081 +
10082 +#ifdef CONFIG_GRKERNSEC
10083 +       old_acl = current->acl;
10084 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
10085 +       old_exec_file = current->exec_file;
10086 +       get_file(file);
10087 +       current->exec_file = file;
10088 +#endif
10089 +
10090 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
10091 +       if (retval < 0)
10092 +               goto out_fail;
10093 +
10094         retval = search_binary_handler(bprm,regs);
10095         if (retval >= 0) {
10096 +#ifdef CONFIG_GRKERNSEC
10097 +               if (old_exec_file)
10098 +                       fput(old_exec_file);
10099 +#endif
10100                 free_arg_pages(bprm);
10101  
10102                 /* execve success */
10103 @@ -1199,6 +1337,14 @@ int do_execve(char * filename,
10104                 return retval;
10105         }
10106  
10107 +out_fail:
10108 +#ifdef CONFIG_GRKERNSEC
10109 +       current->acl = old_acl;
10110 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
10111 +       fput(current->exec_file);
10112 +       current->exec_file = old_exec_file;
10113 +#endif
10114 +
10115  out:
10116         /* Something went wrong, return the inode and free the argument pages*/
10117         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10118 @@ -1359,6 +1505,114 @@ static void format_corename(char *corena
10119         *out_ptr = 0;
10120  }
10121  
10122 +int pax_check_flags(unsigned long * flags)
10123 +{
10124 +       int retval = 0;
10125 +
10126 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
10127 +       if (*flags & MF_PAX_SEGMEXEC)
10128 +       {
10129 +               *flags &= ~MF_PAX_SEGMEXEC;
10130 +               retval = -EINVAL;
10131 +       }
10132 +#endif
10133 +
10134 +       if ((*flags & MF_PAX_PAGEEXEC)
10135 +
10136 +#ifdef CONFIG_PAX_PAGEEXEC
10137 +           &&  (*flags & MF_PAX_SEGMEXEC)
10138 +#endif
10139 +
10140 +          )
10141 +       {
10142 +               *flags &= ~MF_PAX_PAGEEXEC;
10143 +               retval = -EINVAL;
10144 +       }
10145 +
10146 +       if ((*flags & MF_PAX_MPROTECT)
10147 +
10148 +#ifdef CONFIG_PAX_MPROTECT
10149 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
10150 +#endif
10151 +
10152 +          )
10153 +       {
10154 +               *flags &= ~MF_PAX_MPROTECT;
10155 +               retval = -EINVAL;
10156 +       }
10157 +
10158 +       if ((*flags & MF_PAX_EMUTRAMP)
10159 +
10160 +#ifdef CONFIG_PAX_EMUTRAMP
10161 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
10162 +#endif
10163 +
10164 +          )
10165 +       {
10166 +               *flags &= ~MF_PAX_EMUTRAMP;
10167 +               retval = -EINVAL;
10168 +       }
10169 +
10170 +       return retval;
10171 +}
10172 +
10173 +EXPORT_SYMBOL(pax_check_flags);
10174 +
10175 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10176 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
10177 +{
10178 +       struct task_struct *tsk = current;
10179 +       struct mm_struct *mm = current->mm;
10180 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
10181 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
10182 +       char* path_exec=NULL;
10183 +       char* path_fault=NULL;
10184 +       unsigned long start=0UL, end=0UL, offset=0UL;
10185 +
10186 +       if (buffer_exec && buffer_fault) {
10187 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
10188 +
10189 +               down_read(&mm->mmap_sem);
10190 +               vma = mm->mmap;
10191 +               while (vma && (!vma_exec || !vma_fault)) {
10192 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
10193 +                               vma_exec = vma;
10194 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
10195 +                               vma_fault = vma;
10196 +                       vma = vma->vm_next;
10197 +               }
10198 +               if (vma_exec) {
10199 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
10200 +                       if (IS_ERR(path_exec))
10201 +                               path_exec = "<path too long>";
10202 +               }
10203 +               if (vma_fault) {
10204 +                       start = vma_fault->vm_start;
10205 +                       end = vma_fault->vm_end;
10206 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
10207 +                       if (vma_fault->vm_file) {
10208 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
10209 +                               if (IS_ERR(path_fault))
10210 +                                       path_fault = "<path too long>";
10211 +                       } else
10212 +                               path_fault = "<anonymous mapping>";
10213 +               }
10214 +               up_read(&mm->mmap_sem);
10215 +       }
10216 +       if (tsk->signal->curr_ip)
10217 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: execution attempt in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->signal->curr_ip), path_fault, start, end, offset);
10218 +       else
10219 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
10220 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
10221 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
10222 +                       tsk->uid, tsk->euid, pc, sp);
10223 +       free_page((unsigned long)buffer_exec);
10224 +       free_page((unsigned long)buffer_fault);
10225 +       pax_report_insns(pc, sp);
10226 +       do_coredump(SIGKILL, SIGKILL, regs);
10227 +}
10228 +#endif
10229 +
10230  static void zap_process(struct task_struct *start)
10231  {
10232         struct task_struct *t;
10233 @@ -1498,6 +1752,10 @@ int do_coredump(long signr, int exit_cod
10234          */
10235         clear_thread_flag(TIF_SIGPENDING);
10236  
10237 +       if (signr == SIGKILL || signr == SIGILL)
10238 +               gr_handle_brute_attach(current);
10239 +
10240 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
10241         if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
10242                 goto fail_unlock;
10243  
10244 diff -urNp linux-2.6.18/fs/ext3/xattr.c linux-2.6.18/fs/ext3/xattr.c
10245 --- linux-2.6.18/fs/ext3/xattr.c        2006-09-19 23:42:06.000000000 -0400
10246 +++ linux-2.6.18/fs/ext3/xattr.c        2006-09-22 20:45:04.000000000 -0400
10247 @@ -89,8 +89,8 @@
10248                 printk("\n"); \
10249         } while (0)
10250  #else
10251 -# define ea_idebug(f...)
10252 -# define ea_bdebug(f...)
10253 +# define ea_idebug(f...) do {} while (0)
10254 +# define ea_bdebug(f...) do {} while (0)
10255  #endif
10256  
10257  static void ext3_xattr_cache_insert(struct buffer_head *);
10258 diff -urNp linux-2.6.18/fs/fcntl.c linux-2.6.18/fs/fcntl.c
10259 --- linux-2.6.18/fs/fcntl.c     2006-09-19 23:42:06.000000000 -0400
10260 +++ linux-2.6.18/fs/fcntl.c     2006-09-22 20:04:35.000000000 -0400
10261 @@ -18,6 +18,7 @@
10262  #include <linux/ptrace.h>
10263  #include <linux/signal.h>
10264  #include <linux/rcupdate.h>
10265 +#include <linux/grsecurity.h>
10266  
10267  #include <asm/poll.h>
10268  #include <asm/siginfo.h>
10269 @@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
10270         struct fdtable *fdt;
10271  
10272         error = -EINVAL;
10273 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
10274         if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
10275                 goto out;
10276  
10277 @@ -83,6 +85,7 @@ repeat:
10278         }
10279         
10280         error = -EMFILE;
10281 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
10282         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
10283                 goto out;
10284  
10285 @@ -141,6 +144,8 @@ asmlinkage long sys_dup2(unsigned int ol
10286         struct files_struct * files = current->files;
10287         struct fdtable *fdt;
10288  
10289 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
10290 +
10291         spin_lock(&files->file_lock);
10292         if (!(file = fcheck(oldfd)))
10293                 goto out_unlock;
10294 @@ -427,7 +432,8 @@ static inline int sigio_perm(struct task
10295         return (((fown->euid == 0) ||
10296                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
10297                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
10298 -               !security_file_send_sigiotask(p, fown, sig));
10299 +               !security_file_send_sigiotask(p, fown, sig) &&
10300 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
10301  }
10302  
10303  static void send_sigio_to_task(struct task_struct *p,
10304 diff -urNp linux-2.6.18/fs/Kconfig linux-2.6.18/fs/Kconfig
10305 --- linux-2.6.18/fs/Kconfig     2006-09-19 23:42:06.000000000 -0400
10306 +++ linux-2.6.18/fs/Kconfig     2006-09-22 20:04:35.000000000 -0400
10307 @@ -817,7 +817,7 @@ config PROC_FS
10308  
10309  config PROC_KCORE
10310         bool "/proc/kcore support" if !ARM
10311 -       depends on PROC_FS && MMU
10312 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
10313  
10314  config PROC_VMCORE
10315          bool "/proc/vmcore support (EXPERIMENTAL)"
10316 diff -urNp linux-2.6.18/fs/namei.c linux-2.6.18/fs/namei.c
10317 --- linux-2.6.18/fs/namei.c     2006-09-19 23:42:06.000000000 -0400
10318 +++ linux-2.6.18/fs/namei.c     2006-09-22 20:04:35.000000000 -0400
10319 @@ -32,6 +32,7 @@
10320  #include <linux/file.h>
10321  #include <linux/fcntl.h>
10322  #include <linux/namei.h>
10323 +#include <linux/grsecurity.h>
10324  #include <asm/namei.h>
10325  #include <asm/uaccess.h>
10326  
10327 @@ -618,6 +619,13 @@ static inline int do_follow_link(struct 
10328         err = security_inode_follow_link(path->dentry, nd);
10329         if (err)
10330                 goto loop;
10331 +
10332 +       if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
10333 +                                 path->dentry->d_inode, path->dentry, nd->mnt)) {
10334 +               err = -EACCES;
10335 +               goto loop;
10336 +       }
10337 +
10338         current->link_count++;
10339         current->total_link_count++;
10340         nd->depth++;
10341 @@ -961,11 +969,18 @@ return_reval:
10342                                 break;
10343                 }
10344  return_base:
10345 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
10346 +                       path_release(nd);
10347 +                       return -ENOENT;
10348 +               }
10349                 return 0;
10350  out_dput:
10351                 dput_path(&next, nd);
10352                 break;
10353         }
10354 +       if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
10355 +               err = -ENOENT;
10356 +
10357         path_release(nd);
10358  return_err:
10359         return err;
10360 @@ -1608,6 +1623,17 @@ int open_namei(int dfd, const char *path
10361                                          nd, flag);
10362                 if (error)
10363                         return error;
10364 +
10365 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
10366 +                       error = -EPERM;
10367 +                       goto exit;
10368 +               }
10369 +
10370 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
10371 +                       error = -EACCES;
10372 +                       goto exit;
10373 +               }
10374 +
10375                 goto ok;
10376         }
10377  
10378 @@ -1648,9 +1674,16 @@ do_last:
10379  
10380         /* Negative dentry, just create the file */
10381         if (!path.dentry->d_inode) {
10382 +               if (!gr_acl_handle_creat(path.dentry, nd->dentry, nd->mnt, flag, mode)) {
10383 +                       error = -EACCES;
10384 +                       mutex_unlock(&dir->d_inode->i_mutex);
10385 +                       goto exit_dput;
10386 +               }
10387                 if (!IS_POSIXACL(dir->d_inode))
10388                         mode &= ~current->fs->umask;
10389                 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
10390 +               if (!error)
10391 +                       gr_handle_create(path.dentry, nd->mnt);
10392                 mutex_unlock(&dir->d_inode->i_mutex);
10393                 dput(nd->dentry);
10394                 nd->dentry = path.dentry;
10395 @@ -1665,6 +1698,23 @@ do_last:
10396         /*
10397          * It already exists.
10398          */
10399 +
10400 +       if (gr_handle_rawio(path.dentry->d_inode)) {
10401 +               mutex_unlock(&dir->d_inode->i_mutex);
10402 +               error = -EPERM;
10403 +               goto exit_dput;
10404 +       }
10405 +       if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
10406 +               mutex_unlock(&dir->d_inode->i_mutex);
10407 +               error = -EACCES;
10408 +               goto exit_dput;
10409 +       }
10410 +       if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
10411 +               mutex_unlock(&dir->d_inode->i_mutex);
10412 +               error = -EACCES;
10413 +               goto exit_dput;
10414 +       }
10415 +
10416         mutex_unlock(&dir->d_inode->i_mutex);
10417         audit_inode_update(path.dentry->d_inode);
10418  
10419 @@ -1720,6 +1770,13 @@ do_link:
10420         error = security_inode_follow_link(path.dentry, nd);
10421         if (error)
10422                 goto exit_dput;
10423 +
10424 +       if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
10425 +                                 path.dentry, nd->mnt)) {
10426 +               error = -EACCES;
10427 +               goto exit_dput;
10428 +       }
10429 +
10430         error = __do_follow_link(&path, nd);
10431         if (error) {
10432                 /* Does someone understand code flow here? Or it is only
10433 @@ -1848,6 +1905,22 @@ asmlinkage long sys_mknodat(int dfd, con
10434         if (!IS_POSIXACL(nd.dentry->d_inode))
10435                 mode &= ~current->fs->umask;
10436         if (!IS_ERR(dentry)) {
10437 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
10438 +                       error = -EPERM;
10439 +                       dput(dentry);
10440 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
10441 +                       path_release(&nd);
10442 +                       goto out;
10443 +               }
10444 +
10445 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
10446 +                       error = -EACCES;
10447 +                       dput(dentry);
10448 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
10449 +                       path_release(&nd);
10450 +                       goto out;
10451 +               }
10452 +
10453                 switch (mode & S_IFMT) {
10454                 case 0: case S_IFREG:
10455                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
10456 @@ -1865,6 +1938,10 @@ asmlinkage long sys_mknodat(int dfd, con
10457                 default:
10458                         error = -EINVAL;
10459                 }
10460 +
10461 +               if (!error)
10462 +                       gr_handle_create(dentry, nd.mnt);
10463 +
10464                 dput(dentry);
10465         }
10466         mutex_unlock(&nd.dentry->d_inode->i_mutex);
10467 @@ -1919,9 +1996,19 @@ asmlinkage long sys_mkdirat(int dfd, con
10468                 dentry = lookup_create(&nd, 1);
10469                 error = PTR_ERR(dentry);
10470                 if (!IS_ERR(dentry)) {
10471 +                       error = 0;
10472                         if (!IS_POSIXACL(nd.dentry->d_inode))
10473                                 mode &= ~current->fs->umask;
10474 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
10475 +
10476 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
10477 +                               error = -EACCES;
10478 +
10479 +                       if (!error)
10480 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
10481 +
10482 +                       if (!error)
10483 +                               gr_handle_create(dentry, nd.mnt);
10484 +
10485                         dput(dentry);
10486                 }
10487                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
10488 @@ -2005,6 +2092,8 @@ static long do_rmdir(int dfd, const char
10489         char * name;
10490         struct dentry *dentry;
10491         struct nameidata nd;
10492 +       ino_t saved_ino = 0;
10493 +       dev_t saved_dev = 0;
10494  
10495         name = getname(pathname);
10496         if(IS_ERR(name))
10497 @@ -2029,7 +2118,21 @@ static long do_rmdir(int dfd, const char
10498         dentry = lookup_hash(&nd);
10499         error = PTR_ERR(dentry);
10500         if (!IS_ERR(dentry)) {
10501 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
10502 +               error = 0;
10503 +               if (dentry->d_inode) {
10504 +                       if (dentry->d_inode->i_nlink <= 1) {
10505 +                               saved_ino = dentry->d_inode->i_ino;
10506 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
10507 +                       }
10508 +
10509 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
10510 +                               error = -EACCES;
10511 +               }
10512 +
10513 +               if (!error)
10514 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry);
10515 +               if (!error && (saved_dev || saved_ino))
10516 +                       gr_handle_delete(saved_ino, saved_dev);
10517                 dput(dentry);
10518         }
10519         mutex_unlock(&nd.dentry->d_inode->i_mutex);
10520 @@ -2088,6 +2191,8 @@ static long do_unlinkat(int dfd, const c
10521         struct dentry *dentry;
10522         struct nameidata nd;
10523         struct inode *inode = NULL;
10524 +       ino_t saved_ino = 0;
10525 +       dev_t saved_dev = 0;
10526  
10527         name = getname(pathname);
10528         if(IS_ERR(name))
10529 @@ -2103,13 +2208,26 @@ static long do_unlinkat(int dfd, const c
10530         dentry = lookup_hash(&nd);
10531         error = PTR_ERR(dentry);
10532         if (!IS_ERR(dentry)) {
10533 +               error = 0;
10534                 /* Why not before? Because we want correct error value */
10535                 if (nd.last.name[nd.last.len])
10536                         goto slashes;
10537                 inode = dentry->d_inode;
10538 -               if (inode)
10539 +               if (inode) {
10540 +                       if (inode->i_nlink <= 1) {
10541 +                               saved_ino = inode->i_ino;
10542 +                               saved_dev = inode->i_sb->s_dev;
10543 +                       }
10544 +
10545 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
10546 +                               error = -EACCES;
10547 +
10548                         atomic_inc(&inode->i_count);
10549 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
10550 +               }
10551 +               if (!error)
10552 +                       error = vfs_unlink(nd.dentry->d_inode, dentry);
10553 +               if (!error && (saved_ino || saved_dev))
10554 +                       gr_handle_delete(saved_ino, saved_dev);
10555         exit2:
10556                 dput(dentry);
10557         }
10558 @@ -2187,7 +2305,15 @@ asmlinkage long sys_symlinkat(const char
10559                 dentry = lookup_create(&nd, 0);
10560                 error = PTR_ERR(dentry);
10561                 if (!IS_ERR(dentry)) {
10562 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
10563 +                       error = 0;
10564 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
10565 +                               error = -EACCES;
10566 +
10567 +                       if (!error)
10568 +                               error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
10569 +
10570 +                       if (!error)
10571 +                               gr_handle_create(dentry, nd.mnt);
10572                         dput(dentry);
10573                 }
10574                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
10575 @@ -2281,7 +2407,20 @@ asmlinkage long sys_linkat(int olddfd, c
10576         new_dentry = lookup_create(&nd, 0);
10577         error = PTR_ERR(new_dentry);
10578         if (!IS_ERR(new_dentry)) {
10579 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
10580 +               error = 0;
10581 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
10582 +                                      old_nd.dentry->d_inode,
10583 +                                      old_nd.dentry->d_inode->i_mode, to))
10584 +                       error = -EPERM;
10585 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
10586 +                                       old_nd.dentry, old_nd.mnt, to))
10587 +                       error = -EACCES;
10588 +               if (!error)
10589 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
10590 +
10591 +               if (!error)
10592 +                       gr_handle_create(new_dentry, nd.mnt);
10593 +
10594                 dput(new_dentry);
10595         }
10596         mutex_unlock(&nd.dentry->d_inode->i_mutex);
10597 @@ -2507,8 +2646,16 @@ static int do_rename(int olddfd, const c
10598         if (new_dentry == trap)
10599                 goto exit5;
10600  
10601 -       error = vfs_rename(old_dir->d_inode, old_dentry,
10602 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
10603 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
10604 +                                    newname);
10605 +
10606 +       if (!error)
10607 +               error = vfs_rename(old_dir->d_inode, old_dentry,
10608                                    new_dir->d_inode, new_dentry);
10609 +       if (!error)
10610 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
10611 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
10612  exit5:
10613         dput(new_dentry);
10614  exit4:
10615 diff -urNp linux-2.6.18/fs/namespace.c linux-2.6.18/fs/namespace.c
10616 --- linux-2.6.18/fs/namespace.c 2006-09-19 23:42:06.000000000 -0400
10617 +++ linux-2.6.18/fs/namespace.c 2006-09-22 20:04:35.000000000 -0400
10618 @@ -22,6 +22,8 @@
10619  #include <linux/namei.h>
10620  #include <linux/security.h>
10621  #include <linux/mount.h>
10622 +#include <linux/sched.h>
10623 +#include <linux/grsecurity.h>
10624  #include <asm/uaccess.h>
10625  #include <asm/unistd.h>
10626  #include "pnode.h"
10627 @@ -606,6 +608,8 @@ static int do_umount(struct vfsmount *mn
10628                         DQUOT_OFF(sb);
10629                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
10630                         unlock_kernel();
10631 +
10632 +                       gr_log_remount(mnt->mnt_devname, retval);
10633                 }
10634                 up_write(&sb->s_umount);
10635                 return retval;
10636 @@ -626,6 +630,9 @@ static int do_umount(struct vfsmount *mn
10637                 security_sb_umount_busy(mnt);
10638         up_write(&namespace_sem);
10639         release_mounts(&umount_list);
10640 +
10641 +       gr_log_unmount(mnt->mnt_devname, retval);
10642 +
10643         return retval;
10644  }
10645  
10646 @@ -1426,6 +1433,11 @@ long do_mount(char *dev_name, char *dir_
10647         if (retval)
10648                 goto dput_out;
10649  
10650 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
10651 +               retval = -EPERM;
10652 +               goto dput_out;
10653 +       }
10654 +
10655         if (flags & MS_REMOUNT)
10656                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
10657                                     data_page);
10658 @@ -1440,6 +1452,9 @@ long do_mount(char *dev_name, char *dir_
10659                                       dev_name, data_page);
10660  dput_out:
10661         path_release(&nd);
10662 +
10663 +       gr_log_mount(dev_name, dir_name, retval);
10664 +
10665         return retval;
10666  }
10667  
10668 @@ -1692,6 +1707,9 @@ asmlinkage long sys_pivot_root(const cha
10669         if (!capable(CAP_SYS_ADMIN))
10670                 return -EPERM;
10671  
10672 +       if (gr_handle_chroot_pivot())
10673 +               return -EPERM;
10674 +
10675         lock_kernel();
10676  
10677         error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
10678 diff -urNp linux-2.6.18/fs/open.c linux-2.6.18/fs/open.c
10679 --- linux-2.6.18/fs/open.c      2006-09-19 23:42:06.000000000 -0400
10680 +++ linux-2.6.18/fs/open.c      2006-09-22 20:15:13.000000000 -0400
10681 @@ -28,6 +28,7 @@
10682  #include <linux/syscalls.h>
10683  #include <linux/rcupdate.h>
10684  #include <linux/audit.h>
10685 +#include <linux/grsecurity.h>
10686  
10687  #include <asm/unistd.h>
10688  
10689 @@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
10690         if (length < 0)
10691                 return -EINVAL;
10692  
10693 +       if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
10694 +               return -EACCES;
10695 +
10696         newattrs.ia_size = length;
10697         newattrs.ia_valid = ATTR_SIZE | time_attrs;
10698         if (filp) {
10699 @@ -407,6 +411,12 @@ asmlinkage long sys_utime(char __user * 
10700                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
10701                         goto dput_and_out;
10702         }
10703 +
10704 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
10705 +               error = -EACCES;
10706 +               goto dput_and_out;
10707 +       }
10708 +
10709         mutex_lock(&inode->i_mutex);
10710         error = notify_change(nd.dentry, &newattrs);
10711         mutex_unlock(&inode->i_mutex);
10712 @@ -460,6 +470,12 @@ long do_utimes(int dfd, char __user *fil
10713                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
10714                         goto dput_and_out;
10715         }
10716 +
10717 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
10718 +               error = -EACCES;
10719 +               goto dput_and_out;
10720 +       }
10721 +
10722         mutex_lock(&inode->i_mutex);
10723         error = notify_change(nd.dentry, &newattrs);
10724         mutex_unlock(&inode->i_mutex);
10725 @@ -526,6 +542,10 @@ asmlinkage long sys_faccessat(int dfd, c
10726                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
10727                    && !special_file(nd.dentry->d_inode->i_mode))
10728                         res = -EROFS;
10729 +
10730 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
10731 +                       res = -EACCES;
10732 +
10733                 path_release(&nd);
10734         }
10735  
10736 @@ -554,6 +574,8 @@ asmlinkage long sys_chdir(const char __u
10737         if (error)
10738                 goto dput_and_out;
10739  
10740 +       gr_log_chdir(nd.dentry, nd.mnt);
10741 +
10742         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
10743  
10744  dput_and_out:
10745 @@ -584,6 +606,13 @@ asmlinkage long sys_fchdir(unsigned int 
10746                 goto out_putf;
10747  
10748         error = file_permission(file, MAY_EXEC);
10749 +
10750 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
10751 +               error = -EPERM;
10752 +
10753 +       if (!error)
10754 +               gr_log_chdir(dentry, mnt);
10755 +
10756         if (!error)
10757                 set_fs_pwd(current->fs, mnt, dentry);
10758  out_putf:
10759 @@ -609,8 +638,16 @@ asmlinkage long sys_chroot(const char __
10760         if (!capable(CAP_SYS_CHROOT))
10761                 goto dput_and_out;
10762  
10763 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
10764 +               goto dput_and_out;
10765 +
10766         set_fs_root(current->fs, nd.mnt, nd.dentry);
10767         set_fs_altroot();
10768 +
10769 +       gr_handle_chroot_caps(current);
10770 +
10771 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
10772 +
10773         error = 0;
10774  dput_and_out:
10775         path_release(&nd);
10776 @@ -641,9 +678,22 @@ asmlinkage long sys_fchmod(unsigned int 
10777         err = -EPERM;
10778         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
10779                 goto out_putf;
10780 +
10781 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
10782 +               err = -EACCES;
10783 +               goto out_putf;
10784 +       }
10785 +
10786         mutex_lock(&inode->i_mutex);
10787         if (mode == (mode_t) -1)
10788                 mode = inode->i_mode;
10789 +
10790 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
10791 +               err = -EPERM;
10792 +               mutex_unlock(&inode->i_mutex);
10793 +               goto out_putf;
10794 +       }
10795 +
10796         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
10797         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
10798         err = notify_change(dentry, &newattrs);
10799 @@ -676,9 +726,21 @@ asmlinkage long sys_fchmodat(int dfd, co
10800         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
10801                 goto dput_and_out;
10802  
10803 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
10804 +               error = -EACCES;
10805 +               goto dput_and_out;
10806 +       };
10807 +
10808         mutex_lock(&inode->i_mutex);
10809         if (mode == (mode_t) -1)
10810                 mode = inode->i_mode;
10811 +
10812 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
10813 +               error = -EACCES;
10814 +               mutex_unlock(&inode->i_mutex);
10815 +               goto dput_and_out;
10816 +       }
10817 +
10818         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
10819         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
10820         error = notify_change(nd.dentry, &newattrs);
10821 @@ -695,7 +757,7 @@ asmlinkage long sys_chmod(const char __u
10822         return sys_fchmodat(AT_FDCWD, filename, mode);
10823  }
10824  
10825 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
10826 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
10827  {
10828         struct inode * inode;
10829         int error;
10830 @@ -712,6 +774,12 @@ static int chown_common(struct dentry * 
10831         error = -EPERM;
10832         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
10833                 goto out;
10834 +
10835 +       if (!gr_acl_handle_chown(dentry, mnt)) {
10836 +               error = -EACCES;
10837 +               goto out;
10838 +       }
10839 +
10840         newattrs.ia_valid =  ATTR_CTIME;
10841         if (user != (uid_t) -1) {
10842                 newattrs.ia_valid |= ATTR_UID;
10843 @@ -737,7 +805,7 @@ asmlinkage long sys_chown(const char __u
10844  
10845         error = user_path_walk(filename, &nd);
10846         if (!error) {
10847 -               error = chown_common(nd.dentry, user, group);
10848 +               error = chown_common(nd.dentry, user, group, nd.mnt);
10849                 path_release(&nd);
10850         }
10851         return error;
10852 @@ -756,7 +824,7 @@ asmlinkage long sys_fchownat(int dfd, co
10853         follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
10854         error = __user_walk_fd(dfd, filename, follow, &nd);
10855         if (!error) {
10856 -               error = chown_common(nd.dentry, user, group);
10857 +               error = chown_common(nd.dentry, user, group, nd.mnt);
10858                 path_release(&nd);
10859         }
10860  out:
10861 @@ -770,7 +838,7 @@ asmlinkage long sys_lchown(const char __
10862  
10863         error = user_path_walk_link(filename, &nd);
10864         if (!error) {
10865 -               error = chown_common(nd.dentry, user, group);
10866 +               error = chown_common(nd.dentry, user, group, nd.mnt);
10867                 path_release(&nd);
10868         }
10869         return error;
10870 @@ -787,7 +855,7 @@ asmlinkage long sys_fchown(unsigned int 
10871                 struct dentry * dentry;
10872                 dentry = file->f_dentry;
10873                 audit_inode(NULL, dentry->d_inode);
10874 -               error = chown_common(dentry, user, group);
10875 +               error = chown_common(dentry, user, group, file->f_vfsmnt);
10876                 fput(file);
10877         }
10878         return error;
10879 @@ -995,6 +1063,7 @@ repeat:
10880          * N.B. For clone tasks sharing a files structure, this test
10881          * will limit the total number of files that can be opened.
10882          */
10883 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
10884         if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
10885                 goto out;
10886  
10887 diff -urNp linux-2.6.18/fs/partitions/efi.c linux-2.6.18/fs/partitions/efi.c
10888 --- linux-2.6.18/fs/partitions/efi.c    2006-09-19 23:42:06.000000000 -0400
10889 +++ linux-2.6.18/fs/partitions/efi.c    2006-09-22 20:45:04.000000000 -0400
10890 @@ -99,7 +99,7 @@
10891  #ifdef EFI_DEBUG
10892  #define Dprintk(x...) printk(KERN_DEBUG x)
10893  #else
10894 -#define Dprintk(x...)
10895 +#define Dprintk(x...) do {} while (0)
10896  #endif
10897  
10898  /* This allows a kernel command line option 'gpt' to override
10899 diff -urNp linux-2.6.18/fs/pipe.c linux-2.6.18/fs/pipe.c
10900 --- linux-2.6.18/fs/pipe.c      2006-09-19 23:42:06.000000000 -0400
10901 +++ linux-2.6.18/fs/pipe.c      2006-09-22 20:04:35.000000000 -0400
10902 @@ -842,7 +842,7 @@ void free_pipe_info(struct inode *inode)
10903         inode->i_pipe = NULL;
10904  }
10905  
10906 -static struct vfsmount *pipe_mnt __read_mostly;
10907 +struct vfsmount *pipe_mnt __read_mostly;
10908  static int pipefs_delete_dentry(struct dentry *dentry)
10909  {
10910         return 1;
10911 diff -urNp linux-2.6.18/fs/proc/array.c linux-2.6.18/fs/proc/array.c
10912 --- linux-2.6.18/fs/proc/array.c        2006-09-19 23:42:06.000000000 -0400
10913 +++ linux-2.6.18/fs/proc/array.c        2006-09-22 20:45:04.000000000 -0400
10914 @@ -293,6 +293,21 @@ static inline char *task_cap(struct task
10915                             cap_t(p->cap_effective));
10916  }
10917  
10918 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
10919 +static inline char *task_pax(struct task_struct *p, char *buffer)
10920 +{
10921 +       if (p->mm)
10922 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
10923 +                               p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
10924 +                               p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
10925 +                               p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
10926 +                               p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
10927 +                               p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
10928 +       else
10929 +               return buffer + sprintf(buffer, "PaX:\t-----\n");
10930 +}
10931 +#endif
10932 +
10933  int proc_pid_status(struct task_struct *task, char * buffer)
10934  {
10935         char * orig = buffer;
10936 @@ -311,9 +326,20 @@ int proc_pid_status(struct task_struct *
10937  #if defined(CONFIG_S390)
10938         buffer = task_show_regs(task, buffer);
10939  #endif
10940 +
10941 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
10942 +       buffer = task_pax(task, buffer);
10943 +#endif
10944 +
10945         return buffer - orig;
10946  }
10947  
10948 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
10949 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
10950 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
10951 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
10952 +#endif
10953 +
10954  static int do_task_stat(struct task_struct *task, char * buffer, int whole)
10955  {
10956         unsigned long vsize, eip, esp, wchan = ~0UL;
10957 @@ -398,6 +424,19 @@ static int do_task_stat(struct task_stru
10958                 stime = task->stime;
10959         }
10960  
10961 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
10962 +       if (PAX_RAND_FLAGS(mm)) {
10963 +               eip = 0;
10964 +               esp = 0;
10965 +               wchan = 0;
10966 +       }
10967 +#endif
10968 +#ifdef CONFIG_GRKERNSEC_HIDESYM
10969 +       wchan = 0;
10970 +       eip =0;
10971 +       esp =0;
10972 +#endif
10973 +
10974         /* scale priority and nice values from timeslices to -20..20 */
10975         /* to make it look like a "normal" Unix priority/nice value  */
10976         priority = task_prio(task);
10977 @@ -437,9 +476,15 @@ static int do_task_stat(struct task_stru
10978                 vsize,
10979                 mm ? get_mm_rss(mm) : 0,
10980                 rsslim,
10981 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
10982 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
10983 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
10984 +               PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
10985 +#else
10986                 mm ? mm->start_code : 0,
10987                 mm ? mm->end_code : 0,
10988                 mm ? mm->start_stack : 0,
10989 +#endif
10990                 esp,
10991                 eip,
10992                 /* The signal information here is obsolete.
10993 @@ -486,3 +531,14 @@ int proc_pid_statm(struct task_struct *t
10994         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
10995                        size, resident, shared, text, lib, data, 0);
10996  }
10997 +
10998 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
10999 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
11000 +{
11001 +       int len;
11002 +
11003 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
11004 +       return len;
11005 +}
11006 +#endif
11007 +
11008 diff -urNp linux-2.6.18/fs/proc/base.c linux-2.6.18/fs/proc/base.c
11009 --- linux-2.6.18/fs/proc/base.c 2006-09-19 23:42:06.000000000 -0400
11010 +++ linux-2.6.18/fs/proc/base.c 2006-09-22 20:41:43.000000000 -0400
11011 @@ -71,6 +71,7 @@
11012  #include <linux/cpuset.h>
11013  #include <linux/audit.h>
11014  #include <linux/poll.h>
11015 +#include <linux/grsecurity.h>
11016  #include "internal.h"
11017  
11018  /* NOTE:
11019 @@ -136,6 +137,9 @@ enum pid_directory_inos {
11020  #ifdef CONFIG_AUDITSYSCALL
11021         PROC_TGID_LOGINUID,
11022  #endif
11023 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11024 +       PROC_TGID_IPADDR,
11025 +#endif
11026         PROC_TGID_OOM_SCORE,
11027         PROC_TGID_OOM_ADJUST,
11028         PROC_TID_INO,
11029 @@ -220,6 +224,9 @@ static struct pid_entry tgid_base_stuff[
11030         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
11031         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
11032         E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
11033 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11034 +       E(PROC_TGID_IPADDR,     "ipaddr", S_IFREG|S_IRUSR),
11035 +#endif
11036  #ifdef CONFIG_MMU
11037         E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
11038  #endif
11039 @@ -410,7 +417,7 @@ static int proc_root_link(struct inode *
11040         (task->parent == current && \
11041         (task->ptrace & PT_PTRACED) && \
11042          (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
11043 -        security_ptrace(current,task) == 0))
11044 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
11045  
11046  static int proc_pid_environ(struct task_struct *task, char * buffer)
11047  {
11048 @@ -546,6 +553,8 @@ static int proc_fd_access_allowed(struct
11049         task = get_proc_task(inode);
11050         if (task) {
11051                 allowed = ptrace_may_attach(task);
11052 +               if (allowed != 0)
11053 +                       allowed = !gr_acl_handle_procpidmem(task);
11054                 put_task_struct(task);
11055         }
11056         return allowed;
11057 @@ -1322,6 +1331,9 @@ static struct inode *proc_pid_make_inode
11058                 inode->i_uid = task->euid;
11059                 inode->i_gid = task->egid;
11060         }
11061 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11062 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11063 +#endif
11064         security_task_to_inode(task, inode);
11065  
11066  out:
11067 @@ -1357,7 +1369,9 @@ static int pid_revalidate(struct dentry 
11068                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
11069                     task_dumpable(task)) {
11070                         inode->i_uid = task->euid;
11071 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
11072                         inode->i_gid = task->egid;
11073 +#endif
11074                 } else {
11075                         inode->i_uid = 0;
11076                         inode->i_gid = 0;
11077 @@ -1721,6 +1735,12 @@ static struct dentry *proc_pident_lookup
11078                         inode->i_fop = &proc_info_file_operations;
11079                         ei->op.proc_read = proc_pid_status;
11080                         break;
11081 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11082 +               case PROC_TGID_IPADDR:
11083 +                       inode->i_fop = &proc_info_file_operations;
11084 +                       ei->op.proc_read = proc_pid_ipaddr;
11085 +                       break;
11086 +#endif
11087                 case PROC_TID_STAT:
11088                         inode->i_fop = &proc_info_file_operations;
11089                         ei->op.proc_read = proc_tid_stat;
11090 @@ -2057,6 +2077,22 @@ struct dentry *proc_pid_lookup(struct in
11091         if (!task)
11092                 goto out;
11093  
11094 +       if (gr_check_hidden_task(task)) {
11095 +               put_task_struct(task);
11096 +               goto out;
11097 +       }
11098 +
11099 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11100 +       if (current->uid && (task->uid != current->uid)
11101 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11102 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
11103 +#endif
11104 +       ) {
11105 +               put_task_struct(task);
11106 +               goto out;
11107 +       }
11108 +#endif
11109 +
11110         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
11111         if (!inode)
11112                 goto out_put_task;
11113 diff -urNp linux-2.6.18/fs/proc/inode.c linux-2.6.18/fs/proc/inode.c
11114 --- linux-2.6.18/fs/proc/inode.c        2006-09-19 23:42:06.000000000 -0400
11115 +++ linux-2.6.18/fs/proc/inode.c        2006-09-22 20:04:35.000000000 -0400
11116 @@ -166,7 +166,11 @@ struct inode *proc_get_inode(struct supe
11117                 if (de->mode) {
11118                         inode->i_mode = de->mode;
11119                         inode->i_uid = de->uid;
11120 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11121 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11122 +#else
11123                         inode->i_gid = de->gid;
11124 +#endif
11125                 }
11126                 if (de->size)
11127                         inode->i_size = de->size;
11128 diff -urNp linux-2.6.18/fs/proc/internal.h linux-2.6.18/fs/proc/internal.h
11129 --- linux-2.6.18/fs/proc/internal.h     2006-09-19 23:42:06.000000000 -0400
11130 +++ linux-2.6.18/fs/proc/internal.h     2006-09-22 20:04:35.000000000 -0400
11131 @@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
11132  extern int proc_tgid_stat(struct task_struct *, char *);
11133  extern int proc_pid_status(struct task_struct *, char *);
11134  extern int proc_pid_statm(struct task_struct *, char *);
11135 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11136 +extern int proc_pid_ipaddr(struct task_struct*,char*);
11137 +#endif
11138  
11139  extern struct file_operations proc_maps_operations;
11140  extern struct file_operations proc_numa_maps_operations;
11141 diff -urNp linux-2.6.18/fs/proc/proc_misc.c linux-2.6.18/fs/proc/proc_misc.c
11142 --- linux-2.6.18/fs/proc/proc_misc.c    2006-09-19 23:42:06.000000000 -0400
11143 +++ linux-2.6.18/fs/proc/proc_misc.c    2006-09-22 20:04:35.000000000 -0400
11144 @@ -655,6 +655,8 @@ void create_seq_entry(char *name, mode_t
11145  void __init proc_misc_init(void)
11146  {
11147         struct proc_dir_entry *entry;
11148 +       int gr_mode = 0;
11149 +
11150         static struct {
11151                 char *name;
11152                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
11153 @@ -670,7 +672,9 @@ void __init proc_misc_init(void)
11154                 {"stram",       stram_read_proc},
11155  #endif
11156                 {"filesystems", filesystems_read_proc},
11157 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
11158                 {"cmdline",     cmdline_read_proc},
11159 +#endif
11160                 {"locks",       locks_read_proc},
11161                 {"execdomains", execdomains_read_proc},
11162                 {NULL,}
11163 @@ -678,19 +682,36 @@ void __init proc_misc_init(void)
11164         for (p = simple_ones; p->name; p++)
11165                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
11166  
11167 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11168 +       gr_mode = S_IRUSR;
11169 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11170 +       gr_mode = S_IRUSR | S_IRGRP;
11171 +#endif
11172 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11173 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
11174 +#endif
11175 +
11176         proc_symlink("mounts", NULL, "self/mounts");
11177  
11178         /* And now for trickier ones */
11179         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
11180         if (entry)
11181                 entry->proc_fops = &proc_kmsg_operations;
11182 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11183 +       create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
11184 +#else
11185         create_seq_entry("devices", 0, &proc_devinfo_operations);
11186 +#endif
11187         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
11188         create_seq_entry("partitions", 0, &proc_partitions_operations);
11189         create_seq_entry("stat", 0, &proc_stat_operations);
11190         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
11191  #ifdef CONFIG_SLAB
11192 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11193 +       create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
11194 +#else
11195         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
11196 +#endif
11197  #ifdef CONFIG_DEBUG_SLAB_LEAK
11198         create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
11199  #endif
11200 @@ -705,7 +726,7 @@ void __init proc_misc_init(void)
11201  #ifdef CONFIG_SCHEDSTATS
11202         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
11203  #endif
11204 -#ifdef CONFIG_PROC_KCORE
11205 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
11206         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
11207         if (proc_root_kcore) {
11208                 proc_root_kcore->proc_fops = &proc_kcore_operations;
11209 diff -urNp linux-2.6.18/fs/proc/root.c linux-2.6.18/fs/proc/root.c
11210 --- linux-2.6.18/fs/proc/root.c 2006-09-19 23:42:06.000000000 -0400
11211 +++ linux-2.6.18/fs/proc/root.c 2006-09-22 20:04:35.000000000 -0400
11212 @@ -52,7 +52,13 @@ void __init proc_root_init(void)
11213                 return;
11214         }
11215         proc_misc_init();
11216 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11217 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
11218 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11219 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
11220 +#else
11221         proc_net = proc_mkdir("net", NULL);
11222 +#endif
11223         proc_net_stat = proc_mkdir("net/stat", NULL);
11224  
11225  #ifdef CONFIG_SYSVIPC
11226 @@ -76,7 +82,15 @@ void __init proc_root_init(void)
11227  #ifdef CONFIG_PROC_DEVICETREE
11228         proc_device_tree_init();
11229  #endif
11230 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11231 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11232 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
11233 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11234 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
11235 +#endif
11236 +#else
11237         proc_bus = proc_mkdir("bus", NULL);
11238 +#endif
11239  }
11240  
11241  static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
11242 diff -urNp linux-2.6.18/fs/proc/task_mmu.c linux-2.6.18/fs/proc/task_mmu.c
11243 --- linux-2.6.18/fs/proc/task_mmu.c     2006-09-19 23:42:06.000000000 -0400
11244 +++ linux-2.6.18/fs/proc/task_mmu.c     2006-09-22 20:45:04.000000000 -0400
11245 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
11246                 "VmStk:\t%8lu kB\n"
11247                 "VmExe:\t%8lu kB\n"
11248                 "VmLib:\t%8lu kB\n"
11249 -               "VmPTE:\t%8lu kB\n",
11250 -               hiwater_vm << (PAGE_SHIFT-10),
11251 +               "VmPTE:\t%8lu kB\n"
11252 +
11253 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
11254 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
11255 +#endif
11256 +
11257 +               ,hiwater_vm << (PAGE_SHIFT-10),
11258                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
11259                 mm->locked_vm << (PAGE_SHIFT-10),
11260                 hiwater_rss << (PAGE_SHIFT-10),
11261                 total_rss << (PAGE_SHIFT-10),
11262                 data << (PAGE_SHIFT-10),
11263                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
11264 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
11265 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
11266 +
11267 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
11268 +               , mm->context.user_cs_base, mm->context.user_cs_limit
11269 +#endif
11270 +
11271 +       );
11272 +
11273         return buffer;
11274  }
11275  
11276 @@ -127,6 +139,12 @@ __attribute__((weak)) const char *arch_v
11277         return NULL;
11278  }
11279  
11280 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11281 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
11282 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
11283 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
11284 +#endif
11285 +
11286  static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
11287  {
11288         struct proc_maps_private *priv = m->private;
11289 @@ -146,13 +164,30 @@ static int show_map_internal(struct seq_
11290         }
11291  
11292         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
11293 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11294 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
11295 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
11296 +#else
11297                         vma->vm_start,
11298                         vma->vm_end,
11299 +#endif
11300 +
11301 +#if 0
11302 +                       flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
11303 +                       flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
11304 +                       flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
11305 +#else
11306                         flags & VM_READ ? 'r' : '-',
11307                         flags & VM_WRITE ? 'w' : '-',
11308                         flags & VM_EXEC ? 'x' : '-',
11309 +#endif
11310 +
11311                         flags & VM_MAYSHARE ? 's' : 'p',
11312 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11313 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
11314 +#else
11315                         vma->vm_pgoff << PAGE_SHIFT,
11316 +#endif
11317                         MAJOR(dev), MINOR(dev), ino, &len);
11318  
11319         /*
11320 @@ -166,11 +201,11 @@ static int show_map_internal(struct seq_
11321                 const char *name = arch_vma_name(vma);
11322                 if (!name) {
11323                         if (mm) {
11324 -                               if (vma->vm_start <= mm->start_brk &&
11325 -                                               vma->vm_end >= mm->brk) {
11326 +                               if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
11327                                         name = "[heap]";
11328 -                               } else if (vma->vm_start <= mm->start_stack &&
11329 -                                          vma->vm_end >= mm->start_stack) {
11330 +                               } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
11331 +                                          (vma->vm_start <= mm->start_stack &&
11332 +                                           vma->vm_end >= mm->start_stack)) {
11333                                         name = "[stack]";
11334                                 }
11335                         } else {
11336 @@ -184,7 +219,25 @@ static int show_map_internal(struct seq_
11337         }
11338         seq_putc(m, '\n');
11339  
11340 -       if (mss)
11341 +       
11342 +       if (mss) {
11343 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11344 +           if (PAX_RAND_FLAGS(mm))
11345 +               seq_printf(m,
11346 +                          "Size:          %8lu kB\n"
11347 +                          "Rss:           %8lu kB\n"
11348 +                          "Shared_Clean:  %8lu kB\n"
11349 +                          "Shared_Dirty:  %8lu kB\n"
11350 +                          "Private_Clean: %8lu kB\n"
11351 +                          "Private_Dirty: %8lu kB\n",
11352 +                          0UL,
11353 +                          0UL,
11354 +                          0UL,
11355 +                          0UL,
11356 +                          0UL,
11357 +                          0UL);
11358 +           else
11359 +#endif
11360                 seq_printf(m,
11361                            "Size:          %8lu kB\n"
11362                            "Rss:           %8lu kB\n"
11363 @@ -198,6 +251,7 @@ static int show_map_internal(struct seq_
11364                            mss->shared_dirty  >> 10,
11365                            mss->private_clean >> 10,
11366                            mss->private_dirty >> 10);
11367 +       }
11368  
11369         if (m->count < m->size)  /* vma is copied successfully */
11370                 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
11371 diff -urNp linux-2.6.18/fs/readdir.c linux-2.6.18/fs/readdir.c
11372 --- linux-2.6.18/fs/readdir.c   2006-09-19 23:42:06.000000000 -0400
11373 +++ linux-2.6.18/fs/readdir.c   2006-09-22 20:04:35.000000000 -0400
11374 @@ -16,6 +16,8 @@
11375  #include <linux/security.h>
11376  #include <linux/syscalls.h>
11377  #include <linux/unistd.h>
11378 +#include <linux/namei.h>
11379 +#include <linux/grsecurity.h>
11380  
11381  #include <asm/uaccess.h>
11382  
11383 @@ -65,6 +67,7 @@ struct old_linux_dirent {
11384  
11385  struct readdir_callback {
11386         struct old_linux_dirent __user * dirent;
11387 +       struct file * file;
11388         int result;
11389  };
11390  
11391 @@ -76,6 +79,10 @@ static int fillonedir(void * __buf, cons
11392  
11393         if (buf->result)
11394                 return -EINVAL;
11395 +
11396 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
11397 +               return 0;
11398 +
11399         buf->result++;
11400         dirent = buf->dirent;
11401         if (!access_ok(VERIFY_WRITE, dirent,
11402 @@ -107,6 +114,7 @@ asmlinkage long old_readdir(unsigned int
11403  
11404         buf.result = 0;
11405         buf.dirent = dirent;
11406 +       buf.file = file;
11407  
11408         error = vfs_readdir(file, fillonedir, &buf);
11409         if (error >= 0)
11410 @@ -133,6 +141,7 @@ struct linux_dirent {
11411  struct getdents_callback {
11412         struct linux_dirent __user * current_dir;
11413         struct linux_dirent __user * previous;
11414 +       struct file * file;
11415         int count;
11416         int error;
11417  };
11418 @@ -147,6 +156,10 @@ static int filldir(void * __buf, const c
11419         buf->error = -EINVAL;   /* only used if we fail.. */
11420         if (reclen > buf->count)
11421                 return -EINVAL;
11422 +
11423 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
11424 +               return 0;
11425 +
11426         dirent = buf->previous;
11427         if (dirent) {
11428                 if (__put_user(offset, &dirent->d_off))
11429 @@ -191,6 +204,7 @@ asmlinkage long sys_getdents(unsigned in
11430  
11431         buf.current_dir = dirent;
11432         buf.previous = NULL;
11433 +       buf.file = file;
11434         buf.count = count;
11435         buf.error = 0;
11436  
11437 @@ -217,6 +231,7 @@ out:
11438  struct getdents_callback64 {
11439         struct linux_dirent64 __user * current_dir;
11440         struct linux_dirent64 __user * previous;
11441 +       struct file * file;
11442         int count;
11443         int error;
11444  };
11445 @@ -231,6 +246,10 @@ static int filldir64(void * __buf, const
11446         buf->error = -EINVAL;   /* only used if we fail.. */
11447         if (reclen > buf->count)
11448                 return -EINVAL;
11449 +
11450 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
11451 +               return 0;
11452 +
11453         dirent = buf->previous;
11454         if (dirent) {
11455                 if (__put_user(offset, &dirent->d_off))
11456 @@ -277,6 +296,7 @@ asmlinkage long sys_getdents64(unsigned 
11457  
11458         buf.current_dir = dirent;
11459         buf.previous = NULL;
11460 +       buf.file = file;
11461         buf.count = count;
11462         buf.error = 0;
11463  
11464 diff -urNp linux-2.6.18/fs/udf/balloc.c linux-2.6.18/fs/udf/balloc.c
11465 --- linux-2.6.18/fs/udf/balloc.c        2006-09-19 23:42:06.000000000 -0400
11466 +++ linux-2.6.18/fs/udf/balloc.c        2006-09-22 20:45:04.000000000 -0400
11467 @@ -153,8 +153,7 @@ static void udf_bitmap_free_blocks(struc
11468         unsigned long overflow;
11469  
11470         mutex_lock(&sbi->s_alloc_mutex);
11471 -       if (bloc.logicalBlockNum < 0 ||
11472 -               (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
11473 +       if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
11474         {
11475                 udf_debug("%d < %d || %d + %d > %d\n",
11476                         bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
11477 @@ -227,7 +226,7 @@ static int udf_bitmap_prealloc_blocks(st
11478         struct buffer_head *bh;
11479  
11480         mutex_lock(&sbi->s_alloc_mutex);
11481 -       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
11482 +       if (first_block >= UDF_SB_PARTLEN(sb, partition))
11483                 goto out;
11484  
11485         if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
11486 @@ -294,7 +293,7 @@ static int udf_bitmap_new_block(struct s
11487         mutex_lock(&sbi->s_alloc_mutex);
11488  
11489  repeat:
11490 -       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
11491 +       if (goal >= UDF_SB_PARTLEN(sb, partition))
11492                 goal = 0;
11493  
11494         nr_groups = bitmap->s_nr_groups;
11495 @@ -434,8 +433,7 @@ static void udf_table_free_blocks(struct
11496         int i;
11497  
11498         mutex_lock(&sbi->s_alloc_mutex);
11499 -       if (bloc.logicalBlockNum < 0 ||
11500 -               (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
11501 +       if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
11502         {
11503                 udf_debug("%d < %d || %d + %d > %d\n",
11504                         bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
11505 @@ -682,7 +680,7 @@ static int udf_table_prealloc_blocks(str
11506         struct buffer_head *bh;
11507         int8_t etype = -1;
11508  
11509 -       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
11510 +       if (first_block >= UDF_SB_PARTLEN(sb, partition))
11511                 return 0;
11512  
11513         if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
11514 @@ -762,7 +760,7 @@ static int udf_table_new_block(struct su
11515                 return newblock;
11516  
11517         mutex_lock(&sbi->s_alloc_mutex);
11518 -       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
11519 +       if (goal >= UDF_SB_PARTLEN(sb, partition))
11520                 goal = 0;
11521  
11522         /* We search for the closest matching block to goal. If we find a exact hit,
11523 diff -urNp linux-2.6.18/fs/udf/inode.c linux-2.6.18/fs/udf/inode.c
11524 --- linux-2.6.18/fs/udf/inode.c 2006-09-19 23:42:06.000000000 -0400
11525 +++ linux-2.6.18/fs/udf/inode.c 2006-09-22 20:45:04.000000000 -0400
11526 @@ -300,9 +300,6 @@ static int udf_get_block(struct inode *i
11527  
11528         lock_kernel();
11529  
11530 -       if (block < 0)
11531 -               goto abort_negative;
11532 -
11533         if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
11534         {
11535                 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
11536 @@ -323,10 +320,6 @@ static int udf_get_block(struct inode *i
11537  abort:
11538         unlock_kernel();
11539         return err;
11540 -
11541 -abort_negative:
11542 -       udf_warning(inode->i_sb, "udf_get_block", "block < 0");
11543 -       goto abort;
11544  }
11545  
11546  static struct buffer_head *
11547 diff -urNp linux-2.6.18/fs/ufs/inode.c linux-2.6.18/fs/ufs/inode.c
11548 --- linux-2.6.18/fs/ufs/inode.c 2006-09-19 23:42:06.000000000 -0400
11549 +++ linux-2.6.18/fs/ufs/inode.c 2006-09-22 20:45:04.000000000 -0400
11550 @@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
11551  
11552  
11553         UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
11554 -       if (i_block < 0) {
11555 -               ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
11556 -       } else if (i_block < direct_blocks) {
11557 +       if (i_block < direct_blocks) {
11558                 offsets[n++] = i_block;
11559         } else if ((i_block -= direct_blocks) < indirect_blocks) {
11560                 offsets[n++] = UFS_IND_BLOCK;
11561 @@ -454,8 +452,6 @@ int ufs_getfrag_block(struct inode *inod
11562         lock_kernel();
11563  
11564         UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
11565 -       if (fragment < 0)
11566 -               goto abort_negative;
11567         if (fragment >
11568             ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
11569              << uspi->s_fpbshift))
11570 @@ -516,10 +512,6 @@ abort:
11571         unlock_kernel();
11572         return err;
11573  
11574 -abort_negative:
11575 -       ufs_warning(sb, "ufs_get_block", "block < 0");
11576 -       goto abort;
11577 -
11578  abort_too_big:
11579         ufs_warning(sb, "ufs_get_block", "block > big");
11580         goto abort;
11581 diff -urNp linux-2.6.18/fs/xfs/linux-2.6/xfs_file.c linux-2.6.18/fs/xfs/linux-2.6/xfs_file.c
11582 --- linux-2.6.18/fs/xfs/linux-2.6/xfs_file.c    2006-09-19 23:42:06.000000000 -0400
11583 +++ linux-2.6.18/fs/xfs/linux-2.6/xfs_file.c    2006-09-22 20:45:04.000000000 -0400
11584 @@ -432,6 +432,12 @@ xfs_file_mmap(
11585         struct file     *filp,
11586         struct vm_area_struct *vma)
11587  {
11588 +
11589 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
11590 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
11591 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
11592 +#endif
11593 +
11594         vma->vm_ops = &xfs_file_vm_ops;
11595  
11596  #ifdef CONFIG_XFS_DMAPI
11597 diff -urNp linux-2.6.18/fs/xfs/xfs_bmap.c linux-2.6.18/fs/xfs/xfs_bmap.c
11598 --- linux-2.6.18/fs/xfs/xfs_bmap.c      2006-09-19 23:42:06.000000000 -0400
11599 +++ linux-2.6.18/fs/xfs/xfs_bmap.c      2006-09-22 20:45:04.000000000 -0400
11600 @@ -376,7 +376,7 @@ xfs_bmap_validate_ret(
11601         int                     nmap,
11602         int                     ret_nmap);
11603  #else
11604 -#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
11605 +#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
11606  #endif /* DEBUG */
11607  
11608  #if defined(XFS_RW_TRACE)
11609 diff -urNp linux-2.6.18/grsecurity/gracl_alloc.c linux-2.6.18/grsecurity/gracl_alloc.c
11610 --- linux-2.6.18/grsecurity/gracl_alloc.c       1969-12-31 19:00:00.000000000 -0500
11611 +++ linux-2.6.18/grsecurity/gracl_alloc.c       2006-09-22 20:04:35.000000000 -0400
11612 @@ -0,0 +1,91 @@
11613 +#include <linux/kernel.h>
11614 +#include <linux/mm.h>
11615 +#include <linux/slab.h>
11616 +#include <linux/vmalloc.h>
11617 +#include <linux/gracl.h>
11618 +#include <linux/grsecurity.h>
11619 +
11620 +static unsigned long alloc_stack_next = 1;
11621 +static unsigned long alloc_stack_size = 1;
11622 +static void **alloc_stack;
11623 +
11624 +static __inline__ int
11625 +alloc_pop(void)
11626 +{
11627 +       if (alloc_stack_next == 1)
11628 +               return 0;
11629 +
11630 +       kfree(alloc_stack[alloc_stack_next - 2]);
11631 +
11632 +       alloc_stack_next--;
11633 +
11634 +       return 1;
11635 +}
11636 +
11637 +static __inline__ void
11638 +alloc_push(void *buf)
11639 +{
11640 +       if (alloc_stack_next >= alloc_stack_size)
11641 +               BUG();
11642 +
11643 +       alloc_stack[alloc_stack_next - 1] = buf;
11644 +
11645 +       alloc_stack_next++;
11646 +
11647 +       return;
11648 +}
11649 +
11650 +void *
11651 +acl_alloc(unsigned long len)
11652 +{
11653 +       void *ret;
11654 +
11655 +       if (len > PAGE_SIZE)
11656 +               BUG();
11657 +
11658 +       ret = kmalloc(len, GFP_KERNEL);
11659 +
11660 +       if (ret)
11661 +               alloc_push(ret);
11662 +
11663 +       return ret;
11664 +}
11665 +
11666 +void
11667 +acl_free_all(void)
11668 +{
11669 +       if (gr_acl_is_enabled() || !alloc_stack)
11670 +               return;
11671 +
11672 +       while (alloc_pop()) ;
11673 +
11674 +       if (alloc_stack) {
11675 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
11676 +                       kfree(alloc_stack);
11677 +               else
11678 +                       vfree(alloc_stack);
11679 +       }
11680 +
11681 +       alloc_stack = NULL;
11682 +       alloc_stack_size = 1;
11683 +       alloc_stack_next = 1;
11684 +
11685 +       return;
11686 +}
11687 +
11688 +int
11689 +acl_alloc_stack_init(unsigned long size)
11690 +{
11691 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
11692 +               alloc_stack =
11693 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
11694 +       else
11695 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
11696 +
11697 +       alloc_stack_size = size;
11698 +
11699 +       if (!alloc_stack)
11700 +               return 0;
11701 +       else
11702 +               return 1;
11703 +}
11704 diff -urNp linux-2.6.18/grsecurity/gracl.c linux-2.6.18/grsecurity/gracl.c
11705 --- linux-2.6.18/grsecurity/gracl.c     1969-12-31 19:00:00.000000000 -0500
11706 +++ linux-2.6.18/grsecurity/gracl.c     2006-09-22 20:04:35.000000000 -0400
11707 @@ -0,0 +1,3547 @@
11708 +#include <linux/kernel.h>
11709 +#include <linux/module.h>
11710 +#include <linux/sched.h>
11711 +#include <linux/mm.h>
11712 +#include <linux/file.h>
11713 +#include <linux/fs.h>
11714 +#include <linux/namei.h>
11715 +#include <linux/mount.h>
11716 +#include <linux/tty.h>
11717 +#include <linux/proc_fs.h>
11718 +#include <linux/smp_lock.h>
11719 +#include <linux/slab.h>
11720 +#include <linux/vmalloc.h>
11721 +#include <linux/types.h>
11722 +#include <linux/capability.h>
11723 +#include <linux/sysctl.h>
11724 +#include <linux/netdevice.h>
11725 +#include <linux/ptrace.h>
11726 +#include <linux/gracl.h>
11727 +#include <linux/gralloc.h>
11728 +#include <linux/grsecurity.h>
11729 +#include <linux/grinternal.h>
11730 +#include <linux/percpu.h>
11731 +
11732 +#include <asm/uaccess.h>
11733 +#include <asm/errno.h>
11734 +#include <asm/mman.h>
11735 +
11736 +static struct acl_role_db acl_role_set;
11737 +static struct name_db name_set;
11738 +static struct inodev_db inodev_set;
11739 +
11740 +/* for keeping track of userspace pointers used for subjects, so we
11741 +   can share references in the kernel as well
11742 +*/
11743 +
11744 +static struct dentry *real_root;
11745 +static struct vfsmount *real_root_mnt;
11746 +
11747 +static struct acl_subj_map_db subj_map_set;
11748 +
11749 +static struct acl_role_label *default_role;
11750 +
11751 +static u16 acl_sp_role_value;
11752 +
11753 +extern char *gr_shared_page[4];
11754 +static DECLARE_MUTEX(gr_dev_sem);
11755 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
11756 +
11757 +struct gr_arg *gr_usermode;
11758 +
11759 +static unsigned int gr_status = GR_STATUS_INIT;
11760 +
11761 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
11762 +extern void gr_clear_learn_entries(void);
11763 +
11764 +#ifdef CONFIG_GRKERNSEC_RESLOG
11765 +extern void gr_log_resource(const struct task_struct *task,
11766 +                           const int res, const unsigned long wanted, const int gt);
11767 +#endif
11768 +
11769 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
11770 +                        struct dentry *root, struct vfsmount *rootmnt,
11771 +                        char *buffer, int buflen);
11772 +
11773 +unsigned char *gr_system_salt;
11774 +unsigned char *gr_system_sum;
11775 +
11776 +static struct sprole_pw **acl_special_roles = NULL;
11777 +static __u16 num_sprole_pws = 0;
11778 +
11779 +static struct acl_role_label *kernel_role = NULL;
11780 +
11781 +static unsigned int gr_auth_attempts = 0;
11782 +static unsigned long gr_auth_expires = 0UL;
11783 +
11784 +extern struct vfsmount *sock_mnt;
11785 +extern struct vfsmount *pipe_mnt;
11786 +extern struct vfsmount *shm_mnt;
11787 +static struct acl_object_label *fakefs_obj;
11788 +
11789 +extern int gr_init_uidset(void);
11790 +extern void gr_free_uidset(void);
11791 +extern void gr_remove_uid(uid_t uid);
11792 +extern int gr_find_uid(uid_t uid);
11793 +
11794 +__inline__ int
11795 +gr_acl_is_enabled(void)
11796 +{
11797 +       return (gr_status & GR_READY);
11798 +}
11799 +
11800 +char gr_roletype_to_char(void)
11801 +{
11802 +       switch (current->role->roletype &
11803 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
11804 +                GR_ROLE_SPECIAL)) {
11805 +       case GR_ROLE_DEFAULT:
11806 +               return 'D';
11807 +       case GR_ROLE_USER:
11808 +               return 'U';
11809 +       case GR_ROLE_GROUP:
11810 +               return 'G';
11811 +       case GR_ROLE_SPECIAL:
11812 +               return 'S';
11813 +       }
11814 +
11815 +       return 'X';
11816 +}
11817 +
11818 +__inline__ int
11819 +gr_acl_tpe_check(void)
11820 +{
11821 +       if (unlikely(!(gr_status & GR_READY)))
11822 +               return 0;
11823 +       if (current->role->roletype & GR_ROLE_TPE)
11824 +               return 1;
11825 +       else
11826 +               return 0;
11827 +}
11828 +
11829 +int
11830 +gr_handle_rawio(const struct inode *inode)
11831 +{
11832 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11833 +       if (inode && S_ISBLK(inode->i_mode) &&
11834 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
11835 +           !capable(CAP_SYS_RAWIO))
11836 +               return 1;
11837 +#endif
11838 +       return 0;
11839 +}
11840 +
11841 +static int
11842 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
11843 +{
11844 +       int i;
11845 +       unsigned long *l1;
11846 +       unsigned long *l2;
11847 +       unsigned char *c1;
11848 +       unsigned char *c2;
11849 +       int num_longs;
11850 +
11851 +       if (likely(lena != lenb))
11852 +               return 0;
11853 +
11854 +       l1 = (unsigned long *)a;
11855 +       l2 = (unsigned long *)b;
11856 +
11857 +       num_longs = lena / sizeof(unsigned long);
11858 +
11859 +       for (i = num_longs; i--; l1++, l2++) {
11860 +               if (unlikely(*l1 != *l2))
11861 +                       return 0;
11862 +       }
11863 +
11864 +       c1 = (unsigned char *) l1;
11865 +       c2 = (unsigned char *) l2;
11866 +
11867 +       i = lena - (num_longs * sizeof(unsigned long)); 
11868 +
11869 +       for (; i--; c1++, c2++) {
11870 +               if (unlikely(*c1 != *c2))
11871 +                       return 0;
11872 +       }
11873 +
11874 +       return 1;
11875 +}
11876 +               
11877 +static char *
11878 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
11879 +              struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
11880 +{
11881 +       char *end = buf + buflen;
11882 +       char *retval;
11883 +       int namelen = 0;
11884 +
11885 +       *--end = '\0';
11886 +
11887 +       retval = end - 1;
11888 +       *retval = '/';
11889 +
11890 +       if (dentry == root && vfsmnt == rootmnt)
11891 +               return retval;
11892 +       if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
11893 +               namelen = strlen(dentry->d_name.name);
11894 +               buflen -= namelen;
11895 +               if (buflen < 2)
11896 +                       goto err;
11897 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
11898 +                       buflen--;
11899 +       }
11900 +
11901 +       retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
11902 +       if (unlikely(IS_ERR(retval)))
11903 +err:
11904 +               retval = strcpy(buf, "<path too long>");
11905 +       else if (namelen != 0) {
11906 +               end = buf + buflen - 1; // accounts for null termination
11907 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
11908 +                       *end++ = '/'; // accounted for above with buflen--
11909 +               memcpy(end, dentry->d_name.name, namelen);
11910 +       }
11911 +
11912 +       return retval;
11913 +}
11914 +
11915 +static char *
11916 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
11917 +               char *buf, int buflen)
11918 +{
11919 +       char *res;
11920 +
11921 +       /* we can use real_root, real_root_mnt, because this is only called
11922 +          by the RBAC system */
11923 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
11924 +
11925 +       return res;
11926 +}
11927 +
11928 +static char *
11929 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
11930 +           char *buf, int buflen)
11931 +{
11932 +       char *res;
11933 +       struct dentry *root;
11934 +       struct vfsmount *rootmnt;
11935 +
11936 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
11937 +       read_lock(&child_reaper->fs->lock);
11938 +       root = dget(child_reaper->fs->root);
11939 +       rootmnt = mntget(child_reaper->fs->rootmnt);
11940 +       read_unlock(&child_reaper->fs->lock);
11941 +
11942 +       spin_lock(&dcache_lock);
11943 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
11944 +       spin_unlock(&dcache_lock);
11945 +
11946 +       dput(root);
11947 +       mntput(rootmnt);
11948 +       return res;
11949 +}
11950 +
11951 +static char *
11952 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
11953 +{
11954 +       char *ret;
11955 +       spin_lock(&dcache_lock);
11956 +       ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
11957 +                            PAGE_SIZE);
11958 +       spin_unlock(&dcache_lock);
11959 +       return ret;
11960 +}
11961 +
11962 +char *
11963 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
11964 +{
11965 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
11966 +                            PAGE_SIZE);
11967 +}
11968 +
11969 +char *
11970 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
11971 +{
11972 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
11973 +                          PAGE_SIZE);
11974 +}
11975 +
11976 +char *
11977 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
11978 +{
11979 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
11980 +                          PAGE_SIZE);
11981 +}
11982 +
11983 +char *
11984 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
11985 +{
11986 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
11987 +                          PAGE_SIZE);
11988 +}
11989 +
11990 +char *
11991 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
11992 +{
11993 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
11994 +                          PAGE_SIZE);
11995 +}
11996 +
11997 +__inline__ __u32
11998 +to_gr_audit(const __u32 reqmode)
11999 +{
12000 +       /* masks off auditable permission flags, then shifts them to create
12001 +          auditing flags, and adds the special case of append auditing if
12002 +          we're requesting write */
12003 +       return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
12004 +}
12005 +
12006 +struct acl_subject_label *
12007 +lookup_subject_map(const struct acl_subject_label *userp)
12008 +{
12009 +       unsigned int index = shash(userp, subj_map_set.s_size);
12010 +       struct subject_map *match;
12011 +
12012 +       match = subj_map_set.s_hash[index];
12013 +
12014 +       while (match && match->user != userp)
12015 +               match = match->next;
12016 +
12017 +       if (match != NULL)
12018 +               return match->kernel;
12019 +       else
12020 +               return NULL;
12021 +}
12022 +
12023 +static void
12024 +insert_subj_map_entry(struct subject_map *subjmap)
12025 +{
12026 +       unsigned int index = shash(subjmap->user, subj_map_set.s_size);
12027 +       struct subject_map **curr;
12028 +
12029 +       subjmap->prev = NULL;
12030 +
12031 +       curr = &subj_map_set.s_hash[index];
12032 +       if (*curr != NULL)
12033 +               (*curr)->prev = subjmap;
12034 +
12035 +       subjmap->next = *curr;
12036 +       *curr = subjmap;
12037 +
12038 +       return;
12039 +}
12040 +
12041 +static struct acl_role_label *
12042 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
12043 +                     const gid_t gid)
12044 +{
12045 +       unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
12046 +       struct acl_role_label *match;
12047 +       struct role_allowed_ip *ipp;
12048 +       unsigned int x;
12049 +
12050 +       match = acl_role_set.r_hash[index];
12051 +
12052 +       while (match) {
12053 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
12054 +                       for (x = 0; x < match->domain_child_num; x++) {
12055 +                               if (match->domain_children[x] == uid)
12056 +                                       goto found;
12057 +                       }
12058 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
12059 +                       break;
12060 +               match = match->next;
12061 +       }
12062 +found:
12063 +       if (match == NULL) {
12064 +             try_group:
12065 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
12066 +               match = acl_role_set.r_hash[index];
12067 +
12068 +               while (match) {
12069 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
12070 +                               for (x = 0; x < match->domain_child_num; x++) {
12071 +                                       if (match->domain_children[x] == gid)
12072 +                                               goto found2;
12073 +                               }
12074 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
12075 +                               break;
12076 +                       match = match->next;
12077 +               }
12078 +found2:
12079 +               if (match == NULL)
12080 +                       match = default_role;
12081 +               if (match->allowed_ips == NULL)
12082 +                       return match;
12083 +               else {
12084 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
12085 +                               if (likely
12086 +                                   ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
12087 +                                    (ntohl(ipp->addr) & ipp->netmask)))
12088 +                                       return match;
12089 +                       }
12090 +                       match = default_role;
12091 +               }
12092 +       } else if (match->allowed_ips == NULL) {
12093 +               return match;
12094 +       } else {
12095 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
12096 +                       if (likely
12097 +                           ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
12098 +                            (ntohl(ipp->addr) & ipp->netmask)))
12099 +                               return match;
12100 +               }
12101 +               goto try_group;
12102 +       }
12103 +
12104 +       return match;
12105 +}
12106 +
12107 +struct acl_subject_label *
12108 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
12109 +                     const struct acl_role_label *role)
12110 +{
12111 +       unsigned int index = fhash(ino, dev, role->subj_hash_size);
12112 +       struct acl_subject_label *match;
12113 +
12114 +       match = role->subj_hash[index];
12115 +
12116 +       while (match && (match->inode != ino || match->device != dev ||
12117 +              (match->mode & GR_DELETED))) {
12118 +               match = match->next;
12119 +       }
12120 +
12121 +       if (match && !(match->mode & GR_DELETED))
12122 +               return match;
12123 +       else
12124 +               return NULL;
12125 +}
12126 +
12127 +static struct acl_object_label *
12128 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
12129 +                    const struct acl_subject_label *subj)
12130 +{
12131 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
12132 +       struct acl_object_label *match;
12133 +
12134 +       match = subj->obj_hash[index];
12135 +
12136 +       while (match && (match->inode != ino || match->device != dev ||
12137 +              (match->mode & GR_DELETED))) {
12138 +               match = match->next;
12139 +       }
12140 +
12141 +       if (match && !(match->mode & GR_DELETED))
12142 +               return match;
12143 +       else
12144 +               return NULL;
12145 +}
12146 +
12147 +static struct acl_object_label *
12148 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
12149 +                    const struct acl_subject_label *subj)
12150 +{
12151 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
12152 +       struct acl_object_label *match;
12153 +
12154 +       match = subj->obj_hash[index];
12155 +
12156 +       while (match && (match->inode != ino || match->device != dev ||
12157 +              !(match->mode & GR_DELETED))) {
12158 +               match = match->next;
12159 +       }
12160 +
12161 +       if (match && (match->mode & GR_DELETED))
12162 +               return match;
12163 +
12164 +       match = subj->obj_hash[index];
12165 +
12166 +       while (match && (match->inode != ino || match->device != dev ||
12167 +              (match->mode & GR_DELETED))) {
12168 +               match = match->next;
12169 +       }
12170 +
12171 +       if (match && !(match->mode & GR_DELETED))
12172 +               return match;
12173 +       else
12174 +               return NULL;
12175 +}
12176 +
12177 +static struct name_entry *
12178 +lookup_name_entry(const char *name)
12179 +{
12180 +       unsigned int len = strlen(name);
12181 +       unsigned int key = full_name_hash(name, len);
12182 +       unsigned int index = key % name_set.n_size;
12183 +       struct name_entry *match;
12184 +
12185 +       match = name_set.n_hash[index];
12186 +
12187 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
12188 +               match = match->next;
12189 +
12190 +       return match;
12191 +}
12192 +
12193 +static struct inodev_entry *
12194 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
12195 +{
12196 +       unsigned int index = fhash(ino, dev, inodev_set.i_size);
12197 +       struct inodev_entry *match;
12198 +
12199 +       match = inodev_set.i_hash[index];
12200 +
12201 +       while (match && (match->nentry->inode != ino || match->nentry->device != dev))
12202 +               match = match->next;
12203 +
12204 +       return match;
12205 +}
12206 +
12207 +static void
12208 +insert_inodev_entry(struct inodev_entry *entry)
12209 +{
12210 +       unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
12211 +                                   inodev_set.i_size);
12212 +       struct inodev_entry **curr;
12213 +
12214 +       entry->prev = NULL;
12215 +
12216 +       curr = &inodev_set.i_hash[index];
12217 +       if (*curr != NULL)
12218 +               (*curr)->prev = entry;
12219 +       
12220 +       entry->next = *curr;
12221 +       *curr = entry;
12222 +
12223 +       return;
12224 +}
12225 +
12226 +static void
12227 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
12228 +{
12229 +       unsigned int index =
12230 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
12231 +       struct acl_role_label **curr;
12232 +
12233 +       role->prev = NULL;
12234 +
12235 +       curr = &acl_role_set.r_hash[index];
12236 +       if (*curr != NULL)
12237 +               (*curr)->prev = role;
12238 +
12239 +       role->next = *curr;
12240 +       *curr = role;
12241 +
12242 +       return;
12243 +}
12244 +
12245 +static void
12246 +insert_acl_role_label(struct acl_role_label *role)
12247 +{
12248 +       int i;
12249 +
12250 +       if (role->roletype & GR_ROLE_DOMAIN) {
12251 +               for (i = 0; i < role->domain_child_num; i++)
12252 +                       __insert_acl_role_label(role, role->domain_children[i]);
12253 +       } else
12254 +               __insert_acl_role_label(role, role->uidgid);
12255 +}
12256 +                                       
12257 +static int
12258 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
12259 +{
12260 +       struct name_entry **curr, *nentry;
12261 +       struct inodev_entry *ientry;
12262 +       unsigned int len = strlen(name);
12263 +       unsigned int key = full_name_hash(name, len);
12264 +       unsigned int index = key % name_set.n_size;
12265 +
12266 +       curr = &name_set.n_hash[index];
12267 +
12268 +       while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
12269 +               curr = &((*curr)->next);
12270 +
12271 +       if (*curr != NULL)
12272 +               return 1;
12273 +
12274 +       nentry = acl_alloc(sizeof (struct name_entry));
12275 +       if (nentry == NULL)
12276 +               return 0;
12277 +       ientry = acl_alloc(sizeof (struct inodev_entry));
12278 +       if (ientry == NULL)
12279 +               return 0;
12280 +       ientry->nentry = nentry;
12281 +
12282 +       nentry->key = key;
12283 +       nentry->name = name;
12284 +       nentry->inode = inode;
12285 +       nentry->device = device;
12286 +       nentry->len = len;
12287 +
12288 +       nentry->prev = NULL;
12289 +       curr = &name_set.n_hash[index];
12290 +       if (*curr != NULL)
12291 +               (*curr)->prev = nentry;
12292 +       nentry->next = *curr;
12293 +       *curr = nentry;
12294 +
12295 +       /* insert us into the table searchable by inode/dev */
12296 +       insert_inodev_entry(ientry);
12297 +
12298 +       return 1;
12299 +}
12300 +
12301 +static void
12302 +insert_acl_obj_label(struct acl_object_label *obj,
12303 +                    struct acl_subject_label *subj)
12304 +{
12305 +       unsigned int index =
12306 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
12307 +       struct acl_object_label **curr;
12308 +
12309 +       
12310 +       obj->prev = NULL;
12311 +
12312 +       curr = &subj->obj_hash[index];
12313 +       if (*curr != NULL)
12314 +               (*curr)->prev = obj;
12315 +
12316 +       obj->next = *curr;
12317 +       *curr = obj;
12318 +
12319 +       return;
12320 +}
12321 +
12322 +static void
12323 +insert_acl_subj_label(struct acl_subject_label *obj,
12324 +                     struct acl_role_label *role)
12325 +{
12326 +       unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
12327 +       struct acl_subject_label **curr;
12328 +
12329 +       obj->prev = NULL;
12330 +
12331 +       curr = &role->subj_hash[index];
12332 +       if (*curr != NULL)
12333 +               (*curr)->prev = obj;
12334 +
12335 +       obj->next = *curr;
12336 +       *curr = obj;
12337 +
12338 +       return;
12339 +}
12340 +
12341 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
12342 +
12343 +static void *
12344 +create_table(__u32 * len, int elementsize)
12345 +{
12346 +       unsigned int table_sizes[] = {
12347 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
12348 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
12349 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
12350 +               268435399, 536870909, 1073741789, 2147483647
12351 +       };
12352 +       void *newtable = NULL;
12353 +       unsigned int pwr = 0;
12354 +
12355 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
12356 +              table_sizes[pwr] <= *len)
12357 +               pwr++;
12358 +
12359 +       if (table_sizes[pwr] <= *len)
12360 +               return newtable;
12361 +
12362 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
12363 +               newtable =
12364 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
12365 +       else
12366 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
12367 +
12368 +       *len = table_sizes[pwr];
12369 +
12370 +       return newtable;
12371 +}
12372 +
12373 +static int
12374 +init_variables(const struct gr_arg *arg)
12375 +{
12376 +       unsigned int stacksize;
12377 +
12378 +       subj_map_set.s_size = arg->role_db.num_subjects;
12379 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
12380 +       name_set.n_size = arg->role_db.num_objects;
12381 +       inodev_set.i_size = arg->role_db.num_objects;
12382 +
12383 +       if (!subj_map_set.s_size || !acl_role_set.r_size ||
12384 +           !name_set.n_size || !inodev_set.i_size)
12385 +               return 1;
12386 +
12387 +       if (!gr_init_uidset())
12388 +               return 1;
12389 +
12390 +       /* set up the stack that holds allocation info */
12391 +
12392 +       stacksize = arg->role_db.num_pointers + 5;
12393 +
12394 +       if (!acl_alloc_stack_init(stacksize))
12395 +               return 1;
12396 +
12397 +       /* grab reference for the real root dentry and vfsmount */
12398 +       read_lock(&child_reaper->fs->lock);
12399 +       real_root_mnt = mntget(child_reaper->fs->rootmnt);
12400 +       real_root = dget(child_reaper->fs->root);
12401 +       read_unlock(&child_reaper->fs->lock);
12402 +       
12403 +       fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
12404 +       if (fakefs_obj == NULL)
12405 +               return 1;
12406 +       fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
12407 +
12408 +       subj_map_set.s_hash =
12409 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
12410 +       acl_role_set.r_hash =
12411 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
12412 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
12413 +       inodev_set.i_hash =
12414 +           (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
12415 +
12416 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
12417 +           !name_set.n_hash || !inodev_set.i_hash)
12418 +               return 1;
12419 +
12420 +       memset(subj_map_set.s_hash, 0,
12421 +              sizeof(struct subject_map *) * subj_map_set.s_size);
12422 +       memset(acl_role_set.r_hash, 0,
12423 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
12424 +       memset(name_set.n_hash, 0,
12425 +              sizeof (struct name_entry *) * name_set.n_size);
12426 +       memset(inodev_set.i_hash, 0,
12427 +              sizeof (struct inodev_entry *) * inodev_set.i_size);
12428 +
12429 +       return 0;
12430 +}
12431 +
12432 +/* free information not needed after startup
12433 +   currently contains user->kernel pointer mappings for subjects
12434 +*/
12435 +
12436 +static void
12437 +free_init_variables(void)
12438 +{
12439 +       __u32 i;
12440 +
12441 +       if (subj_map_set.s_hash) {
12442 +               for (i = 0; i < subj_map_set.s_size; i++) {
12443 +                       if (subj_map_set.s_hash[i]) {
12444 +                               kfree(subj_map_set.s_hash[i]);
12445 +                               subj_map_set.s_hash[i] = NULL;
12446 +                       }
12447 +               }
12448 +
12449 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
12450 +                   PAGE_SIZE)
12451 +                       kfree(subj_map_set.s_hash);
12452 +               else
12453 +                       vfree(subj_map_set.s_hash);
12454 +       }
12455 +
12456 +       return;
12457 +}
12458 +
12459 +static void
12460 +free_variables(void)
12461 +{
12462 +       struct acl_subject_label *s;
12463 +       struct acl_role_label *r;
12464 +       struct task_struct *task, *task2;
12465 +       unsigned int i, x;
12466 +
12467 +       gr_clear_learn_entries();
12468 +
12469 +       read_lock(&tasklist_lock);
12470 +       do_each_thread(task2, task) {
12471 +               task->acl_sp_role = 0;
12472 +               task->acl_role_id = 0;
12473 +               task->acl = NULL;
12474 +               task->role = NULL;
12475 +       } while_each_thread(task2, task);
12476 +       read_unlock(&tasklist_lock);
12477 +
12478 +       /* release the reference to the real root dentry and vfsmount */
12479 +       if (real_root)
12480 +               dput(real_root);
12481 +       real_root = NULL;
12482 +       if (real_root_mnt)
12483 +               mntput(real_root_mnt);
12484 +       real_root_mnt = NULL;
12485 +
12486 +       /* free all object hash tables */
12487 +
12488 +       FOR_EACH_ROLE_START(r, i)
12489 +               if (r->subj_hash == NULL)
12490 +                       break;
12491 +               FOR_EACH_SUBJECT_START(r, s, x)
12492 +                       if (s->obj_hash == NULL)
12493 +                               break;
12494 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
12495 +                               kfree(s->obj_hash);
12496 +                       else
12497 +                               vfree(s->obj_hash);
12498 +               FOR_EACH_SUBJECT_END(s, x)
12499 +               FOR_EACH_NESTED_SUBJECT_START(r, s)
12500 +                       if (s->obj_hash == NULL)
12501 +                               break;
12502 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
12503 +                               kfree(s->obj_hash);
12504 +                       else
12505 +                               vfree(s->obj_hash);
12506 +               FOR_EACH_NESTED_SUBJECT_END(s)
12507 +               if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
12508 +                       kfree(r->subj_hash);
12509 +               else
12510 +                       vfree(r->subj_hash);
12511 +               r->subj_hash = NULL;
12512 +       FOR_EACH_ROLE_END(r,i)
12513 +
12514 +       acl_free_all();
12515 +
12516 +       if (acl_role_set.r_hash) {
12517 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
12518 +                   PAGE_SIZE)
12519 +                       kfree(acl_role_set.r_hash);
12520 +               else
12521 +                       vfree(acl_role_set.r_hash);
12522 +       }
12523 +       if (name_set.n_hash) {
12524 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
12525 +                   PAGE_SIZE)
12526 +                       kfree(name_set.n_hash);
12527 +               else
12528 +                       vfree(name_set.n_hash);
12529 +       }
12530 +
12531 +       if (inodev_set.i_hash) {
12532 +               if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
12533 +                   PAGE_SIZE)
12534 +                       kfree(inodev_set.i_hash);
12535 +               else
12536 +                       vfree(inodev_set.i_hash);
12537 +       }
12538 +
12539 +       gr_free_uidset();
12540 +
12541 +       memset(&name_set, 0, sizeof (struct name_db));
12542 +       memset(&inodev_set, 0, sizeof (struct inodev_db));
12543 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
12544 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
12545 +
12546 +       default_role = NULL;
12547 +
12548 +       return;
12549 +}
12550 +
12551 +static __u32
12552 +count_user_objs(struct acl_object_label *userp)
12553 +{
12554 +       struct acl_object_label o_tmp;
12555 +       __u32 num = 0;
12556 +
12557 +       while (userp) {
12558 +               if (copy_from_user(&o_tmp, userp,
12559 +                                  sizeof (struct acl_object_label)))
12560 +                       break;
12561 +
12562 +               userp = o_tmp.prev;
12563 +               num++;
12564 +       }
12565 +
12566 +       return num;
12567 +}
12568 +
12569 +static struct acl_subject_label *
12570 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
12571 +
12572 +static int
12573 +copy_user_glob(struct acl_object_label *obj)
12574 +{
12575 +       struct acl_object_label *g_tmp, **guser;
12576 +       unsigned int len;
12577 +       char *tmp;
12578 +
12579 +       if (obj->globbed == NULL)
12580 +               return 0;
12581 +
12582 +       guser = &obj->globbed;
12583 +       while (*guser) {
12584 +               g_tmp = (struct acl_object_label *)
12585 +                       acl_alloc(sizeof (struct acl_object_label));
12586 +               if (g_tmp == NULL)
12587 +                       return -ENOMEM;
12588 +
12589 +               if (copy_from_user(g_tmp, *guser,
12590 +                                  sizeof (struct acl_object_label)))
12591 +                       return -EFAULT;
12592 +
12593 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
12594 +
12595 +               if (!len || len >= PATH_MAX)
12596 +                       return -EINVAL;
12597 +
12598 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
12599 +                       return -ENOMEM;
12600 +
12601 +               if (copy_from_user(tmp, g_tmp->filename, len))
12602 +                       return -EFAULT;
12603 +
12604 +               g_tmp->filename = tmp;
12605 +
12606 +               *guser = g_tmp;
12607 +               guser = &(g_tmp->next);
12608 +       }
12609 +
12610 +       return 0;
12611 +}
12612 +
12613 +static int
12614 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
12615 +              struct acl_role_label *role)
12616 +{
12617 +       struct acl_object_label *o_tmp;
12618 +       unsigned int len;
12619 +       int ret;
12620 +       char *tmp;
12621 +
12622 +       while (userp) {
12623 +               if ((o_tmp = (struct acl_object_label *)
12624 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
12625 +                       return -ENOMEM;
12626 +
12627 +               if (copy_from_user(o_tmp, userp,
12628 +                                  sizeof (struct acl_object_label)))
12629 +                       return -EFAULT;
12630 +
12631 +               userp = o_tmp->prev;
12632 +
12633 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
12634 +
12635 +               if (!len || len >= PATH_MAX)
12636 +                       return -EINVAL;
12637 +
12638 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
12639 +                       return -ENOMEM;
12640 +
12641 +               if (copy_from_user(tmp, o_tmp->filename, len))
12642 +                       return -EFAULT;
12643 +
12644 +               o_tmp->filename = tmp;
12645 +
12646 +               insert_acl_obj_label(o_tmp, subj);
12647 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
12648 +                                      o_tmp->device))
12649 +                       return -ENOMEM;
12650 +
12651 +               ret = copy_user_glob(o_tmp);
12652 +               if (ret)
12653 +                       return ret;
12654 +
12655 +               if (o_tmp->nested) {
12656 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
12657 +                       if (IS_ERR(o_tmp->nested))
12658 +                               return PTR_ERR(o_tmp->nested);
12659 +
12660 +                       /* insert into nested subject list */
12661 +                       o_tmp->nested->next = role->hash->first;
12662 +                       role->hash->first = o_tmp->nested;
12663 +               }
12664 +       }
12665 +
12666 +       return 0;
12667 +}
12668 +
12669 +static __u32
12670 +count_user_subjs(struct acl_subject_label *userp)
12671 +{
12672 +       struct acl_subject_label s_tmp;
12673 +       __u32 num = 0;
12674 +
12675 +       while (userp) {
12676 +               if (copy_from_user(&s_tmp, userp,
12677 +                                  sizeof (struct acl_subject_label)))
12678 +                       break;
12679 +
12680 +               userp = s_tmp.prev;
12681 +               /* do not count nested subjects against this count, since
12682 +                  they are not included in the hash table, but are
12683 +                  attached to objects.  We have already counted
12684 +                  the subjects in userspace for the allocation 
12685 +                  stack
12686 +               */
12687 +               if (!(s_tmp.mode & GR_NESTED))
12688 +                       num++;
12689 +       }
12690 +
12691 +       return num;
12692 +}
12693 +
12694 +static int
12695 +copy_user_allowedips(struct acl_role_label *rolep)
12696 +{
12697 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
12698 +
12699 +       ruserip = rolep->allowed_ips;
12700 +
12701 +       while (ruserip) {
12702 +               rlast = rtmp;
12703 +
12704 +               if ((rtmp = (struct role_allowed_ip *)
12705 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
12706 +                       return -ENOMEM;
12707 +
12708 +               if (copy_from_user(rtmp, ruserip,
12709 +                                  sizeof (struct role_allowed_ip)))
12710 +                       return -EFAULT;
12711 +
12712 +               ruserip = rtmp->prev;
12713 +
12714 +               if (!rlast) {
12715 +                       rtmp->prev = NULL;
12716 +                       rolep->allowed_ips = rtmp;
12717 +               } else {
12718 +                       rlast->next = rtmp;
12719 +                       rtmp->prev = rlast;
12720 +               }
12721 +
12722 +               if (!ruserip)
12723 +                       rtmp->next = NULL;
12724 +       }
12725 +
12726 +       return 0;
12727 +}
12728 +
12729 +static int
12730 +copy_user_transitions(struct acl_role_label *rolep)
12731 +{
12732 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
12733 +       
12734 +       unsigned int len;
12735 +       char *tmp;
12736 +
12737 +       rusertp = rolep->transitions;
12738 +
12739 +       while (rusertp) {
12740 +               rlast = rtmp;
12741 +
12742 +               if ((rtmp = (struct role_transition *)
12743 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
12744 +                       return -ENOMEM;
12745 +
12746 +               if (copy_from_user(rtmp, rusertp,
12747 +                                  sizeof (struct role_transition)))
12748 +                       return -EFAULT;
12749 +
12750 +               rusertp = rtmp->prev;
12751 +
12752 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
12753 +
12754 +               if (!len || len >= GR_SPROLE_LEN)
12755 +                       return -EINVAL;
12756 +
12757 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
12758 +                       return -ENOMEM;
12759 +
12760 +               if (copy_from_user(tmp, rtmp->rolename, len))
12761 +                       return -EFAULT;
12762 +
12763 +               rtmp->rolename = tmp;
12764 +
12765 +               if (!rlast) {
12766 +                       rtmp->prev = NULL;
12767 +                       rolep->transitions = rtmp;
12768 +               } else {
12769 +                       rlast->next = rtmp;
12770 +                       rtmp->prev = rlast;
12771 +               }
12772 +
12773 +               if (!rusertp)
12774 +                       rtmp->next = NULL;
12775 +       }
12776 +
12777 +       return 0;
12778 +}
12779 +
12780 +static struct acl_subject_label *
12781 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
12782 +{
12783 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
12784 +       unsigned int len;
12785 +       char *tmp;
12786 +       __u32 num_objs;
12787 +       struct acl_ip_label **i_tmp, *i_utmp2;
12788 +       struct gr_hash_struct ghash;
12789 +       struct subject_map *subjmap;
12790 +       unsigned int i_num;
12791 +       int err;
12792 +
12793 +       s_tmp = lookup_subject_map(userp);
12794 +
12795 +       /* we've already copied this subject into the kernel, just return
12796 +          the reference to it, and don't copy it over again
12797 +       */
12798 +       if (s_tmp)
12799 +               return(s_tmp);
12800 +
12801 +       if ((s_tmp = (struct acl_subject_label *)
12802 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
12803 +               return ERR_PTR(-ENOMEM);
12804 +
12805 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
12806 +       if (subjmap == NULL)
12807 +               return ERR_PTR(-ENOMEM);
12808 +
12809 +       subjmap->user = userp;
12810 +       subjmap->kernel = s_tmp;
12811 +       insert_subj_map_entry(subjmap);
12812 +
12813 +       if (copy_from_user(s_tmp, userp,
12814 +                          sizeof (struct acl_subject_label)))
12815 +               return ERR_PTR(-EFAULT);
12816 +
12817 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
12818 +
12819 +       if (!len || len >= PATH_MAX)
12820 +               return ERR_PTR(-EINVAL);
12821 +
12822 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
12823 +               return ERR_PTR(-ENOMEM);
12824 +
12825 +       if (copy_from_user(tmp, s_tmp->filename, len))
12826 +               return ERR_PTR(-EFAULT);
12827 +
12828 +       s_tmp->filename = tmp;
12829 +
12830 +       if (!strcmp(s_tmp->filename, "/"))
12831 +               role->root_label = s_tmp;
12832 +
12833 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
12834 +               return ERR_PTR(-EFAULT);
12835 +
12836 +       /* copy user and group transition tables */
12837 +
12838 +       if (s_tmp->user_trans_num) {
12839 +               uid_t *uidlist;
12840 +
12841 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
12842 +               if (uidlist == NULL)
12843 +                       return ERR_PTR(-ENOMEM);
12844 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
12845 +                       return ERR_PTR(-EFAULT);
12846 +
12847 +               s_tmp->user_transitions = uidlist;
12848 +       }
12849 +
12850 +       if (s_tmp->group_trans_num) {
12851 +               gid_t *gidlist;
12852 +
12853 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
12854 +               if (gidlist == NULL)
12855 +                       return ERR_PTR(-ENOMEM);
12856 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
12857 +                       return ERR_PTR(-EFAULT);
12858 +
12859 +               s_tmp->group_transitions = gidlist;
12860 +       }
12861 +
12862 +       /* set up object hash table */
12863 +       num_objs = count_user_objs(ghash.first);
12864 +
12865 +       s_tmp->obj_hash_size = num_objs;
12866 +       s_tmp->obj_hash =
12867 +           (struct acl_object_label **)
12868 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
12869 +
12870 +       if (!s_tmp->obj_hash)
12871 +               return ERR_PTR(-ENOMEM);
12872 +
12873 +       memset(s_tmp->obj_hash, 0,
12874 +              s_tmp->obj_hash_size *
12875 +              sizeof (struct acl_object_label *));
12876 +
12877 +       /* add in objects */
12878 +       err = copy_user_objs(ghash.first, s_tmp, role);
12879 +
12880 +       if (err)
12881 +               return ERR_PTR(err);
12882 +
12883 +       /* set pointer for parent subject */
12884 +       if (s_tmp->parent_subject) {
12885 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
12886 +
12887 +               if (IS_ERR(s_tmp2))
12888 +                       return s_tmp2;
12889 +
12890 +               s_tmp->parent_subject = s_tmp2;
12891 +       }
12892 +
12893 +       /* add in ip acls */
12894 +
12895 +       if (!s_tmp->ip_num) {
12896 +               s_tmp->ips = NULL;
12897 +               goto insert;
12898 +       }
12899 +
12900 +       i_tmp =
12901 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
12902 +                                              sizeof (struct
12903 +                                                      acl_ip_label *));
12904 +
12905 +       if (!i_tmp)
12906 +               return ERR_PTR(-ENOMEM);
12907 +
12908 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
12909 +               *(i_tmp + i_num) =
12910 +                   (struct acl_ip_label *)
12911 +                   acl_alloc(sizeof (struct acl_ip_label));
12912 +               if (!*(i_tmp + i_num))
12913 +                       return ERR_PTR(-ENOMEM);
12914 +
12915 +               if (copy_from_user
12916 +                   (&i_utmp2, s_tmp->ips + i_num,
12917 +                    sizeof (struct acl_ip_label *)))
12918 +                       return ERR_PTR(-EFAULT);
12919 +
12920 +               if (copy_from_user
12921 +                   (*(i_tmp + i_num), i_utmp2,
12922 +                    sizeof (struct acl_ip_label)))
12923 +                       return ERR_PTR(-EFAULT);
12924 +               
12925 +               if ((*(i_tmp + i_num))->iface == NULL)
12926 +                       continue;
12927 +
12928 +               len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
12929 +               if (!len || len >= IFNAMSIZ)
12930 +                       return ERR_PTR(-EINVAL);
12931 +               tmp = acl_alloc(len);
12932 +               if (tmp == NULL)
12933 +                       return ERR_PTR(-ENOMEM);
12934 +               if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
12935 +                       return ERR_PTR(-EFAULT);
12936 +               (*(i_tmp + i_num))->iface = tmp;
12937 +       }
12938 +
12939 +       s_tmp->ips = i_tmp;
12940 +
12941 +insert:
12942 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
12943 +                              s_tmp->device))
12944 +               return ERR_PTR(-ENOMEM);
12945 +
12946 +       return s_tmp;
12947 +}
12948 +
12949 +static int
12950 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
12951 +{
12952 +       struct acl_subject_label s_pre;
12953 +       struct acl_subject_label * ret;
12954 +       int err;
12955 +
12956 +       while (userp) {
12957 +               if (copy_from_user(&s_pre, userp,
12958 +                                  sizeof (struct acl_subject_label)))
12959 +                       return -EFAULT;
12960 +               
12961 +               /* do not add nested subjects here, add
12962 +                  while parsing objects
12963 +               */
12964 +
12965 +               if (s_pre.mode & GR_NESTED) {
12966 +                       userp = s_pre.prev;
12967 +                       continue;
12968 +               }
12969 +
12970 +               ret = do_copy_user_subj(userp, role);
12971 +
12972 +               err = PTR_ERR(ret);
12973 +               if (IS_ERR(ret))
12974 +                       return err;
12975 +
12976 +               insert_acl_subj_label(ret, role);
12977 +
12978 +               userp = s_pre.prev;
12979 +       }
12980 +
12981 +       return 0;
12982 +}
12983 +
12984 +static int
12985 +copy_user_acl(struct gr_arg *arg)
12986 +{
12987 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
12988 +       struct sprole_pw *sptmp;
12989 +       struct gr_hash_struct *ghash;
12990 +       uid_t *domainlist;
12991 +       unsigned int r_num;
12992 +       unsigned int len;
12993 +       char *tmp;
12994 +       int err = 0;
12995 +       __u16 i;
12996 +       __u32 num_subjs;
12997 +
12998 +       /* we need a default and kernel role */
12999 +       if (arg->role_db.num_roles < 2)
13000 +               return -EINVAL;
13001 +
13002 +       /* copy special role authentication info from userspace */
13003 +
13004 +       num_sprole_pws = arg->num_sprole_pws;
13005 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
13006 +
13007 +       if (!acl_special_roles) {
13008 +               err = -ENOMEM;
13009 +               goto cleanup;
13010 +       }
13011 +
13012 +       for (i = 0; i < num_sprole_pws; i++) {
13013 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
13014 +               if (!sptmp) {
13015 +                       err = -ENOMEM;
13016 +                       goto cleanup;
13017 +               }
13018 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
13019 +                                  sizeof (struct sprole_pw))) {
13020 +                       err = -EFAULT;
13021 +                       goto cleanup;
13022 +               }
13023 +
13024 +               len =
13025 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
13026 +
13027 +               if (!len || len >= GR_SPROLE_LEN) {
13028 +                       err = -EINVAL;
13029 +                       goto cleanup;
13030 +               }
13031 +
13032 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
13033 +                       err = -ENOMEM;
13034 +                       goto cleanup;
13035 +               }
13036 +
13037 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
13038 +                       err = -EFAULT;
13039 +                       goto cleanup;
13040 +               }
13041 +
13042 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13043 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
13044 +#endif
13045 +               sptmp->rolename = tmp;
13046 +               acl_special_roles[i] = sptmp;
13047 +       }
13048 +
13049 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
13050 +
13051 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
13052 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
13053 +
13054 +               if (!r_tmp) {
13055 +                       err = -ENOMEM;
13056 +                       goto cleanup;
13057 +               }
13058 +
13059 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
13060 +                                  sizeof (struct acl_role_label *))) {
13061 +                       err = -EFAULT;
13062 +                       goto cleanup;
13063 +               }
13064 +
13065 +               if (copy_from_user(r_tmp, r_utmp2,
13066 +                                  sizeof (struct acl_role_label))) {
13067 +                       err = -EFAULT;
13068 +                       goto cleanup;
13069 +               }
13070 +
13071 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
13072 +
13073 +               if (!len || len >= PATH_MAX) {
13074 +                       err = -EINVAL;
13075 +                       goto cleanup;
13076 +               }
13077 +
13078 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
13079 +                       err = -ENOMEM;
13080 +                       goto cleanup;
13081 +               }
13082 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
13083 +                       err = -EFAULT;
13084 +                       goto cleanup;
13085 +               }
13086 +               r_tmp->rolename = tmp;
13087 +
13088 +               if (!strcmp(r_tmp->rolename, "default")
13089 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
13090 +                       default_role = r_tmp;
13091 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
13092 +                       kernel_role = r_tmp;
13093 +               }
13094 +
13095 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
13096 +                       err = -ENOMEM;
13097 +                       goto cleanup;
13098 +               }
13099 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
13100 +                       err = -EFAULT;
13101 +                       goto cleanup;
13102 +               }
13103 +
13104 +               r_tmp->hash = ghash;
13105 +
13106 +               num_subjs = count_user_subjs(r_tmp->hash->first);
13107 +
13108 +               r_tmp->subj_hash_size = num_subjs;
13109 +               r_tmp->subj_hash =
13110 +                   (struct acl_subject_label **)
13111 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
13112 +
13113 +               if (!r_tmp->subj_hash) {
13114 +                       err = -ENOMEM;
13115 +                       goto cleanup;
13116 +               }
13117 +
13118 +               err = copy_user_allowedips(r_tmp);
13119 +               if (err)
13120 +                       goto cleanup;
13121 +
13122 +               /* copy domain info */
13123 +               if (r_tmp->domain_children != NULL) {
13124 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
13125 +                       if (domainlist == NULL) {
13126 +                               err = -ENOMEM;
13127 +                               goto cleanup;
13128 +                       }
13129 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
13130 +                               err = -EFAULT;
13131 +                               goto cleanup;
13132 +                       }
13133 +                       r_tmp->domain_children = domainlist;
13134 +               }
13135 +
13136 +               err = copy_user_transitions(r_tmp);
13137 +               if (err)
13138 +                       goto cleanup;
13139 +
13140 +               memset(r_tmp->subj_hash, 0,
13141 +                      r_tmp->subj_hash_size *
13142 +                      sizeof (struct acl_subject_label *));
13143 +
13144 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
13145 +
13146 +               if (err)
13147 +                       goto cleanup;
13148 +
13149 +               /* set nested subject list to null */
13150 +               r_tmp->hash->first = NULL;
13151 +
13152 +               insert_acl_role_label(r_tmp);
13153 +       }
13154 +
13155 +       goto return_err;
13156 +      cleanup:
13157 +       free_variables();
13158 +      return_err:
13159 +       return err;
13160 +
13161 +}
13162 +
13163 +static int
13164 +gracl_init(struct gr_arg *args)
13165 +{
13166 +       int error = 0;
13167 +
13168 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
13169 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
13170 +
13171 +       if (init_variables(args)) {
13172 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
13173 +               error = -ENOMEM;
13174 +               free_variables();
13175 +               goto out;
13176 +       }
13177 +
13178 +       error = copy_user_acl(args);
13179 +       free_init_variables();
13180 +       if (error) {
13181 +               free_variables();
13182 +               goto out;
13183 +       }
13184 +
13185 +       if ((error = gr_set_acls(0))) {
13186 +               free_variables();
13187 +               goto out;
13188 +       }
13189 +
13190 +       gr_status |= GR_READY;
13191 +      out:
13192 +       return error;
13193 +}
13194 +
13195 +/* derived from glibc fnmatch() 0: match, 1: no match*/
13196 +
13197 +static int
13198 +glob_match(const char *p, const char *n)
13199 +{
13200 +       char c;
13201 +
13202 +       while ((c = *p++) != '\0') {
13203 +       switch (c) {
13204 +               case '?':
13205 +                       if (*n == '\0')
13206 +                               return 1;
13207 +                       else if (*n == '/')
13208 +                               return 1;
13209 +                       break;
13210 +               case '\\':
13211 +                       if (*n != c)
13212 +                               return 1;
13213 +                       break;
13214 +               case '*':
13215 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
13216 +                               if (*n == '/')
13217 +                                       return 1;
13218 +                               else if (c == '?') {
13219 +                                       if (*n == '\0')
13220 +                                               return 1;
13221 +                                       else
13222 +                                               ++n;
13223 +                               }
13224 +                       }
13225 +                       if (c == '\0') {
13226 +                               return 0;
13227 +                       } else {
13228 +                               const char *endp;
13229 +
13230 +                               if ((endp = strchr(n, '/')) == NULL)
13231 +                                       endp = n + strlen(n);
13232 +
13233 +                               if (c == '[') {
13234 +                                       for (--p; n < endp; ++n)
13235 +                                               if (!glob_match(p, n))
13236 +                                                       return 0;
13237 +                               } else if (c == '/') {
13238 +                                       while (*n != '\0' && *n != '/')
13239 +                                               ++n;
13240 +                                       if (*n == '/' && !glob_match(p, n + 1))
13241 +                                               return 0;
13242 +                               } else {
13243 +                                       for (--p; n < endp; ++n)
13244 +                                               if (*n == c && !glob_match(p, n))
13245 +                                                       return 0;
13246 +                               }
13247 +
13248 +                               return 1;
13249 +                       }
13250 +               case '[':
13251 +                       {
13252 +                       int not;
13253 +                       char cold;
13254 +
13255 +                       if (*n == '\0' || *n == '/')
13256 +                               return 1;
13257 +
13258 +                       not = (*p == '!' || *p == '^');
13259 +                       if (not)
13260 +                               ++p;
13261 +
13262 +                       c = *p++;
13263 +                       for (;;) {
13264 +                               unsigned char fn = (unsigned char)*n;
13265 +
13266 +                               if (c == '\0')
13267 +                                       return 1;
13268 +                               else {
13269 +                                       if (c == fn)
13270 +                                               goto matched;
13271 +                                       cold = c;
13272 +                                       c = *p++;
13273 +
13274 +                                       if (c == '-' && *p != ']') {
13275 +                                               unsigned char cend = *p++;
13276 +
13277 +                                               if (cend == '\0')
13278 +                                                       return 1;
13279 +
13280 +                                               if (cold <= fn && fn <= cend)
13281 +                                                       goto matched;
13282 +
13283 +                                               c = *p++;
13284 +                                       }
13285 +                               }
13286 +
13287 +                               if (c == ']')
13288 +                                       break;
13289 +                       }
13290 +                       if (!not)
13291 +                               return 1;
13292 +                       break;
13293 +               matched:
13294 +                       while (c != ']') {
13295 +                               if (c == '\0')
13296 +                                       return 1;
13297 +
13298 +                               c = *p++;
13299 +                       }
13300 +                       if (not)
13301 +                               return 1;
13302 +               }
13303 +               break;
13304 +       default:
13305 +               if (c != *n)
13306 +                       return 1;
13307 +       }
13308 +
13309 +       ++n;
13310 +       }
13311 +
13312 +       if (*n == '\0')
13313 +               return 0;
13314 +
13315 +       if (*n == '/')
13316 +               return 0;
13317 +
13318 +       return 1;
13319 +}
13320 +
13321 +static struct acl_object_label *
13322 +chk_glob_label(struct acl_object_label *globbed,
13323 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
13324 +{
13325 +       struct acl_object_label *tmp;
13326 +
13327 +       if (*path == NULL)
13328 +               *path = gr_to_filename_nolock(dentry, mnt);
13329 +
13330 +       tmp = globbed;
13331 +
13332 +       while (tmp) {
13333 +               if (!glob_match(tmp->filename, *path))
13334 +                       return tmp;
13335 +               tmp = tmp->next;
13336 +       }
13337 +
13338 +       return NULL;
13339 +}
13340 +
13341 +static struct acl_object_label *
13342 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
13343 +           const ino_t curr_ino, const dev_t curr_dev,
13344 +           const struct acl_subject_label *subj, char **path)
13345 +{
13346 +       struct acl_subject_label *tmpsubj;
13347 +       struct acl_object_label *retval;
13348 +       struct acl_object_label *retval2;
13349 +
13350 +       tmpsubj = (struct acl_subject_label *) subj;
13351 +       read_lock(&gr_inode_lock);
13352 +       do {
13353 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
13354 +               if (retval) {
13355 +                       if (retval->globbed) {
13356 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
13357 +                                               (struct vfsmount *)orig_mnt, path);
13358 +                               if (retval2)
13359 +                                       retval = retval2;
13360 +                       }
13361 +                       break;
13362 +               }
13363 +       } while ((tmpsubj = tmpsubj->parent_subject));
13364 +       read_unlock(&gr_inode_lock);
13365 +
13366 +       return retval;
13367 +}
13368 +
13369 +static __inline__ struct acl_object_label *
13370 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
13371 +           const struct dentry *curr_dentry,
13372 +           const struct acl_subject_label *subj, char **path)
13373 +{
13374 +       return __full_lookup(orig_dentry, orig_mnt,
13375 +                            curr_dentry->d_inode->i_ino, 
13376 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
13377 +}
13378 +
13379 +static struct acl_object_label *
13380 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
13381 +             const struct acl_subject_label *subj, char *path)
13382 +{
13383 +       struct dentry *dentry = (struct dentry *) l_dentry;
13384 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
13385 +       struct acl_object_label *retval;
13386 +
13387 +       spin_lock(&dcache_lock);
13388 +
13389 +       if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt)) {
13390 +               retval = fakefs_obj;
13391 +               goto out;
13392 +       }
13393 +
13394 +       for (;;) {
13395 +               if (dentry == real_root && mnt == real_root_mnt)
13396 +                       break;
13397 +
13398 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
13399 +                       if (mnt->mnt_parent == mnt)
13400 +                               break;
13401 +
13402 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
13403 +                       if (retval != NULL)
13404 +                               goto out;
13405 +
13406 +                       dentry = mnt->mnt_mountpoint;
13407 +                       mnt = mnt->mnt_parent;
13408 +                       continue;
13409 +               }
13410 +
13411 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
13412 +               if (retval != NULL)
13413 +                       goto out;
13414 +
13415 +               dentry = dentry->d_parent;
13416 +       }
13417 +
13418 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
13419 +
13420 +       if (retval == NULL)
13421 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
13422 +out:
13423 +       spin_unlock(&dcache_lock);
13424 +       return retval;
13425 +}
13426 +
13427 +static __inline__ struct acl_object_label *
13428 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
13429 +             const struct acl_subject_label *subj)
13430 +{
13431 +       char *path = NULL;
13432 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
13433 +}
13434 +
13435 +static __inline__ struct acl_object_label *
13436 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
13437 +                    const struct acl_subject_label *subj, char *path)
13438 +{
13439 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
13440 +}
13441 +
13442 +static struct acl_subject_label *
13443 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
13444 +              const struct acl_role_label *role)
13445 +{
13446 +       struct dentry *dentry = (struct dentry *) l_dentry;
13447 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
13448 +       struct acl_subject_label *retval;
13449 +
13450 +       spin_lock(&dcache_lock);
13451 +
13452 +       for (;;) {
13453 +               if (dentry == real_root && mnt == real_root_mnt)
13454 +                       break;
13455 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
13456 +                       if (mnt->mnt_parent == mnt)
13457 +                               break;
13458 +
13459 +                       read_lock(&gr_inode_lock);
13460 +                       retval =
13461 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
13462 +                                               dentry->d_inode->i_sb->s_dev, role);
13463 +                       read_unlock(&gr_inode_lock);
13464 +                       if (retval != NULL)
13465 +                               goto out;
13466 +
13467 +                       dentry = mnt->mnt_mountpoint;
13468 +                       mnt = mnt->mnt_parent;
13469 +                       continue;
13470 +               }
13471 +
13472 +               read_lock(&gr_inode_lock);
13473 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
13474 +                                         dentry->d_inode->i_sb->s_dev, role);
13475 +               read_unlock(&gr_inode_lock);
13476 +               if (retval != NULL)
13477 +                       goto out;
13478 +
13479 +               dentry = dentry->d_parent;
13480 +       }
13481 +
13482 +       read_lock(&gr_inode_lock);
13483 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
13484 +                                 dentry->d_inode->i_sb->s_dev, role);
13485 +       read_unlock(&gr_inode_lock);
13486 +
13487 +       if (unlikely(retval == NULL)) {
13488 +               read_lock(&gr_inode_lock);
13489 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
13490 +                                         real_root->d_inode->i_sb->s_dev, role);
13491 +               read_unlock(&gr_inode_lock);
13492 +       }
13493 +out:
13494 +       spin_unlock(&dcache_lock);
13495 +
13496 +       return retval;
13497 +}
13498 +
13499 +static void
13500 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
13501 +{
13502 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
13503 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
13504 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
13505 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
13506 +
13507 +       return;
13508 +}
13509 +
13510 +static void
13511 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
13512 +                      const unsigned int effective, const unsigned int fs)
13513 +{
13514 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
13515 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
13516 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
13517 +                      type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
13518 +
13519 +       return;
13520 +}
13521 +
13522 +__u32
13523 +gr_check_link(const struct dentry * new_dentry,
13524 +             const struct dentry * parent_dentry,
13525 +             const struct vfsmount * parent_mnt,
13526 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
13527 +{
13528 +       struct acl_object_label *obj;
13529 +       __u32 oldmode, newmode;
13530 +       __u32 needmode;
13531 +
13532 +       if (unlikely(!(gr_status & GR_READY)))
13533 +               return (GR_CREATE | GR_LINK);
13534 +
13535 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
13536 +       oldmode = obj->mode;
13537 +
13538 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
13539 +               oldmode |= (GR_CREATE | GR_LINK);
13540 +
13541 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
13542 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
13543 +               needmode |= GR_SETID | GR_AUDIT_SETID;
13544 +
13545 +       newmode =
13546 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
13547 +                           oldmode | needmode);
13548 +
13549 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
13550 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
13551 +                             GR_INHERIT | GR_AUDIT_INHERIT);
13552 +
13553 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
13554 +               goto bad;
13555 +
13556 +       if ((oldmode & needmode) != needmode)
13557 +               goto bad;
13558 +
13559 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
13560 +       if ((newmode & needmode) != needmode)
13561 +               goto bad;
13562 +
13563 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
13564 +               return newmode;
13565 +bad:
13566 +       needmode = oldmode;
13567 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
13568 +               needmode |= GR_SETID;
13569 +       
13570 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
13571 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
13572 +               return (GR_CREATE | GR_LINK);
13573 +       } else if (newmode & GR_SUPPRESS)
13574 +               return GR_SUPPRESS;
13575 +       else
13576 +               return 0;
13577 +}
13578 +
13579 +__u32
13580 +gr_search_file(const struct dentry * dentry, const __u32 mode,
13581 +              const struct vfsmount * mnt)
13582 +{
13583 +       __u32 retval = mode;
13584 +       struct acl_subject_label *curracl;
13585 +       struct acl_object_label *currobj;
13586 +
13587 +       if (unlikely(!(gr_status & GR_READY)))
13588 +               return (mode & ~GR_AUDITS);
13589 +
13590 +       curracl = current->acl;
13591 +
13592 +       currobj = chk_obj_label(dentry, mnt, curracl);
13593 +       retval = currobj->mode & mode;
13594 +
13595 +       if (unlikely
13596 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
13597 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
13598 +               __u32 new_mode = mode;
13599 +
13600 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
13601 +
13602 +               retval = new_mode;
13603 +
13604 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
13605 +                       new_mode |= GR_INHERIT;
13606 +
13607 +               if (!(mode & GR_NOLEARN))
13608 +                       gr_log_learn(current, dentry, mnt, new_mode);
13609 +       }
13610 +
13611 +       return retval;
13612 +}
13613 +
13614 +__u32
13615 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
13616 +               const struct vfsmount * mnt, const __u32 mode)
13617 +{
13618 +       struct name_entry *match;
13619 +       struct acl_object_label *matchpo;
13620 +       struct acl_subject_label *curracl;
13621 +       char *path;
13622 +       __u32 retval;
13623 +
13624 +       if (unlikely(!(gr_status & GR_READY)))
13625 +               return (mode & ~GR_AUDITS);
13626 +
13627 +       preempt_disable();
13628 +       path = gr_to_filename_rbac(new_dentry, mnt);
13629 +       match = lookup_name_entry(path);
13630 +
13631 +       if (!match)
13632 +               goto check_parent;
13633 +
13634 +       curracl = current->acl;
13635 +
13636 +       read_lock(&gr_inode_lock);
13637 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
13638 +       read_unlock(&gr_inode_lock);
13639 +
13640 +       if (matchpo) {
13641 +               if ((matchpo->mode & mode) !=
13642 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
13643 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
13644 +                       __u32 new_mode = mode;
13645 +
13646 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
13647 +
13648 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
13649 +
13650 +                       preempt_enable();
13651 +                       return new_mode;
13652 +               }
13653 +               preempt_enable();
13654 +               return (matchpo->mode & mode);
13655 +       }
13656 +
13657 +      check_parent:
13658 +       curracl = current->acl;
13659 +
13660 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
13661 +       retval = matchpo->mode & mode;
13662 +
13663 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
13664 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
13665 +               __u32 new_mode = mode;
13666 +
13667 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
13668 +
13669 +               gr_log_learn(current, new_dentry, mnt, new_mode);
13670 +               preempt_enable();
13671 +               return new_mode;
13672 +       }
13673 +
13674 +       preempt_enable();
13675 +       return retval;
13676 +}
13677 +
13678 +int
13679 +gr_check_hidden_task(const struct task_struct *task)
13680 +{
13681 +       if (unlikely(!(gr_status & GR_READY)))
13682 +               return 0;
13683 +
13684 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
13685 +               return 1;
13686 +
13687 +       return 0;
13688 +}
13689 +
13690 +int
13691 +gr_check_protected_task(const struct task_struct *task)
13692 +{
13693 +       if (unlikely(!(gr_status & GR_READY) || !task))
13694 +               return 0;
13695 +
13696 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
13697 +           task->acl != current->acl)
13698 +               return 1;
13699 +
13700 +       return 0;
13701 +}
13702 +
13703 +void
13704 +gr_copy_label(struct task_struct *tsk)
13705 +{
13706 +       tsk->signal->used_accept = 0;
13707 +       tsk->acl_sp_role = 0;
13708 +       tsk->acl_role_id = current->acl_role_id;
13709 +       tsk->acl = current->acl;
13710 +       tsk->role = current->role;
13711 +       tsk->signal->curr_ip = current->signal->curr_ip;
13712 +       if (current->exec_file)
13713 +               get_file(current->exec_file);
13714 +       tsk->exec_file = current->exec_file;
13715 +       tsk->is_writable = current->is_writable;
13716 +       if (unlikely(current->signal->used_accept))
13717 +               current->signal->curr_ip = 0;
13718 +
13719 +       return;
13720 +}
13721 +
13722 +static void
13723 +gr_set_proc_res(struct task_struct *task)
13724 +{
13725 +       struct acl_subject_label *proc;
13726 +       unsigned short i;
13727 +
13728 +       proc = task->acl;
13729 +
13730 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
13731 +               return;
13732 +
13733 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
13734 +               if (!(proc->resmask & (1 << i)))
13735 +                       continue;
13736 +
13737 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
13738 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
13739 +       }
13740 +
13741 +       return;
13742 +}
13743 +
13744 +int
13745 +gr_check_user_change(int real, int effective, int fs)
13746 +{
13747 +       unsigned int i;
13748 +       __u16 num;
13749 +       uid_t *uidlist;
13750 +       int curuid;
13751 +       int realok = 0;
13752 +       int effectiveok = 0;
13753 +       int fsok = 0;
13754 +
13755 +       if (unlikely(!(gr_status & GR_READY)))
13756 +               return 0;
13757 +
13758 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
13759 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
13760 +
13761 +       num = current->acl->user_trans_num;
13762 +       uidlist = current->acl->user_transitions;
13763 +
13764 +       if (uidlist == NULL)
13765 +               return 0;
13766 +
13767 +       if (real == -1)
13768 +               realok = 1;
13769 +       if (effective == -1)
13770 +               effectiveok = 1;
13771 +       if (fs == -1)
13772 +               fsok = 1;
13773 +
13774 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
13775 +               for (i = 0; i < num; i++) {
13776 +                       curuid = (int)uidlist[i];
13777 +                       if (real == curuid)
13778 +                               realok = 1;
13779 +                       if (effective == curuid)
13780 +                               effectiveok = 1;
13781 +                       if (fs == curuid)
13782 +                               fsok = 1;
13783 +               }
13784 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
13785 +               for (i = 0; i < num; i++) {
13786 +                       curuid = (int)uidlist[i];
13787 +                       if (real == curuid)
13788 +                               break;
13789 +                       if (effective == curuid)
13790 +                               break;
13791 +                       if (fs == curuid)
13792 +                               break;
13793 +               }
13794 +               /* not in deny list */
13795 +               if (i == num) {
13796 +                       realok = 1;
13797 +                       effectiveok = 1;
13798 +                       fsok = 1;
13799 +               }
13800 +       }
13801 +
13802 +       if (realok && effectiveok && fsok)
13803 +               return 0;
13804 +       else {
13805 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
13806 +               return 1;
13807 +       }
13808 +}
13809 +
13810 +int
13811 +gr_check_group_change(int real, int effective, int fs)
13812 +{
13813 +       unsigned int i;
13814 +       __u16 num;
13815 +       gid_t *gidlist;
13816 +       int curgid;
13817 +       int realok = 0;
13818 +       int effectiveok = 0;
13819 +       int fsok = 0;
13820 +
13821 +       if (unlikely(!(gr_status & GR_READY)))
13822 +               return 0;
13823 +
13824 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
13825 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
13826 +
13827 +       num = current->acl->group_trans_num;
13828 +       gidlist = current->acl->group_transitions;
13829 +
13830 +       if (gidlist == NULL)
13831 +               return 0;
13832 +
13833 +       if (real == -1)
13834 +               realok = 1;
13835 +       if (effective == -1)
13836 +               effectiveok = 1;
13837 +       if (fs == -1)
13838 +               fsok = 1;
13839 +
13840 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
13841 +               for (i = 0; i < num; i++) {
13842 +                       curgid = (int)gidlist[i];
13843 +                       if (real == curgid)
13844 +                               realok = 1;
13845 +                       if (effective == curgid)
13846 +                               effectiveok = 1;
13847 +                       if (fs == curgid)
13848 +                               fsok = 1;
13849 +               }
13850 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
13851 +               for (i = 0; i < num; i++) {
13852 +                       curgid = (int)gidlist[i];
13853 +                       if (real == curgid)
13854 +                               break;
13855 +                       if (effective == curgid)
13856 +                               break;
13857 +                       if (fs == curgid)
13858 +                               break;
13859 +               }
13860 +               /* not in deny list */
13861 +               if (i == num) {
13862 +                       realok = 1;
13863 +                       effectiveok = 1;
13864 +                       fsok = 1;
13865 +               }
13866 +       }
13867 +
13868 +       if (realok && effectiveok && fsok)
13869 +               return 0;
13870 +       else {
13871 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
13872 +               return 1;
13873 +       }
13874 +}
13875 +
13876 +void
13877 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
13878 +{
13879 +       struct acl_role_label *role = task->role;
13880 +       struct acl_subject_label *subj = NULL;
13881 +       struct acl_object_label *obj;
13882 +       struct file *filp;
13883 +
13884 +       if (unlikely(!(gr_status & GR_READY)))
13885 +               return;
13886 +
13887 +       filp = task->exec_file;
13888 +
13889 +       /* kernel process, we'll give them the kernel role */
13890 +       if (unlikely(!filp)) {
13891 +               task->role = kernel_role;
13892 +               task->acl = kernel_role->root_label;
13893 +               return;
13894 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
13895 +               role = lookup_acl_role_label(task, uid, gid);
13896 +
13897 +       /* perform subject lookup in possibly new role
13898 +          we can use this result below in the case where role == task->role
13899 +       */
13900 +       subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
13901 +
13902 +       /* if we changed uid/gid, but result in the same role
13903 +          and are using inheritance, don't lose the inherited subject
13904 +          if current subject is other than what normal lookup
13905 +          would result in, we arrived via inheritance, don't
13906 +          lose subject
13907 +       */
13908 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
13909 +                                  (subj == task->acl)))
13910 +               task->acl = subj;
13911 +
13912 +       task->role = role;
13913 +
13914 +       task->is_writable = 0;
13915 +
13916 +       /* ignore additional mmap checks for processes that are writable 
13917 +          by the default ACL */
13918 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13919 +       if (unlikely(obj->mode & GR_WRITE))
13920 +               task->is_writable = 1;
13921 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
13922 +       if (unlikely(obj->mode & GR_WRITE))
13923 +               task->is_writable = 1;
13924 +
13925 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13926 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13927 +#endif
13928 +
13929 +       gr_set_proc_res(task);
13930 +
13931 +       return;
13932 +}
13933 +
13934 +int
13935 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
13936 +{
13937 +       struct task_struct *task = current;
13938 +       struct acl_subject_label *newacl;
13939 +       struct acl_object_label *obj;
13940 +       __u32 retmode;
13941 +
13942 +       if (unlikely(!(gr_status & GR_READY)))
13943 +               return 0;
13944 +
13945 +       newacl = chk_subj_label(dentry, mnt, task->role);
13946 +
13947 +       task_lock(task);
13948 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
13949 +            GR_POVERRIDE) && (task->acl != newacl) &&
13950 +            !(task->role->roletype & GR_ROLE_GOD) &&
13951 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
13952 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
13953 +           (atomic_read(&task->fs->count) > 1 ||
13954 +            atomic_read(&task->files->count) > 1 ||
13955 +            atomic_read(&task->sighand->count) > 1)) {
13956 +                task_unlock(task);
13957 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
13958 +               return -EACCES;
13959 +       }
13960 +       task_unlock(task);
13961 +
13962 +       obj = chk_obj_label(dentry, mnt, task->acl);
13963 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
13964 +
13965 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
13966 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
13967 +               if (obj->nested)
13968 +                       task->acl = obj->nested;
13969 +               else
13970 +                       task->acl = newacl;
13971 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
13972 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
13973 +
13974 +       task->is_writable = 0;
13975 +
13976 +       /* ignore additional mmap checks for processes that are writable 
13977 +          by the default ACL */
13978 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
13979 +       if (unlikely(obj->mode & GR_WRITE))
13980 +               task->is_writable = 1;
13981 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
13982 +       if (unlikely(obj->mode & GR_WRITE))
13983 +               task->is_writable = 1;
13984 +
13985 +       gr_set_proc_res(task);
13986 +
13987 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13988 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13989 +#endif
13990 +       return 0;
13991 +}
13992 +
13993 +static void
13994 +do_handle_delete(const ino_t ino, const dev_t dev)
13995 +{
13996 +       struct acl_object_label *matchpo;
13997 +       struct acl_subject_label *matchps;
13998 +       struct acl_subject_label *subj;
13999 +       struct acl_role_label *role;
14000 +       unsigned int i, x;
14001 +
14002 +       FOR_EACH_ROLE_START(role, i)
14003 +               FOR_EACH_SUBJECT_START(role, subj, x)
14004 +                       if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
14005 +                               matchpo->mode |= GR_DELETED;
14006 +               FOR_EACH_SUBJECT_END(subj,x)
14007 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
14008 +                       if (subj->inode == ino && subj->device == dev)
14009 +                               subj->mode |= GR_DELETED;
14010 +               FOR_EACH_NESTED_SUBJECT_END(subj)
14011 +               if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
14012 +                       matchps->mode |= GR_DELETED;
14013 +       FOR_EACH_ROLE_END(role,i)
14014 +
14015 +       return;
14016 +}
14017 +
14018 +void
14019 +gr_handle_delete(const ino_t ino, const dev_t dev)
14020 +{
14021 +       if (unlikely(!(gr_status & GR_READY)))
14022 +               return;
14023 +
14024 +       write_lock(&gr_inode_lock);
14025 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
14026 +               do_handle_delete(ino, dev);
14027 +       write_unlock(&gr_inode_lock);
14028 +
14029 +       return;
14030 +}
14031 +
14032 +static void
14033 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
14034 +                    const ino_t newinode, const dev_t newdevice,
14035 +                    struct acl_subject_label *subj)
14036 +{
14037 +       unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
14038 +       struct acl_object_label *match;
14039 +
14040 +       match = subj->obj_hash[index];
14041 +
14042 +       while (match && (match->inode != oldinode ||
14043 +              match->device != olddevice ||
14044 +              !(match->mode & GR_DELETED)))
14045 +               match = match->next;
14046 +
14047 +       if (match && (match->inode == oldinode)
14048 +           && (match->device == olddevice)
14049 +           && (match->mode & GR_DELETED)) {
14050 +               if (match->prev == NULL) {
14051 +                       subj->obj_hash[index] = match->next;
14052 +                       if (match->next != NULL)
14053 +                               match->next->prev = NULL;
14054 +               } else {
14055 +                       match->prev->next = match->next;
14056 +                       if (match->next != NULL)
14057 +                               match->next->prev = match->prev;
14058 +               }
14059 +               match->prev = NULL;
14060 +               match->next = NULL;
14061 +               match->inode = newinode;
14062 +               match->device = newdevice;
14063 +               match->mode &= ~GR_DELETED;
14064 +
14065 +               insert_acl_obj_label(match, subj);
14066 +       }
14067 +
14068 +       return;
14069 +}
14070 +
14071 +static void
14072 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
14073 +                     const ino_t newinode, const dev_t newdevice,
14074 +                     struct acl_role_label *role)
14075 +{
14076 +       unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
14077 +       struct acl_subject_label *match;
14078 +
14079 +       match = role->subj_hash[index];
14080 +
14081 +       while (match && (match->inode != oldinode ||
14082 +              match->device != olddevice ||
14083 +              !(match->mode & GR_DELETED)))
14084 +               match = match->next;
14085 +
14086 +       if (match && (match->inode == oldinode)
14087 +           && (match->device == olddevice)
14088 +           && (match->mode & GR_DELETED)) {
14089 +               if (match->prev == NULL) {
14090 +                       role->subj_hash[index] = match->next;
14091 +                       if (match->next != NULL)
14092 +                               match->next->prev = NULL;
14093 +               } else {
14094 +                       match->prev->next = match->next;
14095 +                       if (match->next != NULL)
14096 +                               match->next->prev = match->prev;
14097 +               }
14098 +               match->prev = NULL;
14099 +               match->next = NULL;
14100 +               match->inode = newinode;
14101 +               match->device = newdevice;
14102 +               match->mode &= ~GR_DELETED;
14103 +
14104 +               insert_acl_subj_label(match, role);
14105 +       }
14106 +
14107 +       return;
14108 +}
14109 +
14110 +static void
14111 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
14112 +                   const ino_t newinode, const dev_t newdevice)
14113 +{
14114 +       unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
14115 +       struct inodev_entry *match;
14116 +
14117 +       match = inodev_set.i_hash[index];
14118 +
14119 +       while (match && (match->nentry->inode != oldinode ||
14120 +              match->nentry->device != olddevice))
14121 +               match = match->next;
14122 +
14123 +       if (match && (match->nentry->inode == oldinode)
14124 +           && (match->nentry->device == olddevice)) {
14125 +               if (match->prev == NULL) {
14126 +                       inodev_set.i_hash[index] = match->next;
14127 +                       if (match->next != NULL)
14128 +                               match->next->prev = NULL;
14129 +               } else {
14130 +                       match->prev->next = match->next;
14131 +                       if (match->next != NULL)
14132 +                               match->next->prev = match->prev;
14133 +               }
14134 +               match->prev = NULL;
14135 +               match->next = NULL;
14136 +               match->nentry->inode = newinode;
14137 +               match->nentry->device = newdevice;
14138 +
14139 +               insert_inodev_entry(match);
14140 +       }
14141 +
14142 +       return;
14143 +}
14144 +
14145 +static void
14146 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
14147 +                const struct vfsmount *mnt)
14148 +{
14149 +       struct acl_subject_label *subj;
14150 +       struct acl_role_label *role;
14151 +       unsigned int i, x;
14152 +
14153 +       FOR_EACH_ROLE_START(role, i)
14154 +               update_acl_subj_label(matchn->inode, matchn->device,
14155 +                                     dentry->d_inode->i_ino,
14156 +                                     dentry->d_inode->i_sb->s_dev, role);
14157 +
14158 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
14159 +                       if ((subj->inode == dentry->d_inode->i_ino) &&
14160 +                           (subj->device == dentry->d_inode->i_sb->s_dev)) {
14161 +                               subj->inode = dentry->d_inode->i_ino;
14162 +                               subj->device = dentry->d_inode->i_sb->s_dev;
14163 +                       }
14164 +               FOR_EACH_NESTED_SUBJECT_END(subj)
14165 +               FOR_EACH_SUBJECT_START(role, subj, x)
14166 +                       update_acl_obj_label(matchn->inode, matchn->device,
14167 +                                            dentry->d_inode->i_ino,
14168 +                                            dentry->d_inode->i_sb->s_dev, subj);
14169 +               FOR_EACH_SUBJECT_END(subj,x)
14170 +       FOR_EACH_ROLE_END(role,i)
14171 +
14172 +       update_inodev_entry(matchn->inode, matchn->device,
14173 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
14174 +
14175 +       return;
14176 +}
14177 +
14178 +void
14179 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
14180 +{
14181 +       struct name_entry *matchn;
14182 +
14183 +       if (unlikely(!(gr_status & GR_READY)))
14184 +               return;
14185 +
14186 +       preempt_disable();
14187 +       matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
14188 +
14189 +       if (unlikely((unsigned long)matchn)) {
14190 +               write_lock(&gr_inode_lock);
14191 +               do_handle_create(matchn, dentry, mnt);
14192 +               write_unlock(&gr_inode_lock);
14193 +       }
14194 +       preempt_enable();
14195 +
14196 +       return;
14197 +}
14198 +
14199 +void
14200 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
14201 +                struct dentry *old_dentry,
14202 +                struct dentry *new_dentry,
14203 +                struct vfsmount *mnt, const __u8 replace)
14204 +{
14205 +       struct name_entry *matchn;
14206 +
14207 +       if (unlikely(!(gr_status & GR_READY)))
14208 +               return;
14209 +
14210 +       preempt_disable();
14211 +       matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
14212 +
14213 +       /* we wouldn't have to check d_inode if it weren't for
14214 +          NFS silly-renaming
14215 +        */
14216 +
14217 +       write_lock(&gr_inode_lock);
14218 +       if (unlikely(replace && new_dentry->d_inode)) {
14219 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
14220 +                                       new_dentry->d_inode->i_sb->s_dev) &&
14221 +                   (old_dentry->d_inode->i_nlink <= 1)))
14222 +                       do_handle_delete(new_dentry->d_inode->i_ino,
14223 +                                        new_dentry->d_inode->i_sb->s_dev);
14224 +       }
14225 +
14226 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
14227 +                               old_dentry->d_inode->i_sb->s_dev) &&
14228 +           (old_dentry->d_inode->i_nlink <= 1)))
14229 +               do_handle_delete(old_dentry->d_inode->i_ino,
14230 +                                old_dentry->d_inode->i_sb->s_dev);
14231 +
14232 +       if (unlikely((unsigned long)matchn))
14233 +               do_handle_create(matchn, old_dentry, mnt);
14234 +
14235 +       write_unlock(&gr_inode_lock);
14236 +       preempt_enable();
14237 +
14238 +       return;
14239 +}
14240 +
14241 +static int
14242 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
14243 +                        unsigned char **sum)
14244 +{
14245 +       struct acl_role_label *r;
14246 +       struct role_allowed_ip *ipp;
14247 +       struct role_transition *trans;
14248 +       unsigned int i;
14249 +       int found = 0;
14250 +
14251 +       /* check transition table */
14252 +
14253 +       for (trans = current->role->transitions; trans; trans = trans->next) {
14254 +               if (!strcmp(rolename, trans->rolename)) {
14255 +                       found = 1;
14256 +                       break;
14257 +               }
14258 +       }
14259 +
14260 +       if (!found)
14261 +               return 0;
14262 +
14263 +       /* handle special roles that do not require authentication
14264 +          and check ip */
14265 +
14266 +       FOR_EACH_ROLE_START(r, i)
14267 +               if (!strcmp(rolename, r->rolename) &&
14268 +                   (r->roletype & GR_ROLE_SPECIAL)) {
14269 +                       found = 0;
14270 +                       if (r->allowed_ips != NULL) {
14271 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
14272 +                                       if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
14273 +                                            (ntohl(ipp->addr) & ipp->netmask))
14274 +                                               found = 1;
14275 +                               }
14276 +                       } else
14277 +                               found = 2;
14278 +                       if (!found)
14279 +                               return 0;
14280 +
14281 +                       if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
14282 +                           ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
14283 +                               *salt = NULL;
14284 +                               *sum = NULL;
14285 +                               return 1;
14286 +                       }
14287 +               }
14288 +       FOR_EACH_ROLE_END(r,i)
14289 +
14290 +       for (i = 0; i < num_sprole_pws; i++) {
14291 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
14292 +                       *salt = acl_special_roles[i]->salt;
14293 +                       *sum = acl_special_roles[i]->sum;
14294 +                       return 1;
14295 +               }
14296 +       }
14297 +
14298 +       return 0;
14299 +}
14300 +
14301 +static void
14302 +assign_special_role(char *rolename)
14303 +{
14304 +       struct acl_object_label *obj;
14305 +       struct acl_role_label *r;
14306 +       struct acl_role_label *assigned = NULL;
14307 +       struct task_struct *tsk;
14308 +       struct file *filp;
14309 +       unsigned int i;
14310 +
14311 +       FOR_EACH_ROLE_START(r, i)
14312 +               if (!strcmp(rolename, r->rolename) &&
14313 +                   (r->roletype & GR_ROLE_SPECIAL))
14314 +                       assigned = r;
14315 +       FOR_EACH_ROLE_END(r,i)
14316 +
14317 +       if (!assigned)
14318 +               return;
14319 +
14320 +       read_lock(&tasklist_lock);
14321 +       read_lock(&grsec_exec_file_lock);
14322 +
14323 +       tsk = current->parent;
14324 +       if (tsk == NULL)
14325 +               goto out_unlock;
14326 +
14327 +       filp = tsk->exec_file;
14328 +       if (filp == NULL)
14329 +               goto out_unlock;
14330 +
14331 +       tsk->is_writable = 0;
14332 +
14333 +       tsk->acl_sp_role = 1;
14334 +       tsk->acl_role_id = ++acl_sp_role_value;
14335 +       tsk->role = assigned;
14336 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
14337 +
14338 +       /* ignore additional mmap checks for processes that are writable 
14339 +          by the default ACL */
14340 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
14341 +       if (unlikely(obj->mode & GR_WRITE))
14342 +               tsk->is_writable = 1;
14343 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
14344 +       if (unlikely(obj->mode & GR_WRITE))
14345 +               tsk->is_writable = 1;
14346 +
14347 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
14348 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
14349 +#endif
14350 +
14351 +out_unlock:
14352 +       read_unlock(&grsec_exec_file_lock);
14353 +       read_unlock(&tasklist_lock);
14354 +       return;
14355 +}
14356 +
14357 +int gr_check_secure_terminal(struct task_struct *task)
14358 +{
14359 +       struct task_struct *p, *p2, *p3;
14360 +       struct files_struct *files;
14361 +       struct fdtable *fdt;
14362 +       struct file *our_file = NULL, *file;
14363 +       int i;
14364 +
14365 +       if (task->signal->tty == NULL)
14366 +               return 1;
14367 +
14368 +       files = get_files_struct(task);
14369 +       if (files != NULL) {
14370 +               rcu_read_lock();
14371 +               fdt = files_fdtable(files);
14372 +               for (i=0; i < fdt->max_fds; i++) {
14373 +                       file = fcheck_files(files, i);
14374 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
14375 +                               get_file(file);
14376 +                               our_file = file;
14377 +                       }
14378 +               }
14379 +               rcu_read_unlock();
14380 +               put_files_struct(files);
14381 +       }
14382 +
14383 +       if (our_file == NULL)
14384 +               return 1;
14385 +
14386 +       read_lock(&tasklist_lock);
14387 +       do_each_thread(p2, p) {
14388 +               files = get_files_struct(p);
14389 +               if (files == NULL ||
14390 +                   (p->signal && p->signal->tty == task->signal->tty)) {
14391 +                       if (files != NULL)
14392 +                               put_files_struct(files);
14393 +                       continue;
14394 +               }
14395 +               rcu_read_lock();
14396 +               fdt = files_fdtable(files);
14397 +               for (i=0; i < fdt->max_fds; i++) {
14398 +                       file = fcheck_files(files, i);
14399 +                       if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
14400 +                           file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
14401 +                               p3 = task;
14402 +                               while (p3->pid > 0) {
14403 +                                       if (p3 == p)
14404 +                                               break;
14405 +                                       p3 = p3->parent;
14406 +                               }
14407 +                               if (p3 == p)
14408 +                                       break;
14409 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
14410 +                               gr_handle_alertkill(p);
14411 +                               rcu_read_unlock();
14412 +                               put_files_struct(files);
14413 +                               read_unlock(&tasklist_lock);
14414 +                               fput(our_file);
14415 +                               return 0;
14416 +                       }
14417 +               }
14418 +               rcu_read_unlock();
14419 +               put_files_struct(files);
14420 +       } while_each_thread(p2, p);
14421 +       read_unlock(&tasklist_lock);
14422 +
14423 +       fput(our_file);
14424 +       return 1;
14425 +}
14426 +
14427 +ssize_t
14428 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
14429 +{
14430 +       struct gr_arg_wrapper uwrap;
14431 +       unsigned char *sprole_salt;
14432 +       unsigned char *sprole_sum;
14433 +       int error = sizeof (struct gr_arg_wrapper);
14434 +       int error2 = 0;
14435 +
14436 +       down(&gr_dev_sem);
14437 +
14438 +       if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
14439 +               error = -EPERM;
14440 +               goto out;
14441 +       }
14442 +
14443 +       if (count != sizeof (struct gr_arg_wrapper)) {
14444 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
14445 +               error = -EINVAL;
14446 +               goto out;
14447 +       }
14448 +
14449 +       
14450 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
14451 +               gr_auth_expires = 0;
14452 +               gr_auth_attempts = 0;
14453 +       }
14454 +
14455 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
14456 +               error = -EFAULT;
14457 +               goto out;
14458 +       }
14459 +
14460 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
14461 +               error = -EINVAL;
14462 +               goto out;
14463 +       }
14464 +
14465 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
14466 +               error = -EFAULT;
14467 +               goto out;
14468 +       }
14469 +
14470 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
14471 +           gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
14472 +           time_after(gr_auth_expires, get_seconds())) {
14473 +               error = -EBUSY;
14474 +               goto out;
14475 +       }
14476 +
14477 +       /* if non-root trying to do anything other than use a special role,
14478 +          do not attempt authentication, do not count towards authentication
14479 +          locking
14480 +        */
14481 +
14482 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
14483 +           gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
14484 +           current->uid) {
14485 +               error = -EPERM;
14486 +               goto out;
14487 +       }
14488 +
14489 +       /* ensure pw and special role name are null terminated */
14490 +
14491 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
14492 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
14493 +
14494 +       /* Okay. 
14495 +        * We have our enough of the argument structure..(we have yet
14496 +        * to copy_from_user the tables themselves) . Copy the tables
14497 +        * only if we need them, i.e. for loading operations. */
14498 +
14499 +       switch (gr_usermode->mode) {
14500 +       case STATUS:
14501 +                       if (gr_status & GR_READY) {
14502 +                               error = 1;
14503 +                               if (!gr_check_secure_terminal(current))
14504 +                                       error = 3;
14505 +                       } else
14506 +                               error = 2;
14507 +                       goto out;
14508 +       case SHUTDOWN:
14509 +               if ((gr_status & GR_READY)
14510 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
14511 +                       gr_status &= ~GR_READY;
14512 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
14513 +                       free_variables();
14514 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
14515 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
14516 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
14517 +               } else if (gr_status & GR_READY) {
14518 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
14519 +                       error = -EPERM;
14520 +               } else {
14521 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
14522 +                       error = -EAGAIN;
14523 +               }
14524 +               break;
14525 +       case ENABLE:
14526 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
14527 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
14528 +               else {
14529 +                       if (gr_status & GR_READY)
14530 +                               error = -EAGAIN;
14531 +                       else
14532 +                               error = error2;
14533 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
14534 +               }
14535 +               break;
14536 +       case RELOAD:
14537 +               if (!(gr_status & GR_READY)) {
14538 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
14539 +                       error = -EAGAIN;
14540 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
14541 +                       lock_kernel();
14542 +                       gr_status &= ~GR_READY;
14543 +                       free_variables();
14544 +                       if (!(error2 = gracl_init(gr_usermode))) {
14545 +                               unlock_kernel();
14546 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
14547 +                       } else {
14548 +                               unlock_kernel();
14549 +                               error = error2;
14550 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
14551 +                       }
14552 +               } else {
14553 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
14554 +                       error = -EPERM;
14555 +               }
14556 +               break;
14557 +       case SEGVMOD:
14558 +               if (unlikely(!(gr_status & GR_READY))) {
14559 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
14560 +                       error = -EAGAIN;
14561 +                       break;
14562 +               }
14563 +
14564 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
14565 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
14566 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
14567 +                               struct acl_subject_label *segvacl;
14568 +                               segvacl =
14569 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
14570 +                                                         gr_usermode->segv_device,
14571 +                                                         current->role);
14572 +                               if (segvacl) {
14573 +                                       segvacl->crashes = 0;
14574 +                                       segvacl->expires = 0;
14575 +                               }
14576 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
14577 +                               gr_remove_uid(gr_usermode->segv_uid);
14578 +                       }
14579 +               } else {
14580 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
14581 +                       error = -EPERM;
14582 +               }
14583 +               break;
14584 +       case SPROLE:
14585 +       case SPROLEPAM:
14586 +               if (unlikely(!(gr_status & GR_READY))) {
14587 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
14588 +                       error = -EAGAIN;
14589 +                       break;
14590 +               }
14591 +
14592 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
14593 +                       current->role->expires = 0;
14594 +                       current->role->auth_attempts = 0;
14595 +               }
14596 +
14597 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
14598 +                   time_after(current->role->expires, get_seconds())) {
14599 +                       error = -EBUSY;
14600 +                       goto out;
14601 +               }
14602 +
14603 +               if (lookup_special_role_auth
14604 +                   (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
14605 +                   && ((!sprole_salt && !sprole_sum)
14606 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
14607 +                       char *p = "";
14608 +                       assign_special_role(gr_usermode->sp_role);
14609 +                       read_lock(&tasklist_lock);
14610 +                       if (current->parent)
14611 +                               p = current->parent->role->rolename;
14612 +                       read_unlock(&tasklist_lock);
14613 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
14614 +                                       p, acl_sp_role_value);
14615 +               } else {
14616 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
14617 +                       error = -EPERM;
14618 +                       if(!(current->role->auth_attempts++))
14619 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
14620 +
14621 +                       goto out;
14622 +               }
14623 +               break;
14624 +       case UNSPROLE:
14625 +               if (unlikely(!(gr_status & GR_READY))) {
14626 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
14627 +                       error = -EAGAIN;
14628 +                       break;
14629 +               }
14630 +
14631 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
14632 +                       char *p = "";
14633 +                       int i = 0;
14634 +
14635 +                       read_lock(&tasklist_lock);
14636 +                       if (current->parent) {
14637 +                               p = current->parent->role->rolename;
14638 +                               i = current->parent->acl_role_id;
14639 +                       }
14640 +                       read_unlock(&tasklist_lock);
14641 +
14642 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
14643 +                       gr_set_acls(1);
14644 +               } else {
14645 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
14646 +                       error = -EPERM;
14647 +                       goto out;
14648 +               }
14649 +               break;
14650 +       default:
14651 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
14652 +               error = -EINVAL;
14653 +               break;
14654 +       }
14655 +
14656 +       if (error != -EPERM)
14657 +               goto out;
14658 +
14659 +       if(!(gr_auth_attempts++))
14660 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
14661 +
14662 +      out:
14663 +       up(&gr_dev_sem);
14664 +       return error;
14665 +}
14666 +
14667 +int
14668 +gr_set_acls(const int type)
14669 +{
14670 +       struct acl_object_label *obj;
14671 +       struct task_struct *task, *task2;
14672 +       struct file *filp;
14673 +       struct acl_role_label *role = current->role;
14674 +       __u16 acl_role_id = current->acl_role_id;
14675 +
14676 +       read_lock(&tasklist_lock);
14677 +       read_lock(&grsec_exec_file_lock);
14678 +       do_each_thread(task2, task) {
14679 +               /* check to see if we're called from the exit handler,
14680 +                  if so, only replace ACLs that have inherited the admin
14681 +                  ACL */
14682 +
14683 +               if (type && (task->role != role ||
14684 +                            task->acl_role_id != acl_role_id))
14685 +                       continue;
14686 +
14687 +               task->acl_role_id = 0;
14688 +               task->acl_sp_role = 0;
14689 +
14690 +               if ((filp = task->exec_file)) {
14691 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
14692 +
14693 +                       task->acl =
14694 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
14695 +                                          task->role);
14696 +                       if (task->acl) {
14697 +                               struct acl_subject_label *curr;
14698 +                               curr = task->acl;
14699 +
14700 +                               task->is_writable = 0;
14701 +                               /* ignore additional mmap checks for processes that are writable 
14702 +                                  by the default ACL */
14703 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
14704 +                               if (unlikely(obj->mode & GR_WRITE))
14705 +                                       task->is_writable = 1;
14706 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
14707 +                               if (unlikely(obj->mode & GR_WRITE))
14708 +                                       task->is_writable = 1;
14709 +
14710 +                               gr_set_proc_res(task);
14711 +
14712 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
14713 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
14714 +#endif
14715 +                       } else {
14716 +                               read_unlock(&grsec_exec_file_lock);
14717 +                               read_unlock(&tasklist_lock);
14718 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
14719 +                               return 1;
14720 +                       }
14721 +               } else {
14722 +                       // it's a kernel process
14723 +                       task->role = kernel_role;
14724 +                       task->acl = kernel_role->root_label;
14725 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
14726 +                       task->acl->mode &= ~GR_PROCFIND;
14727 +#endif
14728 +               }
14729 +       } while_each_thread(task2, task);
14730 +       read_unlock(&grsec_exec_file_lock);
14731 +       read_unlock(&tasklist_lock);
14732 +       return 0;
14733 +}
14734 +
14735 +void
14736 +gr_learn_resource(const struct task_struct *task,
14737 +                 const int res, const unsigned long wanted, const int gt)
14738 +{
14739 +       struct acl_subject_label *acl;
14740 +
14741 +       if (unlikely((gr_status & GR_READY) &&
14742 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
14743 +               goto skip_reslog;
14744 +
14745 +#ifdef CONFIG_GRKERNSEC_RESLOG
14746 +       gr_log_resource(task, res, wanted, gt);
14747 +#endif
14748 +      skip_reslog:
14749 +
14750 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
14751 +               return;
14752 +
14753 +       acl = task->acl;
14754 +
14755 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
14756 +                  !(acl->resmask & (1 << (unsigned short) res))))
14757 +               return;
14758 +
14759 +       if (wanted >= acl->res[res].rlim_cur) {
14760 +               unsigned long res_add;
14761 +
14762 +               res_add = wanted;
14763 +               switch (res) {
14764 +               case RLIMIT_CPU:
14765 +                       res_add += GR_RLIM_CPU_BUMP;
14766 +                       break;
14767 +               case RLIMIT_FSIZE:
14768 +                       res_add += GR_RLIM_FSIZE_BUMP;
14769 +                       break;
14770 +               case RLIMIT_DATA:
14771 +                       res_add += GR_RLIM_DATA_BUMP;
14772 +                       break;
14773 +               case RLIMIT_STACK:
14774 +                       res_add += GR_RLIM_STACK_BUMP;
14775 +                       break;
14776 +               case RLIMIT_CORE:
14777 +                       res_add += GR_RLIM_CORE_BUMP;
14778 +                       break;
14779 +               case RLIMIT_RSS:
14780 +                       res_add += GR_RLIM_RSS_BUMP;
14781 +                       break;
14782 +               case RLIMIT_NPROC:
14783 +                       res_add += GR_RLIM_NPROC_BUMP;
14784 +                       break;
14785 +               case RLIMIT_NOFILE:
14786 +                       res_add += GR_RLIM_NOFILE_BUMP;
14787 +                       break;
14788 +               case RLIMIT_MEMLOCK:
14789 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
14790 +                       break;
14791 +               case RLIMIT_AS:
14792 +                       res_add += GR_RLIM_AS_BUMP;
14793 +                       break;
14794 +               case RLIMIT_LOCKS:
14795 +                       res_add += GR_RLIM_LOCKS_BUMP;
14796 +                       break;
14797 +               }
14798 +
14799 +               acl->res[res].rlim_cur = res_add;
14800 +
14801 +               if (wanted > acl->res[res].rlim_max)
14802 +                       acl->res[res].rlim_max = res_add;
14803 +
14804 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
14805 +                              task->role->roletype, acl->filename,
14806 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
14807 +                              "", (unsigned long) res);
14808 +       }
14809 +
14810 +       return;
14811 +}
14812 +
14813 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14814 +void
14815 +pax_set_initial_flags(struct linux_binprm *bprm)
14816 +{
14817 +       struct task_struct *task = current;
14818 +        struct acl_subject_label *proc;
14819 +       unsigned long flags;
14820 +
14821 +        if (unlikely(!(gr_status & GR_READY)))
14822 +                return;
14823 +
14824 +       flags = pax_get_flags(task);
14825 +
14826 +        proc = task->acl;
14827 +
14828 +       if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
14829 +               flags &= ~MF_PAX_PAGEEXEC;
14830 +       if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
14831 +               flags &= ~MF_PAX_SEGMEXEC;
14832 +       if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
14833 +               flags &= ~MF_PAX_RANDMMAP;
14834 +       if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
14835 +               flags &= ~MF_PAX_EMUTRAMP;
14836 +       if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
14837 +               flags &= ~MF_PAX_MPROTECT;
14838 +
14839 +       if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
14840 +               flags |= MF_PAX_PAGEEXEC;
14841 +       if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
14842 +               flags |= MF_PAX_SEGMEXEC;
14843 +       if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
14844 +               flags |= MF_PAX_RANDMMAP;
14845 +       if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
14846 +               flags |= MF_PAX_EMUTRAMP;
14847 +       if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
14848 +               flags |= MF_PAX_MPROTECT;
14849 +
14850 +       pax_set_flags(task, flags);
14851 +
14852 +        return;
14853 +}
14854 +#endif
14855 +
14856 +#ifdef CONFIG_SYSCTL
14857 +extern struct proc_dir_entry *proc_sys_root;
14858 +
14859 +/* the following function is called under the BKL */
14860 +
14861 +__u32
14862 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
14863 +                const void *newval)
14864 +{
14865 +       struct proc_dir_entry *tmp;
14866 +       struct nameidata nd;
14867 +       const char *proc_sys = "/proc/sys";
14868 +       char *path;
14869 +       struct acl_object_label *obj;
14870 +       unsigned short len = 0, pos = 0, depth = 0, i;
14871 +       __u32 err = 0;
14872 +       __u32 mode = 0;
14873 +
14874 +       if (unlikely(!(gr_status & GR_READY)))
14875 +               return 1;
14876 +
14877 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
14878 +
14879 +       if (oldval)
14880 +               mode |= GR_READ;
14881 +       if (newval)
14882 +               mode |= GR_WRITE;
14883 +
14884 +       /* convert the requested sysctl entry into a pathname */
14885 +
14886 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
14887 +               len += strlen(tmp->name);
14888 +               len++;
14889 +               depth++;
14890 +       }
14891 +
14892 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
14893 +               return 0;       /* deny */
14894 +
14895 +       memset(path, 0, PAGE_SIZE);
14896 +
14897 +       memcpy(path, proc_sys, strlen(proc_sys));
14898 +
14899 +       pos += strlen(proc_sys);
14900 +
14901 +       for (; depth > 0; depth--) {
14902 +               path[pos] = '/';
14903 +               pos++;
14904 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
14905 +                    tmp = tmp->parent) {
14906 +                       if (depth == i) {
14907 +                               memcpy(path + pos, tmp->name,
14908 +                                      strlen(tmp->name));
14909 +                               pos += strlen(tmp->name);
14910 +                       }
14911 +                       i++;
14912 +               }
14913 +       }
14914 +
14915 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
14916 +
14917 +       if (err)
14918 +               goto out;
14919 +
14920 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
14921 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
14922 +
14923 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
14924 +                    ((err & mode) != mode))) {
14925 +               __u32 new_mode = mode;
14926 +
14927 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14928 +
14929 +               err = new_mode;
14930 +               gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
14931 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
14932 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
14933 +                              path, (mode & GR_READ) ? " reading" : "",
14934 +                              (mode & GR_WRITE) ? " writing" : "");
14935 +               err = 0;
14936 +       } else if ((err & mode) != mode) {
14937 +               err = 0;
14938 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
14939 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
14940 +                              path, (mode & GR_READ) ? " reading" : "",
14941 +                              (mode & GR_WRITE) ? " writing" : "");
14942 +       }
14943 +
14944 +       path_release(&nd);
14945 +
14946 +      out:
14947 +       return err;
14948 +}
14949 +#endif
14950 +
14951 +int
14952 +gr_handle_proc_ptrace(struct task_struct *task)
14953 +{
14954 +       struct file *filp;
14955 +       struct task_struct *tmp = task;
14956 +       struct task_struct *curtemp = current;
14957 +       __u32 retmode;
14958 +
14959 +       if (unlikely(!(gr_status & GR_READY)))
14960 +               return 0;
14961 +
14962 +       read_lock(&tasklist_lock);
14963 +       read_lock(&grsec_exec_file_lock);
14964 +       filp = task->exec_file;
14965 +
14966 +       while (tmp->pid > 0) {
14967 +               if (tmp == curtemp)
14968 +                       break;
14969 +               tmp = tmp->parent;
14970 +       }
14971 +
14972 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
14973 +               read_unlock(&grsec_exec_file_lock);
14974 +               read_unlock(&tasklist_lock);
14975 +               return 1;
14976 +       }
14977 +
14978 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
14979 +       read_unlock(&grsec_exec_file_lock);
14980 +       read_unlock(&tasklist_lock);
14981 +
14982 +       if (retmode & GR_NOPTRACE)
14983 +               return 1;
14984 +
14985 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
14986 +           && (current->acl != task->acl || (current->acl != current->role->root_label
14987 +           && current->pid != task->pid)))
14988 +               return 1;
14989 +
14990 +       return 0;
14991 +}
14992 +
14993 +int
14994 +gr_handle_ptrace(struct task_struct *task, const long request)
14995 +{
14996 +       struct task_struct *tmp = task;
14997 +       struct task_struct *curtemp = current;
14998 +       __u32 retmode;
14999 +
15000 +       if (unlikely(!(gr_status & GR_READY)))
15001 +               return 0;
15002 +
15003 +       read_lock(&tasklist_lock);
15004 +       while (tmp->pid > 0) {
15005 +               if (tmp == curtemp)
15006 +                       break;
15007 +               tmp = tmp->parent;
15008 +       }
15009 +
15010 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
15011 +               read_unlock(&tasklist_lock);
15012 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15013 +               return 1;
15014 +       }
15015 +       read_unlock(&tasklist_lock);
15016 +
15017 +       read_lock(&grsec_exec_file_lock);
15018 +       if (unlikely(!task->exec_file)) {
15019 +               read_unlock(&grsec_exec_file_lock);
15020 +               return 0;
15021 +       }
15022 +
15023 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
15024 +       read_unlock(&grsec_exec_file_lock);
15025 +
15026 +       if (retmode & GR_NOPTRACE) {
15027 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15028 +               return 1;
15029 +       }
15030 +               
15031 +       if (retmode & GR_PTRACERD) {
15032 +               switch (request) {
15033 +               case PTRACE_POKETEXT:
15034 +               case PTRACE_POKEDATA:
15035 +               case PTRACE_POKEUSR:
15036 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
15037 +               case PTRACE_SETREGS:
15038 +               case PTRACE_SETFPREGS:
15039 +#endif
15040 +#ifdef CONFIG_X86
15041 +               case PTRACE_SETFPXREGS:
15042 +#endif
15043 +#ifdef CONFIG_ALTIVEC
15044 +               case PTRACE_SETVRREGS:
15045 +#endif
15046 +                       return 1;
15047 +               default:
15048 +                       return 0;
15049 +               }
15050 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
15051 +                  !(current->role->roletype & GR_ROLE_GOD) &&
15052 +                  (current->acl != task->acl)) {
15053 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15054 +               return 1;
15055 +       }
15056 +
15057 +       return 0;
15058 +}
15059 +
15060 +static int is_writable_mmap(const struct file *filp)
15061 +{
15062 +       struct task_struct *task = current;
15063 +       struct acl_object_label *obj, *obj2;
15064 +
15065 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
15066 +           !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
15067 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
15068 +               obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
15069 +                                    task->role->root_label);
15070 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
15071 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
15072 +                       return 1;
15073 +               }
15074 +       }
15075 +       return 0;
15076 +}
15077 +
15078 +int
15079 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
15080 +{
15081 +       __u32 mode;
15082 +
15083 +       if (unlikely(!file || !(prot & PROT_EXEC)))
15084 +               return 1;
15085 +
15086 +       if (is_writable_mmap(file))
15087 +               return 0;
15088 +
15089 +       mode =
15090 +           gr_search_file(file->f_dentry,
15091 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
15092 +                          file->f_vfsmnt);
15093 +
15094 +       if (!gr_tpe_allow(file))
15095 +               return 0;
15096 +
15097 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
15098 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15099 +               return 0;
15100 +       } else if (unlikely(!(mode & GR_EXEC))) {
15101 +               return 0;
15102 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
15103 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15104 +               return 1;
15105 +       }
15106 +
15107 +       return 1;
15108 +}
15109 +
15110 +int
15111 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
15112 +{
15113 +       __u32 mode;
15114 +
15115 +       if (unlikely(!file || !(prot & PROT_EXEC)))
15116 +               return 1;
15117 +
15118 +       if (is_writable_mmap(file))
15119 +               return 0;
15120 +
15121 +       mode =
15122 +           gr_search_file(file->f_dentry,
15123 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
15124 +                          file->f_vfsmnt);
15125 +
15126 +       if (!gr_tpe_allow(file))
15127 +               return 0;
15128 +
15129 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
15130 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15131 +               return 0;
15132 +       } else if (unlikely(!(mode & GR_EXEC))) {
15133 +               return 0;
15134 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
15135 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15136 +               return 1;
15137 +       }
15138 +
15139 +       return 1;
15140 +}
15141 +
15142 +void
15143 +gr_acl_handle_psacct(struct task_struct *task, const long code)
15144 +{
15145 +       unsigned long runtime;
15146 +       unsigned long cputime;
15147 +       unsigned int wday, cday;
15148 +       __u8 whr, chr;
15149 +       __u8 wmin, cmin;
15150 +       __u8 wsec, csec;
15151 +
15152 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
15153 +                    !(task->acl->mode & GR_PROCACCT)))
15154 +               return;
15155 +
15156 +       runtime = xtime.tv_sec - task->start_time.tv_sec;
15157 +       wday = runtime / (3600 * 24);
15158 +       runtime -= wday * (3600 * 24);
15159 +       whr = runtime / 3600;
15160 +       runtime -= whr * 3600;
15161 +       wmin = runtime / 60;
15162 +       runtime -= wmin * 60;
15163 +       wsec = runtime;
15164 +
15165 +       cputime = (task->utime + task->stime) / HZ;
15166 +       cday = cputime / (3600 * 24);
15167 +       cputime -= cday * (3600 * 24);
15168 +       chr = cputime / 3600;
15169 +       cputime -= chr * 3600;
15170 +       cmin = cputime / 60;
15171 +       cputime -= cmin * 60;
15172 +       csec = cputime;
15173 +
15174 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
15175 +
15176 +       return;
15177 +}
15178 +
15179 +void gr_set_kernel_label(struct task_struct *task)
15180 +{
15181 +       if (gr_status & GR_READY) {
15182 +               task->role = kernel_role;
15183 +               task->acl = kernel_role->root_label;
15184 +       }
15185 +       return;
15186 +}
15187 +
15188 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
15189 +{
15190 +       struct task_struct *task = current;
15191 +       struct dentry *dentry = file->f_dentry;
15192 +       struct vfsmount *mnt = file->f_vfsmnt;
15193 +       struct acl_object_label *obj, *tmp;
15194 +       struct acl_subject_label *subj;
15195 +       unsigned int bufsize;
15196 +       int is_not_root;
15197 +       char *path;
15198 +
15199 +       if (unlikely(!(gr_status & GR_READY)))
15200 +               return 1;
15201 +
15202 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
15203 +               return 1;
15204 +
15205 +       subj = task->acl;
15206 +       do {
15207 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
15208 +               if (obj != NULL)
15209 +                       return (obj->mode & GR_FIND) ? 1 : 0;
15210 +       } while ((subj = subj->parent_subject));
15211 +       
15212 +       obj = chk_obj_label(dentry, mnt, task->acl);
15213 +       if (obj->globbed == NULL)
15214 +               return (obj->mode & GR_FIND) ? 1 : 0;
15215 +
15216 +       is_not_root = ((obj->filename[0] == '/') &&
15217 +                  (obj->filename[1] == '\0')) ? 0 : 1;
15218 +       bufsize = PAGE_SIZE - namelen - is_not_root;
15219 +
15220 +       /* check bufsize > PAGE_SIZE || bufsize == 0 */
15221 +       if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
15222 +               return 1;
15223 +
15224 +       preempt_disable();
15225 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
15226 +                          bufsize);
15227 +
15228 +       bufsize = strlen(path);
15229 +
15230 +       /* if base is "/", don't append an additional slash */
15231 +       if (is_not_root)
15232 +               *(path + bufsize) = '/';
15233 +       memcpy(path + bufsize + is_not_root, name, namelen);
15234 +       *(path + bufsize + namelen + is_not_root) = '\0';
15235 +
15236 +       tmp = obj->globbed;
15237 +       while (tmp) {
15238 +               if (!glob_match(tmp->filename, path)) {
15239 +                       preempt_enable();
15240 +                       return (tmp->mode & GR_FIND) ? 1 : 0;
15241 +               }
15242 +               tmp = tmp->next;
15243 +       }
15244 +       preempt_enable();
15245 +       return (obj->mode & GR_FIND) ? 1 : 0;
15246 +}
15247 +
15248 +EXPORT_SYMBOL(gr_learn_resource);
15249 +EXPORT_SYMBOL(gr_set_kernel_label);
15250 +#ifdef CONFIG_SECURITY
15251 +EXPORT_SYMBOL(gr_check_user_change);
15252 +EXPORT_SYMBOL(gr_check_group_change);
15253 +#endif
15254 +
15255 diff -urNp linux-2.6.18/grsecurity/gracl_cap.c linux-2.6.18/grsecurity/gracl_cap.c
15256 --- linux-2.6.18/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
15257 +++ linux-2.6.18/grsecurity/gracl_cap.c 2006-09-22 20:04:35.000000000 -0400
15258 @@ -0,0 +1,110 @@
15259 +#include <linux/kernel.h>
15260 +#include <linux/module.h>
15261 +#include <linux/sched.h>
15262 +#include <linux/capability.h>
15263 +#include <linux/gracl.h>
15264 +#include <linux/grsecurity.h>
15265 +#include <linux/grinternal.h>
15266 +
15267 +static const char *captab_log[] = {
15268 +       "CAP_CHOWN",
15269 +       "CAP_DAC_OVERRIDE",
15270 +       "CAP_DAC_READ_SEARCH",
15271 +       "CAP_FOWNER",
15272 +       "CAP_FSETID",
15273 +       "CAP_KILL",
15274 +       "CAP_SETGID",
15275 +       "CAP_SETUID",
15276 +       "CAP_SETPCAP",
15277 +       "CAP_LINUX_IMMUTABLE",
15278 +       "CAP_NET_BIND_SERVICE",
15279 +       "CAP_NET_BROADCAST",
15280 +       "CAP_NET_ADMIN",
15281 +       "CAP_NET_RAW",
15282 +       "CAP_IPC_LOCK",
15283 +       "CAP_IPC_OWNER",
15284 +       "CAP_SYS_MODULE",
15285 +       "CAP_SYS_RAWIO",
15286 +       "CAP_SYS_CHROOT",
15287 +       "CAP_SYS_PTRACE",
15288 +       "CAP_SYS_PACCT",
15289 +       "CAP_SYS_ADMIN",
15290 +       "CAP_SYS_BOOT",
15291 +       "CAP_SYS_NICE",
15292 +       "CAP_SYS_RESOURCE",
15293 +       "CAP_SYS_TIME",
15294 +       "CAP_SYS_TTY_CONFIG",
15295 +       "CAP_MKNOD",
15296 +       "CAP_LEASE"
15297 +};
15298 +
15299 +EXPORT_SYMBOL(gr_task_is_capable);
15300 +
15301 +int
15302 +gr_task_is_capable(struct task_struct *task, const int cap)
15303 +{
15304 +       struct acl_subject_label *curracl;
15305 +       __u32 cap_drop = 0, cap_mask = 0;
15306 +
15307 +       if (!gr_acl_is_enabled())
15308 +               return 1;
15309 +
15310 +       curracl = task->acl;
15311 +
15312 +       cap_drop = curracl->cap_lower;
15313 +       cap_mask = curracl->cap_mask;
15314 +
15315 +       while ((curracl = curracl->parent_subject)) {
15316 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
15317 +                       cap_drop |= curracl->cap_lower & (1 << cap);
15318 +               cap_mask |= curracl->cap_mask;
15319 +       }
15320 +
15321 +       if (!cap_raised(cap_drop, cap))
15322 +               return 1;
15323 +
15324 +       curracl = task->acl;
15325 +
15326 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
15327 +           && cap_raised(task->cap_effective, cap)) {
15328 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
15329 +                              task->role->roletype, task->uid,
15330 +                              task->gid, task->exec_file ?
15331 +                              gr_to_filename(task->exec_file->f_dentry,
15332 +                              task->exec_file->f_vfsmnt) : curracl->filename,
15333 +                              curracl->filename, 0UL,
15334 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
15335 +               return 1;
15336 +       }
15337 +
15338 +       if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
15339 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
15340 +
15341 +       return 0;
15342 +}
15343 +
15344 +int
15345 +gr_is_capable_nolog(const int cap)
15346 +{
15347 +       struct acl_subject_label *curracl;
15348 +       __u32 cap_drop = 0, cap_mask = 0;
15349 +
15350 +       if (!gr_acl_is_enabled())
15351 +               return 1;
15352 +
15353 +       curracl = current->acl;
15354 +
15355 +       cap_drop = curracl->cap_lower;
15356 +       cap_mask = curracl->cap_mask;
15357 +
15358 +       while ((curracl = curracl->parent_subject)) {
15359 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
15360 +               cap_mask |= curracl->cap_mask;
15361 +       }
15362 +
15363 +       if (!cap_raised(cap_drop, cap))
15364 +               return 1;
15365 +
15366 +       return 0;
15367 +}
15368 +
15369 diff -urNp linux-2.6.18/grsecurity/gracl_fs.c linux-2.6.18/grsecurity/gracl_fs.c
15370 --- linux-2.6.18/grsecurity/gracl_fs.c  1969-12-31 19:00:00.000000000 -0500
15371 +++ linux-2.6.18/grsecurity/gracl_fs.c  2006-09-22 20:04:35.000000000 -0400
15372 @@ -0,0 +1,423 @@
15373 +#include <linux/kernel.h>
15374 +#include <linux/sched.h>
15375 +#include <linux/types.h>
15376 +#include <linux/fs.h>
15377 +#include <linux/file.h>
15378 +#include <linux/stat.h>
15379 +#include <linux/grsecurity.h>
15380 +#include <linux/grinternal.h>
15381 +#include <linux/gracl.h>
15382 +
15383 +__u32
15384 +gr_acl_handle_hidden_file(const struct dentry * dentry,
15385 +                         const struct vfsmount * mnt)
15386 +{
15387 +       __u32 mode;
15388 +
15389 +       if (unlikely(!dentry->d_inode))
15390 +               return GR_FIND;
15391 +
15392 +       mode =
15393 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
15394 +
15395 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
15396 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
15397 +               return mode;
15398 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
15399 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
15400 +               return 0;
15401 +       } else if (unlikely(!(mode & GR_FIND)))
15402 +               return 0;
15403 +
15404 +       return GR_FIND;
15405 +}
15406 +
15407 +__u32
15408 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
15409 +                  const int fmode)
15410 +{
15411 +       __u32 reqmode = GR_FIND;
15412 +       __u32 mode;
15413 +
15414 +       if (unlikely(!dentry->d_inode))
15415 +               return reqmode;
15416 +
15417 +       if (unlikely(fmode & O_APPEND))
15418 +               reqmode |= GR_APPEND;
15419 +       else if (unlikely(fmode & FMODE_WRITE))
15420 +               reqmode |= GR_WRITE;
15421 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
15422 +               reqmode |= GR_READ;
15423 +
15424 +       mode =
15425 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
15426 +                          mnt);
15427 +
15428 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
15429 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
15430 +                              reqmode & GR_READ ? " reading" : "",
15431 +                              reqmode & GR_WRITE ? " writing" : reqmode &
15432 +                              GR_APPEND ? " appending" : "");
15433 +               return reqmode;
15434 +       } else
15435 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
15436 +       {
15437 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
15438 +                              reqmode & GR_READ ? " reading" : "",
15439 +                              reqmode & GR_WRITE ? " writing" : reqmode &
15440 +                              GR_APPEND ? " appending" : "");
15441 +               return 0;
15442 +       } else if (unlikely((mode & reqmode) != reqmode))
15443 +               return 0;
15444 +
15445 +       return reqmode;
15446 +}
15447 +
15448 +__u32
15449 +gr_acl_handle_creat(const struct dentry * dentry,
15450 +                   const struct dentry * p_dentry,
15451 +                   const struct vfsmount * p_mnt, const int fmode,
15452 +                   const int imode)
15453 +{
15454 +       __u32 reqmode = GR_WRITE | GR_CREATE;
15455 +       __u32 mode;
15456 +
15457 +       if (unlikely(fmode & O_APPEND))
15458 +               reqmode |= GR_APPEND;
15459 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
15460 +               reqmode |= GR_READ;
15461 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
15462 +               reqmode |= GR_SETID;
15463 +
15464 +       mode =
15465 +           gr_check_create(dentry, p_dentry, p_mnt,
15466 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
15467 +
15468 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
15469 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
15470 +                              reqmode & GR_READ ? " reading" : "",
15471 +                              reqmode & GR_WRITE ? " writing" : reqmode &
15472 +                              GR_APPEND ? " appending" : "");
15473 +               return reqmode;
15474 +       } else
15475 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
15476 +       {
15477 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
15478 +                              reqmode & GR_READ ? " reading" : "",
15479 +                              reqmode & GR_WRITE ? " writing" : reqmode &
15480 +                              GR_APPEND ? " appending" : "");
15481 +               return 0;
15482 +       } else if (unlikely((mode & reqmode) != reqmode))
15483 +               return 0;
15484 +
15485 +       return reqmode;
15486 +}
15487 +
15488 +__u32
15489 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
15490 +                    const int fmode)
15491 +{
15492 +       __u32 mode, reqmode = GR_FIND;
15493 +
15494 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
15495 +               reqmode |= GR_EXEC;
15496 +       if (fmode & S_IWOTH)
15497 +               reqmode |= GR_WRITE;
15498 +       if (fmode & S_IROTH)
15499 +               reqmode |= GR_READ;
15500 +
15501 +       mode =
15502 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
15503 +                          mnt);
15504 +
15505 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
15506 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
15507 +                              reqmode & GR_READ ? " reading" : "",
15508 +                              reqmode & GR_WRITE ? " writing" : "",
15509 +                              reqmode & GR_EXEC ? " executing" : "");
15510 +               return reqmode;
15511 +       } else
15512 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
15513 +       {
15514 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
15515 +                              reqmode & GR_READ ? " reading" : "",
15516 +                              reqmode & GR_WRITE ? " writing" : "",
15517 +                              reqmode & GR_EXEC ? " executing" : "");
15518 +               return 0;
15519 +       } else if (unlikely((mode & reqmode) != reqmode))
15520 +               return 0;
15521 +
15522 +       return reqmode;
15523 +}
15524 +
15525 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
15526 +{
15527 +       __u32 mode;
15528 +
15529 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
15530 +
15531 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
15532 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
15533 +               return mode;
15534 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
15535 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
15536 +               return 0;
15537 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
15538 +               return 0;
15539 +
15540 +       return (reqmode);
15541 +}
15542 +
15543 +__u32
15544 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
15545 +{
15546 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
15547 +}
15548 +
15549 +__u32
15550 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
15551 +{
15552 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
15553 +}
15554 +
15555 +__u32
15556 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
15557 +{
15558 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
15559 +}
15560 +
15561 +__u32
15562 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
15563 +{
15564 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
15565 +}
15566 +
15567 +__u32
15568 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
15569 +                    mode_t mode)
15570 +{
15571 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
15572 +               return 1;
15573 +
15574 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
15575 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
15576 +                                  GR_FCHMOD_ACL_MSG);
15577 +       } else {
15578 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
15579 +       }
15580 +}
15581 +
15582 +__u32
15583 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
15584 +                   mode_t mode)
15585 +{
15586 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
15587 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
15588 +                                  GR_CHMOD_ACL_MSG);
15589 +       } else {
15590 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
15591 +       }
15592 +}
15593 +
15594 +__u32
15595 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
15596 +{
15597 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
15598 +}
15599 +
15600 +__u32
15601 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
15602 +{
15603 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
15604 +}
15605 +
15606 +__u32
15607 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
15608 +{
15609 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
15610 +                          GR_UNIXCONNECT_ACL_MSG);
15611 +}
15612 +
15613 +/* hardlinks require at minimum create permission,
15614 +   any additional privilege required is based on the
15615 +   privilege of the file being linked to
15616 +*/
15617 +__u32
15618 +gr_acl_handle_link(const struct dentry * new_dentry,
15619 +                  const struct dentry * parent_dentry,
15620 +                  const struct vfsmount * parent_mnt,
15621 +                  const struct dentry * old_dentry,
15622 +                  const struct vfsmount * old_mnt, const char *to)
15623 +{
15624 +       __u32 mode;
15625 +       __u32 needmode = GR_CREATE | GR_LINK;
15626 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
15627 +
15628 +       mode =
15629 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
15630 +                         old_mnt);
15631 +
15632 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
15633 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
15634 +               return mode;
15635 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
15636 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
15637 +               return 0;
15638 +       } else if (unlikely((mode & needmode) != needmode))
15639 +               return 0;
15640 +
15641 +       return 1;
15642 +}
15643 +
15644 +__u32
15645 +gr_acl_handle_symlink(const struct dentry * new_dentry,
15646 +                     const struct dentry * parent_dentry,
15647 +                     const struct vfsmount * parent_mnt, const char *from)
15648 +{
15649 +       __u32 needmode = GR_WRITE | GR_CREATE;
15650 +       __u32 mode;
15651 +
15652 +       mode =
15653 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
15654 +                           GR_CREATE | GR_AUDIT_CREATE |
15655 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
15656 +
15657 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
15658 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
15659 +               return mode;
15660 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
15661 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
15662 +               return 0;
15663 +       } else if (unlikely((mode & needmode) != needmode))
15664 +               return 0;
15665 +
15666 +       return (GR_WRITE | GR_CREATE);
15667 +}
15668 +
15669 +static __u32 generic_fs_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt)
15670 +{
15671 +       __u32 mode;
15672 +
15673 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
15674 +
15675 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
15676 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
15677 +               return mode;
15678 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
15679 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
15680 +               return 0;
15681 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
15682 +               return 0;
15683 +
15684 +       return (reqmode);
15685 +}
15686 +
15687 +__u32
15688 +gr_acl_handle_mknod(const struct dentry * new_dentry,
15689 +                   const struct dentry * parent_dentry,
15690 +                   const struct vfsmount * parent_mnt,
15691 +                   const int mode)
15692 +{
15693 +       __u32 reqmode = GR_WRITE | GR_CREATE;
15694 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
15695 +               reqmode |= GR_SETID;
15696 +
15697 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
15698 +                                 reqmode, GR_MKNOD_ACL_MSG);
15699 +}
15700 +
15701 +__u32
15702 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
15703 +                   const struct dentry *parent_dentry,
15704 +                   const struct vfsmount *parent_mnt)
15705 +{
15706 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
15707 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
15708 +}
15709 +
15710 +#define RENAME_CHECK_SUCCESS(old, new) \
15711 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
15712 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
15713 +
15714 +int
15715 +gr_acl_handle_rename(struct dentry *new_dentry,
15716 +                    struct dentry *parent_dentry,
15717 +                    const struct vfsmount *parent_mnt,
15718 +                    struct dentry *old_dentry,
15719 +                    struct inode *old_parent_inode,
15720 +                    struct vfsmount *old_mnt, const char *newname)
15721 +{
15722 +       __u32 comp1, comp2;
15723 +       int error = 0;
15724 +
15725 +       if (unlikely(!gr_acl_is_enabled()))
15726 +               return 0;
15727 +
15728 +       if (!new_dentry->d_inode) {
15729 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
15730 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
15731 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
15732 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
15733 +                                      GR_DELETE | GR_AUDIT_DELETE |
15734 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
15735 +                                      GR_SUPPRESS, old_mnt);
15736 +       } else {
15737 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
15738 +                                      GR_CREATE | GR_DELETE |
15739 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
15740 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
15741 +                                      GR_SUPPRESS, parent_mnt);
15742 +               comp2 =
15743 +                   gr_search_file(old_dentry,
15744 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
15745 +                                  GR_DELETE | GR_AUDIT_DELETE |
15746 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
15747 +       }
15748 +
15749 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
15750 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
15751 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
15752 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
15753 +                && !(comp2 & GR_SUPPRESS)) {
15754 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
15755 +               error = -EACCES;
15756 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
15757 +               error = -EACCES;
15758 +
15759 +       return error;
15760 +}
15761 +
15762 +void
15763 +gr_acl_handle_exit(void)
15764 +{
15765 +       u16 id;
15766 +       char *rolename;
15767 +       struct file *exec_file;
15768 +
15769 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
15770 +               id = current->acl_role_id;
15771 +               rolename = current->role->rolename;
15772 +               gr_set_acls(1);
15773 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
15774 +       }
15775 +
15776 +       write_lock(&grsec_exec_file_lock);
15777 +       exec_file = current->exec_file;
15778 +       current->exec_file = NULL;
15779 +       write_unlock(&grsec_exec_file_lock);
15780 +
15781 +       if (exec_file)
15782 +               fput(exec_file);
15783 +}
15784 +
15785 +int
15786 +gr_acl_handle_procpidmem(const struct task_struct *task)
15787 +{
15788 +       if (unlikely(!gr_acl_is_enabled()))
15789 +               return 0;
15790 +
15791 +       if (task->acl->mode & GR_PROTPROCFD)
15792 +               return -EACCES;
15793 +
15794 +       return 0;
15795 +}
15796 diff -urNp linux-2.6.18/grsecurity/gracl_ip.c linux-2.6.18/grsecurity/gracl_ip.c
15797 --- linux-2.6.18/grsecurity/gracl_ip.c  1969-12-31 19:00:00.000000000 -0500
15798 +++ linux-2.6.18/grsecurity/gracl_ip.c  2006-09-22 20:04:35.000000000 -0400
15799 @@ -0,0 +1,313 @@
15800 +#include <linux/kernel.h>
15801 +#include <asm/uaccess.h>
15802 +#include <asm/errno.h>
15803 +#include <net/sock.h>
15804 +#include <linux/file.h>
15805 +#include <linux/fs.h>
15806 +#include <linux/net.h>
15807 +#include <linux/in.h>
15808 +#include <linux/skbuff.h>
15809 +#include <linux/ip.h>
15810 +#include <linux/udp.h>
15811 +#include <linux/smp_lock.h>
15812 +#include <linux/types.h>
15813 +#include <linux/sched.h>
15814 +#include <linux/netdevice.h>
15815 +#include <linux/inetdevice.h>
15816 +#include <linux/gracl.h>
15817 +#include <linux/grsecurity.h>
15818 +#include <linux/grinternal.h>
15819 +
15820 +#define GR_BIND        0x01
15821 +#define GR_CONNECT     0x02
15822 +#define GR_INVERT      0x04
15823 +
15824 +static const char * gr_protocols[256] = {
15825 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
15826 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
15827 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
15828 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
15829 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
15830 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
15831 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
15832 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
15833 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
15834 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
15835 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
15836 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
15837 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
15838 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
15839 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
15840 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
15841 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
15842 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
15843 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
15844 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
15845 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
15846 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
15847 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
15848 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
15849 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
15850 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
15851 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
15852 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
15853 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
15854 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
15855 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
15856 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
15857 +       };
15858 +
15859 +static const char * gr_socktypes[11] = {
15860 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
15861 +       "unknown:7", "unknown:8", "unknown:9", "packet"
15862 +       };
15863 +
15864 +const char *
15865 +gr_proto_to_name(unsigned char proto)
15866 +{
15867 +       return gr_protocols[proto];
15868 +}
15869 +
15870 +const char *
15871 +gr_socktype_to_name(unsigned char type)
15872 +{
15873 +       return gr_socktypes[type];
15874 +}
15875 +
15876 +int
15877 +gr_search_socket(const int domain, const int type, const int protocol)
15878 +{
15879 +       struct acl_subject_label *curr;
15880 +
15881 +       if (unlikely(!gr_acl_is_enabled()))
15882 +               goto exit;
15883 +
15884 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
15885 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
15886 +               goto exit;      // let the kernel handle it
15887 +
15888 +       curr = current->acl;
15889 +
15890 +       if (!curr->ips)
15891 +               goto exit;
15892 +
15893 +       if ((curr->ip_type & (1 << type)) &&
15894 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
15895 +               goto exit;
15896 +
15897 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
15898 +               /* we don't place acls on raw sockets , and sometimes
15899 +                  dgram/ip sockets are opened for ioctl and not
15900 +                  bind/connect, so we'll fake a bind learn log */
15901 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
15902 +                       __u32 fakeip = 0;
15903 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15904 +                                      current->role->roletype, current->uid,
15905 +                                      current->gid, current->exec_file ?
15906 +                                      gr_to_filename(current->exec_file->f_dentry,
15907 +                                      current->exec_file->f_vfsmnt) :
15908 +                                      curr->filename, curr->filename,
15909 +                                      NIPQUAD(fakeip), 0, type,
15910 +                                      protocol, GR_CONNECT, 
15911 +NIPQUAD(current->signal->curr_ip));
15912 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
15913 +                       __u32 fakeip = 0;
15914 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15915 +                                      current->role->roletype, current->uid,
15916 +                                      current->gid, current->exec_file ?
15917 +                                      gr_to_filename(current->exec_file->f_dentry,
15918 +                                      current->exec_file->f_vfsmnt) :
15919 +                                      curr->filename, curr->filename,
15920 +                                      NIPQUAD(fakeip), 0, type,
15921 +                                      protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
15922 +               }
15923 +               /* we'll log when they use connect or bind */
15924 +               goto exit;
15925 +       }
15926 +
15927 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
15928 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
15929 +
15930 +       return 0;
15931 +      exit:
15932 +       return 1;
15933 +}
15934 +
15935 +int check_ip_policy(struct acl_ip_label *ip, __u32 ip_addr, __u16 ip_port, __u8 protocol, const int mode, const int type, __u32 our_addr, __u32 our_netmask)
15936 +{
15937 +       if ((ip->mode & mode) &&
15938 +           (ip_port >= ip->low) &&
15939 +           (ip_port <= ip->high) &&
15940 +           ((ntohl(ip_addr) & our_netmask) ==
15941 +            (ntohl(our_addr) & our_netmask))
15942 +           && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
15943 +           && (ip->type & (1 << type))) {
15944 +               if (ip->mode & GR_INVERT)
15945 +                       return 2; // specifically denied
15946 +               else
15947 +                       return 1; // allowed
15948 +       }
15949 +
15950 +       return 0; // not specifically allowed, may continue parsing
15951 +}
15952 +
15953 +static int
15954 +gr_search_connectbind(const int mode, const struct sock *sk,
15955 +                     const struct sockaddr_in *addr, const int type)
15956 +{
15957 +       char iface[IFNAMSIZ] = {0};
15958 +       struct acl_subject_label *curr;
15959 +       struct acl_ip_label *ip;
15960 +       struct net_device *dev;
15961 +       struct in_device *idev;
15962 +       unsigned long i;
15963 +       int ret;
15964 +       __u32 ip_addr = 0;
15965 +       __u32 our_addr;
15966 +       __u32 our_netmask;
15967 +       char *p;
15968 +       __u16 ip_port = 0;
15969 +
15970 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
15971 +               return 1;
15972 +
15973 +       curr = current->acl;
15974 +
15975 +       if (!curr->ips)
15976 +               return 1;
15977 +
15978 +       ip_addr = addr->sin_addr.s_addr;
15979 +       ip_port = ntohs(addr->sin_port);
15980 +
15981 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
15982 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15983 +                              current->role->roletype, current->uid,
15984 +                              current->gid, current->exec_file ?
15985 +                              gr_to_filename(current->exec_file->f_dentry,
15986 +                              current->exec_file->f_vfsmnt) :
15987 +                              curr->filename, curr->filename,
15988 +                              NIPQUAD(ip_addr), ip_port, type,
15989 +                              sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
15990 +               return 1;
15991 +       }
15992 +
15993 +       for (i = 0; i < curr->ip_num; i++) {
15994 +               ip = *(curr->ips + i);
15995 +               if (ip->iface != NULL) {
15996 +                       strncpy(iface, ip->iface, IFNAMSIZ - 1);
15997 +                       p = strchr(iface, ':');
15998 +                       if (p != NULL)
15999 +                               *p = '\0';
16000 +                       dev = dev_get_by_name(iface);
16001 +                       if (dev == NULL)
16002 +                               continue;
16003 +                       idev = in_dev_get(dev);
16004 +                       if (idev == NULL) {
16005 +                               dev_put(dev);
16006 +                               continue;
16007 +                       }
16008 +                       rcu_read_lock();
16009 +                       for_ifa(idev) {
16010 +                               if (!strcmp(ip->iface, ifa->ifa_label)) {
16011 +                                       our_addr = ifa->ifa_address;
16012 +                                       our_netmask = 0xffffffff;
16013 +                                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
16014 +                                       if (ret == 1) {
16015 +                                               rcu_read_unlock();
16016 +                                               in_dev_put(idev);
16017 +                                               dev_put(dev);
16018 +                                               return 1;
16019 +                                       } else if (ret == 2) {
16020 +                                               rcu_read_unlock();
16021 +                                               in_dev_put(idev);
16022 +                                               dev_put(dev);
16023 +                                               goto denied;
16024 +                                       }
16025 +                               }
16026 +                       } endfor_ifa(idev);
16027 +                       rcu_read_unlock();
16028 +                       in_dev_put(idev);
16029 +                       dev_put(dev);
16030 +               } else {
16031 +                       our_addr = ip->addr;
16032 +                       our_netmask = ip->netmask;
16033 +                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
16034 +                       if (ret == 1)
16035 +                               return 1;
16036 +                       else if (ret == 2)
16037 +                               goto denied;
16038 +               }
16039 +       }
16040 +
16041 +denied:
16042 +       if (mode == GR_BIND)
16043 +               gr_log_int5_str2(GR_DONT_AUDIT, GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
16044 +       else if (mode == GR_CONNECT)
16045 +               gr_log_int5_str2(GR_DONT_AUDIT, GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
16046 +
16047 +       return 0;
16048 +}
16049 +
16050 +int
16051 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
16052 +{
16053 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
16054 +}
16055 +
16056 +int
16057 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
16058 +{
16059 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
16060 +}
16061 +
16062 +int gr_search_listen(const struct socket *sock)
16063 +{
16064 +       struct sock *sk = sock->sk;
16065 +       struct sockaddr_in addr;
16066 +
16067 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
16068 +       addr.sin_port = inet_sk(sk)->sport;
16069 +
16070 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
16071 +}
16072 +
16073 +int gr_search_accept(const struct socket *sock)
16074 +{
16075 +       struct sock *sk = sock->sk;
16076 +       struct sockaddr_in addr;
16077 +
16078 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
16079 +       addr.sin_port = inet_sk(sk)->sport;
16080 +
16081 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
16082 +}
16083 +
16084 +int
16085 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
16086 +{
16087 +       if (addr)
16088 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
16089 +       else {
16090 +               struct sockaddr_in sin;
16091 +               const struct inet_sock *inet = inet_sk(sk);
16092 +
16093 +               sin.sin_addr.s_addr = inet->daddr;
16094 +               sin.sin_port = inet->dport;
16095 +
16096 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
16097 +       }
16098 +}
16099 +
16100 +int
16101 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
16102 +{
16103 +       struct sockaddr_in sin;
16104 +
16105 +       if (unlikely(skb->len < sizeof (struct udphdr)))
16106 +               return 1;       // skip this packet
16107 +
16108 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
16109 +       sin.sin_port = skb->h.uh->source;
16110 +
16111 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
16112 +}
16113 diff -urNp linux-2.6.18/grsecurity/gracl_learn.c linux-2.6.18/grsecurity/gracl_learn.c
16114 --- linux-2.6.18/grsecurity/gracl_learn.c       1969-12-31 19:00:00.000000000 -0500
16115 +++ linux-2.6.18/grsecurity/gracl_learn.c       2006-09-22 20:04:35.000000000 -0400
16116 @@ -0,0 +1,204 @@
16117 +#include <linux/kernel.h>
16118 +#include <linux/mm.h>
16119 +#include <linux/sched.h>
16120 +#include <linux/poll.h>
16121 +#include <linux/smp_lock.h>
16122 +#include <linux/string.h>
16123 +#include <linux/file.h>
16124 +#include <linux/types.h>
16125 +#include <linux/vmalloc.h>
16126 +#include <linux/grinternal.h>
16127 +
16128 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
16129 +                                  size_t count, loff_t *ppos);
16130 +extern int gr_acl_is_enabled(void);
16131 +
16132 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
16133 +static int gr_learn_attached;
16134 +
16135 +/* use a 512k buffer */
16136 +#define LEARN_BUFFER_SIZE (512 * 1024)
16137 +
16138 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
16139 +static DECLARE_MUTEX(gr_learn_user_sem);
16140 +
16141 +/* we need to maintain two buffers, so that the kernel context of grlearn
16142 +   uses a semaphore around the userspace copying, and the other kernel contexts
16143 +   use a spinlock when copying into the buffer, since they cannot sleep
16144 +*/
16145 +static char *learn_buffer;
16146 +static char *learn_buffer_user;
16147 +static int learn_buffer_len;
16148 +static int learn_buffer_user_len;
16149 +
16150 +static ssize_t
16151 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
16152 +{
16153 +       DECLARE_WAITQUEUE(wait, current);
16154 +       ssize_t retval = 0;
16155 +
16156 +       add_wait_queue(&learn_wait, &wait);
16157 +       set_current_state(TASK_INTERRUPTIBLE);
16158 +       do {
16159 +               down(&gr_learn_user_sem);
16160 +               spin_lock(&gr_learn_lock);
16161 +               if (learn_buffer_len)
16162 +                       break;
16163 +               spin_unlock(&gr_learn_lock);
16164 +               up(&gr_learn_user_sem);
16165 +               if (file->f_flags & O_NONBLOCK) {
16166 +                       retval = -EAGAIN;
16167 +                       goto out;
16168 +               }
16169 +               if (signal_pending(current)) {
16170 +                       retval = -ERESTARTSYS;
16171 +                       goto out;
16172 +               }
16173 +
16174 +               schedule();
16175 +       } while (1);
16176 +
16177 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
16178 +       learn_buffer_user_len = learn_buffer_len;
16179 +       retval = learn_buffer_len;
16180 +       learn_buffer_len = 0;
16181 +
16182 +       spin_unlock(&gr_learn_lock);
16183 +
16184 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
16185 +               retval = -EFAULT;
16186 +
16187 +       up(&gr_learn_user_sem);
16188 +out:
16189 +       set_current_state(TASK_RUNNING);
16190 +       remove_wait_queue(&learn_wait, &wait);
16191 +       return retval;
16192 +}
16193 +
16194 +static unsigned int
16195 +poll_learn(struct file * file, poll_table * wait)
16196 +{
16197 +       poll_wait(file, &learn_wait, wait);
16198 +
16199 +       if (learn_buffer_len)
16200 +               return (POLLIN | POLLRDNORM);
16201 +
16202 +       return 0;
16203 +}
16204 +
16205 +void
16206 +gr_clear_learn_entries(void)
16207 +{
16208 +       char *tmp;
16209 +
16210 +       down(&gr_learn_user_sem);
16211 +       if (learn_buffer != NULL) {
16212 +               spin_lock(&gr_learn_lock);
16213 +               tmp = learn_buffer;
16214 +               learn_buffer = NULL;
16215 +               spin_unlock(&gr_learn_lock);
16216 +               vfree(learn_buffer);
16217 +       }
16218 +       if (learn_buffer_user != NULL) {
16219 +               vfree(learn_buffer_user);
16220 +               learn_buffer_user = NULL;
16221 +       }
16222 +       learn_buffer_len = 0;
16223 +       up(&gr_learn_user_sem);
16224 +
16225 +       return;
16226 +}
16227 +
16228 +void
16229 +gr_add_learn_entry(const char *fmt, ...)
16230 +{
16231 +       va_list args;
16232 +       unsigned int len;
16233 +
16234 +       if (!gr_learn_attached)
16235 +               return;
16236 +
16237 +       spin_lock(&gr_learn_lock);
16238 +
16239 +       /* leave a gap at the end so we know when it's "full" but don't have to
16240 +          compute the exact length of the string we're trying to append
16241 +       */
16242 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
16243 +               spin_unlock(&gr_learn_lock);
16244 +               wake_up_interruptible(&learn_wait);
16245 +               return;
16246 +       }
16247 +       if (learn_buffer == NULL) {
16248 +               spin_unlock(&gr_learn_lock);
16249 +               return;
16250 +       }
16251 +
16252 +       va_start(args, fmt);
16253 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
16254 +       va_end(args);
16255 +
16256 +       learn_buffer_len += len + 1;
16257 +
16258 +       spin_unlock(&gr_learn_lock);
16259 +       wake_up_interruptible(&learn_wait);
16260 +
16261 +       return;
16262 +}
16263 +
16264 +static int
16265 +open_learn(struct inode *inode, struct file *file)
16266 +{
16267 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
16268 +               return -EBUSY;
16269 +       if (file->f_mode & FMODE_READ) {
16270 +               down(&gr_learn_user_sem);
16271 +               if (learn_buffer == NULL)
16272 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
16273 +               if (learn_buffer_user == NULL)
16274 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
16275 +               if (learn_buffer == NULL)
16276 +                       return -ENOMEM;
16277 +               if (learn_buffer_user == NULL)
16278 +                       return -ENOMEM;
16279 +               learn_buffer_len = 0;
16280 +               learn_buffer_user_len = 0;
16281 +               gr_learn_attached = 1;
16282 +               up(&gr_learn_user_sem);
16283 +       }
16284 +       return 0;
16285 +}
16286 +
16287 +static int
16288 +close_learn(struct inode *inode, struct file *file)
16289 +{
16290 +       char *tmp;
16291 +
16292 +       if (file->f_mode & FMODE_READ) {
16293 +               down(&gr_learn_user_sem);
16294 +               if (learn_buffer != NULL) {
16295 +                       spin_lock(&gr_learn_lock);
16296 +                       tmp = learn_buffer;
16297 +                       learn_buffer = NULL;
16298 +                       spin_unlock(&gr_learn_lock);
16299 +                       vfree(tmp);
16300 +               }
16301 +               if (learn_buffer_user != NULL) {
16302 +                       vfree(learn_buffer_user);
16303 +                       learn_buffer_user = NULL;
16304 +               }
16305 +               learn_buffer_len = 0;
16306 +               learn_buffer_user_len = 0;
16307 +               gr_learn_attached = 0;
16308 +               up(&gr_learn_user_sem);
16309 +       }
16310 +
16311 +       return 0;
16312 +}
16313 +               
16314 +struct file_operations grsec_fops = {
16315 +       .read           = read_learn,
16316 +       .write          = write_grsec_handler,
16317 +       .open           = open_learn,
16318 +       .release        = close_learn,
16319 +       .poll           = poll_learn,
16320 +};
16321 diff -urNp linux-2.6.18/grsecurity/gracl_res.c linux-2.6.18/grsecurity/gracl_res.c
16322 --- linux-2.6.18/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
16323 +++ linux-2.6.18/grsecurity/gracl_res.c 2006-09-22 20:04:35.000000000 -0400
16324 @@ -0,0 +1,45 @@
16325 +#include <linux/kernel.h>
16326 +#include <linux/sched.h>
16327 +#include <linux/gracl.h>
16328 +#include <linux/grinternal.h>
16329 +
16330 +static const char *restab_log[] = {
16331 +       [RLIMIT_CPU] = "RLIMIT_CPU",
16332 +       [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
16333 +       [RLIMIT_DATA] = "RLIMIT_DATA",
16334 +       [RLIMIT_STACK] = "RLIMIT_STACK",
16335 +       [RLIMIT_CORE] = "RLIMIT_CORE",
16336 +       [RLIMIT_RSS] = "RLIMIT_RSS",
16337 +       [RLIMIT_NPROC] = "RLIMIT_NPROC",
16338 +       [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
16339 +       [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
16340 +       [RLIMIT_AS] = "RLIMIT_AS",
16341 +       [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
16342 +       [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
16343 +};
16344 +
16345 +void
16346 +gr_log_resource(const struct task_struct *task,
16347 +               const int res, const unsigned long wanted, const int gt)
16348 +{
16349 +       if (res == RLIMIT_NPROC && 
16350 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
16351 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
16352 +               return;
16353 +       else if (res == RLIMIT_MEMLOCK &&
16354 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
16355 +               return;
16356 +
16357 +       if (!gr_acl_is_enabled() && !grsec_resource_logging)
16358 +               return;
16359 +
16360 +       preempt_disable();
16361 +
16362 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
16363 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
16364 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
16365 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
16366 +       preempt_enable_no_resched();
16367 +
16368 +       return;
16369 +}
16370 diff -urNp linux-2.6.18/grsecurity/gracl_segv.c linux-2.6.18/grsecurity/gracl_segv.c
16371 --- linux-2.6.18/grsecurity/gracl_segv.c        1969-12-31 19:00:00.000000000 -0500
16372 +++ linux-2.6.18/grsecurity/gracl_segv.c        2006-09-22 20:04:35.000000000 -0400
16373 @@ -0,0 +1,295 @@
16374 +#include <linux/kernel.h>
16375 +#include <linux/mm.h>
16376 +#include <asm/uaccess.h>
16377 +#include <asm/errno.h>
16378 +#include <asm/mman.h>
16379 +#include <net/sock.h>
16380 +#include <linux/file.h>
16381 +#include <linux/fs.h>
16382 +#include <linux/net.h>
16383 +#include <linux/in.h>
16384 +#include <linux/smp_lock.h>
16385 +#include <linux/slab.h>
16386 +#include <linux/types.h>
16387 +#include <linux/sched.h>
16388 +#include <linux/timer.h>
16389 +#include <linux/gracl.h>
16390 +#include <linux/grsecurity.h>
16391 +#include <linux/grinternal.h>
16392 +
16393 +static struct crash_uid *uid_set;
16394 +static unsigned short uid_used;
16395 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
16396 +extern rwlock_t gr_inode_lock;
16397 +extern struct acl_subject_label *
16398 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
16399 +                             struct acl_role_label *role);
16400 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
16401 +
16402 +int
16403 +gr_init_uidset(void)
16404 +{
16405 +       uid_set =
16406 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
16407 +       uid_used = 0;
16408 +
16409 +       return uid_set ? 1 : 0;
16410 +}
16411 +
16412 +void
16413 +gr_free_uidset(void)
16414 +{
16415 +       if (uid_set)
16416 +               kfree(uid_set);
16417 +
16418 +       return;
16419 +}
16420 +
16421 +int
16422 +gr_find_uid(const uid_t uid)
16423 +{
16424 +       struct crash_uid *tmp = uid_set;
16425 +       uid_t buid;
16426 +       int low = 0, high = uid_used - 1, mid;
16427 +
16428 +       while (high >= low) {
16429 +               mid = (low + high) >> 1;
16430 +               buid = tmp[mid].uid;
16431 +               if (buid == uid)
16432 +                       return mid;
16433 +               if (buid > uid)
16434 +                       high = mid - 1;
16435 +               if (buid < uid)
16436 +                       low = mid + 1;
16437 +       }
16438 +
16439 +       return -1;
16440 +}
16441 +
16442 +static __inline__ void
16443 +gr_insertsort(void)
16444 +{
16445 +       unsigned short i, j;
16446 +       struct crash_uid index;
16447 +
16448 +       for (i = 1; i < uid_used; i++) {
16449 +               index = uid_set[i];
16450 +               j = i;
16451 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
16452 +                       uid_set[j] = uid_set[j - 1];
16453 +                       j--;
16454 +               }
16455 +               uid_set[j] = index;
16456 +       }
16457 +
16458 +       return;
16459 +}
16460 +
16461 +static __inline__ void
16462 +gr_insert_uid(const uid_t uid, const unsigned long expires)
16463 +{
16464 +       int loc;
16465 +
16466 +       if (uid_used == GR_UIDTABLE_MAX)
16467 +               return;
16468 +
16469 +       loc = gr_find_uid(uid);
16470 +
16471 +       if (loc >= 0) {
16472 +               uid_set[loc].expires = expires;
16473 +               return;
16474 +       }
16475 +
16476 +       uid_set[uid_used].uid = uid;
16477 +       uid_set[uid_used].expires = expires;
16478 +       uid_used++;
16479 +
16480 +       gr_insertsort();
16481 +
16482 +       return;
16483 +}
16484 +
16485 +void
16486 +gr_remove_uid(const unsigned short loc)
16487 +{
16488 +       unsigned short i;
16489 +
16490 +       for (i = loc + 1; i < uid_used; i++)
16491 +               uid_set[i - 1] = uid_set[i];
16492 +
16493 +       uid_used--;
16494 +
16495 +       return;
16496 +}
16497 +
16498 +int
16499 +gr_check_crash_uid(const uid_t uid)
16500 +{
16501 +       int loc;
16502 +       int ret = 0;
16503 +
16504 +       if (unlikely(!gr_acl_is_enabled()))
16505 +               return 0;
16506 +
16507 +       spin_lock(&gr_uid_lock);
16508 +       loc = gr_find_uid(uid);
16509 +
16510 +       if (loc < 0)
16511 +               goto out_unlock;
16512 +
16513 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
16514 +               gr_remove_uid(loc);
16515 +       else
16516 +               ret = 1;
16517 +
16518 +out_unlock:
16519 +       spin_unlock(&gr_uid_lock);
16520 +       return ret;
16521 +}
16522 +
16523 +static __inline__ int
16524 +proc_is_setxid(const struct task_struct *task)
16525 +{
16526 +       if (task->uid != task->euid || task->uid != task->suid ||
16527 +           task->uid != task->fsuid)
16528 +               return 1;
16529 +       if (task->gid != task->egid || task->gid != task->sgid ||
16530 +           task->gid != task->fsgid)
16531 +               return 1;
16532 +
16533 +       return 0;
16534 +}
16535 +static __inline__ int
16536 +gr_fake_force_sig(int sig, struct task_struct *t)
16537 +{
16538 +       unsigned long int flags;
16539 +       int ret;
16540 +
16541 +       spin_lock_irqsave(&t->sighand->siglock, flags);
16542 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
16543 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
16544 +               sigdelset(&t->blocked, sig);
16545 +               recalc_sigpending_tsk(t);
16546 +       }
16547 +       ret = specific_send_sig_info(sig, (void*)1L, t);
16548 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
16549 +
16550 +       return ret;
16551 +}
16552 +
16553 +void
16554 +gr_handle_crash(struct task_struct *task, const int sig)
16555 +{
16556 +       struct acl_subject_label *curr;
16557 +       struct acl_subject_label *curr2;
16558 +       struct task_struct *tsk, *tsk2;
16559 +
16560 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
16561 +               return;
16562 +
16563 +       if (unlikely(!gr_acl_is_enabled()))
16564 +               return;
16565 +
16566 +       curr = task->acl;
16567 +
16568 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
16569 +               return;
16570 +
16571 +       if (time_before_eq(curr->expires, get_seconds())) {
16572 +               curr->expires = 0;
16573 +               curr->crashes = 0;
16574 +       }
16575 +
16576 +       curr->crashes++;
16577 +
16578 +       if (!curr->expires)
16579 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
16580 +
16581 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
16582 +           time_after(curr->expires, get_seconds())) {
16583 +               if (task->uid && proc_is_setxid(task)) {
16584 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
16585 +                       spin_lock(&gr_uid_lock);
16586 +                       gr_insert_uid(task->uid, curr->expires);
16587 +                       spin_unlock(&gr_uid_lock);
16588 +                       curr->expires = 0;
16589 +                       curr->crashes = 0;
16590 +                       read_lock(&tasklist_lock);
16591 +                       do_each_thread(tsk2, tsk) {
16592 +                               if (tsk != task && tsk->uid == task->uid)
16593 +                                       gr_fake_force_sig(SIGKILL, tsk);
16594 +                       } while_each_thread(tsk2, tsk);
16595 +                       read_unlock(&tasklist_lock);
16596 +               } else {
16597 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
16598 +                       read_lock(&tasklist_lock);
16599 +                       do_each_thread(tsk2, tsk) {
16600 +                               if (likely(tsk != task)) {
16601 +                                       curr2 = tsk->acl;
16602 +
16603 +                                       if (curr2->device == curr->device &&
16604 +                                           curr2->inode == curr->inode)
16605 +                                               gr_fake_force_sig(SIGKILL, tsk);
16606 +                               }
16607 +                       } while_each_thread(tsk2, tsk);
16608 +                       read_unlock(&tasklist_lock);
16609 +               }
16610 +       }
16611 +
16612 +       return;
16613 +}
16614 +
16615 +int
16616 +gr_check_crash_exec(const struct file *filp)
16617 +{
16618 +       struct acl_subject_label *curr;
16619 +
16620 +       if (unlikely(!gr_acl_is_enabled()))
16621 +               return 0;
16622 +
16623 +       read_lock(&gr_inode_lock);
16624 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
16625 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
16626 +                                    current->role);
16627 +       read_unlock(&gr_inode_lock);
16628 +
16629 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
16630 +           (!curr->crashes && !curr->expires))
16631 +               return 0;
16632 +
16633 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
16634 +           time_after(curr->expires, get_seconds()))
16635 +               return 1;
16636 +       else if (time_before_eq(curr->expires, get_seconds())) {
16637 +               curr->crashes = 0;
16638 +               curr->expires = 0;
16639 +       }
16640 +
16641 +       return 0;
16642 +}
16643 +
16644 +void
16645 +gr_handle_alertkill(struct task_struct *task)
16646 +{
16647 +       struct acl_subject_label *curracl;
16648 +       __u32 curr_ip;
16649 +       struct task_struct *p, *p2;
16650 +
16651 +       if (unlikely(!gr_acl_is_enabled()))
16652 +               return;
16653 +
16654 +       curracl = task->acl;
16655 +       curr_ip = task->signal->curr_ip;
16656 +
16657 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
16658 +               read_lock(&tasklist_lock);
16659 +               do_each_thread(p2, p) {
16660 +                       if (p->signal->curr_ip == curr_ip)
16661 +                               gr_fake_force_sig(SIGKILL, p);
16662 +               } while_each_thread(p2, p);
16663 +               read_unlock(&tasklist_lock);
16664 +       } else if (curracl->mode & GR_KILLPROC)
16665 +               gr_fake_force_sig(SIGKILL, task);
16666 +
16667 +       return;
16668 +}
16669 diff -urNp linux-2.6.18/grsecurity/gracl_shm.c linux-2.6.18/grsecurity/gracl_shm.c
16670 --- linux-2.6.18/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
16671 +++ linux-2.6.18/grsecurity/gracl_shm.c 2006-09-22 20:04:35.000000000 -0400
16672 @@ -0,0 +1,33 @@
16673 +#include <linux/kernel.h>
16674 +#include <linux/mm.h>
16675 +#include <linux/sched.h>
16676 +#include <linux/file.h>
16677 +#include <linux/ipc.h>
16678 +#include <linux/gracl.h>
16679 +#include <linux/grsecurity.h>
16680 +#include <linux/grinternal.h>
16681 +
16682 +int
16683 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16684 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
16685 +{
16686 +       struct task_struct *task;
16687 +
16688 +       if (!gr_acl_is_enabled())
16689 +               return 1;
16690 +
16691 +       task = find_task_by_pid(shm_cprid);
16692 +
16693 +       if (unlikely(!task))
16694 +               task = find_task_by_pid(shm_lapid);
16695 +
16696 +       if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
16697 +                             (task->pid == shm_lapid)) &&
16698 +                    (task->acl->mode & GR_PROTSHM) &&
16699 +                    (task->acl != current->acl))) {
16700 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
16701 +               return 0;
16702 +       }
16703 +
16704 +       return 1;
16705 +}
16706 diff -urNp linux-2.6.18/grsecurity/grsec_chdir.c linux-2.6.18/grsecurity/grsec_chdir.c
16707 --- linux-2.6.18/grsecurity/grsec_chdir.c       1969-12-31 19:00:00.000000000 -0500
16708 +++ linux-2.6.18/grsecurity/grsec_chdir.c       2006-09-22 20:04:35.000000000 -0400
16709 @@ -0,0 +1,19 @@
16710 +#include <linux/kernel.h>
16711 +#include <linux/sched.h>
16712 +#include <linux/fs.h>
16713 +#include <linux/file.h>
16714 +#include <linux/grsecurity.h>
16715 +#include <linux/grinternal.h>
16716 +
16717 +void
16718 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
16719 +{
16720 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16721 +       if ((grsec_enable_chdir && grsec_enable_group &&
16722 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
16723 +                                             !grsec_enable_group)) {
16724 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
16725 +       }
16726 +#endif
16727 +       return;
16728 +}
16729 diff -urNp linux-2.6.18/grsecurity/grsec_chroot.c linux-2.6.18/grsecurity/grsec_chroot.c
16730 --- linux-2.6.18/grsecurity/grsec_chroot.c      1969-12-31 19:00:00.000000000 -0500
16731 +++ linux-2.6.18/grsecurity/grsec_chroot.c      2006-09-22 20:04:35.000000000 -0400
16732 @@ -0,0 +1,332 @@
16733 +#include <linux/kernel.h>
16734 +#include <linux/module.h>
16735 +#include <linux/sched.h>
16736 +#include <linux/file.h>
16737 +#include <linux/fs.h>
16738 +#include <linux/mount.h>
16739 +#include <linux/types.h>
16740 +#include <linux/grinternal.h>
16741 +
16742 +int
16743 +gr_handle_chroot_unix(const pid_t pid)
16744 +{
16745 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16746 +       struct pid *spid = NULL;
16747 +
16748 +       if (unlikely(!grsec_enable_chroot_unix))
16749 +               return 1;
16750 +
16751 +       if (likely(!proc_is_chrooted(current)))
16752 +               return 1;
16753 +
16754 +       read_lock(&tasklist_lock);
16755 +
16756 +       spid = find_pid(pid);
16757 +       if (spid) {
16758 +               struct task_struct *p;
16759 +               p = pid_task(spid, PIDTYPE_PID);
16760 +               task_lock(p);
16761 +               if (unlikely(!have_same_root(current, p))) {
16762 +                       task_unlock(p);
16763 +                       read_unlock(&tasklist_lock);
16764 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
16765 +                       return 0;
16766 +               }
16767 +               task_unlock(p);
16768 +       }
16769 +       read_unlock(&tasklist_lock);
16770 +#endif
16771 +       return 1;
16772 +}
16773 +
16774 +int
16775 +gr_handle_chroot_nice(void)
16776 +{
16777 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16778 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
16779 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
16780 +               return -EPERM;
16781 +       }
16782 +#endif
16783 +       return 0;
16784 +}
16785 +
16786 +int
16787 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
16788 +{
16789 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16790 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
16791 +                       && proc_is_chrooted(current)) {
16792 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
16793 +               return -EACCES;
16794 +       }
16795 +#endif
16796 +       return 0;
16797 +}
16798 +
16799 +int
16800 +gr_handle_chroot_rawio(const struct inode *inode)
16801 +{
16802 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16803 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
16804 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
16805 +               return 1;
16806 +#endif
16807 +       return 0;
16808 +}
16809 +
16810 +int
16811 +gr_pid_is_chrooted(struct task_struct *p)
16812 +{
16813 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16814 +       if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !p)
16815 +               return 0;
16816 +
16817 +       task_lock(p);
16818 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
16819 +           !have_same_root(current, p)) {
16820 +               task_unlock(p);
16821 +               return 1;
16822 +       }
16823 +       task_unlock(p);
16824 +#endif
16825 +       return 0;
16826 +}
16827 +
16828 +EXPORT_SYMBOL(gr_pid_is_chrooted);
16829 +
16830 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
16831 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
16832 +{
16833 +       struct dentry *dentry = (struct dentry *)u_dentry;
16834 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
16835 +       struct dentry *realroot;
16836 +       struct vfsmount *realrootmnt;
16837 +       struct dentry *currentroot;
16838 +       struct vfsmount *currentmnt;
16839 +       int ret = 1;
16840 +
16841 +       read_lock(&child_reaper->fs->lock);
16842 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
16843 +       realroot = dget(child_reaper->fs->root);
16844 +       read_unlock(&child_reaper->fs->lock);
16845 +
16846 +       read_lock(&current->fs->lock);
16847 +       currentmnt = mntget(current->fs->rootmnt);
16848 +       currentroot = dget(current->fs->root);
16849 +       read_unlock(&current->fs->lock);
16850 +
16851 +       spin_lock(&dcache_lock);
16852 +       for (;;) {
16853 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
16854 +                    || (dentry == currentroot && mnt == currentmnt)))
16855 +                       break;
16856 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
16857 +                       if (mnt->mnt_parent == mnt)
16858 +                               break;
16859 +                       dentry = mnt->mnt_mountpoint;
16860 +                       mnt = mnt->mnt_parent;
16861 +                       continue;
16862 +               }
16863 +               dentry = dentry->d_parent;
16864 +       }
16865 +       spin_unlock(&dcache_lock);
16866 +
16867 +       dput(currentroot);
16868 +       mntput(currentmnt);
16869 +
16870 +       /* access is outside of chroot */
16871 +       if (dentry == realroot && mnt == realrootmnt)
16872 +               ret = 0;
16873 +
16874 +       dput(realroot);
16875 +       mntput(realrootmnt);
16876 +       return ret;
16877 +}
16878 +#endif
16879 +
16880 +int
16881 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
16882 +{
16883 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16884 +       if (!grsec_enable_chroot_fchdir)
16885 +               return 1;
16886 +
16887 +       if (!proc_is_chrooted(current))
16888 +               return 1;
16889 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
16890 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
16891 +               return 0;
16892 +       }
16893 +#endif
16894 +       return 1;
16895 +}
16896 +
16897 +int
16898 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16899 +               const time_t shm_createtime)
16900 +{
16901 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16902 +       struct pid *pid = NULL;
16903 +       time_t starttime;
16904 +
16905 +       if (unlikely(!grsec_enable_chroot_shmat))
16906 +               return 1;
16907 +
16908 +       if (likely(!proc_is_chrooted(current)))
16909 +               return 1;
16910 +
16911 +       read_lock(&tasklist_lock);
16912 +
16913 +       pid = find_pid(shm_cprid);
16914 +       if (pid) {
16915 +               struct task_struct *p;
16916 +               p = pid_task(pid, PIDTYPE_PID);
16917 +               task_lock(p);
16918 +               starttime = p->start_time.tv_sec;
16919 +               if (unlikely(!have_same_root(current, p) &&
16920 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
16921 +                       task_unlock(p);
16922 +                       read_unlock(&tasklist_lock);
16923 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
16924 +                       return 0;
16925 +               }
16926 +               task_unlock(p);
16927 +       } else {
16928 +               pid = find_pid(shm_lapid);
16929 +               if (pid) {
16930 +                       struct task_struct *p;
16931 +                       p = pid_task(pid, PIDTYPE_PID);
16932 +                       task_lock(p);
16933 +                       if (unlikely(!have_same_root(current, p))) {
16934 +                               task_unlock(p);
16935 +                               read_unlock(&tasklist_lock);
16936 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
16937 +                               return 0;
16938 +                       }
16939 +                       task_unlock(p);
16940 +               }
16941 +       }
16942 +
16943 +       read_unlock(&tasklist_lock);
16944 +#endif
16945 +       return 1;
16946 +}
16947 +
16948 +void
16949 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
16950 +{
16951 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16952 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
16953 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
16954 +#endif
16955 +       return;
16956 +}
16957 +
16958 +int
16959 +gr_handle_chroot_mknod(const struct dentry *dentry,
16960 +                      const struct vfsmount *mnt, const int mode)
16961 +{
16962 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16963 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
16964 +           proc_is_chrooted(current)) {
16965 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
16966 +               return -EPERM;
16967 +       }
16968 +#endif
16969 +       return 0;
16970 +}
16971 +
16972 +int
16973 +gr_handle_chroot_mount(const struct dentry *dentry,
16974 +                      const struct vfsmount *mnt, const char *dev_name)
16975 +{
16976 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16977 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
16978 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
16979 +               return -EPERM;
16980 +       }
16981 +#endif
16982 +       return 0;
16983 +}
16984 +
16985 +int
16986 +gr_handle_chroot_pivot(void)
16987 +{
16988 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16989 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
16990 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
16991 +               return -EPERM;
16992 +       }
16993 +#endif
16994 +       return 0;
16995 +}
16996 +
16997 +int
16998 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
16999 +{
17000 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17001 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
17002 +           !gr_is_outside_chroot(dentry, mnt)) {
17003 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
17004 +               return -EPERM;
17005 +       }
17006 +#endif
17007 +       return 0;
17008 +}
17009 +
17010 +void
17011 +gr_handle_chroot_caps(struct task_struct *task)
17012 +{
17013 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17014 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
17015 +               task->cap_permitted =
17016 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
17017 +               task->cap_inheritable =
17018 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
17019 +               task->cap_effective =
17020 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
17021 +       }
17022 +#endif
17023 +       return;
17024 +}
17025 +
17026 +int
17027 +gr_handle_chroot_sysctl(const int op)
17028 +{
17029 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17030 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
17031 +           && (op & 002))
17032 +               return -EACCES;
17033 +#endif
17034 +       return 0;
17035 +}
17036 +
17037 +void
17038 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
17039 +{
17040 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17041 +       if (grsec_enable_chroot_chdir)
17042 +               set_fs_pwd(current->fs, mnt, dentry);
17043 +#endif
17044 +       return;
17045 +}
17046 +
17047 +int
17048 +gr_handle_chroot_chmod(const struct dentry *dentry,
17049 +                      const struct vfsmount *mnt, const int mode)
17050 +{
17051 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17052 +       if (grsec_enable_chroot_chmod &&
17053 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
17054 +           proc_is_chrooted(current)) {
17055 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
17056 +               return -EPERM;
17057 +       }
17058 +#endif
17059 +       return 0;
17060 +}
17061 +
17062 +#ifdef CONFIG_SECURITY
17063 +EXPORT_SYMBOL(gr_handle_chroot_caps);
17064 +#endif
17065 diff -urNp linux-2.6.18/grsecurity/grsec_disabled.c linux-2.6.18/grsecurity/grsec_disabled.c
17066 --- linux-2.6.18/grsecurity/grsec_disabled.c    1969-12-31 19:00:00.000000000 -0500
17067 +++ linux-2.6.18/grsecurity/grsec_disabled.c    2006-09-22 20:04:35.000000000 -0400
17068 @@ -0,0 +1,418 @@
17069 +#include <linux/kernel.h>
17070 +#include <linux/module.h>
17071 +#include <linux/config.h>
17072 +#include <linux/sched.h>
17073 +#include <linux/file.h>
17074 +#include <linux/fs.h>
17075 +#include <linux/kdev_t.h>
17076 +#include <linux/net.h>
17077 +#include <linux/in.h>
17078 +#include <linux/ip.h>
17079 +#include <linux/skbuff.h>
17080 +#include <linux/sysctl.h>
17081 +
17082 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
17083 +void
17084 +pax_set_initial_flags(struct linux_binprm *bprm)
17085 +{
17086 +       return;
17087 +}
17088 +#endif
17089 +
17090 +#ifdef CONFIG_SYSCTL
17091 +__u32
17092 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
17093 +{
17094 +       return mode;
17095 +}
17096 +#endif
17097 +
17098 +int
17099 +gr_acl_is_enabled(void)
17100 +{
17101 +       return 0;
17102 +}
17103 +
17104 +int
17105 +gr_handle_rawio(const struct inode *inode)
17106 +{
17107 +       return 0;
17108 +}
17109 +
17110 +void
17111 +gr_acl_handle_psacct(struct task_struct *task, const long code)
17112 +{
17113 +       return;
17114 +}
17115 +
17116 +int
17117 +gr_handle_ptrace(struct task_struct *task, const long request)
17118 +{
17119 +       return 0;
17120 +}
17121 +
17122 +int
17123 +gr_handle_proc_ptrace(struct task_struct *task)
17124 +{
17125 +       return 0;
17126 +}
17127 +
17128 +void
17129 +gr_learn_resource(const struct task_struct *task,
17130 +                 const int res, const unsigned long wanted, const int gt)
17131 +{
17132 +       return;
17133 +}
17134 +
17135 +int
17136 +gr_set_acls(const int type)
17137 +{
17138 +       return 0;
17139 +}
17140 +
17141 +int
17142 +gr_check_hidden_task(const struct task_struct *tsk)
17143 +{
17144 +       return 0;
17145 +}
17146 +
17147 +int
17148 +gr_check_protected_task(const struct task_struct *task)
17149 +{
17150 +       return 0;
17151 +}
17152 +
17153 +void
17154 +gr_copy_label(struct task_struct *tsk)
17155 +{
17156 +       return;
17157 +}
17158 +
17159 +void
17160 +gr_set_pax_flags(struct task_struct *task)
17161 +{
17162 +       return;
17163 +}
17164 +
17165 +int
17166 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
17167 +{
17168 +       return 0;
17169 +}
17170 +
17171 +void
17172 +gr_handle_delete(const ino_t ino, const dev_t dev)
17173 +{
17174 +       return;
17175 +}
17176 +
17177 +void
17178 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
17179 +{
17180 +       return;
17181 +}
17182 +
17183 +void
17184 +gr_handle_crash(struct task_struct *task, const int sig)
17185 +{
17186 +       return;
17187 +}
17188 +
17189 +int
17190 +gr_check_crash_exec(const struct file *filp)
17191 +{
17192 +       return 0;
17193 +}
17194 +
17195 +int
17196 +gr_check_crash_uid(const uid_t uid)
17197 +{
17198 +       return 0;
17199 +}
17200 +
17201 +void
17202 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
17203 +                struct dentry *old_dentry,
17204 +                struct dentry *new_dentry,
17205 +                struct vfsmount *mnt, const __u8 replace)
17206 +{
17207 +       return;
17208 +}
17209 +
17210 +int
17211 +gr_search_socket(const int family, const int type, const int protocol)
17212 +{
17213 +       return 1;
17214 +}
17215 +
17216 +int
17217 +gr_search_connectbind(const int mode, const struct socket *sock,
17218 +                     const struct sockaddr_in *addr)
17219 +{
17220 +       return 1;
17221 +}
17222 +
17223 +int
17224 +gr_task_is_capable(struct task_struct *task, const int cap)
17225 +{
17226 +       return 1;
17227 +}
17228 +
17229 +int
17230 +gr_is_capable_nolog(const int cap)
17231 +{
17232 +       return 1;
17233 +}
17234 +
17235 +void
17236 +gr_handle_alertkill(struct task_struct *task)
17237 +{
17238 +       return;
17239 +}
17240 +
17241 +__u32
17242 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
17243 +{
17244 +       return 1;
17245 +}
17246 +
17247 +__u32
17248 +gr_acl_handle_hidden_file(const struct dentry * dentry,
17249 +                         const struct vfsmount * mnt)
17250 +{
17251 +       return 1;
17252 +}
17253 +
17254 +__u32
17255 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
17256 +                  const int fmode)
17257 +{
17258 +       return 1;
17259 +}
17260 +
17261 +__u32
17262 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
17263 +{
17264 +       return 1;
17265 +}
17266 +
17267 +__u32
17268 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
17269 +{
17270 +       return 1;
17271 +}
17272 +
17273 +int
17274 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
17275 +                  unsigned int *vm_flags)
17276 +{
17277 +       return 1;
17278 +}
17279 +
17280 +__u32
17281 +gr_acl_handle_truncate(const struct dentry * dentry,
17282 +                      const struct vfsmount * mnt)
17283 +{
17284 +       return 1;
17285 +}
17286 +
17287 +__u32
17288 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
17289 +{
17290 +       return 1;
17291 +}
17292 +
17293 +__u32
17294 +gr_acl_handle_access(const struct dentry * dentry,
17295 +                    const struct vfsmount * mnt, const int fmode)
17296 +{
17297 +       return 1;
17298 +}
17299 +
17300 +__u32
17301 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
17302 +                    mode_t mode)
17303 +{
17304 +       return 1;
17305 +}
17306 +
17307 +__u32
17308 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
17309 +                   mode_t mode)
17310 +{
17311 +       return 1;
17312 +}
17313 +
17314 +__u32
17315 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
17316 +{
17317 +       return 1;
17318 +}
17319 +
17320 +void
17321 +grsecurity_init(void)
17322 +{
17323 +       return;
17324 +}
17325 +
17326 +__u32
17327 +gr_acl_handle_mknod(const struct dentry * new_dentry,
17328 +                   const struct dentry * parent_dentry,
17329 +                   const struct vfsmount * parent_mnt,
17330 +                   const int mode)
17331 +{
17332 +       return 1;
17333 +}
17334 +
17335 +__u32
17336 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
17337 +                   const struct dentry * parent_dentry,
17338 +                   const struct vfsmount * parent_mnt)
17339 +{
17340 +       return 1;
17341 +}
17342 +
17343 +__u32
17344 +gr_acl_handle_symlink(const struct dentry * new_dentry,
17345 +                     const struct dentry * parent_dentry,
17346 +                     const struct vfsmount * parent_mnt, const char *from)
17347 +{
17348 +       return 1;
17349 +}
17350 +
17351 +__u32
17352 +gr_acl_handle_link(const struct dentry * new_dentry,
17353 +                  const struct dentry * parent_dentry,
17354 +                  const struct vfsmount * parent_mnt,
17355 +                  const struct dentry * old_dentry,
17356 +                  const struct vfsmount * old_mnt, const char *to)
17357 +{
17358 +       return 1;
17359 +}
17360 +
17361 +int
17362 +gr_acl_handle_rename(const struct dentry *new_dentry,
17363 +                    const struct dentry *parent_dentry,
17364 +                    const struct vfsmount *parent_mnt,
17365 +                    const struct dentry *old_dentry,
17366 +                    const struct inode *old_parent_inode,
17367 +                    const struct vfsmount *old_mnt, const char *newname)
17368 +{
17369 +       return 0;
17370 +}
17371 +
17372 +int
17373 +gr_acl_handle_filldir(const struct file *file, const char *name,
17374 +                     const int namelen, const ino_t ino)
17375 +{
17376 +       return 1;
17377 +}
17378 +
17379 +int
17380 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
17381 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
17382 +{
17383 +       return 1;
17384 +}
17385 +
17386 +int
17387 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
17388 +{
17389 +       return 1;
17390 +}
17391 +
17392 +int
17393 +gr_search_accept(const struct socket *sock)
17394 +{
17395 +       return 1;
17396 +}
17397 +
17398 +int
17399 +gr_search_listen(const struct socket *sock)
17400 +{
17401 +       return 1;
17402 +}
17403 +
17404 +int
17405 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
17406 +{
17407 +       return 1;
17408 +}
17409 +
17410 +__u32
17411 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
17412 +{
17413 +       return 1;
17414 +}
17415 +
17416 +__u32
17417 +gr_acl_handle_creat(const struct dentry * dentry,
17418 +                   const struct dentry * p_dentry,
17419 +                   const struct vfsmount * p_mnt, const int fmode,
17420 +                   const int imode)
17421 +{
17422 +       return 1;
17423 +}
17424 +
17425 +void
17426 +gr_acl_handle_exit(void)
17427 +{
17428 +       return;
17429 +}
17430 +
17431 +int
17432 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
17433 +{
17434 +       return 1;
17435 +}
17436 +
17437 +void
17438 +gr_set_role_label(const uid_t uid, const gid_t gid)
17439 +{
17440 +       return;
17441 +}
17442 +
17443 +int
17444 +gr_acl_handle_procpidmem(const struct task_struct *task)
17445 +{
17446 +       return 0;
17447 +}
17448 +
17449 +int
17450 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
17451 +{
17452 +       return 1;
17453 +}
17454 +
17455 +int
17456 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
17457 +{
17458 +       return 1;
17459 +}
17460 +
17461 +void
17462 +gr_set_kernel_label(struct task_struct *task)
17463 +{
17464 +       return;
17465 +}
17466 +
17467 +int
17468 +gr_check_user_change(int real, int effective, int fs)
17469 +{
17470 +       return 0;
17471 +}
17472 +
17473 +int
17474 +gr_check_group_change(int real, int effective, int fs)
17475 +{
17476 +       return 0;
17477 +}
17478 +
17479 +
17480 +EXPORT_SYMBOL(gr_task_is_capable);
17481 +EXPORT_SYMBOL(gr_learn_resource);
17482 +EXPORT_SYMBOL(gr_set_kernel_label);
17483 +#ifdef CONFIG_SECURITY
17484 +EXPORT_SYMBOL(gr_check_user_change);
17485 +EXPORT_SYMBOL(gr_check_group_change);
17486 +#endif
17487 diff -urNp linux-2.6.18/grsecurity/grsec_exec.c linux-2.6.18/grsecurity/grsec_exec.c
17488 --- linux-2.6.18/grsecurity/grsec_exec.c        1969-12-31 19:00:00.000000000 -0500
17489 +++ linux-2.6.18/grsecurity/grsec_exec.c        2006-09-22 20:04:35.000000000 -0400
17490 @@ -0,0 +1,88 @@
17491 +#include <linux/kernel.h>
17492 +#include <linux/sched.h>
17493 +#include <linux/file.h>
17494 +#include <linux/binfmts.h>
17495 +#include <linux/smp_lock.h>
17496 +#include <linux/fs.h>
17497 +#include <linux/types.h>
17498 +#include <linux/grdefs.h>
17499 +#include <linux/grinternal.h>
17500 +#include <linux/capability.h>
17501 +
17502 +#include <asm/uaccess.h>
17503 +
17504 +#ifdef CONFIG_GRKERNSEC_EXECLOG
17505 +static char gr_exec_arg_buf[132];
17506 +static DECLARE_MUTEX(gr_exec_arg_sem);
17507 +#endif
17508 +
17509 +int
17510 +gr_handle_nproc(void)
17511 +{
17512 +#ifdef CONFIG_GRKERNSEC_EXECVE
17513 +       if (grsec_enable_execve && current->user &&
17514 +           (atomic_read(&current->user->processes) >
17515 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
17516 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
17517 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
17518 +               return -EAGAIN;
17519 +       }
17520 +#endif
17521 +       return 0;
17522 +}
17523 +
17524 +void
17525 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
17526 +{
17527 +#ifdef CONFIG_GRKERNSEC_EXECLOG
17528 +       char *grarg = gr_exec_arg_buf;
17529 +       unsigned int i, x, execlen = 0;
17530 +       char c;
17531 +
17532 +       if (!((grsec_enable_execlog && grsec_enable_group &&
17533 +              in_group_p(grsec_audit_gid))
17534 +             || (grsec_enable_execlog && !grsec_enable_group)))
17535 +               return;
17536 +
17537 +       down(&gr_exec_arg_sem);
17538 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
17539 +
17540 +       if (unlikely(argv == NULL))
17541 +               goto log;
17542 +
17543 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
17544 +               const char __user *p;
17545 +               unsigned int len;
17546 +
17547 +               if (copy_from_user(&p, argv + i, sizeof(p)))
17548 +                       goto log;
17549 +               if (!p)
17550 +                       goto log;
17551 +               len = strnlen_user(p, 128 - execlen);
17552 +               if (len > 128 - execlen)
17553 +                       len = 128 - execlen;
17554 +               else if (len > 0)
17555 +                       len--;
17556 +               if (copy_from_user(grarg + execlen, p, len))
17557 +                       goto log;
17558 +
17559 +               /* rewrite unprintable characters */
17560 +               for (x = 0; x < len; x++) {
17561 +                       c = *(grarg + execlen + x);
17562 +                       if (c < 32 || c > 126)
17563 +                               *(grarg + execlen + x) = ' ';
17564 +               }
17565 +
17566 +               execlen += len;
17567 +               *(grarg + execlen) = ' ';
17568 +               *(grarg + execlen + 1) = '\0';
17569 +               execlen++;
17570 +       }
17571 +
17572 +      log:
17573 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
17574 +                       bprm->file->f_vfsmnt, grarg);
17575 +       up(&gr_exec_arg_sem);
17576 +#endif
17577 +       return;
17578 +}
17579 diff -urNp linux-2.6.18/grsecurity/grsec_fifo.c linux-2.6.18/grsecurity/grsec_fifo.c
17580 --- linux-2.6.18/grsecurity/grsec_fifo.c        1969-12-31 19:00:00.000000000 -0500
17581 +++ linux-2.6.18/grsecurity/grsec_fifo.c        2006-09-22 20:04:35.000000000 -0400
17582 @@ -0,0 +1,22 @@
17583 +#include <linux/kernel.h>
17584 +#include <linux/sched.h>
17585 +#include <linux/fs.h>
17586 +#include <linux/file.h>
17587 +#include <linux/grinternal.h>
17588 +
17589 +int
17590 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
17591 +              const struct dentry *dir, const int flag, const int acc_mode)
17592 +{
17593 +#ifdef CONFIG_GRKERNSEC_FIFO
17594 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
17595 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
17596 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
17597 +           (current->fsuid != dentry->d_inode->i_uid)) {
17598 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
17599 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
17600 +               return -EACCES;
17601 +       }
17602 +#endif
17603 +       return 0;
17604 +}
17605 diff -urNp linux-2.6.18/grsecurity/grsec_fork.c linux-2.6.18/grsecurity/grsec_fork.c
17606 --- linux-2.6.18/grsecurity/grsec_fork.c        1969-12-31 19:00:00.000000000 -0500
17607 +++ linux-2.6.18/grsecurity/grsec_fork.c        2006-09-22 20:04:35.000000000 -0400
17608 @@ -0,0 +1,15 @@
17609 +#include <linux/kernel.h>
17610 +#include <linux/sched.h>
17611 +#include <linux/grsecurity.h>
17612 +#include <linux/grinternal.h>
17613 +#include <linux/errno.h>
17614 +
17615 +void
17616 +gr_log_forkfail(const int retval)
17617 +{
17618 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
17619 +       if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
17620 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
17621 +#endif
17622 +       return;
17623 +}
17624 diff -urNp linux-2.6.18/grsecurity/grsec_init.c linux-2.6.18/grsecurity/grsec_init.c
17625 --- linux-2.6.18/grsecurity/grsec_init.c        1969-12-31 19:00:00.000000000 -0500
17626 +++ linux-2.6.18/grsecurity/grsec_init.c        2006-09-22 20:04:35.000000000 -0400
17627 @@ -0,0 +1,236 @@
17628 +#include <linux/kernel.h>
17629 +#include <linux/sched.h>
17630 +#include <linux/mm.h>
17631 +#include <linux/smp_lock.h>
17632 +#include <linux/gracl.h>
17633 +#include <linux/slab.h>
17634 +#include <linux/vmalloc.h>
17635 +#include <linux/percpu.h>
17636 +
17637 +int grsec_enable_shm;
17638 +int grsec_enable_link;
17639 +int grsec_enable_dmesg;
17640 +int grsec_enable_fifo;
17641 +int grsec_enable_execve;
17642 +int grsec_enable_execlog;
17643 +int grsec_enable_signal;
17644 +int grsec_enable_forkfail;
17645 +int grsec_enable_time;
17646 +int grsec_enable_audit_textrel;
17647 +int grsec_enable_group;
17648 +int grsec_audit_gid;
17649 +int grsec_enable_chdir;
17650 +int grsec_enable_audit_ipc;
17651 +int grsec_enable_mount;
17652 +int grsec_enable_chroot_findtask;
17653 +int grsec_enable_chroot_mount;
17654 +int grsec_enable_chroot_shmat;
17655 +int grsec_enable_chroot_fchdir;
17656 +int grsec_enable_chroot_double;
17657 +int grsec_enable_chroot_pivot;
17658 +int grsec_enable_chroot_chdir;
17659 +int grsec_enable_chroot_chmod;
17660 +int grsec_enable_chroot_mknod;
17661 +int grsec_enable_chroot_nice;
17662 +int grsec_enable_chroot_execlog;
17663 +int grsec_enable_chroot_caps;
17664 +int grsec_enable_chroot_sysctl;
17665 +int grsec_enable_chroot_unix;
17666 +int grsec_enable_tpe;
17667 +int grsec_tpe_gid;
17668 +int grsec_enable_tpe_all;
17669 +int grsec_enable_randpid;
17670 +int grsec_enable_socket_all;
17671 +int grsec_socket_all_gid;
17672 +int grsec_enable_socket_client;
17673 +int grsec_socket_client_gid;
17674 +int grsec_enable_socket_server;
17675 +int grsec_socket_server_gid;
17676 +int grsec_resource_logging;
17677 +int grsec_lock;
17678 +
17679 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
17680 +unsigned long grsec_alert_wtime = 0;
17681 +unsigned long grsec_alert_fyet = 0;
17682 +
17683 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
17684 +
17685 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
17686 +
17687 +char *gr_shared_page[4];
17688 +
17689 +char *gr_alert_log_fmt;
17690 +char *gr_audit_log_fmt;
17691 +char *gr_alert_log_buf;
17692 +char *gr_audit_log_buf;
17693 +
17694 +extern struct gr_arg *gr_usermode;
17695 +extern unsigned char *gr_system_salt;
17696 +extern unsigned char *gr_system_sum;
17697 +
17698 +void
17699 +grsecurity_init(void)
17700 +{
17701 +       int j;
17702 +       /* create the per-cpu shared pages */
17703 +
17704 +       preempt_disable();
17705 +       for (j = 0; j < 4; j++) {
17706 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
17707 +               if (gr_shared_page[j] == NULL) {
17708 +                       panic("Unable to allocate grsecurity shared page");
17709 +                       return;
17710 +               }
17711 +       }
17712 +       preempt_enable();
17713 +
17714 +       /* allocate log buffers */
17715 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
17716 +       if (!gr_alert_log_fmt) {
17717 +               panic("Unable to allocate grsecurity alert log format buffer");
17718 +               return;
17719 +       }
17720 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
17721 +       if (!gr_audit_log_fmt) {
17722 +               panic("Unable to allocate grsecurity audit log format buffer");
17723 +               return;
17724 +       }
17725 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
17726 +       if (!gr_alert_log_buf) {
17727 +               panic("Unable to allocate grsecurity alert log buffer");
17728 +               return;
17729 +       }
17730 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
17731 +       if (!gr_audit_log_buf) {
17732 +               panic("Unable to allocate grsecurity audit log buffer");
17733 +               return;
17734 +       }
17735 +
17736 +       /* allocate memory for authentication structure */
17737 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
17738 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
17739 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
17740 +
17741 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
17742 +               panic("Unable to allocate grsecurity authentication structure");
17743 +               return;
17744 +       }
17745 +
17746 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
17747 +#ifndef CONFIG_GRKERNSEC_SYSCTL
17748 +       grsec_lock = 1;
17749 +#endif
17750 +#ifdef CONFIG_GRKERNSEC_SHM
17751 +       grsec_enable_shm = 1;
17752 +#endif
17753 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
17754 +       grsec_enable_audit_textrel = 1;
17755 +#endif
17756 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
17757 +       grsec_enable_group = 1;
17758 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
17759 +#endif
17760 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
17761 +       grsec_enable_chdir = 1;
17762 +#endif
17763 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17764 +       grsec_enable_audit_ipc = 1;
17765 +#endif
17766 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17767 +       grsec_enable_mount = 1;
17768 +#endif
17769 +#ifdef CONFIG_GRKERNSEC_LINK
17770 +       grsec_enable_link = 1;
17771 +#endif
17772 +#ifdef CONFIG_GRKERNSEC_DMESG
17773 +       grsec_enable_dmesg = 1;
17774 +#endif
17775 +#ifdef CONFIG_GRKERNSEC_FIFO
17776 +       grsec_enable_fifo = 1;
17777 +#endif
17778 +#ifdef CONFIG_GRKERNSEC_EXECVE
17779 +       grsec_enable_execve = 1;
17780 +#endif
17781 +#ifdef CONFIG_GRKERNSEC_EXECLOG
17782 +       grsec_enable_execlog = 1;
17783 +#endif
17784 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17785 +       grsec_enable_signal = 1;
17786 +#endif
17787 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
17788 +       grsec_enable_forkfail = 1;
17789 +#endif
17790 +#ifdef CONFIG_GRKERNSEC_TIME
17791 +       grsec_enable_time = 1;
17792 +#endif
17793 +#ifdef CONFIG_GRKERNSEC_RESLOG
17794 +       grsec_resource_logging = 1;
17795 +#endif
17796 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
17797 +       grsec_enable_chroot_findtask = 1;
17798 +#endif
17799 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
17800 +       grsec_enable_chroot_unix = 1;
17801 +#endif
17802 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
17803 +       grsec_enable_chroot_mount = 1;
17804 +#endif
17805 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
17806 +       grsec_enable_chroot_fchdir = 1;
17807 +#endif
17808 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
17809 +       grsec_enable_chroot_shmat = 1;
17810 +#endif
17811 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17812 +       grsec_enable_chroot_double = 1;
17813 +#endif
17814 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
17815 +       grsec_enable_chroot_pivot = 1;
17816 +#endif
17817 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17818 +       grsec_enable_chroot_chdir = 1;
17819 +#endif
17820 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17821 +       grsec_enable_chroot_chmod = 1;
17822 +#endif
17823 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
17824 +       grsec_enable_chroot_mknod = 1;
17825 +#endif
17826 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17827 +       grsec_enable_chroot_nice = 1;
17828 +#endif
17829 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
17830 +       grsec_enable_chroot_execlog = 1;
17831 +#endif
17832 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17833 +       grsec_enable_chroot_caps = 1;
17834 +#endif
17835 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17836 +       grsec_enable_chroot_sysctl = 1;
17837 +#endif
17838 +#ifdef CONFIG_GRKERNSEC_TPE
17839 +       grsec_enable_tpe = 1;
17840 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
17841 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
17842 +       grsec_enable_tpe_all = 1;
17843 +#endif
17844 +#endif
17845 +#ifdef CONFIG_GRKERNSEC_RANDPID
17846 +       grsec_enable_randpid = 1;
17847 +#endif
17848 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
17849 +       grsec_enable_socket_all = 1;
17850 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
17851 +#endif
17852 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
17853 +       grsec_enable_socket_client = 1;
17854 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
17855 +#endif
17856 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
17857 +       grsec_enable_socket_server = 1;
17858 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
17859 +#endif
17860 +#endif
17861 +
17862 +       return;
17863 +}
17864 diff -urNp linux-2.6.18/grsecurity/grsec_ipc.c linux-2.6.18/grsecurity/grsec_ipc.c
17865 --- linux-2.6.18/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
17866 +++ linux-2.6.18/grsecurity/grsec_ipc.c 2006-09-22 20:04:35.000000000 -0400
17867 @@ -0,0 +1,81 @@
17868 +#include <linux/kernel.h>
17869 +#include <linux/sched.h>
17870 +#include <linux/types.h>
17871 +#include <linux/ipc.h>
17872 +#include <linux/grsecurity.h>
17873 +#include <linux/grinternal.h>
17874 +
17875 +void
17876 +gr_log_msgget(const int ret, const int msgflg)
17877 +{
17878 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17879 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17880 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17881 +                                         !grsec_enable_group)) && (ret >= 0)
17882 +           && (msgflg & IPC_CREAT))
17883 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
17884 +#endif
17885 +       return;
17886 +}
17887 +
17888 +void
17889 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
17890 +{
17891 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17892 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17893 +            grsec_enable_audit_ipc) ||
17894 +           (grsec_enable_audit_ipc && !grsec_enable_group))
17895 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
17896 +#endif
17897 +       return;
17898 +}
17899 +
17900 +void
17901 +gr_log_semget(const int err, const int semflg)
17902 +{
17903 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17904 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17905 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17906 +                                         !grsec_enable_group)) && (err >= 0)
17907 +           && (semflg & IPC_CREAT))
17908 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
17909 +#endif
17910 +       return;
17911 +}
17912 +
17913 +void
17914 +gr_log_semrm(const uid_t uid, const uid_t cuid)
17915 +{
17916 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17917 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17918 +            grsec_enable_audit_ipc) ||
17919 +           (grsec_enable_audit_ipc && !grsec_enable_group))
17920 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
17921 +#endif
17922 +       return;
17923 +}
17924 +
17925 +void
17926 +gr_log_shmget(const int err, const int shmflg, const size_t size)
17927 +{
17928 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17929 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17930 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17931 +                                         !grsec_enable_group)) && (err >= 0)
17932 +           && (shmflg & IPC_CREAT))
17933 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
17934 +#endif
17935 +       return;
17936 +}
17937 +
17938 +void
17939 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
17940 +{
17941 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17942 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17943 +            grsec_enable_audit_ipc) ||
17944 +           (grsec_enable_audit_ipc && !grsec_enable_group))
17945 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
17946 +#endif
17947 +       return;
17948 +}
17949 diff -urNp linux-2.6.18/grsecurity/grsec_link.c linux-2.6.18/grsecurity/grsec_link.c
17950 --- linux-2.6.18/grsecurity/grsec_link.c        1969-12-31 19:00:00.000000000 -0500
17951 +++ linux-2.6.18/grsecurity/grsec_link.c        2006-09-22 20:04:35.000000000 -0400
17952 @@ -0,0 +1,39 @@
17953 +#include <linux/kernel.h>
17954 +#include <linux/sched.h>
17955 +#include <linux/fs.h>
17956 +#include <linux/file.h>
17957 +#include <linux/grinternal.h>
17958 +
17959 +int
17960 +gr_handle_follow_link(const struct inode *parent,
17961 +                     const struct inode *inode,
17962 +                     const struct dentry *dentry, const struct vfsmount *mnt)
17963 +{
17964 +#ifdef CONFIG_GRKERNSEC_LINK
17965 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
17966 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
17967 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
17968 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
17969 +               return -EACCES;
17970 +       }
17971 +#endif
17972 +       return 0;
17973 +}
17974 +
17975 +int
17976 +gr_handle_hardlink(const struct dentry *dentry,
17977 +                  const struct vfsmount *mnt,
17978 +                  struct inode *inode, const int mode, const char *to)
17979 +{
17980 +#ifdef CONFIG_GRKERNSEC_LINK
17981 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
17982 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
17983 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
17984 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
17985 +           !capable(CAP_FOWNER) && current->uid) {
17986 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
17987 +               return -EPERM;
17988 +       }
17989 +#endif
17990 +       return 0;
17991 +}
17992 diff -urNp linux-2.6.18/grsecurity/grsec_log.c linux-2.6.18/grsecurity/grsec_log.c
17993 --- linux-2.6.18/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
17994 +++ linux-2.6.18/grsecurity/grsec_log.c 2006-09-22 20:04:35.000000000 -0400
17995 @@ -0,0 +1,265 @@
17996 +#include <linux/kernel.h>
17997 +#include <linux/sched.h>
17998 +#include <linux/file.h>
17999 +#include <linux/tty.h>
18000 +#include <linux/fs.h>
18001 +#include <linux/grinternal.h>
18002 +
18003 +#define BEGIN_LOCKS(x) \
18004 +       read_lock(&tasklist_lock); \
18005 +       read_lock(&grsec_exec_file_lock); \
18006 +       if (x != GR_DO_AUDIT) \
18007 +               spin_lock(&grsec_alert_lock); \
18008 +       else \
18009 +               spin_lock(&grsec_audit_lock)
18010 +
18011 +#define END_LOCKS(x) \
18012 +       if (x != GR_DO_AUDIT) \
18013 +               spin_unlock(&grsec_alert_lock); \
18014 +       else \
18015 +               spin_unlock(&grsec_audit_lock); \
18016 +       read_unlock(&grsec_exec_file_lock); \
18017 +       read_unlock(&tasklist_lock); \
18018 +       if (x == GR_DONT_AUDIT) \
18019 +               gr_handle_alertkill(current)
18020 +
18021 +enum {
18022 +       FLOODING,
18023 +       NO_FLOODING
18024 +};
18025 +
18026 +extern char *gr_alert_log_fmt;
18027 +extern char *gr_audit_log_fmt;
18028 +extern char *gr_alert_log_buf;
18029 +extern char *gr_audit_log_buf;
18030 +
18031 +static int gr_log_start(int audit)
18032 +{
18033 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
18034 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
18035 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18036 +
18037 +       if (audit == GR_DO_AUDIT)
18038 +               goto set_fmt;
18039 +
18040 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
18041 +               grsec_alert_wtime = jiffies;
18042 +               grsec_alert_fyet = 0;
18043 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
18044 +               grsec_alert_fyet++;
18045 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
18046 +               grsec_alert_wtime = jiffies;
18047 +               grsec_alert_fyet++;
18048 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
18049 +               return FLOODING;
18050 +       } else return FLOODING;
18051 +
18052 +set_fmt:
18053 +       memset(buf, 0, PAGE_SIZE);
18054 +       if (current->signal->curr_ip && gr_acl_is_enabled()) {
18055 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
18056 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
18057 +       } else if (current->signal->curr_ip) {
18058 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
18059 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
18060 +       } else if (gr_acl_is_enabled()) {
18061 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
18062 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
18063 +       } else {
18064 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
18065 +               strcpy(buf, fmt);
18066 +       }
18067 +
18068 +       return NO_FLOODING;
18069 +}
18070 +
18071 +static void gr_log_middle(int audit, const char *msg, va_list ap)
18072 +{
18073 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18074 +       unsigned int len = strlen(buf);
18075 +
18076 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
18077 +
18078 +       return;
18079 +}
18080 +
18081 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
18082 +{
18083 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18084 +       unsigned int len = strlen(buf);
18085 +       va_list ap;
18086 +
18087 +       va_start(ap, msg);
18088 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
18089 +       va_end(ap);
18090 +
18091 +       return;
18092 +}
18093 +
18094 +static void gr_log_end(int audit)
18095 +{
18096 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18097 +       unsigned int len = strlen(buf);
18098 +
18099 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
18100 +       printk("%s\n", buf);
18101 +
18102 +       return;
18103 +}
18104 +
18105 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
18106 +{
18107 +       int logtype;
18108 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
18109 +       char *str1, *str2, *str3;
18110 +       int num1, num2;
18111 +       unsigned long ulong1, ulong2;
18112 +       struct dentry *dentry;
18113 +       struct vfsmount *mnt;
18114 +       struct file *file;
18115 +       struct task_struct *task;
18116 +       va_list ap;
18117 +
18118 +       BEGIN_LOCKS(audit);
18119 +       logtype = gr_log_start(audit);
18120 +       if (logtype == FLOODING) {
18121 +               END_LOCKS(audit);
18122 +               return;
18123 +       }
18124 +       va_start(ap, argtypes);
18125 +       switch (argtypes) {
18126 +       case GR_TTYSNIFF:
18127 +               task = va_arg(ap, struct task_struct *);
18128 +               gr_log_middle_varargs(audit, msg, NIPQUAD(task->signal->curr_ip), gr_task_fullpath0(task), task->comm, task->pid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid);
18129 +               break;
18130 +       case GR_RBAC:
18131 +               dentry = va_arg(ap, struct dentry *);
18132 +               mnt = va_arg(ap, struct vfsmount *);
18133 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
18134 +               break;
18135 +       case GR_RBAC_STR:
18136 +               dentry = va_arg(ap, struct dentry *);
18137 +               mnt = va_arg(ap, struct vfsmount *);
18138 +               str1 = va_arg(ap, char *);
18139 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
18140 +               break;
18141 +       case GR_STR_RBAC:
18142 +               str1 = va_arg(ap, char *);
18143 +               dentry = va_arg(ap, struct dentry *);
18144 +               mnt = va_arg(ap, struct vfsmount *);
18145 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
18146 +               break;
18147 +       case GR_RBAC_MODE2:
18148 +               dentry = va_arg(ap, struct dentry *);
18149 +               mnt = va_arg(ap, struct vfsmount *);
18150 +               str1 = va_arg(ap, char *);
18151 +               str2 = va_arg(ap, char *);
18152 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
18153 +               break;
18154 +       case GR_RBAC_MODE3:
18155 +               dentry = va_arg(ap, struct dentry *);
18156 +               mnt = va_arg(ap, struct vfsmount *);
18157 +               str1 = va_arg(ap, char *);
18158 +               str2 = va_arg(ap, char *);
18159 +               str3 = va_arg(ap, char *);
18160 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
18161 +               break;
18162 +       case GR_FILENAME:
18163 +               dentry = va_arg(ap, struct dentry *);
18164 +               mnt = va_arg(ap, struct vfsmount *);
18165 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
18166 +               break;
18167 +       case GR_STR_FILENAME:
18168 +               str1 = va_arg(ap, char *);
18169 +               dentry = va_arg(ap, struct dentry *);
18170 +               mnt = va_arg(ap, struct vfsmount *);
18171 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
18172 +               break;
18173 +       case GR_FILENAME_STR:
18174 +               dentry = va_arg(ap, struct dentry *);
18175 +               mnt = va_arg(ap, struct vfsmount *);
18176 +               str1 = va_arg(ap, char *);
18177 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
18178 +               break;
18179 +       case GR_FILENAME_TWO_INT:
18180 +               dentry = va_arg(ap, struct dentry *);
18181 +               mnt = va_arg(ap, struct vfsmount *);
18182 +               num1 = va_arg(ap, int);
18183 +               num2 = va_arg(ap, int);
18184 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
18185 +               break;
18186 +       case GR_FILENAME_TWO_INT_STR:
18187 +               dentry = va_arg(ap, struct dentry *);
18188 +               mnt = va_arg(ap, struct vfsmount *);
18189 +               num1 = va_arg(ap, int);
18190 +               num2 = va_arg(ap, int);
18191 +               str1 = va_arg(ap, char *);
18192 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
18193 +               break;
18194 +       case GR_TEXTREL:
18195 +               file = va_arg(ap, struct file *);
18196 +               ulong1 = va_arg(ap, unsigned long);
18197 +               ulong2 = va_arg(ap, unsigned long);
18198 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
18199 +               break;
18200 +       case GR_PTRACE:
18201 +               task = va_arg(ap, struct task_struct *);
18202 +               gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) : "(none)", task->comm, task->pid);
18203 +               break;
18204 +       case GR_RESOURCE:
18205 +               task = va_arg(ap, struct task_struct *);
18206 +               ulong1 = va_arg(ap, unsigned long);
18207 +               str1 = va_arg(ap, char *);
18208 +               ulong2 = va_arg(ap, unsigned long);
18209 +               gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
18210 +               break;
18211 +       case GR_CAP:
18212 +               task = va_arg(ap, struct task_struct *);
18213 +               str1 = va_arg(ap, char *);
18214 +               gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
18215 +               break;
18216 +       case GR_SIG:
18217 +               task = va_arg(ap, struct task_struct *);
18218 +               num1 = va_arg(ap, int);
18219 +               gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
18220 +               break;
18221 +       case GR_CRASH1:
18222 +               task = va_arg(ap, struct task_struct *);
18223 +               ulong1 = va_arg(ap, unsigned long);
18224 +               gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, task->uid, ulong1);
18225 +               break;
18226 +       case GR_CRASH2:
18227 +               task = va_arg(ap, struct task_struct *);
18228 +               ulong1 = va_arg(ap, unsigned long);
18229 +               gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, ulong1);
18230 +               break;
18231 +       case GR_PSACCT:
18232 +               {
18233 +                       unsigned int wday, cday;
18234 +                       __u8 whr, chr;
18235 +                       __u8 wmin, cmin;
18236 +                       __u8 wsec, csec;
18237 +                       char cur_tty[64] = { 0 };
18238 +                       char parent_tty[64] = { 0 };
18239 +
18240 +                       task = va_arg(ap, struct task_struct *);
18241 +                       wday = va_arg(ap, unsigned int);
18242 +                       cday = va_arg(ap, unsigned int);
18243 +                       whr = va_arg(ap, int);
18244 +                       chr = va_arg(ap, int);
18245 +                       wmin = va_arg(ap, int);
18246 +                       cmin = va_arg(ap, int);
18247 +                       wsec = va_arg(ap, int);
18248 +                       csec = va_arg(ap, int);
18249 +                       ulong1 = va_arg(ap, unsigned long);
18250 +
18251 +                       gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, NIPQUAD(task->signal->curr_ip), tty_name(task->signal->tty, cur_tty), task->uid, task->euid, task->gid, task->egid, wday, whr, wmin, wsec, cday, chr, cmin, csec, (task->flags & PF_SIGNALED) ? "killed by signal" : "exited", ulong1, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, NIPQUAD(task->parent->signal->curr_ip), tty_name(task->parent->signal->tty, parent_tty), task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
18252 +               }
18253 +               break;
18254 +       default:
18255 +               gr_log_middle(audit, msg, ap);
18256 +       }
18257 +       va_end(ap);
18258 +       gr_log_end(audit);
18259 +       END_LOCKS(audit);
18260 +}
18261 diff -urNp linux-2.6.18/grsecurity/grsec_mem.c linux-2.6.18/grsecurity/grsec_mem.c
18262 --- linux-2.6.18/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
18263 +++ linux-2.6.18/grsecurity/grsec_mem.c 2006-09-22 20:04:35.000000000 -0400
18264 @@ -0,0 +1,71 @@
18265 +#include <linux/kernel.h>
18266 +#include <linux/sched.h>
18267 +#include <linux/mm.h>
18268 +#include <linux/mman.h>
18269 +#include <linux/grinternal.h>
18270 +
18271 +void
18272 +gr_handle_ioperm(void)
18273 +{
18274 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
18275 +       return;
18276 +}
18277 +
18278 +void
18279 +gr_handle_iopl(void)
18280 +{
18281 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
18282 +       return;
18283 +}
18284 +
18285 +void
18286 +gr_handle_mem_write(void)
18287 +{
18288 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
18289 +       return;
18290 +}
18291 +
18292 +void
18293 +gr_handle_kmem_write(void)
18294 +{
18295 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
18296 +       return;
18297 +}
18298 +
18299 +void
18300 +gr_handle_open_port(void)
18301 +{
18302 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
18303 +       return;
18304 +}
18305 +
18306 +int
18307 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
18308 +{
18309 +       unsigned long start, end;
18310 +
18311 +       start = offset;
18312 +       end = start + vma->vm_end - vma->vm_start;
18313 +
18314 +       if (start > end) {
18315 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
18316 +               return -EPERM;
18317 +       }
18318 +
18319 +       /* allowed ranges : ISA I/O BIOS */
18320 +       if ((start >= __pa(high_memory))
18321 +#ifdef CONFIG_X86
18322 +           || (start >= 0x000a0000 && end <= 0x00100000)
18323 +           || (start >= 0x00000000 && end <= 0x00001000)
18324 +#endif
18325 +       )
18326 +               return 0;
18327 +
18328 +       if (vma->vm_flags & VM_WRITE) {
18329 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
18330 +               return -EPERM;
18331 +       } else
18332 +               vma->vm_flags &= ~VM_MAYWRITE;
18333 +
18334 +       return 0;
18335 +}
18336 diff -urNp linux-2.6.18/grsecurity/grsec_mount.c linux-2.6.18/grsecurity/grsec_mount.c
18337 --- linux-2.6.18/grsecurity/grsec_mount.c       1969-12-31 19:00:00.000000000 -0500
18338 +++ linux-2.6.18/grsecurity/grsec_mount.c       2006-09-22 20:04:35.000000000 -0400
18339 @@ -0,0 +1,34 @@
18340 +#include <linux/kernel.h>
18341 +#include <linux/sched.h>
18342 +#include <linux/grsecurity.h>
18343 +#include <linux/grinternal.h>
18344 +
18345 +void
18346 +gr_log_remount(const char *devname, const int retval)
18347 +{
18348 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18349 +       if (grsec_enable_mount && (retval >= 0))
18350 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
18351 +#endif
18352 +       return;
18353 +}
18354 +
18355 +void
18356 +gr_log_unmount(const char *devname, const int retval)
18357 +{
18358 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18359 +       if (grsec_enable_mount && (retval >= 0))
18360 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
18361 +#endif
18362 +       return;
18363 +}
18364 +
18365 +void
18366 +gr_log_mount(const char *from, const char *to, const int retval)
18367 +{
18368 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18369 +       if (grsec_enable_mount && (retval >= 0))
18370 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
18371 +#endif
18372 +       return;
18373 +}
18374 diff -urNp linux-2.6.18/grsecurity/grsec_rand.c linux-2.6.18/grsecurity/grsec_rand.c
18375 --- linux-2.6.18/grsecurity/grsec_rand.c        1969-12-31 19:00:00.000000000 -0500
18376 +++ linux-2.6.18/grsecurity/grsec_rand.c        2006-09-22 20:04:35.000000000 -0400
18377 @@ -0,0 +1,26 @@
18378 +#include <linux/kernel.h>
18379 +#include <linux/sched.h>
18380 +#include <linux/smp_lock.h>
18381 +#include <linux/grsecurity.h>
18382 +#include <linux/grinternal.h>
18383 +
18384 +extern int pid_max;
18385 +
18386 +int
18387 +gr_random_pid(void)
18388 +{
18389 +#ifdef CONFIG_GRKERNSEC_RANDPID
18390 +       int pid;
18391 +
18392 +       if (grsec_enable_randpid && current->fs->root) {
18393 +               /* return a pid in the range 1 ... pid_max - 1
18394 +                  optimize this so we don't have to do a real division
18395 +               */
18396 +               pid = 1 + (get_random_long() % pid_max);
18397 +               if (pid == pid_max)
18398 +                       pid = pid_max - 1;
18399 +               return pid;
18400 +       }
18401 +#endif
18402 +       return 0;
18403 +}
18404 diff -urNp linux-2.6.18/grsecurity/grsec_sig.c linux-2.6.18/grsecurity/grsec_sig.c
18405 --- linux-2.6.18/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
18406 +++ linux-2.6.18/grsecurity/grsec_sig.c 2006-09-22 20:04:35.000000000 -0400
18407 @@ -0,0 +1,59 @@
18408 +#include <linux/kernel.h>
18409 +#include <linux/sched.h>
18410 +#include <linux/grsecurity.h>
18411 +#include <linux/grinternal.h>
18412 +
18413 +void
18414 +gr_log_signal(const int sig, const struct task_struct *t)
18415 +{
18416 +#ifdef CONFIG_GRKERNSEC_SIGNAL
18417 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
18418 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
18419 +               if (t->pid == current->pid) {
18420 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
18421 +               } else {
18422 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
18423 +               }
18424 +       }
18425 +#endif
18426 +       return;
18427 +}
18428 +
18429 +int
18430 +gr_handle_signal(const struct task_struct *p, const int sig)
18431 +{
18432 +#ifdef CONFIG_GRKERNSEC
18433 +       if (current->pid > 1 && gr_check_protected_task(p)) {
18434 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
18435 +               return -EPERM;
18436 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
18437 +               return -EPERM;
18438 +       }
18439 +#endif
18440 +       return 0;
18441 +}
18442 +
18443 +void gr_handle_brute_attach(struct task_struct *p)
18444 +{
18445 +#ifdef CONFIG_GRKERNSEC_BRUTE
18446 +       read_lock(&tasklist_lock);
18447 +       read_lock(&grsec_exec_file_lock);
18448 +       if (p->parent && p->parent->exec_file == p->exec_file)
18449 +               p->parent->brute = 1;
18450 +       read_unlock(&grsec_exec_file_lock);
18451 +       read_unlock(&tasklist_lock);
18452 +#endif
18453 +       return;
18454 +}
18455 +
18456 +void gr_handle_brute_check(void)
18457 +{
18458 +#ifdef CONFIG_GRKERNSEC_BRUTE
18459 +       if (current->brute) {
18460 +               set_current_state(TASK_UNINTERRUPTIBLE);
18461 +               schedule_timeout(30 * HZ);
18462 +       }
18463 +#endif
18464 +       return;
18465 +}
18466 +
18467 diff -urNp linux-2.6.18/grsecurity/grsec_sock.c linux-2.6.18/grsecurity/grsec_sock.c
18468 --- linux-2.6.18/grsecurity/grsec_sock.c        1969-12-31 19:00:00.000000000 -0500
18469 +++ linux-2.6.18/grsecurity/grsec_sock.c        2006-09-22 20:04:35.000000000 -0400
18470 @@ -0,0 +1,263 @@
18471 +#include <linux/kernel.h>
18472 +#include <linux/module.h>
18473 +#include <linux/sched.h>
18474 +#include <linux/file.h>
18475 +#include <linux/net.h>
18476 +#include <linux/in.h>
18477 +#include <linux/ip.h>
18478 +#include <net/sock.h>
18479 +#include <net/inet_sock.h>
18480 +#include <linux/grsecurity.h>
18481 +#include <linux/grinternal.h>
18482 +#include <linux/gracl.h>
18483 +
18484 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
18485 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
18486 +EXPORT_SYMBOL(udp_v4_lookup);
18487 +#endif
18488 +
18489 +EXPORT_SYMBOL(gr_cap_rtnetlink);
18490 +
18491 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
18492 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
18493 +
18494 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
18495 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
18496 +
18497 +#ifdef CONFIG_UNIX_MODULE
18498 +EXPORT_SYMBOL(gr_acl_handle_unix);
18499 +EXPORT_SYMBOL(gr_acl_handle_mknod);
18500 +EXPORT_SYMBOL(gr_handle_chroot_unix);
18501 +EXPORT_SYMBOL(gr_handle_create);
18502 +#endif
18503 +
18504 +#ifdef CONFIG_GRKERNSEC
18505 +#define gr_conn_table_size 32749
18506 +struct conn_table_entry {
18507 +       struct conn_table_entry *next;
18508 +       struct signal_struct *sig;
18509 +};
18510 +
18511 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
18512 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
18513 +
18514 +extern const char * gr_socktype_to_name(unsigned char type);
18515 +extern const char * gr_proto_to_name(unsigned char proto);
18516 +
18517 +static __inline__ int 
18518 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
18519 +{
18520 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
18521 +}
18522 +
18523 +static __inline__ int
18524 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, 
18525 +          __u16 sport, __u16 dport)
18526 +{
18527 +       if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
18528 +                    sig->gr_sport == sport && sig->gr_dport == dport))
18529 +               return 1;
18530 +       else
18531 +               return 0;
18532 +}
18533 +
18534 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
18535 +{
18536 +       struct conn_table_entry **match;
18537 +       unsigned int index;
18538 +
18539 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
18540 +                         sig->gr_sport, sig->gr_dport, 
18541 +                         gr_conn_table_size);
18542 +
18543 +       newent->sig = sig;
18544 +       
18545 +       match = &gr_conn_table[index];
18546 +       newent->next = *match;
18547 +       *match = newent;
18548 +
18549 +       return;
18550 +}
18551 +
18552 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
18553 +{
18554 +       struct conn_table_entry *match, *last = NULL;
18555 +       unsigned int index;
18556 +
18557 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
18558 +                         sig->gr_sport, sig->gr_dport, 
18559 +                         gr_conn_table_size);
18560 +
18561 +       match = gr_conn_table[index];
18562 +       while (match && !conn_match(match->sig, 
18563 +               sig->gr_saddr, sig->gr_daddr, sig->gr_sport, 
18564 +               sig->gr_dport)) {
18565 +               last = match;
18566 +               match = match->next;
18567 +       }
18568 +
18569 +       if (match) {
18570 +               if (last)
18571 +                       last->next = match->next;
18572 +               else
18573 +                       gr_conn_table[index] = NULL;
18574 +               kfree(match);
18575 +       }
18576 +
18577 +       return;
18578 +}
18579 +
18580 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
18581 +                                            __u16 sport, __u16 dport)
18582 +{
18583 +       struct conn_table_entry *match;
18584 +       unsigned int index;
18585 +
18586 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
18587 +
18588 +       match = gr_conn_table[index];
18589 +       while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
18590 +               match = match->next;
18591 +
18592 +       if (match)
18593 +               return match->sig;
18594 +       else
18595 +               return NULL;
18596 +}
18597 +
18598 +#endif
18599 +
18600 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
18601 +{
18602 +#ifdef CONFIG_GRKERNSEC
18603 +       struct signal_struct *sig = task->signal;
18604 +       struct conn_table_entry *newent;
18605 +
18606 +       newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
18607 +       if (newent == NULL)
18608 +               return;
18609 +       /* no bh lock needed since we are called with bh disabled */
18610 +       spin_lock(&gr_conn_table_lock);
18611 +       gr_del_task_from_ip_table_nolock(sig);
18612 +       sig->gr_saddr = inet->rcv_saddr;
18613 +       sig->gr_daddr = inet->daddr;
18614 +       sig->gr_sport = inet->sport;
18615 +       sig->gr_dport = inet->dport;
18616 +       gr_add_to_task_ip_table_nolock(sig, newent);
18617 +       spin_unlock(&gr_conn_table_lock);
18618 +#endif
18619 +       return;
18620 +}
18621 +
18622 +void gr_del_task_from_ip_table(struct task_struct *task)
18623 +{
18624 +#ifdef CONFIG_GRKERNSEC
18625 +       spin_lock(&gr_conn_table_lock);
18626 +       gr_del_task_from_ip_table_nolock(task->signal);
18627 +       spin_unlock(&gr_conn_table_lock);
18628 +#endif
18629 +       return;
18630 +}
18631 +
18632 +void
18633 +gr_attach_curr_ip(const struct sock *sk)
18634 +{
18635 +#ifdef CONFIG_GRKERNSEC
18636 +       struct signal_struct *p, *set;
18637 +       const struct inet_sock *inet = inet_sk(sk);     
18638 +
18639 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
18640 +               return;
18641 +
18642 +       set = current->signal;
18643 +
18644 +       spin_lock_bh(&gr_conn_table_lock);
18645 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
18646 +                                   inet->dport, inet->sport);
18647 +       if (unlikely(p != NULL)) {
18648 +               set->curr_ip = p->curr_ip;
18649 +               set->used_accept = 1;
18650 +               gr_del_task_from_ip_table_nolock(p);
18651 +               spin_unlock_bh(&gr_conn_table_lock);
18652 +               return;
18653 +       }
18654 +       spin_unlock_bh(&gr_conn_table_lock);
18655 +
18656 +       set->curr_ip = inet->daddr;
18657 +       set->used_accept = 1;
18658 +#endif
18659 +       return;
18660 +}
18661 +
18662 +int
18663 +gr_handle_sock_all(const int family, const int type, const int protocol)
18664 +{
18665 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
18666 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
18667 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
18668 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
18669 +               return -EACCES;
18670 +       }
18671 +#endif
18672 +       return 0;
18673 +}
18674 +
18675 +int
18676 +gr_handle_sock_server(const struct sockaddr *sck)
18677 +{
18678 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18679 +       if (grsec_enable_socket_server &&
18680 +           in_group_p(grsec_socket_server_gid) &&
18681 +           sck && (sck->sa_family != AF_UNIX) &&
18682 +           (sck->sa_family != AF_LOCAL)) {
18683 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
18684 +               return -EACCES;
18685 +       }
18686 +#endif
18687 +       return 0;
18688 +}
18689 +
18690 +int
18691 +gr_handle_sock_server_other(const struct sock *sck)
18692 +{
18693 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18694 +       if (grsec_enable_socket_server &&
18695 +           in_group_p(grsec_socket_server_gid) &&
18696 +           sck && (sck->sk_family != AF_UNIX) &&
18697 +           (sck->sk_family != AF_LOCAL)) {
18698 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
18699 +               return -EACCES;
18700 +       }
18701 +#endif
18702 +       return 0;
18703 +}
18704 +
18705 +int
18706 +gr_handle_sock_client(const struct sockaddr *sck)
18707 +{
18708 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
18709 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
18710 +           sck && (sck->sa_family != AF_UNIX) &&
18711 +           (sck->sa_family != AF_LOCAL)) {
18712 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
18713 +               return -EACCES;
18714 +       }
18715 +#endif
18716 +       return 0;
18717 +}
18718 +
18719 +__u32
18720 +gr_cap_rtnetlink(void)
18721 +{
18722 +#ifdef CONFIG_GRKERNSEC
18723 +       if (!gr_acl_is_enabled())
18724 +               return current->cap_effective;
18725 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
18726 +                gr_task_is_capable(current, CAP_NET_ADMIN))
18727 +               return current->cap_effective;
18728 +       else
18729 +               return 0;
18730 +#else
18731 +       return current->cap_effective;
18732 +#endif
18733 +}
18734 diff -urNp linux-2.6.18/grsecurity/grsec_sysctl.c linux-2.6.18/grsecurity/grsec_sysctl.c
18735 --- linux-2.6.18/grsecurity/grsec_sysctl.c      1969-12-31 19:00:00.000000000 -0500
18736 +++ linux-2.6.18/grsecurity/grsec_sysctl.c      2006-09-22 20:04:35.000000000 -0400
18737 @@ -0,0 +1,466 @@
18738 +#include <linux/kernel.h>
18739 +#include <linux/sched.h>
18740 +#include <linux/sysctl.h>
18741 +#include <linux/grsecurity.h>
18742 +#include <linux/grinternal.h>
18743 +
18744 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18745 +int grsec_modstop;
18746 +#endif
18747 +
18748 +int
18749 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
18750 +{
18751 +#ifdef CONFIG_GRKERNSEC_SYSCTL
18752 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
18753 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
18754 +               return -EACCES;
18755 +       }
18756 +#endif
18757 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18758 +       if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
18759 +           grsec_modstop && (op & 002)) {
18760 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
18761 +               return -EACCES;
18762 +       }
18763 +#endif
18764 +       return 0;
18765 +}
18766 +
18767 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
18768 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
18769 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
18770 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
18771 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
18772 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
18773 +GS_RANDPID, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
18774 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, 
18775 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
18776 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
18777 +
18778 +
18779 +ctl_table grsecurity_table[] = {
18780 +#ifdef CONFIG_GRKERNSEC_SYSCTL
18781 +#ifdef CONFIG_GRKERNSEC_LINK
18782 +       {
18783 +               .ctl_name       = GS_LINK,
18784 +               .procname       = "linking_restrictions",
18785 +               .data           = &grsec_enable_link,
18786 +               .maxlen         = sizeof(int),
18787 +               .mode           = 0600,
18788 +               .proc_handler   = &proc_dointvec,
18789 +       },
18790 +#endif
18791 +#ifdef CONFIG_GRKERNSEC_FIFO
18792 +       {
18793 +               .ctl_name       = GS_FIFO,
18794 +               .procname       = "fifo_restrictions",
18795 +               .data           = &grsec_enable_fifo,
18796 +               .maxlen         = sizeof(int),
18797 +               .mode           = 0600,
18798 +               .proc_handler   = &proc_dointvec,
18799 +       },
18800 +#endif
18801 +#ifdef CONFIG_GRKERNSEC_EXECVE
18802 +       {
18803 +               .ctl_name       = GS_EXECVE,
18804 +               .procname       = "execve_limiting",
18805 +               .data           = &grsec_enable_execve,
18806 +               .maxlen         = sizeof(int),
18807 +               .mode           = 0600,
18808 +               .proc_handler   = &proc_dointvec,
18809 +       },
18810 +#endif
18811 +#ifdef CONFIG_GRKERNSEC_EXECLOG
18812 +       {
18813 +               .ctl_name       = GS_EXECLOG,
18814 +               .procname       = "exec_logging",
18815 +               .data           = &grsec_enable_execlog,
18816 +               .maxlen         = sizeof(int),
18817 +               .mode           = 0600,
18818 +               .proc_handler   = &proc_dointvec,
18819 +       },
18820 +#endif
18821 +#ifdef CONFIG_GRKERNSEC_SIGNAL
18822 +       {
18823 +               .ctl_name       = GS_SIGNAL,
18824 +               .procname       = "signal_logging",
18825 +               .data           = &grsec_enable_signal,
18826 +               .maxlen         = sizeof(int),
18827 +               .mode           = 0600,
18828 +               .proc_handler   = &proc_dointvec,
18829 +       },
18830 +#endif
18831 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
18832 +       {
18833 +               .ctl_name       = GS_FORKFAIL,
18834 +               .procname       = "forkfail_logging",
18835 +               .data           = &grsec_enable_forkfail,
18836 +               .maxlen         = sizeof(int),
18837 +               .mode           = 0600,
18838 +               .proc_handler   = &proc_dointvec,
18839 +       },
18840 +#endif
18841 +#ifdef CONFIG_GRKERNSEC_TIME
18842 +       {
18843 +               .ctl_name       = GS_TIME,
18844 +               .procname       = "timechange_logging",
18845 +               .data           = &grsec_enable_time,
18846 +               .maxlen         = sizeof(int),
18847 +               .mode           = 0600,
18848 +               .proc_handler   = &proc_dointvec,
18849 +       },
18850 +#endif
18851 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
18852 +       {
18853 +               .ctl_name       = GS_CHROOT_SHMAT,
18854 +               .procname       = "chroot_deny_shmat",
18855 +               .data           = &grsec_enable_chroot_shmat,
18856 +               .maxlen         = sizeof(int),
18857 +               .mode           = 0600,
18858 +               .proc_handler   = &proc_dointvec,
18859 +       },
18860 +#endif
18861 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
18862 +       {
18863 +               .ctl_name       = GS_CHROOT_UNIX,
18864 +               .procname       = "chroot_deny_unix",
18865 +               .data           = &grsec_enable_chroot_unix,
18866 +               .maxlen         = sizeof(int),
18867 +               .mode           = 0600,
18868 +               .proc_handler   = &proc_dointvec,
18869 +       },
18870 +#endif
18871 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
18872 +       {
18873 +               .ctl_name       = GS_CHROOT_MNT,
18874 +               .procname       = "chroot_deny_mount",
18875 +               .data           = &grsec_enable_chroot_mount,
18876 +               .maxlen         = sizeof(int),
18877 +               .mode           = 0600,
18878 +               .proc_handler   = &proc_dointvec,
18879 +       },
18880 +#endif
18881 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
18882 +       {
18883 +               .ctl_name       = GS_CHROOT_FCHDIR,
18884 +               .procname       = "chroot_deny_fchdir",
18885 +               .data           = &grsec_enable_chroot_fchdir,
18886 +               .maxlen         = sizeof(int),
18887 +               .mode           = 0600,
18888 +               .proc_handler   = &proc_dointvec,
18889 +       },
18890 +#endif
18891 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
18892 +       {
18893 +               .ctl_name       = GS_CHROOT_DBL,
18894 +               .procname       = "chroot_deny_chroot",
18895 +               .data           = &grsec_enable_chroot_double,
18896 +               .maxlen         = sizeof(int),
18897 +               .mode           = 0600,
18898 +               .proc_handler   = &proc_dointvec,
18899 +       },
18900 +#endif
18901 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
18902 +       {
18903 +               .ctl_name       = GS_CHROOT_PVT,
18904 +               .procname       = "chroot_deny_pivot",
18905 +               .data           = &grsec_enable_chroot_pivot,
18906 +               .maxlen         = sizeof(int),
18907 +               .mode           = 0600,
18908 +               .proc_handler   = &proc_dointvec,
18909 +       },
18910 +#endif
18911 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
18912 +       {
18913 +               .ctl_name       = GS_CHROOT_CD,
18914 +               .procname       = "chroot_enforce_chdir",
18915 +               .data           = &grsec_enable_chroot_chdir,
18916 +               .maxlen         = sizeof(int),
18917 +               .mode           = 0600,
18918 +               .proc_handler   = &proc_dointvec,
18919 +       },
18920 +#endif
18921 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
18922 +       {
18923 +               .ctl_name       = GS_CHROOT_CM,
18924 +               .procname       = "chroot_deny_chmod",
18925 +               .data           = &grsec_enable_chroot_chmod,
18926 +               .maxlen         = sizeof(int),
18927 +               .mode           = 0600,
18928 +               .proc_handler   = &proc_dointvec,
18929 +       },
18930 +#endif
18931 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
18932 +       {
18933 +               .ctl_name       = GS_CHROOT_MK,
18934 +               .procname       = "chroot_deny_mknod",
18935 +               .data           = &grsec_enable_chroot_mknod,
18936 +               .maxlen         = sizeof(int),
18937 +               .mode           = 0600,
18938 +               .proc_handler   = &proc_dointvec,
18939 +       },
18940 +#endif
18941 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
18942 +       {
18943 +               .ctl_name       = GS_CHROOT_NI,
18944 +               .procname       = "chroot_restrict_nice",
18945 +               .data           = &grsec_enable_chroot_nice,
18946 +               .maxlen         = sizeof(int),
18947 +               .mode           = 0600,
18948 +               .proc_handler   = &proc_dointvec,
18949 +       },
18950 +#endif
18951 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
18952 +       {
18953 +               .ctl_name       = GS_CHROOT_EXECLOG,
18954 +               .procname       = "chroot_execlog",
18955 +               .data           = &grsec_enable_chroot_execlog,
18956 +               .maxlen         = sizeof(int),
18957 +               .mode           = 0600,
18958 +               .proc_handler   = &proc_dointvec,
18959 +       },
18960 +#endif
18961 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
18962 +       {
18963 +               .ctl_name       = GS_CHROOT_CAPS,
18964 +               .procname       = "chroot_caps",
18965 +               .data           = &grsec_enable_chroot_caps,
18966 +               .maxlen         = sizeof(int),
18967 +               .mode           = 0600,
18968 +               .proc_handler   = &proc_dointvec,
18969 +       },
18970 +#endif
18971 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
18972 +       {
18973 +               .ctl_name       = GS_CHROOT_SYSCTL,
18974 +               .procname       = "chroot_deny_sysctl",
18975 +               .data           = &grsec_enable_chroot_sysctl,
18976 +               .maxlen         = sizeof(int),
18977 +               .mode           = 0600,
18978 +               .proc_handler   = &proc_dointvec,
18979 +       },
18980 +#endif
18981 +#ifdef CONFIG_GRKERNSEC_TPE
18982 +       {
18983 +               .ctl_name       = GS_TPE,
18984 +               .procname       = "tpe",
18985 +               .data           = &grsec_enable_tpe,
18986 +               .maxlen         = sizeof(int),
18987 +               .mode           = 0600,
18988 +               .proc_handler   = &proc_dointvec,
18989 +       },
18990 +       {
18991 +               .ctl_name       = GS_TPE_GID,
18992 +               .procname       = "tpe_gid",
18993 +               .data           = &grsec_tpe_gid,
18994 +               .maxlen         = sizeof(int),
18995 +               .mode           = 0600,
18996 +               .proc_handler   = &proc_dointvec,
18997 +       },
18998 +#endif
18999 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
19000 +       {
19001 +               .ctl_name       = GS_TPE_ALL,
19002 +               .procname       = "tpe_restrict_all",
19003 +               .data           = &grsec_enable_tpe_all,
19004 +               .maxlen         = sizeof(int),
19005 +               .mode           = 0600,
19006 +               .proc_handler   = &proc_dointvec,
19007 +       },
19008 +#endif
19009 +#ifdef CONFIG_GRKERNSEC_RANDPID
19010 +       {
19011 +               .ctl_name       = GS_RANDPID,
19012 +               .procname       = "rand_pids",
19013 +               .data           = &grsec_enable_randpid,
19014 +               .maxlen         = sizeof(int),
19015 +               .mode           = 0600,
19016 +               .proc_handler   = &proc_dointvec,
19017 +       },
19018 +#endif
19019 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
19020 +       {
19021 +               .ctl_name       = GS_SOCKET_ALL,
19022 +               .procname       = "socket_all",
19023 +               .data           = &grsec_enable_socket_all,
19024 +               .maxlen         = sizeof(int),
19025 +               .mode           = 0600,
19026 +               .proc_handler   = &proc_dointvec,
19027 +       },
19028 +       {
19029 +               .ctl_name       = GS_SOCKET_ALL_GID,
19030 +               .procname       = "socket_all_gid",
19031 +               .data           = &grsec_socket_all_gid,
19032 +               .maxlen         = sizeof(int),
19033 +               .mode           = 0600,
19034 +               .proc_handler   = &proc_dointvec,
19035 +       },
19036 +#endif
19037 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
19038 +       {
19039 +               .ctl_name       = GS_SOCKET_CLIENT,
19040 +               .procname       = "socket_client",
19041 +               .data           = &grsec_enable_socket_client,
19042 +               .maxlen         = sizeof(int),
19043 +               .mode           = 0600,
19044 +               .proc_handler   = &proc_dointvec,
19045 +       },
19046 +       {
19047 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
19048 +               .procname       = "socket_client_gid",
19049 +               .data           = &grsec_socket_client_gid,
19050 +               .maxlen         = sizeof(int),
19051 +               .mode           = 0600,
19052 +               .proc_handler   = &proc_dointvec,
19053 +       },
19054 +#endif
19055 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
19056 +       {
19057 +               .ctl_name       = GS_SOCKET_SERVER,
19058 +               .procname       = "socket_server",
19059 +               .data           = &grsec_enable_socket_server,
19060 +               .maxlen         = sizeof(int),
19061 +               .mode           = 0600,
19062 +               .proc_handler   = &proc_dointvec,
19063 +       },
19064 +       {
19065 +               .ctl_name       = GS_SOCKET_SERVER_GID,
19066 +               .procname       = "socket_server_gid",
19067 +               .data           = &grsec_socket_server_gid,
19068 +               .maxlen         = sizeof(int),
19069 +               .mode           = 0600,
19070 +               .proc_handler   = &proc_dointvec,
19071 +       },
19072 +#endif
19073 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
19074 +       {
19075 +               .ctl_name       = GS_GROUP,
19076 +               .procname       = "audit_group",
19077 +               .data           = &grsec_enable_group,
19078 +               .maxlen         = sizeof(int),
19079 +               .mode           = 0600,
19080 +               .proc_handler   = &proc_dointvec,
19081 +       },
19082 +       {
19083 +               .ctl_name       = GS_GID,
19084 +               .procname       = "audit_gid",
19085 +               .data           = &grsec_audit_gid,
19086 +               .maxlen         = sizeof(int),
19087 +               .mode           = 0600,
19088 +               .proc_handler   = &proc_dointvec,
19089 +       },
19090 +#endif
19091 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
19092 +       {
19093 +               .ctl_name       = GS_ACHDIR,
19094 +               .procname       = "audit_chdir",
19095 +               .data           = &grsec_enable_chdir,
19096 +               .maxlen         = sizeof(int),
19097 +               .mode           = 0600,
19098 +               .proc_handler   = &proc_dointvec,
19099 +       },
19100 +#endif
19101 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
19102 +       {
19103 +               .ctl_name       = GS_AMOUNT,
19104 +               .procname       = "audit_mount",
19105 +               .data           = &grsec_enable_mount,
19106 +               .maxlen         = sizeof(int),
19107 +               .mode           = 0600,
19108 +               .proc_handler   = &proc_dointvec,
19109 +       },
19110 +#endif
19111 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
19112 +       {
19113 +               .ctl_name       = GS_AIPC,
19114 +               .procname       = "audit_ipc",
19115 +               .data           = &grsec_enable_audit_ipc,
19116 +               .maxlen         = sizeof(int),
19117 +               .mode           = 0600,
19118 +               .proc_handler   = &proc_dointvec,
19119 +       },
19120 +#endif
19121 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
19122 +       {
19123 +               .ctl_name       = GS_TEXTREL,
19124 +               .procname       = "audit_textrel",
19125 +               .data           = &grsec_enable_audit_textrel,
19126 +               .maxlen         = sizeof(int),
19127 +               .mode           = 0600,
19128 +               .proc_handler   = &proc_dointvec,
19129 +       },
19130 +#endif
19131 +#ifdef CONFIG_GRKERNSEC_DMESG
19132 +       {
19133 +               .ctl_name       = GS_DMSG,
19134 +               .procname       = "dmesg",
19135 +               .data           = &grsec_enable_dmesg,
19136 +               .maxlen         = sizeof(int),
19137 +               .mode           = 0600,
19138 +               .proc_handler   = &proc_dointvec,
19139 +       },
19140 +#endif
19141 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
19142 +       {
19143 +               .ctl_name       = GS_FINDTASK,
19144 +               .procname       = "chroot_findtask",
19145 +               .data           = &grsec_enable_chroot_findtask,
19146 +               .maxlen         = sizeof(int),
19147 +               .mode           = 0600,
19148 +               .proc_handler   = &proc_dointvec,
19149 +       },
19150 +#endif
19151 +#ifdef CONFIG_GRKERNSEC_SHM
19152 +       {
19153 +               .ctl_name       = GS_SHM,
19154 +               .procname       = "destroy_unused_shm",
19155 +               .data           = &grsec_enable_shm,
19156 +               .maxlen         = sizeof(int),
19157 +               .mode           = 0600,
19158 +               .proc_handler   = &proc_dointvec,
19159 +       },
19160 +#endif
19161 +#ifdef CONFIG_GRKERNSEC_RESLOG
19162 +       {
19163 +               .ctl_name       = GS_RESLOG,
19164 +               .procname       = "resource_logging",
19165 +               .data           = &grsec_resource_logging,
19166 +               .maxlen         = sizeof(int),
19167 +               .mode           = 0600,
19168 +               .proc_handler   = &proc_dointvec,
19169 +       },
19170 +#endif
19171 +       {
19172 +               .ctl_name       = GS_LOCK,
19173 +               .procname       = "grsec_lock",
19174 +               .data           = &grsec_lock,
19175 +               .maxlen         = sizeof(int),
19176 +               .mode           = 0600,
19177 +               .proc_handler   = &proc_dointvec,
19178 +       },
19179 +#endif
19180 +#ifdef CONFIG_GRKERNSEC_MODSTOP
19181 +       {
19182 +               .ctl_name       = GS_MODSTOP,
19183 +               .procname       = "disable_modules",
19184 +               .data           = &grsec_modstop,
19185 +               .maxlen         = sizeof(int),
19186 +               .mode           = 0600,
19187 +               .proc_handler   = &proc_dointvec,
19188 +       },
19189 +#endif
19190 +       { .ctl_name = 0 }
19191 +};
19192 +#endif
19193 +
19194 +int gr_check_modstop(void)
19195 +{
19196 +#ifdef CONFIG_GRKERNSEC_MODSTOP
19197 +       if (grsec_modstop == 1) {
19198 +               gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
19199 +               return 1;
19200 +       }
19201 +#endif
19202 +       return 0;
19203 +}
19204 diff -urNp linux-2.6.18/grsecurity/grsec_textrel.c linux-2.6.18/grsecurity/grsec_textrel.c
19205 --- linux-2.6.18/grsecurity/grsec_textrel.c     1969-12-31 19:00:00.000000000 -0500
19206 +++ linux-2.6.18/grsecurity/grsec_textrel.c     2006-09-22 20:04:35.000000000 -0400
19207 @@ -0,0 +1,16 @@
19208 +#include <linux/kernel.h>
19209 +#include <linux/sched.h>
19210 +#include <linux/mm.h>
19211 +#include <linux/file.h>
19212 +#include <linux/grinternal.h>
19213 +#include <linux/grsecurity.h>
19214 +
19215 +void
19216 +gr_log_textrel(struct vm_area_struct * vma)
19217 +{
19218 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
19219 +       if (grsec_enable_audit_textrel)
19220 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
19221 +#endif
19222 +       return;
19223 +}
19224 diff -urNp linux-2.6.18/grsecurity/grsec_time.c linux-2.6.18/grsecurity/grsec_time.c
19225 --- linux-2.6.18/grsecurity/grsec_time.c        1969-12-31 19:00:00.000000000 -0500
19226 +++ linux-2.6.18/grsecurity/grsec_time.c        2006-09-22 20:04:35.000000000 -0400
19227 @@ -0,0 +1,13 @@
19228 +#include <linux/kernel.h>
19229 +#include <linux/sched.h>
19230 +#include <linux/grinternal.h>
19231 +
19232 +void
19233 +gr_log_timechange(void)
19234 +{
19235 +#ifdef CONFIG_GRKERNSEC_TIME
19236 +       if (grsec_enable_time)
19237 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
19238 +#endif
19239 +       return;
19240 +}
19241 diff -urNp linux-2.6.18/grsecurity/grsec_tpe.c linux-2.6.18/grsecurity/grsec_tpe.c
19242 --- linux-2.6.18/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
19243 +++ linux-2.6.18/grsecurity/grsec_tpe.c 2006-09-22 20:04:35.000000000 -0400
19244 @@ -0,0 +1,37 @@
19245 +#include <linux/kernel.h>
19246 +#include <linux/sched.h>
19247 +#include <linux/file.h>
19248 +#include <linux/fs.h>
19249 +#include <linux/grinternal.h>
19250 +
19251 +extern int gr_acl_tpe_check(void);
19252 +
19253 +int
19254 +gr_tpe_allow(const struct file *file)
19255 +{
19256 +#ifdef CONFIG_GRKERNSEC
19257 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
19258 +
19259 +       if (current->uid && ((grsec_enable_tpe &&
19260 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
19261 +           !in_group_p(grsec_tpe_gid)
19262 +#else
19263 +           in_group_p(grsec_tpe_gid)
19264 +#endif
19265 +           ) || gr_acl_tpe_check()) &&
19266 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
19267 +                                               (inode->i_mode & S_IWOTH))))) {
19268 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
19269 +               return 0;
19270 +       }
19271 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
19272 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
19273 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
19274 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
19275 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
19276 +               return 0;
19277 +       }
19278 +#endif
19279 +#endif
19280 +       return 1;
19281 +}
19282 diff -urNp linux-2.6.18/grsecurity/grsum.c linux-2.6.18/grsecurity/grsum.c
19283 --- linux-2.6.18/grsecurity/grsum.c     1969-12-31 19:00:00.000000000 -0500
19284 +++ linux-2.6.18/grsecurity/grsum.c     2006-09-22 20:04:35.000000000 -0400
19285 @@ -0,0 +1,59 @@
19286 +#include <linux/kernel.h>
19287 +#include <linux/sched.h>
19288 +#include <linux/mm.h>
19289 +#include <asm/scatterlist.h>
19290 +#include <linux/crypto.h>
19291 +#include <linux/gracl.h>
19292 +
19293 +
19294 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
19295 +#error "crypto and sha256 must be built into the kernel"
19296 +#endif
19297 +
19298 +int
19299 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
19300 +{
19301 +       char *p;
19302 +       struct crypto_tfm *tfm;
19303 +       unsigned char temp_sum[GR_SHA_LEN];
19304 +       struct scatterlist sg[2];
19305 +       volatile int retval = 0;
19306 +       volatile int dummy = 0;
19307 +       unsigned int i;
19308 +
19309 +       tfm = crypto_alloc_tfm("sha256", 0);
19310 +       if (tfm == NULL) {
19311 +               /* should never happen, since sha256 should be built in */
19312 +               return 1;
19313 +       }
19314 +
19315 +       crypto_digest_init(tfm);
19316 +
19317 +       p = salt;
19318 +       sg[0].page = virt_to_page(p);
19319 +       sg[0].offset = ((long) p & ~PAGE_MASK);
19320 +       sg[0].length = GR_SALT_LEN;
19321 +       
19322 +       crypto_digest_update(tfm, sg, 1);
19323 +
19324 +       p = entry->pw;
19325 +       sg[0].page = virt_to_page(p);
19326 +       sg[0].offset = ((long) p & ~PAGE_MASK);
19327 +       sg[0].length = strlen(entry->pw);
19328 +
19329 +       crypto_digest_update(tfm, sg, 1);
19330 +
19331 +       crypto_digest_final(tfm, temp_sum);
19332 +
19333 +       memset(entry->pw, 0, GR_PW_LEN);
19334 +
19335 +       for (i = 0; i < GR_SHA_LEN; i++)
19336 +               if (sum[i] != temp_sum[i])
19337 +                       retval = 1;
19338 +               else
19339 +                       dummy = 1;      // waste a cycle
19340 +
19341 +       crypto_free_tfm(tfm);
19342 +
19343 +       return retval;
19344 +}
19345 diff -urNp linux-2.6.18/grsecurity/Kconfig linux-2.6.18/grsecurity/Kconfig
19346 --- linux-2.6.18/grsecurity/Kconfig     1969-12-31 19:00:00.000000000 -0500
19347 +++ linux-2.6.18/grsecurity/Kconfig     2006-09-22 22:12:27.000000000 -0400
19348 @@ -0,0 +1,888 @@
19349 +#
19350 +# grecurity configuration
19351 +#
19352 +
19353 +menu "Grsecurity"
19354 +
19355 +config GRKERNSEC
19356 +       bool "Grsecurity"
19357 +       select CRYPTO
19358 +       select CRYPTO_SHA256
19359 +       help
19360 +         If you say Y here, you will be able to configure many features
19361 +         that will enhance the security of your system.  It is highly
19362 +         recommended that you say Y here and read through the help
19363 +         for each option so that you fully understand the features and
19364 +         can evaluate their usefulness for your machine.
19365 +
19366 +choice
19367 +       prompt "Security Level"
19368 +       depends GRKERNSEC
19369 +       default GRKERNSEC_CUSTOM
19370 +
19371 +config GRKERNSEC_LOW
19372 +       bool "Low"
19373 +       select GRKERNSEC_LINK
19374 +       select GRKERNSEC_FIFO
19375 +       select GRKERNSEC_RANDPID
19376 +       select GRKERNSEC_EXECVE
19377 +       select GRKERNSEC_RANDNET
19378 +       select GRKERNSEC_DMESG
19379 +       select GRKERNSEC_CHROOT_CHDIR
19380 +       select GRKERNSEC_MODSTOP if (MODULES)
19381 +
19382 +       help
19383 +         If you choose this option, several of the grsecurity options will
19384 +         be enabled that will give you greater protection against a number
19385 +         of attacks, while assuring that none of your software will have any
19386 +         conflicts with the additional security measures.  If you run a lot
19387 +         of unusual software, or you are having problems with the higher
19388 +         security levels, you should say Y here.  With this option, the
19389 +         following features are enabled:
19390 +
19391 +         - Linking restrictions
19392 +         - FIFO restrictions
19393 +         - Randomized PIDs
19394 +         - Enforcing RLIMIT_NPROC on execve
19395 +         - Restricted dmesg
19396 +         - Enforced chdir("/") on chroot
19397 +         - Runtime module disabling
19398 +
19399 +config GRKERNSEC_MEDIUM
19400 +       bool "Medium"
19401 +       select PAX
19402 +       select PAX_EI_PAX
19403 +       select PAX_PT_PAX_FLAGS
19404 +       select PAX_HAVE_ACL_FLAGS
19405 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
19406 +       select GRKERNSEC_CHROOT_SYSCTL
19407 +       select GRKERNSEC_LINK
19408 +       select GRKERNSEC_FIFO
19409 +       select GRKERNSEC_RANDPID
19410 +       select GRKERNSEC_EXECVE
19411 +       select GRKERNSEC_DMESG
19412 +       select GRKERNSEC_RANDNET
19413 +       select GRKERNSEC_FORKFAIL
19414 +       select GRKERNSEC_TIME
19415 +       select GRKERNSEC_SIGNAL
19416 +       select GRKERNSEC_CHROOT
19417 +       select GRKERNSEC_CHROOT_UNIX
19418 +       select GRKERNSEC_CHROOT_MOUNT
19419 +       select GRKERNSEC_CHROOT_PIVOT
19420 +       select GRKERNSEC_CHROOT_DOUBLE
19421 +       select GRKERNSEC_CHROOT_CHDIR
19422 +       select GRKERNSEC_CHROOT_MKNOD
19423 +       select GRKERNSEC_PROC
19424 +       select GRKERNSEC_PROC_USERGROUP
19425 +       select GRKERNSEC_MODSTOP if (MODULES)
19426 +       select PAX_RANDUSTACK
19427 +       select PAX_ASLR
19428 +       select PAX_RANDMMAP
19429 +
19430 +       help
19431 +         If you say Y here, several features in addition to those included
19432 +         in the low additional security level will be enabled.  These
19433 +         features provide even more security to your system, though in rare
19434 +         cases they may be incompatible with very old or poorly written
19435 +         software.  If you enable this option, make sure that your auth
19436 +         service (identd) is running as gid 1001.  With this option, 
19437 +         the following features (in addition to those provided in the 
19438 +         low additional security level) will be enabled:
19439 +
19440 +         - Randomized TCP source ports
19441 +         - Failed fork logging
19442 +         - Time change logging
19443 +         - Signal logging
19444 +         - Deny mounts in chroot
19445 +         - Deny double chrooting
19446 +         - Deny sysctl writes in chroot
19447 +         - Deny mknod in chroot
19448 +         - Deny access to abstract AF_UNIX sockets out of chroot
19449 +         - Deny pivot_root in chroot
19450 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
19451 +         - /proc restrictions with special GID set to 10 (usually wheel)
19452 +         - Address Space Layout Randomization (ASLR)
19453 +
19454 +config GRKERNSEC_HIGH
19455 +       bool "High"
19456 +       select GRKERNSEC_LINK
19457 +       select GRKERNSEC_FIFO
19458 +       select GRKERNSEC_RANDPID
19459 +       select GRKERNSEC_EXECVE
19460 +       select GRKERNSEC_DMESG
19461 +       select GRKERNSEC_FORKFAIL
19462 +       select GRKERNSEC_TIME
19463 +       select GRKERNSEC_SIGNAL
19464 +       select GRKERNSEC_CHROOT_SHMAT
19465 +       select GRKERNSEC_CHROOT_UNIX
19466 +       select GRKERNSEC_CHROOT_MOUNT
19467 +       select GRKERNSEC_CHROOT_FCHDIR
19468 +       select GRKERNSEC_CHROOT_PIVOT
19469 +       select GRKERNSEC_CHROOT_DOUBLE
19470 +       select GRKERNSEC_CHROOT_CHDIR
19471 +       select GRKERNSEC_CHROOT_MKNOD
19472 +       select GRKERNSEC_CHROOT_CAPS
19473 +       select GRKERNSEC_CHROOT_SYSCTL
19474 +       select GRKERNSEC_CHROOT_FINDTASK
19475 +       select GRKERNSEC_PROC
19476 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
19477 +       select GRKERNSEC_HIDESYM
19478 +       select GRKERNSEC_BRUTE
19479 +       select GRKERNSEC_SHM if (SYSVIPC)
19480 +       select GRKERNSEC_PROC_USERGROUP
19481 +       select GRKERNSEC_KMEM
19482 +       select GRKERNSEC_RESLOG
19483 +       select GRKERNSEC_RANDNET
19484 +       select GRKERNSEC_PROC_ADD
19485 +       select GRKERNSEC_CHROOT_CHMOD
19486 +       select GRKERNSEC_CHROOT_NICE
19487 +       select GRKERNSEC_AUDIT_MOUNT
19488 +       select GRKERNSEC_MODSTOP if (MODULES)
19489 +       select PAX
19490 +       select PAX_RANDUSTACK
19491 +       select PAX_ASLR
19492 +       select PAX_RANDMMAP
19493 +       select PAX_NOEXEC
19494 +       select PAX_MPROTECT
19495 +       select PAX_EI_PAX
19496 +       select PAX_PT_PAX_FLAGS
19497 +       select PAX_HAVE_ACL_FLAGS
19498 +       select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
19499 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
19500 +       select PAX_SEGMEXEC if (X86 && !X86_64)
19501 +       select PAX_PAGEEXEC if (!X86)
19502 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
19503 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
19504 +       select PAX_SYSCALL if (PPC32)
19505 +       select PAX_EMUTRAMP if (PARISC)
19506 +       select PAX_EMUSIGRT if (PARISC)
19507 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
19508 +       help
19509 +         If you say Y here, many of the features of grsecurity will be
19510 +         enabled, which will protect you against many kinds of attacks
19511 +         against your system.  The heightened security comes at a cost
19512 +         of an increased chance of incompatibilities with rare software
19513 +         on your machine.  Since this security level enables PaX, you should
19514 +         view <http://pax.grsecurity.net> and read about the PaX
19515 +         project.  While you are there, download chpax and run it on
19516 +         binaries that cause problems with PaX.  Also remember that
19517 +         since the /proc restrictions are enabled, you must run your
19518 +         identd as gid 1001.  This security level enables the following 
19519 +         features in addition to those listed in the low and medium 
19520 +         security levels:
19521 +
19522 +         - Additional /proc restrictions
19523 +         - Chmod restrictions in chroot
19524 +         - No signals, ptrace, or viewing of processes outside of chroot
19525 +         - Capability restrictions in chroot
19526 +         - Deny fchdir out of chroot
19527 +         - Priority restrictions in chroot
19528 +         - Segmentation-based implementation of PaX
19529 +         - Mprotect restrictions
19530 +         - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
19531 +         - Kernel stack randomization
19532 +         - Mount/unmount/remount logging
19533 +         - Kernel symbol hiding
19534 +         - Destroy unused shared memory        
19535 +         - Prevention of memory exhaustion-based exploits
19536 +config GRKERNSEC_CUSTOM
19537 +       bool "Custom"
19538 +       help
19539 +         If you say Y here, you will be able to configure every grsecurity
19540 +         option, which allows you to enable many more features that aren't
19541 +         covered in the basic security levels.  These additional features
19542 +         include TPE, socket restrictions, and the sysctl system for
19543 +         grsecurity.  It is advised that you read through the help for
19544 +         each option to determine its usefulness in your situation.
19545 +
19546 +endchoice
19547 +
19548 +menu "Address Space Protection"
19549 +depends on GRKERNSEC
19550 +
19551 +config GRKERNSEC_KMEM
19552 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
19553 +       help
19554 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
19555 +         be written to via mmap or otherwise to modify the running kernel.
19556 +         /dev/port will also not be allowed to be opened. If you have module
19557 +         support disabled, enabling this will close up four ways that are
19558 +         currently used  to insert malicious code into the running kernel.
19559 +         Even with all these features enabled, we still highly recommend that
19560 +         you use the RBAC system, as it is still possible for an attacker to
19561 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
19562 +         If you are not using XFree86, you may be able to stop this additional
19563 +         case by enabling the 'Disable privileged I/O' option. Though nothing
19564 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
19565 +         but only to video memory, which is the only writing we allow in this
19566 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
19567 +         not be allowed to mprotect it with PROT_WRITE later.
19568 +         It is highly recommended that you say Y here if you meet all the
19569 +         conditions above.
19570 +
19571 +config GRKERNSEC_IO
19572 +       bool "Disable privileged I/O"
19573 +       depends on X86
19574 +       select RTC
19575 +       help
19576 +         If you say Y here, all ioperm and iopl calls will return an error.
19577 +         Ioperm and iopl can be used to modify the running kernel.
19578 +         Unfortunately, some programs need this access to operate properly,
19579 +         the most notable of which are XFree86 and hwclock.  hwclock can be
19580 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
19581 +         enabled if this option is enabled, to ensure that hwclock operates
19582 +         correctly.  XFree86 still will not operate correctly with this option
19583 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
19584 +         and you still want to protect your kernel against modification,
19585 +         use the RBAC system.
19586 +
19587 +config GRKERNSEC_PROC_MEMMAP
19588 +       bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
19589 +       depends on PAX_NOEXEC || PAX_ASLR
19590 +       help
19591 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
19592 +         give no information about the addresses of its mappings if
19593 +         PaX features that rely on random addresses are enabled on the task.
19594 +         If you use PaX it is greatly recommended that you say Y here as it
19595 +         closes up a hole that makes the full ASLR useless for suid
19596 +         binaries.
19597 +
19598 +config GRKERNSEC_BRUTE
19599 +       bool "Deter exploit bruteforcing"
19600 +       help
19601 +         If you say Y here, attempts to bruteforce exploits against forking
19602 +         daemons such as apache or sshd will be deterred.  When a child of a
19603 +         forking daemon is killed by PaX or crashes due to an illegal
19604 +         instruction, the parent process will be delayed 30 seconds upon every
19605 +         subsequent fork until the administrator is able to assess the
19606 +         situation and restart the daemon.  It is recommended that you also
19607 +         enable signal logging in the auditing section so that logs are
19608 +         generated when a process performs an illegal instruction.
19609 +
19610 +config GRKERNSEC_MODSTOP
19611 +       bool "Runtime module disabling"
19612 +       depends on MODULES
19613 +       help
19614 +         If you say Y here, you will be able to disable the ability to (un)load
19615 +         modules at runtime.  This feature is useful if you need the ability
19616 +         to load kernel modules at boot time, but do not want to allow an
19617 +         attacker to load a rootkit kernel module into the system, or to remove
19618 +         a loaded kernel module important to system functioning.  You should
19619 +         enable the /dev/mem protection feature as well, since rootkits can be
19620 +         inserted into the kernel via other methods than kernel modules.  Since
19621 +         an untrusted module could still be loaded by modifying init scripts and
19622 +         rebooting the system, it is also recommended that you enable the RBAC
19623 +         system.  If you enable this option, a sysctl option with name
19624 +         "disable_modules" will be created.  Setting this option to "1" disables
19625 +         module loading.  After this option is set, no further writes to it are
19626 +         allowed until the system is rebooted.
19627 +
19628 +config GRKERNSEC_HIDESYM
19629 +       bool "Hide kernel symbols"
19630 +       help
19631 +         If you say Y here, getting information on loaded modules, and
19632 +         displaying all kernel symbols through a syscall will be restricted
19633 +         to users with CAP_SYS_MODULE.  This option is only effective
19634 +         provided the following conditions are met:
19635 +         1) The kernel using grsecurity is not precompiled by some distribution
19636 +         2) You are using the RBAC system and hiding other files such as your
19637 +            kernel image and System.map
19638 +         3) You have the additional /proc restrictions enabled, which removes
19639 +            /proc/kcore
19640 +         If the above conditions are met, this option will aid to provide a
19641 +         useful protection against local and remote kernel exploitation of
19642 +         overflows and arbitrary read/write vulnerabilities.
19643 +
19644 +endmenu
19645 +menu "Role Based Access Control Options"
19646 +depends on GRKERNSEC
19647 +
19648 +config GRKERNSEC_ACL_HIDEKERN
19649 +       bool "Hide kernel processes"
19650 +       help
19651 +         If you say Y here, all kernel threads will be hidden to all
19652 +         processes but those whose subject has the "view hidden processes"
19653 +         flag.
19654 +
19655 +config GRKERNSEC_ACL_MAXTRIES
19656 +       int "Maximum tries before password lockout"
19657 +       default 3
19658 +       help
19659 +         This option enforces the maximum number of times a user can attempt
19660 +         to authorize themselves with the grsecurity RBAC system before being
19661 +         denied the ability to attempt authorization again for a specified time.
19662 +         The lower the number, the harder it will be to brute-force a password.
19663 +
19664 +config GRKERNSEC_ACL_TIMEOUT
19665 +       int "Time to wait after max password tries, in seconds"
19666 +       default 30
19667 +       help
19668 +         This option specifies the time the user must wait after attempting to
19669 +         authorize to the RBAC system with the maximum number of invalid
19670 +         passwords.  The higher the number, the harder it will be to brute-force
19671 +         a password.
19672 +
19673 +endmenu
19674 +menu "Filesystem Protections"
19675 +depends on GRKERNSEC
19676 +
19677 +config GRKERNSEC_PROC
19678 +       bool "Proc restrictions"
19679 +       help
19680 +         If you say Y here, the permissions of the /proc filesystem
19681 +         will be altered to enhance system security and privacy.  You MUST
19682 +         choose either a user only restriction or a user and group restriction.
19683 +         Depending upon the option you choose, you can either restrict users to
19684 +         see only the processes they themselves run, or choose a group that can
19685 +         view all processes and files normally restricted to root if you choose
19686 +         the "restrict to user only" option.  NOTE: If you're running identd as
19687 +         a non-root user, you will have to run it as the group you specify here.
19688 +
19689 +config GRKERNSEC_PROC_USER
19690 +       bool "Restrict /proc to user only"
19691 +       depends on GRKERNSEC_PROC
19692 +       help
19693 +         If you say Y here, non-root users will only be able to view their own
19694 +         processes, and restricts them from viewing network-related information,
19695 +         and viewing kernel symbol and module information.
19696 +
19697 +config GRKERNSEC_PROC_USERGROUP
19698 +       bool "Allow special group"
19699 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
19700 +       help
19701 +         If you say Y here, you will be able to select a group that will be
19702 +         able to view all processes, network-related information, and
19703 +         kernel and symbol information.  This option is useful if you want
19704 +         to run identd as a non-root user.
19705 +
19706 +config GRKERNSEC_PROC_GID
19707 +       int "GID for special group"
19708 +       depends on GRKERNSEC_PROC_USERGROUP
19709 +       default 1001
19710 +
19711 +config GRKERNSEC_PROC_ADD
19712 +       bool "Additional restrictions"
19713 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
19714 +       help
19715 +         If you say Y here, additional restrictions will be placed on
19716 +         /proc that keep normal users from viewing device information and 
19717 +         slabinfo information that could be useful for exploits.
19718 +
19719 +config GRKERNSEC_LINK
19720 +       bool "Linking restrictions"
19721 +       help
19722 +         If you say Y here, /tmp race exploits will be prevented, since users
19723 +         will no longer be able to follow symlinks owned by other users in
19724 +         world-writable +t directories (i.e. /tmp), unless the owner of the
19725 +         symlink is the owner of the directory. users will also not be
19726 +         able to hardlink to files they do not own.  If the sysctl option is
19727 +         enabled, a sysctl option with name "linking_restrictions" is created.
19728 +
19729 +config GRKERNSEC_FIFO
19730 +       bool "FIFO restrictions"
19731 +       help
19732 +         If you say Y here, users will not be able to write to FIFOs they don't
19733 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
19734 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
19735 +         option is enabled, a sysctl option with name "fifo_restrictions" is
19736 +         created.
19737 +
19738 +config GRKERNSEC_CHROOT
19739 +       bool "Chroot jail restrictions"
19740 +       help
19741 +         If you say Y here, you will be able to choose several options that will
19742 +         make breaking out of a chrooted jail much more difficult.  If you
19743 +         encounter no software incompatibilities with the following options, it
19744 +         is recommended that you enable each one.
19745 +
19746 +config GRKERNSEC_CHROOT_MOUNT
19747 +       bool "Deny mounts"
19748 +       depends on GRKERNSEC_CHROOT
19749 +       help
19750 +         If you say Y here, processes inside a chroot will not be able to
19751 +         mount or remount filesystems.  If the sysctl option is enabled, a
19752 +         sysctl option with name "chroot_deny_mount" is created.
19753 +
19754 +config GRKERNSEC_CHROOT_DOUBLE
19755 +       bool "Deny double-chroots"
19756 +       depends on GRKERNSEC_CHROOT
19757 +       help
19758 +         If you say Y here, processes inside a chroot will not be able to chroot
19759 +         again outside the chroot.  This is a widely used method of breaking
19760 +         out of a chroot jail and should not be allowed.  If the sysctl 
19761 +         option is enabled, a sysctl option with name 
19762 +         "chroot_deny_chroot" is created.
19763 +
19764 +config GRKERNSEC_CHROOT_PIVOT
19765 +       bool "Deny pivot_root in chroot"
19766 +       depends on GRKERNSEC_CHROOT
19767 +       help
19768 +         If you say Y here, processes inside a chroot will not be able to use
19769 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
19770 +         works similar to chroot in that it changes the root filesystem.  This
19771 +         function could be misused in a chrooted process to attempt to break out
19772 +         of the chroot, and therefore should not be allowed.  If the sysctl
19773 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
19774 +         created.
19775 +
19776 +config GRKERNSEC_CHROOT_CHDIR
19777 +       bool "Enforce chdir(\"/\") on all chroots"
19778 +       depends on GRKERNSEC_CHROOT
19779 +       help
19780 +         If you say Y here, the current working directory of all newly-chrooted
19781 +         applications will be set to the the root directory of the chroot.
19782 +         The man page on chroot(2) states:
19783 +         Note that this call does not change  the  current  working
19784 +         directory,  so  that `.' can be outside the tree rooted at
19785 +         `/'.  In particular, the  super-user  can  escape  from  a
19786 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
19787 +
19788 +         It is recommended that you say Y here, since it's not known to break
19789 +         any software.  If the sysctl option is enabled, a sysctl option with
19790 +         name "chroot_enforce_chdir" is created.
19791 +
19792 +config GRKERNSEC_CHROOT_CHMOD
19793 +       bool "Deny (f)chmod +s"
19794 +       depends on GRKERNSEC_CHROOT
19795 +       help
19796 +         If you say Y here, processes inside a chroot will not be able to chmod
19797 +         or fchmod files to make them have suid or sgid bits.  This protects
19798 +         against another published method of breaking a chroot.  If the sysctl
19799 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
19800 +         created.
19801 +
19802 +config GRKERNSEC_CHROOT_FCHDIR
19803 +       bool "Deny fchdir out of chroot"
19804 +       depends on GRKERNSEC_CHROOT
19805 +       help
19806 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
19807 +         to a file descriptor of the chrooting process that points to a directory
19808 +         outside the filesystem will be stopped.  If the sysctl option
19809 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
19810 +
19811 +config GRKERNSEC_CHROOT_MKNOD
19812 +       bool "Deny mknod"
19813 +       depends on GRKERNSEC_CHROOT
19814 +       help
19815 +         If you say Y here, processes inside a chroot will not be allowed to
19816 +         mknod.  The problem with using mknod inside a chroot is that it
19817 +         would allow an attacker to create a device entry that is the same
19818 +         as one on the physical root of your system, which could range from
19819 +         anything from the console device to a device for your harddrive (which
19820 +         they could then use to wipe the drive or steal data).  It is recommended
19821 +         that you say Y here, unless you run into software incompatibilities.
19822 +         If the sysctl option is enabled, a sysctl option with name
19823 +         "chroot_deny_mknod" is created.
19824 +
19825 +config GRKERNSEC_CHROOT_SHMAT
19826 +       bool "Deny shmat() out of chroot"
19827 +       depends on GRKERNSEC_CHROOT
19828 +       help
19829 +         If you say Y here, processes inside a chroot will not be able to attach
19830 +         to shared memory segments that were created outside of the chroot jail.
19831 +         It is recommended that you say Y here.  If the sysctl option is enabled,
19832 +         a sysctl option with name "chroot_deny_shmat" is created.
19833 +
19834 +config GRKERNSEC_CHROOT_UNIX
19835 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
19836 +       depends on GRKERNSEC_CHROOT
19837 +       help
19838 +         If you say Y here, processes inside a chroot will not be able to
19839 +         connect to abstract (meaning not belonging to a filesystem) Unix
19840 +         domain sockets that were bound outside of a chroot.  It is recommended
19841 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
19842 +         with name "chroot_deny_unix" is created.
19843 +
19844 +config GRKERNSEC_CHROOT_FINDTASK
19845 +       bool "Protect outside processes"
19846 +       depends on GRKERNSEC_CHROOT
19847 +       help
19848 +         If you say Y here, processes inside a chroot will not be able to
19849 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
19850 +         getsid, or view any process outside of the chroot.  If the sysctl
19851 +         option is enabled, a sysctl option with name "chroot_findtask" is
19852 +         created.
19853 +
19854 +config GRKERNSEC_CHROOT_NICE
19855 +       bool "Restrict priority changes"
19856 +       depends on GRKERNSEC_CHROOT
19857 +       help
19858 +         If you say Y here, processes inside a chroot will not be able to raise
19859 +         the priority of processes in the chroot, or alter the priority of
19860 +         processes outside the chroot.  This provides more security than simply
19861 +         removing CAP_SYS_NICE from the process' capability set.  If the
19862 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
19863 +         is created.
19864 +
19865 +config GRKERNSEC_CHROOT_SYSCTL
19866 +       bool "Deny sysctl writes"
19867 +       depends on GRKERNSEC_CHROOT
19868 +       help
19869 +         If you say Y here, an attacker in a chroot will not be able to
19870 +         write to sysctl entries, either by sysctl(2) or through a /proc
19871 +         interface.  It is strongly recommended that you say Y here. If the
19872 +         sysctl option is enabled, a sysctl option with name
19873 +         "chroot_deny_sysctl" is created.
19874 +
19875 +config GRKERNSEC_CHROOT_CAPS
19876 +       bool "Capability restrictions"
19877 +       depends on GRKERNSEC_CHROOT
19878 +       help
19879 +         If you say Y here, the capabilities on all root processes within a
19880 +         chroot jail will be lowered to stop module insertion, raw i/o,
19881 +         system and net admin tasks, rebooting the system, modifying immutable
19882 +         files, modifying IPC owned by another, and changing the system time.
19883 +         This is left an option because it can break some apps.  Disable this
19884 +         if your chrooted apps are having problems performing those kinds of
19885 +         tasks.  If the sysctl option is enabled, a sysctl option with
19886 +         name "chroot_caps" is created.
19887 +
19888 +endmenu
19889 +menu "Kernel Auditing"
19890 +depends on GRKERNSEC
19891 +
19892 +config GRKERNSEC_AUDIT_GROUP
19893 +       bool "Single group for auditing"
19894 +       help
19895 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
19896 +         will only operate on a group you specify.  This option is recommended
19897 +         if you only want to watch certain users instead of having a large
19898 +         amount of logs from the entire system.  If the sysctl option is enabled,
19899 +         a sysctl option with name "audit_group" is created.
19900 +
19901 +config GRKERNSEC_AUDIT_GID
19902 +       int "GID for auditing"
19903 +       depends on GRKERNSEC_AUDIT_GROUP
19904 +       default 1007
19905 +
19906 +config GRKERNSEC_EXECLOG
19907 +       bool "Exec logging"
19908 +       help
19909 +         If you say Y here, all execve() calls will be logged (since the
19910 +         other exec*() calls are frontends to execve(), all execution
19911 +         will be logged).  Useful for shell-servers that like to keep track
19912 +         of their users.  If the sysctl option is enabled, a sysctl option with
19913 +         name "exec_logging" is created.
19914 +         WARNING: This option when enabled will produce a LOT of logs, especially
19915 +         on an active system.
19916 +
19917 +config GRKERNSEC_RESLOG
19918 +       bool "Resource logging"
19919 +       help
19920 +         If you say Y here, all attempts to overstep resource limits will
19921 +         be logged with the resource name, the requested size, and the current
19922 +         limit.  It is highly recommended that you say Y here.  If the sysctl
19923 +         option is enabled, a sysctl option with name "resource_logging" is
19924 +         created.  If the RBAC system is enabled, the sysctl value is ignored.
19925 +
19926 +config GRKERNSEC_CHROOT_EXECLOG
19927 +       bool "Log execs within chroot"
19928 +       help
19929 +         If you say Y here, all executions inside a chroot jail will be logged
19930 +         to syslog.  This can cause a large amount of logs if certain
19931 +         applications (eg. djb's daemontools) are installed on the system, and
19932 +         is therefore left as an option.  If the sysctl option is enabled, a
19933 +         sysctl option with name "chroot_execlog" is created.
19934 +
19935 +config GRKERNSEC_AUDIT_CHDIR
19936 +       bool "Chdir logging"
19937 +       help
19938 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
19939 +         option is enabled, a sysctl option with name "audit_chdir" is created.
19940 +
19941 +config GRKERNSEC_AUDIT_MOUNT
19942 +       bool "(Un)Mount logging"
19943 +       help
19944 +         If you say Y here, all mounts and unmounts will be logged.  If the
19945 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
19946 +         created.
19947 +
19948 +config GRKERNSEC_AUDIT_IPC
19949 +       bool "IPC logging"
19950 +       help
19951 +         If you say Y here, creation and removal of message queues, semaphores,
19952 +         and shared memory will be logged.  If the sysctl option is enabled, a
19953 +         sysctl option with name "audit_ipc" is created.
19954 +
19955 +config GRKERNSEC_SIGNAL
19956 +       bool "Signal logging"
19957 +       help
19958 +         If you say Y here, certain important signals will be logged, such as
19959 +         SIGSEGV, which will as a result inform you of when a error in a program
19960 +         occurred, which in some cases could mean a possible exploit attempt.
19961 +         If the sysctl option is enabled, a sysctl option with name
19962 +         "signal_logging" is created.
19963 +
19964 +config GRKERNSEC_FORKFAIL
19965 +       bool "Fork failure logging"
19966 +       help
19967 +         If you say Y here, all failed fork() attempts will be logged.
19968 +         This could suggest a fork bomb, or someone attempting to overstep
19969 +         their process limit.  If the sysctl option is enabled, a sysctl option
19970 +         with name "forkfail_logging" is created.
19971 +
19972 +config GRKERNSEC_TIME
19973 +       bool "Time change logging"
19974 +       help
19975 +         If you say Y here, any changes of the system clock will be logged.
19976 +         If the sysctl option is enabled, a sysctl option with name
19977 +         "timechange_logging" is created.
19978 +
19979 +config GRKERNSEC_PROC_IPADDR
19980 +       bool "/proc/<pid>/ipaddr support"
19981 +       help
19982 +         If you say Y here, a new entry will be added to each /proc/<pid>
19983 +         directory that contains the IP address of the person using the task.
19984 +         The IP is carried across local TCP and AF_UNIX stream sockets.
19985 +         This information can be useful for IDS/IPSes to perform remote response
19986 +         to a local attack.  The entry is readable by only the owner of the
19987 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
19988 +         the RBAC system), and thus does not create privacy concerns.
19989 +
19990 +config GRKERNSEC_AUDIT_TEXTREL
19991 +       bool 'ELF text relocations logging (READ HELP)'
19992 +       depends on PAX_MPROTECT
19993 +       help
19994 +         If you say Y here, text relocations will be logged with the filename
19995 +         of the offending library or binary.  The purpose of the feature is
19996 +         to help Linux distribution developers get rid of libraries and
19997 +         binaries that need text relocations which hinder the future progress
19998 +         of PaX.  Only Linux distribution developers should say Y here, and
19999 +         never on a production machine, as this option creates an information
20000 +         leak that could aid an attacker in defeating the randomization of
20001 +         a single memory region.  If the sysctl option is enabled, a sysctl
20002 +         option with name "audit_textrel" is created.
20003 +
20004 +endmenu
20005 +
20006 +menu "Executable Protections"
20007 +depends on GRKERNSEC
20008 +
20009 +config GRKERNSEC_EXECVE
20010 +       bool "Enforce RLIMIT_NPROC on execs"
20011 +       help
20012 +         If you say Y here, users with a resource limit on processes will
20013 +         have the value checked during execve() calls.  The current system
20014 +         only checks the system limit during fork() calls.  If the sysctl option
20015 +         is enabled, a sysctl option with name "execve_limiting" is created.
20016 +
20017 +config GRKERNSEC_SHM
20018 +       bool "Destroy unused shared memory"
20019 +       depends on SYSVIPC
20020 +       help
20021 +         If you say Y here, shared memory will be destroyed when no one is
20022 +         attached to it.  Otherwise, resources involved with the shared
20023 +         memory can be used up and not be associated with any process (as the
20024 +         shared memory still exists, and the creating process has exited).  If
20025 +         the sysctl option is enabled, a sysctl option with name
20026 +         "destroy_unused_shm" is created.
20027 +
20028 +config GRKERNSEC_DMESG
20029 +       bool "Dmesg(8) restriction"
20030 +       help
20031 +         If you say Y here, non-root users will not be able to use dmesg(8)
20032 +         to view up to the last 4kb of messages in the kernel's log buffer.
20033 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
20034 +         created.
20035 +
20036 +config GRKERNSEC_RANDPID
20037 +       bool "Randomized PIDs"
20038 +       help
20039 +         If you say Y here, all PIDs created on the system will be
20040 +         pseudo-randomly generated.  This is extremely effective along
20041 +         with the /proc restrictions to disallow an attacker from guessing
20042 +         pids of daemons, etc.  PIDs are also used in some cases as part
20043 +         of a naming system for temporary files, so this option would keep
20044 +         those filenames from being predicted as well.  We also use code
20045 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
20046 +         option is enabled, a sysctl option with name "rand_pids" is created.
20047 +
20048 +config GRKERNSEC_TPE
20049 +       bool "Trusted Path Execution (TPE)"
20050 +       help
20051 +         If you say Y here, you will be able to choose a gid to add to the
20052 +         supplementary groups of users you want to mark as "untrusted."
20053 +         These users will not be able to execute any files that are not in
20054 +         root-owned directories writable only by root.  If the sysctl option
20055 +         is enabled, a sysctl option with name "tpe" is created.
20056 +
20057 +config GRKERNSEC_TPE_ALL
20058 +       bool "Partially restrict non-root users"
20059 +       depends on GRKERNSEC_TPE
20060 +       help
20061 +         If you say Y here, All non-root users other than the ones in the
20062 +         group specified in the main TPE option will only be allowed to
20063 +         execute files in directories they own that are not group or
20064 +         world-writable, or in directories owned by root and writable only by
20065 +         root.  If the sysctl option is enabled, a sysctl option with name
20066 +         "tpe_restrict_all" is created.
20067 +
20068 +config GRKERNSEC_TPE_INVERT
20069 +       bool "Invert GID option"
20070 +       depends on GRKERNSEC_TPE
20071 +       help
20072 +         If you say Y here, the group you specify in the TPE configuration will
20073 +         decide what group TPE restrictions will be *disabled* for.  This
20074 +         option is useful if you want TPE restrictions to be applied to most
20075 +         users on the system.
20076 +
20077 +config GRKERNSEC_TPE_GID
20078 +       int "GID for untrusted users"
20079 +       depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
20080 +       default 1005
20081 +       help
20082 +         If you have selected the "Invert GID option" above, setting this
20083 +         GID determines what group TPE restrictions will be *disabled* for.
20084 +         If you have not selected the "Invert GID option" above, setting this
20085 +         GID determines what group TPE restrictions will be *enabled* for.
20086 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
20087 +         is created.
20088 +
20089 +config GRKERNSEC_TPE_GID
20090 +       int "GID for trusted users"
20091 +       depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
20092 +       default 1005
20093 +       help
20094 +         If you have selected the "Invert GID option" above, setting this
20095 +         GID determines what group TPE restrictions will be *disabled* for.
20096 +         If you have not selected the "Invert GID option" above, setting this
20097 +         GID determines what group TPE restrictions will be *enabled* for.
20098 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
20099 +         is created.
20100 +
20101 +endmenu
20102 +menu "Network Protections"
20103 +depends on GRKERNSEC
20104 +
20105 +config GRKERNSEC_RANDNET
20106 +       bool "Larger entropy pools"
20107 +       help
20108 +         If you say Y here, the entropy pools used for many features of Linux
20109 +         and grsecurity will be doubled in size.  Since several grsecurity
20110 +         features use additional randomness, it is recommended that you say Y
20111 +         here.  Saying Y here has a similar effect as modifying
20112 +         /proc/sys/kernel/random/poolsize.
20113 +
20114 +config GRKERNSEC_SOCKET
20115 +       bool "Socket restrictions"
20116 +       help
20117 +         If you say Y here, you will be able to choose from several options.
20118 +         If you assign a GID on your system and add it to the supplementary
20119 +         groups of users you want to restrict socket access to, this patch
20120 +         will perform up to three things, based on the option(s) you choose.
20121 +
20122 +config GRKERNSEC_SOCKET_ALL
20123 +       bool "Deny any sockets to group"
20124 +       depends on GRKERNSEC_SOCKET
20125 +       help
20126 +         If you say Y here, you will be able to choose a GID of whose users will
20127 +         be unable to connect to other hosts from your machine or run server
20128 +         applications from your machine.  If the sysctl option is enabled, a
20129 +         sysctl option with name "socket_all" is created.
20130 +
20131 +config GRKERNSEC_SOCKET_ALL_GID
20132 +       int "GID to deny all sockets for"
20133 +       depends on GRKERNSEC_SOCKET_ALL
20134 +       default 1004
20135 +       help
20136 +         Here you can choose the GID to disable socket access for. Remember to
20137 +         add the users you want socket access disabled for to the GID
20138 +         specified here.  If the sysctl option is enabled, a sysctl option
20139 +         with name "socket_all_gid" is created.
20140 +
20141 +config GRKERNSEC_SOCKET_CLIENT
20142 +       bool "Deny client sockets to group"
20143 +       depends on GRKERNSEC_SOCKET
20144 +       help
20145 +         If you say Y here, you will be able to choose a GID of whose users will
20146 +         be unable to connect to other hosts from your machine, but will be
20147 +         able to run servers.  If this option is enabled, all users in the group
20148 +         you specify will have to use passive mode when initiating ftp transfers
20149 +         from the shell on your machine.  If the sysctl option is enabled, a
20150 +         sysctl option with name "socket_client" is created.
20151 +
20152 +config GRKERNSEC_SOCKET_CLIENT_GID
20153 +       int "GID to deny client sockets for"
20154 +       depends on GRKERNSEC_SOCKET_CLIENT
20155 +       default 1003
20156 +       help
20157 +         Here you can choose the GID to disable client socket access for.
20158 +         Remember to add the users you want client socket access disabled for to
20159 +         the GID specified here.  If the sysctl option is enabled, a sysctl
20160 +         option with name "socket_client_gid" is created.
20161 +
20162 +config GRKERNSEC_SOCKET_SERVER
20163 +       bool "Deny server sockets to group"
20164 +       depends on GRKERNSEC_SOCKET
20165 +       help
20166 +         If you say Y here, you will be able to choose a GID of whose users will
20167 +         be unable to run server applications from your machine.  If the sysctl
20168 +         option is enabled, a sysctl option with name "socket_server" is created.
20169 +
20170 +config GRKERNSEC_SOCKET_SERVER_GID
20171 +       int "GID to deny server sockets for"
20172 +       depends on GRKERNSEC_SOCKET_SERVER
20173 +       default 1002
20174 +       help
20175 +         Here you can choose the GID to disable server socket access for.
20176 +         Remember to add the users you want server socket access disabled for to
20177 +         the GID specified here.  If the sysctl option is enabled, a sysctl
20178 +         option with name "socket_server_gid" is created.
20179 +
20180 +endmenu
20181 +menu "Sysctl support"
20182 +depends on GRKERNSEC && SYSCTL
20183 +
20184 +config GRKERNSEC_SYSCTL
20185 +       bool "Sysctl support"
20186 +       help
20187 +         If you say Y here, you will be able to change the options that
20188 +         grsecurity runs with at bootup, without having to recompile your
20189 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
20190 +         to enable (1) or disable (0) various features.  All the sysctl entries
20191 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
20192 +         All features enabled in the kernel configuration are disabled at boot
20193 +         if you do not say Y to the "Turn on features by default" option.
20194 +         All options should be set at startup, and the grsec_lock entry should
20195 +         be set to a non-zero value after all the options are set.
20196 +         *THIS IS EXTREMELY IMPORTANT*
20197 +
20198 +config GRKERNSEC_SYSCTL_ON
20199 +       bool "Turn on features by default"
20200 +       depends on GRKERNSEC_SYSCTL
20201 +       help
20202 +         If you say Y here, instead of having all features enabled in the
20203 +         kernel configuration disabled at boot time, the features will be
20204 +         enabled at boot time.  It is recommended you say Y here unless
20205 +         there is some reason you would want all sysctl-tunable features to
20206 +         be disabled by default.  As mentioned elsewhere, it is important
20207 +         to enable the grsec_lock entry once you have finished modifying
20208 +         the sysctl entries.
20209 +
20210 +endmenu
20211 +menu "Logging Options"
20212 +depends on GRKERNSEC
20213 +
20214 +config GRKERNSEC_FLOODTIME
20215 +       int "Seconds in between log messages (minimum)"
20216 +       default 10
20217 +       help
20218 +         This option allows you to enforce the number of seconds between
20219 +         grsecurity log messages.  The default should be suitable for most
20220 +         people, however, if you choose to change it, choose a value small enough
20221 +         to allow informative logs to be produced, but large enough to
20222 +         prevent flooding.
20223 +
20224 +config GRKERNSEC_FLOODBURST
20225 +       int "Number of messages in a burst (maximum)"
20226 +       default 4
20227 +       help
20228 +         This option allows you to choose the maximum number of messages allowed
20229 +         within the flood time interval you chose in a separate option.  The
20230 +         default should be suitable for most people, however if you find that
20231 +         many of your logs are being interpreted as flooding, you may want to
20232 +         raise this value.
20233 +
20234 +endmenu
20235 +
20236 +endmenu
20237 diff -urNp linux-2.6.18/grsecurity/Makefile linux-2.6.18/grsecurity/Makefile
20238 --- linux-2.6.18/grsecurity/Makefile    1969-12-31 19:00:00.000000000 -0500
20239 +++ linux-2.6.18/grsecurity/Makefile    2006-09-22 20:04:35.000000000 -0400
20240 @@ -0,0 +1,20 @@
20241 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
20242 +# during 2001-2005 it has been completely redesigned by Brad Spengler
20243 +# into an RBAC system
20244 +#
20245 +# All code in this directory and various hooks inserted throughout the kernel
20246 +# are copyright Brad Spengler, and released under the GPL v2 or higher
20247 +
20248 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
20249 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
20250 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
20251 +
20252 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
20253 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
20254 +       gracl_learn.o grsec_log.o
20255 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
20256 +
20257 +ifndef CONFIG_GRKERNSEC
20258 +obj-y += grsec_disabled.o
20259 +endif
20260 +
20261 diff -urNp linux-2.6.18/include/acpi/acmacros.h linux-2.6.18/include/acpi/acmacros.h
20262 --- linux-2.6.18/include/acpi/acmacros.h        2006-09-19 23:42:06.000000000 -0400
20263 +++ linux-2.6.18/include/acpi/acmacros.h        2006-09-22 20:45:04.000000000 -0400
20264 @@ -672,7 +672,7 @@
20265  #define ACPI_DUMP_PATHNAME(a,b,c,d)
20266  #define ACPI_DUMP_RESOURCE_LIST(a)
20267  #define ACPI_DUMP_BUFFER(a,b)
20268 -#define ACPI_DEBUG_PRINT(pl)
20269 +#define ACPI_DEBUG_PRINT(pl) do {} while (0)
20270  #define ACPI_DEBUG_PRINT_RAW(pl)
20271  
20272  #define return_VOID                     return
20273 diff -urNp linux-2.6.18/include/asm-alpha/a.out.h linux-2.6.18/include/asm-alpha/a.out.h
20274 --- linux-2.6.18/include/asm-alpha/a.out.h      2006-09-19 23:42:06.000000000 -0400
20275 +++ linux-2.6.18/include/asm-alpha/a.out.h      2006-09-22 20:45:04.000000000 -0400
20276 @@ -98,7 +98,7 @@ struct exec
20277         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
20278                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
20279  
20280 -#define STACK_TOP \
20281 +#define __STACK_TOP \
20282    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
20283  
20284  #endif
20285 diff -urNp linux-2.6.18/include/asm-alpha/elf.h linux-2.6.18/include/asm-alpha/elf.h
20286 --- linux-2.6.18/include/asm-alpha/elf.h        2006-09-19 23:42:06.000000000 -0400
20287 +++ linux-2.6.18/include/asm-alpha/elf.h        2006-09-22 20:45:04.000000000 -0400
20288 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
20289  
20290  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
20291  
20292 +#ifdef CONFIG_PAX_ASLR
20293 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
20294 +
20295 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20296 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
20297 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20298 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
20299 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20300 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
20301 +#endif
20302 +
20303  /* $0 is set by ld.so to a pointer to a function which might be 
20304     registered using atexit.  This provides a mean for the dynamic
20305     linker to call DT_FINI functions for shared libraries that have
20306 diff -urNp linux-2.6.18/include/asm-alpha/kmap_types.h linux-2.6.18/include/asm-alpha/kmap_types.h
20307 --- linux-2.6.18/include/asm-alpha/kmap_types.h 2006-09-19 23:42:06.000000000 -0400
20308 +++ linux-2.6.18/include/asm-alpha/kmap_types.h 2006-09-22 20:45:04.000000000 -0400
20309 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
20310  D(10)  KM_IRQ1,
20311  D(11)  KM_SOFTIRQ0,
20312  D(12)  KM_SOFTIRQ1,
20313 -D(13)  KM_TYPE_NR
20314 +D(13)  KM_CLEARPAGE,
20315 +D(14)  KM_TYPE_NR
20316  };
20317  
20318  #undef D
20319 diff -urNp linux-2.6.18/include/asm-alpha/page.h linux-2.6.18/include/asm-alpha/page.h
20320 --- linux-2.6.18/include/asm-alpha/page.h       2006-09-19 23:42:06.000000000 -0400
20321 +++ linux-2.6.18/include/asm-alpha/page.h       2006-09-22 20:45:04.000000000 -0400
20322 @@ -93,6 +93,15 @@ typedef unsigned long pgprot_t;
20323  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
20324                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20325  
20326 +#ifdef CONFIG_PAX_PAGEEXEC
20327 +#ifdef CONFIG_PAX_MPROTECT
20328 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20329 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20330 +#else
20331 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20332 +#endif
20333 +#endif
20334 +
20335  #include <asm-generic/memory_model.h>
20336  #include <asm-generic/page.h>
20337  
20338 diff -urNp linux-2.6.18/include/asm-alpha/pgtable.h linux-2.6.18/include/asm-alpha/pgtable.h
20339 --- linux-2.6.18/include/asm-alpha/pgtable.h    2006-09-19 23:42:06.000000000 -0400
20340 +++ linux-2.6.18/include/asm-alpha/pgtable.h    2006-09-22 20:45:04.000000000 -0400
20341 @@ -101,6 +101,17 @@ struct vm_area_struct;
20342  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
20343  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
20344  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
20345 +
20346 +#ifdef CONFIG_PAX_PAGEEXEC
20347 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
20348 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
20349 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
20350 +#else
20351 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20352 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20353 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20354 +#endif
20355 +
20356  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
20357  
20358  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
20359 diff -urNp linux-2.6.18/include/asm-arm/a.out.h linux-2.6.18/include/asm-arm/a.out.h
20360 --- linux-2.6.18/include/asm-arm/a.out.h        2006-09-19 23:42:06.000000000 -0400
20361 +++ linux-2.6.18/include/asm-arm/a.out.h        2006-09-22 20:45:04.000000000 -0400
20362 @@ -28,7 +28,7 @@ struct exec
20363  #define M_ARM 103
20364  
20365  #ifdef __KERNEL__
20366 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
20367 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
20368                          TASK_SIZE : TASK_SIZE_26)
20369  #endif
20370  
20371 diff -urNp linux-2.6.18/include/asm-arm/elf.h linux-2.6.18/include/asm-arm/elf.h
20372 --- linux-2.6.18/include/asm-arm/elf.h  2006-09-19 23:42:06.000000000 -0400
20373 +++ linux-2.6.18/include/asm-arm/elf.h  2006-09-22 20:45:04.000000000 -0400
20374 @@ -57,6 +57,17 @@ typedef struct user_fp elf_fpregset_t;
20375  
20376  #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
20377  
20378 +#ifdef CONFIG_PAX_ASLR
20379 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x00008000UL
20380 +
20381 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20382 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
20383 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20384 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
20385 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20386 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
20387 +#endif
20388 +
20389  /* When the program starts, a1 contains a pointer to a function to be 
20390     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
20391     have no such handler.  */
20392 diff -urNp linux-2.6.18/include/asm-arm/kmap_types.h linux-2.6.18/include/asm-arm/kmap_types.h
20393 --- linux-2.6.18/include/asm-arm/kmap_types.h   2006-09-19 23:42:06.000000000 -0400
20394 +++ linux-2.6.18/include/asm-arm/kmap_types.h   2006-09-22 20:45:04.000000000 -0400
20395 @@ -18,6 +18,7 @@ enum km_type {
20396         KM_IRQ1,
20397         KM_SOFTIRQ0,
20398         KM_SOFTIRQ1,
20399 +       KM_CLEARPAGE,
20400         KM_TYPE_NR
20401  };
20402  
20403 diff -urNp linux-2.6.18/include/asm-arm26/kmap_types.h linux-2.6.18/include/asm-arm26/kmap_types.h
20404 --- linux-2.6.18/include/asm-arm26/kmap_types.h 2006-09-19 23:42:06.000000000 -0400
20405 +++ linux-2.6.18/include/asm-arm26/kmap_types.h 2006-09-22 20:45:04.000000000 -0400
20406 @@ -6,7 +6,8 @@
20407   */
20408  enum km_type {
20409          KM_IRQ0,
20410 -        KM_USER1
20411 +        KM_USER1,
20412 +        KM_CLEARPAGE
20413  };
20414  
20415  #endif
20416 diff -urNp linux-2.6.18/include/asm-cris/kmap_types.h linux-2.6.18/include/asm-cris/kmap_types.h
20417 --- linux-2.6.18/include/asm-cris/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
20418 +++ linux-2.6.18/include/asm-cris/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
20419 @@ -19,6 +19,7 @@ enum km_type {
20420         KM_IRQ1,
20421         KM_SOFTIRQ0,
20422         KM_SOFTIRQ1,
20423 +       KM_CLEARPAGE,
20424         KM_TYPE_NR
20425  };
20426  
20427 diff -urNp linux-2.6.18/include/asm-frv/kmap_types.h linux-2.6.18/include/asm-frv/kmap_types.h
20428 --- linux-2.6.18/include/asm-frv/kmap_types.h   2006-09-19 23:42:06.000000000 -0400
20429 +++ linux-2.6.18/include/asm-frv/kmap_types.h   2006-09-22 20:45:04.000000000 -0400
20430 @@ -23,6 +23,7 @@ enum km_type {
20431         KM_IRQ1,
20432         KM_SOFTIRQ0,
20433         KM_SOFTIRQ1,
20434 +       KM_CLEARPAGE,
20435         KM_TYPE_NR
20436  };
20437  
20438 diff -urNp linux-2.6.18/include/asm-h8300/kmap_types.h linux-2.6.18/include/asm-h8300/kmap_types.h
20439 --- linux-2.6.18/include/asm-h8300/kmap_types.h 2006-09-19 23:42:06.000000000 -0400
20440 +++ linux-2.6.18/include/asm-h8300/kmap_types.h 2006-09-22 20:45:04.000000000 -0400
20441 @@ -15,6 +15,7 @@ enum km_type {
20442         KM_IRQ1,
20443         KM_SOFTIRQ0,
20444         KM_SOFTIRQ1,
20445 +       KM_CLEARPAGE,
20446         KM_TYPE_NR
20447  };
20448  
20449 diff -urNp linux-2.6.18/include/asm-i386/alternative.h linux-2.6.18/include/asm-i386/alternative.h
20450 --- linux-2.6.18/include/asm-i386/alternative.h 2006-09-19 23:42:06.000000000 -0400
20451 +++ linux-2.6.18/include/asm-i386/alternative.h 2006-09-22 20:45:04.000000000 -0400
20452 @@ -57,7 +57,7 @@ static inline void alternatives_smp_swit
20453                       "  .byte 662b-661b\n"       /* sourcelen */       \
20454                       "  .byte 664f-663f\n"       /* replacementlen */  \
20455                       ".previous\n"                                     \
20456 -                     ".section .altinstr_replacement,\"ax\"\n"         \
20457 +                     ".section .altinstr_replacement,\"a\"\n"          \
20458                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
20459                       ".previous" :: "i" (feature) : "memory")
20460  
20461 @@ -81,7 +81,7 @@ static inline void alternatives_smp_swit
20462                       "  .byte 662b-661b\n"       /* sourcelen */       \
20463                       "  .byte 664f-663f\n"       /* replacementlen */  \
20464                       ".previous\n"                                     \
20465 -                     ".section .altinstr_replacement,\"ax\"\n"         \
20466 +                     ".section .altinstr_replacement,\"a\"\n"          \
20467                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
20468                       ".previous" :: "i" (feature), ##input)
20469  
20470 diff -urNp linux-2.6.18/include/asm-i386/a.out.h linux-2.6.18/include/asm-i386/a.out.h
20471 --- linux-2.6.18/include/asm-i386/a.out.h       2006-09-19 23:42:06.000000000 -0400
20472 +++ linux-2.6.18/include/asm-i386/a.out.h       2006-09-22 20:45:04.000000000 -0400
20473 @@ -19,7 +19,11 @@ struct exec
20474  
20475  #ifdef __KERNEL__
20476  
20477 -#define STACK_TOP      TASK_SIZE
20478 +#ifdef CONFIG_PAX_SEGMEXEC
20479 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
20480 +#else
20481 +#define __STACK_TOP TASK_SIZE
20482 +#endif
20483  
20484  #endif
20485  
20486 diff -urNp linux-2.6.18/include/asm-i386/apic.h linux-2.6.18/include/asm-i386/apic.h
20487 --- linux-2.6.18/include/asm-i386/apic.h        2006-09-19 23:42:06.000000000 -0400
20488 +++ linux-2.6.18/include/asm-i386/apic.h        2006-09-22 20:45:04.000000000 -0400
20489 @@ -7,7 +7,7 @@
20490  #include <asm/processor.h>
20491  #include <asm/system.h>
20492  
20493 -#define Dprintk(x...)
20494 +#define Dprintk(x...) do {} while (0)
20495  
20496  /*
20497   * Debugging macros
20498 diff -urNp linux-2.6.18/include/asm-i386/bug.h linux-2.6.18/include/asm-i386/bug.h
20499 --- linux-2.6.18/include/asm-i386/bug.h 2006-09-19 23:42:06.000000000 -0400
20500 +++ linux-2.6.18/include/asm-i386/bug.h 2006-09-22 20:45:04.000000000 -0400
20501 @@ -11,10 +11,9 @@
20502  #ifdef CONFIG_BUG
20503  #define HAVE_ARCH_BUG
20504  #ifdef CONFIG_DEBUG_BUGVERBOSE
20505 -#define BUG()                          \
20506 - __asm__ __volatile__( "ud2\n"         \
20507 -                       "\t.word %c0\n" \
20508 -                       "\t.long %c1\n" \
20509 +#define BUG()                                  \
20510 + __asm__ __volatile__( "ud2\n\t"               \
20511 +                       "ljmp %0, %1\n\t"       \
20512                          : : "i" (__LINE__), "i" (__FILE__))
20513  #else
20514  #define BUG() __asm__ __volatile__("ud2\n")
20515 diff -urNp linux-2.6.18/include/asm-i386/checksum.h linux-2.6.18/include/asm-i386/checksum.h
20516 --- linux-2.6.18/include/asm-i386/checksum.h    2006-09-19 23:42:06.000000000 -0400
20517 +++ linux-2.6.18/include/asm-i386/checksum.h    2006-09-22 20:45:04.000000000 -0400
20518 @@ -30,6 +30,12 @@ asmlinkage unsigned int csum_partial(con
20519  asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned char *dst,
20520                                                   int len, int sum, int *src_err_ptr, int *dst_err_ptr);
20521  
20522 +asmlinkage unsigned int csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
20523 +                                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
20524 +
20525 +asmlinkage unsigned int csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
20526 +                                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
20527 +
20528  /*
20529   *     Note: when you get a NULL pointer exception here this means someone
20530   *     passed in an incorrect kernel address to one of these functions.
20531 @@ -49,7 +55,7 @@ unsigned int csum_partial_copy_from_user
20532                                                 int len, int sum, int *err_ptr)
20533  {
20534         might_sleep();
20535 -       return csum_partial_copy_generic((__force unsigned char *)src, dst,
20536 +       return csum_partial_copy_generic_from_user((__force unsigned char *)src, dst,
20537                                         len, sum, err_ptr, NULL);
20538  }
20539  
20540 @@ -183,7 +189,7 @@ static __inline__ unsigned int csum_and_
20541  {
20542         might_sleep();
20543         if (access_ok(VERIFY_WRITE, dst, len))
20544 -               return csum_partial_copy_generic(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
20545 +               return csum_partial_copy_generic_to_user(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
20546  
20547         if (len)
20548                 *err_ptr = -EFAULT;
20549 diff -urNp linux-2.6.18/include/asm-i386/desc.h linux-2.6.18/include/asm-i386/desc.h
20550 --- linux-2.6.18/include/asm-i386/desc.h        2006-09-19 23:42:06.000000000 -0400
20551 +++ linux-2.6.18/include/asm-i386/desc.h        2006-09-22 20:45:04.000000000 -0400
20552 @@ -10,11 +10,13 @@
20553  
20554  #include <linux/preempt.h>
20555  #include <linux/smp.h>
20556 -#include <linux/percpu.h>
20557 +#include <linux/sched.h>
20558  
20559  #include <asm/mmu.h>
20560 +#include <asm/pgtable.h>
20561 +#include <asm/tlbflush.h>
20562  
20563 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
20564 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
20565  
20566  DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
20567  
20568 @@ -24,13 +26,53 @@ struct Xgt_desc_struct {
20569         unsigned short pad;
20570  } __attribute__ ((packed));
20571  
20572 -extern struct Xgt_desc_struct idt_descr;
20573 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
20574 -
20575 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
20576  
20577  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
20578  {
20579 -       return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
20580 +       return cpu_gdt_table[cpu];
20581 +}
20582 +
20583 +#define pax_open_kernel(cr0)           \
20584 +do {                                   \
20585 +       typecheck(unsigned long,cr0);   \
20586 +       preempt_disable();              \
20587 +       cr0 = read_cr0();               \
20588 +       write_cr0(cr0 & ~0x10000UL);    \
20589 +} while(0)
20590 +
20591 +#define pax_close_kernel(cr0)          \
20592 +do {                                   \
20593 +       typecheck(unsigned long,cr0);   \
20594 +       write_cr0(cr0);                 \
20595 +       preempt_enable_no_resched();    \
20596 +} while(0)
20597 +
20598 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
20599 +{
20600 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20601 +       unsigned long base = mm->context.user_cs_base;
20602 +       unsigned long limit = mm->context.user_cs_limit;
20603 +
20604 +#ifdef CONFIG_PAX_KERNEXEC
20605 +       unsigned long cr0;
20606 +
20607 +       pax_open_kernel(cr0);
20608 +#endif
20609 +
20610 +       if (likely(limit)) {
20611 +               limit -= 1UL;
20612 +               limit >>= 12;
20613 +       }
20614 +
20615 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
20616 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
20617 +
20618 +#ifdef CONFIG_PAX_KERNEXEC
20619 +       pax_close_kernel(cr0);
20620 +#endif
20621 +
20622 +#endif
20623  }
20624  
20625  #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
20626 @@ -50,7 +92,7 @@ static inline struct desc_struct *get_cp
20627   * This is the ldt that every process will get unless we need
20628   * something other than this.
20629   */
20630 -extern struct desc_struct default_ldt[];
20631 +extern const struct desc_struct default_ldt[];
20632  extern void set_intr_gate(unsigned int irq, void * addr);
20633  
20634  #define _set_tssldt_desc(n,addr,limit,type) \
20635 @@ -64,7 +106,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
20636         "rorl $16,%1" \
20637         : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
20638  
20639 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
20640 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
20641  {
20642         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
20643                 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
20644 @@ -72,11 +114,28 @@ static inline void __set_tss_desc(unsign
20645  
20646  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
20647  
20648 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
20649 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
20650  {
20651         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
20652  }
20653  
20654 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
20655 +{
20656 +
20657 +#ifdef CONFIG_PAX_KERNEXEC
20658 +       unsigned long cr0;
20659 +
20660 +       pax_open_kernel(cr0);
20661 +#endif
20662 +
20663 +       _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
20664 +
20665 +#ifdef CONFIG_PAX_KERNEXEC
20666 +       pax_close_kernel(cr0);
20667 +#endif
20668 +
20669 +}
20670 +
20671  #define LDT_entry_a(info) \
20672         ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
20673  
20674 @@ -90,7 +149,7 @@ static inline void set_ldt_desc(unsigned
20675         ((info)->seg_32bit << 22) | \
20676         ((info)->limit_in_pages << 23) | \
20677         ((info)->useable << 20) | \
20678 -       0x7000)
20679 +       0x7100)
20680  
20681  #define LDT_empty(info) (\
20682         (info)->base_addr       == 0    && \
20683 @@ -134,7 +193,7 @@ static inline void clear_LDT(void)
20684   */
20685  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
20686  {
20687 -       void *segments = pc->ldt;
20688 +       const void *segments = pc->ldt;
20689         int count = pc->size;
20690  
20691         if (likely(!count)) {
20692 @@ -162,6 +221,22 @@ static inline unsigned long get_desc_bas
20693         return base;
20694  }
20695  
20696 +static inline void _load_LDT(mm_context_t *pc)
20697 +{
20698 +       int cpu = get_cpu();
20699 +       const void *segments = pc->ldt;
20700 +       int count = pc->size;
20701 +
20702 +       if (likely(!count)) {
20703 +               segments = &default_ldt[0];
20704 +               count = 5;
20705 +       }
20706 +               
20707 +       __set_ldt_desc(cpu, segments, count);
20708 +       load_LDT_desc();
20709 +       put_cpu();
20710 +}
20711 +
20712  #endif /* !__ASSEMBLY__ */
20713  
20714  #endif
20715 diff -urNp linux-2.6.18/include/asm-i386/elf.h linux-2.6.18/include/asm-i386/elf.h
20716 --- linux-2.6.18/include/asm-i386/elf.h 2006-09-19 23:42:06.000000000 -0400
20717 +++ linux-2.6.18/include/asm-i386/elf.h 2006-09-22 20:45:04.000000000 -0400
20718 @@ -75,7 +75,22 @@ typedef struct user_fxsr_struct elf_fpxr
20719     the loader.  We need to make sure that it is out of the way of the program
20720     that it will "exec", and that there is sufficient room for the brk.  */
20721  
20722 +#ifdef CONFIG_PAX_SEGMEXEC
20723 +#define ELF_ET_DYN_BASE         ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
20724 +#else
20725  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
20726 +#endif
20727 +
20728 +#ifdef CONFIG_PAX_ASLR
20729 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
20730 +
20731 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20732 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
20733 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20734 +#define PAX_DELTA_EXEC_LEN(tsk)                15
20735 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20736 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
20737 +#endif
20738  
20739  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
20740     now struct_user_regs, they are different) */
20741 diff -urNp linux-2.6.18/include/asm-i386/i387.h linux-2.6.18/include/asm-i386/i387.h
20742 --- linux-2.6.18/include/asm-i386/i387.h        2006-09-19 23:42:06.000000000 -0400
20743 +++ linux-2.6.18/include/asm-i386/i387.h        2006-09-22 20:45:04.000000000 -0400
20744 @@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
20745  #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
20746  
20747  /* We need a safe address that is cheap to find and that is already
20748 -   in L1 during context switch. The best choices are unfortunately
20749 -   different for UP and SMP */
20750 -#ifdef CONFIG_SMP
20751 -#define safe_address (__per_cpu_offset[0])
20752 -#else
20753 -#define safe_address (kstat_cpu(0).cpustat.user)
20754 -#endif
20755 +   in L1 during context switch. */
20756 +#define safe_address (init_tss[smp_processor_id()].esp0)
20757  
20758  /*
20759   * These must be called with preempt disabled
20760 diff -urNp linux-2.6.18/include/asm-i386/kmap_types.h linux-2.6.18/include/asm-i386/kmap_types.h
20761 --- linux-2.6.18/include/asm-i386/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
20762 +++ linux-2.6.18/include/asm-i386/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
20763 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
20764  D(10)  KM_IRQ1,
20765  D(11)  KM_SOFTIRQ0,
20766  D(12)  KM_SOFTIRQ1,
20767 -D(13)  KM_TYPE_NR
20768 +D(13)  KM_CLEARPAGE,
20769 +D(14)  KM_TYPE_NR
20770  };
20771  
20772  #undef D
20773 diff -urNp linux-2.6.18/include/asm-i386/mach-default/apm.h linux-2.6.18/include/asm-i386/mach-default/apm.h
20774 --- linux-2.6.18/include/asm-i386/mach-default/apm.h    2006-09-19 23:42:06.000000000 -0400
20775 +++ linux-2.6.18/include/asm-i386/mach-default/apm.h    2006-09-22 20:45:04.000000000 -0400
20776 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
20777         __asm__ __volatile__(APM_DO_ZERO_SEGS
20778                 "pushl %%edi\n\t"
20779                 "pushl %%ebp\n\t"
20780 -               "lcall *%%cs:apm_bios_entry\n\t"
20781 +               "lcall *%%ss:apm_bios_entry\n\t"
20782                 "setc %%al\n\t"
20783                 "popl %%ebp\n\t"
20784                 "popl %%edi\n\t"
20785 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
20786         __asm__ __volatile__(APM_DO_ZERO_SEGS
20787                 "pushl %%edi\n\t"
20788                 "pushl %%ebp\n\t"
20789 -               "lcall *%%cs:apm_bios_entry\n\t"
20790 +               "lcall *%%ss:apm_bios_entry\n\t"
20791                 "setc %%bl\n\t"
20792                 "popl %%ebp\n\t"
20793                 "popl %%edi\n\t"
20794 diff -urNp linux-2.6.18/include/asm-i386/mach-default/do_timer.h linux-2.6.18/include/asm-i386/mach-default/do_timer.h
20795 --- linux-2.6.18/include/asm-i386/mach-default/do_timer.h       2006-09-19 23:42:06.000000000 -0400
20796 +++ linux-2.6.18/include/asm-i386/mach-default/do_timer.h       2006-09-22 20:45:04.000000000 -0400
20797 @@ -18,7 +18,7 @@ static inline void do_timer_interrupt_ho
20798  {
20799         do_timer(regs);
20800  #ifndef CONFIG_SMP
20801 -       update_process_times(user_mode_vm(regs));
20802 +       update_process_times(user_mode(regs));
20803  #endif
20804  /*
20805   * In the SMP case we use the local APIC timer interrupt to do the
20806 diff -urNp linux-2.6.18/include/asm-i386/mach-visws/do_timer.h linux-2.6.18/include/asm-i386/mach-visws/do_timer.h
20807 --- linux-2.6.18/include/asm-i386/mach-visws/do_timer.h 2006-09-19 23:42:06.000000000 -0400
20808 +++ linux-2.6.18/include/asm-i386/mach-visws/do_timer.h 2006-09-22 20:45:04.000000000 -0400
20809 @@ -11,7 +11,7 @@ static inline void do_timer_interrupt_ho
20810  
20811         do_timer(regs);
20812  #ifndef CONFIG_SMP
20813 -       update_process_times(user_mode_vm(regs));
20814 +       update_process_times(user_mode(regs));
20815  #endif
20816  /*
20817   * In the SMP case we use the local APIC timer interrupt to do the
20818 diff -urNp linux-2.6.18/include/asm-i386/mach-voyager/do_timer.h linux-2.6.18/include/asm-i386/mach-voyager/do_timer.h
20819 --- linux-2.6.18/include/asm-i386/mach-voyager/do_timer.h       2006-09-19 23:42:06.000000000 -0400
20820 +++ linux-2.6.18/include/asm-i386/mach-voyager/do_timer.h       2006-09-22 20:45:04.000000000 -0400
20821 @@ -5,7 +5,7 @@ static inline void do_timer_interrupt_ho
20822  {
20823         do_timer(regs);
20824  #ifndef CONFIG_SMP
20825 -       update_process_times(user_mode_vm(regs));
20826 +       update_process_times(user_mode(regs));
20827  #endif
20828  
20829         voyager_timer_interrupt(regs);
20830 diff -urNp linux-2.6.18/include/asm-i386/mman.h linux-2.6.18/include/asm-i386/mman.h
20831 --- linux-2.6.18/include/asm-i386/mman.h        2006-09-19 23:42:06.000000000 -0400
20832 +++ linux-2.6.18/include/asm-i386/mman.h        2006-09-22 20:45:04.000000000 -0400
20833 @@ -11,6 +11,10 @@
20834  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
20835  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
20836  
20837 +#ifdef CONFIG_PAX_SEGMEXEC
20838 +#define MAP_MIRROR     0x20000
20839 +#endif
20840 +
20841  #define MCL_CURRENT    1               /* lock all current mappings */
20842  #define MCL_FUTURE     2               /* lock all future mappings */
20843  
20844 diff -urNp linux-2.6.18/include/asm-i386/mmu_context.h linux-2.6.18/include/asm-i386/mmu_context.h
20845 --- linux-2.6.18/include/asm-i386/mmu_context.h 2006-09-19 23:42:06.000000000 -0400
20846 +++ linux-2.6.18/include/asm-i386/mmu_context.h 2006-09-22 23:33:51.000000000 -0400
20847 @@ -45,6 +45,17 @@ static inline void switch_mm(struct mm_s
20848                  */
20849                 if (unlikely(prev->context.ldt != next->context.ldt))
20850                         load_LDT_nolock(&next->context, cpu);
20851 +
20852 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
20853 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
20854 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
20855 +#endif
20856 +
20857 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20858 +               if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
20859 +                            prev->context.user_cs_limit != next->context.user_cs_limit))
20860 +#endif
20861 +                       set_user_cs(next, cpu);
20862         }
20863  #ifdef CONFIG_SMP
20864         else {
20865 @@ -57,6 +68,12 @@ static inline void switch_mm(struct mm_s
20866                          */
20867                         load_cr3(next->pgd);
20868                         load_LDT_nolock(&next->context, cpu);
20869 +
20870 +#ifdef CONFIG_PAX_PAGEEXEC
20871 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
20872 +#endif
20873 +
20874 +                       set_user_cs(next, cpu);
20875                 }
20876         }
20877  #endif
20878 diff -urNp linux-2.6.18/include/asm-i386/mmu.h linux-2.6.18/include/asm-i386/mmu.h
20879 --- linux-2.6.18/include/asm-i386/mmu.h 2006-09-19 23:42:06.000000000 -0400
20880 +++ linux-2.6.18/include/asm-i386/mmu.h 2006-09-22 20:45:04.000000000 -0400
20881 @@ -13,6 +13,17 @@ typedef struct { 
20882         struct semaphore sem;
20883         void *ldt;
20884         void *vdso;
20885 +
20886 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20887 +       unsigned long user_cs_base;
20888 +       unsigned long user_cs_limit;
20889 +
20890 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
20891 +       cpumask_t cpu_user_cs_mask;
20892 +#endif
20893 +
20894 +#endif
20895 +
20896  } mm_context_t;
20897  
20898  #endif
20899 diff -urNp linux-2.6.18/include/asm-i386/module.h linux-2.6.18/include/asm-i386/module.h
20900 --- linux-2.6.18/include/asm-i386/module.h      2006-09-19 23:42:06.000000000 -0400
20901 +++ linux-2.6.18/include/asm-i386/module.h      2006-09-22 20:04:35.000000000 -0400
20902 @@ -72,6 +72,12 @@ struct mod_arch_specific
20903  #define MODULE_STACKSIZE ""
20904  #endif
20905  
20906 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
20907 +#ifdef CONFIG_GRKERNSEC
20908 +#define MODULE_GRSEC "GRSECURITY "
20909 +#else
20910 +#define MODULE_GRSEC ""
20911 +#endif
20912 +
20913 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
20914  
20915  #endif /* _ASM_I386_MODULE_H */
20916 diff -urNp linux-2.6.18/include/asm-i386/page.h linux-2.6.18/include/asm-i386/page.h
20917 --- linux-2.6.18/include/asm-i386/page.h        2006-09-19 23:42:06.000000000 -0400
20918 +++ linux-2.6.18/include/asm-i386/page.h        2006-09-22 20:45:04.000000000 -0400
20919 @@ -51,13 +51,14 @@ typedef struct { unsigned long long pgpr
20920  #define pmd_val(x)     ((x).pmd)
20921  #define pte_val(x)     ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
20922  #define __pmd(x) ((pmd_t) { (x) } )
20923 +#define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
20924  #define HPAGE_SHIFT    21
20925  #else
20926  typedef struct { unsigned long pte_low; } pte_t;
20927  typedef struct { unsigned long pgd; } pgd_t;
20928  typedef struct { unsigned long pgprot; } pgprot_t;
20929 -#define boot_pte_t pte_t /* or would you rather have a typedef */
20930  #define pte_val(x)     ((x).pte_low)
20931 +#define __pte(x) ((pte_t) { (x) } )
20932  #define HPAGE_SHIFT    22
20933  #endif
20934  #define PTE_MASK       PAGE_MASK
20935 @@ -72,7 +73,6 @@ typedef struct { unsigned long pgprot; }
20936  #define pgd_val(x)     ((x).pgd)
20937  #define pgprot_val(x)  ((x).pgprot)
20938  
20939 -#define __pte(x) ((pte_t) { (x) } )
20940  #define __pgd(x) ((pgd_t) { (x) } )
20941  #define __pgprot(x)    ((pgprot_t) { (x) } )
20942  
20943 @@ -119,6 +119,15 @@ extern int page_is_ram(unsigned long pag
20944  #endif
20945  #define __KERNEL_START         (__PAGE_OFFSET + __PHYSICAL_START)
20946  
20947 +#ifdef CONFIG_PAX_KERNEXEC
20948 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + ((__PHYSICAL_START + ~(4*1024*1024)) & (4*1024*1024)))
20949 +#ifndef __ASSEMBLY__
20950 +extern unsigned char MODULES_VADDR[];
20951 +extern unsigned char MODULES_END[];
20952 +#endif
20953 +#else
20954 +#define __KERNEL_TEXT_OFFSET   (0)
20955 +#endif
20956  
20957  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
20958  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
20959 @@ -138,6 +147,19 @@ extern int page_is_ram(unsigned long pag
20960         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
20961                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20962  
20963 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20964 +#ifdef CONFIG_PAX_MPROTECT
20965 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20966 +                         ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
20967 +#else
20968 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
20969 +#endif
20970 +#endif
20971 +
20972 +#ifdef CONFIG_PAX_PAGEEXEC
20973 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
20974 +#endif
20975 +
20976  #include <asm-generic/memory_model.h>
20977  #include <asm-generic/page.h>
20978  
20979 diff -urNp linux-2.6.18/include/asm-i386/pgalloc.h linux-2.6.18/include/asm-i386/pgalloc.h
20980 --- linux-2.6.18/include/asm-i386/pgalloc.h     2006-09-19 23:42:06.000000000 -0400
20981 +++ linux-2.6.18/include/asm-i386/pgalloc.h     2006-09-22 20:45:04.000000000 -0400
20982 @@ -2,11 +2,17 @@
20983  #define _I386_PGALLOC_H
20984  
20985  #include <asm/fixmap.h>
20986 +#include <asm/desc.h>
20987  #include <linux/threads.h>
20988  #include <linux/mm.h>          /* for struct page */
20989  
20990 +#ifdef CONFIG_COMPAT_VDSO
20991  #define pmd_populate_kernel(mm, pmd, pte) \
20992                 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
20993 +#else
20994 +#define pmd_populate_kernel(mm, pmd, pte) \
20995 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
20996 +#endif
20997  
20998  #define pmd_populate(mm, pmd, pte)                             \
20999         set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
21000 diff -urNp linux-2.6.18/include/asm-i386/pgtable.h linux-2.6.18/include/asm-i386/pgtable.h
21001 --- linux-2.6.18/include/asm-i386/pgtable.h     2006-09-19 23:42:06.000000000 -0400
21002 +++ linux-2.6.18/include/asm-i386/pgtable.h     2006-09-22 20:45:04.000000000 -0400
21003 @@ -33,7 +33,6 @@ struct vm_area_struct;
21004   */
21005  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
21006  extern unsigned long empty_zero_page[1024];
21007 -extern pgd_t swapper_pg_dir[1024];
21008  extern kmem_cache_t *pgd_cache;
21009  extern kmem_cache_t *pmd_cache;
21010  extern spinlock_t pgd_lock;
21011 @@ -58,6 +57,11 @@ void paging_init(void);
21012  # include <asm/pgtable-2level-defs.h>
21013  #endif
21014  
21015 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
21016 +#ifdef CONFIG_X86_PAE
21017 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
21018 +#endif
21019 +
21020  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
21021  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
21022  
21023 @@ -67,9 +71,11 @@ void paging_init(void);
21024  #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
21025  #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
21026  
21027 +#ifndef CONFIG_X86_PAE
21028  #define TWOLEVEL_PGDIR_SHIFT   22
21029  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
21030  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
21031 +#endif
21032  
21033  /* Just any arbitrary offset to the start of the vmalloc VM area: the
21034   * current 8MB value just means that there will be a 8MB "hole" after the
21035 @@ -140,17 +146,26 @@ void paging_init(void);
21036  
21037  #define PAGE_SHARED_EXEC \
21038         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
21039 -#define PAGE_COPY_NOEXEC \
21040 -       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21041  #define PAGE_COPY_EXEC \
21042         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
21043 -#define PAGE_COPY \
21044 -       PAGE_COPY_NOEXEC
21045  #define PAGE_READONLY \
21046         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21047  #define PAGE_READONLY_EXEC \
21048         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
21049  
21050 +#ifdef CONFIG_PAX_PAGEEXEC
21051 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
21052 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
21053 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
21054 +#else
21055 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
21056 +# define PAGE_COPY_NOEXEC \
21057 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21058 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
21059 +#endif
21060 +
21061 +#define PAGE_COPY \
21062 +       PAGE_COPY_NOEXEC
21063  #define _PAGE_KERNEL \
21064         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
21065  #define _PAGE_KERNEL_EXEC \
21066 @@ -175,18 +190,18 @@ extern unsigned long long __PAGE_KERNEL,
21067   * This is the closest we can get..
21068   */
21069  #define __P000 PAGE_NONE
21070 -#define __P001 PAGE_READONLY
21071 -#define __P010 PAGE_COPY
21072 -#define __P011 PAGE_COPY
21073 +#define __P001 PAGE_READONLY_NOEXEC
21074 +#define __P010 PAGE_COPY_NOEXEC
21075 +#define __P011 PAGE_COPY_NOEXEC
21076  #define __P100 PAGE_READONLY_EXEC
21077  #define __P101 PAGE_READONLY_EXEC
21078  #define __P110 PAGE_COPY_EXEC
21079  #define __P111 PAGE_COPY_EXEC
21080  
21081  #define __S000 PAGE_NONE
21082 -#define __S001 PAGE_READONLY
21083 -#define __S010 PAGE_SHARED
21084 -#define __S011 PAGE_SHARED
21085 +#define __S001 PAGE_READONLY_NOEXEC
21086 +#define __S010 PAGE_SHARED_NOEXEC
21087 +#define __S011 PAGE_SHARED_NOEXEC
21088  #define __S100 PAGE_READONLY_EXEC
21089  #define __S101 PAGE_READONLY_EXEC
21090  #define __S110 PAGE_SHARED_EXEC
21091 @@ -430,6 +445,9 @@ extern void noexec_setup(const char *str
21092  
21093  #endif /* !__ASSEMBLY__ */
21094  
21095 +#define HAVE_ARCH_UNMAPPED_AREA
21096 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
21097 +
21098  #ifdef CONFIG_FLATMEM
21099  #define kern_addr_valid(addr)  (1)
21100  #endif /* CONFIG_FLATMEM */
21101 diff -urNp linux-2.6.18/include/asm-i386/processor.h linux-2.6.18/include/asm-i386/processor.h
21102 --- linux-2.6.18/include/asm-i386/processor.h   2006-09-19 23:42:06.000000000 -0400
21103 +++ linux-2.6.18/include/asm-i386/processor.h   2006-09-22 20:45:04.000000000 -0400
21104 @@ -18,7 +18,6 @@
21105  #include <asm/system.h>
21106  #include <linux/cache.h>
21107  #include <linux/threads.h>
21108 -#include <asm/percpu.h>
21109  #include <linux/cpumask.h>
21110  
21111  /* flag for disabling the tsc */
21112 @@ -97,8 +96,6 @@ struct cpuinfo_x86 {
21113  
21114  extern struct cpuinfo_x86 boot_cpu_data;
21115  extern struct cpuinfo_x86 new_cpu_data;
21116 -extern struct tss_struct doublefault_tss;
21117 -DECLARE_PER_CPU(struct tss_struct, init_tss);
21118  
21119  #ifdef CONFIG_SMP
21120  extern struct cpuinfo_x86 cpu_data[];
21121 @@ -327,10 +324,19 @@ extern int bootloader_type;
21122   */
21123  #define TASK_SIZE      (PAGE_OFFSET)
21124  
21125 +#ifdef CONFIG_PAX_SEGMEXEC
21126 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
21127 +#endif
21128 +
21129  /* This decides where the kernel will search for a free chunk of vm
21130   * space during mmap's.
21131   */
21132 +
21133 +#ifdef CONFIG_PAX_SEGMEXEC
21134 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
21135 +#else
21136  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
21137 +#endif
21138  
21139  #define HAVE_ARCH_PICK_MMAP_LAYOUT
21140  
21141 @@ -446,6 +452,9 @@ struct tss_struct {
21142  
21143  #define ARCH_MIN_TASKALIGN     16
21144  
21145 +extern struct tss_struct doublefault_tss;
21146 +extern struct tss_struct init_tss[NR_CPUS];
21147 +
21148  struct thread_struct {
21149  /* cached TLS descriptors. */
21150         struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
21151 @@ -474,6 +483,7 @@ struct thread_struct {
21152  };
21153  
21154  #define INIT_THREAD  {                                                 \
21155 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
21156         .vm86_info = NULL,                                              \
21157         .sysenter_cs = __KERNEL_CS,                                     \
21158         .io_bitmap_ptr = NULL,                                          \
21159 @@ -486,7 +496,7 @@ struct thread_struct {
21160   * be within the limit.
21161   */
21162  #define INIT_TSS  {                                                    \
21163 -       .esp0           = sizeof(init_stack) + (long)&init_stack,       \
21164 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
21165         .ss0            = __KERNEL_DS,                                  \
21166         .ss1            = __KERNEL_CS,                                  \
21167         .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,                     \
21168 @@ -562,11 +572,7 @@ void show_trace(struct task_struct *task
21169  unsigned long get_wchan(struct task_struct *p);
21170  
21171  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
21172 -#define KSTK_TOP(info)                                                 \
21173 -({                                                                     \
21174 -       unsigned long *__ptr = (unsigned long *)(info);                 \
21175 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
21176 -})
21177 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
21178  
21179  /*
21180   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
21181 @@ -581,7 +587,7 @@ unsigned long get_wchan(struct task_stru
21182  #define task_pt_regs(task)                                             \
21183  ({                                                                     \
21184         struct pt_regs *__regs__;                                       \
21185 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
21186 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
21187         __regs__ - 1;                                                   \
21188  })
21189  
21190 diff -urNp linux-2.6.18/include/asm-i386/ptrace.h linux-2.6.18/include/asm-i386/ptrace.h
21191 --- linux-2.6.18/include/asm-i386/ptrace.h      2006-09-19 23:42:06.000000000 -0400
21192 +++ linux-2.6.18/include/asm-i386/ptrace.h      2006-09-22 20:45:04.000000000 -0400
21193 @@ -65,17 +65,18 @@ struct task_struct;
21194  extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
21195  
21196  /*
21197 - * user_mode_vm(regs) determines whether a register set came from user mode.
21198 + * user_mode(regs) determines whether a register set came from user mode.
21199   * This is true if V8086 mode was enabled OR if the register set was from
21200   * protected mode with RPL-3 CS value.  This tricky test checks that with
21201   * one comparison.  Many places in the kernel can bypass this full check
21202 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
21203 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
21204 + * be used.
21205   */
21206 -static inline int user_mode(struct pt_regs *regs)
21207 +static inline int user_mode_novm(struct pt_regs *regs)
21208  {
21209         return (regs->xcs & 3) != 0;
21210  }
21211 -static inline int user_mode_vm(struct pt_regs *regs)
21212 +static inline int user_mode(struct pt_regs *regs)
21213  {
21214         return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
21215  }
21216 diff -urNp linux-2.6.18/include/asm-i386/system.h linux-2.6.18/include/asm-i386/system.h
21217 --- linux-2.6.18/include/asm-i386/system.h      2006-09-19 23:42:06.000000000 -0400
21218 +++ linux-2.6.18/include/asm-i386/system.h      2006-09-22 20:45:04.000000000 -0400
21219 @@ -4,6 +4,7 @@
21220  #include <linux/kernel.h>
21221  #include <asm/segment.h>
21222  #include <asm/cpufeature.h>
21223 +#include <asm/page.h>
21224  #include <linux/bitops.h> /* for LOCK_PREFIX */
21225  
21226  #ifdef __KERNEL__
21227 @@ -155,7 +156,7 @@ static inline unsigned long get_limit(un
21228         unsigned long __limit;
21229         __asm__("lsll %1,%0"
21230                 :"=r" (__limit):"r" (segment));
21231 -       return __limit+1;
21232 +       return __limit;
21233  }
21234  
21235  #define nop() __asm__ __volatile__ ("nop")
21236 @@ -480,7 +481,7 @@ static inline void sched_cacheflush(void
21237         wbinvd();
21238  }
21239  
21240 -extern unsigned long arch_align_stack(unsigned long sp);
21241 +#define arch_align_stack(x) (x)
21242  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
21243  
21244  void default_idle(void);
21245 diff -urNp linux-2.6.18/include/asm-i386/uaccess.h linux-2.6.18/include/asm-i386/uaccess.h
21246 --- linux-2.6.18/include/asm-i386/uaccess.h     2006-09-19 23:42:06.000000000 -0400
21247 +++ linux-2.6.18/include/asm-i386/uaccess.h     2006-09-22 20:45:04.000000000 -0400
21248 @@ -9,6 +9,8 @@
21249  #include <linux/prefetch.h>
21250  #include <linux/string.h>
21251  #include <asm/page.h>
21252 +#include <asm/segment.h>
21253 +#include <asm/desc.h>
21254  
21255  #define VERIFY_READ 0
21256  #define VERIFY_WRITE 1
21257 @@ -29,7 +31,8 @@
21258  
21259  #define get_ds()       (KERNEL_DS)
21260  #define get_fs()       (current_thread_info()->addr_limit)
21261 -#define set_fs(x)      (current_thread_info()->addr_limit = (x))
21262 +void __set_fs(mm_segment_t x, int cpu);
21263 +void set_fs(mm_segment_t x);
21264  
21265  #define segment_eq(a,b)        ((a).seg == (b).seg)
21266  
21267 @@ -280,9 +283,12 @@ extern void __put_user_8(void);
21268  
21269  #define __put_user_u64(x, addr, err)                           \
21270         __asm__ __volatile__(                                   \
21271 -               "1:     movl %%eax,0(%2)\n"                     \
21272 -               "2:     movl %%edx,4(%2)\n"                     \
21273 +               "       movw %w5,%%ds\n"                        \
21274 +               "1:     movl %%eax,%%ds:0(%2)\n"                \
21275 +               "2:     movl %%edx,%%ds:4(%2)\n"                \
21276                 "3:\n"                                          \
21277 +               "       pushl %%ss\n"                           \
21278 +               "       popl %%ds\n"                            \
21279                 ".section .fixup,\"ax\"\n"                      \
21280                 "4:     movl %3,%0\n"                           \
21281                 "       jmp 3b\n"                               \
21282 @@ -293,7 +299,8 @@ extern void __put_user_8(void);
21283                 "       .long 2b,4b\n"                          \
21284                 ".previous"                                     \
21285                 : "=r"(err)                                     \
21286 -               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
21287 +               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err),  \
21288 +                 "r"(__USER_DS))
21289  
21290  #ifdef CONFIG_X86_WP_WORKS_OK
21291  
21292 @@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
21293   */
21294  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
21295         __asm__ __volatile__(                                           \
21296 -               "1:     mov"itype" %"rtype"1,%2\n"                      \
21297 +               "       movw %w5,%%ds\n"                                \
21298 +               "1:     mov"itype" %"rtype"1,%%ds:%2\n"                 \
21299                 "2:\n"                                                  \
21300 +               "       pushl %%ss\n"                                   \
21301 +               "       popl %%ds\n"                                    \
21302                 ".section .fixup,\"ax\"\n"                              \
21303                 "3:     movl %3,%0\n"                                   \
21304                 "       jmp 2b\n"                                       \
21305 @@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
21306                 "       .long 1b,3b\n"                                  \
21307                 ".previous"                                             \
21308                 : "=r"(err)                                             \
21309 -               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
21310 +               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err),     \
21311 +                 "r"(__USER_DS))
21312  
21313  
21314  #define __get_user_nocheck(x,ptr,size)                         \
21315 @@ -371,8 +382,11 @@ do {                                                                       \
21316  
21317  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
21318         __asm__ __volatile__(                                           \
21319 -               "1:     mov"itype" %2,%"rtype"1\n"                      \
21320 +               "       movw %w5,%%ds\n"                                \
21321 +               "1:     mov"itype" %%ds:%2,%"rtype"1\n"                 \
21322                 "2:\n"                                                  \
21323 +               "       pushl %%ss\n"                                   \
21324 +               "       popl %%ds\n"                                    \
21325                 ".section .fixup,\"ax\"\n"                              \
21326                 "3:     movl %3,%0\n"                                   \
21327                 "       xor"itype" %"rtype"1,%"rtype"1\n"               \
21328 @@ -383,7 +397,7 @@ do {                                                                        \
21329                 "       .long 1b,3b\n"                                  \
21330                 ".previous"                                             \
21331                 : "=r"(err), ltype (x)                                  \
21332 -               : "m"(__m(addr)), "i"(errret), "0"(err))
21333 +               : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
21334  
21335  
21336  unsigned long __must_check __copy_to_user_ll(void __user *to,
21337 diff -urNp linux-2.6.18/include/asm-i386/unwind.h linux-2.6.18/include/asm-i386/unwind.h
21338 --- linux-2.6.18/include/asm-i386/unwind.h      2006-09-19 23:42:06.000000000 -0400
21339 +++ linux-2.6.18/include/asm-i386/unwind.h      2006-09-22 20:45:04.000000000 -0400
21340 @@ -45,7 +45,7 @@ struct unwind_frame_info
21341  static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
21342                                              /*const*/ struct pt_regs *regs)
21343  {
21344 -       if (user_mode_vm(regs))
21345 +       if (user_mode(regs))
21346                 info->regs = *regs;
21347         else {
21348                 memcpy(&info->regs, regs, offsetof(struct pt_regs, esp));
21349 @@ -62,8 +62,8 @@ static inline void arch_unw_init_blocked
21350         __get_user(info->regs.ebp, (long *)info->task->thread.esp);
21351         info->regs.esp = info->task->thread.esp;
21352         info->regs.xss = __KERNEL_DS;
21353 -       info->regs.xds = __USER_DS;
21354 -       info->regs.xes = __USER_DS;
21355 +       info->regs.xds = __KERNEL_DS;
21356 +       info->regs.xes = __KERNEL_DS;
21357  }
21358  
21359  extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,
21360 @@ -75,9 +75,9 @@ static inline int arch_unw_user_mode(con
21361  {
21362  #if 0 /* This can only work when selector register and EFLAGS saves/restores
21363           are properly annotated (and tracked in UNW_REGISTER_INFO). */
21364 -       return user_mode_vm(&info->regs);
21365 +       return user_mode(&info->regs);
21366  #else
21367 -       return info->regs.eip < PAGE_OFFSET
21368 +       return (info->regs.eip < PAGE_OFFSET && (info->regs.xcs & 0xFFFF) != __KERNEL_CS)
21369                || (info->regs.eip >= __fix_to_virt(FIX_VDSO)
21370                     && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE)
21371                || info->regs.esp < PAGE_OFFSET;
21372 diff -urNp linux-2.6.18/include/asm-ia64/elf.h linux-2.6.18/include/asm-ia64/elf.h
21373 --- linux-2.6.18/include/asm-ia64/elf.h 2006-09-19 23:42:06.000000000 -0400
21374 +++ linux-2.6.18/include/asm-ia64/elf.h 2006-09-22 20:45:04.000000000 -0400
21375 @@ -162,6 +162,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
21376  typedef struct ia64_fpreg elf_fpreg_t;
21377  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
21378  
21379 +#ifdef CONFIG_PAX_ASLR
21380 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
21381 +
21382 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
21383 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
21384 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
21385 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
21386 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
21387 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
21388 +#endif
21389  
21390  
21391  struct pt_regs;        /* forward declaration... */
21392 diff -urNp linux-2.6.18/include/asm-ia64/kmap_types.h linux-2.6.18/include/asm-ia64/kmap_types.h
21393 --- linux-2.6.18/include/asm-ia64/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
21394 +++ linux-2.6.18/include/asm-ia64/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
21395 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
21396  D(10)  KM_IRQ1,
21397  D(11)  KM_SOFTIRQ0,
21398  D(12)  KM_SOFTIRQ1,
21399 -D(13)  KM_TYPE_NR
21400 +D(13)  KM_CLEARPAGE,
21401 +D(14)  KM_TYPE_NR
21402  };
21403  
21404  #undef D
21405 diff -urNp linux-2.6.18/include/asm-ia64/page.h linux-2.6.18/include/asm-ia64/page.h
21406 --- linux-2.6.18/include/asm-ia64/page.h        2006-09-19 23:42:06.000000000 -0400
21407 +++ linux-2.6.18/include/asm-ia64/page.h        2006-09-22 20:45:04.000000000 -0400
21408 @@ -227,5 +227,14 @@ get_order (unsigned long size)
21409                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
21410                                           ? VM_EXEC : 0))
21411  
21412 +#ifdef CONFIG_PAX_PAGEEXEC
21413 +#ifdef CONFIG_PAX_MPROTECT
21414 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21415 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21416 +#else
21417 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21418 +#endif
21419 +#endif
21420 +
21421  # endif /* __KERNEL__ */
21422  #endif /* _ASM_IA64_PAGE_H */
21423 diff -urNp linux-2.6.18/include/asm-ia64/pgtable.h linux-2.6.18/include/asm-ia64/pgtable.h
21424 --- linux-2.6.18/include/asm-ia64/pgtable.h     2006-09-19 23:42:06.000000000 -0400
21425 +++ linux-2.6.18/include/asm-ia64/pgtable.h     2006-09-22 20:45:04.000000000 -0400
21426 @@ -143,6 +143,17 @@
21427  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
21428  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
21429  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
21430 +
21431 +#ifdef CONFIG_PAX_PAGEEXEC
21432 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
21433 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
21434 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
21435 +#else
21436 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
21437 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
21438 +# define PAGE_COPY_NOEXEC      PAGE_COPY
21439 +#endif
21440 +
21441  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
21442  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
21443  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
21444 diff -urNp linux-2.6.18/include/asm-ia64/processor.h linux-2.6.18/include/asm-ia64/processor.h
21445 --- linux-2.6.18/include/asm-ia64/processor.h   2006-09-19 23:42:06.000000000 -0400
21446 +++ linux-2.6.18/include/asm-ia64/processor.h   2006-09-22 20:45:04.000000000 -0400
21447 @@ -283,7 +283,7 @@ struct thread_struct {
21448         .on_ustack =    0,                                      \
21449         .ksp =          0,                                      \
21450         .map_base =     DEFAULT_MAP_BASE,                       \
21451 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
21452 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
21453         .task_size =    DEFAULT_TASK_SIZE,                      \
21454         .last_fph_cpu =  -1,                                    \
21455         INIT_THREAD_IA32                                        \
21456 diff -urNp linux-2.6.18/include/asm-ia64/ustack.h linux-2.6.18/include/asm-ia64/ustack.h
21457 --- linux-2.6.18/include/asm-ia64/ustack.h      2006-09-19 23:42:06.000000000 -0400
21458 +++ linux-2.6.18/include/asm-ia64/ustack.h      2006-09-22 20:45:04.000000000 -0400
21459 @@ -10,10 +10,10 @@
21460  
21461  /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
21462  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
21463 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
21464 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
21465  #endif
21466  
21467 -/* Make a default stack size of 2GiB */
21468 +/* Make a default stack size of 2GB */
21469  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
21470  
21471  #endif /* _ASM_IA64_USTACK_H */
21472 diff -urNp linux-2.6.18/include/asm-m32r/kmap_types.h linux-2.6.18/include/asm-m32r/kmap_types.h
21473 --- linux-2.6.18/include/asm-m32r/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
21474 +++ linux-2.6.18/include/asm-m32r/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
21475 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
21476  D(10)  KM_IRQ1,
21477  D(11)  KM_SOFTIRQ0,
21478  D(12)  KM_SOFTIRQ1,
21479 -D(13)  KM_TYPE_NR
21480 +D(13)  KM_CLEARPAGE,
21481 +D(14)  KM_TYPE_NR
21482  };
21483  
21484  #undef D
21485 diff -urNp linux-2.6.18/include/asm-m68k/kmap_types.h linux-2.6.18/include/asm-m68k/kmap_types.h
21486 --- linux-2.6.18/include/asm-m68k/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
21487 +++ linux-2.6.18/include/asm-m68k/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
21488 @@ -15,6 +15,7 @@ enum km_type {
21489         KM_IRQ1,
21490         KM_SOFTIRQ0,
21491         KM_SOFTIRQ1,
21492 +       KM_CLEARPAGE,
21493         KM_TYPE_NR
21494  };
21495  
21496 diff -urNp linux-2.6.18/include/asm-m68knommu/kmap_types.h linux-2.6.18/include/asm-m68knommu/kmap_types.h
21497 --- linux-2.6.18/include/asm-m68knommu/kmap_types.h     2006-09-19 23:42:06.000000000 -0400
21498 +++ linux-2.6.18/include/asm-m68knommu/kmap_types.h     2006-09-22 20:45:04.000000000 -0400
21499 @@ -15,6 +15,7 @@ enum km_type {
21500         KM_IRQ1,
21501         KM_SOFTIRQ0,
21502         KM_SOFTIRQ1,
21503 +       KM_CLEARPAGE,
21504         KM_TYPE_NR
21505  };
21506  
21507 diff -urNp linux-2.6.18/include/asm-mips/a.out.h linux-2.6.18/include/asm-mips/a.out.h
21508 --- linux-2.6.18/include/asm-mips/a.out.h       2006-09-19 23:42:06.000000000 -0400
21509 +++ linux-2.6.18/include/asm-mips/a.out.h       2006-09-22 20:45:04.000000000 -0400
21510 @@ -35,10 +35,10 @@ struct exec
21511  #ifdef __KERNEL__
21512  
21513  #ifdef CONFIG_32BIT
21514 -#define STACK_TOP      TASK_SIZE
21515 +#define __STACK_TOP    TASK_SIZE
21516  #endif
21517  #ifdef CONFIG_64BIT
21518 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
21519 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
21520  #endif
21521  
21522  #endif
21523 diff -urNp linux-2.6.18/include/asm-mips/elf.h linux-2.6.18/include/asm-mips/elf.h
21524 --- linux-2.6.18/include/asm-mips/elf.h 2006-09-19 23:42:06.000000000 -0400
21525 +++ linux-2.6.18/include/asm-mips/elf.h 2006-09-22 20:45:04.000000000 -0400
21526 @@ -371,4 +371,15 @@ extern int dump_task_fpu(struct task_str
21527  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
21528  #endif
21529  
21530 +#ifdef CONFIG_PAX_ASLR
21531 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
21532 +
21533 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
21534 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
21535 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
21536 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
21537 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
21538 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
21539 +#endif
21540 +
21541  #endif /* _ASM_ELF_H */
21542 diff -urNp linux-2.6.18/include/asm-mips/kmap_types.h linux-2.6.18/include/asm-mips/kmap_types.h
21543 --- linux-2.6.18/include/asm-mips/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
21544 +++ linux-2.6.18/include/asm-mips/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
21545 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
21546  D(10)  KM_IRQ1,
21547  D(11)  KM_SOFTIRQ0,
21548  D(12)  KM_SOFTIRQ1,
21549 -D(13)  KM_TYPE_NR
21550 +D(13)  KM_CLEARPAGE,
21551 +D(14)  KM_TYPE_NR
21552  };
21553  
21554  #undef D
21555 diff -urNp linux-2.6.18/include/asm-mips/page.h linux-2.6.18/include/asm-mips/page.h
21556 --- linux-2.6.18/include/asm-mips/page.h        2006-09-19 23:42:06.000000000 -0400
21557 +++ linux-2.6.18/include/asm-mips/page.h        2006-09-22 20:45:04.000000000 -0400
21558 @@ -74,15 +74,17 @@ static inline void copy_user_page(void *
21559    #ifdef CONFIG_CPU_MIPS32
21560      typedef struct { unsigned long pte_low, pte_high; } pte_t;
21561      #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
21562 +    #define __pte(x)   ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
21563    #else
21564       typedef struct { unsigned long long pte; } pte_t;
21565       #define pte_val(x)        ((x).pte)
21566 +     #define __pte(x)  ((pte_t) { (x) } )
21567    #endif
21568  #else
21569  typedef struct { unsigned long pte; } pte_t;
21570  #define pte_val(x)     ((x).pte)
21571 -#endif
21572  #define __pte(x)       ((pte_t) { (x) } )
21573 +#endif
21574  
21575  /*
21576   * For 3-level pagetables we defines these ourselves, for 2-level the
21577 @@ -161,6 +163,15 @@ typedef struct { unsigned long pgprot; }
21578  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
21579                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21580  
21581 +#ifdef CONFIG_PAX_PAGEEXEC
21582 +#ifdef CONFIG_PAX_MPROTECT
21583 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21584 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21585 +#else
21586 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21587 +#endif
21588 +#endif
21589 +
21590  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
21591  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
21592  
21593 diff -urNp linux-2.6.18/include/asm-parisc/a.out.h linux-2.6.18/include/asm-parisc/a.out.h
21594 --- linux-2.6.18/include/asm-parisc/a.out.h     2006-09-19 23:42:06.000000000 -0400
21595 +++ linux-2.6.18/include/asm-parisc/a.out.h     2006-09-22 20:45:04.000000000 -0400
21596 @@ -22,7 +22,7 @@ struct exec
21597  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
21598   * prumpf */
21599  
21600 -#define STACK_TOP      TASK_SIZE
21601 +#define __STACK_TOP    TASK_SIZE
21602  
21603  #endif
21604  
21605 diff -urNp linux-2.6.18/include/asm-parisc/elf.h linux-2.6.18/include/asm-parisc/elf.h
21606 --- linux-2.6.18/include/asm-parisc/elf.h       2006-09-19 23:42:06.000000000 -0400
21607 +++ linux-2.6.18/include/asm-parisc/elf.h       2006-09-22 20:45:04.000000000 -0400
21608 @@ -337,6 +337,17 @@ struct pt_regs;    /* forward declaration..
21609  
21610  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
21611  
21612 +#ifdef CONFIG_PAX_ASLR
21613 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
21614 +
21615 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
21616 +#define PAX_DELTA_MMAP_LEN(tsk)                16
21617 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
21618 +#define PAX_DELTA_EXEC_LEN(tsk)                16
21619 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
21620 +#define PAX_DELTA_STACK_LEN(tsk)       16
21621 +#endif
21622 +
21623  /* This yields a mask that user programs can use to figure out what
21624     instruction set this CPU supports.  This could be done in user space,
21625     but it's not easy, and we've already done it here.  */
21626 diff -urNp linux-2.6.18/include/asm-parisc/kmap_types.h linux-2.6.18/include/asm-parisc/kmap_types.h
21627 --- linux-2.6.18/include/asm-parisc/kmap_types.h        2006-09-19 23:42:06.000000000 -0400
21628 +++ linux-2.6.18/include/asm-parisc/kmap_types.h        2006-09-22 20:45:04.000000000 -0400
21629 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
21630  D(10)  KM_IRQ1,
21631  D(11)  KM_SOFTIRQ0,
21632  D(12)  KM_SOFTIRQ1,
21633 -D(13)  KM_TYPE_NR
21634 +D(13)  KM_CLEARPAGE,
21635 +D(14)  KM_TYPE_NR
21636  };
21637  
21638  #undef D
21639 diff -urNp linux-2.6.18/include/asm-parisc/page.h linux-2.6.18/include/asm-parisc/page.h
21640 --- linux-2.6.18/include/asm-parisc/page.h      2006-09-19 23:42:06.000000000 -0400
21641 +++ linux-2.6.18/include/asm-parisc/page.h      2006-09-22 20:45:04.000000000 -0400
21642 @@ -180,6 +180,15 @@ extern int npmem_ranges;
21643  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
21644                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21645  
21646 +#ifdef CONFIG_PAX_PAGEEXEC
21647 +#ifdef CONFIG_PAX_MPROTECT
21648 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21649 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21650 +#else
21651 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21652 +#endif
21653 +#endif
21654 +
21655  #include <asm-generic/memory_model.h>
21656  #include <asm-generic/page.h>
21657  
21658 diff -urNp linux-2.6.18/include/asm-parisc/pgtable.h linux-2.6.18/include/asm-parisc/pgtable.h
21659 --- linux-2.6.18/include/asm-parisc/pgtable.h   2006-09-19 23:42:06.000000000 -0400
21660 +++ linux-2.6.18/include/asm-parisc/pgtable.h   2006-09-22 20:45:04.000000000 -0400
21661 @@ -219,6 +219,17 @@ extern  void *vmalloc_start;
21662  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
21663  #define PAGE_COPY       PAGE_EXECREAD
21664  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
21665 +
21666 +#ifdef CONFIG_PAX_PAGEEXEC
21667 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
21668 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
21669 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
21670 +#else
21671 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
21672 +# define PAGE_COPY_NOEXEC      PAGE_COPY
21673 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
21674 +#endif
21675 +
21676  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
21677  #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
21678  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
21679 diff -urNp linux-2.6.18/include/asm-powerpc/a.out.h linux-2.6.18/include/asm-powerpc/a.out.h
21680 --- linux-2.6.18/include/asm-powerpc/a.out.h    2006-09-19 23:42:06.000000000 -0400
21681 +++ linux-2.6.18/include/asm-powerpc/a.out.h    2006-09-22 20:45:04.000000000 -0400
21682 @@ -23,12 +23,12 @@ struct exec
21683  #define STACK_TOP_USER64 TASK_SIZE_USER64
21684  #define STACK_TOP_USER32 TASK_SIZE_USER32
21685  
21686 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
21687 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
21688                    STACK_TOP_USER32 : STACK_TOP_USER64)
21689  
21690  #else /* __powerpc64__ */
21691  
21692 -#define STACK_TOP TASK_SIZE
21693 +#define __STACK_TOP TASK_SIZE
21694  
21695  #endif /* __powerpc64__ */
21696  #endif /* __KERNEL__ */
21697 diff -urNp linux-2.6.18/include/asm-powerpc/elf.h linux-2.6.18/include/asm-powerpc/elf.h
21698 --- linux-2.6.18/include/asm-powerpc/elf.h      2006-09-19 23:42:06.000000000 -0400
21699 +++ linux-2.6.18/include/asm-powerpc/elf.h      2006-09-22 20:45:04.000000000 -0400
21700 @@ -161,6 +161,26 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
21701  typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
21702  #endif
21703  
21704 +#ifdef CONFIG_PAX_ASLR
21705 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
21706 +
21707 +#ifdef __powerpc64__
21708 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
21709 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
21710 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
21711 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
21712 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
21713 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 16 : 28)
21714 +#else
21715 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
21716 +#define PAX_DELTA_MMAP_LEN(tsk)                15
21717 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
21718 +#define PAX_DELTA_EXEC_LEN(tsk)                15
21719 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
21720 +#define PAX_DELTA_STACK_LEN(tsk)       15
21721 +#endif
21722 +#endif
21723 +
21724  #ifdef __KERNEL__
21725  /*
21726   * This is used to ensure we don't load something for the wrong architecture.
21727 diff -urNp linux-2.6.18/include/asm-powerpc/kmap_types.h linux-2.6.18/include/asm-powerpc/kmap_types.h
21728 --- linux-2.6.18/include/asm-powerpc/kmap_types.h       2006-09-19 23:42:06.000000000 -0400
21729 +++ linux-2.6.18/include/asm-powerpc/kmap_types.h       2006-09-22 20:45:04.000000000 -0400
21730 @@ -26,6 +26,7 @@ enum km_type {
21731         KM_SOFTIRQ1,
21732         KM_PPC_SYNC_PAGE,
21733         KM_PPC_SYNC_ICACHE,
21734 +       KM_CLEARPAGE,
21735         KM_TYPE_NR
21736  };
21737  
21738 diff -urNp linux-2.6.18/include/asm-powerpc/page_64.h linux-2.6.18/include/asm-powerpc/page_64.h
21739 --- linux-2.6.18/include/asm-powerpc/page_64.h  2006-09-19 23:42:06.000000000 -0400
21740 +++ linux-2.6.18/include/asm-powerpc/page_64.h  2006-09-22 20:45:04.000000000 -0400
21741 @@ -160,15 +160,18 @@ extern unsigned int HPAGE_SHIFT;
21742   * stack by default, so in the absense of a PT_GNU_STACK program header
21743   * we turn execute permission off.
21744   */
21745 -#define VM_STACK_DEFAULT_FLAGS32       (VM_READ | VM_WRITE | VM_EXEC | \
21746 -                                        VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21747 +#define VM_STACK_DEFAULT_FLAGS32 \
21748 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
21749 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21750  
21751  #define VM_STACK_DEFAULT_FLAGS64       (VM_READ | VM_WRITE | \
21752                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21753  
21754 +#ifndef CONFIG_PAX_PAGEEXEC
21755  #define VM_STACK_DEFAULT_FLAGS \
21756         (test_thread_flag(TIF_32BIT) ? \
21757          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
21758 +#endif
21759  
21760  #include <asm-generic/page.h>
21761  
21762 diff -urNp linux-2.6.18/include/asm-powerpc/page.h linux-2.6.18/include/asm-powerpc/page.h
21763 --- linux-2.6.18/include/asm-powerpc/page.h     2006-09-19 23:42:06.000000000 -0400
21764 +++ linux-2.6.18/include/asm-powerpc/page.h     2006-09-22 20:45:04.000000000 -0400
21765 @@ -77,8 +77,9 @@
21766   * and needs to be executable.  This means the whole heap ends
21767   * up being executable.
21768   */
21769 -#define VM_DATA_DEFAULT_FLAGS32        (VM_READ | VM_WRITE | VM_EXEC | \
21770 -                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21771 +#define VM_DATA_DEFAULT_FLAGS32 \
21772 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
21773 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21774  
21775  #define VM_DATA_DEFAULT_FLAGS64        (VM_READ | VM_WRITE | \
21776                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21777 @@ -89,6 +90,15 @@
21778  #include <asm/page_32.h>
21779  #endif
21780  
21781 +#ifdef CONFIG_PAX_PAGEEXEC
21782 +#ifdef CONFIG_PAX_MPROTECT
21783 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21784 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21785 +#else
21786 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21787 +#endif
21788 +#endif
21789 +
21790  /* align addr on a size boundary - adjust address up/down if needed */
21791  #define _ALIGN_UP(addr,size)   (((addr)+((size)-1))&(~((size)-1)))
21792  #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
21793 diff -urNp linux-2.6.18/include/asm-ppc/page.h linux-2.6.18/include/asm-ppc/page.h
21794 --- linux-2.6.18/include/asm-ppc/page.h 2006-09-19 23:42:06.000000000 -0400
21795 +++ linux-2.6.18/include/asm-ppc/page.h 2006-09-22 20:45:04.000000000 -0400
21796 @@ -173,6 +173,15 @@ extern __inline__ int get_order(unsigned
21797  /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
21798  #define __HAVE_ARCH_GATE_AREA          1
21799  
21800 +#ifdef CONFIG_PAX_PAGEEXEC
21801 +#ifdef CONFIG_PAX_MPROTECT
21802 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21803 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21804 +#else
21805 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21806 +#endif
21807 +#endif
21808 +
21809  #include <asm-generic/memory_model.h>
21810  #endif /* __KERNEL__ */
21811  #endif /* _PPC_PAGE_H */
21812 diff -urNp linux-2.6.18/include/asm-ppc/pgtable.h linux-2.6.18/include/asm-ppc/pgtable.h
21813 --- linux-2.6.18/include/asm-ppc/pgtable.h      2006-09-19 23:42:06.000000000 -0400
21814 +++ linux-2.6.18/include/asm-ppc/pgtable.h      2006-09-22 20:45:04.000000000 -0400
21815 @@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
21816  
21817  #define PAGE_NONE      __pgprot(_PAGE_BASE)
21818  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
21819 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
21820 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
21821  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
21822 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
21823 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
21824  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
21825 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
21826 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
21827 +
21828 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
21829 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
21830 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
21831 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
21832 +#else
21833 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
21834 +# define PAGE_COPY_NOEXEC      PAGE_COPY
21835 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
21836 +#endif
21837  
21838  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
21839  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
21840 @@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
21841   * This is the closest we can get..
21842   */
21843  #define __P000 PAGE_NONE
21844 -#define __P001 PAGE_READONLY_X
21845 -#define __P010 PAGE_COPY
21846 -#define __P011 PAGE_COPY_X
21847 -#define __P100 PAGE_READONLY
21848 +#define __P001 PAGE_READONLY_NOEXEC
21849 +#define __P010 PAGE_COPY_NOEXEC
21850 +#define __P011 PAGE_COPY_NOEXEC
21851 +#define __P100 PAGE_READONLY_X
21852  #define __P101 PAGE_READONLY_X
21853 -#define __P110 PAGE_COPY
21854 +#define __P110 PAGE_COPY_X
21855  #define __P111 PAGE_COPY_X
21856  
21857  #define __S000 PAGE_NONE
21858 -#define __S001 PAGE_READONLY_X
21859 -#define __S010 PAGE_SHARED
21860 -#define __S011 PAGE_SHARED_X
21861 -#define __S100 PAGE_READONLY
21862 +#define __S001 PAGE_READONLY_NOEXEC
21863 +#define __S010 PAGE_SHARED_NOEXEC
21864 +#define __S011 PAGE_SHARED_NOEXEC
21865 +#define __S100 PAGE_READONLY_X
21866  #define __S101 PAGE_READONLY_X
21867 -#define __S110 PAGE_SHARED
21868 +#define __S110 PAGE_SHARED_X
21869  #define __S111 PAGE_SHARED_X
21870  
21871  #ifndef __ASSEMBLY__
21872 diff -urNp linux-2.6.18/include/asm-s390/kmap_types.h linux-2.6.18/include/asm-s390/kmap_types.h
21873 --- linux-2.6.18/include/asm-s390/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
21874 +++ linux-2.6.18/include/asm-s390/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
21875 @@ -16,6 +16,7 @@ enum km_type {
21876         KM_IRQ1,
21877         KM_SOFTIRQ0,
21878         KM_SOFTIRQ1,    
21879 +       KM_CLEARPAGE,
21880         KM_TYPE_NR
21881  };
21882  
21883 diff -urNp linux-2.6.18/include/asm-sh/kmap_types.h linux-2.6.18/include/asm-sh/kmap_types.h
21884 --- linux-2.6.18/include/asm-sh/kmap_types.h    2006-09-19 23:42:06.000000000 -0400
21885 +++ linux-2.6.18/include/asm-sh/kmap_types.h    2006-09-22 20:45:04.000000000 -0400
21886 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
21887  D(10)  KM_IRQ1,
21888  D(11)  KM_SOFTIRQ0,
21889  D(12)  KM_SOFTIRQ1,
21890 -D(13)  KM_TYPE_NR
21891 +D(13)  KM_CLEARPAGE,
21892 +D(14)  KM_TYPE_NR
21893  };
21894  
21895  #undef D
21896 diff -urNp linux-2.6.18/include/asm-sparc/a.out.h linux-2.6.18/include/asm-sparc/a.out.h
21897 --- linux-2.6.18/include/asm-sparc/a.out.h      2006-09-19 23:42:06.000000000 -0400
21898 +++ linux-2.6.18/include/asm-sparc/a.out.h      2006-09-22 20:45:04.000000000 -0400
21899 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
21900  
21901  #include <asm/page.h>
21902  
21903 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
21904 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
21905  
21906  #endif /* __KERNEL__ */
21907  
21908 diff -urNp linux-2.6.18/include/asm-sparc/elf.h linux-2.6.18/include/asm-sparc/elf.h
21909 --- linux-2.6.18/include/asm-sparc/elf.h        2006-09-19 23:42:06.000000000 -0400
21910 +++ linux-2.6.18/include/asm-sparc/elf.h        2006-09-22 20:45:04.000000000 -0400
21911 @@ -144,6 +144,17 @@ typedef struct {
21912  
21913  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
21914  
21915 +#ifdef CONFIG_PAX_ASLR
21916 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
21917 +
21918 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
21919 +#define PAX_DELTA_MMAP_LEN(tsk)                16
21920 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
21921 +#define PAX_DELTA_EXEC_LEN(tsk)                16
21922 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
21923 +#define PAX_DELTA_STACK_LEN(tsk)       16
21924 +#endif
21925 +
21926  /* This yields a mask that user programs can use to figure out what
21927     instruction set this cpu supports.  This can NOT be done in userspace
21928     on Sparc.  */
21929 diff -urNp linux-2.6.18/include/asm-sparc/kmap_types.h linux-2.6.18/include/asm-sparc/kmap_types.h
21930 --- linux-2.6.18/include/asm-sparc/kmap_types.h 2006-09-19 23:42:06.000000000 -0400
21931 +++ linux-2.6.18/include/asm-sparc/kmap_types.h 2006-09-22 20:45:04.000000000 -0400
21932 @@ -15,6 +15,7 @@ enum km_type {
21933         KM_IRQ1,
21934         KM_SOFTIRQ0,
21935         KM_SOFTIRQ1,
21936 +       KM_CLEARPAGE,
21937         KM_TYPE_NR
21938  };
21939  
21940 diff -urNp linux-2.6.18/include/asm-sparc/page.h linux-2.6.18/include/asm-sparc/page.h
21941 --- linux-2.6.18/include/asm-sparc/page.h       2006-09-19 23:42:06.000000000 -0400
21942 +++ linux-2.6.18/include/asm-sparc/page.h       2006-09-22 20:45:04.000000000 -0400
21943 @@ -160,6 +160,15 @@ extern unsigned long pfn_base;
21944  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
21945                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21946  
21947 +#ifdef CONFIG_PAX_PAGEEXEC
21948 +#ifdef CONFIG_PAX_MPROTECT
21949 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21950 +                        ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21951 +#else
21952 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21953 +#endif
21954 +#endif
21955 +
21956  #endif /* __KERNEL__ */
21957  
21958  #include <asm-generic/memory_model.h>
21959 diff -urNp linux-2.6.18/include/asm-sparc/pgtable.h linux-2.6.18/include/asm-sparc/pgtable.h
21960 --- linux-2.6.18/include/asm-sparc/pgtable.h    2006-09-19 23:42:06.000000000 -0400
21961 +++ linux-2.6.18/include/asm-sparc/pgtable.h    2006-09-22 20:45:04.000000000 -0400
21962 @@ -49,6 +49,13 @@ BTFIXUPDEF_INT(page_none)
21963  BTFIXUPDEF_INT(page_shared)
21964  BTFIXUPDEF_INT(page_copy)
21965  BTFIXUPDEF_INT(page_readonly)
21966 +
21967 +#ifdef CONFIG_PAX_PAGEEXEC
21968 +BTFIXUPDEF_INT(page_shared_noexec)
21969 +BTFIXUPDEF_INT(page_copy_noexec)
21970 +BTFIXUPDEF_INT(page_readonly_noexec)
21971 +#endif
21972 +
21973  BTFIXUPDEF_INT(page_kernel)
21974  
21975  #define PMD_SHIFT              SUN4C_PMD_SHIFT
21976 @@ -70,6 +77,16 @@ BTFIXUPDEF_INT(page_kernel)
21977  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
21978  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
21979  
21980 +#ifdef CONFIG_PAX_PAGEEXEC
21981 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
21982 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
21983 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
21984 +#else
21985 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
21986 +# define PAGE_COPY_NOEXEC      PAGE_COPY
21987 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
21988 +#endif
21989 +
21990  extern unsigned long page_kernel;
21991  
21992  #ifdef MODULE
21993 diff -urNp linux-2.6.18/include/asm-sparc/pgtsrmmu.h linux-2.6.18/include/asm-sparc/pgtsrmmu.h
21994 --- linux-2.6.18/include/asm-sparc/pgtsrmmu.h   2006-09-19 23:42:06.000000000 -0400
21995 +++ linux-2.6.18/include/asm-sparc/pgtsrmmu.h   2006-09-22 20:45:04.000000000 -0400
21996 @@ -115,6 +115,16 @@
21997                                     SRMMU_EXEC | SRMMU_REF)
21998  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
21999                                     SRMMU_EXEC | SRMMU_REF)
22000 +
22001 +#ifdef CONFIG_PAX_PAGEEXEC
22002 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22003 +                                          SRMMU_WRITE | SRMMU_REF)
22004 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22005 +                                          SRMMU_REF)
22006 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22007 +                                          SRMMU_REF)
22008 +#endif
22009 +
22010  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
22011                                     SRMMU_DIRTY | SRMMU_REF)
22012  
22013 diff -urNp linux-2.6.18/include/asm-sparc/uaccess.h linux-2.6.18/include/asm-sparc/uaccess.h
22014 --- linux-2.6.18/include/asm-sparc/uaccess.h    2006-09-19 23:42:06.000000000 -0400
22015 +++ linux-2.6.18/include/asm-sparc/uaccess.h    2006-09-22 20:45:04.000000000 -0400
22016 @@ -41,7 +41,7 @@
22017   * No one can read/write anything from userland in the kernel space by setting
22018   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
22019   */
22020 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
22021 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
22022  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
22023  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
22024  #define access_ok(type, addr, size)                                    \
22025 diff -urNp linux-2.6.18/include/asm-sparc64/a.out.h linux-2.6.18/include/asm-sparc64/a.out.h
22026 --- linux-2.6.18/include/asm-sparc64/a.out.h    2006-09-19 23:42:06.000000000 -0400
22027 +++ linux-2.6.18/include/asm-sparc64/a.out.h    2006-09-22 20:45:04.000000000 -0400
22028 @@ -98,7 +98,7 @@ struct relocation_info /* used when head
22029  #define STACK_TOP32    ((1UL << 32UL) - PAGE_SIZE)
22030  #define STACK_TOP64    (0x0000080000000000UL - (1UL << 32UL))
22031  
22032 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22033 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22034                    STACK_TOP32 : STACK_TOP64)
22035  
22036  #endif
22037 diff -urNp linux-2.6.18/include/asm-sparc64/elf.h linux-2.6.18/include/asm-sparc64/elf.h
22038 --- linux-2.6.18/include/asm-sparc64/elf.h      2006-09-19 23:42:06.000000000 -0400
22039 +++ linux-2.6.18/include/asm-sparc64/elf.h      2006-09-22 20:45:04.000000000 -0400
22040 @@ -142,6 +142,16 @@ typedef struct {
22041  #define ELF_ET_DYN_BASE         0x0000010000000000UL
22042  #endif
22043  
22044 +#ifdef CONFIG_PAX_ASLR
22045 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
22046 +
22047 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
22048 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
22049 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
22050 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
22051 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22052 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
22053 +#endif
22054  
22055  /* This yields a mask that user programs can use to figure out what
22056     instruction set this cpu supports.  */
22057 diff -urNp linux-2.6.18/include/asm-sparc64/kmap_types.h linux-2.6.18/include/asm-sparc64/kmap_types.h
22058 --- linux-2.6.18/include/asm-sparc64/kmap_types.h       2006-09-19 23:42:06.000000000 -0400
22059 +++ linux-2.6.18/include/asm-sparc64/kmap_types.h       2006-09-22 20:45:04.000000000 -0400
22060 @@ -19,6 +19,7 @@ enum km_type {
22061         KM_IRQ1,
22062         KM_SOFTIRQ0,
22063         KM_SOFTIRQ1,
22064 +       KM_CLEARPAGE,
22065         KM_TYPE_NR
22066  };
22067  
22068 diff -urNp linux-2.6.18/include/asm-sparc64/page.h linux-2.6.18/include/asm-sparc64/page.h
22069 --- linux-2.6.18/include/asm-sparc64/page.h     2006-09-19 23:42:06.000000000 -0400
22070 +++ linux-2.6.18/include/asm-sparc64/page.h     2006-09-22 20:45:04.000000000 -0400
22071 @@ -141,6 +141,15 @@ typedef unsigned long pgprot_t;
22072  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
22073                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22074  
22075 +#ifdef CONFIG_PAX_PAGEEXEC
22076 +#ifdef CONFIG_PAX_MPROTECT
22077 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22078 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22079 +#else
22080 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22081 +#endif
22082 +#endif
22083 +
22084  #endif /* !(__KERNEL__) */
22085  
22086  #include <asm-generic/page.h>
22087 diff -urNp linux-2.6.18/include/asm-v850/kmap_types.h linux-2.6.18/include/asm-v850/kmap_types.h
22088 --- linux-2.6.18/include/asm-v850/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
22089 +++ linux-2.6.18/include/asm-v850/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
22090 @@ -13,6 +13,7 @@ enum km_type {
22091         KM_PTE1,
22092         KM_IRQ0,
22093         KM_IRQ1,
22094 +       KM_CLEARPAGE,
22095         KM_TYPE_NR
22096  };
22097  
22098 diff -urNp linux-2.6.18/include/asm-x86_64/a.out.h linux-2.6.18/include/asm-x86_64/a.out.h
22099 --- linux-2.6.18/include/asm-x86_64/a.out.h     2006-09-19 23:42:06.000000000 -0400
22100 +++ linux-2.6.18/include/asm-x86_64/a.out.h     2006-09-22 20:45:04.000000000 -0400
22101 @@ -21,7 +21,7 @@ struct exec
22102  
22103  #ifdef __KERNEL__
22104  #include <linux/thread_info.h>
22105 -#define STACK_TOP TASK_SIZE
22106 +#define __STACK_TOP TASK_SIZE
22107  #endif
22108  
22109  #endif /* __A_OUT_GNU_H__ */
22110 diff -urNp linux-2.6.18/include/asm-x86_64/elf.h linux-2.6.18/include/asm-x86_64/elf.h
22111 --- linux-2.6.18/include/asm-x86_64/elf.h       2006-09-19 23:42:06.000000000 -0400
22112 +++ linux-2.6.18/include/asm-x86_64/elf.h       2006-09-22 20:45:04.000000000 -0400
22113 @@ -93,6 +93,17 @@ typedef struct user_i387_struct elf_fpre
22114  
22115  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
22116  
22117 +#ifdef CONFIG_PAX_ASLR
22118 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
22119 +
22120 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
22121 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
22122 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
22123 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
22124 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22125 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 32)
22126 +#endif
22127 +
22128  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
22129     now struct_user_regs, they are different). Assumes current is the process
22130     getting dumped. */
22131 diff -urNp linux-2.6.18/include/asm-x86_64/ia32.h linux-2.6.18/include/asm-x86_64/ia32.h
22132 --- linux-2.6.18/include/asm-x86_64/ia32.h      2006-09-19 23:42:06.000000000 -0400
22133 +++ linux-2.6.18/include/asm-x86_64/ia32.h      2006-09-22 20:45:04.000000000 -0400
22134 @@ -156,7 +156,13 @@ struct ustat32 {
22135         char                    f_fpack[6];
22136  };
22137  
22138 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
22139 +#ifdef CONFIG_PAX_RANDUSTACK
22140 +#define IA32_DELTA_STACK (current->mm->delta_stack)
22141 +#else
22142 +#define IA32_DELTA_STACK 0UL
22143 +#endif
22144 +
22145 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
22146  
22147  #ifdef __KERNEL__
22148  struct user_desc;
22149 diff -urNp linux-2.6.18/include/asm-x86_64/kmap_types.h linux-2.6.18/include/asm-x86_64/kmap_types.h
22150 --- linux-2.6.18/include/asm-x86_64/kmap_types.h        2006-09-19 23:42:06.000000000 -0400
22151 +++ linux-2.6.18/include/asm-x86_64/kmap_types.h        2006-09-22 20:45:04.000000000 -0400
22152 @@ -13,6 +13,7 @@ enum km_type {
22153         KM_IRQ1,
22154         KM_SOFTIRQ0,
22155         KM_SOFTIRQ1,
22156 +       KM_CLEARPAGE,
22157         KM_TYPE_NR
22158  };
22159  
22160 diff -urNp linux-2.6.18/include/asm-x86_64/page.h linux-2.6.18/include/asm-x86_64/page.h
22161 --- linux-2.6.18/include/asm-x86_64/page.h      2006-09-19 23:42:06.000000000 -0400
22162 +++ linux-2.6.18/include/asm-x86_64/page.h      2006-09-22 20:45:04.000000000 -0400
22163 @@ -88,6 +88,8 @@ typedef struct { unsigned long pgprot; }
22164  #define __PAGE_OFFSET           0xffff810000000000
22165  #endif /* !__ASSEMBLY__ */
22166  
22167 +#define __KERNEL_TEXT_OFFSET   (0)
22168 +
22169  /* to align the pointer to the (next) page boundary */
22170  #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
22171  
22172 @@ -133,6 +135,15 @@ typedef struct { unsigned long pgprot; }
22173         (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
22174          VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22175  
22176 +#ifdef CONFIG_PAX_PAGEEXEC
22177 +#ifdef CONFIG_PAX_MPROTECT
22178 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22179 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22180 +#else
22181 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22182 +#endif
22183 +#endif
22184 +
22185  #define __HAVE_ARCH_GATE_AREA 1        
22186  
22187  #include <asm-generic/memory_model.h>
22188 diff -urNp linux-2.6.18/include/asm-x86_64/pci-direct.h linux-2.6.18/include/asm-x86_64/pci-direct.h
22189 --- linux-2.6.18/include/asm-x86_64/pci-direct.h        2006-09-19 23:42:06.000000000 -0400
22190 +++ linux-2.6.18/include/asm-x86_64/pci-direct.h        2006-09-22 20:45:04.000000000 -0400
22191 @@ -7,7 +7,7 @@
22192  /* Direct PCI access. This is used for PCI accesses in early boot before
22193     the PCI subsystem works. */ 
22194  
22195 -#define PDprintk(x...)
22196 +#define PDprintk(x...) do {} while (0)
22197  
22198  static inline u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
22199  {
22200 diff -urNp linux-2.6.18/include/asm-x86_64/pgalloc.h linux-2.6.18/include/asm-x86_64/pgalloc.h
22201 --- linux-2.6.18/include/asm-x86_64/pgalloc.h   2006-09-19 23:42:06.000000000 -0400
22202 +++ linux-2.6.18/include/asm-x86_64/pgalloc.h   2006-09-22 20:45:04.000000000 -0400
22203 @@ -7,7 +7,7 @@
22204  #include <linux/mm.h>
22205  
22206  #define pmd_populate_kernel(mm, pmd, pte) \
22207 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
22208 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
22209  #define pud_populate(mm, pud, pmd) \
22210                 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
22211  #define pgd_populate(mm, pgd, pud) \
22212 diff -urNp linux-2.6.18/include/asm-x86_64/pgtable.h linux-2.6.18/include/asm-x86_64/pgtable.h
22213 --- linux-2.6.18/include/asm-x86_64/pgtable.h   2006-09-19 23:42:06.000000000 -0400
22214 +++ linux-2.6.18/include/asm-x86_64/pgtable.h   2006-09-22 20:45:04.000000000 -0400
22215 @@ -180,6 +180,10 @@ static inline pte_t ptep_get_and_clear_f
22216  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
22217  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
22218  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
22219 +
22220 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
22221 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
22222 +
22223  #define __PAGE_KERNEL \
22224         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
22225  #define __PAGE_KERNEL_EXEC \
22226 @@ -268,7 +272,13 @@ static inline pte_t pfn_pte(unsigned lon
22227  #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
22228  static inline int pte_user(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
22229  static inline int pte_read(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
22230 -static inline int pte_exec(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
22231 +extern inline int pte_exec(pte_t pte)
22232 +{
22233 +       if (__supported_pte_mask & _PAGE_NX)
22234 +               return pte_val(pte) & _PAGE_NX;
22235 +       else
22236 +               return pte_val(pte) & _PAGE_USER;
22237 +}
22238  static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
22239  static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
22240  static inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_RW; }
22241 @@ -276,12 +286,26 @@ static inline int pte_file(pte_t pte)             {
22242  static inline int pte_huge(pte_t pte)          { return pte_val(pte) & _PAGE_PSE; }
22243  
22244  static inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
22245 -static inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
22246 +extern inline pte_t pte_exprotect(pte_t pte)
22247 +{
22248 +       if (__supported_pte_mask & _PAGE_NX)
22249 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
22250 +       else
22251 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
22252 +       return pte;
22253 +}
22254  static inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
22255  static inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
22256  static inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
22257  static inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
22258 -static inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
22259 +extern inline pte_t pte_mkexec(pte_t pte)
22260 +{
22261 +       if (__supported_pte_mask & _PAGE_NX)
22262 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
22263 +       else
22264 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
22265 +       return pte;
22266 +}
22267  static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
22268  static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
22269  static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
22270 diff -urNp linux-2.6.18/include/asm-x86_64/system.h linux-2.6.18/include/asm-x86_64/system.h
22271 --- linux-2.6.18/include/asm-x86_64/system.h    2006-09-19 23:42:06.000000000 -0400
22272 +++ linux-2.6.18/include/asm-x86_64/system.h    2006-09-22 20:45:04.000000000 -0400
22273 @@ -247,7 +247,7 @@ static inline unsigned long __cmpxchg(vo
22274  
22275  void cpu_idle_wait(void);
22276  
22277 -extern unsigned long arch_align_stack(unsigned long sp);
22278 +#define arch_align_stack(x) (x)
22279  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
22280  
22281  #endif
22282 diff -urNp linux-2.6.18/include/asm-xtensa/kmap_types.h linux-2.6.18/include/asm-xtensa/kmap_types.h
22283 --- linux-2.6.18/include/asm-xtensa/kmap_types.h        2006-09-19 23:42:06.000000000 -0400
22284 +++ linux-2.6.18/include/asm-xtensa/kmap_types.h        2006-09-22 20:45:04.000000000 -0400
22285 @@ -25,6 +25,7 @@ enum km_type {
22286    KM_IRQ1,
22287    KM_SOFTIRQ0,
22288    KM_SOFTIRQ1,
22289 +  KM_CLEARPAGE,
22290    KM_TYPE_NR
22291  };
22292  
22293 diff -urNp linux-2.6.18/include/linux/a.out.h linux-2.6.18/include/linux/a.out.h
22294 --- linux-2.6.18/include/linux/a.out.h  2006-09-19 23:42:06.000000000 -0400
22295 +++ linux-2.6.18/include/linux/a.out.h  2006-09-22 20:45:04.000000000 -0400
22296 @@ -7,6 +7,16 @@
22297  
22298  #include <asm/a.out.h>
22299  
22300 +#ifdef CONFIG_PAX_RANDUSTACK
22301 +#define __DELTA_STACK (current->mm->delta_stack)
22302 +#else
22303 +#define __DELTA_STACK 0UL
22304 +#endif
22305 +
22306 +#ifndef STACK_TOP
22307 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
22308 +#endif
22309 +
22310  #endif /* __STRUCT_EXEC_OVERRIDE__ */
22311  
22312  /* these go in the N_MACHTYPE field */
22313 @@ -37,6 +47,14 @@ enum machine_type {
22314    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
22315  };
22316  
22317 +/* Constants for the N_FLAGS field */
22318 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
22319 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
22320 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
22321 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
22322 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
22323 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
22324 +
22325  #if !defined (N_MAGIC)
22326  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
22327  #endif
22328 diff -urNp linux-2.6.18/include/linux/binfmts.h linux-2.6.18/include/linux/binfmts.h
22329 --- linux-2.6.18/include/linux/binfmts.h        2006-09-19 23:42:06.000000000 -0400
22330 +++ linux-2.6.18/include/linux/binfmts.h        2006-09-22 20:45:04.000000000 -0400
22331 @@ -7,10 +7,10 @@ struct pt_regs;
22332  
22333  /*
22334   * MAX_ARG_PAGES defines the number of pages allocated for arguments
22335 - * and envelope for the new program. 32 should suffice, this gives
22336 - * a maximum env+arg of 128kB w/4KB pages!
22337 + * and envelope for the new program. 33 should suffice, this gives
22338 + * a maximum env+arg of 132kB w/4KB pages!
22339   */
22340 -#define MAX_ARG_PAGES 32
22341 +#define MAX_ARG_PAGES 33
22342  
22343  /* sizeof(linux_binprm->buf) */
22344  #define BINPRM_BUF_SIZE 128
22345 @@ -38,6 +38,7 @@ struct linux_binprm{
22346         unsigned interp_flags;
22347         unsigned interp_data;
22348         unsigned long loader, exec;
22349 +       int misc;
22350  };
22351  
22352  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
22353 @@ -87,5 +88,8 @@ extern void compute_creds(struct linux_b
22354  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
22355  extern int set_binfmt(struct linux_binfmt *new);
22356  
22357 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
22358 +void pax_report_insns(void *pc, void *sp);
22359 +
22360  #endif /* __KERNEL__ */
22361  #endif /* _LINUX_BINFMTS_H */
22362 diff -urNp linux-2.6.18/include/linux/capability.h linux-2.6.18/include/linux/capability.h
22363 --- linux-2.6.18/include/linux/capability.h     2006-09-19 23:42:06.000000000 -0400
22364 +++ linux-2.6.18/include/linux/capability.h     2006-09-22 20:04:35.000000000 -0400
22365 @@ -358,6 +358,7 @@ static inline kernel_cap_t cap_invert(ke
22366  #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
22367  
22368  int capable(int cap);
22369 +int capable_nolog(int cap);
22370  int __capable(struct task_struct *t, int cap);
22371  
22372  #endif /* __KERNEL__ */
22373 diff -urNp linux-2.6.18/include/linux/elf.h linux-2.6.18/include/linux/elf.h
22374 --- linux-2.6.18/include/linux/elf.h    2006-09-19 23:42:06.000000000 -0400
22375 +++ linux-2.6.18/include/linux/elf.h    2006-09-22 20:45:04.000000000 -0400
22376 @@ -6,6 +6,10 @@
22377  #include <linux/elf-em.h>
22378  #include <asm/elf.h>
22379  
22380 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22381 +#undef elf_read_implies_exec
22382 +#endif
22383 +
22384  #ifndef elf_read_implies_exec
22385    /* Executables for which elf_read_implies_exec() returns TRUE will
22386       have the READ_IMPLIES_EXEC personality flag set automatically.
22387 @@ -47,6 +51,16 @@ typedef __s64        Elf64_Sxword;
22388  
22389  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
22390  
22391 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
22392 +
22393 +/* Constants for the e_flags field */
22394 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
22395 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
22396 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
22397 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
22398 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
22399 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
22400 +
22401  /* These constants define the different elf file types */
22402  #define ET_NONE   0
22403  #define ET_REL    1
22404 @@ -81,6 +95,8 @@ typedef __s64 Elf64_Sxword;
22405  #define DT_DEBUG       21
22406  #define DT_TEXTREL     22
22407  #define DT_JMPREL      23
22408 +#define DT_FLAGS       30
22409 +  #define DF_TEXTREL   0x00000004
22410  #define DT_LOPROC      0x70000000
22411  #define DT_HIPROC      0x7fffffff
22412  
22413 @@ -210,6 +226,19 @@ typedef struct elf64_hdr {
22414  #define PF_W           0x2
22415  #define PF_X           0x1
22416  
22417 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
22418 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
22419 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
22420 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
22421 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
22422 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
22423 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
22424 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
22425 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
22426 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
22427 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
22428 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
22429 +
22430  typedef struct elf32_phdr{
22431    Elf32_Word   p_type;
22432    Elf32_Off    p_offset;
22433 @@ -302,6 +331,8 @@ typedef struct elf64_shdr {
22434  #define        EI_OSABI        7
22435  #define        EI_PAD          8
22436  
22437 +#define        EI_PAX          14
22438 +
22439  #define        ELFMAG0         0x7f            /* EI_MAG */
22440  #define        ELFMAG1         'E'
22441  #define        ELFMAG2         'L'
22442 @@ -358,6 +389,7 @@ extern Elf32_Dyn _DYNAMIC [];
22443  #define elfhdr         elf32_hdr
22444  #define elf_phdr       elf32_phdr
22445  #define elf_note       elf32_note
22446 +#define elf_dyn                Elf32_Dyn
22447  
22448  #else
22449  
22450 @@ -365,6 +397,7 @@ extern Elf64_Dyn _DYNAMIC [];
22451  #define elfhdr         elf64_hdr
22452  #define elf_phdr       elf64_phdr
22453  #define elf_note       elf64_note
22454 +#define elf_dyn                Elf64_Dyn
22455  
22456  #endif
22457  
22458 diff -urNp linux-2.6.18/include/linux/gracl.h linux-2.6.18/include/linux/gracl.h
22459 --- linux-2.6.18/include/linux/gracl.h  1969-12-31 19:00:00.000000000 -0500
22460 +++ linux-2.6.18/include/linux/gracl.h  2006-09-22 20:04:35.000000000 -0400
22461 @@ -0,0 +1,316 @@
22462 +#ifndef GR_ACL_H
22463 +#define GR_ACL_H
22464 +
22465 +#include <linux/grdefs.h>
22466 +#include <linux/resource.h>
22467 +#include <linux/dcache.h>
22468 +#include <asm/resource.h>
22469 +
22470 +/* Major status information */
22471 +
22472 +#define GR_VERSION  "grsecurity 2.1.9"
22473 +#define GRSECURITY_VERSION 0x219
22474 +
22475 +enum {
22476 +
22477 +       SHUTDOWN = 0,
22478 +       ENABLE = 1,
22479 +       SPROLE = 2,
22480 +       RELOAD = 3,
22481 +       SEGVMOD = 4,
22482 +       STATUS = 5,
22483 +       UNSPROLE = 6,
22484 +       PASSSET = 7,
22485 +       SPROLEPAM = 8
22486 +};
22487 +
22488 +/* Password setup definitions
22489 + * kernel/grhash.c */
22490 +enum {
22491 +       GR_PW_LEN = 128,
22492 +       GR_SALT_LEN = 16,
22493 +       GR_SHA_LEN = 32,
22494 +};
22495 +
22496 +enum {
22497 +       GR_SPROLE_LEN = 64,
22498 +};
22499 +
22500 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
22501 +
22502 +/* Begin Data Structures */
22503 +
22504 +struct sprole_pw {
22505 +       unsigned char *rolename;
22506 +       unsigned char salt[GR_SALT_LEN];
22507 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
22508 +};
22509 +
22510 +struct name_entry {
22511 +       __u32 key;
22512 +       ino_t inode;
22513 +       dev_t device;
22514 +       char *name;
22515 +       __u16 len;
22516 +       struct name_entry *prev;
22517 +       struct name_entry *next;
22518 +};
22519 +
22520 +struct inodev_entry {
22521 +       struct name_entry *nentry;
22522 +       struct inodev_entry *prev;
22523 +       struct inodev_entry *next;
22524 +};
22525 +
22526 +struct acl_role_db {
22527 +       struct acl_role_label **r_hash;
22528 +       __u32 r_size;
22529 +};
22530 +
22531 +struct inodev_db {
22532 +       struct inodev_entry **i_hash;
22533 +       __u32 i_size;
22534 +};
22535 +
22536 +struct name_db {
22537 +       struct name_entry **n_hash;
22538 +       __u32 n_size;
22539 +};
22540 +
22541 +struct crash_uid {
22542 +       uid_t uid;
22543 +       unsigned long expires;
22544 +};
22545 +
22546 +struct gr_hash_struct {
22547 +       void **table;
22548 +       void **nametable;
22549 +       void *first;
22550 +       __u32 table_size;
22551 +       __u32 used_size;
22552 +       int type;
22553 +};
22554 +
22555 +/* Userspace Grsecurity ACL data structures */
22556 +
22557 +struct acl_subject_label {
22558 +       char *filename;
22559 +       ino_t inode;
22560 +       dev_t device;
22561 +       __u32 mode;
22562 +       __u32 cap_mask;
22563 +       __u32 cap_lower;
22564 +
22565 +       struct rlimit res[GR_NLIMITS];
22566 +       __u16 resmask;
22567 +
22568 +       __u8 user_trans_type;
22569 +       __u8 group_trans_type;
22570 +       uid_t *user_transitions;
22571 +       gid_t *group_transitions;
22572 +       __u16 user_trans_num;
22573 +       __u16 group_trans_num;
22574 +
22575 +       __u32 ip_proto[8];
22576 +       __u32 ip_type;
22577 +       struct acl_ip_label **ips;
22578 +       __u32 ip_num;
22579 +
22580 +       __u32 crashes;
22581 +       unsigned long expires;
22582 +
22583 +       struct acl_subject_label *parent_subject;
22584 +       struct gr_hash_struct *hash;
22585 +       struct acl_subject_label *prev;
22586 +       struct acl_subject_label *next;
22587 +
22588 +       struct acl_object_label **obj_hash;
22589 +       __u32 obj_hash_size;
22590 +       __u16 pax_flags;
22591 +};
22592 +
22593 +struct role_allowed_ip {
22594 +       __u32 addr;
22595 +       __u32 netmask;
22596 +
22597 +       struct role_allowed_ip *prev;
22598 +       struct role_allowed_ip *next;
22599 +};
22600 +
22601 +struct role_transition {
22602 +       char *rolename;
22603 +
22604 +       struct role_transition *prev;
22605 +       struct role_transition *next;
22606 +};
22607 +
22608 +struct acl_role_label {
22609 +       char *rolename;
22610 +       uid_t uidgid;
22611 +       __u16 roletype;
22612 +
22613 +       __u16 auth_attempts;
22614 +       unsigned long expires;
22615 +
22616 +       struct acl_subject_label *root_label;
22617 +       struct gr_hash_struct *hash;
22618 +
22619 +       struct acl_role_label *prev;
22620 +       struct acl_role_label *next;
22621 +
22622 +       struct role_transition *transitions;
22623 +       struct role_allowed_ip *allowed_ips;
22624 +       uid_t *domain_children;
22625 +       __u16 domain_child_num;
22626 +
22627 +       struct acl_subject_label **subj_hash;
22628 +       __u32 subj_hash_size;
22629 +};
22630 +
22631 +struct user_acl_role_db {
22632 +       struct acl_role_label **r_table;
22633 +       __u32 num_pointers;             /* Number of allocations to track */
22634 +       __u32 num_roles;                /* Number of roles */
22635 +       __u32 num_domain_children;      /* Number of domain children */
22636 +       __u32 num_subjects;             /* Number of subjects */
22637 +       __u32 num_objects;              /* Number of objects */
22638 +};
22639 +
22640 +struct acl_object_label {
22641 +       char *filename;
22642 +       ino_t inode;
22643 +       dev_t device;
22644 +       __u32 mode;
22645 +
22646 +       struct acl_subject_label *nested;
22647 +       struct acl_object_label *globbed;
22648 +
22649 +       /* next two structures not used */
22650 +
22651 +       struct acl_object_label *prev;
22652 +       struct acl_object_label *next;
22653 +};
22654 +
22655 +struct acl_ip_label {
22656 +       char *iface;
22657 +       __u32 addr;
22658 +       __u32 netmask;
22659 +       __u16 low, high;
22660 +       __u8 mode;
22661 +       __u32 type;
22662 +       __u32 proto[8];
22663 +
22664 +       /* next two structures not used */
22665 +
22666 +       struct acl_ip_label *prev;
22667 +       struct acl_ip_label *next;
22668 +};
22669 +
22670 +struct gr_arg {
22671 +       struct user_acl_role_db role_db;
22672 +       unsigned char pw[GR_PW_LEN];
22673 +       unsigned char salt[GR_SALT_LEN];
22674 +       unsigned char sum[GR_SHA_LEN];
22675 +       unsigned char sp_role[GR_SPROLE_LEN];
22676 +       struct sprole_pw *sprole_pws;
22677 +       dev_t segv_device;
22678 +       ino_t segv_inode;
22679 +       uid_t segv_uid;
22680 +       __u16 num_sprole_pws;
22681 +       __u16 mode;
22682 +};
22683 +
22684 +struct gr_arg_wrapper {
22685 +       struct gr_arg *arg;
22686 +       __u32 version;
22687 +       __u32 size;
22688 +};
22689 +
22690 +struct subject_map {
22691 +       struct acl_subject_label *user;
22692 +       struct acl_subject_label *kernel;
22693 +       struct subject_map *prev;
22694 +       struct subject_map *next;
22695 +};
22696 +
22697 +struct acl_subj_map_db {
22698 +       struct subject_map **s_hash;
22699 +       __u32 s_size;
22700 +};
22701 +
22702 +/* End Data Structures Section */
22703 +
22704 +/* Hash functions generated by empirical testing by Brad Spengler
22705 +   Makes good use of the low bits of the inode.  Generally 0-1 times
22706 +   in loop for successful match.  0-3 for unsuccessful match.
22707 +   Shift/add algorithm with modulus of table size and an XOR*/
22708 +
22709 +static __inline__ unsigned int
22710 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
22711 +{
22712 +       return (((uid << type) + (uid ^ type)) % sz);
22713 +}
22714 +
22715 + static __inline__ unsigned int
22716 +shash(const struct acl_subject_label *userp, const unsigned int sz)
22717 +{
22718 +       return ((const unsigned long)userp % sz);
22719 +}
22720 +
22721 +static __inline__ unsigned int
22722 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
22723 +{
22724 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
22725 +}
22726 +
22727 +static __inline__ unsigned int
22728 +nhash(const char *name, const __u16 len, const unsigned int sz)
22729 +{
22730 +       return full_name_hash(name, len) % sz;
22731 +}
22732 +
22733 +#define FOR_EACH_ROLE_START(role,iter) \
22734 +       role = NULL; \
22735 +       iter = 0; \
22736 +       while (iter < acl_role_set.r_size) { \
22737 +               if (role == NULL) \
22738 +                       role = acl_role_set.r_hash[iter]; \
22739 +               if (role == NULL) { \
22740 +                       iter++; \
22741 +                       continue; \
22742 +               }
22743 +
22744 +#define FOR_EACH_ROLE_END(role,iter) \
22745 +               role = role->next; \
22746 +               if (role == NULL) \
22747 +                       iter++; \
22748 +       }
22749 +
22750 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
22751 +       subj = NULL; \
22752 +       iter = 0; \
22753 +       while (iter < role->subj_hash_size) { \
22754 +               if (subj == NULL) \
22755 +                       subj = role->subj_hash[iter]; \
22756 +               if (subj == NULL) { \
22757 +                       iter++; \
22758 +                       continue; \
22759 +               }
22760 +
22761 +#define FOR_EACH_SUBJECT_END(subj,iter) \
22762 +               subj = subj->next; \
22763 +               if (subj == NULL) \
22764 +                       iter++; \
22765 +       }
22766 +
22767 +
22768 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
22769 +       subj = role->hash->first; \
22770 +       while (subj != NULL) {
22771 +
22772 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
22773 +               subj = subj->next; \
22774 +       }
22775 +
22776 +#endif
22777 +
22778 diff -urNp linux-2.6.18/include/linux/gralloc.h linux-2.6.18/include/linux/gralloc.h
22779 --- linux-2.6.18/include/linux/gralloc.h        1969-12-31 19:00:00.000000000 -0500
22780 +++ linux-2.6.18/include/linux/gralloc.h        2006-09-22 20:04:35.000000000 -0400
22781 @@ -0,0 +1,8 @@
22782 +#ifndef __GRALLOC_H
22783 +#define __GRALLOC_H
22784 +
22785 +void acl_free_all(void);
22786 +int acl_alloc_stack_init(unsigned long size);
22787 +void *acl_alloc(unsigned long len);
22788 +
22789 +#endif
22790 diff -urNp linux-2.6.18/include/linux/grdefs.h linux-2.6.18/include/linux/grdefs.h
22791 --- linux-2.6.18/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
22792 +++ linux-2.6.18/include/linux/grdefs.h 2006-09-22 20:04:35.000000000 -0400
22793 @@ -0,0 +1,131 @@
22794 +#ifndef GRDEFS_H
22795 +#define GRDEFS_H
22796 +
22797 +/* Begin grsecurity status declarations */
22798 +
22799 +enum {
22800 +       GR_READY = 0x01,
22801 +       GR_STATUS_INIT = 0x00   // disabled state
22802 +};
22803 +
22804 +/* Begin  ACL declarations */
22805 +
22806 +/* Role flags */
22807 +
22808 +enum {
22809 +       GR_ROLE_USER = 0x0001,
22810 +       GR_ROLE_GROUP = 0x0002,
22811 +       GR_ROLE_DEFAULT = 0x0004,
22812 +       GR_ROLE_SPECIAL = 0x0008,
22813 +       GR_ROLE_AUTH = 0x0010,
22814 +       GR_ROLE_NOPW = 0x0020,
22815 +       GR_ROLE_GOD = 0x0040,
22816 +       GR_ROLE_LEARN = 0x0080,
22817 +       GR_ROLE_TPE = 0x0100,
22818 +       GR_ROLE_DOMAIN = 0x0200,
22819 +       GR_ROLE_PAM = 0x0400
22820 +};
22821 +
22822 +/* ACL Subject and Object mode flags */
22823 +enum {
22824 +       GR_DELETED = 0x80000000
22825 +};
22826 +
22827 +/* ACL Object-only mode flags */
22828 +enum {
22829 +       GR_READ         = 0x00000001,
22830 +       GR_APPEND       = 0x00000002,
22831 +       GR_WRITE        = 0x00000004,
22832 +       GR_EXEC         = 0x00000008,
22833 +       GR_FIND         = 0x00000010,
22834 +       GR_INHERIT      = 0x00000020,
22835 +       GR_SETID        = 0x00000040,
22836 +       GR_CREATE       = 0x00000080,
22837 +       GR_DELETE       = 0x00000100,
22838 +       GR_LINK         = 0x00000200,
22839 +       GR_AUDIT_READ   = 0x00000400,
22840 +       GR_AUDIT_APPEND = 0x00000800,
22841 +       GR_AUDIT_WRITE  = 0x00001000,
22842 +       GR_AUDIT_EXEC   = 0x00002000,
22843 +       GR_AUDIT_FIND   = 0x00004000,
22844 +       GR_AUDIT_INHERIT= 0x00008000,
22845 +       GR_AUDIT_SETID  = 0x00010000,
22846 +       GR_AUDIT_CREATE = 0x00020000,
22847 +       GR_AUDIT_DELETE = 0x00040000,
22848 +       GR_AUDIT_LINK   = 0x00080000,
22849 +       GR_PTRACERD     = 0x00100000,
22850 +       GR_NOPTRACE     = 0x00200000,
22851 +       GR_SUPPRESS     = 0x00400000,
22852 +       GR_NOLEARN      = 0x00800000
22853 +};
22854 +
22855 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
22856 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
22857 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
22858 +
22859 +/* ACL subject-only mode flags */
22860 +enum {
22861 +       GR_KILL         = 0x00000001,
22862 +       GR_VIEW         = 0x00000002,
22863 +       GR_PROTECTED    = 0x00000004,
22864 +       GR_LEARN        = 0x00000008,
22865 +       GR_OVERRIDE     = 0x00000010,
22866 +       /* just a placeholder, this mode is only used in userspace */
22867 +       GR_DUMMY        = 0x00000020,
22868 +       GR_PROTSHM      = 0x00000040,
22869 +       GR_KILLPROC     = 0x00000080,
22870 +       GR_KILLIPPROC   = 0x00000100,
22871 +       /* just a placeholder, this mode is only used in userspace */
22872 +       GR_NOTROJAN     = 0x00000200,
22873 +       GR_PROTPROCFD   = 0x00000400,
22874 +       GR_PROCACCT     = 0x00000800,
22875 +       GR_RELAXPTRACE  = 0x00001000,
22876 +       GR_NESTED       = 0x00002000,
22877 +       GR_INHERITLEARN = 0x00004000,
22878 +       GR_PROCFIND     = 0x00008000,
22879 +       GR_POVERRIDE    = 0x00010000,
22880 +       GR_KERNELAUTH   = 0x00020000,
22881 +};
22882 +
22883 +enum {
22884 +       GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
22885 +       GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
22886 +       GR_PAX_ENABLE_MPROTECT  = 0x0004,
22887 +       GR_PAX_ENABLE_RANDMMAP  = 0x0008,
22888 +       GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
22889 +       GR_PAX_DISABLE_SEGMEXEC = 0x8001,
22890 +       GR_PAX_DISABLE_PAGEEXEC = 0x8002,
22891 +       GR_PAX_DISABLE_MPROTECT = 0x8004,
22892 +       GR_PAX_DISABLE_RANDMMAP = 0x8008,
22893 +       GR_PAX_DISABLE_EMUTRAMP = 0x8010,
22894 +};
22895 +
22896 +enum {
22897 +       GR_ID_USER      = 0x01,
22898 +       GR_ID_GROUP     = 0x02,
22899 +};
22900 +
22901 +enum {
22902 +       GR_ID_ALLOW     = 0x01,
22903 +       GR_ID_DENY      = 0x02,
22904 +};
22905 +
22906 +#define GR_CRASH_RES   11
22907 +#define GR_UIDTABLE_MAX 500
22908 +
22909 +/* begin resource learning section */
22910 +enum {
22911 +       GR_RLIM_CPU_BUMP = 60,
22912 +       GR_RLIM_FSIZE_BUMP = 50000,
22913 +       GR_RLIM_DATA_BUMP = 10000,
22914 +       GR_RLIM_STACK_BUMP = 1000,
22915 +       GR_RLIM_CORE_BUMP = 10000,
22916 +       GR_RLIM_RSS_BUMP = 500000,
22917 +       GR_RLIM_NPROC_BUMP = 1,
22918 +       GR_RLIM_NOFILE_BUMP = 5,
22919 +       GR_RLIM_MEMLOCK_BUMP = 50000,
22920 +       GR_RLIM_AS_BUMP = 500000,
22921 +       GR_RLIM_LOCKS_BUMP = 2
22922 +};
22923 +
22924 +#endif
22925 diff -urNp linux-2.6.18/include/linux/grinternal.h linux-2.6.18/include/linux/grinternal.h
22926 --- linux-2.6.18/include/linux/grinternal.h     1969-12-31 19:00:00.000000000 -0500
22927 +++ linux-2.6.18/include/linux/grinternal.h     2006-09-22 20:04:35.000000000 -0400
22928 @@ -0,0 +1,211 @@
22929 +#ifndef __GRINTERNAL_H
22930 +#define __GRINTERNAL_H
22931 +
22932 +#ifdef CONFIG_GRKERNSEC
22933 +
22934 +#include <linux/fs.h>
22935 +#include <linux/gracl.h>
22936 +#include <linux/grdefs.h>
22937 +#include <linux/grmsg.h>
22938 +
22939 +extern void gr_add_learn_entry(const char *fmt, ...);
22940 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
22941 +                           const struct vfsmount *mnt);
22942 +extern __u32 gr_check_create(const struct dentry *new_dentry,
22943 +                            const struct dentry *parent,
22944 +                            const struct vfsmount *mnt, const __u32 mode);
22945 +extern int gr_check_protected_task(const struct task_struct *task);
22946 +extern __u32 to_gr_audit(const __u32 reqmode);
22947 +extern int gr_set_acls(const int type);
22948 +
22949 +extern int gr_acl_is_enabled(void);
22950 +extern char gr_roletype_to_char(void);
22951 +
22952 +extern void gr_handle_alertkill(struct task_struct *task);
22953 +extern char *gr_to_filename(const struct dentry *dentry,
22954 +                           const struct vfsmount *mnt);
22955 +extern char *gr_to_filename1(const struct dentry *dentry,
22956 +                           const struct vfsmount *mnt);
22957 +extern char *gr_to_filename2(const struct dentry *dentry,
22958 +                           const struct vfsmount *mnt);
22959 +extern char *gr_to_filename3(const struct dentry *dentry,
22960 +                           const struct vfsmount *mnt);
22961 +
22962 +extern int grsec_enable_link;
22963 +extern int grsec_enable_fifo;
22964 +extern int grsec_enable_execve;
22965 +extern int grsec_enable_shm;
22966 +extern int grsec_enable_execlog;
22967 +extern int grsec_enable_signal;
22968 +extern int grsec_enable_forkfail;
22969 +extern int grsec_enable_time;
22970 +extern int grsec_enable_chroot_shmat;
22971 +extern int grsec_enable_chroot_findtask;
22972 +extern int grsec_enable_chroot_mount;
22973 +extern int grsec_enable_chroot_double;
22974 +extern int grsec_enable_chroot_pivot;
22975 +extern int grsec_enable_chroot_chdir;
22976 +extern int grsec_enable_chroot_chmod;
22977 +extern int grsec_enable_chroot_mknod;
22978 +extern int grsec_enable_chroot_fchdir;
22979 +extern int grsec_enable_chroot_nice;
22980 +extern int grsec_enable_chroot_execlog;
22981 +extern int grsec_enable_chroot_caps;
22982 +extern int grsec_enable_chroot_sysctl;
22983 +extern int grsec_enable_chroot_unix;
22984 +extern int grsec_enable_tpe;
22985 +extern int grsec_tpe_gid;
22986 +extern int grsec_enable_tpe_all;
22987 +extern int grsec_enable_sidcaps;
22988 +extern int grsec_enable_randpid;
22989 +extern int grsec_enable_socket_all;
22990 +extern int grsec_socket_all_gid;
22991 +extern int grsec_enable_socket_client;
22992 +extern int grsec_socket_client_gid;
22993 +extern int grsec_enable_socket_server;
22994 +extern int grsec_socket_server_gid;
22995 +extern int grsec_audit_gid;
22996 +extern int grsec_enable_group;
22997 +extern int grsec_enable_audit_ipc;
22998 +extern int grsec_enable_audit_textrel;
22999 +extern int grsec_enable_mount;
23000 +extern int grsec_enable_chdir;
23001 +extern int grsec_resource_logging;
23002 +extern int grsec_lock;
23003 +
23004 +extern struct task_struct *child_reaper;
23005 +
23006 +extern spinlock_t grsec_alert_lock;
23007 +extern unsigned long grsec_alert_wtime;
23008 +extern unsigned long grsec_alert_fyet;
23009 +
23010 +extern spinlock_t grsec_audit_lock;
23011 +
23012 +extern rwlock_t grsec_exec_file_lock;
23013 +
23014 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
23015 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
23016 +                       tsk->exec_file->f_vfsmnt) : "/")
23017 +
23018 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
23019 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
23020 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
23021 +
23022 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
23023 +                       gr_to_filename(tsk->exec_file->f_dentry, \
23024 +                       tsk->exec_file->f_vfsmnt) : "/")
23025 +
23026 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
23027 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
23028 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
23029 +
23030 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
23031 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
23032 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
23033 +                         (tsk_a->fs->root->d_inode->i_ino != \
23034 +                         child_reaper->fs->root->d_inode->i_ino)))
23035 +
23036 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
23037 +                         (tsk_a->fs->root->d_inode->i_sb->s_dev == \
23038 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
23039 +                         (tsk_a->fs->root->d_inode->i_ino == \
23040 +                         tsk_b->fs->root->d_inode->i_ino))
23041 +
23042 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
23043 +                      task->pid, task->uid, \
23044 +                      task->euid, task->gid, task->egid, \
23045 +                      gr_parent_task_fullpath(task), \
23046 +                      task->parent->comm, task->parent->pid, \
23047 +                      task->parent->uid, task->parent->euid, \
23048 +                      task->parent->gid, task->parent->egid
23049 +
23050 +#define GR_CHROOT_CAPS ( \
23051 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
23052 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
23053 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
23054 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
23055 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
23056 +       CAP_TO_MASK(CAP_IPC_OWNER))
23057 +
23058 +#define security_learn(normal_msg,args...) \
23059 +({ \
23060 +       read_lock(&grsec_exec_file_lock); \
23061 +       gr_add_learn_entry(normal_msg "\n", ## args); \
23062 +       read_unlock(&grsec_exec_file_lock); \
23063 +})
23064 +
23065 +enum {
23066 +       GR_DO_AUDIT,
23067 +       GR_DONT_AUDIT,
23068 +       GR_DONT_AUDIT_GOOD
23069 +};
23070 +
23071 +enum {
23072 +       GR_TTYSNIFF,
23073 +       GR_RBAC,
23074 +       GR_RBAC_STR,
23075 +       GR_STR_RBAC,
23076 +       GR_RBAC_MODE2,
23077 +       GR_RBAC_MODE3,
23078 +       GR_FILENAME,
23079 +       GR_NOARGS,
23080 +       GR_ONE_INT,
23081 +       GR_ONE_INT_TWO_STR,
23082 +       GR_ONE_STR,
23083 +       GR_STR_INT,
23084 +       GR_TWO_INT,
23085 +       GR_THREE_INT,
23086 +       GR_FIVE_INT_TWO_STR,
23087 +       GR_TWO_STR,
23088 +       GR_THREE_STR,
23089 +       GR_FOUR_STR,
23090 +       GR_STR_FILENAME,
23091 +       GR_FILENAME_STR,
23092 +       GR_FILENAME_TWO_INT,
23093 +       GR_FILENAME_TWO_INT_STR,
23094 +       GR_TEXTREL,
23095 +       GR_PTRACE,
23096 +       GR_RESOURCE,
23097 +       GR_CAP,
23098 +       GR_SIG,
23099 +       GR_CRASH1,
23100 +       GR_CRASH2,
23101 +       GR_PSACCT
23102 +};
23103 +
23104 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
23105 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
23106 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
23107 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
23108 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
23109 +#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3)
23110 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
23111 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
23112 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
23113 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
23114 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
23115 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
23116 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
23117 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
23118 +#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2)
23119 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
23120 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
23121 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
23122 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
23123 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
23124 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
23125 +#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str)
23126 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
23127 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
23128 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
23129 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
23130 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
23131 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
23132 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
23133 +#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9)
23134 +
23135 +extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
23136 +
23137 +#endif
23138 +
23139 +#endif
23140 diff -urNp linux-2.6.18/include/linux/grmsg.h linux-2.6.18/include/linux/grmsg.h
23141 --- linux-2.6.18/include/linux/grmsg.h  1969-12-31 19:00:00.000000000 -0500
23142 +++ linux-2.6.18/include/linux/grmsg.h  2006-09-22 20:04:35.000000000 -0400
23143 @@ -0,0 +1,108 @@
23144 +#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u"
23145 +#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
23146 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
23147 +#define GR_STOPMOD_MSG "denied modification of module state by "
23148 +#define GR_IOPERM_MSG "denied use of ioperm() by "
23149 +#define GR_IOPL_MSG "denied use of iopl() by "
23150 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
23151 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
23152 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
23153 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
23154 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
23155 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
23156 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
23157 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
23158 +#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%u.%u.%u.%u"
23159 +#define GR_ID_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%c\t%d\t%d\t%d\t%u.%u.%u.%u"
23160 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
23161 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
23162 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
23163 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
23164 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
23165 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
23166 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
23167 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
23168 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
23169 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
23170 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
23171 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
23172 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
23173 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
23174 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
23175 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
23176 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
23177 +#define GR_NPROC_MSG "denied overstep of process limit by "
23178 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
23179 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
23180 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
23181 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
23182 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
23183 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
23184 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
23185 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
23186 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
23187 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
23188 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
23189 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
23190 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
23191 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
23192 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
23193 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
23194 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
23195 +#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader"
23196 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
23197 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
23198 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
23199 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
23200 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
23201 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
23202 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
23203 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
23204 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
23205 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
23206 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
23207 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
23208 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
23209 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
23210 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
23211 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
23212 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
23213 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
23214 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
23215 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
23216 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
23217 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
23218 +#define GR_NICE_CHROOT_MSG "denied priority change by "
23219 +#define GR_UNISIGLOG_MSG "signal %d sent to "
23220 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
23221 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
23222 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
23223 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
23224 +#define GR_TIME_MSG "time set by "
23225 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
23226 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
23227 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
23228 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
23229 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
23230 +#define GR_BIND_MSG "denied bind() by "
23231 +#define GR_CONNECT_MSG "denied connect() by "
23232 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
23233 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
23234 +#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%u.%u.%u.%u\t%u\t%u\t%u\t%u\t%u.%u.%u.%u"
23235 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
23236 +#define GR_CAP_ACL_MSG "use of %s denied for "
23237 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
23238 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
23239 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
23240 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
23241 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
23242 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
23243 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
23244 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
23245 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
23246 +#define GR_SEM_AUDIT_MSG "semaphore created by "
23247 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
23248 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
23249 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
23250 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
23251 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
23252 diff -urNp linux-2.6.18/include/linux/grsecurity.h linux-2.6.18/include/linux/grsecurity.h
23253 --- linux-2.6.18/include/linux/grsecurity.h     1969-12-31 19:00:00.000000000 -0500
23254 +++ linux-2.6.18/include/linux/grsecurity.h     2006-09-22 20:04:35.000000000 -0400
23255 @@ -0,0 +1,196 @@
23256 +#ifndef GR_SECURITY_H
23257 +#define GR_SECURITY_H
23258 +#include <linux/fs.h>
23259 +#include <linux/binfmts.h>
23260 +#include <linux/gracl.h>
23261 +
23262 +extern void gr_handle_brute_attach(struct task_struct *p);
23263 +extern void gr_handle_brute_check(void);
23264 +
23265 +extern char gr_roletype_to_char(void);
23266 +
23267 +extern int gr_check_user_change(int real, int effective, int fs);
23268 +extern int gr_check_group_change(int real, int effective, int fs);
23269 +
23270 +extern void gr_del_task_from_ip_table(struct task_struct *p);
23271 +
23272 +extern int gr_pid_is_chrooted(struct task_struct *p);
23273 +extern int gr_handle_chroot_nice(void);
23274 +extern int gr_handle_chroot_sysctl(const int op);
23275 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
23276 +                                       const int niceval);
23277 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
23278 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
23279 +                                  const struct vfsmount *mnt);
23280 +extern void gr_handle_chroot_caps(struct task_struct *task);
23281 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
23282 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
23283 +                                 const struct vfsmount *mnt, const int mode);
23284 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
23285 +                                 const struct vfsmount *mnt, const int mode);
23286 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
23287 +                                 const struct vfsmount *mnt,
23288 +                                 const char *dev_name);
23289 +extern int gr_handle_chroot_pivot(void);
23290 +extern int gr_handle_chroot_unix(const pid_t pid);
23291 +
23292 +extern int gr_handle_rawio(const struct inode *inode);
23293 +extern int gr_handle_nproc(void);
23294 +
23295 +extern void gr_handle_ioperm(void);
23296 +extern void gr_handle_iopl(void);
23297 +
23298 +extern int gr_tpe_allow(const struct file *file);
23299 +
23300 +extern int gr_random_pid(void);
23301 +
23302 +extern void gr_log_forkfail(const int retval);
23303 +extern void gr_log_timechange(void);
23304 +extern void gr_log_signal(const int sig, const struct task_struct *t);
23305 +extern void gr_log_chdir(const struct dentry *dentry,
23306 +                        const struct vfsmount *mnt);
23307 +extern void gr_log_chroot_exec(const struct dentry *dentry,
23308 +                              const struct vfsmount *mnt);
23309 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
23310 +extern void gr_log_remount(const char *devname, const int retval);
23311 +extern void gr_log_unmount(const char *devname, const int retval);
23312 +extern void gr_log_mount(const char *from, const char *to, const int retval);
23313 +extern void gr_log_msgget(const int ret, const int msgflg);
23314 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
23315 +extern void gr_log_semget(const int err, const int semflg);
23316 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
23317 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
23318 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
23319 +extern void gr_log_textrel(struct vm_area_struct *vma);
23320 +
23321 +extern int gr_handle_follow_link(const struct inode *parent,
23322 +                                const struct inode *inode,
23323 +                                const struct dentry *dentry,
23324 +                                const struct vfsmount *mnt);
23325 +extern int gr_handle_fifo(const struct dentry *dentry,
23326 +                         const struct vfsmount *mnt,
23327 +                         const struct dentry *dir, const int flag,
23328 +                         const int acc_mode);
23329 +extern int gr_handle_hardlink(const struct dentry *dentry,
23330 +                             const struct vfsmount *mnt,
23331 +                             struct inode *inode,
23332 +                             const int mode, const char *to);
23333 +
23334 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
23335 +extern int gr_is_capable_nolog(const int cap);
23336 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
23337 +                             const unsigned long wanted, const int gt);
23338 +extern void gr_copy_label(struct task_struct *tsk);
23339 +extern void gr_handle_crash(struct task_struct *task, const int sig);
23340 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
23341 +extern int gr_check_crash_uid(const uid_t uid);
23342 +extern int gr_check_protected_task(const struct task_struct *task);
23343 +extern int gr_acl_handle_mmap(const struct file *file,
23344 +                             const unsigned long prot);
23345 +extern int gr_acl_handle_mprotect(const struct file *file,
23346 +                                 const unsigned long prot);
23347 +extern int gr_check_hidden_task(const struct task_struct *tsk);
23348 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
23349 +                                   const struct vfsmount *mnt);
23350 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
23351 +                                const struct vfsmount *mnt);
23352 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
23353 +                                 const struct vfsmount *mnt, const int fmode);
23354 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
23355 +                                 const struct vfsmount *mnt, mode_t mode);
23356 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
23357 +                                const struct vfsmount *mnt, mode_t mode);
23358 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
23359 +                                const struct vfsmount *mnt);
23360 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
23361 +extern int gr_handle_proc_ptrace(struct task_struct *task);
23362 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
23363 +                                 const struct vfsmount *mnt);
23364 +extern int gr_check_crash_exec(const struct file *filp);
23365 +extern int gr_acl_is_enabled(void);
23366 +extern void gr_set_kernel_label(struct task_struct *task);
23367 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
23368 +                             const gid_t gid);
23369 +extern int gr_set_proc_label(const struct dentry *dentry,
23370 +                             const struct vfsmount *mnt);
23371 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
23372 +                                      const struct vfsmount *mnt);
23373 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
23374 +                               const struct vfsmount *mnt, const int fmode);
23375 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
23376 +                                const struct dentry *p_dentry,
23377 +                                const struct vfsmount *p_mnt, const int fmode,
23378 +                                const int imode);
23379 +extern void gr_handle_create(const struct dentry *dentry,
23380 +                            const struct vfsmount *mnt);
23381 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
23382 +                                const struct dentry *parent_dentry,
23383 +                                const struct vfsmount *parent_mnt,
23384 +                                const int mode);
23385 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
23386 +                                const struct dentry *parent_dentry,
23387 +                                const struct vfsmount *parent_mnt);
23388 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
23389 +                                const struct vfsmount *mnt);
23390 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
23391 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
23392 +                                 const struct vfsmount *mnt);
23393 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
23394 +                                  const struct dentry *parent_dentry,
23395 +                                  const struct vfsmount *parent_mnt,
23396 +                                  const char *from);
23397 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
23398 +                               const struct dentry *parent_dentry,
23399 +                               const struct vfsmount *parent_mnt,
23400 +                               const struct dentry *old_dentry,
23401 +                               const struct vfsmount *old_mnt, const char *to);
23402 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
23403 +                               struct dentry *parent_dentry,
23404 +                               const struct vfsmount *parent_mnt,
23405 +                               struct dentry *old_dentry,
23406 +                               struct inode *old_parent_inode,
23407 +                               struct vfsmount *old_mnt, const char *newname);
23408 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
23409 +                               struct dentry *old_dentry,
23410 +                               struct dentry *new_dentry,
23411 +                               struct vfsmount *mnt, const __u8 replace);
23412 +extern __u32 gr_check_link(const struct dentry *new_dentry,
23413 +                          const struct dentry *parent_dentry,
23414 +                          const struct vfsmount *parent_mnt,
23415 +                          const struct dentry *old_dentry,
23416 +                          const struct vfsmount *old_mnt);
23417 +extern int gr_acl_handle_filldir(const struct file *file, const char *name,
23418 +                                const unsigned int namelen, const ino_t ino);
23419 +
23420 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
23421 +                               const struct vfsmount *mnt);
23422 +extern void gr_acl_handle_exit(void);
23423 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
23424 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
23425 +extern __u32 gr_cap_rtnetlink(void);
23426 +
23427 +#ifdef CONFIG_SYSVIPC
23428 +extern void gr_shm_exit(struct task_struct *task);
23429 +#else
23430 +static inline void gr_shm_exit(struct task_struct *task)
23431 +{
23432 +       return;
23433 +}
23434 +#endif
23435 +
23436 +#ifdef CONFIG_GRKERNSEC
23437 +extern void gr_handle_mem_write(void);
23438 +extern void gr_handle_kmem_write(void);
23439 +extern void gr_handle_open_port(void);
23440 +extern int gr_handle_mem_mmap(const unsigned long offset,
23441 +                             struct vm_area_struct *vma);
23442 +
23443 +extern unsigned long pax_get_random_long(void);
23444 +#define get_random_long() pax_get_random_long()
23445 +
23446 +extern int grsec_enable_dmesg;
23447 +extern int grsec_enable_randsrc;
23448 +extern int grsec_enable_shm;
23449 +#endif
23450 +
23451 +#endif
23452 diff -urNp linux-2.6.18/include/linux/highmem.h linux-2.6.18/include/linux/highmem.h
23453 --- linux-2.6.18/include/linux/highmem.h        2006-09-19 23:42:06.000000000 -0400
23454 +++ linux-2.6.18/include/linux/highmem.h        2006-09-22 20:45:04.000000000 -0400
23455 @@ -69,9 +69,9 @@ alloc_zeroed_user_highpage(struct vm_are
23456  
23457  static inline void clear_highpage(struct page *page)
23458  {
23459 -       void *kaddr = kmap_atomic(page, KM_USER0);
23460 +       void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
23461         clear_page(kaddr);
23462 -       kunmap_atomic(kaddr, KM_USER0);
23463 +       kunmap_atomic(kaddr, KM_CLEARPAGE);
23464  }
23465  
23466  /*
23467 diff -urNp linux-2.6.18/include/linux/jbd.h linux-2.6.18/include/linux/jbd.h
23468 --- linux-2.6.18/include/linux/jbd.h    2006-09-19 23:42:06.000000000 -0400
23469 +++ linux-2.6.18/include/linux/jbd.h    2006-09-22 20:45:04.000000000 -0400
23470 @@ -68,7 +68,7 @@ extern int journal_enable_debug;
23471                 }                                                       \
23472         } while (0)
23473  #else
23474 -#define jbd_debug(f, a...)     /**/
23475 +#define jbd_debug(f, a...)     do {} while (0)
23476  #endif
23477  
23478  extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
23479 diff -urNp linux-2.6.18/include/linux/mman.h linux-2.6.18/include/linux/mman.h
23480 --- linux-2.6.18/include/linux/mman.h   2006-09-19 23:42:06.000000000 -0400
23481 +++ linux-2.6.18/include/linux/mman.h   2006-09-22 20:45:04.000000000 -0400
23482 @@ -61,6 +61,11 @@ static inline unsigned long
23483  calc_vm_flag_bits(unsigned long flags)
23484  {
23485         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
23486 +
23487 +#ifdef CONFIG_PAX_SEGMEXEC
23488 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
23489 +#endif
23490 +
23491                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
23492                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
23493                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
23494 diff -urNp linux-2.6.18/include/linux/mm.h linux-2.6.18/include/linux/mm.h
23495 --- linux-2.6.18/include/linux/mm.h     2006-09-19 23:42:06.000000000 -0400
23496 +++ linux-2.6.18/include/linux/mm.h     2006-09-22 20:45:04.000000000 -0400
23497 @@ -37,6 +37,7 @@ extern int sysctl_legacy_va_layout;
23498  #include <asm/page.h>
23499  #include <asm/pgtable.h>
23500  #include <asm/processor.h>
23501 +#include <asm/mman.h>
23502  
23503  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
23504  
23505 @@ -110,8 +111,43 @@ struct vm_area_struct {
23506  #ifdef CONFIG_NUMA
23507         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
23508  #endif
23509 +
23510 +       unsigned long vm_mirror;        /* PaX: mirror distance */
23511  };
23512  
23513 +#ifdef CONFIG_PAX_SOFTMODE
23514 +extern unsigned int pax_softmode;
23515 +#endif
23516 +
23517 +extern int pax_check_flags(unsigned long *);
23518 +
23519 +/* if tsk != current then task_lock must be held on it */
23520 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
23521 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
23522 +{
23523 +       if (likely(tsk->mm))
23524 +               return tsk->mm->pax_flags;
23525 +       else
23526 +               return 0UL;
23527 +}
23528 +
23529 +/* if tsk != current then task_lock must be held on it */
23530 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
23531 +{
23532 +       if (likely(tsk->mm)) {
23533 +               tsk->mm->pax_flags = flags;
23534 +               return 0;
23535 +       }
23536 +       return -EINVAL;
23537 +}
23538 +#endif
23539 +
23540 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23541 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
23542 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
23543 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
23544 +#endif
23545 +
23546  /*
23547   * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
23548   * disabled, then there's a single shared list of VMAs maintained by the
23549 @@ -165,6 +201,18 @@ extern unsigned int kobjsize(const void 
23550  #define VM_MAPPED_COPY 0x01000000      /* T if mapped copy of data (nommu mmap) */
23551  #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
23552  
23553 +#ifdef CONFIG_PAX_SEGMEXEC
23554 +#define VM_MIRROR      0x04000000      /* vma is mirroring another */
23555 +#endif
23556 +
23557 +#ifdef CONFIG_PAX_MPROTECT
23558 +#define VM_MAYNOTWRITE 0x08000000      /* vma cannot be granted VM_WRITE any more */
23559 +#endif
23560 +
23561 +#ifdef __VM_STACK_FLAGS
23562 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
23563 +#endif
23564 +
23565  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
23566  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
23567  #endif
23568 @@ -1073,5 +1121,11 @@ extern int randomize_va_space;
23569  
23570  const char *arch_vma_name(struct vm_area_struct *vma);
23571  
23572 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
23573 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
23574 +#else
23575 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
23576 +#endif
23577 +
23578  #endif /* __KERNEL__ */
23579  #endif /* _LINUX_MM_H */
23580 diff -urNp linux-2.6.18/include/linux/module.h linux-2.6.18/include/linux/module.h
23581 --- linux-2.6.18/include/linux/module.h 2006-09-19 23:42:06.000000000 -0400
23582 +++ linux-2.6.18/include/linux/module.h 2006-09-22 20:45:04.000000000 -0400
23583 @@ -292,16 +292,16 @@ struct module
23584         int (*init)(void);
23585  
23586         /* If this is non-NULL, vfree after init() returns */
23587 -       void *module_init;
23588 +       void *module_init_rx, *module_init_rw;
23589  
23590         /* Here is the actual code + data, vfree'd on unload. */
23591 -       void *module_core;
23592 +       void *module_core_rx, *module_core_rw;
23593  
23594         /* Here are the sizes of the init and core sections */
23595 -       unsigned long init_size, core_size;
23596 +       unsigned long init_size_rw, core_size_rw;
23597  
23598         /* The size of the executable code in each section.  */
23599 -       unsigned long init_text_size, core_text_size;
23600 +       unsigned long init_size_rx, core_size_rx;
23601  
23602         /* The handle returned from unwind_add_table. */
23603         void *unwind_info;
23604 diff -urNp linux-2.6.18/include/linux/moduleloader.h linux-2.6.18/include/linux/moduleloader.h
23605 --- linux-2.6.18/include/linux/moduleloader.h   2006-09-19 23:42:06.000000000 -0400
23606 +++ linux-2.6.18/include/linux/moduleloader.h   2006-09-22 20:45:04.000000000 -0400
23607 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
23608     sections.  Returns NULL on failure. */
23609  void *module_alloc(unsigned long size);
23610  
23611 +#ifdef CONFIG_PAX_KERNEXEC
23612 +void *module_alloc_exec(unsigned long size);
23613 +#else
23614 +#define module_alloc_exec(x) module_alloc(x)
23615 +#endif
23616 +
23617  /* Free memory returned from module_alloc. */
23618  void module_free(struct module *mod, void *module_region);
23619  
23620 +#ifdef CONFIG_PAX_KERNEXEC
23621 +void module_free_exec(struct module *mod, void *module_region);
23622 +#else
23623 +#define module_free_exec(x, y) module_free(x, y)
23624 +#endif
23625 +
23626  /* Apply the given relocation to the (simplified) ELF.  Return -error
23627     or 0. */
23628  int apply_relocate(Elf_Shdr *sechdrs,
23629 diff -urNp linux-2.6.18/include/linux/random.h linux-2.6.18/include/linux/random.h
23630 --- linux-2.6.18/include/linux/random.h 2006-09-19 23:42:06.000000000 -0400
23631 +++ linux-2.6.18/include/linux/random.h 2006-09-22 20:45:04.000000000 -0400
23632 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
23633  extern u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
23634                                        __u16 sport, __u16 dport);
23635  
23636 +extern unsigned long pax_get_random_long(void);
23637 +
23638  #ifndef MODULE
23639  extern struct file_operations random_fops, urandom_fops;
23640  #endif
23641 diff -urNp linux-2.6.18/include/linux/sched.h linux-2.6.18/include/linux/sched.h
23642 --- linux-2.6.18/include/linux/sched.h  2006-09-19 23:42:06.000000000 -0400
23643 +++ linux-2.6.18/include/linux/sched.h  2006-09-22 20:45:04.000000000 -0400
23644 @@ -85,6 +85,7 @@ struct sched_param {
23645  
23646  struct exec_domain;
23647  struct futex_pi_state;
23648 +struct linux_binprm;
23649  
23650  /*
23651   * List of flags we want to share for kernel threads,
23652 @@ -353,8 +354,34 @@ struct mm_struct {
23653         /* aio bits */
23654         rwlock_t                ioctx_list_lock;
23655         struct kioctx           *ioctx_list;
23656 +
23657 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
23658 +       unsigned long pax_flags;
23659 +#endif
23660 +
23661 +#ifdef CONFIG_PAX_DLRESOLVE
23662 +       unsigned long call_dl_resolve;
23663 +#endif
23664 +
23665 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
23666 +       unsigned long call_syscall;
23667 +#endif
23668 +
23669 +#ifdef CONFIG_PAX_ASLR
23670 +       unsigned long delta_mmap;               /* randomized offset */
23671 +       unsigned long delta_exec;               /* randomized offset */
23672 +       unsigned long delta_stack;              /* randomized offset */
23673 +#endif
23674 +
23675  };
23676  
23677 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
23678 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
23679 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
23680 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
23681 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
23682 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
23683 +
23684  struct sighand_struct {
23685         atomic_t                count;
23686         struct k_sigaction      action[_NSIG];
23687 @@ -467,6 +494,15 @@ struct signal_struct {
23688         spinlock_t stats_lock;
23689         struct taskstats *stats;
23690  #endif
23691 +
23692 +#ifdef CONFIG_GRKERNSEC
23693 +       u32 curr_ip;
23694 +       u32 gr_saddr;
23695 +       u32 gr_daddr;
23696 +       u16 gr_sport;
23697 +       u16 gr_dport;
23698 +       u8 used_accept:1;
23699 +#endif
23700  };
23701  
23702  /* Context switch must be unlocked if interrupts are to be enabled */
23703 @@ -986,6 +1022,17 @@ struct task_struct {
23704         struct list_head pi_state_list;
23705         struct futex_pi_state *pi_state_cache;
23706  
23707 +#ifdef CONFIG_GRKERNSEC
23708 +       /* grsecurity */
23709 +       struct acl_subject_label *acl;
23710 +       struct acl_role_label *role;
23711 +       struct file *exec_file;
23712 +       u16 acl_role_id;
23713 +       u8 acl_sp_role:1;
23714 +       u8 is_writable:1;
23715 +       u8 brute:1;
23716 +#endif
23717 +
23718         atomic_t fs_excl;       /* holding fs exclusive resources */
23719         struct rcu_head rcu;
23720  
23721 @@ -1515,6 +1562,12 @@ extern void arch_pick_mmap_layout(struct
23722  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
23723  {
23724         mm->mmap_base = TASK_UNMAPPED_BASE;
23725 +
23726 +#ifdef CONFIG_PAX_RANDMMAP
23727 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
23728 +               mm->mmap_base += mm->delta_mmap;
23729 +#endif
23730 +
23731         mm->get_unmapped_area = arch_get_unmapped_area;
23732         mm->unmap_area = arch_unmap_area;
23733  }
23734 diff -urNp linux-2.6.18/include/linux/shm.h linux-2.6.18/include/linux/shm.h
23735 --- linux-2.6.18/include/linux/shm.h    2006-09-19 23:42:06.000000000 -0400
23736 +++ linux-2.6.18/include/linux/shm.h    2006-09-22 20:04:35.000000000 -0400
23737 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
23738         pid_t                   shm_cprid;
23739         pid_t                   shm_lprid;
23740         struct user_struct      *mlock_user;
23741 +#ifdef CONFIG_GRKERNSEC
23742 +       time_t                  shm_createtime;
23743 +       pid_t                   shm_lapid;
23744 +#endif
23745  };
23746  
23747  /* shm_mode upper byte flags */
23748 diff -urNp linux-2.6.18/include/linux/skbuff.h linux-2.6.18/include/linux/skbuff.h
23749 --- linux-2.6.18/include/linux/skbuff.h 2006-09-19 23:42:06.000000000 -0400
23750 +++ linux-2.6.18/include/linux/skbuff.h 2006-09-22 20:45:04.000000000 -0400
23751 @@ -371,7 +371,7 @@ extern void       skb_truesize_bug(struc
23752  
23753  static inline void skb_truesize_check(struct sk_buff *skb)
23754  {
23755 -       if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
23756 +       if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
23757                 skb_truesize_bug(skb);
23758  }
23759  
23760 diff -urNp linux-2.6.18/include/linux/sysctl.h linux-2.6.18/include/linux/sysctl.h
23761 --- linux-2.6.18/include/linux/sysctl.h 2006-09-19 23:42:06.000000000 -0400
23762 +++ linux-2.6.18/include/linux/sysctl.h 2006-09-22 20:45:04.000000000 -0400
23763 @@ -150,9 +150,21 @@ enum
23764         KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */
23765         KERN_COMPAT_LOG=73,     /* int: print compat layer  messages */
23766         KERN_MAX_LOCK_DEPTH=74,
23767 -};
23768 +#ifdef CONFIG_GRKERNSEC
23769 +       KERN_GRSECURITY=98,     /* grsecurity */
23770 +#endif
23771 +
23772 +#ifdef CONFIG_PAX_SOFTMODE
23773 +       KERN_PAX=99,            /* PaX control */
23774 +#endif
23775  
23776 +};
23777  
23778 +#ifdef CONFIG_PAX_SOFTMODE
23779 +enum {
23780 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
23781 +};
23782 +#endif
23783  
23784  /* CTL_VM names: */
23785  enum
23786 diff -urNp linux-2.6.18/include/linux/udf_fs.h linux-2.6.18/include/linux/udf_fs.h
23787 --- linux-2.6.18/include/linux/udf_fs.h 2006-09-19 23:42:06.000000000 -0400
23788 +++ linux-2.6.18/include/linux/udf_fs.h 2006-09-22 20:45:04.000000000 -0400
23789 @@ -45,7 +45,7 @@
23790                 printk (f, ##a); \
23791         }
23792  #else
23793 -#define udf_debug(f, a...) /**/
23794 +#define udf_debug(f, a...) do {} while (0)
23795  #endif
23796  
23797  #define udf_info(f, a...) \
23798 diff -urNp linux-2.6.18/include/net/sctp/sctp.h linux-2.6.18/include/net/sctp/sctp.h
23799 --- linux-2.6.18/include/net/sctp/sctp.h        2006-09-19 23:42:06.000000000 -0400
23800 +++ linux-2.6.18/include/net/sctp/sctp.h        2006-09-22 20:45:04.000000000 -0400
23801 @@ -250,8 +250,8 @@ extern int sctp_debug_flag;
23802  
23803  #else  /* SCTP_DEBUG */
23804  
23805 -#define SCTP_DEBUG_PRINTK(whatever...)
23806 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
23807 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
23808 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
23809  #define SCTP_ENABLE_DEBUG
23810  #define SCTP_DISABLE_DEBUG
23811  #define SCTP_ASSERT(expr, str, func)
23812 diff -urNp linux-2.6.18/include/sound/core.h linux-2.6.18/include/sound/core.h
23813 --- linux-2.6.18/include/sound/core.h   2006-09-19 23:42:06.000000000 -0400
23814 +++ linux-2.6.18/include/sound/core.h   2006-09-22 20:45:04.000000000 -0400
23815 @@ -349,9 +349,9 @@ void snd_verbose_printd(const char *file
23816  
23817  #else /* !CONFIG_SND_DEBUG */
23818  
23819 -#define snd_printd(fmt, args...)       /* nothing */
23820 +#define snd_printd(fmt, args...)       do {} while (0)
23821  #define snd_assert(expr, args...)      (void)(expr)
23822 -#define snd_BUG()                      /* nothing */
23823 +#define snd_BUG()                      do {} while (0)
23824  
23825  #endif /* CONFIG_SND_DEBUG */
23826  
23827 diff -urNp linux-2.6.18/init/Kconfig linux-2.6.18/init/Kconfig
23828 --- linux-2.6.18/init/Kconfig   2006-09-19 23:42:06.000000000 -0400
23829 +++ linux-2.6.18/init/Kconfig   2006-09-22 20:04:35.000000000 -0400
23830 @@ -292,6 +292,7 @@ config SYSCTL
23831  config KALLSYMS
23832          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
23833          default y
23834 +        depends on !GRKERNSEC_HIDESYM
23835          help
23836            Say Y here to let the kernel print out symbolic crash information and
23837            symbolic stack backtraces. This increases the size of the kernel
23838 diff -urNp linux-2.6.18/init/main.c linux-2.6.18/init/main.c
23839 --- linux-2.6.18/init/main.c    2006-09-19 23:42:06.000000000 -0400
23840 +++ linux-2.6.18/init/main.c    2006-09-22 20:45:04.000000000 -0400
23841 @@ -103,6 +103,7 @@ static inline void mark_rodata_ro(void) 
23842  #ifdef CONFIG_TC
23843  extern void tc_init(void);
23844  #endif
23845 +extern void grsecurity_init(void);
23846  
23847  enum system_states system_state;
23848  EXPORT_SYMBOL(system_state);
23849 @@ -153,6 +154,15 @@ static int __init maxcpus(char *str)
23850  
23851  __setup("maxcpus=", maxcpus);
23852  
23853 +#ifdef CONFIG_PAX_SOFTMODE
23854 +static int __init setup_pax_softmode(char *str)
23855 +{
23856 +       get_option(&str, &pax_softmode);
23857 +       return 1;
23858 +}
23859 +__setup("pax_softmode=", setup_pax_softmode);
23860 +#endif
23861 +
23862  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
23863  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
23864  static const char *panic_later, *panic_param;
23865 @@ -729,6 +739,8 @@ static int init(void * unused)
23866                 prepare_namespace();
23867         }
23868  
23869 +       grsecurity_init();
23870 +
23871         /*
23872          * Ok, we have completed the initial bootup, and
23873          * we're essentially up and running. Get rid of the
23874 diff -urNp linux-2.6.18/ipc/msg.c linux-2.6.18/ipc/msg.c
23875 --- linux-2.6.18/ipc/msg.c      2006-09-19 23:42:06.000000000 -0400
23876 +++ linux-2.6.18/ipc/msg.c      2006-09-22 20:08:16.000000000 -0400
23877 @@ -31,6 +31,7 @@
23878  #include <linux/audit.h>
23879  #include <linux/seq_file.h>
23880  #include <linux/mutex.h>
23881 +#include <linux/grsecurity.h>
23882  
23883  #include <asm/current.h>
23884  #include <asm/uaccess.h>
23885 @@ -239,6 +240,8 @@ asmlinkage long sys_msgget(key_t key, in
23886         }
23887         mutex_unlock(&msg_ids.mutex);
23888  
23889 +       gr_log_msgget(ret, msgflg);
23890 +
23891         return ret;
23892  }
23893  
23894 @@ -503,6 +506,7 @@ asmlinkage long sys_msgctl(int msqid, in
23895                 break;
23896         }
23897         case IPC_RMID:
23898 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
23899                 freeque(msq, msqid);
23900                 break;
23901         }
23902 diff -urNp linux-2.6.18/ipc/sem.c linux-2.6.18/ipc/sem.c
23903 --- linux-2.6.18/ipc/sem.c      2006-09-19 23:42:06.000000000 -0400
23904 +++ linux-2.6.18/ipc/sem.c      2006-09-22 20:04:35.000000000 -0400
23905 @@ -78,6 +78,7 @@
23906  #include <linux/capability.h>
23907  #include <linux/seq_file.h>
23908  #include <linux/mutex.h>
23909 +#include <linux/grsecurity.h>
23910  
23911  #include <asm/uaccess.h>
23912  #include "util.h"
23913 @@ -246,6 +247,9 @@ asmlinkage long sys_semget (key_t key, i
23914         }
23915  
23916         mutex_unlock(&sem_ids.mutex);
23917 +
23918 +       gr_log_semget(err, semflg);
23919 +
23920         return err;
23921  }
23922  
23923 @@ -844,6 +848,8 @@ static int semctl_down(int semid, int se
23924  
23925         switch(cmd){
23926         case IPC_RMID:
23927 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
23928 +
23929                 freeary(sma, semid);
23930                 err = 0;
23931                 break;
23932 diff -urNp linux-2.6.18/ipc/shm.c linux-2.6.18/ipc/shm.c
23933 --- linux-2.6.18/ipc/shm.c      2006-09-19 23:42:06.000000000 -0400
23934 +++ linux-2.6.18/ipc/shm.c      2006-09-22 20:04:35.000000000 -0400
23935 @@ -32,6 +32,7 @@
23936  #include <linux/ptrace.h>
23937  #include <linux/seq_file.h>
23938  #include <linux/mutex.h>
23939 +#include <linux/grsecurity.h>
23940  
23941  #include <asm/uaccess.h>
23942  
23943 @@ -55,6 +56,14 @@ static void shm_close (struct vm_area_st
23944  static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
23945  #endif
23946  
23947 +#ifdef CONFIG_GRKERNSEC
23948 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23949 +                          const time_t shm_createtime, const uid_t cuid,
23950 +                          const int shmid);
23951 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23952 +                          const time_t shm_createtime);
23953 +#endif
23954 +
23955  size_t shm_ctlmax = SHMMAX;
23956  size_t         shm_ctlall = SHMALL;
23957  int    shm_ctlmni = SHMMNI;
23958 @@ -148,6 +157,17 @@ static void shm_close (struct vm_area_st
23959         shp->shm_lprid = current->tgid;
23960         shp->shm_dtim = get_seconds();
23961         shp->shm_nattch--;
23962 +#ifdef CONFIG_GRKERNSEC_SHM
23963 +       if (grsec_enable_shm) {
23964 +               if (shp->shm_nattch == 0) {
23965 +                       shp->shm_perm.mode |= SHM_DEST;
23966 +                       shm_destroy(shp);
23967 +               } else
23968 +                       shm_unlock(shp);
23969 +               mutex_unlock(&shm_ids.mutex);
23970 +               return;
23971 +       }
23972 +#endif
23973         if(shp->shm_nattch == 0 &&
23974            shp->shm_perm.mode & SHM_DEST)
23975                 shm_destroy (shp);
23976 @@ -247,6 +267,9 @@ static int newseg (key_t key, int shmflg
23977         shp->shm_lprid = 0;
23978         shp->shm_atim = shp->shm_dtim = 0;
23979         shp->shm_ctim = get_seconds();
23980 +#ifdef CONFIG_GRKERNSEC
23981 +       shp->shm_createtime = get_seconds();
23982 +#endif
23983         shp->shm_segsz = size;
23984         shp->shm_nattch = 0;
23985         shp->id = shm_buildid(id,shp->shm_perm.seq);
23986 @@ -301,6 +324,8 @@ asmlinkage long sys_shmget (key_t key, s
23987         }
23988         mutex_unlock(&shm_ids.mutex);
23989  
23990 +       gr_log_shmget(err, shmflg, size);
23991 +
23992         return err;
23993  }
23994  
23995 @@ -614,6 +639,8 @@ asmlinkage long sys_shmctl (int shmid, i
23996                 if (err)
23997                         goto out_unlock_up;
23998  
23999 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
24000 +
24001                 if (shp->shm_nattch){
24002                         shp->shm_perm.mode |= SHM_DEST;
24003                         /* Do not find it any more */
24004 @@ -759,9 +786,27 @@ long do_shmat(int shmid, char __user *sh
24005                 return err;
24006         }
24007                 
24008 +#ifdef CONFIG_GRKERNSEC
24009 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
24010 +                            shp->shm_perm.cuid, shmid)) {
24011 +               shm_unlock(shp);
24012 +               return -EACCES;
24013 +       }
24014 +
24015 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
24016 +               shm_unlock(shp);
24017 +               return -EACCES;
24018 +       }
24019 +#endif
24020 +
24021         file = shp->shm_file;
24022         size = i_size_read(file->f_dentry->d_inode);
24023         shp->shm_nattch++;
24024 +
24025 +#ifdef CONFIG_GRKERNSEC
24026 +       shp->shm_lapid = current->pid;
24027 +#endif
24028 +
24029         shm_unlock(shp);
24030  
24031         down_write(&current->mm->mmap_sem);
24032 @@ -931,3 +976,24 @@ static int sysvipc_shm_proc_show(struct 
24033                           shp->shm_ctim);
24034  }
24035  #endif
24036 +
24037 +void gr_shm_exit(struct task_struct *task)
24038 +{
24039 +#ifdef CONFIG_GRKERNSEC_SHM
24040 +       int i;
24041 +       struct shmid_kernel *shp;
24042 +
24043 +       if (!grsec_enable_shm)
24044 +               return;
24045 +
24046 +       for (i = 0; i <= shm_ids.max_id; i++) {
24047 +               shp = shm_get(i);
24048 +               if (shp && (shp->shm_cprid == task->pid) &&
24049 +                   (shp->shm_nattch <= 0)) {
24050 +                       shp->shm_perm.mode |= SHM_DEST;
24051 +                       shm_destroy(shp);
24052 +               }
24053 +       }
24054 +#endif
24055 +       return;
24056 +}
24057 diff -urNp linux-2.6.18/kernel/capability.c linux-2.6.18/kernel/capability.c
24058 --- linux-2.6.18/kernel/capability.c    2006-09-19 23:42:06.000000000 -0400
24059 +++ linux-2.6.18/kernel/capability.c    2006-09-22 20:04:35.000000000 -0400
24060 @@ -12,6 +12,7 @@
24061  #include <linux/module.h>
24062  #include <linux/security.h>
24063  #include <linux/syscalls.h>
24064 +#include <linux/grsecurity.h>
24065  #include <asm/uaccess.h>
24066  
24067  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
24068 @@ -234,14 +235,25 @@ out:
24069       return ret;
24070  }
24071  
24072 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
24073 +extern int gr_is_capable_nolog(const int cap);
24074 +
24075  int __capable(struct task_struct *t, int cap)
24076  {
24077 -       if (security_capable(t, cap) == 0) {
24078 +       if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
24079                 t->flags |= PF_SUPERPRIV;
24080                 return 1;
24081         }
24082         return 0;
24083  }
24084 +int capable_nolog(int cap)
24085 +{
24086 +       if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
24087 +               current->flags |= PF_SUPERPRIV;
24088 +               return 1;
24089 +       }
24090 +       return 0;
24091 +}
24092  EXPORT_SYMBOL(__capable);
24093  
24094  int capable(int cap)
24095 @@ -249,3 +261,4 @@ int capable(int cap)
24096         return __capable(current, cap);
24097  }
24098  EXPORT_SYMBOL(capable);
24099 +EXPORT_SYMBOL(capable_nolog);
24100 diff -urNp linux-2.6.18/kernel/configs.c linux-2.6.18/kernel/configs.c
24101 --- linux-2.6.18/kernel/configs.c       2006-09-19 23:42:06.000000000 -0400
24102 +++ linux-2.6.18/kernel/configs.c       2006-09-22 20:04:35.000000000 -0400
24103 @@ -88,8 +88,16 @@ static int __init ikconfig_init(void)
24104         struct proc_dir_entry *entry;
24105  
24106         /* create the current config file */
24107 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
24108 +#ifdef CONFIG_GRKERNSEC_PROC_USER
24109 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
24110 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
24111 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
24112 +#endif
24113 +#else
24114         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
24115                                   &proc_root);
24116 +#endif
24117         if (!entry)
24118                 return -ENOMEM;
24119  
24120 diff -urNp linux-2.6.18/kernel/exit.c linux-2.6.18/kernel/exit.c
24121 --- linux-2.6.18/kernel/exit.c  2006-09-19 23:42:06.000000000 -0400
24122 +++ linux-2.6.18/kernel/exit.c  2006-09-22 20:21:45.000000000 -0400
24123 @@ -38,6 +38,11 @@
24124  #include <linux/pipe_fs_i.h>
24125  #include <linux/audit.h> /* for audit_free() */
24126  #include <linux/resource.h>
24127 +#include <linux/grsecurity.h>
24128 +
24129 +#ifdef CONFIG_GRKERNSEC
24130 +extern rwlock_t grsec_exec_file_lock;
24131 +#endif
24132  
24133  #include <asm/uaccess.h>
24134  #include <asm/unistd.h>
24135 @@ -115,6 +120,7 @@ static void __exit_signal(struct task_st
24136  
24137         __unhash_process(tsk);
24138  
24139 +       gr_del_task_from_ip_table(tsk);
24140         tsk->signal = NULL;
24141         tsk->sighand = NULL;
24142         spin_unlock(&sighand->siglock);
24143 @@ -282,6 +288,15 @@ static void reparent_to_init(void)
24144  {
24145         write_lock_irq(&tasklist_lock);
24146  
24147 +#ifdef CONFIG_GRKERNSEC
24148 +       write_lock(&grsec_exec_file_lock);
24149 +       if (current->exec_file) {
24150 +               fput(current->exec_file);
24151 +               current->exec_file = NULL;
24152 +       }
24153 +       write_unlock(&grsec_exec_file_lock);
24154 +#endif
24155 +
24156         ptrace_unlink(current);
24157         /* Reparent to init */
24158         remove_parent(current);
24159 @@ -289,6 +304,8 @@ static void reparent_to_init(void)
24160         current->real_parent = child_reaper;
24161         add_parent(current);
24162  
24163 +       gr_set_kernel_label(current);
24164 +
24165         /* Set the exit signal to SIGCHLD so we signal init on exit */
24166         current->exit_signal = SIGCHLD;
24167  
24168 @@ -385,6 +402,17 @@ void daemonize(const char *name, ...)
24169         vsnprintf(current->comm, sizeof(current->comm), name, args);
24170         va_end(args);
24171  
24172 +#ifdef CONFIG_GRKERNSEC
24173 +       write_lock(&grsec_exec_file_lock);
24174 +       if (current->exec_file) {
24175 +               fput(current->exec_file);
24176 +               current->exec_file = NULL;
24177 +       }
24178 +       write_unlock(&grsec_exec_file_lock);
24179 +#endif
24180 +
24181 +       gr_set_kernel_label(current);
24182 +
24183         /*
24184          * If we were started as result of loading a module, close all of the
24185          * user space pages.  We don't need them, and if we didn't close them
24186 @@ -909,11 +937,15 @@ fastcall NORET_TYPE void do_exit(long co
24187         taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
24188         taskstats_exit_free(tidstats);
24189  
24190 +       gr_acl_handle_psacct(tsk, code);
24191 +       gr_acl_handle_exit();
24192 +
24193         exit_mm(tsk);
24194  
24195         if (group_dead)
24196                 acct_process();
24197         exit_sem(tsk);
24198 +       gr_shm_exit(tsk);
24199         __exit_files(tsk);
24200         __exit_fs(tsk);
24201         exit_namespace(tsk);
24202 diff -urNp linux-2.6.18/kernel/fork.c linux-2.6.18/kernel/fork.c
24203 --- linux-2.6.18/kernel/fork.c  2006-09-19 23:42:06.000000000 -0400
24204 +++ linux-2.6.18/kernel/fork.c  2006-09-22 20:45:04.000000000 -0400
24205 @@ -45,6 +45,7 @@
24206  #include <linux/cn_proc.h>
24207  #include <linux/delayacct.h>
24208  #include <linux/taskstats_kern.h>
24209 +#include <linux/grsecurity.h>
24210  
24211  #include <asm/pgtable.h>
24212  #include <asm/pgalloc.h>
24213 @@ -202,8 +203,8 @@ static inline int dup_mmap(struct mm_str
24214         mm->locked_vm = 0;
24215         mm->mmap = NULL;
24216         mm->mmap_cache = NULL;
24217 -       mm->free_area_cache = oldmm->mmap_base;
24218 -       mm->cached_hole_size = ~0UL;
24219 +       mm->free_area_cache = oldmm->free_area_cache;
24220 +       mm->cached_hole_size = oldmm->cached_hole_size;
24221         mm->map_count = 0;
24222         cpus_clear(mm->cpu_vm_mask);
24223         mm->mm_rb = RB_ROOT;
24224 @@ -328,7 +329,7 @@ static struct mm_struct * mm_init(struct
24225         spin_lock_init(&mm->page_table_lock);
24226         rwlock_init(&mm->ioctx_list_lock);
24227         mm->ioctx_list = NULL;
24228 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
24229 +       mm->free_area_cache = ~0UL;
24230         mm->cached_hole_size = ~0UL;
24231  
24232         if (likely(!mm_alloc_pgd(mm))) {
24233 @@ -980,6 +981,9 @@ static struct task_struct *copy_process(
24234         DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
24235  #endif
24236         retval = -EAGAIN;
24237 +
24238 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
24239 +
24240         if (atomic_read(&p->user->processes) >=
24241                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
24242                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
24243 @@ -1110,6 +1114,8 @@ static struct task_struct *copy_process(
24244         if (retval)
24245                 goto bad_fork_cleanup_namespace;
24246  
24247 +       gr_copy_label(p);
24248 +
24249         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
24250         /*
24251          * Clear TID on mm_release()?
24252 @@ -1291,6 +1297,8 @@ bad_fork_cleanup_count:
24253  bad_fork_free:
24254         free_task(p);
24255  fork_out:
24256 +       gr_log_forkfail(retval);
24257 +
24258         return ERR_PTR(retval);
24259  }
24260  
24261 @@ -1364,6 +1372,8 @@ long do_fork(unsigned long clone_flags,
24262         if (!IS_ERR(p)) {
24263                 struct completion vfork;
24264  
24265 +               gr_handle_brute_check();
24266 +
24267                 if (clone_flags & CLONE_VFORK) {
24268                         p->vfork_done = &vfork;
24269                         init_completion(&vfork);
24270 diff -urNp linux-2.6.18/kernel/futex.c linux-2.6.18/kernel/futex.c
24271 --- linux-2.6.18/kernel/futex.c 2006-09-19 23:42:06.000000000 -0400
24272 +++ linux-2.6.18/kernel/futex.c 2006-09-22 20:45:04.000000000 -0400
24273 @@ -183,6 +183,11 @@ static int get_futex_key(u32 __user *uad
24274         struct page *page;
24275         int err;
24276  
24277 +#ifdef CONFIG_PAX_SEGMEXEC
24278 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((unsigned long)uaddr >= SEGMEXEC_TASK_SIZE))
24279 +               return -EFAULT;
24280 +#endif
24281 +
24282         /*
24283          * The futex address must be "naturally" aligned.
24284          */
24285 diff -urNp linux-2.6.18/kernel/kallsyms.c linux-2.6.18/kernel/kallsyms.c
24286 --- linux-2.6.18/kernel/kallsyms.c      2006-09-19 23:42:06.000000000 -0400
24287 +++ linux-2.6.18/kernel/kallsyms.c      2006-09-22 20:45:04.000000000 -0400
24288 @@ -301,7 +301,6 @@ static unsigned long get_ksymbol_core(st
24289  
24290  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
24291  {
24292 -       iter->name[0] = '\0';
24293         iter->nameoff = get_symbol_offset(new_pos);
24294         iter->pos = new_pos;
24295  }
24296 @@ -380,7 +379,7 @@ static int kallsyms_open(struct inode *i
24297         struct kallsym_iter *iter;
24298         int ret;
24299  
24300 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
24301 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
24302         if (!iter)
24303                 return -ENOMEM;
24304         reset_iter(iter, 0);
24305 @@ -411,7 +410,15 @@ static int __init kallsyms_init(void)
24306  {
24307         struct proc_dir_entry *entry;
24308  
24309 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
24310 +#ifdef CONFIG_GRKERNSEC_PROC_USER
24311 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
24312 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
24313 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
24314 +#endif
24315 +#else
24316         entry = create_proc_entry("kallsyms", 0444, NULL);
24317 +#endif
24318         if (entry)
24319                 entry->proc_fops = &kallsyms_operations;
24320         return 0;
24321 diff -urNp linux-2.6.18/kernel/kprobes.c linux-2.6.18/kernel/kprobes.c
24322 --- linux-2.6.18/kernel/kprobes.c       2006-09-19 23:42:06.000000000 -0400
24323 +++ linux-2.6.18/kernel/kprobes.c       2006-09-22 20:45:04.000000000 -0400
24324 @@ -112,7 +112,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
24325          * kernel image and loaded module images reside. This is required
24326          * so x86_64 can correctly handle the %rip-relative fixups.
24327          */
24328 -       kip->insns = module_alloc(PAGE_SIZE);
24329 +       kip->insns = module_alloc_exec(PAGE_SIZE);
24330         if (!kip->insns) {
24331                 kfree(kip);
24332                 return NULL;
24333 diff -urNp linux-2.6.18/kernel/module.c linux-2.6.18/kernel/module.c
24334 --- linux-2.6.18/kernel/module.c        2006-09-19 23:42:06.000000000 -0400
24335 +++ linux-2.6.18/kernel/module.c        2006-09-22 20:45:04.000000000 -0400
24336 @@ -43,6 +43,11 @@
24337  #include <asm/uaccess.h>
24338  #include <asm/semaphore.h>
24339  #include <asm/cacheflush.h>
24340 +
24341 +#ifdef CONFIG_PAX_KERNEXEC
24342 +#include <asm/desc.h>
24343 +#endif
24344 +
24345  #include <linux/license.h>
24346  
24347  #if 0
24348 @@ -67,6 +72,8 @@ static LIST_HEAD(modules);
24349  
24350  static BLOCKING_NOTIFIER_HEAD(module_notify_list);
24351  
24352 +extern int gr_check_modstop(void);
24353 +
24354  int register_module_notifier(struct notifier_block * nb)
24355  {
24356         return blocking_notifier_chain_register(&module_notify_list, nb);
24357 @@ -650,6 +657,9 @@ sys_delete_module(const char __user *nam
24358         char name[MODULE_NAME_LEN];
24359         int ret, forced = 0;
24360  
24361 +       if (gr_check_modstop())
24362 +               return -EPERM;
24363 +
24364         if (!capable(CAP_SYS_MODULE))
24365                 return -EPERM;
24366  
24367 @@ -1116,7 +1126,8 @@ static void free_module(struct module *m
24368         module_unload_free(mod);
24369  
24370         /* This may be NULL, but that's OK */
24371 -       module_free(mod, mod->module_init);
24372 +       module_free(mod, mod->module_init_rw);
24373 +       module_free_exec(mod, mod->module_init_rx);
24374         kfree(mod->args);
24375         if (mod->percpu)
24376                 percpu_modfree(mod->percpu);
24377 @@ -1125,7 +1136,8 @@ static void free_module(struct module *m
24378         lockdep_free_key_range(mod->module_core, mod->core_size);
24379  
24380         /* Finally, free the core (containing the module structure) */
24381 -       module_free(mod, mod->module_core);
24382 +       module_free_exec(mod, mod->module_core_rx);
24383 +       module_free(mod, mod->module_core_rw);
24384  }
24385  
24386  void *__symbol_get(const char *symbol)
24387 @@ -1282,11 +1294,14 @@ static void layout_sections(struct modul
24388                             || strncmp(secstrings + s->sh_name,
24389                                        ".init", 5) == 0)
24390                                 continue;
24391 -                       s->sh_entsize = get_offset(&mod->core_size, s);
24392 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
24393 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
24394 +                       else
24395 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
24396                         DEBUGP("\t%s\n", secstrings + s->sh_name);
24397                 }
24398                 if (m == 0)
24399 -                       mod->core_text_size = mod->core_size;
24400 +                       mod->core_size_rx = mod->core_size_rx;
24401         }
24402  
24403         DEBUGP("Init section allocation order:\n");
24404 @@ -1300,12 +1315,15 @@ static void layout_sections(struct modul
24405                             || strncmp(secstrings + s->sh_name,
24406                                        ".init", 5) != 0)
24407                                 continue;
24408 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
24409 -                                        | INIT_OFFSET_MASK);
24410 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
24411 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
24412 +                       else
24413 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
24414 +                       s->sh_entsize |= INIT_OFFSET_MASK;
24415                         DEBUGP("\t%s\n", secstrings + s->sh_name);
24416                 }
24417                 if (m == 0)
24418 -                       mod->init_text_size = mod->init_size;
24419 +                       mod->init_size_rx = mod->init_size_rx;
24420         }
24421  }
24422  
24423 @@ -1487,6 +1505,10 @@ static struct module *load_module(void _
24424         struct exception_table_entry *extable;
24425         mm_segment_t old_fs;
24426  
24427 +#ifdef CONFIG_PAX_KERNEXEC
24428 +       unsigned long cr0;
24429 +#endif
24430 +
24431         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
24432                umod, len, uargs);
24433         if (len < sizeof(*hdr))
24434 @@ -1645,21 +1667,57 @@ static struct module *load_module(void _
24435         layout_sections(mod, hdr, sechdrs, secstrings);
24436  
24437         /* Do the allocs. */
24438 -       ptr = module_alloc(mod->core_size);
24439 +       ptr = module_alloc(mod->core_size_rw);
24440         if (!ptr) {
24441                 err = -ENOMEM;
24442                 goto free_percpu;
24443         }
24444 -       memset(ptr, 0, mod->core_size);
24445 -       mod->module_core = ptr;
24446 +       memset(ptr, 0, mod->core_size_rw);
24447 +       mod->module_core_rw = ptr;
24448 +
24449 +       ptr = module_alloc(mod->init_size_rw);
24450 +       if (!ptr && mod->init_size_rw) {
24451 +               err = -ENOMEM;
24452 +               goto free_core_rw;
24453 +       }
24454 +       memset(ptr, 0, mod->init_size_rw);
24455 +       mod->module_init_rw = ptr;
24456 +
24457 +       ptr = module_alloc_exec(mod->core_size_rx);
24458 +       if (!ptr) {
24459 +               err = -ENOMEM;
24460 +               goto free_init_rw;
24461 +       }
24462  
24463 -       ptr = module_alloc(mod->init_size);
24464 -       if (!ptr && mod->init_size) {
24465 +#ifdef CONFIG_PAX_KERNEXEC
24466 +       pax_open_kernel(cr0);
24467 +#endif
24468 +
24469 +       memset(ptr, 0, mod->core_size_rx);
24470 +
24471 +#ifdef CONFIG_PAX_KERNEXEC
24472 +       pax_close_kernel(cr0);
24473 +#endif
24474 +
24475 +       mod->module_core_rx = ptr;
24476 +
24477 +       ptr = module_alloc_exec(mod->init_size_rx);
24478 +       if (!ptr && mod->init_size_rx) {
24479                 err = -ENOMEM;
24480 -               goto free_core;
24481 +               goto free_core_rx;
24482         }
24483 -       memset(ptr, 0, mod->init_size);
24484 -       mod->module_init = ptr;
24485 +
24486 +#ifdef CONFIG_PAX_KERNEXEC
24487 +       pax_open_kernel(cr0);
24488 +#endif
24489 +
24490 +       memset(ptr, 0, mod->init_size_rx);
24491 +
24492 +#ifdef CONFIG_PAX_KERNEXEC
24493 +       pax_close_kernel(cr0);
24494 +#endif
24495 +
24496 +       mod->module_init_rx = ptr;
24497  
24498         /* Transfer each section which specifies SHF_ALLOC */
24499         DEBUGP("final section addresses:\n");
24500 @@ -1669,17 +1727,44 @@ static struct module *load_module(void _
24501                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
24502                         continue;
24503  
24504 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
24505 -                       dest = mod->module_init
24506 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
24507 -               else
24508 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
24509 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
24510 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
24511 +                               dest = mod->module_init_rw
24512 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
24513 +                       else
24514 +                               dest = mod->module_init_rx
24515 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
24516 +               } else {
24517 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
24518 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
24519 +                       else
24520 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
24521 +               }
24522 +
24523 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
24524  
24525 -               if (sechdrs[i].sh_type != SHT_NOBITS)
24526 -                       memcpy(dest, (void *)sechdrs[i].sh_addr,
24527 -                              sechdrs[i].sh_size);
24528 +#ifdef CONFIG_PAX_KERNEXEC
24529 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
24530 +                               pax_open_kernel(cr0);
24531 +#endif
24532 +
24533 +                       memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
24534 +
24535 +#ifdef CONFIG_PAX_KERNEXEC
24536 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
24537 +                               pax_close_kernel(cr0);
24538 +#endif
24539 +
24540 +               }
24541                 /* Update sh_addr to point to copy in image. */
24542 -               sechdrs[i].sh_addr = (unsigned long)dest;
24543 +
24544 +#ifdef CONFIG_PAX_KERNEXEC
24545 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
24546 +                       sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
24547 +               else
24548 +#endif
24549 +
24550 +                       sechdrs[i].sh_addr = (unsigned long)dest;
24551                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
24552         }
24553         /* Module has been moved. */
24554 @@ -1700,8 +1785,18 @@ static struct module *load_module(void _
24555         setup_modinfo(mod, sechdrs, infoindex);
24556  
24557         /* Fix up syms, so that st_value is a pointer to location. */
24558 +
24559 +#ifdef CONFIG_PAX_KERNEXEC
24560 +       pax_open_kernel(cr0);
24561 +#endif
24562 +
24563         err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
24564                                mod);
24565 +
24566 +#ifdef CONFIG_PAX_KERNEXEC
24567 +       pax_close_kernel(cr0);
24568 +#endif
24569 +
24570         if (err < 0)
24571                 goto cleanup;
24572  
24573 @@ -1756,11 +1851,20 @@ static struct module *load_module(void _
24574                 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
24575                         continue;
24576  
24577 +#ifdef CONFIG_PAX_KERNEXEC
24578 +       pax_open_kernel(cr0);
24579 +#endif
24580 +
24581                 if (sechdrs[i].sh_type == SHT_REL)
24582                         err = apply_relocate(sechdrs, strtab, symindex, i,mod);
24583                 else if (sechdrs[i].sh_type == SHT_RELA)
24584                         err = apply_relocate_add(sechdrs, strtab, symindex, i,
24585                                                  mod);
24586 +
24587 +#ifdef CONFIG_PAX_KERNEXEC
24588 +       pax_close_kernel(cr0);
24589 +#endif
24590 +
24591                 if (err < 0)
24592                         goto cleanup;
24593         }
24594 @@ -1774,14 +1878,31 @@ static struct module *load_module(void _
24595         /* Set up and sort exception table */
24596         mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
24597         mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
24598 +
24599 +#ifdef CONFIG_PAX_KERNEXEC
24600 +       pax_open_kernel(cr0);
24601 +#endif
24602 +
24603         sort_extable(extable, extable + mod->num_exentries);
24604  
24605 +#ifdef CONFIG_PAX_KERNEXEC
24606 +       pax_close_kernel(cr0);
24607 +#endif
24608 +
24609         /* Finally, copy percpu area over. */
24610         percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
24611                        sechdrs[pcpuindex].sh_size);
24612  
24613 +#ifdef CONFIG_PAX_KERNEXEC
24614 +       pax_open_kernel(cr0);
24615 +#endif
24616 +
24617         add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
24618  
24619 +#ifdef CONFIG_PAX_KERNEXEC
24620 +       pax_close_kernel(cr0);
24621 +#endif
24622 +
24623         err = module_finalize(hdr, sechdrs, mod);
24624         if (err < 0)
24625                 goto cleanup;
24626 @@ -1795,12 +1916,12 @@ static struct module *load_module(void _
24627          * Do it before processing of module parameters, so the module
24628          * can provide parameter accessor functions of its own.
24629          */
24630 -       if (mod->module_init)
24631 -               flush_icache_range((unsigned long)mod->module_init,
24632 -                                  (unsigned long)mod->module_init
24633 -                                  + mod->init_size);
24634 -       flush_icache_range((unsigned long)mod->module_core,
24635 -                          (unsigned long)mod->module_core + mod->core_size);
24636 +       if (mod->module_init_rx)
24637 +               flush_icache_range((unsigned long)mod->module_init_rx,
24638 +                                  (unsigned long)mod->module_init_rx
24639 +                                  + mod->init_size_rx);
24640 +       flush_icache_range((unsigned long)mod->module_core_rx,
24641 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
24642  
24643         set_fs(old_fs);
24644  
24645 @@ -1843,9 +1964,13 @@ static struct module *load_module(void _
24646         module_arch_cleanup(mod);
24647   cleanup:
24648         module_unload_free(mod);
24649 -       module_free(mod, mod->module_init);
24650 - free_core:
24651 -       module_free(mod, mod->module_core);
24652 +       module_free_exec(mod, mod->module_init_rx);
24653 + free_core_rx:
24654 +       module_free_exec(mod, mod->module_core_rx);
24655 + free_init_rw:
24656 +       module_free(mod, mod->module_init_rw);
24657 + free_core_rw:
24658 +       module_free(mod, mod->module_core_rw);
24659   free_percpu:
24660         if (percpu)
24661                 percpu_modfree(percpu);
24662 @@ -1881,6 +2006,9 @@ sys_init_module(void __user *umod,
24663         struct module *mod;
24664         int ret = 0;
24665  
24666 +       if (gr_check_modstop())
24667 +               return -EPERM;
24668 +
24669         /* Must have permission */
24670         if (!capable(CAP_SYS_MODULE))
24671                 return -EPERM;
24672 @@ -1932,10 +2060,12 @@ sys_init_module(void __user *umod,
24673         /* Drop initial reference. */
24674         module_put(mod);
24675         unwind_remove_table(mod->unwind_info, 1);
24676 -       module_free(mod, mod->module_init);
24677 -       mod->module_init = NULL;
24678 -       mod->init_size = 0;
24679 -       mod->init_text_size = 0;
24680 +       module_free(mod, mod->module_init_rw);
24681 +       module_free_exec(mod, mod->module_init_rx);
24682 +       mod->module_init_rw = NULL;
24683 +       mod->module_init_rx = NULL;
24684 +       mod->init_size_rw = 0;
24685 +       mod->init_size_rx = 0;
24686         mutex_unlock(&module_mutex);
24687  
24688         return 0;
24689 @@ -1966,10 +2096,14 @@ static const char *get_ksymbol(struct mo
24690         unsigned long nextval;
24691  
24692         /* At worse, next value is at end of module */
24693 -       if (within(addr, mod->module_init, mod->init_size))
24694 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
24695 -       else 
24696 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
24697 +       if (within(addr, mod->module_init_rx, mod->init_size_rx))
24698 +               nextval = (unsigned long)mod->module_init_rw;
24699 +       else if (within(addr, mod->module_init_rw, mod->init_size_rw))
24700 +               nextval = (unsigned long)mod->module_core_rx;
24701 +       else if (within(addr, mod->module_core_rx, mod->core_size_rx))
24702 +               nextval = (unsigned long)mod->module_core_rw;
24703 +       else
24704 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
24705  
24706         /* Scan for closest preceeding symbol, and next symbol. (ELF
24707             starts real symbols at 1). */
24708 @@ -2010,8 +2144,10 @@ const char *module_address_lookup(unsign
24709         struct module *mod;
24710  
24711         list_for_each_entry(mod, &modules, list) {
24712 -               if (within(addr, mod->module_init, mod->init_size)
24713 -                   || within(addr, mod->module_core, mod->core_size)) {
24714 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
24715 +                   || within(addr, mod->module_init_rw, mod->init_size_rw)
24716 +                   || within(addr, mod->module_core_rx, mod->core_size_rx)
24717 +                   || within(addr, mod->module_core_rw, mod->core_size_rw)) {
24718                         *modname = mod->name;
24719                         return get_ksymbol(mod, addr, size, offset);
24720                 }
24721 @@ -2107,7 +2243,7 @@ static int m_show(struct seq_file *m, vo
24722  {
24723         struct module *mod = list_entry(p, struct module, list);
24724         seq_printf(m, "%s %lu",
24725 -                  mod->name, mod->init_size + mod->core_size);
24726 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
24727         print_unload_info(m, mod);
24728  
24729         /* Informative for users. */
24730 @@ -2116,7 +2252,7 @@ static int m_show(struct seq_file *m, vo
24731                    mod->state == MODULE_STATE_COMING ? "Loading":
24732                    "Live");
24733         /* Used by oprofile and other similar tools. */
24734 -       seq_printf(m, " 0x%p", mod->module_core);
24735 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
24736  
24737         seq_printf(m, "\n");
24738         return 0;
24739 @@ -2170,7 +2306,8 @@ int is_module_address(unsigned long addr
24740         spin_lock_irqsave(&modlist_lock, flags);
24741  
24742         list_for_each_entry(mod, &modules, list) {
24743 -               if (within(addr, mod->module_core, mod->core_size)) {
24744 +               if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
24745 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
24746                         spin_unlock_irqrestore(&modlist_lock, flags);
24747                         return 1;
24748                 }
24749 @@ -2188,8 +2325,8 @@ struct module *__module_text_address(uns
24750         struct module *mod;
24751  
24752         list_for_each_entry(mod, &modules, list)
24753 -               if (within(addr, mod->module_init, mod->init_text_size)
24754 -                   || within(addr, mod->module_core, mod->core_text_size))
24755 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
24756 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
24757                         return mod;
24758         return NULL;
24759  }
24760 diff -urNp linux-2.6.18/kernel/mutex.c linux-2.6.18/kernel/mutex.c
24761 --- linux-2.6.18/kernel/mutex.c 2006-09-19 23:42:06.000000000 -0400
24762 +++ linux-2.6.18/kernel/mutex.c 2006-09-22 20:45:04.000000000 -0400
24763 @@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
24764   *
24765   * This function is similar to (but not equivalent to) down().
24766   */
24767 -void inline fastcall __sched mutex_lock(struct mutex *lock)
24768 +inline void fastcall __sched mutex_lock(struct mutex *lock)
24769  {
24770         might_sleep();
24771         /*
24772 diff -urNp linux-2.6.18/kernel/pid.c linux-2.6.18/kernel/pid.c
24773 --- linux-2.6.18/kernel/pid.c   2006-09-19 23:42:06.000000000 -0400
24774 +++ linux-2.6.18/kernel/pid.c   2006-09-22 22:23:55.000000000 -0400
24775 @@ -26,6 +26,7 @@
24776  #include <linux/init.h>
24777  #include <linux/bootmem.h>
24778  #include <linux/hash.h>
24779 +#include <linux/grsecurity.h>
24780  
24781  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
24782  static struct hlist_head *pid_hash;
24783 @@ -90,7 +91,9 @@ static int alloc_pidmap(void)
24784         int i, offset, max_scan, pid, last = last_pid;
24785         pidmap_t *map;
24786  
24787 -       pid = last + 1;
24788 +       pid = gr_random_pid();
24789 +       if (!pid)
24790 +               pid = last_pid + 1;
24791         if (pid >= pid_max)
24792                 pid = RESERVED_PIDS;
24793         offset = pid & BITS_PER_PAGE_MASK;
24794 @@ -269,7 +272,14 @@ struct task_struct * fastcall pid_task(s
24795   */
24796  struct task_struct *find_task_by_pid_type(int type, int nr)
24797  {
24798 -       return pid_task(find_pid(nr), type);
24799 +       struct task_struct *task;
24800 +       
24801 +       task = pid_task(find_pid(nr), type);
24802 +
24803 +       if (gr_pid_is_chrooted(task))
24804 +               return NULL;
24805 +
24806 +       return task;
24807  }
24808  
24809  EXPORT_SYMBOL(find_task_by_pid_type);
24810 @@ -279,6 +289,8 @@ struct task_struct *fastcall get_pid_tas
24811         struct task_struct *result;
24812         rcu_read_lock();
24813         result = pid_task(pid, type);
24814 +       if (gr_pid_is_chrooted(result))
24815 +               result = NULL;
24816         if (result)
24817                 get_task_struct(result);
24818         rcu_read_unlock();
24819 diff -urNp linux-2.6.18/kernel/posix-cpu-timers.c linux-2.6.18/kernel/posix-cpu-timers.c
24820 --- linux-2.6.18/kernel/posix-cpu-timers.c      2006-09-19 23:42:06.000000000 -0400
24821 +++ linux-2.6.18/kernel/posix-cpu-timers.c      2006-09-22 20:04:35.000000000 -0400
24822 @@ -6,6 +6,7 @@
24823  #include <linux/posix-timers.h>
24824  #include <asm/uaccess.h>
24825  #include <linux/errno.h>
24826 +#include <linux/grsecurity.h>
24827  
24828  static int check_clock(const clockid_t which_clock)
24829  {
24830 @@ -1125,6 +1126,7 @@ static void check_process_timers(struct 
24831                         __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
24832                         return;
24833                 }
24834 +               gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
24835                 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
24836                         /*
24837                          * At the soft limit, send a SIGXCPU every second.
24838 diff -urNp linux-2.6.18/kernel/printk.c linux-2.6.18/kernel/printk.c
24839 --- linux-2.6.18/kernel/printk.c        2006-09-19 23:42:06.000000000 -0400
24840 +++ linux-2.6.18/kernel/printk.c        2006-09-22 20:04:35.000000000 -0400
24841 @@ -31,6 +31,7 @@
24842  #include <linux/security.h>
24843  #include <linux/bootmem.h>
24844  #include <linux/syscalls.h>
24845 +#include <linux/grsecurity.h>
24846  
24847  #include <asm/uaccess.h>
24848  
24849 @@ -186,6 +187,11 @@ int do_syslog(int type, char __user *buf
24850         char c;
24851         int error = 0;
24852  
24853 +#ifdef CONFIG_GRKERNSEC_DMESG
24854 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
24855 +               return -EPERM;
24856 +#endif
24857 +
24858         error = security_syslog(type);
24859         if (error)
24860                 return error;
24861 diff -urNp linux-2.6.18/kernel/ptrace.c linux-2.6.18/kernel/ptrace.c
24862 --- linux-2.6.18/kernel/ptrace.c        2006-09-19 23:42:06.000000000 -0400
24863 +++ linux-2.6.18/kernel/ptrace.c        2006-09-22 20:19:31.000000000 -0400
24864 @@ -18,6 +18,7 @@
24865  #include <linux/ptrace.h>
24866  #include <linux/security.h>
24867  #include <linux/signal.h>
24868 +#include <linux/grsecurity.h>
24869  
24870  #include <asm/pgtable.h>
24871  #include <asm/uaccess.h>
24872 @@ -137,12 +138,12 @@ static int may_attach(struct task_struct
24873              (current->uid != task->uid) ||
24874              (current->gid != task->egid) ||
24875              (current->gid != task->sgid) ||
24876 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
24877 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
24878                 return -EPERM;
24879         smp_rmb();
24880         if (task->mm)
24881                 dumpable = task->mm->dumpable;
24882 -       if (!dumpable && !capable(CAP_SYS_PTRACE))
24883 +       if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
24884                 return -EPERM;
24885  
24886         return security_ptrace(current, task);
24887 @@ -530,6 +531,11 @@ asmlinkage long sys_ptrace(long request,
24888         if (ret < 0)
24889                 goto out_put_task_struct;
24890  
24891 +       if (gr_handle_ptrace(child, request)) {
24892 +               ret = -EPERM;
24893 +               goto out_put_task_struct;
24894 +       }
24895 +
24896         ret = arch_ptrace(child, request, addr, data);
24897         if (ret < 0)
24898                 goto out_put_task_struct;
24899 diff -urNp linux-2.6.18/kernel/resource.c linux-2.6.18/kernel/resource.c
24900 --- linux-2.6.18/kernel/resource.c      2006-09-19 23:42:06.000000000 -0400
24901 +++ linux-2.6.18/kernel/resource.c      2006-09-22 20:04:35.000000000 -0400
24902 @@ -133,10 +133,27 @@ static int __init ioresources_init(void)
24903  {
24904         struct proc_dir_entry *entry;
24905  
24906 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
24907 +#ifdef CONFIG_GRKERNSEC_PROC_USER
24908 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
24909 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
24910 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
24911 +#endif
24912 +#else
24913         entry = create_proc_entry("ioports", 0, NULL);
24914 +#endif
24915         if (entry)
24916                 entry->proc_fops = &proc_ioports_operations;
24917 +
24918 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
24919 +#ifdef CONFIG_GRKERNSEC_PROC_USER
24920 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
24921 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
24922 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
24923 +#endif
24924 +#else
24925         entry = create_proc_entry("iomem", 0, NULL);
24926 +#endif
24927         if (entry)
24928                 entry->proc_fops = &proc_iomem_operations;
24929         return 0;
24930 diff -urNp linux-2.6.18/kernel/sched.c linux-2.6.18/kernel/sched.c
24931 --- linux-2.6.18/kernel/sched.c 2006-09-19 23:42:06.000000000 -0400
24932 +++ linux-2.6.18/kernel/sched.c 2006-09-22 20:18:35.000000000 -0400
24933 @@ -52,6 +52,7 @@
24934  #include <linux/acct.h>
24935  #include <linux/kprobes.h>
24936  #include <linux/delayacct.h>
24937 +#include <linux/grsecurity.h>
24938  #include <asm/tlb.h>
24939  
24940  #include <asm/unistd.h>
24941 @@ -3956,7 +3957,8 @@ asmlinkage long sys_nice(int increment)
24942         if (nice > 19)
24943                 nice = 19;
24944  
24945 -       if (increment < 0 && !can_nice(current, nice))
24946 +       if (increment < 0 && (!can_nice(current, nice) ||
24947 +                             gr_handle_chroot_nice()))
24948                 return -EPERM;
24949  
24950         retval = security_task_setnice(current, nice);
24951 diff -urNp linux-2.6.18/kernel/signal.c linux-2.6.18/kernel/signal.c
24952 --- linux-2.6.18/kernel/signal.c        2006-09-19 23:42:06.000000000 -0400
24953 +++ linux-2.6.18/kernel/signal.c        2006-09-22 20:25:59.000000000 -0400
24954 @@ -23,6 +23,7 @@
24955  #include <linux/ptrace.h>
24956  #include <linux/signal.h>
24957  #include <linux/capability.h>
24958 +#include <linux/grsecurity.h>
24959  #include <asm/param.h>
24960  #include <asm/uaccess.h>
24961  #include <asm/unistd.h>
24962 @@ -576,16 +577,18 @@ static int check_kill_permission(int sig
24963                 return error;
24964         error = -EPERM;
24965         if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
24966 -           && ((sig != SIGCONT) ||
24967 +           && ((((sig != SIGCONT) ||
24968                 (current->signal->session != t->signal->session))
24969             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
24970             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
24971 -           && !capable(CAP_KILL))
24972 +           && !capable(CAP_KILL)) || gr_handle_signal(t, sig)))
24973                 return error;
24974  
24975         error = security_task_kill(t, info, sig, 0);
24976 -       if (!error)
24977 +       if (!error) {
24978                 audit_signal_info(sig, t); /* Let audit system see the signal */
24979 +               gr_log_signal(sig, t);
24980 +       }
24981         return error;
24982  }
24983  
24984 @@ -763,7 +766,7 @@ out_set:
24985         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
24986  
24987  
24988 -static int
24989 +int
24990  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
24991  {
24992         int ret = 0;
24993 @@ -817,6 +820,10 @@ force_sig_info(int sig, struct siginfo *
24994                 }
24995         }
24996         ret = specific_send_sig_info(sig, info, t);
24997 +
24998 +       gr_log_signal(sig, t);
24999 +       gr_handle_crash(t, sig);
25000 +
25001         spin_unlock_irqrestore(&t->sighand->siglock, flags);
25002  
25003         return ret;
25004 diff -urNp linux-2.6.18/kernel/sys.c linux-2.6.18/kernel/sys.c
25005 --- linux-2.6.18/kernel/sys.c   2006-09-19 23:42:06.000000000 -0400
25006 +++ linux-2.6.18/kernel/sys.c   2006-09-22 20:45:04.000000000 -0400
25007 @@ -28,6 +28,7 @@
25008  #include <linux/tty.h>
25009  #include <linux/signal.h>
25010  #include <linux/cn_proc.h>
25011 +#include <linux/grsecurity.h>
25012  
25013  #include <linux/compat.h>
25014  #include <linux/syscalls.h>
25015 @@ -447,6 +448,12 @@ static int set_one_prio(struct task_stru
25016                 error = -EACCES;
25017                 goto out;
25018         }
25019 +
25020 +       if (gr_handle_chroot_setpriority(p, niceval)) {
25021 +               error = -EACCES;
25022 +               goto out;
25023 +       }
25024 +
25025         no_nice = security_task_setnice(p, niceval);
25026         if (no_nice) {
25027                 error = no_nice;
25028 @@ -835,6 +842,9 @@ asmlinkage long sys_setregid(gid_t rgid,
25029         if (rgid != (gid_t) -1 ||
25030             (egid != (gid_t) -1 && egid != old_rgid))
25031                 current->sgid = new_egid;
25032 +
25033 +       gr_set_role_label(current, current->uid, new_rgid);
25034 +
25035         current->fsgid = new_egid;
25036         current->egid = new_egid;
25037         current->gid = new_rgid;
25038 @@ -864,6 +874,9 @@ asmlinkage long sys_setgid(gid_t gid)
25039                         current->mm->dumpable = suid_dumpable;
25040                         smp_wmb();
25041                 }
25042 +
25043 +               gr_set_role_label(current, current->uid, gid);
25044 +
25045                 current->gid = current->egid = current->sgid = current->fsgid = gid;
25046         }
25047         else if ((gid == current->gid) || (gid == current->sgid))
25048 @@ -905,6 +918,9 @@ static int set_user(uid_t new_ruid, int 
25049                 current->mm->dumpable = suid_dumpable;
25050                 smp_wmb();
25051         }
25052 +
25053 +       gr_set_role_label(current, new_ruid, current->gid);
25054 +
25055         current->uid = new_ruid;
25056         return 0;
25057  }
25058 @@ -1008,6 +1024,9 @@ asmlinkage long sys_setuid(uid_t uid)
25059         } else if ((uid != current->uid) && (uid != new_suid))
25060                 return -EPERM;
25061  
25062 +       if (gr_check_crash_uid(uid))
25063 +               return -EPERM;
25064 +
25065         if (old_euid != uid)
25066         {
25067                 current->mm->dumpable = suid_dumpable;
25068 @@ -1113,8 +1132,10 @@ asmlinkage long sys_setresgid(gid_t rgid
25069                 current->egid = egid;
25070         }
25071         current->fsgid = current->egid;
25072 -       if (rgid != (gid_t) -1)
25073 +       if (rgid != (gid_t) -1) {
25074 +               gr_set_role_label(current, current->uid, rgid);
25075                 current->gid = rgid;
25076 +       }
25077         if (sgid != (gid_t) -1)
25078                 current->sgid = sgid;
25079  
25080 @@ -1983,7 +2004,7 @@ asmlinkage long sys_prctl(int option, un
25081                         error = current->mm->dumpable;
25082                         break;
25083                 case PR_SET_DUMPABLE:
25084 -                       if (arg2 < 0 || arg2 > 1) {
25085 +                       if (arg2 > 1) {
25086                                 error = -EINVAL;
25087                                 break;
25088                         }
25089 diff -urNp linux-2.6.18/kernel/sysctl.c linux-2.6.18/kernel/sysctl.c
25090 --- linux-2.6.18/kernel/sysctl.c        2006-09-19 23:42:06.000000000 -0400
25091 +++ linux-2.6.18/kernel/sysctl.c        2006-09-23 00:26:32.000000000 -0400
25092 @@ -53,6 +53,14 @@ extern int proc_nr_files(ctl_table *tabl
25093                       void __user *buffer, size_t *lenp, loff_t *ppos);
25094  
25095  #if defined(CONFIG_SYSCTL)
25096 +#include <linux/grsecurity.h>
25097 +#include <linux/grinternal.h>
25098 +
25099 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
25100 +                             const void *newval);
25101 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
25102 +                               const int op);
25103 +extern int gr_handle_chroot_sysctl(const int op);
25104  
25105  /* External variables not in a header file. */
25106  extern int C_A_D;
25107 @@ -161,6 +169,22 @@ extern ctl_table inotify_table[];
25108  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
25109  int sysctl_legacy_va_layout;
25110  #endif
25111 +extern ctl_table grsecurity_table[];
25112 +
25113 +#ifdef CONFIG_PAX_SOFTMODE
25114 +static ctl_table pax_table[] = {
25115 +       {
25116 +               .ctl_name       = PAX_SOFTMODE,
25117 +               .procname       = "softmode",
25118 +               .data           = &pax_softmode,
25119 +               .maxlen         = sizeof(unsigned int),
25120 +               .mode           = 0600,
25121 +               .proc_handler   = &proc_dointvec,
25122 +       },
25123 +
25124 +       { .ctl_name = 0 }
25125 +};
25126 +#endif
25127  
25128  /* /proc declarations: */
25129  
25130 @@ -702,6 +726,24 @@ static ctl_table kern_table[] = {
25131         },
25132  #endif
25133  
25134 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
25135 +       {
25136 +               .ctl_name       = KERN_GRSECURITY,
25137 +               .procname       = "grsecurity",
25138 +               .mode           = 0500,
25139 +               .child          = grsecurity_table,
25140 +       },
25141 +#endif
25142 +
25143 +#ifdef CONFIG_PAX_SOFTMODE
25144 +       {
25145 +               .ctl_name       = KERN_PAX,
25146 +               .procname       = "pax",
25147 +               .mode           = 0500,
25148 +               .child          = pax_table,
25149 +       },
25150 +#endif
25151 +
25152         { .ctl_name = 0 }
25153  };
25154  
25155 @@ -1217,6 +1259,10 @@ static int test_perm(int mode, int op)
25156  static inline int ctl_perm(ctl_table *table, int op)
25157  {
25158         int error;
25159 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
25160 +               return -EACCES;
25161 +       if (gr_handle_chroot_sysctl(op))
25162 +               return -EACCES;
25163         error = security_sysctl(table, op);
25164         if (error)
25165                 return error;
25166 @@ -1253,6 +1299,10 @@ repeat:
25167                                 table = table->child;
25168                                 goto repeat;
25169                         }
25170 +
25171 +                       if (!gr_handle_sysctl(table, oldval, newval))
25172 +                               return -EPERM;
25173 +
25174                         error = do_sysctl_strategy(table, name, nlen,
25175                                                    oldval, oldlenp,
25176                                                    newval, newlen, context);
25177 diff -urNp linux-2.6.18/kernel/time.c linux-2.6.18/kernel/time.c
25178 --- linux-2.6.18/kernel/time.c  2006-09-19 23:42:06.000000000 -0400
25179 +++ linux-2.6.18/kernel/time.c  2006-09-22 20:04:35.000000000 -0400
25180 @@ -36,6 +36,7 @@
25181  #include <linux/security.h>
25182  #include <linux/fs.h>
25183  #include <linux/module.h>
25184 +#include <linux/grsecurity.h>
25185  
25186  #include <asm/uaccess.h>
25187  #include <asm/unistd.h>
25188 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user 
25189                 return err;
25190  
25191         do_settimeofday(&tv);
25192 +
25193 +       gr_log_timechange();
25194 +
25195         return 0;
25196  }
25197  
25198 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct 
25199                         return -EFAULT;
25200         }
25201  
25202 +       gr_log_timechange();
25203 +
25204         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
25205  }
25206  
25207 diff -urNp linux-2.6.18/kernel/unwind.c linux-2.6.18/kernel/unwind.c
25208 --- linux-2.6.18/kernel/unwind.c        2006-09-19 23:42:06.000000000 -0400
25209 +++ linux-2.6.18/kernel/unwind.c        2006-09-22 20:45:04.000000000 -0400
25210 @@ -189,8 +189,8 @@ void *unwind_add_table(struct module *mo
25211                 return NULL;
25212  
25213         init_unwind_table(table, module->name,
25214 -                         module->module_core, module->core_size,
25215 -                         module->module_init, module->init_size,
25216 +                         module->module_core_rx, module->core_size_rx,
25217 +                         module->module_init_rx, module->init_size_rx,
25218                           table_start, table_size);
25219  
25220         if (last_table)
25221 diff -urNp linux-2.6.18/localversion-grsec linux-2.6.18/localversion-grsec
25222 --- linux-2.6.18/localversion-grsec     1969-12-31 19:00:00.000000000 -0500
25223 +++ linux-2.6.18/localversion-grsec     2006-09-22 20:04:35.000000000 -0400
25224 @@ -0,0 +1 @@
25225 +-grsec
25226 diff -urNp linux-2.6.18/Makefile linux-2.6.18/Makefile
25227 --- linux-2.6.18/Makefile       2006-09-19 23:42:06.000000000 -0400
25228 +++ linux-2.6.18/Makefile       2006-09-22 20:45:03.000000000 -0400
25229 @@ -307,7 +307,7 @@ LINUXINCLUDE    := -Iinclude \
25230  
25231  CPPFLAGS        := -D__KERNEL__ $(LINUXINCLUDE)
25232  
25233 -CFLAGS          := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
25234 +CFLAGS          := -Wall -Wextra -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
25235                     -fno-strict-aliasing -fno-common
25236  AFLAGS          := -D__ASSEMBLY__
25237  
25238 @@ -552,7 +552,7 @@ export mod_strip_cmd
25239  
25240  
25241  ifeq ($(KBUILD_EXTMOD),)
25242 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
25243 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
25244  
25245  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
25246                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
25247 diff -urNp linux-2.6.18/mm/filemap.c linux-2.6.18/mm/filemap.c
25248 --- linux-2.6.18/mm/filemap.c   2006-09-19 23:42:06.000000000 -0400
25249 +++ linux-2.6.18/mm/filemap.c   2006-09-22 20:45:04.000000000 -0400
25250 @@ -30,6 +30,7 @@
25251  #include <linux/security.h>
25252  #include <linux/syscalls.h>
25253  #include <linux/cpuset.h>
25254 +#include <linux/grsecurity.h>
25255  #include "filemap.h"
25256  #include "internal.h"
25257  
25258 @@ -1737,7 +1738,13 @@ int generic_file_mmap(struct file * file
25259         struct address_space *mapping = file->f_mapping;
25260  
25261         if (!mapping->a_ops->readpage)
25262 -               return -ENOEXEC;
25263 +               return -ENODEV;
25264 +
25265 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
25266 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
25267 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
25268 +#endif
25269 +
25270         file_accessed(file);
25271         vma->vm_ops = &generic_file_vm_ops;
25272         return 0;
25273 @@ -1960,6 +1967,7 @@ inline int generic_write_checks(struct f
25274                          *pos = i_size_read(inode);
25275  
25276                 if (limit != RLIM_INFINITY) {
25277 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
25278                         if (*pos >= limit) {
25279                                 send_sig(SIGXFSZ, current, 0);
25280                                 return -EFBIG;
25281 diff -urNp linux-2.6.18/mm/madvise.c linux-2.6.18/mm/madvise.c
25282 --- linux-2.6.18/mm/madvise.c   2006-09-19 23:42:06.000000000 -0400
25283 +++ linux-2.6.18/mm/madvise.c   2006-09-22 20:45:04.000000000 -0400
25284 @@ -15,9 +15,46 @@
25285   * We can potentially split a vm area into separate
25286   * areas, each area with its own behavior.
25287   */
25288 +
25289 +#ifdef CONFIG_PAX_SEGMEXEC
25290 +static long __madvise_behavior(struct vm_area_struct * vma,
25291 +                    struct vm_area_struct **prev,
25292 +                    unsigned long start, unsigned long end, int behavior);
25293 +
25294 +static long madvise_behavior(struct vm_area_struct * vma,
25295 +                    struct vm_area_struct **prev,
25296 +                    unsigned long start, unsigned long end, int behavior)
25297 +{
25298 +       if (vma->vm_flags & VM_MIRROR) {
25299 +               struct vm_area_struct * vma_m, * prev_m;
25300 +               unsigned long start_m, end_m;
25301 +               int error;
25302 +
25303 +               start_m = vma->vm_start + vma->vm_mirror;
25304 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
25305 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
25306 +                       start_m = start + vma->vm_mirror;
25307 +                       end_m = end + vma->vm_mirror;
25308 +                       error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
25309 +                       if (error)
25310 +                               return error;
25311 +               } else {
25312 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
25313 +                       return -ENOMEM;
25314 +               }
25315 +       }
25316 +
25317 +       return __madvise_behavior(vma, prev, start, end, behavior);
25318 +}
25319 +
25320 +static long __madvise_behavior(struct vm_area_struct * vma,
25321 +                    struct vm_area_struct **prev,
25322 +                    unsigned long start, unsigned long end, int behavior)
25323 +#else
25324  static long madvise_behavior(struct vm_area_struct * vma,
25325                      struct vm_area_struct **prev,
25326                      unsigned long start, unsigned long end, int behavior)
25327 +#endif
25328  {
25329         struct mm_struct * mm = vma->vm_mm;
25330         int error = 0;
25331 diff -urNp linux-2.6.18/mm/memory.c linux-2.6.18/mm/memory.c
25332 --- linux-2.6.18/mm/memory.c    2006-09-19 23:42:06.000000000 -0400
25333 +++ linux-2.6.18/mm/memory.c    2006-09-22 20:45:04.000000000 -0400
25334 @@ -49,6 +49,7 @@
25335  #include <linux/module.h>
25336  #include <linux/delayacct.h>
25337  #include <linux/init.h>
25338 +#include <linux/grsecurity.h>
25339  
25340  #include <asm/pgalloc.h>
25341  #include <asm/uaccess.h>
25342 @@ -321,6 +322,11 @@ int __pte_alloc(struct mm_struct *mm, pm
25343  
25344  int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
25345  {
25346 +
25347 +#ifdef CONFIG_PAX_KERNEXEC
25348 +       unsigned long cr0;
25349 +#endif
25350 +
25351         pte_t *new = pte_alloc_one_kernel(&init_mm, address);
25352         if (!new)
25353                 return -ENOMEM;
25354 @@ -328,8 +334,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
25355         spin_lock(&init_mm.page_table_lock);
25356         if (pmd_present(*pmd))          /* Another has populated it */
25357                 pte_free_kernel(new);
25358 -       else
25359 +       else {
25360 +
25361 +#ifdef CONFIG_PAX_KERNEXEC
25362 +               pax_open_kernel(cr0);
25363 +#endif
25364 +
25365                 pmd_populate_kernel(&init_mm, pmd, new);
25366 +
25367 +#ifdef CONFIG_PAX_KERNEXEC
25368 +               pax_close_kernel(cr0);
25369 +#endif
25370 +
25371 +       }
25372         spin_unlock(&init_mm.page_table_lock);
25373         return 0;
25374  }
25375 @@ -1434,6 +1451,88 @@ static inline void cow_user_page(struct 
25376         copy_user_highpage(dst, src, va);
25377  }
25378  
25379 +#ifdef CONFIG_PAX_SEGMEXEC
25380 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
25381 + *
25382 + * the ptl of the lower mapped page is held on entry and is not released on exit
25383 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
25384 + */
25385 +static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
25386 +{
25387 +       struct mm_struct *mm = vma->vm_mm;
25388 +       unsigned long address_m, pfn_m;
25389 +       struct vm_area_struct * vma_m = NULL;
25390 +       pte_t * pte_m, entry_m;
25391 +       struct page * page_m = NULL;
25392 +
25393 +       address_m = vma->vm_start + vma->vm_mirror;
25394 +       vma_m = find_vma(mm, address_m);
25395 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
25396 +
25397 +       address_m = address + vma->vm_mirror;
25398 +       pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
25399 +
25400 +       if (pte_same(*pte, *pte_m)) {
25401 +               pte_unmap_nested(pte_m);
25402 +               return;
25403 +       }
25404 +
25405 +       pfn_m = pte_pfn(*pte);
25406 +       if (pte_present(*pte_m)) {
25407 +               page_m = vm_normal_page(vma_m, address_m, *pte_m);
25408 +               if (page_m) {
25409 +                       flush_cache_page(vma_m, address_m, pfn_m);
25410 +                       flush_icache_page(vma_m, page_m);
25411 +               }
25412 +       }
25413 +
25414 +       if (pte_present(*pte_m))
25415 +               entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
25416 +       else
25417 +               entry_m = ptep_get_and_clear(mm, address_m, pte_m);
25418 +
25419 +       if (pte_none(entry_m)) {
25420 +       } else if (pte_present(entry_m)) {
25421 +               if (page_m) {
25422 +                       page_remove_rmap(page_m);
25423 +                       if (PageAnon(page_m))
25424 +                               dec_mm_counter(mm, anon_rss);
25425 +                       else
25426 +                               dec_mm_counter(mm, file_rss);
25427 +                       page_cache_release(page_m);
25428 +               }
25429 +       } else if (!pte_file(entry_m)) {
25430 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
25431 +       } else {
25432 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
25433 +                               address, vma->vm_start, address_m, vma_m->vm_start);
25434 +       }
25435 +
25436 +       page_m = vm_normal_page(vma, address, *pte);
25437 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
25438 +       if (pte_write(*pte))
25439 +               entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
25440 +       if (page_m) {
25441 +               page_cache_get(page_m);
25442 +               /*
25443 +                * we can test PAGE_MAPPING_ANON without holding page_map_lock because
25444 +                * we hold the page table lock and have a reference to page_m
25445 +                */
25446 +               if (PageAnon(page_m)) {
25447 +                       page_add_anon_rmap(page_m, vma_m, address_m);
25448 +                       inc_mm_counter(mm, anon_rss);
25449 +               } else {
25450 +                       page_add_file_rmap(page_m);
25451 +                       inc_mm_counter(mm, file_rss);
25452 +               }
25453 +       }
25454 +       set_pte_at(mm, address_m, pte_m, entry_m);
25455 +       update_mmu_cache(vma_m, address_m, entry_m);
25456 +       lazy_mmu_prot_update(entry_m);
25457 +       pte_unmap_nested(pte_m);
25458 +}
25459 +#endif
25460 +
25461  /*
25462   * This routine handles present pages, when users try to write
25463   * to a shared page. It is done by copying the page to a new address
25464 @@ -1559,6 +1658,12 @@ gotten:
25465                 /* Free the old page.. */
25466                 new_page = old_page;
25467                 ret |= VM_FAULT_WRITE;
25468 +
25469 +#ifdef CONFIG_PAX_SEGMEXEC
25470 +               if (vma->vm_flags & VM_MIRROR)
25471 +                       pax_mirror_fault(vma, address, page_table);
25472 +#endif
25473 +
25474         }
25475         if (new_page)
25476                 page_cache_release(new_page);
25477 @@ -1813,6 +1918,7 @@ int vmtruncate(struct inode * inode, lof
25478  
25479  do_expand:
25480         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
25481 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
25482         if (limit != RLIM_INFINITY && offset > limit)
25483                 goto out_sig;
25484         if (offset > inode->i_sb->s_maxbytes)
25485 @@ -2002,6 +2108,12 @@ static int do_swap_page(struct mm_struct
25486         /* No need to invalidate - it was non-present before */
25487         update_mmu_cache(vma, address, pte);
25488         lazy_mmu_prot_update(pte);
25489 +
25490 +#ifdef CONFIG_PAX_SEGMEXEC
25491 +       if (vma->vm_flags & VM_MIRROR)
25492 +               pax_mirror_fault(vma, address, page_table);
25493 +#endif
25494 +
25495  unlock:
25496         pte_unmap_unlock(page_table, ptl);
25497  out:
25498 @@ -2064,6 +2176,12 @@ static int do_anonymous_page(struct mm_s
25499         /* No need to invalidate - it was non-present before */
25500         update_mmu_cache(vma, address, entry);
25501         lazy_mmu_prot_update(entry);
25502 +
25503 +#ifdef CONFIG_PAX_SEGMEXEC
25504 +       if (vma->vm_flags & VM_MIRROR)
25505 +               pax_mirror_fault(vma, address, page_table);
25506 +#endif
25507 +
25508  unlock:
25509         pte_unmap_unlock(page_table, ptl);
25510         return VM_FAULT_MINOR;
25511 @@ -2202,6 +2320,12 @@ retry:
25512         /* no need to invalidate: a not-present page shouldn't be cached */
25513         update_mmu_cache(vma, address, entry);
25514         lazy_mmu_prot_update(entry);
25515 +
25516 +#ifdef CONFIG_PAX_SEGMEXEC
25517 +       if (vma->vm_flags & VM_MIRROR)
25518 +               pax_mirror_fault(vma, address, page_table);
25519 +#endif
25520 +
25521  unlock:
25522         pte_unmap_unlock(page_table, ptl);
25523         return ret;
25524 @@ -2311,6 +2435,12 @@ static inline int handle_pte_fault(struc
25525                         flush_tlb_page(vma, address);
25526         }
25527  unlock:
25528 +
25529 +#ifdef CONFIG_PAX_SEGMEXEC
25530 +       if (vma->vm_flags & VM_MIRROR)
25531 +               pax_mirror_fault(vma, address, pte);
25532 +#endif
25533 +
25534         pte_unmap_unlock(pte, ptl);
25535         return VM_FAULT_MINOR;
25536  }
25537 @@ -2333,6 +2463,49 @@ int __handle_mm_fault(struct mm_struct *
25538         if (unlikely(is_vm_hugetlb_page(vma)))
25539                 return hugetlb_fault(mm, vma, address, write_access);
25540  
25541 +#ifdef CONFIG_PAX_SEGMEXEC
25542 +       if (vma->vm_flags & VM_MIRROR) {
25543 +               unsigned long address_m;
25544 +               struct vm_area_struct * vma_m;
25545 +               pgd_t *pgd_m;
25546 +               pud_t *pud_m;
25547 +               pmd_t *pmd_m;
25548 +
25549 +               address_m = vma->vm_start + vma->vm_mirror;
25550 +               vma_m = find_vma(mm, address_m);
25551 +
25552 +               /* PaX: sanity checks */
25553 +               if (!vma_m) {
25554 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
25555 +                              address, vma, address_m, vma_m);
25556 +                       return VM_FAULT_SIGBUS;
25557 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
25558 +                       vma_m->vm_start != address_m ||
25559 +                       vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
25560 +               {
25561 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
25562 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
25563 +                       return VM_FAULT_SIGBUS;
25564 +               }
25565 +
25566 +               if (address_m < address) {
25567 +                       address += vma->vm_mirror;
25568 +                       vma = vma_m;
25569 +               }
25570 +
25571 +               address_m = address + vma->vm_mirror;
25572 +               pgd_m = pgd_offset(mm, address_m);
25573 +               pud_m = pud_alloc(mm, pgd_m, address_m);
25574 +               if (!pud_m)
25575 +                       return VM_FAULT_OOM;
25576 +               pmd_m = pmd_alloc(mm, pud_m, address_m);
25577 +               if (!pmd_m)
25578 +                       return VM_FAULT_OOM;
25579 +               if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
25580 +                       return VM_FAULT_OOM;
25581 +       }
25582 +#endif
25583 +
25584         pgd = pgd_offset(mm, address);
25585         pud = pud_alloc(mm, pgd, address);
25586         if (!pud)
25587 diff -urNp linux-2.6.18/mm/mempolicy.c linux-2.6.18/mm/mempolicy.c
25588 --- linux-2.6.18/mm/mempolicy.c 2006-09-19 23:42:06.000000000 -0400
25589 +++ linux-2.6.18/mm/mempolicy.c 2006-09-22 20:45:04.000000000 -0400
25590 @@ -348,6 +348,12 @@ check_range(struct mm_struct *mm, unsign
25591                         if (prev && prev->vm_end < vma->vm_start)
25592                                 return ERR_PTR(-EFAULT);
25593                 }
25594 +
25595 +#ifdef CONFIG_PAX_SEGMEXEC
25596 +               if (vma->vm_flags & VM_MIRROR)
25597 +                       return ERR_PTR(-EFAULT);
25598 +#endif
25599 +
25600                 if (!is_vm_hugetlb_page(vma) &&
25601                     ((flags & MPOL_MF_STRICT) ||
25602                      ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
25603 diff -urNp linux-2.6.18/mm/mlock.c linux-2.6.18/mm/mlock.c
25604 --- linux-2.6.18/mm/mlock.c     2006-09-19 23:42:06.000000000 -0400
25605 +++ linux-2.6.18/mm/mlock.c     2006-09-22 20:45:04.000000000 -0400
25606 @@ -10,14 +10,85 @@
25607  #include <linux/mm.h>
25608  #include <linux/mempolicy.h>
25609  #include <linux/syscalls.h>
25610 +#include <linux/grsecurity.h>
25611  
25612 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
25613 +       unsigned long start, unsigned long end, unsigned int newflags);
25614  
25615  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
25616         unsigned long start, unsigned long end, unsigned int newflags)
25617  {
25618         struct mm_struct * mm = vma->vm_mm;
25619 -       pgoff_t pgoff;
25620         int pages;
25621 +       int ret;
25622 +
25623 +#ifdef CONFIG_PAX_SEGMEXEC
25624 +       struct vm_area_struct * vma_m = NULL, *prev_m;
25625 +       unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
25626 +
25627 +       if (vma->vm_flags & VM_MIRROR) {
25628 +               start_m = vma->vm_start + vma->vm_mirror;
25629 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
25630 +               if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
25631 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
25632 +                       return -ENOMEM;
25633 +               }
25634 +
25635 +               start_m = start + vma->vm_mirror;
25636 +               end_m = end + vma->vm_mirror;
25637 +               if (newflags & VM_LOCKED)
25638 +                       newflags_m = vma_m->vm_flags | VM_LOCKED;
25639 +               else
25640 +                       newflags_m = vma_m->vm_flags & ~VM_LOCKED;
25641 +               ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
25642 +               if (ret)
25643 +                       return ret;
25644 +       }
25645 +#endif
25646 +
25647 +       ret = __mlock_fixup(vma, prev, start, end, newflags);
25648 +       if (ret)
25649 +               return ret;
25650 +
25651 +       /*
25652 +        * vm_flags is protected by the mmap_sem held in write mode.
25653 +        * It's okay if try_to_unmap_one unmaps a page just after we
25654 +        * set VM_LOCKED, make_pages_present below will bring it back.
25655 +        */
25656 +       vma->vm_flags = newflags;
25657 +
25658 +#ifdef CONFIG_PAX_SEGMEXEC
25659 +       if (vma->vm_flags & VM_MIRROR)
25660 +               vma_m->vm_flags = newflags_m;
25661 +#endif
25662 +
25663 +       /*
25664 +        * Keep track of amount of locked VM.
25665 +        */
25666 +       pages = (end - start) >> PAGE_SHIFT;
25667 +       if (newflags & VM_LOCKED) {
25668 +               pages = -pages;
25669 +               if (!(newflags & VM_IO))
25670 +                       ret = make_pages_present(start, end);
25671 +       }
25672 +
25673 +       mm->locked_vm -= pages;
25674 +
25675 +#ifdef CONFIG_PAX_SEGMEXEC
25676 +       if (vma->vm_flags & VM_MIRROR)
25677 +               mm->locked_vm -= pages;
25678 +#endif
25679 +
25680 +       if (ret == -ENOMEM)
25681 +               ret = -EAGAIN;
25682 +       return ret;
25683 +}
25684 +
25685 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
25686 +       unsigned long start, unsigned long end, unsigned int newflags)
25687 +{
25688 +       struct mm_struct * mm = vma->vm_mm;
25689 +       pgoff_t pgoff;
25690         int ret = 0;
25691  
25692         if (newflags == vma->vm_flags) {
25693 @@ -30,7 +101,7 @@ static int mlock_fixup(struct vm_area_st
25694                           vma->vm_file, pgoff, vma_policy(vma));
25695         if (*prev) {
25696                 vma = *prev;
25697 -               goto success;
25698 +               goto out;
25699         }
25700  
25701         *prev = vma;
25702 @@ -41,31 +112,9 @@ static int mlock_fixup(struct vm_area_st
25703                         goto out;
25704         }
25705  
25706 -       if (end != vma->vm_end) {
25707 +       if (end != vma->vm_end)
25708                 ret = split_vma(mm, vma, end, 0);
25709 -               if (ret)
25710 -                       goto out;
25711 -       }
25712  
25713 -success:
25714 -       /*
25715 -        * vm_flags is protected by the mmap_sem held in write mode.
25716 -        * It's okay if try_to_unmap_one unmaps a page just after we
25717 -        * set VM_LOCKED, make_pages_present below will bring it back.
25718 -        */
25719 -       vma->vm_flags = newflags;
25720 -
25721 -       /*
25722 -        * Keep track of amount of locked VM.
25723 -        */
25724 -       pages = (end - start) >> PAGE_SHIFT;
25725 -       if (newflags & VM_LOCKED) {
25726 -               pages = -pages;
25727 -               if (!(newflags & VM_IO))
25728 -                       ret = make_pages_present(start, end);
25729 -       }
25730 -
25731 -       vma->vm_mm->locked_vm -= pages;
25732  out:
25733         if (ret == -ENOMEM)
25734                 ret = -EAGAIN;
25735 @@ -84,6 +133,17 @@ static int do_mlock(unsigned long start,
25736                 return -EINVAL;
25737         if (end == start)
25738                 return 0;
25739 +
25740 +#ifdef CONFIG_PAX_SEGMEXEC
25741 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
25742 +               if (end > SEGMEXEC_TASK_SIZE)
25743 +                       return -EINVAL;
25744 +       } else
25745 +#endif
25746 +
25747 +       if (end > TASK_SIZE)
25748 +               return -EINVAL;
25749 +
25750         vma = find_vma_prev(current->mm, start, &prev);
25751         if (!vma || vma->vm_start > start)
25752                 return -ENOMEM;
25753 @@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long 
25754         lock_limit >>= PAGE_SHIFT;
25755  
25756         /* check against resource limits */
25757 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
25758         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
25759                 error = do_mlock(start, len, 1);
25760         up_write(&current->mm->mmap_sem);
25761 @@ -173,6 +234,16 @@ static int do_mlockall(int flags)
25762         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
25763                 unsigned int newflags;
25764  
25765 +#ifdef CONFIG_PAX_SEGMEXEC
25766 +               if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
25767 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
25768 +                               break;
25769 +               } else
25770 +#endif
25771 +
25772 +               if (vma->vm_end > TASK_SIZE)
25773 +                       break;
25774 +
25775                 newflags = vma->vm_flags | VM_LOCKED;
25776                 if (!(flags & MCL_CURRENT))
25777                         newflags &= ~VM_LOCKED;
25778 @@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
25779         lock_limit >>= PAGE_SHIFT;
25780  
25781         ret = -ENOMEM;
25782 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
25783         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
25784             capable(CAP_IPC_LOCK))
25785                 ret = do_mlockall(flags);
25786 diff -urNp linux-2.6.18/mm/mmap.c linux-2.6.18/mm/mmap.c
25787 --- linux-2.6.18/mm/mmap.c      2006-09-19 23:42:06.000000000 -0400
25788 +++ linux-2.6.18/mm/mmap.c      2006-09-22 20:45:04.000000000 -0400
25789 @@ -25,6 +25,7 @@
25790  #include <linux/mount.h>
25791  #include <linux/mempolicy.h>
25792  #include <linux/rmap.h>
25793 +#include <linux/grsecurity.h>
25794  
25795  #include <asm/uaccess.h>
25796  #include <asm/cacheflush.h>
25797 @@ -244,6 +245,7 @@ asmlinkage unsigned long sys_brk(unsigne
25798          * not page aligned -Ram Gupta
25799          */
25800         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
25801 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
25802         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
25803                 goto out;
25804  
25805 @@ -632,11 +634,17 @@ again:                    remove_next = 1 + (end > next->
25806   * If the vma has a ->close operation then the driver probably needs to release
25807   * per-vma resources, so we don't attempt to merge those.
25808   */
25809 +#ifdef CONFIG_PAX_SEGMEXEC
25810 +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
25811 +#else
25812  #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
25813 +#endif
25814  
25815  static inline int is_mergeable_vma(struct vm_area_struct *vma,
25816                         struct file *file, unsigned long vm_flags)
25817  {
25818 +       if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
25819 +               return 0;
25820         if (vma->vm_flags != vm_flags)
25821                 return 0;
25822         if (vma->vm_file != file)
25823 @@ -861,14 +869,11 @@ none:
25824  void vm_stat_account(struct mm_struct *mm, unsigned long flags,
25825                                                 struct file *file, long pages)
25826  {
25827 -       const unsigned long stack_flags
25828 -               = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
25829 -
25830         if (file) {
25831                 mm->shared_vm += pages;
25832                 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
25833                         mm->exec_vm += pages;
25834 -       } else if (flags & stack_flags)
25835 +       } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
25836                 mm->stack_vm += pages;
25837         if (flags & (VM_RESERVED|VM_IO))
25838                 mm->reserved_vm += pages;
25839 @@ -879,9 +884,54 @@ void vm_stat_account(struct mm_struct *m
25840   * The caller must hold down_write(current->mm->mmap_sem).
25841   */
25842  
25843 +#ifdef CONFIG_PAX_SEGMEXEC
25844 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
25845 +                       unsigned long len, unsigned long prot,
25846 +                       unsigned long flags, unsigned long pgoff);
25847 +
25848 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
25849 +                       unsigned long len, unsigned long prot,
25850 +                       unsigned long flags, unsigned long pgoff)
25851 +{
25852 +       unsigned long ret = -EINVAL;
25853 +
25854 +       if (flags & MAP_MIRROR)
25855 +               return ret;
25856 +
25857 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
25858 +           (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
25859 +               return ret;
25860 +
25861 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
25862 +
25863 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
25864 +
25865 +#ifdef CONFIG_PAX_MPROTECT
25866 +           && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
25867 +#endif
25868 +
25869 +          )
25870 +       {
25871 +               unsigned long ret_m;
25872 +               prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
25873 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
25874 +               if (ret_m >= TASK_SIZE) {
25875 +                       do_munmap(current->mm, ret, len);
25876 +                       ret = ret_m;
25877 +               }
25878 +       }
25879 +
25880 +       return ret;
25881 +}
25882 +
25883 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
25884 +                       unsigned long len, unsigned long prot,
25885 +                       unsigned long flags, unsigned long pgoff)
25886 +#else
25887  unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
25888                         unsigned long len, unsigned long prot,
25889                         unsigned long flags, unsigned long pgoff)
25890 +#endif
25891  {
25892         struct mm_struct * mm = current->mm;
25893         struct vm_area_struct * vma, * prev;
25894 @@ -893,6 +943,28 @@ unsigned long do_mmap_pgoff(struct file 
25895         int accountable = 1;
25896         unsigned long charged = 0, reqprot = prot;
25897  
25898 +#ifdef CONFIG_PAX_SEGMEXEC
25899 +       struct vm_area_struct * vma_m = NULL;
25900 +
25901 +       if (flags & MAP_MIRROR) {
25902 +               /* PaX: sanity checks, to be removed when proved to be stable */
25903 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
25904 +                       return -EINVAL;
25905 +
25906 +               vma_m = find_vma(mm, pgoff);
25907 +
25908 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
25909 +                   vma_m->vm_start != pgoff ||
25910 +                   (vma_m->vm_flags & VM_SPECIAL) ||
25911 +                   (prot & PROT_WRITE))
25912 +                       return -EINVAL;
25913 +
25914 +               file = vma_m->vm_file;
25915 +               pgoff = vma_m->vm_pgoff;
25916 +               len = vma_m->vm_end - vma_m->vm_start;
25917 +       }
25918 +#endif
25919 +
25920         if (file) {
25921                 if (is_file_hugepages(file))
25922                         accountable = 0;
25923 @@ -910,7 +982,7 @@ unsigned long do_mmap_pgoff(struct file 
25924          * (the exception is when the underlying filesystem is noexec
25925          *  mounted, in which case we dont add PROT_EXEC.)
25926          */
25927 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
25928 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
25929                 if (!(file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)))
25930                         prot |= PROT_EXEC;
25931  
25932 @@ -937,7 +1009,7 @@ unsigned long do_mmap_pgoff(struct file 
25933         /* Obtain the address to map to. we verify (or select) it and ensure
25934          * that it represents a valid section of the address space.
25935          */
25936 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
25937 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
25938         if (addr & ~PAGE_MASK)
25939                 return addr;
25940  
25941 @@ -948,6 +1020,24 @@ unsigned long do_mmap_pgoff(struct file 
25942         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
25943                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
25944  
25945 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
25946 +               vm_flags &= ~VM_MAYEXEC;
25947 +
25948 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
25949 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
25950 +
25951 +#ifdef CONFIG_PAX_MPROTECT
25952 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
25953 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
25954 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
25955 +                       else
25956 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
25957 +               }
25958 +#endif
25959 +
25960 +       }
25961 +#endif
25962 +
25963         if (flags & MAP_LOCKED) {
25964                 if (!can_do_mlock())
25965                         return -EPERM;
25966 @@ -960,6 +1050,7 @@ unsigned long do_mmap_pgoff(struct file 
25967                 locked += mm->locked_vm;
25968                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
25969                 lock_limit >>= PAGE_SHIFT;
25970 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
25971                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
25972                         return -EAGAIN;
25973         }
25974 @@ -1007,6 +1098,11 @@ unsigned long do_mmap_pgoff(struct file 
25975                         /*
25976                          * Set pgoff according to addr for anon_vma.
25977                          */
25978 +
25979 +#ifdef CONFIG_PAX_SEGMEXEC
25980 +                       if (!(flags & MAP_MIRROR))
25981 +#endif
25982 +
25983                         pgoff = addr >> PAGE_SHIFT;
25984                         break;
25985                 default:
25986 @@ -1018,14 +1114,17 @@ unsigned long do_mmap_pgoff(struct file 
25987         if (error)
25988                 return error;
25989                 
25990 +       if (!gr_acl_handle_mmap(file, prot))
25991 +               return -EACCES;
25992 +
25993         /* Clear old maps */
25994         error = -ENOMEM;
25995 -munmap_back:
25996         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
25997         if (vma && vma->vm_start < addr + len) {
25998                 if (do_munmap(mm, addr, len))
25999                         return -ENOMEM;
26000 -               goto munmap_back;
26001 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
26002 +               BUG_ON(vma && vma->vm_start < addr + len);
26003         }
26004  
26005         /* Check against address space limit. */
26006 @@ -1073,6 +1172,13 @@ munmap_back:
26007         vma->vm_start = addr;
26008         vma->vm_end = addr + len;
26009         vma->vm_flags = vm_flags;
26010 +
26011 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26012 +       if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
26013 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
26014 +       else
26015 +#endif
26016 +
26017         vma->vm_page_prot = protection_map[vm_flags &
26018                                 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
26019         vma->vm_pgoff = pgoff;
26020 @@ -1100,9 +1206,25 @@ munmap_back:
26021  
26022         /* Don't make the VMA automatically writable if it's shared, but the
26023          * backer wishes to know when pages are first written to */
26024 -       if (vma->vm_ops && vma->vm_ops->page_mkwrite)
26025 +       if (vma->vm_ops && vma->vm_ops->page_mkwrite) {
26026 +
26027 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26028 +               if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
26029 +                       vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
26030 +               else
26031 +#endif
26032 +
26033                 vma->vm_page_prot =
26034                         protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
26035 +       }
26036 +
26037 +#ifdef CONFIG_PAX_SEGMEXEC
26038 +       if (flags & MAP_MIRROR) {
26039 +               vma_m->vm_flags |= VM_MIRROR;
26040 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
26041 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
26042 +       }
26043 +#endif
26044  
26045         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
26046          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
26047 @@ -1139,6 +1261,7 @@ munmap_back:
26048  out:   
26049         mm->total_vm += len >> PAGE_SHIFT;
26050         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
26051 +       track_exec_limit(mm, addr, addr + len, vm_flags);
26052         if (vm_flags & VM_LOCKED) {
26053                 mm->locked_vm += len >> PAGE_SHIFT;
26054                 make_pages_present(addr, addr + len);
26055 @@ -1193,6 +1316,10 @@ arch_get_unmapped_area(struct file *filp
26056         if (len > TASK_SIZE)
26057                 return -ENOMEM;
26058  
26059 +#ifdef CONFIG_PAX_RANDMMAP
26060 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
26061 +#endif
26062 +
26063         if (addr) {
26064                 addr = PAGE_ALIGN(addr);
26065                 vma = find_vma(mm, addr);
26066 @@ -1203,7 +1330,7 @@ arch_get_unmapped_area(struct file *filp
26067         if (len > mm->cached_hole_size) {
26068                 start_addr = addr = mm->free_area_cache;
26069         } else {
26070 -               start_addr = addr = TASK_UNMAPPED_BASE;
26071 +               start_addr = addr = mm->mmap_base;
26072                 mm->cached_hole_size = 0;
26073         }
26074  
26075 @@ -1215,9 +1342,8 @@ full_search:
26076                          * Start a new search - just in case we missed
26077                          * some holes.
26078                          */
26079 -                       if (start_addr != TASK_UNMAPPED_BASE) {
26080 -                               addr = TASK_UNMAPPED_BASE;
26081 -                               start_addr = addr;
26082 +                       if (start_addr != mm->mmap_base) {
26083 +                               start_addr = addr = mm->mmap_base;
26084                                 mm->cached_hole_size = 0;
26085                                 goto full_search;
26086                         }
26087 @@ -1242,7 +1368,7 @@ void arch_unmap_area(struct mm_struct *m
26088         /*
26089          * Is this a new hole at the lowest possible address?
26090          */
26091 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
26092 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
26093                 mm->free_area_cache = addr;
26094                 mm->cached_hole_size = ~0UL;
26095         }
26096 @@ -1260,12 +1386,16 @@ arch_get_unmapped_area_topdown(struct fi
26097  {
26098         struct vm_area_struct *vma;
26099         struct mm_struct *mm = current->mm;
26100 -       unsigned long addr = addr0;
26101 +       unsigned long base = mm->mmap_base, addr = addr0;
26102  
26103         /* requested length too big for entire address space */
26104         if (len > TASK_SIZE)
26105                 return -ENOMEM;
26106  
26107 +#ifdef CONFIG_PAX_RANDMMAP
26108 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
26109 +#endif
26110 +
26111         /* requesting a specific address */
26112         if (addr) {
26113                 addr = PAGE_ALIGN(addr);
26114 @@ -1323,13 +1453,21 @@ bottomup:
26115          * can happen with large stack limits and large mmap()
26116          * allocations.
26117          */
26118 +       mm->mmap_base = TASK_UNMAPPED_BASE;
26119 +
26120 +#ifdef CONFIG_PAX_RANDMMAP
26121 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
26122 +               mm->mmap_base += mm->delta_mmap;
26123 +#endif
26124 +
26125 +       mm->free_area_cache = mm->mmap_base;
26126         mm->cached_hole_size = ~0UL;
26127 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
26128         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
26129         /*
26130          * Restore the topdown base:
26131          */
26132 -       mm->free_area_cache = mm->mmap_base;
26133 +       mm->mmap_base = base;
26134 +       mm->free_area_cache = base;
26135         mm->cached_hole_size = ~0UL;
26136  
26137         return addr;
26138 @@ -1345,8 +1483,10 @@ void arch_unmap_area_topdown(struct mm_s
26139                 mm->free_area_cache = addr;
26140  
26141         /* dont allow allocations above current base */
26142 -       if (mm->free_area_cache > mm->mmap_base)
26143 +       if (mm->free_area_cache > mm->mmap_base) {
26144                 mm->free_area_cache = mm->mmap_base;
26145 +               mm->cached_hole_size = ~0UL;
26146 +       }
26147  }
26148  
26149  unsigned long
26150 @@ -1479,6 +1619,7 @@ static int acct_stack_growth(struct vm_a
26151                 return -ENOMEM;
26152  
26153         /* Stack limit test */
26154 +       gr_learn_resource(current, RLIMIT_STACK, size, 1);
26155         if (size > rlim[RLIMIT_STACK].rlim_cur)
26156                 return -ENOMEM;
26157  
26158 @@ -1488,6 +1629,7 @@ static int acct_stack_growth(struct vm_a
26159                 unsigned long limit;
26160                 locked = mm->locked_vm + grow;
26161                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
26162 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
26163                 if (locked > limit && !capable(CAP_IPC_LOCK))
26164                         return -ENOMEM;
26165         }
26166 @@ -1605,13 +1747,49 @@ int expand_stack(struct vm_area_struct *
26167         if (address < vma->vm_start) {
26168                 unsigned long size, grow;
26169  
26170 +#ifdef CONFIG_PAX_SEGMEXEC
26171 +               struct vm_area_struct *vma_m = NULL;
26172 +               unsigned long address_m = 0UL;
26173 +
26174 +               if (vma->vm_flags & VM_MIRROR) {
26175 +                       address_m = vma->vm_start + vma->vm_mirror;
26176 +                       vma_m = find_vma(vma->vm_mm, address_m);
26177 +                       if (!vma_m || vma_m->vm_start != address_m ||
26178 +                           !(vma_m->vm_flags & VM_MIRROR) ||
26179 +                           vma->vm_end - vma->vm_start !=
26180 +                           vma_m->vm_end - vma_m->vm_start ||
26181 +                           vma->anon_vma != vma_m->anon_vma) {
26182 +                               printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
26183 +                                      address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
26184 +                               anon_vma_unlock(vma);
26185 +                               return -EFAULT;
26186 +                       }
26187 +                       address_m = address + vma->vm_mirror;
26188 +               }
26189 +#endif
26190 +
26191                 size = vma->vm_end - address;
26192                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
26193  
26194 +#ifdef CONFIG_PAX_SEGMEXEC
26195 +               if (vma_m)
26196 +                       error = acct_stack_growth(vma, size, 2*grow);
26197 +               else
26198 +#endif
26199 +
26200                 error = acct_stack_growth(vma, size, grow);
26201                 if (!error) {
26202                         vma->vm_start = address;
26203                         vma->vm_pgoff -= grow;
26204 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
26205 +
26206 +#ifdef CONFIG_PAX_SEGMEXEC
26207 +                       if (vma_m) {
26208 +                               vma_m->vm_start = address_m;
26209 +                               vma_m->vm_pgoff -= grow;
26210 +                       }
26211 +#endif
26212 +
26213                 }
26214         }
26215         anon_vma_unlock(vma);
26216 @@ -1773,7 +1951,24 @@ int split_vma(struct mm_struct * mm, str
26217   * work.  This now handles partial unmappings.
26218   * Jeremy Fitzhardinge <jeremy@goop.org>
26219   */
26220 +#ifdef CONFIG_PAX_SEGMEXEC
26221 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
26222 +
26223 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
26224 +{
26225 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
26226 +               int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
26227 +               if (ret)
26228 +                       return ret;
26229 +       }
26230 +
26231 +       return __do_munmap(mm, start, len);
26232 +}
26233 +
26234 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
26235 +#else
26236  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
26237 +#endif
26238  {
26239         unsigned long end;
26240         struct vm_area_struct *vma, *prev, *last;
26241 @@ -1827,6 +2022,8 @@ int do_munmap(struct mm_struct *mm, unsi
26242         /* Fix up all other VM information */
26243         remove_vma_list(mm, vma);
26244  
26245 +       track_exec_limit(mm, start, end, 0UL);
26246 +
26247         return 0;
26248  }
26249  
26250 @@ -1839,6 +2036,12 @@ asmlinkage long sys_munmap(unsigned long
26251  
26252         profile_munmap(addr);
26253  
26254 +#ifdef CONFIG_PAX_SEGMEXEC
26255 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
26256 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
26257 +               return -EINVAL;
26258 +#endif
26259 +
26260         down_write(&mm->mmap_sem);
26261         ret = do_munmap(mm, addr, len);
26262         up_write(&mm->mmap_sem);
26263 @@ -1860,11 +2063,35 @@ static inline void verify_mm_writelocked
26264   *  anonymous maps.  eventually we may be able to do some
26265   *  brk-specific accounting here.
26266   */
26267 +#ifdef CONFIG_PAX_SEGMEXEC
26268 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
26269 +
26270 +unsigned long do_brk(unsigned long addr, unsigned long len)
26271 +{
26272 +       unsigned long ret;
26273 +
26274 +       ret = __do_brk(addr, len);
26275 +       if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
26276 +               unsigned long ret_m;
26277 +
26278 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
26279 +               if (ret_m > TASK_SIZE) {
26280 +                       do_munmap(current->mm, addr, len);
26281 +                       ret = ret_m;
26282 +               }
26283 +       }
26284 +
26285 +       return ret;
26286 +}
26287 +
26288 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
26289 +#else
26290  unsigned long do_brk(unsigned long addr, unsigned long len)
26291 +#endif
26292  {
26293         struct mm_struct * mm = current->mm;
26294         struct vm_area_struct * vma, * prev;
26295 -       unsigned long flags;
26296 +       unsigned long flags, task_size = TASK_SIZE;
26297         struct rb_node ** rb_link, * rb_parent;
26298         pgoff_t pgoff = addr >> PAGE_SHIFT;
26299         int error;
26300 @@ -1873,11 +2100,28 @@ unsigned long do_brk(unsigned long addr,
26301         if (!len)
26302                 return addr;
26303  
26304 -       if ((addr + len) > TASK_SIZE || (addr + len) < addr)
26305 +#ifdef CONFIG_PAX_SEGMEXEC
26306 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
26307 +               task_size = SEGMEXEC_TASK_SIZE;
26308 +#endif
26309 +
26310 +       if ((addr + len) > task_size || (addr + len) < addr)
26311                 return -EINVAL;
26312  
26313         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
26314  
26315 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
26316 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
26317 +               flags &= ~VM_EXEC;
26318 +
26319 +#ifdef CONFIG_PAX_MPROTECT
26320 +               if (mm->pax_flags & MF_PAX_MPROTECT)
26321 +                       flags &= ~VM_MAYEXEC;
26322 +#endif
26323 +
26324 +       }
26325 +#endif
26326 +
26327         error = arch_mmap_check(addr, len, flags);
26328         if (error)
26329                 return error;
26330 @@ -1891,6 +2135,7 @@ unsigned long do_brk(unsigned long addr,
26331                 locked += mm->locked_vm;
26332                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
26333                 lock_limit >>= PAGE_SHIFT;
26334 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
26335                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
26336                         return -EAGAIN;
26337         }
26338 @@ -1904,12 +2149,12 @@ unsigned long do_brk(unsigned long addr,
26339         /*
26340          * Clear old maps.  this also does some error checking for us
26341          */
26342 - munmap_back:
26343         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
26344         if (vma && vma->vm_start < addr + len) {
26345                 if (do_munmap(mm, addr, len))
26346                         return -ENOMEM;
26347 -               goto munmap_back;
26348 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
26349 +               BUG_ON(vma && vma->vm_start < addr + len);
26350         }
26351  
26352         /* Check against address space limits *after* clearing old maps... */
26353 @@ -1941,6 +2186,13 @@ unsigned long do_brk(unsigned long addr,
26354         vma->vm_end = addr + len;
26355         vma->vm_pgoff = pgoff;
26356         vma->vm_flags = flags;
26357 +
26358 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26359 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
26360 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
26361 +       else
26362 +#endif
26363 +
26364         vma->vm_page_prot = protection_map[flags &
26365                                 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
26366         vma_link(mm, vma, prev, rb_link, rb_parent);
26367 @@ -1950,6 +2202,7 @@ out:
26368                 mm->locked_vm += len >> PAGE_SHIFT;
26369                 make_pages_present(addr, addr + len);
26370         }
26371 +       track_exec_limit(mm, addr, addr + len, flags);
26372         return addr;
26373  }
26374  
26375 @@ -2082,7 +2335,7 @@ int may_expand_vm(struct mm_struct *mm, 
26376         unsigned long lim;
26377  
26378         lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
26379 -
26380 +       gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
26381         if (cur + npages > lim)
26382                 return 0;
26383         return 1;
26384 diff -urNp linux-2.6.18/mm/mprotect.c linux-2.6.18/mm/mprotect.c
26385 --- linux-2.6.18/mm/mprotect.c  2006-09-19 23:42:06.000000000 -0400
26386 +++ linux-2.6.18/mm/mprotect.c  2006-09-22 21:54:23.000000000 -0400
26387 @@ -21,10 +21,18 @@
26388  #include <linux/syscalls.h>
26389  #include <linux/swap.h>
26390  #include <linux/swapops.h>
26391 +#include <linux/grsecurity.h>
26392 +
26393 +#ifdef CONFIG_PAX_MPROTECT
26394 +#include <linux/elf.h>
26395 +#include <linux/fs.h>
26396 +#endif
26397 +
26398  #include <asm/uaccess.h>
26399  #include <asm/pgtable.h>
26400  #include <asm/cacheflush.h>
26401  #include <asm/tlbflush.h>
26402 +#include <asm/mmu_context.h>
26403  
26404  static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
26405                 unsigned long addr, unsigned long end, pgprot_t newprot)
26406 @@ -115,6 +123,95 @@ static void change_protection(struct vm_
26407         flush_tlb_range(vma, start, end);
26408  }
26409  
26410 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
26411 +/* called while holding the mmap semaphor for writing */
26412 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
26413 +{
26414 +       struct vm_area_struct *vma = find_vma(mm, start);
26415 +
26416 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
26417 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
26418 +
26419 +}
26420 +
26421 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
26422 +{
26423 +       unsigned long oldlimit, newlimit = 0UL;
26424 +
26425 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
26426 +               return;
26427 +
26428 +       spin_lock(&mm->page_table_lock);
26429 +       oldlimit = mm->context.user_cs_limit;
26430 +       if ((prot & VM_EXEC) && oldlimit < end)
26431 +               /* USER_CS limit moved up */
26432 +               newlimit = end;
26433 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
26434 +               /* USER_CS limit moved down */
26435 +               newlimit = start;
26436 +
26437 +       if (newlimit) {
26438 +               mm->context.user_cs_limit = newlimit;
26439 +
26440 +#ifdef CONFIG_SMP
26441 +               wmb();
26442 +               cpus_clear(mm->context.cpu_user_cs_mask);
26443 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
26444 +#endif
26445 +
26446 +               set_user_cs(mm, smp_processor_id());
26447 +       }
26448 +       spin_unlock(&mm->page_table_lock);
26449 +       if (newlimit == end)
26450 +               establish_user_cs_limit(mm, oldlimit, end);
26451 +}
26452 +#endif
26453 +
26454 +#ifdef CONFIG_PAX_SEGMEXEC
26455 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
26456 +       unsigned long start, unsigned long end, unsigned int newflags);
26457 +
26458 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
26459 +       unsigned long start, unsigned long end, unsigned int newflags)
26460 +{
26461 +       if (vma->vm_flags & VM_MIRROR) {
26462 +               struct vm_area_struct * vma_m, * prev_m;
26463 +               unsigned long start_m, end_m;
26464 +               int error;
26465 +
26466 +               start_m = vma->vm_start + vma->vm_mirror;
26467 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
26468 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
26469 +                       start_m = start + vma->vm_mirror;
26470 +                       end_m = end + vma->vm_mirror;
26471 +
26472 +                       if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
26473 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
26474 +                       else
26475 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
26476 +                       if (error)
26477 +                               return error;
26478 +               } else {
26479 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
26480 +                       return -ENOMEM;
26481 +               }
26482 +       }
26483 +
26484 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
26485 +}
26486 +
26487 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
26488 +       unsigned long start, unsigned long end, unsigned int newflags)
26489 +{
26490 +       struct mm_struct * mm = vma->vm_mm;
26491 +       unsigned long oldflags = vma->vm_flags;
26492 +       long nrpages = (end - start) >> PAGE_SHIFT;
26493 +       unsigned long charged = 0;
26494 +       unsigned int mask;
26495 +       pgprot_t newprot;
26496 +       pgoff_t pgoff;
26497 +       int error;
26498 +#else
26499  static int
26500  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
26501         unsigned long start, unsigned long end, unsigned long newflags)
26502 @@ -132,6 +229,7 @@ mprotect_fixup(struct vm_area_struct *vm
26503                 *pprev = vma;
26504                 return 0;
26505         }
26506 +#endif
26507  
26508         /*
26509          * If we make a private mapping writable we increase our commit;
26510 @@ -182,6 +280,12 @@ success:
26511         if (vma->vm_ops && vma->vm_ops->page_mkwrite)
26512                 mask &= ~VM_SHARED;
26513  
26514 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26515 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
26516 +               newprot = protection_map[(newflags | VM_EXEC) & mask];
26517 +       else
26518 +#endif
26519 +
26520         newprot = protection_map[newflags & mask];
26521  
26522         /*
26523 @@ -203,6 +307,69 @@ fail:
26524         return error;
26525  }
26526  
26527 +#ifdef CONFIG_PAX_MPROTECT
26528 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
26529 + * therefore we'll grant them VM_MAYWRITE once during their life.
26530 + *
26531 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
26532 + * basis because we want to allow the common case and not the special ones.
26533 + */
26534 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
26535 +{
26536 +       struct elfhdr elf_h;
26537 +       struct elf_phdr elf_p, p_dyn;
26538 +       elf_dyn dyn;
26539 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
26540 +
26541 +#ifndef CONFIG_PAX_NOELFRELOCS
26542 +       if ((vma->vm_start != start) ||
26543 +           !vma->vm_file ||
26544 +           !(vma->vm_flags & VM_MAYEXEC) ||
26545 +           (vma->vm_flags & VM_MAYNOTWRITE))
26546 +#endif
26547 +
26548 +               return;
26549 +
26550 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
26551 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
26552 +
26553 +#ifdef CONFIG_PAX_ETEXECRELOCS
26554 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
26555 +#else
26556 +           elf_h.e_type != ET_DYN ||
26557 +#endif
26558 +
26559 +           !elf_check_arch(&elf_h) ||
26560 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
26561 +           elf_h.e_phnum > j)
26562 +               return;
26563 +
26564 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
26565 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
26566 +                       return;
26567 +               if (elf_p.p_type == PT_DYNAMIC) {
26568 +                       p_dyn = elf_p;
26569 +                       j = i;
26570 +               }
26571 +       }
26572 +       if (elf_h.e_phnum <= j)
26573 +               return;
26574 +
26575 +       i = 0UL;
26576 +       do {
26577 +               if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
26578 +                       return;
26579 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
26580 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
26581 +                       gr_log_textrel(vma);
26582 +                       return;
26583 +               }
26584 +               i++;
26585 +       } while (dyn.d_tag != DT_NULL);
26586 +       return;
26587 +}
26588 +#endif
26589 +
26590  asmlinkage long
26591  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
26592  {
26593 @@ -222,6 +389,17 @@ sys_mprotect(unsigned long start, size_t
26594         end = start + len;
26595         if (end <= start)
26596                 return -ENOMEM;
26597 +
26598 +#ifdef CONFIG_PAX_SEGMEXEC
26599 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
26600 +               if (end > SEGMEXEC_TASK_SIZE)
26601 +                       return -EINVAL;
26602 +       } else
26603 +#endif
26604 +
26605 +       if (end > TASK_SIZE)
26606 +               return -EINVAL;
26607 +
26608         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
26609                 return -EINVAL;
26610  
26611 @@ -229,7 +407,7 @@ sys_mprotect(unsigned long start, size_t
26612         /*
26613          * Does the application expect PROT_READ to imply PROT_EXEC:
26614          */
26615 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
26616 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
26617                 prot |= PROT_EXEC;
26618  
26619         vm_flags = calc_vm_prot_bits(prot);
26620 @@ -261,6 +439,16 @@ sys_mprotect(unsigned long start, size_t
26621         if (start > vma->vm_start)
26622                 prev = vma;
26623  
26624 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
26625 +               error = -EACCES;
26626 +               goto out;
26627 +       }
26628 +
26629 +#ifdef CONFIG_PAX_MPROTECT
26630 +       if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
26631 +               pax_handle_maywrite(vma, start);
26632 +#endif
26633 +
26634         for (nstart = start ; ; ) {
26635                 unsigned long newflags;
26636  
26637 @@ -274,6 +462,12 @@ sys_mprotect(unsigned long start, size_t
26638                         goto out;
26639                 }
26640  
26641 +#ifdef CONFIG_PAX_MPROTECT
26642 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
26643 +               if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
26644 +                       newflags &= ~VM_MAYWRITE;
26645 +#endif
26646 +
26647                 error = security_file_mprotect(vma, reqprot, prot);
26648                 if (error)
26649                         goto out;
26650 @@ -297,6 +491,9 @@ sys_mprotect(unsigned long start, size_t
26651                         goto out;
26652                 }
26653         }
26654 +
26655 +       track_exec_limit(current->mm, start, end, vm_flags);
26656 +
26657  out:
26658         up_write(&current->mm->mmap_sem);
26659         return error;
26660 diff -urNp linux-2.6.18/mm/mremap.c linux-2.6.18/mm/mremap.c
26661 --- linux-2.6.18/mm/mremap.c    2006-09-19 23:42:06.000000000 -0400
26662 +++ linux-2.6.18/mm/mremap.c    2006-09-22 20:45:04.000000000 -0400
26663 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
26664                 pte = ptep_clear_flush(vma, old_addr, old_pte);
26665                 /* ZERO_PAGE can be dependant on virtual addr */
26666                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
26667 +
26668 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
26669 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
26670 +                       pte_exprotect(pte);
26671 +#endif
26672 +
26673                 set_pte_at(mm, new_addr, new_pte, pte);
26674         }
26675  
26676 @@ -253,6 +259,7 @@ unsigned long do_mremap(unsigned long ad
26677         struct vm_area_struct *vma;
26678         unsigned long ret = -EINVAL;
26679         unsigned long charged = 0;
26680 +       unsigned long task_size = TASK_SIZE;
26681  
26682         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
26683                 goto out;
26684 @@ -271,6 +278,15 @@ unsigned long do_mremap(unsigned long ad
26685         if (!new_len)
26686                 goto out;
26687  
26688 +#ifdef CONFIG_PAX_SEGMEXEC
26689 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
26690 +               task_size = SEGMEXEC_TASK_SIZE;
26691 +#endif
26692 +
26693 +       if (new_len > task_size || addr > task_size-new_len ||
26694 +           old_len > task_size || addr > task_size-old_len)
26695 +               goto out;
26696 +
26697         /* new_addr is only valid if MREMAP_FIXED is specified */
26698         if (flags & MREMAP_FIXED) {
26699                 if (new_addr & ~PAGE_MASK)
26700 @@ -278,16 +294,13 @@ unsigned long do_mremap(unsigned long ad
26701                 if (!(flags & MREMAP_MAYMOVE))
26702                         goto out;
26703  
26704 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
26705 +               if (new_addr > task_size - new_len)
26706                         goto out;
26707  
26708                 /* Check if the location we're moving into overlaps the
26709                  * old location at all, and fail if it does.
26710                  */
26711 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
26712 -                       goto out;
26713 -
26714 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
26715 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
26716                         goto out;
26717  
26718                 ret = do_munmap(mm, new_addr, new_len);
26719 @@ -321,6 +334,14 @@ unsigned long do_mremap(unsigned long ad
26720                 ret = -EINVAL;
26721                 goto out;
26722         }
26723 +
26724 +#ifdef CONFIG_PAX_SEGMEXEC
26725 +       if (vma->vm_flags & VM_MIRROR) {
26726 +               ret = -EINVAL;
26727 +               goto out;
26728 +       }
26729 +#endif
26730 +
26731         /* We can't remap across vm area boundaries */
26732         if (old_len > vma->vm_end - addr)
26733                 goto out;
26734 @@ -354,7 +375,7 @@ unsigned long do_mremap(unsigned long ad
26735         if (old_len == vma->vm_end - addr &&
26736             !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
26737             (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
26738 -               unsigned long max_addr = TASK_SIZE;
26739 +               unsigned long max_addr = task_size;
26740                 if (vma->vm_next)
26741                         max_addr = vma->vm_next->vm_start;
26742                 /* can we just expand the current mapping? */
26743 @@ -372,6 +393,7 @@ unsigned long do_mremap(unsigned long ad
26744                                                    addr + new_len);
26745                         }
26746                         ret = addr;
26747 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
26748                         goto out;
26749                 }
26750         }
26751 @@ -382,8 +404,8 @@ unsigned long do_mremap(unsigned long ad
26752          */
26753         ret = -ENOMEM;
26754         if (flags & MREMAP_MAYMOVE) {
26755 +               unsigned long map_flags = 0;
26756                 if (!(flags & MREMAP_FIXED)) {
26757 -                       unsigned long map_flags = 0;
26758                         if (vma->vm_flags & VM_MAYSHARE)
26759                                 map_flags |= MAP_SHARED;
26760  
26761 @@ -393,7 +415,12 @@ unsigned long do_mremap(unsigned long ad
26762                         if (new_addr & ~PAGE_MASK)
26763                                 goto out;
26764                 }
26765 +               map_flags = vma->vm_flags;
26766                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
26767 +               if (!(ret & ~PAGE_MASK)) {
26768 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
26769 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
26770 +               }
26771         }
26772  out:
26773         if (ret & ~PAGE_MASK)
26774 diff -urNp linux-2.6.18/mm/page_alloc.c linux-2.6.18/mm/page_alloc.c
26775 --- linux-2.6.18/mm/page_alloc.c        2006-09-19 23:42:06.000000000 -0400
26776 +++ linux-2.6.18/mm/page_alloc.c        2006-09-22 20:45:04.000000000 -0400
26777 @@ -339,7 +339,7 @@ static inline int page_is_buddy(struct p
26778  static inline void __free_one_page(struct page *page,
26779                 struct zone *zone, unsigned int order)
26780  {
26781 -       unsigned long page_idx;
26782 +       unsigned long page_idx, index;
26783         int order_size = 1 << order;
26784  
26785         if (unlikely(PageCompound(page)))
26786 @@ -350,6 +350,11 @@ static inline void __free_one_page(struc
26787         BUG_ON(page_idx & (order_size - 1));
26788         BUG_ON(bad_range(zone, page));
26789  
26790 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
26791 +       for (index = order_size; index; --index)
26792 +               clear_highpage(page + index - 1);
26793 +#endif
26794 +
26795         zone->free_pages += order_size;
26796         while (order < MAX_ORDER-1) {
26797                 unsigned long combined_idx;
26798 diff -urNp linux-2.6.18/mm/rmap.c linux-2.6.18/mm/rmap.c
26799 --- linux-2.6.18/mm/rmap.c      2006-09-19 23:42:06.000000000 -0400
26800 +++ linux-2.6.18/mm/rmap.c      2006-09-22 20:45:04.000000000 -0400
26801 @@ -106,6 +106,19 @@ int anon_vma_prepare(struct vm_area_stru
26802                         list_add_tail(&vma->anon_vma_node, &anon_vma->head);
26803                         allocated = NULL;
26804                 }
26805 +
26806 +#ifdef CONFIG_PAX_SEGMEXEC
26807 +               if (vma->vm_flags & VM_MIRROR) {
26808 +                       struct vm_area_struct *vma_m;
26809 +
26810 +                       vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
26811 +                       BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
26812 +                       BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
26813 +                       vma_m->anon_vma = anon_vma;
26814 +                       __anon_vma_link(vma_m);
26815 +               }
26816 +#endif
26817 +
26818                 spin_unlock(&mm->page_table_lock);
26819  
26820                 if (locked)
26821 diff -urNp linux-2.6.18/mm/shmem.c linux-2.6.18/mm/shmem.c
26822 --- linux-2.6.18/mm/shmem.c     2006-09-19 23:42:06.000000000 -0400
26823 +++ linux-2.6.18/mm/shmem.c     2006-09-22 20:04:35.000000000 -0400
26824 @@ -2235,7 +2235,7 @@ static struct file_system_type tmpfs_fs_
26825         .get_sb         = shmem_get_sb,
26826         .kill_sb        = kill_litter_super,
26827  };
26828 -static struct vfsmount *shm_mnt;
26829 +struct vfsmount *shm_mnt;
26830  
26831  static int __init init_tmpfs(void)
26832  {
26833 diff -urNp linux-2.6.18/mm/slab.c linux-2.6.18/mm/slab.c
26834 --- linux-2.6.18/mm/slab.c      2006-09-19 23:42:06.000000000 -0400
26835 +++ linux-2.6.18/mm/slab.c      2006-09-22 20:45:04.000000000 -0400
26836 @@ -1613,6 +1613,11 @@ static void store_stackinfo(struct kmem_
26837  
26838                 while (!kstack_end(sptr)) {
26839                         svalue = *sptr++;
26840 +
26841 +#ifdef CONFIG_PAX_KERNEXEC
26842 +                       svalue += __KERNEL_TEXT_OFFSET;
26843 +#endif
26844 +
26845                         if (kernel_text_address(svalue)) {
26846                                 *addr++ = svalue;
26847                                 size -= sizeof(unsigned long);
26848 diff -urNp linux-2.6.18/mm/tiny-shmem.c linux-2.6.18/mm/tiny-shmem.c
26849 --- linux-2.6.18/mm/tiny-shmem.c        2006-09-19 23:42:06.000000000 -0400
26850 +++ linux-2.6.18/mm/tiny-shmem.c        2006-09-22 20:04:35.000000000 -0400
26851 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
26852         .kill_sb        = kill_litter_super,
26853  };
26854  
26855 -static struct vfsmount *shm_mnt;
26856 +struct vfsmount *shm_mnt;
26857  
26858  static int __init init_tmpfs(void)
26859  {
26860 diff -urNp linux-2.6.18/mm/vmalloc.c linux-2.6.18/mm/vmalloc.c
26861 --- linux-2.6.18/mm/vmalloc.c   2006-09-19 23:42:06.000000000 -0400
26862 +++ linux-2.6.18/mm/vmalloc.c   2006-09-22 20:45:04.000000000 -0400
26863 @@ -193,6 +193,8 @@ struct vm_struct *__get_vm_area_node(uns
26864  
26865         write_lock(&vmlist_lock);
26866         for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
26867 +               if (addr > end - size)
26868 +                       goto out;
26869                 if ((unsigned long)tmp->addr < addr) {
26870                         if((unsigned long)tmp->addr + tmp->size >= addr)
26871                                 addr = ALIGN(tmp->size + 
26872 @@ -204,8 +206,6 @@ struct vm_struct *__get_vm_area_node(uns
26873                 if (size + addr <= (unsigned long)tmp->addr)
26874                         goto found;
26875                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
26876 -               if (addr > end - size)
26877 -                       goto out;
26878         }
26879  
26880  found:
26881 diff -urNp linux-2.6.18/net/core/sock.c linux-2.6.18/net/core/sock.c
26882 --- linux-2.6.18/net/core/sock.c        2006-09-19 23:42:06.000000000 -0400
26883 +++ linux-2.6.18/net/core/sock.c        2006-09-22 20:45:04.000000000 -0400
26884 @@ -808,7 +808,7 @@ lenout:
26885   *
26886   * (We also register the sk_lock with the lock validator.)
26887   */
26888 -static void inline sock_lock_init(struct sock *sk)
26889 +static inline void sock_lock_init(struct sock *sk)
26890  {
26891         spin_lock_init(&sk->sk_lock.slock);
26892         sk->sk_lock.owner = NULL;
26893 diff -urNp linux-2.6.18/net/dccp/ccids/ccid3.c linux-2.6.18/net/dccp/ccids/ccid3.c
26894 --- linux-2.6.18/net/dccp/ccids/ccid3.c 2006-09-19 23:42:06.000000000 -0400
26895 +++ linux-2.6.18/net/dccp/ccids/ccid3.c 2006-09-22 20:45:04.000000000 -0400
26896 @@ -68,7 +68,7 @@ static int ccid3_debug;
26897                 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
26898         } while (0)
26899  #else
26900 -#define ccid3_pr_debug(format, a...)
26901 +#define ccid3_pr_debug(format, a...) do {} while (0)
26902  #endif
26903  
26904  static struct dccp_tx_hist *ccid3_tx_hist;
26905 diff -urNp linux-2.6.18/net/dccp/dccp.h linux-2.6.18/net/dccp/dccp.h
26906 --- linux-2.6.18/net/dccp/dccp.h        2006-09-19 23:42:06.000000000 -0400
26907 +++ linux-2.6.18/net/dccp/dccp.h        2006-09-22 20:45:04.000000000 -0400
26908 @@ -28,8 +28,8 @@ extern int dccp_debug;
26909  #define dccp_pr_debug_cat(format, a...) do { if (dccp_debug) \
26910                                              printk(format, ##a); } while (0)
26911  #else
26912 -#define dccp_pr_debug(format, a...)
26913 -#define dccp_pr_debug_cat(format, a...)
26914 +#define dccp_pr_debug(format, a...) do {} while (0)
26915 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
26916  #endif
26917  
26918  extern struct inet_hashinfo dccp_hashinfo;
26919 diff -urNp linux-2.6.18/net/ipv4/inet_connection_sock.c linux-2.6.18/net/ipv4/inet_connection_sock.c
26920 --- linux-2.6.18/net/ipv4/inet_connection_sock.c        2006-09-19 23:42:06.000000000 -0400
26921 +++ linux-2.6.18/net/ipv4/inet_connection_sock.c        2006-09-22 20:04:35.000000000 -0400
26922 @@ -15,6 +15,7 @@
26923  
26924  #include <linux/module.h>
26925  #include <linux/jhash.h>
26926 +#include <linux/grsecurity.h>
26927  
26928  #include <net/inet_connection_sock.h>
26929  #include <net/inet_hashtables.h>
26930 diff -urNp linux-2.6.18/net/ipv4/inet_hashtables.c linux-2.6.18/net/ipv4/inet_hashtables.c
26931 --- linux-2.6.18/net/ipv4/inet_hashtables.c     2006-09-19 23:42:06.000000000 -0400
26932 +++ linux-2.6.18/net/ipv4/inet_hashtables.c     2006-09-22 20:04:35.000000000 -0400
26933 @@ -18,11 +18,14 @@
26934  #include <linux/sched.h>
26935  #include <linux/slab.h>
26936  #include <linux/wait.h>
26937 +#include <linux/grsecurity.h>
26938  
26939  #include <net/inet_connection_sock.h>
26940  #include <net/inet_hashtables.h>
26941  #include <net/ip.h>
26942  
26943 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
26944 +
26945  /*
26946   * Allocate and initialize a new local port bind bucket.
26947   * The bindhash mutex for snum's hash chain must be held here.
26948 @@ -309,6 +312,8 @@ ok:
26949                 }
26950                 spin_unlock(&head->lock);
26951  
26952 +               gr_update_task_in_ip_table(current, inet_sk(sk));
26953 +
26954                 if (tw) {
26955                         inet_twsk_deschedule(tw, death_row);
26956                         inet_twsk_put(tw);
26957 diff -urNp linux-2.6.18/net/ipv4/netfilter/ipt_stealth.c linux-2.6.18/net/ipv4/netfilter/ipt_stealth.c
26958 --- linux-2.6.18/net/ipv4/netfilter/ipt_stealth.c       1969-12-31 19:00:00.000000000 -0500
26959 +++ linux-2.6.18/net/ipv4/netfilter/ipt_stealth.c       2006-09-22 20:04:35.000000000 -0400
26960 @@ -0,0 +1,116 @@
26961 +/* Kernel module to add stealth support.
26962 + *
26963 + * Copyright (C) 2002,2005 Brad Spengler  <spender@grsecurity.net>
26964 + *
26965 + */
26966 +
26967 +#include <linux/kernel.h>
26968 +#include <linux/module.h>
26969 +#include <linux/skbuff.h>
26970 +#include <linux/net.h>
26971 +#include <linux/sched.h>
26972 +#include <linux/inet.h>
26973 +#include <linux/stddef.h>
26974 +
26975 +#include <net/ip.h>
26976 +#include <net/sock.h>
26977 +#include <net/tcp.h>
26978 +#include <net/udp.h>
26979 +#include <net/route.h>
26980 +#include <net/inet_common.h>
26981 +
26982 +#include <linux/netfilter_ipv4/ip_tables.h>
26983 +
26984 +MODULE_LICENSE("GPL");
26985 +
26986 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
26987 +
26988 +static int
26989 +match(const struct sk_buff *skb,
26990 +      const struct net_device *in,
26991 +      const struct net_device *out,
26992 +      const struct xt_match *match,
26993 +      const void *matchinfo,
26994 +      int offset,
26995 +      unsigned int protoff,
26996 +      int *hotdrop)
26997 +{
26998 +       struct iphdr *ip = skb->nh.iph;
26999 +       struct tcphdr th;
27000 +       struct udphdr uh;
27001 +       struct sock *sk = NULL;
27002 +
27003 +       if (!ip || offset) return 0;
27004 +
27005 +       switch(ip->protocol) {
27006 +       case IPPROTO_TCP:
27007 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
27008 +                       *hotdrop = 1;
27009 +                       return 0;
27010 +               }
27011 +               if (!(th.syn && !th.ack)) return 0;
27012 +               sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);        
27013 +               break;
27014 +       case IPPROTO_UDP:
27015 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
27016 +                       *hotdrop = 1;
27017 +                       return 0;
27018 +               }
27019 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
27020 +               break;
27021 +       default:
27022 +               return 0;
27023 +       }
27024 +
27025 +       if(!sk) // port is being listened on, match this
27026 +               return 1;
27027 +       else {
27028 +               sock_put(sk);
27029 +               return 0;
27030 +       }
27031 +}
27032 +
27033 +/* Called when user tries to insert an entry of this type. */
27034 +static int
27035 +checkentry(const char *tablename,
27036 +           const void *nip,
27037 +          const struct xt_match *match,
27038 +           void *matchinfo,
27039 +           unsigned int matchsize,
27040 +           unsigned int hook_mask)
27041 +{
27042 +       const struct ipt_ip *ip = (const struct ipt_ip *)nip;
27043 +        if (matchsize != IPT_ALIGN(0))
27044 +                return 0;
27045 +
27046 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
27047 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
27048 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
27049 +                       return 1;
27050 +
27051 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
27052 +
27053 +        return 0;
27054 +}
27055 +
27056 +
27057 +static struct ipt_match stealth_match = {
27058 +       .name = "stealth",
27059 +       .match = match,
27060 +       .checkentry = checkentry,
27061 +       .destroy = NULL,
27062 +       .me = THIS_MODULE
27063 +};
27064 +
27065 +static int __init init(void)
27066 +{
27067 +       return ipt_register_match(&stealth_match);
27068 +}
27069 +
27070 +static void __exit fini(void)
27071 +{
27072 +       ipt_unregister_match(&stealth_match);
27073 +}
27074 +
27075 +module_init(init);
27076 +module_exit(fini);
27077 diff -urNp linux-2.6.18/net/ipv4/netfilter/Kconfig linux-2.6.18/net/ipv4/netfilter/Kconfig
27078 --- linux-2.6.18/net/ipv4/netfilter/Kconfig     2006-09-19 23:42:06.000000000 -0400
27079 +++ linux-2.6.18/net/ipv4/netfilter/Kconfig     2006-09-22 20:04:35.000000000 -0400
27080 @@ -340,6 +340,21 @@ config IP_NF_MATCH_HASHLIMIT
27081           destination IP' or `500pps from any given source IP'  with a single
27082           IPtables rule.
27083  
27084 +config IP_NF_MATCH_STEALTH
27085 +       tristate "stealth match support"
27086 +       depends on IP_NF_IPTABLES
27087 +       help
27088 +         Enabling this option will drop all syn packets coming to unserved tcp
27089 +         ports as well as all packets coming to unserved udp ports.  If you
27090 +         are using your system to route any type of packets (ie. via NAT)
27091 +         you should put this module at the end of your ruleset, since it will
27092 +         drop packets that aren't going to ports that are listening on your
27093 +         machine itself, it doesn't take into account that the packet might be
27094 +         destined for someone on your internal network if you're using NAT for
27095 +         instance.
27096 +
27097 +         To compile it as a module, choose M here.  If unsure, say N.
27098 +
27099  # `filter', generic and specific targets
27100  config IP_NF_FILTER
27101         tristate "Packet filtering"
27102 @@ -646,4 +661,3 @@ config IP_NF_ARP_MANGLE
27103           hardware and network addresses.
27104  
27105  endmenu
27106 -
27107 diff -urNp linux-2.6.18/net/ipv4/netfilter/Makefile linux-2.6.18/net/ipv4/netfilter/Makefile
27108 --- linux-2.6.18/net/ipv4/netfilter/Makefile    2006-09-19 23:42:06.000000000 -0400
27109 +++ linux-2.6.18/net/ipv4/netfilter/Makefile    2006-09-22 20:04:35.000000000 -0400
27110 @@ -63,6 +63,7 @@ obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_ds
27111  obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
27112  obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
27113  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
27114 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
27115  
27116  # targets
27117  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
27118 diff -urNp linux-2.6.18/net/ipv4/tcp_ipv4.c linux-2.6.18/net/ipv4/tcp_ipv4.c
27119 --- linux-2.6.18/net/ipv4/tcp_ipv4.c    2006-09-19 23:42:06.000000000 -0400
27120 +++ linux-2.6.18/net/ipv4/tcp_ipv4.c    2006-09-22 20:04:35.000000000 -0400
27121 @@ -61,6 +61,7 @@
27122  #include <linux/jhash.h>
27123  #include <linux/init.h>
27124  #include <linux/times.h>
27125 +#include <linux/grsecurity.h>
27126  
27127  #include <net/icmp.h>
27128  #include <net/inet_hashtables.h>
27129 diff -urNp linux-2.6.18/net/ipv4/tcp_lp.c linux-2.6.18/net/ipv4/tcp_lp.c
27130 --- linux-2.6.18/net/ipv4/tcp_lp.c      2006-09-19 23:42:06.000000000 -0400
27131 +++ linux-2.6.18/net/ipv4/tcp_lp.c      2006-09-22 20:45:04.000000000 -0400
27132 @@ -165,7 +165,7 @@ static u32 tcp_lp_remote_hz_estimator(st
27133  
27134   out:
27135         /* record time for successful remote HZ calc */
27136 -       if (rhz > 0)
27137 +       if (rhz > 63)
27138                 lp->flag |= LP_VALID_RHZ;
27139         else
27140                 lp->flag &= ~LP_VALID_RHZ;
27141 diff -urNp linux-2.6.18/net/ipv4/udp.c linux-2.6.18/net/ipv4/udp.c
27142 --- linux-2.6.18/net/ipv4/udp.c 2006-09-19 23:42:06.000000000 -0400
27143 +++ linux-2.6.18/net/ipv4/udp.c 2006-09-22 20:04:35.000000000 -0400
27144 @@ -101,6 +101,7 @@
27145  #include <linux/skbuff.h>
27146  #include <linux/proc_fs.h>
27147  #include <linux/seq_file.h>
27148 +#include <linux/grsecurity.h>
27149  #include <net/sock.h>
27150  #include <net/udp.h>
27151  #include <net/icmp.h>
27152 @@ -109,6 +110,12 @@
27153  #include <net/checksum.h>
27154  #include <net/xfrm.h>
27155  
27156 +extern int gr_search_udp_recvmsg(const struct sock *sk,
27157 +                                const struct sk_buff *skb);
27158 +extern int gr_search_udp_sendmsg(const struct sock *sk,
27159 +                                const struct sockaddr_in *addr);
27160 +
27161 +
27162  /*
27163   *     Snmp MIB for the UDP layer
27164   */
27165 @@ -265,8 +272,7 @@ static struct sock *udp_v4_lookup_longwa
27166         return result;
27167  }
27168  
27169 -static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
27170 -                                            u32 daddr, u16 dport, int dif)
27171 +struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
27172  {
27173         struct sock *sk;
27174  
27175 @@ -541,9 +547,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
27176                 dport = usin->sin_port;
27177                 if (dport == 0)
27178                         return -EINVAL;
27179 +
27180 +               if (!gr_search_udp_sendmsg(sk, usin))
27181 +                       return -EPERM;
27182         } else {
27183                 if (sk->sk_state != TCP_ESTABLISHED)
27184                         return -EDESTADDRREQ;
27185 +
27186 +               if (!gr_search_udp_sendmsg(sk, NULL))
27187 +                       return -EPERM;
27188 +
27189                 daddr = inet->daddr;
27190                 dport = inet->dport;
27191                 /* Open fast path for connected socket.
27192 @@ -797,6 +810,11 @@ try_again:
27193         if (!skb)
27194                 goto out;
27195    
27196 +       if (!gr_search_udp_recvmsg(sk, skb)) {
27197 +               err = -EPERM;
27198 +               goto out_free;
27199 +       }
27200 +
27201         copied = skb->len - sizeof(struct udphdr);
27202         if (copied > len) {
27203                 copied = len;
27204 diff -urNp linux-2.6.18/net/ipv6/addrconf.c linux-2.6.18/net/ipv6/addrconf.c
27205 --- linux-2.6.18/net/ipv6/addrconf.c    2006-09-19 23:42:06.000000000 -0400
27206 +++ linux-2.6.18/net/ipv6/addrconf.c    2006-09-22 20:45:04.000000000 -0400
27207 @@ -861,7 +861,7 @@ struct ipv6_saddr_score {
27208  #define IPV6_SADDR_SCORE_LABEL         0x0020
27209  #define IPV6_SADDR_SCORE_PRIVACY       0x0040
27210  
27211 -static int inline ipv6_saddr_preferred(int type)
27212 +static inline int ipv6_saddr_preferred(int type)
27213  {
27214         if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
27215                     IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
27216 @@ -870,7 +870,7 @@ static int inline ipv6_saddr_preferred(i
27217  }
27218  
27219  /* static matching label */
27220 -static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
27221 +static inline int ipv6_saddr_label(const struct in6_addr *addr, int type)
27222  {
27223   /*
27224    *    prefix (longest match)  label
27225 @@ -3297,7 +3297,7 @@ static void inet6_ifa_notify(int event, 
27226         netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFADDR, GFP_ATOMIC);
27227  }
27228  
27229 -static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
27230 +static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
27231                                 __s32 *array, int bytes)
27232  {
27233         memset(array, 0, bytes);
27234 diff -urNp linux-2.6.18/net/ipv6/raw.c linux-2.6.18/net/ipv6/raw.c
27235 --- linux-2.6.18/net/ipv6/raw.c 2006-09-19 23:42:06.000000000 -0400
27236 +++ linux-2.6.18/net/ipv6/raw.c 2006-09-22 20:45:04.000000000 -0400
27237 @@ -522,7 +522,7 @@ out:
27238         return err;
27239  }
27240  
27241 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
27242 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
27243                         struct flowi *fl, struct rt6_info *rt, 
27244                         unsigned int flags)
27245  {
27246 @@ -644,7 +644,7 @@ static int rawv6_sendmsg(struct kiocb *i
27247         /* Rough check on arithmetic overflow,
27248            better check is made in ip6_build_xmit
27249          */
27250 -       if (len < 0)
27251 +       if ((ssize_t)len < 0)
27252                 return -EMSGSIZE;
27253  
27254         /* Mirror BSD error message compatibility */
27255 diff -urNp linux-2.6.18/net/ipv6/route.c linux-2.6.18/net/ipv6/route.c
27256 --- linux-2.6.18/net/ipv6/route.c       2006-09-19 23:42:06.000000000 -0400
27257 +++ linux-2.6.18/net/ipv6/route.c       2006-09-22 20:45:04.000000000 -0400
27258 @@ -265,7 +265,7 @@ static inline void rt6_probe(struct rt6_
27259  /*
27260   * Default Router Selection (RFC 2461 6.3.6)
27261   */
27262 -static int inline rt6_check_dev(struct rt6_info *rt, int oif)
27263 +static inline int rt6_check_dev(struct rt6_info *rt, int oif)
27264  {
27265         struct net_device *dev = rt->rt6i_dev;
27266         if (!oif || dev->ifindex == oif)
27267 @@ -276,7 +276,7 @@ static int inline rt6_check_dev(struct r
27268         return 0;
27269  }
27270  
27271 -static int inline rt6_check_neigh(struct rt6_info *rt)
27272 +static inline int rt6_check_neigh(struct rt6_info *rt)
27273  {
27274         struct neighbour *neigh = rt->rt6i_nexthop;
27275         int m = 0;
27276 diff -urNp linux-2.6.18/net/ipv6/xfrm6_tunnel.c linux-2.6.18/net/ipv6/xfrm6_tunnel.c
27277 --- linux-2.6.18/net/ipv6/xfrm6_tunnel.c        2006-09-19 23:42:06.000000000 -0400
27278 +++ linux-2.6.18/net/ipv6/xfrm6_tunnel.c        2006-09-22 20:45:04.000000000 -0400
27279 @@ -58,7 +58,7 @@ static kmem_cache_t *xfrm6_tunnel_spi_km
27280  static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
27281  static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
27282  
27283 -static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
27284 +static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
27285  {
27286         unsigned h;
27287  
27288 @@ -70,7 +70,7 @@ static unsigned inline xfrm6_tunnel_spi_
27289         return h;
27290  }
27291  
27292 -static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi)
27293 +static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
27294  {
27295         return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
27296  }
27297 diff -urNp linux-2.6.18/net/sctp/sm_statetable.c linux-2.6.18/net/sctp/sm_statetable.c
27298 --- linux-2.6.18/net/sctp/sm_statetable.c       2006-09-19 23:42:06.000000000 -0400
27299 +++ linux-2.6.18/net/sctp/sm_statetable.c       2006-09-22 20:45:04.000000000 -0400
27300 @@ -986,7 +986,7 @@ static const sctp_sm_table_entry_t *sctp
27301         if (state > SCTP_STATE_MAX)
27302                 return &bug;
27303  
27304 -       if (cid >= 0 && cid <= SCTP_CID_BASE_MAX)
27305 +       if (cid <= SCTP_CID_BASE_MAX)
27306                 return &chunk_event_table[cid][state];
27307  
27308         if (sctp_prsctp_enable) {
27309 diff -urNp linux-2.6.18/net/socket.c linux-2.6.18/net/socket.c
27310 --- linux-2.6.18/net/socket.c   2006-09-19 23:42:06.000000000 -0400
27311 +++ linux-2.6.18/net/socket.c   2006-09-22 20:04:35.000000000 -0400
27312 @@ -85,6 +85,7 @@
27313  #include <linux/kmod.h>
27314  #include <linux/audit.h>
27315  #include <linux/wireless.h>
27316 +#include <linux/in.h>
27317  
27318  #include <asm/uaccess.h>
27319  #include <asm/unistd.h>
27320 @@ -94,6 +95,21 @@
27321  #include <net/sock.h>
27322  #include <linux/netfilter.h>
27323  
27324 +extern void gr_attach_curr_ip(const struct sock *sk);
27325 +extern int gr_handle_sock_all(const int family, const int type,
27326 +                             const int protocol);
27327 +extern int gr_handle_sock_server(const struct sockaddr *sck);
27328 +extern int gr_handle_sock_server_other(const struct socket *sck);
27329 +extern int gr_handle_sock_client(const struct sockaddr *sck);
27330 +extern int gr_search_connect(const struct socket * sock,
27331 +                            const struct sockaddr_in * addr);
27332 +extern int gr_search_bind(const struct socket * sock,
27333 +                          const struct sockaddr_in * addr);
27334 +extern int gr_search_listen(const struct socket * sock);
27335 +extern int gr_search_accept(const struct socket * sock);
27336 +extern int gr_search_socket(const int domain, const int type,
27337 +                           const int protocol);
27338 +
27339  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
27340  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
27341                          size_t size, loff_t pos);
27342 @@ -341,7 +357,7 @@ static int sockfs_get_sb(struct file_sys
27343                              mnt);
27344  }
27345  
27346 -static struct vfsmount *sock_mnt __read_mostly;
27347 +struct vfsmount *sock_mnt __read_mostly;
27348  
27349  static struct file_system_type sock_fs_type = {
27350         .name =         "sockfs",
27351 @@ -1241,6 +1257,16 @@ asmlinkage long sys_socket(int family, i
27352         int retval;
27353         struct socket *sock;
27354  
27355 +       if(!gr_search_socket(family, type, protocol)) {
27356 +               retval = -EACCES;
27357 +               goto out;
27358 +       }
27359 +
27360 +       if (gr_handle_sock_all(family, type, protocol)) {
27361 +               retval = -EACCES;
27362 +               goto out;
27363 +       }
27364 +
27365         retval = sock_create(family, type, protocol, &sock);
27366         if (retval < 0)
27367                 goto out;
27368 @@ -1336,16 +1362,25 @@ asmlinkage long sys_bind(int fd, struct 
27369  {
27370         struct socket *sock;
27371         char address[MAX_SOCK_ADDR];
27372 +       struct sockaddr *sck;
27373         int err, fput_needed;
27374  
27375         if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
27376         {
27377                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
27378 +                       sck = (struct sockaddr *)address;
27379 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck) ||
27380 +                           gr_handle_sock_server(sck)) {
27381 +                               err = -EACCES;
27382 +                               goto error;
27383 +                       }
27384 +
27385                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
27386                         if (!err)
27387                                 err = sock->ops->bind(sock,
27388                                         (struct sockaddr *)address, addrlen);
27389                 }
27390 +error:
27391                 fput_light(sock->file, fput_needed);
27392         }                       
27393         return err;
27394 @@ -1369,10 +1404,17 @@ asmlinkage long sys_listen(int fd, int b
27395                 if ((unsigned) backlog > sysctl_somaxconn)
27396                         backlog = sysctl_somaxconn;
27397  
27398 +               if (gr_handle_sock_server_other(sock) ||
27399 +                   !gr_search_listen(sock)) {
27400 +                       err = -EPERM;
27401 +                       goto error;
27402 +               }
27403 +
27404                 err = security_socket_listen(sock, backlog);
27405                 if (!err)
27406                         err = sock->ops->listen(sock, backlog);
27407  
27408 +error:
27409                 fput_light(sock->file, fput_needed);
27410         }
27411         return err;
27412 @@ -1409,6 +1451,13 @@ asmlinkage long sys_accept(int fd, struc
27413         newsock->type = sock->type;
27414         newsock->ops = sock->ops;
27415  
27416 +       if (gr_handle_sock_server_other(sock) ||
27417 +           !gr_search_accept(sock)) {
27418 +               err = -EPERM;
27419 +               sock_release(newsock);
27420 +               goto out_put;
27421 +       }
27422 +
27423         /*
27424          * We don't need try_module_get here, as the listening socket (sock)
27425          * has the protocol module (sock->ops->owner) held.
27426 @@ -1450,6 +1499,7 @@ asmlinkage long sys_accept(int fd, struc
27427         err = newfd;
27428  
27429         security_socket_post_accept(sock, newsock);
27430 +       gr_attach_curr_ip(newsock->sk);
27431  
27432  out_put:
27433         fput_light(sock->file, fput_needed);
27434 @@ -1478,6 +1528,7 @@ asmlinkage long sys_connect(int fd, stru
27435  {
27436         struct socket *sock;
27437         char address[MAX_SOCK_ADDR];
27438 +       struct sockaddr *sck;
27439         int err, fput_needed;
27440  
27441         sock = sockfd_lookup_light(fd, &err, &fput_needed);
27442 @@ -1487,6 +1538,13 @@ asmlinkage long sys_connect(int fd, stru
27443         if (err < 0)
27444                 goto out_put;
27445  
27446 +       sck = (struct sockaddr *)address;
27447 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
27448 +           gr_handle_sock_client(sck)) {
27449 +               err = -EACCES;
27450 +               goto out_put;
27451 +       }
27452 +
27453         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
27454         if (err)
27455                 goto out_put;
27456 @@ -1741,6 +1799,7 @@ asmlinkage long sys_shutdown(int fd, int
27457                         err = sock->ops->shutdown(sock, how);
27458                 fput_light(sock->file, fput_needed);
27459         }
27460 +
27461         return err;
27462  }
27463  
27464 diff -urNp linux-2.6.18/net/unix/af_unix.c linux-2.6.18/net/unix/af_unix.c
27465 --- linux-2.6.18/net/unix/af_unix.c     2006-09-19 23:42:06.000000000 -0400
27466 +++ linux-2.6.18/net/unix/af_unix.c     2006-09-22 20:04:35.000000000 -0400
27467 @@ -116,6 +116,7 @@
27468  #include <linux/mount.h>
27469  #include <net/checksum.h>
27470  #include <linux/security.h>
27471 +#include <linux/grsecurity.h>
27472  
27473  int sysctl_unix_max_dgram_qlen = 10;
27474  
27475 @@ -706,6 +707,11 @@ static struct sock *unix_find_other(stru
27476                 if (err)
27477                         goto put_fail;
27478  
27479 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
27480 +                       err = -EACCES;
27481 +                       goto put_fail;
27482 +               }
27483 +
27484                 err = -ECONNREFUSED;
27485                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
27486                         goto put_fail;
27487 @@ -729,6 +735,13 @@ static struct sock *unix_find_other(stru
27488                 if (u) {
27489                         struct dentry *dentry;
27490                         dentry = unix_sk(u)->dentry;
27491 +
27492 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
27493 +                               err = -EPERM;
27494 +                               sock_put(u);
27495 +                               goto fail;
27496 +                       }
27497 +
27498                         if (dentry)
27499                                 touch_atime(unix_sk(u)->mnt, dentry);
27500                 } else
27501 @@ -807,9 +820,18 @@ static int unix_bind(struct socket *sock
27502                  */
27503                 mode = S_IFSOCK |
27504                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
27505 +
27506 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
27507 +                       err = -EACCES;
27508 +                       goto out_mknod_dput;
27509 +               }
27510 +
27511                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
27512                 if (err)
27513                         goto out_mknod_dput;
27514 +
27515 +               gr_handle_create(dentry, nd.mnt);
27516 +
27517                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
27518                 dput(nd.dentry);
27519                 nd.dentry = dentry;
27520 @@ -827,6 +849,10 @@ static int unix_bind(struct socket *sock
27521                         goto out_unlock;
27522                 }
27523  
27524 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
27525 +               sk->sk_peercred.pid = current->pid;
27526 +#endif
27527 +
27528                 list = &unix_socket_table[addr->hash];
27529         } else {
27530                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
27531 diff -urNp linux-2.6.18/net/xfrm/xfrm_user.c linux-2.6.18/net/xfrm/xfrm_user.c
27532 --- linux-2.6.18/net/xfrm/xfrm_user.c   2006-09-19 23:42:06.000000000 -0400
27533 +++ linux-2.6.18/net/xfrm/xfrm_user.c   2006-09-22 20:45:04.000000000 -0400
27534 @@ -1584,7 +1584,7 @@ nlmsg_failure:
27535         return -1;
27536  }
27537  
27538 -static int inline xfrm_sa_len(struct xfrm_state *x)
27539 +static inline int xfrm_sa_len(struct xfrm_state *x)
27540  {
27541         int l = 0;
27542         if (x->aalg)
27543 diff -urNp linux-2.6.18/security/commoncap.c linux-2.6.18/security/commoncap.c
27544 --- linux-2.6.18/security/commoncap.c   2006-09-19 23:42:06.000000000 -0400
27545 +++ linux-2.6.18/security/commoncap.c   2006-09-22 20:04:35.000000000 -0400
27546 @@ -23,6 +23,7 @@
27547  #include <linux/ptrace.h>
27548  #include <linux/xattr.h>
27549  #include <linux/hugetlb.h>
27550 +#include <linux/grsecurity.h>
27551  
27552  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
27553  {
27554 @@ -44,7 +45,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
27555  int cap_capable (struct task_struct *tsk, int cap)
27556  {
27557         /* Derived from include/linux/sched.h:capable. */
27558 -       if (cap_raised(tsk->cap_effective, cap))
27559 +       if (cap_raised (tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
27560 +               return 0;
27561 +       return -EPERM;
27562 +}
27563 +
27564 +int cap_capable_nolog (struct task_struct *tsk, int cap)
27565 +{
27566 +       /* Derived from include/linux/sched.h:capable. */
27567 +       if (cap_raised (tsk->cap_effective, cap))
27568                 return 0;
27569         return -EPERM;
27570  }
27571 @@ -163,8 +172,11 @@ void cap_bprm_apply_creds (struct linux_
27572                 }
27573         }
27574  
27575 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
27576 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
27577 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
27578 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
27579 +
27580 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
27581 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
27582  
27583         /* For init, we want to retain the capabilities set
27584          * in the init_task struct. Thus we skip the usual
27585 @@ -175,6 +187,8 @@ void cap_bprm_apply_creds (struct linux_
27586                     cap_intersect (new_permitted, bprm->cap_effective);
27587         }
27588  
27589 +       gr_handle_chroot_caps(current);
27590 +
27591         /* AUD: Audit candidate if current->cap_effective is set */
27592  
27593         current->keep_capabilities = 0;
27594 @@ -320,12 +334,13 @@ int cap_vm_enough_memory(long pages)
27595  {
27596         int cap_sys_admin = 0;
27597  
27598 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
27599 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
27600                 cap_sys_admin = 1;
27601         return __vm_enough_memory(pages, cap_sys_admin);
27602  }
27603  
27604  EXPORT_SYMBOL(cap_capable);
27605 +EXPORT_SYMBOL(cap_capable_nolog);
27606  EXPORT_SYMBOL(cap_settime);
27607  EXPORT_SYMBOL(cap_ptrace);
27608  EXPORT_SYMBOL(cap_capget);
27609 diff -urNp linux-2.6.18/security/dummy.c linux-2.6.18/security/dummy.c
27610 --- linux-2.6.18/security/dummy.c       2006-09-19 23:42:06.000000000 -0400
27611 +++ linux-2.6.18/security/dummy.c       2006-09-22 20:04:35.000000000 -0400
27612 @@ -28,6 +28,7 @@
27613  #include <linux/hugetlb.h>
27614  #include <linux/ptrace.h>
27615  #include <linux/file.h>
27616 +#include <linux/grsecurity.h>
27617  
27618  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
27619  {
27620 @@ -138,8 +139,11 @@ static void dummy_bprm_apply_creds (stru
27621                 }
27622         }
27623  
27624 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
27625 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
27626 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
27627 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
27628 +
27629 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
27630 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
27631  
27632         dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
27633  }
27634 diff -urNp linux-2.6.18/security/Kconfig linux-2.6.18/security/Kconfig
27635 --- linux-2.6.18/security/Kconfig       2006-09-19 23:42:06.000000000 -0400
27636 +++ linux-2.6.18/security/Kconfig       2006-09-22 20:49:25.000000000 -0400
27637 @@ -4,6 +4,432 @@
27638  
27639  menu "Security options"
27640  
27641 +menu "PaX"
27642 +
27643 +config PAX
27644 +       bool "Enable various PaX features"
27645 +       depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
27646 +       help
27647 +         This allows you to enable various PaX features.  PaX adds
27648 +         intrusion prevention mechanisms to the kernel that reduce
27649 +         the risks posed by exploitable memory corruption bugs.
27650 +
27651 +menu "PaX Control"
27652 +       depends on PAX
27653 +
27654 +config PAX_SOFTMODE
27655 +       bool 'Support soft mode'
27656 +       help
27657 +         Enabling this option will allow you to run PaX in soft mode, that
27658 +         is, PaX features will not be enforced by default, only on executables
27659 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
27660 +         is the only way to mark executables for soft mode use.
27661 +
27662 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
27663 +         line option on boot.  Furthermore you can control various PaX features
27664 +         at runtime via the entries in /proc/sys/kernel/pax.
27665 +
27666 +config PAX_EI_PAX
27667 +       bool 'Use legacy ELF header marking'
27668 +       help
27669 +         Enabling this option will allow you to control PaX features on
27670 +         a per executable basis via the 'chpax' utility available at
27671 +         http://pax.grsecurity.net/.  The control flags will be read from
27672 +         an otherwise reserved part of the ELF header.  This marking has
27673 +         numerous drawbacks (no support for soft-mode, toolchain does not
27674 +         know about the non-standard use of the ELF header) therefore it
27675 +         has been deprecated in favour of PT_PAX_FLAGS support.
27676 +
27677 +         If you have applications not marked by the PT_PAX_FLAGS ELF
27678 +         program header then you MUST enable this option otherwise they
27679 +         will not get any protection.
27680 +
27681 +         Note that if you enable PT_PAX_FLAGS marking support as well,
27682 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
27683 +
27684 +config PAX_PT_PAX_FLAGS
27685 +       bool 'Use ELF program header marking'
27686 +       help
27687 +         Enabling this option will allow you to control PaX features on
27688 +         a per executable basis via the 'paxctl' utility available at
27689 +         http://pax.grsecurity.net/.  The control flags will be read from
27690 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
27691 +         has the benefits of supporting both soft mode and being fully
27692 +         integrated into the toolchain (the binutils patch is available
27693 +         from http://pax.grsecurity.net).
27694 +
27695 +         If you have applications not marked by the PT_PAX_FLAGS ELF
27696 +         program header then you MUST enable the EI_PAX marking support
27697 +         otherwise they will not get any protection.
27698 +
27699 +         Note that if you enable the legacy EI_PAX marking support as well,
27700 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
27701 +
27702 +choice
27703 +       prompt 'MAC system integration'
27704 +       default PAX_NO_ACL_FLAGS
27705 +       help
27706 +         Mandatory Access Control systems have the option of controlling
27707 +         PaX flags on a per executable basis, choose the method supported
27708 +         by your particular system.
27709 +
27710 +         - "none": if your MAC system does not interact with PaX,
27711 +         - "direct": if your MAC system defines pax_set_flags() itself,
27712 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
27713 +
27714 +         NOTE: this option is for developers/integrators only.
27715 +
27716 +config PAX_NO_ACL_FLAGS
27717 +       bool 'none'
27718 +
27719 +config PAX_HAVE_ACL_FLAGS
27720 +       bool 'direct'
27721 +
27722 +config PAX_HOOK_ACL_FLAGS
27723 +       bool 'hook'
27724 +endchoice
27725 +
27726 +endmenu
27727 +
27728 +menu "Non-executable pages"
27729 +       depends on PAX
27730 +
27731 +config PAX_NOEXEC
27732 +       bool "Enforce non-executable pages"
27733 +       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)
27734 +       help
27735 +         By design some architectures do not allow for protecting memory
27736 +         pages against execution or even if they do, Linux does not make
27737 +         use of this feature.  In practice this means that if a page is
27738 +         readable (such as the stack or heap) it is also executable.
27739 +
27740 +         There is a well known exploit technique that makes use of this
27741 +         fact and a common programming mistake where an attacker can
27742 +         introduce code of his choice somewhere in the attacked program's
27743 +         memory (typically the stack or the heap) and then execute it.
27744 +
27745 +         If the attacked program was running with different (typically
27746 +         higher) privileges than that of the attacker, then he can elevate
27747 +         his own privilege level (e.g. get a root shell, write to files for
27748 +         which he does not have write access to, etc).
27749 +
27750 +         Enabling this option will let you choose from various features
27751 +         that prevent the injection and execution of 'foreign' code in
27752 +         a program.
27753 +
27754 +         This will also break programs that rely on the old behaviour and
27755 +         expect that dynamically allocated memory via the malloc() family
27756 +         of functions is executable (which it is not).  Notable examples
27757 +         are the XFree86 4.x server, the java runtime and wine.
27758 +
27759 +config PAX_PAGEEXEC
27760 +       bool "Paging based non-executable pages"
27761 +       depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
27762 +       help
27763 +         This implementation is based on the paging feature of the CPU.
27764 +         On i386 and ppc there is a variable but usually low performance
27765 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
27766 +         and x86_64 there is no performance impact.
27767 +
27768 +config PAX_SEGMEXEC
27769 +       bool "Segmentation based non-executable pages"
27770 +       depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
27771 +       help
27772 +         This implementation is based on the segmentation feature of the
27773 +         CPU and has little performance impact, however applications will
27774 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
27775 +
27776 +choice
27777 +       prompt "Default non-executable page method"
27778 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
27779 +       default PAX_DEFAULT_SEGMEXEC
27780 +       help
27781 +         Select the default non-executable page method applied to applications
27782 +         that do not select one themselves.
27783 +
27784 +config PAX_DEFAULT_PAGEEXEC
27785 +       bool "PAGEEXEC"
27786 +
27787 +config PAX_DEFAULT_SEGMEXEC
27788 +       bool "SEGMEXEC"
27789 +endchoice
27790 +
27791 +config PAX_EMUTRAMP
27792 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
27793 +       default y if PARISC || PPC32
27794 +       help
27795 +         There are some programs and libraries that for one reason or
27796 +         another attempt to execute special small code snippets from
27797 +         non-executable memory pages.  Most notable examples are the
27798 +         signal handler return code generated by the kernel itself and
27799 +         the GCC trampolines.
27800 +
27801 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
27802 +         such programs will no longer work under your kernel.
27803 +
27804 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
27805 +         utilities to enable trampoline emulation for the affected programs
27806 +         yet still have the protection provided by the non-executable pages.
27807 +
27808 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
27809 +         well, otherwise your system will not even boot.
27810 +
27811 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
27812 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
27813 +         for the affected files.
27814 +
27815 +         NOTE: enabling this feature *may* open up a loophole in the
27816 +         protection provided by non-executable pages that an attacker
27817 +         could abuse.  Therefore the best solution is to not have any
27818 +         files on your system that would require this option.  This can
27819 +         be achieved by not using libc5 (which relies on the kernel
27820 +         signal handler return code) and not using or rewriting programs
27821 +         that make use of the nested function implementation of GCC.
27822 +         Skilled users can just fix GCC itself so that it implements
27823 +         nested function calls in a way that does not interfere with PaX.
27824 +
27825 +config PAX_EMUSIGRT
27826 +       bool "Automatically emulate sigreturn trampolines"
27827 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
27828 +       default y
27829 +       help
27830 +         Enabling this option will have the kernel automatically detect
27831 +         and emulate signal return trampolines executing on the stack
27832 +         that would otherwise lead to task termination.
27833 +
27834 +         This solution is intended as a temporary one for users with
27835 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
27836 +         Modula-3 runtime, etc) or executables linked to such, basically
27837 +         everything that does not specify its own SA_RESTORER function in
27838 +         normal executable memory like glibc 2.1+ does.
27839 +
27840 +         On parisc and ppc you MUST enable this option, otherwise your
27841 +         system will not even boot.
27842 +
27843 +         NOTE: this feature cannot be disabled on a per executable basis
27844 +         and since it *does* open up a loophole in the protection provided
27845 +         by non-executable pages, the best solution is to not have any
27846 +         files on your system that would require this option.
27847 +
27848 +config PAX_MPROTECT
27849 +       bool "Restrict mprotect()"
27850 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
27851 +       help
27852 +         Enabling this option will prevent programs from
27853 +          - changing the executable status of memory pages that were
27854 +            not originally created as executable,
27855 +          - making read-only executable pages writable again,
27856 +          - creating executable pages from anonymous memory.
27857 +
27858 +         You should say Y here to complete the protection provided by
27859 +         the enforcement of non-executable pages.
27860 +
27861 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
27862 +         this feature on a per file basis.
27863 +
27864 +config PAX_NOELFRELOCS
27865 +       bool "Disallow ELF text relocations"
27866 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
27867 +       help
27868 +         Non-executable pages and mprotect() restrictions are effective
27869 +         in preventing the introduction of new executable code into an
27870 +         attacked task's address space.  There remain only two venues
27871 +         for this kind of attack: if the attacker can execute already
27872 +         existing code in the attacked task then he can either have it
27873 +         create and mmap() a file containing his code or have it mmap()
27874 +         an already existing ELF library that does not have position
27875 +         independent code in it and use mprotect() on it to make it
27876 +         writable and copy his code there.  While protecting against
27877 +         the former approach is beyond PaX, the latter can be prevented
27878 +         by having only PIC ELF libraries on one's system (which do not
27879 +         need to relocate their code).  If you are sure this is your case,
27880 +         then enable this option otherwise be careful as you may not even
27881 +         be able to boot or log on your system (for example, some PAM
27882 +         modules are erroneously compiled as non-PIC by default).
27883 +
27884 +         NOTE: if you are using dynamic ELF executables (as suggested
27885 +         when using ASLR) then you must have made sure that you linked
27886 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
27887 +         referenced there has already been updated to support this).
27888 +
27889 +config PAX_ETEXECRELOCS
27890 +       bool "Allow ELF ET_EXEC text relocations"
27891 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
27892 +       default y
27893 +       help
27894 +         On some architectures there are incorrectly created applications
27895 +         that require text relocations and would not work without enabling
27896 +         this option.  If you are an alpha, ia64 or parisc user, you should
27897 +         enable this option and disable it once you have made sure that
27898 +         none of your applications need it.
27899 +
27900 +config PAX_EMUPLT
27901 +       bool "Automatically emulate ELF PLT"
27902 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
27903 +       default y
27904 +       help
27905 +         Enabling this option will have the kernel automatically detect
27906 +         and emulate the Procedure Linkage Table entries in ELF files.
27907 +         On some architectures such entries are in writable memory, and
27908 +         become non-executable leading to task termination.  Therefore
27909 +         it is mandatory that you enable this option on alpha, parisc, ppc,
27910 +         sparc and sparc64, otherwise your system would not even boot.
27911 +
27912 +         NOTE: this feature *does* open up a loophole in the protection
27913 +         provided by the non-executable pages, therefore the proper
27914 +         solution is to modify the toolchain to produce a PLT that does
27915 +         not need to be writable.
27916 +
27917 +config PAX_DLRESOLVE
27918 +       bool
27919 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
27920 +       default y
27921 +
27922 +config PAX_SYSCALL
27923 +       bool
27924 +       depends on PAX_PAGEEXEC && PPC32
27925 +       default y
27926 +
27927 +config PAX_KERNEXEC
27928 +       bool "Enforce non-executable kernel pages"
27929 +       depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !DEBUG_RODATA && !COMPAT_VDSO
27930 +       help
27931 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
27932 +         that is, enabling this option will make it harder to inject
27933 +         and execute 'foreign' code in kernel memory itself.
27934 +
27935 +endmenu
27936 +
27937 +menu "Address Space Layout Randomization"
27938 +       depends on PAX
27939 +
27940 +config PAX_ASLR
27941 +       bool "Address Space Layout Randomization"
27942 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
27943 +       help
27944 +         Many if not most exploit techniques rely on the knowledge of
27945 +         certain addresses in the attacked program.  The following options
27946 +         will allow the kernel to apply a certain amount of randomization
27947 +         to specific parts of the program thereby forcing an attacker to
27948 +         guess them in most cases.  Any failed guess will most likely crash
27949 +         the attacked program which allows the kernel to detect such attempts
27950 +         and react on them.  PaX itself provides no reaction mechanisms,
27951 +         instead it is strongly encouraged that you make use of Nergal's
27952 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
27953 +         (http://www.grsecurity.net/) built-in crash detection features or
27954 +         develop one yourself.
27955 +
27956 +         By saying Y here you can choose to randomize the following areas:
27957 +          - top of the task's kernel stack
27958 +          - top of the task's userland stack
27959 +          - base address for mmap() requests that do not specify one
27960 +            (this includes all libraries)
27961 +          - base address of the main executable
27962 +
27963 +         It is strongly recommended to say Y here as address space layout
27964 +         randomization has negligible impact on performance yet it provides
27965 +         a very effective protection.
27966 +
27967 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
27968 +         this feature on a per file basis.
27969 +
27970 +config PAX_RANDKSTACK
27971 +       bool "Randomize kernel stack base"
27972 +       depends on PAX_ASLR && X86_TSC && X86_32
27973 +       help
27974 +         By saying Y here the kernel will randomize every task's kernel
27975 +         stack on every system call.  This will not only force an attacker
27976 +         to guess it but also prevent him from making use of possible
27977 +         leaked information about it.
27978 +
27979 +         Since the kernel stack is a rather scarce resource, randomization
27980 +         may cause unexpected stack overflows, therefore you should very
27981 +         carefully test your system.  Note that once enabled in the kernel
27982 +         configuration, this feature cannot be disabled on a per file basis.
27983 +
27984 +config PAX_RANDUSTACK
27985 +       bool "Randomize user stack base"
27986 +       depends on PAX_ASLR
27987 +       help
27988 +         By saying Y here the kernel will randomize every task's userland
27989 +         stack.  The randomization is done in two steps where the second
27990 +         one may apply a big amount of shift to the top of the stack and
27991 +         cause problems for programs that want to use lots of memory (more
27992 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
27993 +         For this reason the second step can be controlled by 'chpax' or
27994 +         'paxctl' on a per file basis.
27995 +
27996 +config PAX_RANDMMAP
27997 +       bool "Randomize mmap() base"
27998 +       depends on PAX_ASLR
27999 +       help
28000 +         By saying Y here the kernel will use a randomized base address for
28001 +         mmap() requests that do not specify one themselves.  As a result
28002 +         all dynamically loaded libraries will appear at random addresses
28003 +         and therefore be harder to exploit by a technique where an attacker
28004 +         attempts to execute library code for his purposes (e.g. spawn a
28005 +         shell from an exploited program that is running at an elevated
28006 +         privilege level).
28007 +
28008 +         Furthermore, if a program is relinked as a dynamic ELF file, its
28009 +         base address will be randomized as well, completing the full
28010 +         randomization of the address space layout.  Attacking such programs
28011 +         becomes a guess game.  You can find an example of doing this at
28012 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
28013 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
28014 +
28015 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
28016 +         feature on a per file basis.
28017 +
28018 +endmenu
28019 +
28020 +menu "Miscellaneous hardening features"
28021 +
28022 +config PAX_MEMORY_SANITIZE
28023 +       bool "Sanitize all freed memory"
28024 +       help
28025 +         By saying Y here the kernel will erase memory pages as soon as they
28026 +         are freed.  This in turn reduces the lifetime of data stored in the
28027 +         pages, making it less likely that sensitive information such as
28028 +         passwords, cryptographic secrets, etc stay in memory for too long.
28029 +
28030 +         This is especially useful for programs whose runtime is short, long
28031 +         lived processes and the kernel itself benefit from this as long as
28032 +         they operate on whole memory pages and ensure timely freeing of pages
28033 +         that may hold sensitive information.
28034 +
28035 +         The tradeoff is performance impact, on a single CPU system kernel
28036 +         compilation sees a 3% slowdown, other systems and workloads may vary
28037 +         and you are advised to test this feature on your expected workload
28038 +         before deploying it.
28039 +
28040 +         Note that this feature does not protect data stored in live pages,
28041 +         e.g., process memory swapped to disk may stay there for a long time.
28042 +
28043 +config PAX_MEMORY_UDEREF
28044 +       bool "Prevent invalid userland pointer dereference"
28045 +       depends on X86_32 && !COMPAT_VDSO
28046 +       help
28047 +         By saying Y here the kernel will be prevented from dereferencing
28048 +         userland pointers in contexts where the kernel expects only kernel
28049 +         pointers.  This is both a useful runtime debugging feature and a
28050 +         security measure that prevents exploiting a class of kernel bugs.
28051 +
28052 +         The tradeoff is that some virtualization solutions may experience
28053 +         a huge slowdown and therefore you should not enable this feature
28054 +         for kernels meant to run in such environments.  Whether a given VM
28055 +         solution is affected or not is best determined by simply trying it
28056 +         out, the performance impact will be obvious right on boot as this
28057 +         mechanism engages from very early on.  A good rule of thumb is that
28058 +         VMs running on CPUs without hardware virtualization support (i.e.,
28059 +         the majority of IA-32 CPUs) will likely experience the slowdown.
28060 +
28061 +endmenu
28062 +
28063 +endmenu
28064 +
28065 +source grsecurity/Kconfig
28066 +
28067  config KEYS
28068         bool "Enable access key retention support"
28069         help
28070 diff -urNp linux-2.6.18/sound/core/oss/pcm_oss.c linux-2.6.18/sound/core/oss/pcm_oss.c
28071 --- linux-2.6.18/sound/core/oss/pcm_oss.c       2006-09-19 23:42:06.000000000 -0400
28072 +++ linux-2.6.18/sound/core/oss/pcm_oss.c       2006-09-22 20:45:04.000000000 -0400
28073 @@ -2854,8 +2854,8 @@ static void snd_pcm_oss_proc_done(struct
28074         }
28075  }
28076  #else /* !CONFIG_SND_VERBOSE_PROCFS */
28077 -#define snd_pcm_oss_proc_init(pcm)
28078 -#define snd_pcm_oss_proc_done(pcm)
28079 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
28080 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
28081  #endif /* CONFIG_SND_VERBOSE_PROCFS */
28082  
28083  /*
This page took 2.353673 seconds and 3 git commands to generate.