]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.1.9-2.6.18.patch
- use CUBIC by default:
[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-23 00:27:55.000000000 -0400
3708 @@ -27,34 +27,41 @@ static inline int __movsl_is_ok(unsigned
3709   * Copy a null terminated string from userspace.
3710   */
3711  
3712 -#define __do_strncpy_from_user(dst,src,count,res)                         \
3713 -do {                                                                      \
3714 -       int __d0, __d1, __d2;                                              \
3715 -       might_sleep();                                                     \
3716 -       __asm__ __volatile__(                                              \
3717 -               "       testl %1,%1\n"                                     \
3718 -               "       jz 2f\n"                                           \
3719 -               "0:     lodsb\n"                                           \
3720 -               "       stosb\n"                                           \
3721 -               "       testb %%al,%%al\n"                                 \
3722 -               "       jz 1f\n"                                           \
3723 -               "       decl %1\n"                                         \
3724 -               "       jnz 0b\n"                                          \
3725 -               "1:     subl %1,%0\n"                                      \
3726 -               "2:\n"                                                     \
3727 -               ".section .fixup,\"ax\"\n"                                 \
3728 -               "3:     movl %5,%0\n"                                      \
3729 -               "       jmp 2b\n"                                          \
3730 -               ".previous\n"                                              \
3731 -               ".section __ex_table,\"a\"\n"                              \
3732 -               "       .align 4\n"                                        \
3733 -               "       .long 0b,3b\n"                                     \
3734 -               ".previous"                                                \
3735 -               : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
3736 -                 "=&D" (__d2)                                             \
3737 -               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
3738 -               : "memory");                                               \
3739 -} while (0)
3740 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
3741 +{
3742 +       int __d0, __d1, __d2;
3743 +       long res = -EFAULT;
3744 +
3745 +       might_sleep();
3746 +       __asm__ __volatile__(
3747 +               "       movw %w10,%%ds\n"
3748 +               "       testl %1,%1\n"
3749 +               "       jz 2f\n"
3750 +               "0:     lodsb\n"
3751 +               "       stosb\n"
3752 +               "       testb %%al,%%al\n"
3753 +               "       jz 1f\n"
3754 +               "       decl %1\n"
3755 +               "       jnz 0b\n"
3756 +               "1:     subl %1,%0\n"
3757 +               "2:\n"
3758 +               "       pushl %%ss\n"
3759 +               "       popl %%ds\n"
3760 +               ".section .fixup,\"ax\"\n"
3761 +               "3:     movl %5,%0\n"
3762 +               "       jmp 2b\n"
3763 +               ".previous\n"
3764 +               ".section __ex_table,\"a\"\n"
3765 +               "       .align 4\n"
3766 +               "       .long 0b,3b\n"
3767 +               ".previous"
3768 +               : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
3769 +                 "=&D" (__d2)
3770 +               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
3771 +                 "r"(__USER_DS)
3772 +               : "memory");
3773 +       return res;
3774 +}
3775  
3776  /**
3777   * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
3778 @@ -79,9 +86,7 @@ do {                                                                     \
3779  long
3780  __strncpy_from_user(char *dst, const char __user *src, long count)
3781  {
3782 -       long res;
3783 -       __do_strncpy_from_user(dst, src, count, res);
3784 -       return res;
3785 +       return __do_strncpy_from_user(dst, src, count);
3786  }
3787  EXPORT_SYMBOL(__strncpy_from_user);
3788  
3789 @@ -108,7 +113,7 @@ strncpy_from_user(char *dst, const char 
3790  {
3791         long res = -EFAULT;
3792         if (access_ok(VERIFY_READ, src, 1))
3793 -               __do_strncpy_from_user(dst, src, count, res);
3794 +               res = __do_strncpy_from_user(dst, src, count);
3795         return res;
3796  }
3797  EXPORT_SYMBOL(strncpy_from_user);
3798 @@ -117,27 +122,33 @@ EXPORT_SYMBOL(strncpy_from_user);
3799   * Zero Userspace
3800   */
3801  
3802 -#define __do_clear_user(addr,size)                                     \
3803 -do {                                                                   \
3804 -       int __d0;                                                       \
3805 -       might_sleep();                                                  \
3806 -       __asm__ __volatile__(                                           \
3807 -               "0:     rep; stosl\n"                                   \
3808 -               "       movl %2,%0\n"                                   \
3809 -               "1:     rep; stosb\n"                                   \
3810 -               "2:\n"                                                  \
3811 -               ".section .fixup,\"ax\"\n"                              \
3812 -               "3:     lea 0(%2,%0,4),%0\n"                            \
3813 -               "       jmp 2b\n"                                       \
3814 -               ".previous\n"                                           \
3815 -               ".section __ex_table,\"a\"\n"                           \
3816 -               "       .align 4\n"                                     \
3817 -               "       .long 0b,3b\n"                                  \
3818 -               "       .long 1b,2b\n"                                  \
3819 -               ".previous"                                             \
3820 -               : "=&c"(size), "=&D" (__d0)                             \
3821 -               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
3822 -} while (0)
3823 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
3824 +{
3825 +       int __d0;
3826 +
3827 +       might_sleep();
3828 +       __asm__ __volatile__(
3829 +               "       movw %w6,%%es\n"
3830 +               "0:     rep; stosl\n"
3831 +               "       movl %2,%0\n"
3832 +               "1:     rep; stosb\n"
3833 +               "2:\n"
3834 +               "       pushl %%ss\n"
3835 +               "       popl %%es\n"
3836 +               ".section .fixup,\"ax\"\n"
3837 +               "3:     lea 0(%2,%0,4),%0\n"
3838 +               "       jmp 2b\n"
3839 +               ".previous\n"
3840 +               ".section __ex_table,\"a\"\n"
3841 +               "       .align 4\n"
3842 +               "       .long 0b,3b\n"
3843 +               "       .long 1b,2b\n"
3844 +               ".previous"
3845 +               : "=&c"(size), "=&D" (__d0)
3846 +               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
3847 +                 "r"(__USER_DS));
3848 +       return size;
3849 +}
3850  
3851  /**
3852   * clear_user: - Zero a block of memory in user space.
3853 @@ -154,7 +165,7 @@ clear_user(void __user *to, unsigned lon
3854  {
3855         might_sleep();
3856         if (access_ok(VERIFY_WRITE, to, n))
3857 -               __do_clear_user(to, n);
3858 +               n = __do_clear_user(to, n);
3859         return n;
3860  }
3861  EXPORT_SYMBOL(clear_user);
3862 @@ -173,8 +184,7 @@ EXPORT_SYMBOL(clear_user);
3863  unsigned long
3864  __clear_user(void __user *to, unsigned long n)
3865  {
3866 -       __do_clear_user(to, n);
3867 -       return n;
3868 +       return __do_clear_user(to, n);
3869  }
3870  EXPORT_SYMBOL(__clear_user);
3871  
3872 @@ -197,14 +207,17 @@ long strnlen_user(const char __user *s, 
3873         might_sleep();
3874  
3875         __asm__ __volatile__(
3876 +               "       movw %w8,%%es\n"
3877                 "       testl %0, %0\n"
3878                 "       jz 3f\n"
3879 -               "       andl %0,%%ecx\n"
3880 +               "       movl %0,%%ecx\n"
3881                 "0:     repne; scasb\n"
3882                 "       setne %%al\n"
3883                 "       subl %%ecx,%0\n"
3884                 "       addl %0,%%eax\n"
3885                 "1:\n"
3886 +               "       pushl %%ss\n"
3887 +               "       popl %%es\n"
3888                 ".section .fixup,\"ax\"\n"
3889                 "2:     xorl %%eax,%%eax\n"
3890                 "       jmp 1b\n"
3891 @@ -216,7 +229,7 @@ long strnlen_user(const char __user *s, 
3892                 "       .long 0b,2b\n"
3893                 ".previous"
3894                 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
3895 -               :"0" (n), "1" (s), "2" (0), "3" (mask)
3896 +               :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
3897                 :"cc");
3898         return res & mask;
3899  }
3900 @@ -224,10 +237,11 @@ EXPORT_SYMBOL(strnlen_user);
3901  
3902  #ifdef CONFIG_X86_INTEL_USERCOPY
3903  static unsigned long
3904 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
3905 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
3906  {
3907         int d0, d1;
3908         __asm__ __volatile__(
3909 +                      "       movw %w6, %%es\n"
3910                        "       .align 2,0x90\n"
3911                        "1:     movl 32(%4), %%eax\n"
3912                        "       cmpl $67, %0\n"
3913 @@ -236,36 +250,36 @@ __copy_user_intel(void __user *to, const
3914                        "       .align 2,0x90\n"
3915                        "3:     movl 0(%4), %%eax\n"
3916                        "4:     movl 4(%4), %%edx\n"
3917 -                      "5:     movl %%eax, 0(%3)\n"
3918 -                      "6:     movl %%edx, 4(%3)\n"
3919 +                      "5:     movl %%eax, %%es:0(%3)\n"
3920 +                      "6:     movl %%edx, %%es:4(%3)\n"
3921                        "7:     movl 8(%4), %%eax\n"
3922                        "8:     movl 12(%4),%%edx\n"
3923 -                      "9:     movl %%eax, 8(%3)\n"
3924 -                      "10:    movl %%edx, 12(%3)\n"
3925 +                      "9:     movl %%eax, %%es:8(%3)\n"
3926 +                      "10:    movl %%edx, %%es:12(%3)\n"
3927                        "11:    movl 16(%4), %%eax\n"
3928                        "12:    movl 20(%4), %%edx\n"
3929 -                      "13:    movl %%eax, 16(%3)\n"
3930 -                      "14:    movl %%edx, 20(%3)\n"
3931 +                      "13:    movl %%eax, %%es:16(%3)\n"
3932 +                      "14:    movl %%edx, %%es:20(%3)\n"
3933                        "15:    movl 24(%4), %%eax\n"
3934                        "16:    movl 28(%4), %%edx\n"
3935 -                      "17:    movl %%eax, 24(%3)\n"
3936 -                      "18:    movl %%edx, 28(%3)\n"
3937 +                      "17:    movl %%eax, %%es:24(%3)\n"
3938 +                      "18:    movl %%edx, %%es:28(%3)\n"
3939                        "19:    movl 32(%4), %%eax\n"
3940                        "20:    movl 36(%4), %%edx\n"
3941 -                      "21:    movl %%eax, 32(%3)\n"
3942 -                      "22:    movl %%edx, 36(%3)\n"
3943 +                      "21:    movl %%eax, %%es:32(%3)\n"
3944 +                      "22:    movl %%edx, %%es:36(%3)\n"
3945                        "23:    movl 40(%4), %%eax\n"
3946                        "24:    movl 44(%4), %%edx\n"
3947 -                      "25:    movl %%eax, 40(%3)\n"
3948 -                      "26:    movl %%edx, 44(%3)\n"
3949 +                      "25:    movl %%eax, %%es:40(%3)\n"
3950 +                      "26:    movl %%edx, %%es:44(%3)\n"
3951                        "27:    movl 48(%4), %%eax\n"
3952                        "28:    movl 52(%4), %%edx\n"
3953 -                      "29:    movl %%eax, 48(%3)\n"
3954 -                      "30:    movl %%edx, 52(%3)\n"
3955 +                      "29:    movl %%eax, %%es:48(%3)\n"
3956 +                      "30:    movl %%edx, %%es:52(%3)\n"
3957                        "31:    movl 56(%4), %%eax\n"
3958                        "32:    movl 60(%4), %%edx\n"
3959 -                      "33:    movl %%eax, 56(%3)\n"
3960 -                      "34:    movl %%edx, 60(%3)\n"
3961 +                      "33:    movl %%eax, %%es:56(%3)\n"
3962 +                      "34:    movl %%edx, %%es:60(%3)\n"
3963                        "       addl $-64, %0\n"
3964                        "       addl $64, %4\n"
3965                        "       addl $64, %3\n"
3966 @@ -279,6 +293,8 @@ __copy_user_intel(void __user *to, const
3967                        "36:    movl %%eax, %0\n"
3968                        "37:    rep; movsb\n"
3969                        "100:\n"
3970 +                      "       pushl %%ss\n"
3971 +                      "       popl %%es\n"
3972                        ".section .fixup,\"ax\"\n"
3973                        "101:   lea 0(%%eax,%0,4),%0\n"
3974                        "       jmp 100b\n"
3975 @@ -325,7 +341,117 @@ __copy_user_intel(void __user *to, const
3976                        "       .long 99b,101b\n"
3977                        ".previous"
3978                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
3979 -                      :  "1"(to), "2"(from), "0"(size)
3980 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3981 +                      : "eax", "edx", "memory");
3982 +       return size;
3983 +}
3984 +
3985 +static unsigned long
3986 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
3987 +{
3988 +       int d0, d1;
3989 +       __asm__ __volatile__(
3990 +                      "       movw %w6, %%ds\n"
3991 +                      "       .align 2,0x90\n"
3992 +                      "1:     movl 32(%4), %%eax\n"
3993 +                      "       cmpl $67, %0\n"
3994 +                      "       jbe 3f\n"
3995 +                      "2:     movl 64(%4), %%eax\n"
3996 +                      "       .align 2,0x90\n"
3997 +                      "3:     movl 0(%4), %%eax\n"
3998 +                      "4:     movl 4(%4), %%edx\n"
3999 +                      "5:     movl %%eax, %%es:0(%3)\n"
4000 +                      "6:     movl %%edx, %%es:4(%3)\n"
4001 +                      "7:     movl 8(%4), %%eax\n"
4002 +                      "8:     movl 12(%4),%%edx\n"
4003 +                      "9:     movl %%eax, %%es:8(%3)\n"
4004 +                      "10:    movl %%edx, %%es:12(%3)\n"
4005 +                      "11:    movl 16(%4), %%eax\n"
4006 +                      "12:    movl 20(%4), %%edx\n"
4007 +                      "13:    movl %%eax, %%es:16(%3)\n"
4008 +                      "14:    movl %%edx, %%es:20(%3)\n"
4009 +                      "15:    movl 24(%4), %%eax\n"
4010 +                      "16:    movl 28(%4), %%edx\n"
4011 +                      "17:    movl %%eax, %%es:24(%3)\n"
4012 +                      "18:    movl %%edx, %%es:28(%3)\n"
4013 +                      "19:    movl 32(%4), %%eax\n"
4014 +                      "20:    movl 36(%4), %%edx\n"
4015 +                      "21:    movl %%eax, %%es:32(%3)\n"
4016 +                      "22:    movl %%edx, %%es:36(%3)\n"
4017 +                      "23:    movl 40(%4), %%eax\n"
4018 +                      "24:    movl 44(%4), %%edx\n"
4019 +                      "25:    movl %%eax, %%es:40(%3)\n"
4020 +                      "26:    movl %%edx, %%es:44(%3)\n"
4021 +                      "27:    movl 48(%4), %%eax\n"
4022 +                      "28:    movl 52(%4), %%edx\n"
4023 +                      "29:    movl %%eax, %%es:48(%3)\n"
4024 +                      "30:    movl %%edx, %%es:52(%3)\n"
4025 +                      "31:    movl 56(%4), %%eax\n"
4026 +                      "32:    movl 60(%4), %%edx\n"
4027 +                      "33:    movl %%eax, %%es:56(%3)\n"
4028 +                      "34:    movl %%edx, %%es:60(%3)\n"
4029 +                      "       addl $-64, %0\n"
4030 +                      "       addl $64, %4\n"
4031 +                      "       addl $64, %3\n"
4032 +                      "       cmpl $63, %0\n"
4033 +                      "       ja  1b\n"
4034 +                      "35:    movl  %0, %%eax\n"
4035 +                      "       shrl  $2, %0\n"
4036 +                      "       andl  $3, %%eax\n"
4037 +                      "       cld\n"
4038 +                      "99:    rep; movsl\n"
4039 +                      "36:    movl %%eax, %0\n"
4040 +                      "37:    rep; movsb\n"
4041 +                      "100:\n"
4042 +                      "       pushl %%ss\n"
4043 +                      "       popl %%ds\n"
4044 +                      ".section .fixup,\"ax\"\n"
4045 +                      "101:   lea 0(%%eax,%0,4),%0\n"
4046 +                      "       jmp 100b\n"
4047 +                      ".previous\n"
4048 +                      ".section __ex_table,\"a\"\n"
4049 +                      "       .align 4\n"
4050 +                      "       .long 1b,100b\n"
4051 +                      "       .long 2b,100b\n"
4052 +                      "       .long 3b,100b\n"
4053 +                      "       .long 4b,100b\n"
4054 +                      "       .long 5b,100b\n"
4055 +                      "       .long 6b,100b\n"
4056 +                      "       .long 7b,100b\n"
4057 +                      "       .long 8b,100b\n"
4058 +                      "       .long 9b,100b\n"
4059 +                      "       .long 10b,100b\n"
4060 +                      "       .long 11b,100b\n"
4061 +                      "       .long 12b,100b\n"
4062 +                      "       .long 13b,100b\n"
4063 +                      "       .long 14b,100b\n"
4064 +                      "       .long 15b,100b\n"
4065 +                      "       .long 16b,100b\n"
4066 +                      "       .long 17b,100b\n"
4067 +                      "       .long 18b,100b\n"
4068 +                      "       .long 19b,100b\n"
4069 +                      "       .long 20b,100b\n"
4070 +                      "       .long 21b,100b\n"
4071 +                      "       .long 22b,100b\n"
4072 +                      "       .long 23b,100b\n"
4073 +                      "       .long 24b,100b\n"
4074 +                      "       .long 25b,100b\n"
4075 +                      "       .long 26b,100b\n"
4076 +                      "       .long 27b,100b\n"
4077 +                      "       .long 28b,100b\n"
4078 +                      "       .long 29b,100b\n"
4079 +                      "       .long 30b,100b\n"
4080 +                      "       .long 31b,100b\n"
4081 +                      "       .long 32b,100b\n"
4082 +                      "       .long 33b,100b\n"
4083 +                      "       .long 34b,100b\n"
4084 +                      "       .long 35b,100b\n"
4085 +                      "       .long 36b,100b\n"
4086 +                      "       .long 37b,100b\n"
4087 +                      "       .long 99b,101b\n"
4088 +                      ".previous"
4089 +                      : "=&c"(size), "=&D" (d0), "=&S" (d1)
4090 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4091                        : "eax", "edx", "memory");
4092         return size;
4093  }
4094 @@ -335,6 +461,7 @@ __copy_user_zeroing_intel(void *to, cons
4095  {
4096         int d0, d1;
4097         __asm__ __volatile__(
4098 +                      "        movw %w6, %%ds\n"
4099                        "        .align 2,0x90\n"
4100                        "0:      movl 32(%4), %%eax\n"
4101                        "        cmpl $67, %0\n"      
4102 @@ -343,36 +470,36 @@ __copy_user_zeroing_intel(void *to, cons
4103                        "        .align 2,0x90\n"     
4104                        "2:      movl 0(%4), %%eax\n" 
4105                        "21:     movl 4(%4), %%edx\n" 
4106 -                      "        movl %%eax, 0(%3)\n" 
4107 -                      "        movl %%edx, 4(%3)\n" 
4108 +                      "        movl %%eax, %%es:0(%3)\n" 
4109 +                      "        movl %%edx, %%es:4(%3)\n" 
4110                        "3:      movl 8(%4), %%eax\n" 
4111                        "31:     movl 12(%4),%%edx\n" 
4112 -                      "        movl %%eax, 8(%3)\n" 
4113 -                      "        movl %%edx, 12(%3)\n"
4114 +                      "        movl %%eax, %%es:8(%3)\n" 
4115 +                      "        movl %%edx, %%es:12(%3)\n"
4116                        "4:      movl 16(%4), %%eax\n"
4117                        "41:     movl 20(%4), %%edx\n"
4118 -                      "        movl %%eax, 16(%3)\n"
4119 -                      "        movl %%edx, 20(%3)\n"
4120 +                      "        movl %%eax, %%es:16(%3)\n"
4121 +                      "        movl %%edx, %%es:20(%3)\n"
4122                        "10:     movl 24(%4), %%eax\n"
4123                        "51:     movl 28(%4), %%edx\n"
4124 -                      "        movl %%eax, 24(%3)\n"
4125 -                      "        movl %%edx, 28(%3)\n"
4126 +                      "        movl %%eax, %%es:24(%3)\n"
4127 +                      "        movl %%edx, %%es:28(%3)\n"
4128                        "11:     movl 32(%4), %%eax\n"
4129                        "61:     movl 36(%4), %%edx\n"
4130 -                      "        movl %%eax, 32(%3)\n"
4131 -                      "        movl %%edx, 36(%3)\n"
4132 +                      "        movl %%eax, %%es:32(%3)\n"
4133 +                      "        movl %%edx, %%es:36(%3)\n"
4134                        "12:     movl 40(%4), %%eax\n"
4135                        "71:     movl 44(%4), %%edx\n"
4136 -                      "        movl %%eax, 40(%3)\n"
4137 -                      "        movl %%edx, 44(%3)\n"
4138 +                      "        movl %%eax, %%es:40(%3)\n"
4139 +                      "        movl %%edx, %%es:44(%3)\n"
4140                        "13:     movl 48(%4), %%eax\n"
4141                        "81:     movl 52(%4), %%edx\n"
4142 -                      "        movl %%eax, 48(%3)\n"
4143 -                      "        movl %%edx, 52(%3)\n"
4144 +                      "        movl %%eax, %%es:48(%3)\n"
4145 +                      "        movl %%edx, %%es:52(%3)\n"
4146                        "14:     movl 56(%4), %%eax\n"
4147                        "91:     movl 60(%4), %%edx\n"
4148 -                      "        movl %%eax, 56(%3)\n"
4149 -                      "        movl %%edx, 60(%3)\n"
4150 +                      "        movl %%eax, %%es:56(%3)\n"
4151 +                      "        movl %%edx, %%es:60(%3)\n"
4152                        "        addl $-64, %0\n"     
4153                        "        addl $64, %4\n"      
4154                        "        addl $64, %3\n"      
4155 @@ -386,6 +513,8 @@ __copy_user_zeroing_intel(void *to, cons
4156                        "        movl %%eax,%0\n"
4157                        "7:      rep; movsb\n"   
4158                        "8:\n"                   
4159 +                      "        pushl %%ss\n"
4160 +                      "        popl %%ds\n"
4161                        ".section .fixup,\"ax\"\n"
4162                        "9:      lea 0(%%eax,%0,4),%0\n" 
4163                        "16:     pushl %0\n"     
4164 @@ -420,7 +549,7 @@ __copy_user_zeroing_intel(void *to, cons
4165                        "        .long 7b,16b\n" 
4166                        ".previous"              
4167                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
4168 -                      :  "1"(to), "2"(from), "0"(size)
4169 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4170                        : "eax", "edx", "memory");
4171         return size;
4172  }
4173 @@ -436,6 +565,7 @@ static unsigned long __copy_user_zeroing
4174          int d0, d1;
4175  
4176         __asm__ __volatile__(
4177 +              "        movw %w6, %%ds\n"
4178                "        .align 2,0x90\n"
4179                "0:      movl 32(%4), %%eax\n"
4180                "        cmpl $67, %0\n"
4181 @@ -444,36 +574,36 @@ static unsigned long __copy_user_zeroing
4182                "        .align 2,0x90\n"
4183                "2:      movl 0(%4), %%eax\n"
4184                "21:     movl 4(%4), %%edx\n"
4185 -              "        movnti %%eax, 0(%3)\n"
4186 -              "        movnti %%edx, 4(%3)\n"
4187 +              "        movnti %%eax, %%es:0(%3)\n"
4188 +              "        movnti %%edx, %%es:4(%3)\n"
4189                "3:      movl 8(%4), %%eax\n"
4190                "31:     movl 12(%4),%%edx\n"
4191 -              "        movnti %%eax, 8(%3)\n"
4192 -              "        movnti %%edx, 12(%3)\n"
4193 +              "        movnti %%eax, %%es:8(%3)\n"
4194 +              "        movnti %%edx, %%es:12(%3)\n"
4195                "4:      movl 16(%4), %%eax\n"
4196                "41:     movl 20(%4), %%edx\n"
4197 -              "        movnti %%eax, 16(%3)\n"
4198 -              "        movnti %%edx, 20(%3)\n"
4199 +              "        movnti %%eax, %%es:16(%3)\n"
4200 +              "        movnti %%edx, %%es:20(%3)\n"
4201                "10:     movl 24(%4), %%eax\n"
4202                "51:     movl 28(%4), %%edx\n"
4203 -              "        movnti %%eax, 24(%3)\n"
4204 -              "        movnti %%edx, 28(%3)\n"
4205 +              "        movnti %%eax, %%es:24(%3)\n"
4206 +              "        movnti %%edx, %%es:28(%3)\n"
4207                "11:     movl 32(%4), %%eax\n"
4208                "61:     movl 36(%4), %%edx\n"
4209 -              "        movnti %%eax, 32(%3)\n"
4210 -              "        movnti %%edx, 36(%3)\n"
4211 +              "        movnti %%eax, %%es:32(%3)\n"
4212 +              "        movnti %%edx, %%es:36(%3)\n"
4213                "12:     movl 40(%4), %%eax\n"
4214                "71:     movl 44(%4), %%edx\n"
4215 -              "        movnti %%eax, 40(%3)\n"
4216 -              "        movnti %%edx, 44(%3)\n"
4217 +              "        movnti %%eax, %%es:40(%3)\n"
4218 +              "        movnti %%edx, %%es:44(%3)\n"
4219                "13:     movl 48(%4), %%eax\n"
4220                "81:     movl 52(%4), %%edx\n"
4221 -              "        movnti %%eax, 48(%3)\n"
4222 -              "        movnti %%edx, 52(%3)\n"
4223 +              "        movnti %%eax, %%es:48(%3)\n"
4224 +              "        movnti %%edx, %%es:52(%3)\n"
4225                "14:     movl 56(%4), %%eax\n"
4226                "91:     movl 60(%4), %%edx\n"
4227 -              "        movnti %%eax, 56(%3)\n"
4228 -              "        movnti %%edx, 60(%3)\n"
4229 +              "        movnti %%eax, %%es:56(%3)\n"
4230 +              "        movnti %%edx, %%es:60(%3)\n"
4231                "        addl $-64, %0\n"
4232                "        addl $64, %4\n"
4233                "        addl $64, %3\n"
4234 @@ -488,6 +618,8 @@ static unsigned long __copy_user_zeroing
4235                "        movl %%eax,%0\n"
4236                "7:      rep; movsb\n"
4237                "8:\n"
4238 +              "        pushl %%ss\n"
4239 +              "        popl %%ds\n"
4240                ".section .fixup,\"ax\"\n"
4241                "9:      lea 0(%%eax,%0,4),%0\n"
4242                "16:     pushl %0\n"
4243 @@ -522,7 +654,7 @@ static unsigned long __copy_user_zeroing
4244                "        .long 7b,16b\n"
4245                ".previous"
4246                : "=&c"(size), "=&D" (d0), "=&S" (d1)
4247 -              :  "1"(to), "2"(from), "0"(size)
4248 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4249                : "eax", "edx", "memory");
4250         return size;
4251  }
4252 @@ -533,6 +665,7 @@ static unsigned long __copy_user_intel_n
4253          int d0, d1;
4254  
4255         __asm__ __volatile__(
4256 +              "        movw %w6, %%ds\n"
4257                "        .align 2,0x90\n"
4258                "0:      movl 32(%4), %%eax\n"
4259                "        cmpl $67, %0\n"
4260 @@ -541,36 +674,36 @@ static unsigned long __copy_user_intel_n
4261                "        .align 2,0x90\n"
4262                "2:      movl 0(%4), %%eax\n"
4263                "21:     movl 4(%4), %%edx\n"
4264 -              "        movnti %%eax, 0(%3)\n"
4265 -              "        movnti %%edx, 4(%3)\n"
4266 +              "        movnti %%eax, %%es:0(%3)\n"
4267 +              "        movnti %%edx, %%es:4(%3)\n"
4268                "3:      movl 8(%4), %%eax\n"
4269                "31:     movl 12(%4),%%edx\n"
4270 -              "        movnti %%eax, 8(%3)\n"
4271 -              "        movnti %%edx, 12(%3)\n"
4272 +              "        movnti %%eax, %%es:8(%3)\n"
4273 +              "        movnti %%edx, %%es:12(%3)\n"
4274                "4:      movl 16(%4), %%eax\n"
4275                "41:     movl 20(%4), %%edx\n"
4276 -              "        movnti %%eax, 16(%3)\n"
4277 -              "        movnti %%edx, 20(%3)\n"
4278 +              "        movnti %%eax, %%es:16(%3)\n"
4279 +              "        movnti %%edx, %%es:20(%3)\n"
4280                "10:     movl 24(%4), %%eax\n"
4281                "51:     movl 28(%4), %%edx\n"
4282 -              "        movnti %%eax, 24(%3)\n"
4283 -              "        movnti %%edx, 28(%3)\n"
4284 +              "        movnti %%eax, %%es:24(%3)\n"
4285 +              "        movnti %%edx, %%es:28(%3)\n"
4286                "11:     movl 32(%4), %%eax\n"
4287                "61:     movl 36(%4), %%edx\n"
4288 -              "        movnti %%eax, 32(%3)\n"
4289 -              "        movnti %%edx, 36(%3)\n"
4290 +              "        movnti %%eax, %%es:32(%3)\n"
4291 +              "        movnti %%edx, %%es:36(%3)\n"
4292                "12:     movl 40(%4), %%eax\n"
4293                "71:     movl 44(%4), %%edx\n"
4294 -              "        movnti %%eax, 40(%3)\n"
4295 -              "        movnti %%edx, 44(%3)\n"
4296 +              "        movnti %%eax, %%es:40(%3)\n"
4297 +              "        movnti %%edx, %%es:44(%3)\n"
4298                "13:     movl 48(%4), %%eax\n"
4299                "81:     movl 52(%4), %%edx\n"
4300 -              "        movnti %%eax, 48(%3)\n"
4301 -              "        movnti %%edx, 52(%3)\n"
4302 +              "        movnti %%eax, %%es:48(%3)\n"
4303 +              "        movnti %%edx, %%es:52(%3)\n"
4304                "14:     movl 56(%4), %%eax\n"
4305                "91:     movl 60(%4), %%edx\n"
4306 -              "        movnti %%eax, 56(%3)\n"
4307 -              "        movnti %%edx, 60(%3)\n"
4308 +              "        movnti %%eax, %%es:56(%3)\n"
4309 +              "        movnti %%edx, %%es:60(%3)\n"
4310                "        addl $-64, %0\n"
4311                "        addl $64, %4\n"
4312                "        addl $64, %3\n"
4313 @@ -585,6 +718,8 @@ static unsigned long __copy_user_intel_n
4314                "        movl %%eax,%0\n"
4315                "7:      rep; movsb\n"
4316                "8:\n"
4317 +              "        pushl %%ss\n"
4318 +              "        popl %%ds\n"
4319                ".section .fixup,\"ax\"\n"
4320                "9:      lea 0(%%eax,%0,4),%0\n"
4321                "16:     jmp 8b\n"
4322 @@ -613,7 +748,7 @@ static unsigned long __copy_user_intel_n
4323                "        .long 7b,16b\n"
4324                ".previous"
4325                : "=&c"(size), "=&D" (d0), "=&S" (d1)
4326 -              :  "1"(to), "2"(from), "0"(size)
4327 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4328                : "eax", "edx", "memory");
4329         return size;
4330  }
4331 @@ -626,90 +761,146 @@ static unsigned long __copy_user_intel_n
4332   */
4333  unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
4334                                         unsigned long size);
4335 -unsigned long __copy_user_intel(void __user *to, const void *from,
4336 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
4337 +                                       unsigned long size);
4338 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
4339                                         unsigned long size);
4340  unsigned long __copy_user_zeroing_intel_nocache(void *to,
4341                                 const void __user *from, unsigned long size);
4342  #endif /* CONFIG_X86_INTEL_USERCOPY */
4343  
4344  /* Generic arbitrary sized copy.  */
4345 -#define __copy_user(to,from,size)                                      \
4346 -do {                                                                   \
4347 -       int __d0, __d1, __d2;                                           \
4348 -       __asm__ __volatile__(                                           \
4349 -               "       cmp  $7,%0\n"                                   \
4350 -               "       jbe  1f\n"                                      \
4351 -               "       movl %1,%0\n"                                   \
4352 -               "       negl %0\n"                                      \
4353 -               "       andl $7,%0\n"                                   \
4354 -               "       subl %0,%3\n"                                   \
4355 -               "4:     rep; movsb\n"                                   \
4356 -               "       movl %3,%0\n"                                   \
4357 -               "       shrl $2,%0\n"                                   \
4358 -               "       andl $3,%3\n"                                   \
4359 -               "       .align 2,0x90\n"                                \
4360 -               "0:     rep; movsl\n"                                   \
4361 -               "       movl %3,%0\n"                                   \
4362 -               "1:     rep; movsb\n"                                   \
4363 -               "2:\n"                                                  \
4364 -               ".section .fixup,\"ax\"\n"                              \
4365 -               "5:     addl %3,%0\n"                                   \
4366 -               "       jmp 2b\n"                                       \
4367 -               "3:     lea 0(%3,%0,4),%0\n"                            \
4368 -               "       jmp 2b\n"                                       \
4369 -               ".previous\n"                                           \
4370 -               ".section __ex_table,\"a\"\n"                           \
4371 -               "       .align 4\n"                                     \
4372 -               "       .long 4b,5b\n"                                  \
4373 -               "       .long 0b,3b\n"                                  \
4374 -               "       .long 1b,2b\n"                                  \
4375 -               ".previous"                                             \
4376 -               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
4377 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
4378 -               : "memory");                                            \
4379 -} while (0)
4380 -
4381 -#define __copy_user_zeroing(to,from,size)                              \
4382 -do {                                                                   \
4383 -       int __d0, __d1, __d2;                                           \
4384 -       __asm__ __volatile__(                                           \
4385 -               "       cmp  $7,%0\n"                                   \
4386 -               "       jbe  1f\n"                                      \
4387 -               "       movl %1,%0\n"                                   \
4388 -               "       negl %0\n"                                      \
4389 -               "       andl $7,%0\n"                                   \
4390 -               "       subl %0,%3\n"                                   \
4391 -               "4:     rep; movsb\n"                                   \
4392 -               "       movl %3,%0\n"                                   \
4393 -               "       shrl $2,%0\n"                                   \
4394 -               "       andl $3,%3\n"                                   \
4395 -               "       .align 2,0x90\n"                                \
4396 -               "0:     rep; movsl\n"                                   \
4397 -               "       movl %3,%0\n"                                   \
4398 -               "1:     rep; movsb\n"                                   \
4399 -               "2:\n"                                                  \
4400 -               ".section .fixup,\"ax\"\n"                              \
4401 -               "5:     addl %3,%0\n"                                   \
4402 -               "       jmp 6f\n"                                       \
4403 -               "3:     lea 0(%3,%0,4),%0\n"                            \
4404 -               "6:     pushl %0\n"                                     \
4405 -               "       pushl %%eax\n"                                  \
4406 -               "       xorl %%eax,%%eax\n"                             \
4407 -               "       rep; stosb\n"                                   \
4408 -               "       popl %%eax\n"                                   \
4409 -               "       popl %0\n"                                      \
4410 -               "       jmp 2b\n"                                       \
4411 -               ".previous\n"                                           \
4412 -               ".section __ex_table,\"a\"\n"                           \
4413 -               "       .align 4\n"                                     \
4414 -               "       .long 4b,5b\n"                                  \
4415 -               "       .long 0b,3b\n"                                  \
4416 -               "       .long 1b,6b\n"                                  \
4417 -               ".previous"                                             \
4418 -               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
4419 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
4420 -               : "memory");                                            \
4421 -} while (0)
4422 +static unsigned long
4423 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
4424 +{
4425 +       int __d0, __d1, __d2;
4426 +
4427 +       __asm__ __volatile__(
4428 +               "       movw %w8,%%es\n"
4429 +               "       cmp  $7,%0\n"
4430 +               "       jbe  1f\n"
4431 +               "       movl %1,%0\n"
4432 +               "       negl %0\n"
4433 +               "       andl $7,%0\n"
4434 +               "       subl %0,%3\n"
4435 +               "4:     rep; movsb\n"
4436 +               "       movl %3,%0\n"
4437 +               "       shrl $2,%0\n"
4438 +               "       andl $3,%3\n"
4439 +               "       .align 2,0x90\n"
4440 +               "0:     rep; movsl\n"
4441 +               "       movl %3,%0\n"
4442 +               "1:     rep; movsb\n"
4443 +               "2:\n"
4444 +               "       pushl %%ss\n"
4445 +               "       popl %%es\n"
4446 +               ".section .fixup,\"ax\"\n"
4447 +               "5:     addl %3,%0\n"
4448 +               "       jmp 2b\n"
4449 +               "3:     lea 0(%3,%0,4),%0\n"
4450 +               "       jmp 2b\n"
4451 +               ".previous\n"
4452 +               ".section __ex_table,\"a\"\n"
4453 +               "       .align 4\n"
4454 +               "       .long 4b,5b\n"
4455 +               "       .long 0b,3b\n"
4456 +               "       .long 1b,2b\n"
4457 +               ".previous"
4458 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
4459 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
4460 +               : "memory");
4461 +       return size;
4462 +}
4463 +
4464 +static unsigned long
4465 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
4466 +{
4467 +       int __d0, __d1, __d2;
4468 +
4469 +       __asm__ __volatile__(
4470 +               "       movw %w8,%%ds\n"
4471 +               "       cmp  $7,%0\n"
4472 +               "       jbe  1f\n"
4473 +               "       movl %1,%0\n"
4474 +               "       negl %0\n"
4475 +               "       andl $7,%0\n"
4476 +               "       subl %0,%3\n"
4477 +               "4:     rep; movsb\n"
4478 +               "       movl %3,%0\n"
4479 +               "       shrl $2,%0\n"
4480 +               "       andl $3,%3\n"
4481 +               "       .align 2,0x90\n"
4482 +               "0:     rep; movsl\n"
4483 +               "       movl %3,%0\n"
4484 +               "1:     rep; movsb\n"
4485 +               "2:\n"
4486 +               "       pushl %%ss\n"
4487 +               "       popl %%ds\n"
4488 +               ".section .fixup,\"ax\"\n"
4489 +               "5:     addl %3,%0\n"
4490 +               "       jmp 2b\n"
4491 +               "3:     lea 0(%3,%0,4),%0\n"
4492 +               "       jmp 2b\n"
4493 +               ".previous\n"
4494 +               ".section __ex_table,\"a\"\n"
4495 +               "       .align 4\n"
4496 +               "       .long 4b,5b\n"
4497 +               "       .long 0b,3b\n"
4498 +               "       .long 1b,2b\n"
4499 +               ".previous"
4500 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
4501 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
4502 +               : "memory");
4503 +       return size;
4504 +}
4505 +
4506 +static unsigned long
4507 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
4508 +{
4509 +       int __d0, __d1, __d2;
4510 +
4511 +       __asm__ __volatile__(
4512 +               "       movw %w8,%%ds\n"
4513 +               "       cmp  $7,%0\n"
4514 +               "       jbe  1f\n"
4515 +               "       movl %1,%0\n"
4516 +               "       negl %0\n"
4517 +               "       andl $7,%0\n"
4518 +               "       subl %0,%3\n"
4519 +               "4:     rep; movsb\n"
4520 +               "       movl %3,%0\n"
4521 +               "       shrl $2,%0\n"
4522 +               "       andl $3,%3\n"
4523 +               "       .align 2,0x90\n"
4524 +               "0:     rep; movsl\n"
4525 +               "       movl %3,%0\n"
4526 +               "1:     rep; movsb\n"
4527 +               "2:\n"
4528 +               "       pushl %%ss\n"
4529 +               "       popl %%ds\n"
4530 +               ".section .fixup,\"ax\"\n"
4531 +               "5:     addl %3,%0\n"
4532 +               "       jmp 6f\n"
4533 +               "3:     lea 0(%3,%0,4),%0\n"
4534 +               "6:     pushl %0\n"
4535 +               "       pushl %%eax\n"
4536 +               "       xorl %%eax,%%eax\n"
4537 +               "       rep; stosb\n"
4538 +               "       popl %%eax\n"
4539 +               "       popl %0\n"
4540 +               "       jmp 2b\n"
4541 +               ".previous\n"
4542 +               ".section __ex_table,\"a\"\n"
4543 +               "       .align 4\n"
4544 +               "       .long 4b,5b\n"
4545 +               "       .long 0b,3b\n"
4546 +               "       .long 1b,6b\n"
4547 +               ".previous"
4548 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
4549 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
4550 +               : "memory");
4551 +       return size;
4552 +}
4553  
4554  unsigned long __copy_to_user_ll(void __user *to, const void *from,
4555                                 unsigned long n)
4556 @@ -765,9 +956,9 @@ survive:
4557         }
4558  #endif
4559         if (movsl_is_ok(to, from, n))
4560 -               __copy_user(to, from, n);
4561 +               n = __generic_copy_to_user(to, from, n);
4562         else
4563 -               n = __copy_user_intel(to, from, n);
4564 +               n = __generic_copy_to_user_intel(to, from, n);
4565         return n;
4566  }
4567  EXPORT_SYMBOL(__copy_to_user_ll);
4568 @@ -777,7 +968,7 @@ unsigned long __copy_from_user_ll(void *
4569  {
4570         BUG_ON((long)n < 0);
4571         if (movsl_is_ok(to, from, n))
4572 -               __copy_user_zeroing(to, from, n);
4573 +               n = __copy_user_zeroing(to, from, n);
4574         else
4575                 n = __copy_user_zeroing_intel(to, from, n);
4576         return n;
4577 @@ -789,10 +980,9 @@ unsigned long __copy_from_user_ll_nozero
4578  {
4579         BUG_ON((long)n < 0);
4580         if (movsl_is_ok(to, from, n))
4581 -               __copy_user(to, from, n);
4582 +               n = __generic_copy_from_user(to, from, n);
4583         else
4584 -               n = __copy_user_intel((void __user *)to,
4585 -                                     (const void *)from, n);
4586 +               n = __generic_copy_from_user_intel(to, from, n);
4587         return n;
4588  }
4589  EXPORT_SYMBOL(__copy_from_user_ll_nozero);
4590 @@ -803,11 +993,11 @@ unsigned long __copy_from_user_ll_nocach
4591         BUG_ON((long)n < 0);
4592  #ifdef CONFIG_X86_INTEL_USERCOPY
4593         if ( n > 64 && cpu_has_xmm2)
4594 -                n = __copy_user_zeroing_intel_nocache(to, from, n);
4595 +               n = __copy_user_zeroing_intel_nocache(to, from, n);
4596         else
4597 -               __copy_user_zeroing(to, from, n);
4598 +               n = __copy_user_zeroing(to, from, n);
4599  #else
4600 -        __copy_user_zeroing(to, from, n);
4601 +       n = __copy_user_zeroing(to, from, n);
4602  #endif
4603         return n;
4604  }
4605 @@ -818,11 +1008,11 @@ unsigned long __copy_from_user_ll_nocach
4606         BUG_ON((long)n < 0);
4607  #ifdef CONFIG_X86_INTEL_USERCOPY
4608         if ( n > 64 && cpu_has_xmm2)
4609 -                n = __copy_user_intel_nocache(to, from, n);
4610 +               n = __copy_user_intel_nocache(to, from, n);
4611         else
4612 -               __copy_user(to, from, n);
4613 +               n = __generic_copy_from_user(to, from, n);
4614  #else
4615 -        __copy_user(to, from, n);
4616 +       n = __generic_copy_from_user(to, from, n);
4617  #endif
4618         return n;
4619  }
4620 @@ -877,3 +1067,45 @@ copy_from_user(void *to, const void __us
4621         return n;
4622  }
4623  EXPORT_SYMBOL(copy_from_user);
4624 +
4625 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4626 +void __set_fs(mm_segment_t x, int cpu)
4627 +{
4628 +       unsigned long limit = x.seg;
4629 +
4630 +       current_thread_info()->addr_limit = x;
4631 +       if (likely(limit)) {
4632 +               limit -= 1UL;
4633 +               limit >>= 12;
4634 +       }
4635 +
4636 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].a = (limit & 0xFFFFUL);
4637 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].b = (limit & 0xF0000UL) | 0xC0F300UL;
4638 +}
4639 +
4640 +void set_fs(mm_segment_t x)
4641 +{
4642 +       int cpu = get_cpu();
4643 +
4644 +#ifdef CONFIG_PAX_KERNEXEC
4645 +       unsigned long cr0;
4646 +
4647 +       pax_open_kernel(cr0);
4648 +#endif
4649 +
4650 +       __set_fs(x, cpu);
4651 +
4652 +#ifdef CONFIG_PAX_KERNEXEC
4653 +       pax_close_kernel(cr0);
4654 +#endif
4655 +
4656 +       put_cpu_no_resched();
4657 +}
4658 +#else
4659 +void set_fs(mm_segment_t x)
4660 +{
4661 +       current_thread_info()->addr_limit = x;
4662 +}
4663 +#endif
4664 +
4665 +EXPORT_SYMBOL(set_fs);
4666 diff -urNp linux-2.6.18/arch/i386/mach-voyager/voyager_smp.c linux-2.6.18/arch/i386/mach-voyager/voyager_smp.c
4667 --- linux-2.6.18/arch/i386/mach-voyager/voyager_smp.c   2006-09-19 23:42:06.000000000 -0400
4668 +++ linux-2.6.18/arch/i386/mach-voyager/voyager_smp.c   2006-09-22 20:45:03.000000000 -0400
4669 @@ -1295,7 +1295,7 @@ smp_local_timer_interrupt(struct pt_regs
4670                                                 per_cpu(prof_counter, cpu);
4671                 }
4672  
4673 -               update_process_times(user_mode_vm(regs));
4674 +               update_process_times(user_mode(regs));
4675         }
4676  
4677         if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
4678 diff -urNp linux-2.6.18/arch/i386/mm/boot_ioremap.c linux-2.6.18/arch/i386/mm/boot_ioremap.c
4679 --- linux-2.6.18/arch/i386/mm/boot_ioremap.c    2006-09-19 23:42:06.000000000 -0400
4680 +++ linux-2.6.18/arch/i386/mm/boot_ioremap.c    2006-09-23 00:27:55.000000000 -0400
4681 @@ -7,53 +7,35 @@
4682   * Written by Dave Hansen <haveblue@us.ibm.com>
4683   */
4684  
4685 -
4686 -/*
4687 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
4688 - * keeps that from happenning.  If anyone has a better way, I'm listening.
4689 - *
4690 - * boot_pte_t is defined only if this all works correctly
4691 - */
4692 -
4693 -#undef CONFIG_X86_PAE
4694  #include <asm/page.h>
4695  #include <asm/pgtable.h>
4696  #include <asm/tlbflush.h>
4697  #include <linux/init.h>
4698  #include <linux/stddef.h>
4699  
4700 -/* 
4701 - * I'm cheating here.  It is known that the two boot PTE pages are 
4702 - * allocated next to each other.  I'm pretending that they're just
4703 - * one big array. 
4704 - */
4705 -
4706 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
4707 -#define boot_pte_index(address) \
4708 -            (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
4709 -
4710 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
4711 -{
4712 -       boot_pte_t* boot_pg = (boot_pte_t*)pg0;
4713 -       return &boot_pg[boot_pte_index((unsigned long)address)];
4714 -}
4715 -
4716  /*
4717   * This is only for a caller who is clever enough to page-align
4718   * phys_addr and virtual_source, and who also has a preference
4719   * about which virtual address from which to steal ptes
4720   */
4721 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
4722 -                   void* virtual_source)
4723 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
4724 +                   char* virtual_source)
4725  {
4726 -       boot_pte_t* pte;
4727 -       int i;
4728 -       char *vaddr = virtual_source;
4729 +       pgd_t *pgd;
4730 +       pud_t *pud;
4731 +       pmd_t *pmd;
4732 +       pte_t* pte;
4733 +       unsigned int i;
4734 +       unsigned long vaddr = (unsigned long)virtual_source;
4735 +
4736 +       pgd = pgd_offset_k(vaddr);
4737 +       pud = pud_offset(pgd, vaddr);
4738 +       pmd = pmd_offset(pud, vaddr);
4739 +       pte = pte_offset_kernel(pmd, vaddr);
4740  
4741 -       pte = boot_vaddr_to_pte(virtual_source);
4742         for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
4743                 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
4744 -               __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
4745 +               __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
4746         }
4747  }
4748  
4749 diff -urNp linux-2.6.18/arch/i386/mm/extable.c linux-2.6.18/arch/i386/mm/extable.c
4750 --- linux-2.6.18/arch/i386/mm/extable.c 2006-09-19 23:42:06.000000000 -0400
4751 +++ linux-2.6.18/arch/i386/mm/extable.c 2006-09-22 20:45:03.000000000 -0400
4752 @@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs
4753         const struct exception_table_entry *fixup;
4754  
4755  #ifdef CONFIG_PNPBIOS
4756 -       if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
4757 +       if (unlikely(!(regs->eflags & VM_MASK) && ((regs->xcs & 0xFFFCU) == PNP_CS32 || (regs->xcs & 0xFFFCU) == PNP_CS16)))
4758         {
4759                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
4760                 extern u32 pnp_bios_is_utter_crap;
4761 diff -urNp linux-2.6.18/arch/i386/mm/fault.c linux-2.6.18/arch/i386/mm/fault.c
4762 --- linux-2.6.18/arch/i386/mm/fault.c   2006-09-19 23:42:06.000000000 -0400
4763 +++ linux-2.6.18/arch/i386/mm/fault.c   2006-09-23 00:26:29.000000000 -0400
4764 @@ -22,6 +22,9 @@
4765  #include <linux/highmem.h>
4766  #include <linux/module.h>
4767  #include <linux/kprobes.h>
4768 +#include <linux/unistd.h>
4769 +#include <linux/compiler.h>
4770 +#include <linux/binfmts.h>
4771  
4772  #include <asm/system.h>
4773  #include <asm/uaccess.h>
4774 @@ -122,9 +125,12 @@ static inline unsigned long get_segment_
4775         *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg;
4776         
4777         /* By far the most common cases. */
4778 -       if (likely(seg == __USER_CS || seg == __KERNEL_CS))
4779 +       if (likely(seg == __USER_CS))
4780                 return eip;
4781  
4782 +       if (likely(seg == __KERNEL_CS))
4783 +               return eip + __KERNEL_TEXT_OFFSET;
4784 +
4785         /* Check the segment exists, is within the current LDT/GDT size,
4786            that kernel/user (ring 0..3) has the appropriate privilege,
4787            that it's a code segment, and get the limit. */
4788 @@ -251,6 +257,30 @@ static noinline void force_sig_info_faul
4789  
4790  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
4791  
4792 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4793 +static int pax_handle_fetch_fault(struct pt_regs *regs);
4794 +#endif
4795 +
4796 +#ifdef CONFIG_PAX_PAGEEXEC
4797 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
4798 +{
4799 +       pgd_t *pgd;
4800 +       pud_t *pud;
4801 +       pmd_t *pmd;
4802 +
4803 +       pgd = pgd_offset(mm, address);
4804 +       if (!pgd_present(*pgd))
4805 +               return NULL;
4806 +       pud = pud_offset(pgd, address);
4807 +       if (!pud_present(*pud))
4808 +               return NULL;
4809 +       pmd = pmd_offset(pud, address);
4810 +       if (!pmd_present(*pmd))
4811 +               return NULL;
4812 +       return pmd;
4813 +}
4814 +#endif
4815 +
4816  static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
4817  {
4818         unsigned index = pgd_index(address);
4819 @@ -332,13 +362,20 @@ fastcall void __kprobes do_page_fault(st
4820         struct mm_struct *mm;
4821         struct vm_area_struct * vma;
4822         unsigned long address;
4823 -       unsigned long page;
4824         int write, si_code;
4825  
4826 +#ifdef CONFIG_PAX_PAGEEXEC
4827 +       pmd_t *pmd;
4828 +       pte_t *pte;
4829 +       spinlock_t *ptl;
4830 +       unsigned char pte_mask;
4831 +#endif
4832 +
4833         /* get the address */
4834          address = read_cr2();
4835  
4836         tsk = current;
4837 +       mm = tsk->mm;
4838  
4839         si_code = SEGV_MAPERR;
4840  
4841 @@ -377,14 +414,12 @@ fastcall void __kprobes do_page_fault(st
4842         if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
4843                 local_irq_enable();
4844  
4845 -       mm = tsk->mm;
4846 -
4847         /*
4848          * If we're in an interrupt, have no user context or are running in an
4849          * atomic region then we must not take the fault..
4850          */
4851         if (in_atomic() || !mm)
4852 -               goto bad_area_nosemaphore;
4853 +               goto bad_area_nopax;
4854  
4855         /* When running in the kernel we expect faults to occur only to
4856          * addresses in user space.  All other faults represent errors in the
4857 @@ -404,10 +439,101 @@ fastcall void __kprobes do_page_fault(st
4858         if (!down_read_trylock(&mm->mmap_sem)) {
4859                 if ((error_code & 4) == 0 &&
4860                     !search_exception_tables(regs->eip))
4861 -                       goto bad_area_nosemaphore;
4862 +                       goto bad_area_nopax;
4863                 down_read(&mm->mmap_sem);
4864         }
4865  
4866 +#ifdef CONFIG_PAX_PAGEEXEC
4867 +       if (unlikely((error_code & 5) != 5 ||
4868 +                    (regs->eflags & X86_EFLAGS_VM) ||
4869 +                    !(mm->pax_flags & MF_PAX_PAGEEXEC)))
4870 +               goto not_pax_fault;
4871 +
4872 +       /* PaX: it's our fault, let's handle it if we can */
4873 +
4874 +       /* PaX: take a look at read faults before acquiring any locks */
4875 +       if (unlikely(!(error_code & 2) && (regs->eip == address))) {
4876 +               /* instruction fetch attempt from a protected page in user mode */
4877 +               up_read(&mm->mmap_sem);
4878 +               switch (pax_handle_fetch_fault(regs)) {
4879 +
4880 +#ifdef CONFIG_PAX_EMUTRAMP
4881 +               case 2:
4882 +                       return;
4883 +#endif
4884 +
4885 +               }
4886 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4887 +               do_exit(SIGKILL);
4888 +       }
4889 +
4890 +       pmd = pax_get_pmd(mm, address);
4891 +       if (unlikely(!pmd))
4892 +               goto not_pax_fault;
4893 +
4894 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
4895 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
4896 +               pte_unmap_unlock(pte, ptl);
4897 +               goto not_pax_fault;
4898 +       }
4899 +
4900 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
4901 +               /* write attempt to a protected page in user mode */
4902 +               pte_unmap_unlock(pte, ptl);
4903 +               goto not_pax_fault;
4904 +       }
4905 +
4906 +#ifdef CONFIG_SMP
4907 +       if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
4908 +#else
4909 +       if (likely(address > get_limit(regs->xcs)))
4910 +#endif
4911 +       {
4912 +               set_pte(pte, pte_mkread(*pte));
4913 +               __flush_tlb_one(address);
4914 +               pte_unmap_unlock(pte, ptl);
4915 +               up_read(&mm->mmap_sem);
4916 +               return;
4917 +       }
4918 +
4919 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
4920 +
4921 +       /*
4922 +        * PaX: fill DTLB with user rights and retry
4923 +        */
4924 +       __asm__ __volatile__ (
4925 +               "movw %w4,%%ds\n"
4926 +               "orb %2,%%ss:(%1)\n"
4927 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
4928 +/*
4929 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
4930 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
4931 + * page fault when examined during a TLB load attempt. this is true not only
4932 + * for PTEs holding a non-present entry but also present entries that will
4933 + * raise a page fault (such as those set up by PaX, or the copy-on-write
4934 + * mechanism). in effect it means that we do *not* need to flush the TLBs
4935 + * for our target pages since their PTEs are simply not in the TLBs at all.
4936 +
4937 + * the best thing in omitting it is that we gain around 15-20% speed in the
4938 + * fast path of the page fault handler and can get rid of tracing since we
4939 + * can no longer flush unintended entries.
4940 + */
4941 +               "invlpg (%0)\n"
4942 +#endif
4943 +               "testb $0,(%0)\n"
4944 +               "xorb %3,%%ss:(%1)\n"
4945 +               "pushl %%ss\n"
4946 +               "popl %%ds\n"
4947 +               :
4948 +               : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
4949 +               : "memory", "cc");
4950 +       pte_unmap_unlock(pte, ptl);
4951 +       up_read(&mm->mmap_sem);
4952 +       return;
4953 +
4954 +not_pax_fault:
4955 +#endif
4956 +
4957         vma = find_vma(mm, address);
4958         if (!vma)
4959                 goto bad_area;
4960 @@ -493,6 +619,37 @@ bad_area:
4961         up_read(&mm->mmap_sem);
4962  
4963  bad_area_nosemaphore:
4964 +
4965 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4966 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
4967 +
4968 +#ifdef CONFIG_PAX_PAGEEXEC
4969 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
4970 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4971 +                       do_exit(SIGKILL);
4972 +               }
4973 +#endif
4974 +
4975 +#ifdef CONFIG_PAX_SEGMEXEC
4976 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
4977 +
4978 +                       switch (pax_handle_fetch_fault(regs)) {
4979 +
4980 +#ifdef CONFIG_PAX_EMUTRAMP
4981 +                       case 2:
4982 +                               return;
4983 +#endif
4984 +
4985 +                       }
4986 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4987 +                       do_exit(SIGKILL);
4988 +               }
4989 +#endif
4990 +
4991 +       }
4992 +#endif
4993 +
4994 +bad_area_nopax:
4995         /* User mode accesses just cause a SIGSEGV */
4996         if (error_code & 4) {
4997                 /* 
4998 @@ -560,6 +717,21 @@ no_context:
4999                 if (address < PAGE_SIZE)
5000                         printk(KERN_ALERT "BUG: unable to handle kernel NULL "
5001                                         "pointer dereference");
5002 +
5003 +#ifdef CONFIG_PAX_KERNEXEC
5004 +#ifdef CONFIG_MODULES
5005 +               else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
5006 +#else
5007 +               else if (init_mm.start_code <= address && address < init_mm.end_code)
5008 +#endif
5009 +                       if (tsk->signal->curr_ip)
5010 +                               printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
5011 +                                                NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
5012 +                       else
5013 +                               printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
5014 +                                                tsk->comm, tsk->pid, tsk->uid, tsk->euid);
5015 +#endif
5016 +
5017                 else
5018                         printk(KERN_ALERT "BUG: unable to handle kernel paging"
5019                                         " request");
5020 @@ -567,24 +739,34 @@ no_context:
5021                 printk(KERN_ALERT " printing eip:\n");
5022                 printk("%08lx\n", regs->eip);
5023         }
5024 -       page = read_cr3();
5025 -       page = ((unsigned long *) __va(page))[address >> 22];
5026 -       if (oops_may_print())
5027 -               printk(KERN_ALERT "*pde = %08lx\n", page);
5028 -       /*
5029 -        * We must not directly access the pte in the highpte
5030 -        * case, the page table might be allocated in highmem.
5031 -        * And lets rather not kmap-atomic the pte, just in case
5032 -        * it's allocated already.
5033 -        */
5034 +
5035 +       if (oops_may_print()) {
5036 +               unsigned long index = pgd_index(address);
5037 +               pgd_t *pgd;
5038 +               pud_t *pud;
5039 +               pmd_t *pmd;
5040 +               pte_t *pte;
5041 +
5042 +               pgd = index + (pgd_t *)__va(read_cr3());
5043 +               printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
5044 +               if (pgd_present(*pgd)) {
5045 +                       pud = pud_offset(pgd, address);
5046 +                       pmd = pmd_offset(pud, address);
5047 +                       printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
5048 +                       /*
5049 +                        * We must not directly access the pte in the highpte
5050 +                        * case, the page table might be allocated in highmem.
5051 +                        * And lets rather not kmap-atomic the pte, just in case
5052 +                        * it's allocated already.
5053 +                        */
5054  #ifndef CONFIG_HIGHPTE
5055 -       if ((page & 1) && oops_may_print()) {
5056 -               page &= PAGE_MASK;
5057 -               address &= 0x003ff000;
5058 -               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
5059 -               printk(KERN_ALERT "*pte = %08lx\n", page);
5060 -       }
5061 +                       if (pmd_present(*pmd) && !pmd_large(*pmd)) {
5062 +                               pte = pte_offset_kernel(pmd, address);
5063 +                               printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
5064 +                       }
5065  #endif
5066 +               }
5067 +       }
5068         tsk->thread.cr2 = address;
5069         tsk->thread.trap_no = 14;
5070         tsk->thread.error_code = error_code;
5071 @@ -661,3 +843,105 @@ void vmalloc_sync_all(void)
5072         }
5073  }
5074  #endif
5075 +
5076 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5077 +/*
5078 + * PaX: decide what to do with offenders (regs->eip = fault address)
5079 + *
5080 + * returns 1 when task should be killed
5081 + *         2 when gcc trampoline was detected
5082 + */
5083 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5084 +{
5085 +
5086 +#ifdef CONFIG_PAX_EMUTRAMP
5087 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
5088 +       int err;
5089 +#endif
5090 +
5091 +       if (regs->eflags & X86_EFLAGS_VM)
5092 +               return 1;
5093 +
5094 +#ifdef CONFIG_PAX_EMUTRAMP
5095 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
5096 +               return 1;
5097 +
5098 +       do { /* PaX: gcc trampoline emulation #1 */
5099 +               unsigned char mov1, mov2;
5100 +               unsigned short jmp;
5101 +               unsigned long addr1, addr2;
5102 +
5103 +               err = get_user(mov1, (unsigned char __user *)regs->eip);
5104 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
5105 +               err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
5106 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
5107 +               err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
5108 +
5109 +               if (err)
5110 +                       break;
5111 +
5112 +               if ((mov1 & 0xF8) == 0xB8 &&
5113 +                   (mov2 & 0xF8) == 0xB8 &&
5114 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
5115 +                   (jmp & 0xF8FF) == 0xE0FF &&
5116 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07))
5117 +               {
5118 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
5119 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
5120 +                       regs->eip = addr2;
5121 +                       return 2;
5122 +               }
5123 +       } while (0);
5124 +
5125 +       do { /* PaX: gcc trampoline emulation #2 */
5126 +               unsigned char mov, jmp;
5127 +               unsigned long addr1, addr2;
5128 +
5129 +               err = get_user(mov, (unsigned char __user *)regs->eip);
5130 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
5131 +               err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
5132 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
5133 +
5134 +               if (err)
5135 +                       break;
5136 +
5137 +               if ((mov & 0xF8) == 0xB8 &&
5138 +                   jmp == 0xE9)
5139 +               {
5140 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
5141 +                       regs->eip += addr2 + 10;
5142 +                       return 2;
5143 +               }
5144 +       } while (0);
5145 +#endif
5146 +
5147 +       return 1; /* PaX in action */
5148 +}
5149 +#endif
5150 +
5151 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5152 +void pax_report_insns(void *pc, void *sp)
5153 +{
5154 +       long i;
5155 +
5156 +       printk(KERN_ERR "PAX: bytes at PC: ");
5157 +       for (i = 0; i < 20; i++) {
5158 +               unsigned char c;
5159 +               if (get_user(c, (unsigned char __user *)pc+i))
5160 +                       printk("?? ");
5161 +               else
5162 +                       printk("%02x ", c);
5163 +       }
5164 +       printk("\n");
5165 +
5166 +       printk(KERN_ERR "PAX: bytes at SP-4: ");
5167 +       for (i = -1; i < 20; i++) {
5168 +               unsigned long c;
5169 +               if (get_user(c, (unsigned long __user *)sp+i))
5170 +                       printk("???????? ");
5171 +               else
5172 +                       printk("%08lx ", c);
5173 +       }
5174 +       printk("\n");
5175 +}
5176 +#endif
5177 diff -urNp linux-2.6.18/arch/i386/mm/hugetlbpage.c linux-2.6.18/arch/i386/mm/hugetlbpage.c
5178 --- linux-2.6.18/arch/i386/mm/hugetlbpage.c     2006-09-19 23:42:06.000000000 -0400
5179 +++ linux-2.6.18/arch/i386/mm/hugetlbpage.c     2006-09-22 20:45:03.000000000 -0400
5180 @@ -120,7 +120,12 @@ static unsigned long hugetlb_get_unmappe
5181  {
5182         struct mm_struct *mm = current->mm;
5183         struct vm_area_struct *vma;
5184 -       unsigned long start_addr;
5185 +       unsigned long start_addr, task_size = TASK_SIZE;
5186 +
5187 +#ifdef CONFIG_PAX_SEGMEXEC
5188 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
5189 +               task_size = SEGMEXEC_TASK_SIZE;
5190 +#endif
5191  
5192         if (len > mm->cached_hole_size) {
5193                 start_addr = mm->free_area_cache;
5194 @@ -134,7 +139,7 @@ full_search:
5195  
5196         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
5197                 /* At this point:  (!vma || addr < vma->vm_end). */
5198 -               if (TASK_SIZE - len < addr) {
5199 +               if (task_size - len < addr) {
5200                         /*
5201                          * Start a new search - just in case we missed
5202                          * some holes.
5203 @@ -162,9 +167,8 @@ static unsigned long hugetlb_get_unmappe
5204  {
5205         struct mm_struct *mm = current->mm;
5206         struct vm_area_struct *vma, *prev_vma;
5207 -       unsigned long base = mm->mmap_base, addr = addr0;
5208 +       unsigned long base = mm->mmap_base, addr;
5209         unsigned long largest_hole = mm->cached_hole_size;
5210 -       int first_time = 1;
5211  
5212         /* don't allow allocations above current base */
5213         if (mm->free_area_cache > base)
5214 @@ -174,7 +178,7 @@ static unsigned long hugetlb_get_unmappe
5215                 largest_hole = 0;
5216                 mm->free_area_cache  = base;
5217         }
5218 -try_again:
5219 +
5220         /* make sure it can fit in the remaining address space */
5221         if (mm->free_area_cache < len)
5222                 goto fail;
5223 @@ -216,16 +220,6 @@ try_again:
5224  
5225  fail:
5226         /*
5227 -        * if hint left us with no space for the requested
5228 -        * mapping then try again:
5229 -        */
5230 -       if (first_time) {
5231 -               mm->free_area_cache = base;
5232 -               largest_hole = 0;
5233 -               first_time = 0;
5234 -               goto try_again;
5235 -       }
5236 -       /*
5237          * A failed mmap() very likely causes application failure,
5238          * so fall back to the bottom-up function here. This scenario
5239          * can happen with large stack limits and large mmap()
5240 @@ -251,16 +245,23 @@ hugetlb_get_unmapped_area(struct file *f
5241  {
5242         struct mm_struct *mm = current->mm;
5243         struct vm_area_struct *vma;
5244 +       unsigned long task_size = TASK_SIZE;
5245  
5246         if (len & ~HPAGE_MASK)
5247                 return -EINVAL;
5248 -       if (len > TASK_SIZE)
5249 +
5250 +#ifdef CONFIG_PAX_SEGMEXEC
5251 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
5252 +               task_size = SEGMEXEC_TASK_SIZE;
5253 +#endif
5254 +
5255 +       if (len > task_size || addr > task_size - len)
5256                 return -ENOMEM;
5257  
5258         if (addr) {
5259                 addr = ALIGN(addr, HPAGE_SIZE);
5260                 vma = find_vma(mm, addr);
5261 -               if (TASK_SIZE - len >= addr &&
5262 +               if (task_size - len >= addr &&
5263                     (!vma || addr + len <= vma->vm_start))
5264                         return addr;
5265         }
5266 diff -urNp linux-2.6.18/arch/i386/mm/init.c linux-2.6.18/arch/i386/mm/init.c
5267 --- linux-2.6.18/arch/i386/mm/init.c    2006-09-19 23:42:06.000000000 -0400
5268 +++ linux-2.6.18/arch/i386/mm/init.c    2006-09-22 20:45:03.000000000 -0400
5269 @@ -42,6 +42,7 @@
5270  #include <asm/tlb.h>
5271  #include <asm/tlbflush.h>
5272  #include <asm/sections.h>
5273 +#include <asm/desc.h>
5274  
5275  unsigned int __VMALLOC_RESERVE = 128 << 20;
5276  
5277 @@ -51,30 +52,6 @@ unsigned long highstart_pfn, highend_pfn
5278  static int noinline do_test_wp_bit(void);
5279  
5280  /*
5281 - * Creates a middle page table and puts a pointer to it in the
5282 - * given global directory entry. This only returns the gd entry
5283 - * in non-PAE compilation mode, since the middle layer is folded.
5284 - */
5285 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
5286 -{
5287 -       pud_t *pud;
5288 -       pmd_t *pmd_table;
5289 -               
5290 -#ifdef CONFIG_X86_PAE
5291 -       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
5292 -       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
5293 -       pud = pud_offset(pgd, 0);
5294 -       if (pmd_table != pmd_offset(pud, 0)) 
5295 -               BUG();
5296 -#else
5297 -       pud = pud_offset(pgd, 0);
5298 -       pmd_table = pmd_offset(pud, 0);
5299 -#endif
5300 -
5301 -       return pmd_table;
5302 -}
5303 -
5304 -/*
5305   * Create a page table and place a pointer to it in a middle page
5306   * directory entry.
5307   */
5308 @@ -82,7 +59,11 @@ static pte_t * __init one_page_table_ini
5309  {
5310         if (pmd_none(*pmd)) {
5311                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
5312 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5313 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
5314 +#else
5315                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
5316 +#endif
5317                 if (page_table != pte_offset_kernel(pmd, 0))
5318                         BUG();  
5319  
5320 @@ -117,8 +98,6 @@ static void __init page_table_range_init
5321         pgd = pgd_base + pgd_idx;
5322  
5323         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
5324 -               if (pgd_none(*pgd)) 
5325 -                       one_md_table_init(pgd);
5326                 pud = pud_offset(pgd, vaddr);
5327                 pmd = pmd_offset(pud, vaddr);
5328                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
5329 @@ -131,11 +110,22 @@ static void __init page_table_range_init
5330         }
5331  }
5332  
5333 -static inline int is_kernel_text(unsigned long addr)
5334 +static inline int is_kernel_text(unsigned long start, unsigned long end)
5335  {
5336 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
5337 -               return 1;
5338 -       return 0;
5339 +       unsigned long etext;
5340 +
5341 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
5342 +       etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
5343 +#else
5344 +       etext = (unsigned long)&_etext;
5345 +#endif
5346 +
5347 +       if ((start > etext + __KERNEL_TEXT_OFFSET ||
5348 +            end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
5349 +           (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
5350 +            end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
5351 +               return 0;
5352 +       return 1;
5353  }
5354  
5355  /*
5356 @@ -147,26 +137,24 @@ static void __init kernel_physical_mappi
5357  {
5358         unsigned long pfn;
5359         pgd_t *pgd;
5360 +       pud_t *pud;
5361         pmd_t *pmd;
5362         pte_t *pte;
5363 -       int pgd_idx, pmd_idx, pte_ofs;
5364 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
5365  
5366         pgd_idx = pgd_index(PAGE_OFFSET);
5367         pgd = pgd_base + pgd_idx;
5368         pfn = 0;
5369  
5370 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
5371 -               pmd = one_md_table_init(pgd);
5372 -               if (pfn >= max_low_pfn)
5373 -                       continue;
5374 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
5375 +               pud = pud_offset(pgd, 0);
5376 +               pmd = pmd_offset(pud, 0);
5377                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
5378 -                       unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
5379 +                       unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
5380  
5381                         /* Map with big pages if possible, otherwise create normal page tables. */
5382                         if (cpu_has_pse) {
5383 -                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
5384 -
5385 -                               if (is_kernel_text(address) || is_kernel_text(address2))
5386 +                               if (is_kernel_text(address, address + PMD_SIZE))
5387                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
5388                                 else
5389                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
5390 @@ -175,7 +163,7 @@ static void __init kernel_physical_mappi
5391                                 pte = one_page_table_init(pmd);
5392  
5393                                 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
5394 -                                               if (is_kernel_text(address))
5395 +                                               if (is_kernel_text(address, address + PAGE_SIZE))
5396                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
5397                                                 else
5398                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
5399 @@ -342,13 +330,6 @@ static void __init pagetable_init (void)
5400         unsigned long vaddr;
5401         pgd_t *pgd_base = swapper_pg_dir;
5402  
5403 -#ifdef CONFIG_X86_PAE
5404 -       int i;
5405 -       /* Init entries of the first-level page table to the zero page */
5406 -       for (i = 0; i < PTRS_PER_PGD; i++)
5407 -               set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
5408 -#endif
5409 -
5410         /* Enable PSE if available */
5411         if (cpu_has_pse) {
5412                 set_in_cr4(X86_CR4_PSE);
5413 @@ -372,17 +353,6 @@ static void __init pagetable_init (void)
5414         page_table_range_init(vaddr, 0, pgd_base);
5415  
5416         permanent_kmaps_init(pgd_base);
5417 -
5418 -#ifdef CONFIG_X86_PAE
5419 -       /*
5420 -        * Add low memory identity-mappings - SMP needs it when
5421 -        * starting up on an AP from real-mode. In the non-PAE
5422 -        * case we already have these mappings through head.S.
5423 -        * All user-space mappings are explicitly cleared after
5424 -        * SMP startup.
5425 -        */
5426 -       set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
5427 -#endif
5428  }
5429  
5430  #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP)
5431 @@ -424,7 +394,6 @@ void zap_low_mappings (void)
5432         flush_tlb_all();
5433  }
5434  
5435 -static int disable_nx __initdata = 0;
5436  u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
5437  
5438  /*
5439 @@ -438,11 +407,9 @@ u64 __supported_pte_mask __read_mostly =
5440  void __init noexec_setup(const char *str)
5441  {
5442         if (!strncmp(str, "on",2) && cpu_has_nx) {
5443 -               __supported_pte_mask |= _PAGE_NX;
5444 -               disable_nx = 0;
5445 +               nx_enabled = 1;
5446         } else if (!strncmp(str,"off",3)) {
5447 -               disable_nx = 1;
5448 -               __supported_pte_mask &= ~_PAGE_NX;
5449 +               nx_enabled = 0;
5450         }
5451  }
5452  
5453 @@ -451,17 +418,13 @@ int nx_enabled = 0;
5454  
5455  static void __init set_nx(void)
5456  {
5457 -       unsigned int v[4], l, h;
5458 +       if (!nx_enabled && cpu_has_nx) {
5459 +               unsigned l, h;
5460  
5461 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
5462 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
5463 -               if ((v[3] & (1 << 20)) && !disable_nx) {
5464 -                       rdmsr(MSR_EFER, l, h);
5465 -                       l |= EFER_NX;
5466 -                       wrmsr(MSR_EFER, l, h);
5467 -                       nx_enabled = 1;
5468 -                       __supported_pte_mask |= _PAGE_NX;
5469 -               }
5470 +               __supported_pte_mask &= ~_PAGE_NX;
5471 +               rdmsr(MSR_EFER, l, h);
5472 +               l &= ~EFER_NX;
5473 +               wrmsr(MSR_EFER, l, h);
5474         }
5475  }
5476  
5477 @@ -513,14 +476,6 @@ void __init paging_init(void)
5478  
5479         load_cr3(swapper_pg_dir);
5480  
5481 -#ifdef CONFIG_X86_PAE
5482 -       /*
5483 -        * We will bail out later - printk doesn't work right now so
5484 -        * the user would just see a hanging kernel.
5485 -        */
5486 -       if (cpu_has_pae)
5487 -               set_in_cr4(X86_CR4_PAE);
5488 -#endif
5489         __flush_tlb_all();
5490  
5491         kmap_init();
5492 @@ -612,7 +567,7 @@ void __init mem_init(void)
5493         set_highmem_pages_init(bad_ppro);
5494  
5495         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
5496 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
5497 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
5498         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
5499  
5500         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
5501 @@ -629,10 +584,6 @@ void __init mem_init(void)
5502                 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
5503                );
5504  
5505 -#ifdef CONFIG_X86_PAE
5506 -       if (!cpu_has_pae)
5507 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
5508 -#endif
5509         if (boot_cpu_data.wp_works_ok < 0)
5510                 test_wp_bit();
5511  
5512 @@ -761,6 +712,37 @@ void free_init_pages(char *what, unsigne
5513  
5514  void free_initmem(void)
5515  {
5516 +
5517 +#ifdef CONFIG_PAX_KERNEXEC
5518 +       /* PaX: limit KERNEL_CS to actual size */
5519 +       unsigned long addr, limit;
5520 +       int cpu;
5521 +       pgd_t *pgd;
5522 +       pud_t *pud;
5523 +       pmd_t *pmd;
5524 +
5525 +#ifdef CONFIG_MODULES
5526 +       limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
5527 +#else
5528 +       limit = (unsigned long)&_etext;
5529 +#endif
5530 +       limit = (limit - 1UL) >> PAGE_SHIFT;
5531 +
5532 +       for (cpu = 0; cpu < NR_CPUS; cpu++) {
5533 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
5534 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
5535 +       }
5536 +
5537 +       /* PaX: make KERNEL_CS read-only */
5538 +       for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
5539 +               pgd = pgd_offset_k(addr);
5540 +               pud = pud_offset(pgd, addr);
5541 +               pmd = pmd_offset(pud, addr);
5542 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
5543 +       }
5544 +       flush_tlb_all();
5545 +#endif
5546 +
5547         free_init_pages("unused kernel memory",
5548                         (unsigned long)(&__init_begin),
5549                         (unsigned long)(&__init_end));
5550 diff -urNp linux-2.6.18/arch/i386/mm/mmap.c linux-2.6.18/arch/i386/mm/mmap.c
5551 --- linux-2.6.18/arch/i386/mm/mmap.c    2006-09-19 23:42:06.000000000 -0400
5552 +++ linux-2.6.18/arch/i386/mm/mmap.c    2006-09-22 20:45:03.000000000 -0400
5553 @@ -34,12 +34,18 @@
5554   * Leave an at least ~128 MB hole.
5555   */
5556  #define MIN_GAP (128*1024*1024)
5557 -#define MAX_GAP (TASK_SIZE/6*5)
5558 +#define MAX_GAP (task_size/6*5)
5559  
5560  static inline unsigned long mmap_base(struct mm_struct *mm)
5561  {
5562         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
5563         unsigned long random_factor = 0;
5564 +       unsigned long task_size = TASK_SIZE;
5565 +
5566 +#ifdef CONFIG_PAX_SEGMEXEC
5567 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
5568 +               task_size = SEGMEXEC_TASK_SIZE;
5569 +#endif
5570  
5571         if (current->flags & PF_RANDOMIZE)
5572                 random_factor = get_random_int() % (1024*1024);
5573 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
5574         else if (gap > MAX_GAP)
5575                 gap = MAX_GAP;
5576  
5577 -       return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
5578 +       return PAGE_ALIGN(task_size - gap - random_factor);
5579  }
5580  
5581  /*
5582 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
5583                         (current->personality & ADDR_COMPAT_LAYOUT) ||
5584                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
5585                 mm->mmap_base = TASK_UNMAPPED_BASE;
5586 +
5587 +#ifdef CONFIG_PAX_RANDMMAP
5588 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5589 +                       mm->mmap_base += mm->delta_mmap;
5590 +#endif
5591 +
5592                 mm->get_unmapped_area = arch_get_unmapped_area;
5593                 mm->unmap_area = arch_unmap_area;
5594         } else {
5595                 mm->mmap_base = mmap_base(mm);
5596 +
5597 +#ifdef CONFIG_PAX_RANDMMAP
5598 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5599 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
5600 +#endif
5601 +
5602                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
5603                 mm->unmap_area = arch_unmap_area_topdown;
5604         }
5605 diff -urNp linux-2.6.18/arch/i386/mm/pageattr.c linux-2.6.18/arch/i386/mm/pageattr.c
5606 --- linux-2.6.18/arch/i386/mm/pageattr.c        2006-09-19 23:42:06.000000000 -0400
5607 +++ linux-2.6.18/arch/i386/mm/pageattr.c        2006-09-22 20:45:03.000000000 -0400
5608 @@ -13,6 +13,7 @@
5609  #include <asm/tlbflush.h>
5610  #include <asm/pgalloc.h>
5611  #include <asm/sections.h>
5612 +#include <asm/desc.h>
5613  
5614  static DEFINE_SPINLOCK(cpa_lock);
5615  static struct list_head df_list = LIST_HEAD_INIT(df_list);
5616 @@ -83,7 +84,18 @@ static void set_pmd_pte(pte_t *kpte, uns
5617         struct page *page;
5618         unsigned long flags;
5619  
5620 +#ifdef CONFIG_PAX_KERNEXEC
5621 +       unsigned long cr0;
5622 +
5623 +       pax_open_kernel(cr0);
5624 +#endif
5625 +
5626         set_pte_atomic(kpte, pte);      /* change init_mm */
5627 +
5628 +#ifdef CONFIG_PAX_KERNEXEC
5629 +       pax_close_kernel(cr0);
5630 +#endif
5631 +
5632         if (PTRS_PER_PMD > 1)
5633                 return;
5634  
5635 @@ -110,7 +122,7 @@ static inline void revert_page(struct pa
5636         pte_t *linear;
5637  
5638         ref_prot =
5639 -       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
5640 +       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
5641                 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
5642  
5643         linear = (pte_t *)
5644 @@ -142,7 +154,7 @@ __change_page_attr(struct page *page, pg
5645                         struct page *split;
5646  
5647                         ref_prot =
5648 -                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
5649 +                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
5650                                 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
5651                         split = split_large_page(address, prot, ref_prot);
5652                         if (!split)
5653 diff -urNp linux-2.6.18/arch/i386/oprofile/backtrace.c linux-2.6.18/arch/i386/oprofile/backtrace.c
5654 --- linux-2.6.18/arch/i386/oprofile/backtrace.c 2006-09-19 23:42:06.000000000 -0400
5655 +++ linux-2.6.18/arch/i386/oprofile/backtrace.c 2006-09-22 20:45:03.000000000 -0400
5656 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
5657         head = (struct frame_head *)regs->ebp;
5658  #endif
5659  
5660 -       if (!user_mode_vm(regs)) {
5661 +       if (!user_mode(regs)) {
5662                 while (depth-- && valid_kernel_stack(head, regs))
5663                         head = dump_kernel_backtrace(head);
5664                 return;
5665 diff -urNp linux-2.6.18/arch/i386/oprofile/op_model_p4.c linux-2.6.18/arch/i386/oprofile/op_model_p4.c
5666 --- linux-2.6.18/arch/i386/oprofile/op_model_p4.c       2006-09-19 23:42:06.000000000 -0400
5667 +++ linux-2.6.18/arch/i386/oprofile/op_model_p4.c       2006-09-22 20:45:03.000000000 -0400
5668 @@ -45,7 +45,7 @@ static inline void setup_num_counters(vo
5669  #endif
5670  }
5671  
5672 -static int inline addr_increment(void)
5673 +static inline int addr_increment(void)
5674  {
5675  #ifdef CONFIG_SMP
5676         return smp_num_siblings == 2 ? 2 : 1;
5677 diff -urNp linux-2.6.18/arch/i386/power/cpu.c linux-2.6.18/arch/i386/power/cpu.c
5678 --- linux-2.6.18/arch/i386/power/cpu.c  2006-09-19 23:42:06.000000000 -0400
5679 +++ linux-2.6.18/arch/i386/power/cpu.c  2006-09-22 20:45:03.000000000 -0400
5680 @@ -63,7 +63,7 @@ static void do_fpu_end(void)
5681  static void fix_processor_context(void)
5682  {
5683         int cpu = smp_processor_id();
5684 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
5685 +       struct tss_struct * t = init_tss + cpu;
5686  
5687         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. */
5688  
5689 diff -urNp linux-2.6.18/arch/ia64/ia32/binfmt_elf32.c linux-2.6.18/arch/ia64/ia32/binfmt_elf32.c
5690 --- linux-2.6.18/arch/ia64/ia32/binfmt_elf32.c  2006-09-19 23:42:06.000000000 -0400
5691 +++ linux-2.6.18/arch/ia64/ia32/binfmt_elf32.c  2006-09-22 20:45:03.000000000 -0400
5692 @@ -45,6 +45,17 @@ randomize_stack_top(unsigned long stack_
5693  
5694  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
5695  
5696 +#ifdef CONFIG_PAX_ASLR
5697 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
5698 +
5699 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
5700 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5701 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
5702 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5703 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
5704 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5705 +#endif
5706 +
5707  /* Ugly but avoids duplication */
5708  #include "../../../fs/binfmt_elf.c"
5709  
5710 diff -urNp linux-2.6.18/arch/ia64/ia32/ia32priv.h linux-2.6.18/arch/ia64/ia32/ia32priv.h
5711 --- linux-2.6.18/arch/ia64/ia32/ia32priv.h      2006-09-19 23:42:06.000000000 -0400
5712 +++ linux-2.6.18/arch/ia64/ia32/ia32priv.h      2006-09-22 20:45:03.000000000 -0400
5713 @@ -304,7 +304,14 @@ struct old_linux32_dirent {
5714  #define ELF_DATA       ELFDATA2LSB
5715  #define ELF_ARCH       EM_386
5716  
5717 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
5718 +#ifdef CONFIG_PAX_RANDUSTACK
5719 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
5720 +#else
5721 +#define __IA32_DELTA_STACK     0UL
5722 +#endif
5723 +
5724 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
5725 +
5726  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
5727  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
5728  
5729 diff -urNp linux-2.6.18/arch/ia64/kernel/module.c linux-2.6.18/arch/ia64/kernel/module.c
5730 --- linux-2.6.18/arch/ia64/kernel/module.c      2006-09-19 23:42:06.000000000 -0400
5731 +++ linux-2.6.18/arch/ia64/kernel/module.c      2006-09-22 20:45:03.000000000 -0400
5732 @@ -321,7 +321,7 @@ module_alloc (unsigned long size)
5733  void
5734  module_free (struct module *mod, void *module_region)
5735  {
5736 -       if (mod->arch.init_unw_table && module_region == mod->module_init) {
5737 +       if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
5738                 unw_remove_unwind_table(mod->arch.init_unw_table);
5739                 mod->arch.init_unw_table = NULL;
5740         }
5741 @@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
5742  }
5743  
5744  static inline int
5745 +in_init_rx (const struct module *mod, uint64_t addr)
5746 +{
5747 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
5748 +}
5749 +
5750 +static inline int
5751 +in_init_rw (const struct module *mod, uint64_t addr)
5752 +{
5753 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
5754 +}
5755 +
5756 +static inline int
5757  in_init (const struct module *mod, uint64_t addr)
5758  {
5759 -       return addr - (uint64_t) mod->module_init < mod->init_size;
5760 +       return in_init_rx(mod, value) || in_init_rw(mod, value);
5761 +}
5762 +
5763 +static inline int
5764 +in_core_rx (const struct module *mod, uint64_t addr)
5765 +{
5766 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
5767 +}
5768 +
5769 +static inline int
5770 +in_core_rw (const struct module *mod, uint64_t addr)
5771 +{
5772 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
5773  }
5774  
5775  static inline int
5776  in_core (const struct module *mod, uint64_t addr)
5777  {
5778 -       return addr - (uint64_t) mod->module_core < mod->core_size;
5779 +       return in_core_rx(mod, value) || in_core_rw(mod, value);
5780  }
5781  
5782  static inline int
5783 @@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
5784                 break;
5785  
5786               case RV_BDREL:
5787 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
5788 +               if (in_init_rx(mod, val))
5789 +                       val -= (uint64_t) mod->module_init_rx;
5790 +               else if (in_init_rw(mod, val))
5791 +                       val -= (uint64_t) mod->module_init_rw;
5792 +               else if (in_core_rx(mod, val))
5793 +                       val -= (uint64_t) mod->module_core_rx;
5794 +               else if (in_core_rw(mod, val))
5795 +                       val -= (uint64_t) mod->module_core_rw;
5796                 break;
5797  
5798               case RV_LTV:
5799 @@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
5800                  *     addresses have been selected...
5801                  */
5802                 uint64_t gp;
5803 -               if (mod->core_size > MAX_LTOFF)
5804 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
5805                         /*
5806                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
5807                          * at the end of the module.
5808                          */
5809 -                       gp = mod->core_size - MAX_LTOFF / 2;
5810 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
5811                 else
5812 -                       gp = mod->core_size / 2;
5813 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
5814 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
5815 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
5816                 mod->arch.gp = gp;
5817                 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
5818         }
5819 diff -urNp linux-2.6.18/arch/ia64/kernel/ptrace.c linux-2.6.18/arch/ia64/kernel/ptrace.c
5820 --- linux-2.6.18/arch/ia64/kernel/ptrace.c      2006-09-19 23:42:06.000000000 -0400
5821 +++ linux-2.6.18/arch/ia64/kernel/ptrace.c      2006-09-22 20:04:35.000000000 -0400
5822 @@ -17,6 +17,7 @@
5823  #include <linux/audit.h>
5824  #include <linux/signal.h>
5825  #include <linux/vs_pid.h>
5826 +#include <linux/grsecurity.h>
5827  
5828  #include <asm/pgtable.h>
5829  #include <asm/processor.h>
5830 @@ -1446,6 +1447,9 @@ sys_ptrace (long request, pid_t pid, uns
5831         if (pid == 1)           /* no messing around with init! */
5832                 goto out_tsk;
5833  
5834 +       if (gr_handle_ptrace(child, request))
5835 +               goto out_tsk;
5836 +
5837         if (request == PTRACE_ATTACH) {
5838                 ret = ptrace_attach(child);
5839                 goto out_tsk;
5840 diff -urNp linux-2.6.18/arch/ia64/kernel/sys_ia64.c linux-2.6.18/arch/ia64/kernel/sys_ia64.c
5841 --- linux-2.6.18/arch/ia64/kernel/sys_ia64.c    2006-09-19 23:42:06.000000000 -0400
5842 +++ linux-2.6.18/arch/ia64/kernel/sys_ia64.c    2006-09-22 20:45:03.000000000 -0400
5843 @@ -37,6 +37,13 @@ arch_get_unmapped_area (struct file *fil
5844         if (REGION_NUMBER(addr) == RGN_HPAGE)
5845                 addr = 0;
5846  #endif
5847 +
5848 +#ifdef CONFIG_PAX_RANDMMAP
5849 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
5850 +               addr = mm->free_area_cache;
5851 +       else
5852 +#endif
5853 +
5854         if (!addr)
5855                 addr = mm->free_area_cache;
5856  
5857 @@ -55,9 +62,9 @@ arch_get_unmapped_area (struct file *fil
5858         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
5859                 /* At this point:  (!vma || addr < vma->vm_end). */
5860                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
5861 -                       if (start_addr != TASK_UNMAPPED_BASE) {
5862 +                       if (start_addr != mm->mmap_base) {
5863                                 /* Start a new search --- just in case we missed some holes.  */
5864 -                               addr = TASK_UNMAPPED_BASE;
5865 +                               addr = mm->mmap_base;
5866                                 goto full_search;
5867                         }
5868                         return -ENOMEM;
5869 diff -urNp linux-2.6.18/arch/ia64/mm/fault.c linux-2.6.18/arch/ia64/mm/fault.c
5870 --- linux-2.6.18/arch/ia64/mm/fault.c   2006-09-19 23:42:06.000000000 -0400
5871 +++ linux-2.6.18/arch/ia64/mm/fault.c   2006-09-22 20:45:03.000000000 -0400
5872 @@ -10,6 +10,7 @@
5873  #include <linux/interrupt.h>
5874  #include <linux/kprobes.h>
5875  #include <linux/vs_memory.h>
5876 +#include <linux/binfmts.h>
5877  
5878  #include <asm/pgtable.h>
5879  #include <asm/processor.h>
5880 @@ -85,6 +86,23 @@ mapped_kernel_page_is_present (unsigned 
5881         return pte_present(pte);
5882  }
5883  
5884 +#ifdef CONFIG_PAX_PAGEEXEC
5885 +void pax_report_insns(void *pc, void *sp)
5886 +{
5887 +       unsigned long i;
5888 +
5889 +       printk(KERN_ERR "PAX: bytes at PC: ");
5890 +       for (i = 0; i < 8; i++) {
5891 +               unsigned int c;
5892 +               if (get_user(c, (unsigned int*)pc+i))
5893 +                       printk("???????? ");
5894 +               else
5895 +                       printk("%08x ", c);
5896 +       }
5897 +       printk("\n");
5898 +}
5899 +#endif
5900 +
5901  void __kprobes
5902  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
5903  {
5904 @@ -150,9 +168,23 @@ ia64_do_page_fault (unsigned long addres
5905                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
5906                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
5907  
5908 -       if ((vma->vm_flags & mask) != mask)
5909 +       if ((vma->vm_flags & mask) != mask) {
5910 +
5911 +#ifdef CONFIG_PAX_PAGEEXEC
5912 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
5913 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
5914 +                               goto bad_area;
5915 +
5916 +                       up_read(&mm->mmap_sem);
5917 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
5918 +                       do_exit(SIGKILL);
5919 +               }
5920 +#endif
5921 +
5922                 goto bad_area;
5923  
5924 +       }
5925 +
5926    survive:
5927         /*
5928          * If for any reason at all we couldn't handle the fault, make
5929 diff -urNp linux-2.6.18/arch/ia64/mm/init.c linux-2.6.18/arch/ia64/mm/init.c
5930 --- linux-2.6.18/arch/ia64/mm/init.c    2006-09-19 23:42:06.000000000 -0400
5931 +++ linux-2.6.18/arch/ia64/mm/init.c    2006-09-22 20:45:03.000000000 -0400
5932 @@ -19,8 +19,8 @@
5933  #include <linux/swap.h>
5934  #include <linux/proc_fs.h>
5935  #include <linux/bitops.h>
5936 +#include <linux/a.out.h>
5937  
5938 -#include <asm/a.out.h>
5939  #include <asm/dma.h>
5940  #include <asm/ia32.h>
5941  #include <asm/io.h>
5942 diff -urNp linux-2.6.18/arch/mips/kernel/binfmt_elfn32.c linux-2.6.18/arch/mips/kernel/binfmt_elfn32.c
5943 --- linux-2.6.18/arch/mips/kernel/binfmt_elfn32.c       2006-09-19 23:42:06.000000000 -0400
5944 +++ linux-2.6.18/arch/mips/kernel/binfmt_elfn32.c       2006-09-22 20:45:03.000000000 -0400
5945 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
5946  #undef ELF_ET_DYN_BASE
5947  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
5948  
5949 +#ifdef CONFIG_PAX_ASLR
5950 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5951 +
5952 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5953 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5954 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5955 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5956 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5957 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5958 +#endif
5959 +
5960  #include <asm/processor.h>
5961  #include <linux/module.h>
5962  #include <linux/elfcore.h>
5963 diff -urNp linux-2.6.18/arch/mips/kernel/binfmt_elfo32.c linux-2.6.18/arch/mips/kernel/binfmt_elfo32.c
5964 --- linux-2.6.18/arch/mips/kernel/binfmt_elfo32.c       2006-09-19 23:42:06.000000000 -0400
5965 +++ linux-2.6.18/arch/mips/kernel/binfmt_elfo32.c       2006-09-22 20:45:03.000000000 -0400
5966 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
5967  #undef ELF_ET_DYN_BASE
5968  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
5969  
5970 +#ifdef CONFIG_PAX_ASLR
5971 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5972 +
5973 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5974 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5975 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5976 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5977 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5978 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5979 +#endif
5980 +
5981  #include <asm/processor.h>
5982  #include <linux/module.h>
5983  #include <linux/elfcore.h>
5984 diff -urNp linux-2.6.18/arch/mips/kernel/syscall.c linux-2.6.18/arch/mips/kernel/syscall.c
5985 --- linux-2.6.18/arch/mips/kernel/syscall.c     2006-09-19 23:42:06.000000000 -0400
5986 +++ linux-2.6.18/arch/mips/kernel/syscall.c     2006-09-22 20:45:03.000000000 -0400
5987 @@ -88,6 +88,11 @@ unsigned long arch_get_unmapped_area(str
5988         do_color_align = 0;
5989         if (filp || (flags & MAP_SHARED))
5990                 do_color_align = 1;
5991 +
5992 +#ifdef CONFIG_PAX_RANDMMAP
5993 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5994 +#endif
5995 +
5996         if (addr) {
5997                 if (do_color_align)
5998                         addr = COLOUR_ALIGN(addr, pgoff);
5999 @@ -98,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
6000                     (!vmm || addr + len <= vmm->vm_start))
6001                         return addr;
6002         }
6003 -       addr = TASK_UNMAPPED_BASE;
6004 +       addr = current->mm->mmap_base;
6005         if (do_color_align)
6006                 addr = COLOUR_ALIGN(addr, pgoff);
6007         else
6008 diff -urNp linux-2.6.18/arch/mips/mm/fault.c linux-2.6.18/arch/mips/mm/fault.c
6009 --- linux-2.6.18/arch/mips/mm/fault.c   2006-09-19 23:42:06.000000000 -0400
6010 +++ linux-2.6.18/arch/mips/mm/fault.c   2006-09-22 20:45:03.000000000 -0400
6011 @@ -27,6 +27,23 @@
6012  #include <asm/ptrace.h>
6013  #include <asm/highmem.h>               /* For VMALLOC_END */
6014  
6015 +#ifdef CONFIG_PAX_PAGEEXEC
6016 +void pax_report_insns(void *pc)
6017 +{
6018 +       unsigned long i;
6019 +
6020 +       printk(KERN_ERR "PAX: bytes at PC: ");
6021 +       for (i = 0; i < 5; i++) {
6022 +               unsigned int c;
6023 +               if (get_user(c, (unsigned int*)pc+i))
6024 +                       printk("???????? ");
6025 +               else
6026 +                       printk("%08x ", c);
6027 +       }
6028 +       printk("\n");
6029 +}
6030 +#endif
6031 +
6032  /*
6033   * This routine handles page faults.  It determines the address,
6034   * and the problem, and then passes it off to one of the appropriate
6035 diff -urNp linux-2.6.18/arch/parisc/kernel/module.c linux-2.6.18/arch/parisc/kernel/module.c
6036 --- linux-2.6.18/arch/parisc/kernel/module.c    2006-09-19 23:42:06.000000000 -0400
6037 +++ linux-2.6.18/arch/parisc/kernel/module.c    2006-09-22 20:45:03.000000000 -0400
6038 @@ -72,16 +72,38 @@
6039  
6040  /* three functions to determine where in the module core
6041   * or init pieces the location is */
6042 +static inline int is_init_rx(struct module *me, void *loc)
6043 +{
6044 +       return (loc >= me->module_init_rx &&
6045 +               loc < (me->module_init_rx + me->init_size_rx));
6046 +}
6047 +
6048 +static inline int is_init_rw(struct module *me, void *loc)
6049 +{
6050 +       return (loc >= me->module_init_rw &&
6051 +               loc < (me->module_init_rw + me->init_size_rw));
6052 +}
6053 +
6054  static inline int is_init(struct module *me, void *loc)
6055  {
6056 -       return (loc >= me->module_init &&
6057 -               loc <= (me->module_init + me->init_size));
6058 +       return is_init_rx(me, loc) || is_init_rw(me, loc);
6059 +}
6060 +
6061 +static inline int is_core_rx(struct module *me, void *loc)
6062 +{
6063 +       return (loc >= me->module_core_rx &&
6064 +               loc < (me->module_core_rx + me->core_size_rx));
6065 +}
6066 +
6067 +static inline int is_core_rw(struct module *me, void *loc)
6068 +{
6069 +       return (loc >= me->module_core_rw &&
6070 +               loc < (me->module_core_rw + me->core_size_rw));
6071  }
6072  
6073  static inline int is_core(struct module *me, void *loc)
6074  {
6075 -       return (loc >= me->module_core &&
6076 -               loc <= (me->module_core + me->core_size));
6077 +       return is_core_rx(me, loc) || is_core_rw(me, loc);
6078  }
6079  
6080  static inline int is_local(struct module *me, void *loc)
6081 @@ -295,21 +317,21 @@ int module_frob_arch_sections(CONST Elf_
6082         }
6083  
6084         /* align things a bit */
6085 -       me->core_size = ALIGN(me->core_size, 16);
6086 -       me->arch.got_offset = me->core_size;
6087 -       me->core_size += gots * sizeof(struct got_entry);
6088 -
6089 -       me->core_size = ALIGN(me->core_size, 16);
6090 -       me->arch.fdesc_offset = me->core_size;
6091 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
6092 -
6093 -       me->core_size = ALIGN(me->core_size, 16);
6094 -       me->arch.stub_offset = me->core_size;
6095 -       me->core_size += stubs * sizeof(struct stub_entry);
6096 -
6097 -       me->init_size = ALIGN(me->init_size, 16);
6098 -       me->arch.init_stub_offset = me->init_size;
6099 -       me->init_size += init_stubs * sizeof(struct stub_entry);
6100 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
6101 +       me->arch.got_offset = me->core_size_rw;
6102 +       me->core_size_rw += gots * sizeof(struct got_entry);
6103 +
6104 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
6105 +       me->arch.fdesc_offset = me->core_size_rw;
6106 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
6107 +
6108 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
6109 +       me->arch.stub_offset = me->core_size_rx;
6110 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
6111 +
6112 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
6113 +       me->arch.init_stub_offset = me->init_size_rx;
6114 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
6115  
6116         me->arch.got_max = gots;
6117         me->arch.fdesc_max = fdescs;
6118 @@ -329,7 +351,7 @@ static Elf64_Word get_got(struct module 
6119  
6120         BUG_ON(value == 0);
6121  
6122 -       got = me->module_core + me->arch.got_offset;
6123 +       got = me->module_core_rw + me->arch.got_offset;
6124         for (i = 0; got[i].addr; i++)
6125                 if (got[i].addr == value)
6126                         goto out;
6127 @@ -347,7 +369,7 @@ static Elf64_Word get_got(struct module 
6128  #ifdef __LP64__
6129  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
6130  {
6131 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
6132 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
6133  
6134         if (!value) {
6135                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
6136 @@ -365,7 +387,7 @@ static Elf_Addr get_fdesc(struct module 
6137  
6138         /* Create new one */
6139         fdesc->addr = value;
6140 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
6141 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
6142         return (Elf_Addr)fdesc;
6143  }
6144  #endif /* __LP64__ */
6145 @@ -385,12 +407,12 @@ static Elf_Addr get_stub(struct module *
6146         if(init_section) {
6147                 i = me->arch.init_stub_count++;
6148                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
6149 -               stub = me->module_init + me->arch.init_stub_offset + 
6150 +               stub = me->module_init_rx + me->arch.init_stub_offset + 
6151                         i * sizeof(struct stub_entry);
6152         } else {
6153                 i = me->arch.stub_count++;
6154                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
6155 -               stub = me->module_core + me->arch.stub_offset + 
6156 +               stub = me->module_core_rx + me->arch.stub_offset + 
6157                         i * sizeof(struct stub_entry);
6158         }
6159  
6160 @@ -758,7 +780,7 @@ register_unwind_table(struct module *me,
6161  
6162         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
6163         end = table + sechdrs[me->arch.unwind_section].sh_size;
6164 -       gp = (Elf_Addr)me->module_core + me->arch.got_offset;
6165 +       gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
6166  
6167         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
6168                me->arch.unwind_section, table, end, gp);
6169 diff -urNp linux-2.6.18/arch/parisc/kernel/ptrace.c linux-2.6.18/arch/parisc/kernel/ptrace.c
6170 --- linux-2.6.18/arch/parisc/kernel/ptrace.c    2006-09-19 23:42:06.000000000 -0400
6171 +++ linux-2.6.18/arch/parisc/kernel/ptrace.c    2006-09-22 20:04:35.000000000 -0400
6172 @@ -18,6 +18,7 @@
6173  #include <linux/security.h>
6174  #include <linux/compat.h>
6175  #include <linux/signal.h>
6176 +#include <linux/grsecurity.h>
6177  
6178  #include <asm/uaccess.h>
6179  #include <asm/pgtable.h>
6180 diff -urNp linux-2.6.18/arch/parisc/kernel/sys_parisc.c linux-2.6.18/arch/parisc/kernel/sys_parisc.c
6181 --- linux-2.6.18/arch/parisc/kernel/sys_parisc.c        2006-09-19 23:42:06.000000000 -0400
6182 +++ linux-2.6.18/arch/parisc/kernel/sys_parisc.c        2006-09-22 20:45:03.000000000 -0400
6183 @@ -105,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
6184         if (len > TASK_SIZE)
6185                 return -ENOMEM;
6186         if (!addr)
6187 -               addr = TASK_UNMAPPED_BASE;
6188 +               addr = current->mm->mmap_base;
6189  
6190         if (filp) {
6191                 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
6192 diff -urNp linux-2.6.18/arch/parisc/kernel/traps.c linux-2.6.18/arch/parisc/kernel/traps.c
6193 --- linux-2.6.18/arch/parisc/kernel/traps.c     2006-09-19 23:42:06.000000000 -0400
6194 +++ linux-2.6.18/arch/parisc/kernel/traps.c     2006-09-22 20:45:03.000000000 -0400
6195 @@ -706,9 +706,7 @@ void handle_interruption(int code, struc
6196  
6197                         down_read(&current->mm->mmap_sem);
6198                         vma = find_vma(current->mm,regs->iaoq[0]);
6199 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
6200 -                               && (vma->vm_flags & VM_EXEC)) {
6201 -
6202 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
6203                                 fault_address = regs->iaoq[0];
6204                                 fault_space = regs->iasq[0];
6205  
6206 diff -urNp linux-2.6.18/arch/parisc/mm/fault.c linux-2.6.18/arch/parisc/mm/fault.c
6207 --- linux-2.6.18/arch/parisc/mm/fault.c 2006-09-19 23:42:06.000000000 -0400
6208 +++ linux-2.6.18/arch/parisc/mm/fault.c 2006-09-22 20:45:03.000000000 -0400
6209 @@ -16,6 +16,8 @@
6210  #include <linux/sched.h>
6211  #include <linux/interrupt.h>
6212  #include <linux/module.h>
6213 +#include <linux/unistd.h>
6214 +#include <linux/binfmts.h>
6215  
6216  #include <asm/uaccess.h>
6217  #include <asm/traps.h>
6218 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
6219  static unsigned long
6220  parisc_acctyp(unsigned long code, unsigned int inst)
6221  {
6222 -       if (code == 6 || code == 16)
6223 +       if (code == 6 || code == 7 || code == 16)
6224             return VM_EXEC;
6225  
6226         switch (inst & 0xf0000000) {
6227 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
6228                         }
6229  #endif
6230  
6231 +#ifdef CONFIG_PAX_PAGEEXEC
6232 +/*
6233 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
6234 + *
6235 + * returns 1 when task should be killed
6236 + *         2 when rt_sigreturn trampoline was detected
6237 + *         3 when unpatched PLT trampoline was detected
6238 + */
6239 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6240 +{
6241 +
6242 +#ifdef CONFIG_PAX_EMUPLT
6243 +       int err;
6244 +
6245 +       do { /* PaX: unpatched PLT emulation */
6246 +               unsigned int bl, depwi;
6247 +
6248 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
6249 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
6250 +
6251 +               if (err)
6252 +                       break;
6253 +
6254 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
6255 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
6256 +
6257 +                       err = get_user(ldw, (unsigned int*)addr);
6258 +                       err |= get_user(bv, (unsigned int*)(addr+4));
6259 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
6260 +
6261 +                       if (err)
6262 +                               break;
6263 +
6264 +                       if (ldw == 0x0E801096U &&
6265 +                           bv == 0xEAC0C000U &&
6266 +                           ldw2 == 0x0E881095U)
6267 +                       {
6268 +                               unsigned int resolver, map;
6269 +
6270 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
6271 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
6272 +                               if (err)
6273 +                                       break;
6274 +
6275 +                               regs->gr[20] = instruction_pointer(regs)+8;
6276 +                               regs->gr[21] = map;
6277 +                               regs->gr[22] = resolver;
6278 +                               regs->iaoq[0] = resolver | 3UL;
6279 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
6280 +                               return 3;
6281 +                       }
6282 +               }
6283 +       } while (0);
6284 +#endif
6285 +
6286 +#ifdef CONFIG_PAX_EMUTRAMP
6287 +
6288 +#ifndef CONFIG_PAX_EMUSIGRT
6289 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
6290 +               return 1;
6291 +#endif
6292 +
6293 +       do { /* PaX: rt_sigreturn emulation */
6294 +               unsigned int ldi1, ldi2, bel, nop;
6295 +
6296 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
6297 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
6298 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
6299 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
6300 +
6301 +               if (err)
6302 +                       break;
6303 +
6304 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
6305 +                   ldi2 == 0x3414015AU &&
6306 +                   bel == 0xE4008200U &&
6307 +                   nop == 0x08000240U)
6308 +               {
6309 +                       regs->gr[25] = (ldi1 & 2) >> 1;
6310 +                       regs->gr[20] = __NR_rt_sigreturn;
6311 +                       regs->gr[31] = regs->iaoq[1] + 16;
6312 +                       regs->sr[0] = regs->iasq[1];
6313 +                       regs->iaoq[0] = 0x100UL;
6314 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
6315 +                       regs->iasq[0] = regs->sr[2];
6316 +                       regs->iasq[1] = regs->sr[2];
6317 +                       return 2;
6318 +               }
6319 +       } while (0);
6320 +#endif
6321 +
6322 +       return 1;
6323 +}
6324 +
6325 +void pax_report_insns(void *pc, void *sp)
6326 +{
6327 +       unsigned long i;
6328 +
6329 +       printk(KERN_ERR "PAX: bytes at PC: ");
6330 +       for (i = 0; i < 5; i++) {
6331 +               unsigned int c;
6332 +               if (get_user(c, (unsigned int*)pc+i))
6333 +                       printk("???????? ");
6334 +               else
6335 +                       printk("%08x ", c);
6336 +       }
6337 +       printk("\n");
6338 +}
6339 +#endif
6340 +
6341  void do_page_fault(struct pt_regs *regs, unsigned long code,
6342                               unsigned long address)
6343  {
6344 @@ -168,8 +280,33 @@ good_area:
6345  
6346         acc_type = parisc_acctyp(code,regs->iir);
6347  
6348 -       if ((vma->vm_flags & acc_type) != acc_type)
6349 +       if ((vma->vm_flags & acc_type) != acc_type) {
6350 +
6351 +#ifdef CONFIG_PAX_PAGEEXEC
6352 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
6353 +                   (address & ~3UL) == instruction_pointer(regs))
6354 +               {
6355 +                       up_read(&mm->mmap_sem);
6356 +                       switch(pax_handle_fetch_fault(regs)) {
6357 +
6358 +#ifdef CONFIG_PAX_EMUPLT
6359 +                       case 3:
6360 +                               return;
6361 +#endif
6362 +
6363 +#ifdef CONFIG_PAX_EMUTRAMP
6364 +                       case 2:
6365 +                               return;
6366 +#endif
6367 +
6368 +                       }
6369 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
6370 +                       do_exit(SIGKILL);
6371 +               }
6372 +#endif
6373 +
6374                 goto bad_area;
6375 +       }
6376  
6377         /*
6378          * If for any reason at all we couldn't handle the fault, make
6379 diff -urNp linux-2.6.18/arch/powerpc/kernel/module_32.c linux-2.6.18/arch/powerpc/kernel/module_32.c
6380 --- linux-2.6.18/arch/powerpc/kernel/module_32.c        2006-09-19 23:42:06.000000000 -0400
6381 +++ linux-2.6.18/arch/powerpc/kernel/module_32.c        2006-09-22 20:45:03.000000000 -0400
6382 @@ -123,7 +123,7 @@ int module_frob_arch_sections(Elf32_Ehdr
6383                         me->arch.core_plt_section = i;
6384         }
6385         if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
6386 -               printk("Module doesn't contain .plt or .init.plt sections.\n");
6387 +               printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
6388                 return -ENOEXEC;
6389         }
6390  
6391 @@ -164,11 +164,16 @@ static uint32_t do_plt_call(void *locati
6392  
6393         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
6394         /* Init, or core PLT? */
6395 -       if (location >= mod->module_core
6396 -           && location < mod->module_core + mod->core_size)
6397 +       if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
6398 +           (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
6399                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
6400 -       else
6401 +       else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
6402 +                (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
6403                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
6404 +       else {
6405 +               printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
6406 +               return ~0UL;
6407 +       }
6408  
6409         /* Find this entry, or if that fails, the next avail. entry */
6410         while (entry->jump[0]) {
6411 diff -urNp linux-2.6.18/arch/powerpc/kernel/vdso.c linux-2.6.18/arch/powerpc/kernel/vdso.c
6412 --- linux-2.6.18/arch/powerpc/kernel/vdso.c     2006-09-19 23:42:06.000000000 -0400
6413 +++ linux-2.6.18/arch/powerpc/kernel/vdso.c     2006-09-22 20:45:03.000000000 -0400
6414 @@ -254,7 +254,7 @@ int arch_setup_additional_pages(struct l
6415          */
6416         down_write(&mm->mmap_sem);
6417         vdso_base = get_unmapped_area(NULL, vdso_base,
6418 -                                     vdso_pages << PAGE_SHIFT, 0, 0);
6419 +                                     vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
6420         if (IS_ERR_VALUE(vdso_base)) {
6421                 rc = vdso_base;
6422                 goto fail_mmapsem;
6423 diff -urNp linux-2.6.18/arch/powerpc/mm/fault.c linux-2.6.18/arch/powerpc/mm/fault.c
6424 --- linux-2.6.18/arch/powerpc/mm/fault.c        2006-09-19 23:42:06.000000000 -0400
6425 +++ linux-2.6.18/arch/powerpc/mm/fault.c        2006-09-22 20:45:03.000000000 -0400
6426 @@ -28,6 +28,12 @@
6427  #include <linux/highmem.h>
6428  #include <linux/module.h>
6429  #include <linux/kprobes.h>
6430 +#include <linux/binfmts.h>
6431 +#include <linux/slab.h>
6432 +#include <linux/pagemap.h>
6433 +#include <linux/compiler.h>
6434 +#include <linux/binfmts.h>
6435 +#include <linux/unistd.h>
6436  
6437  #include <asm/page.h>
6438  #include <asm/pgtable.h>
6439 @@ -73,6 +79,364 @@ static inline int notify_page_fault(enum
6440  }
6441  #endif
6442  
6443 +#ifdef CONFIG_PAX_EMUSIGRT
6444 +void pax_syscall_close(struct vm_area_struct * vma)
6445 +{
6446 +       vma->vm_mm->call_syscall = 0UL;
6447 +}
6448 +
6449 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6450 +{
6451 +       struct page* page;
6452 +       unsigned int *kaddr;
6453 +
6454 +       page = alloc_page(GFP_HIGHUSER);
6455 +       if (!page)
6456 +               return NOPAGE_OOM;
6457 +
6458 +       kaddr = kmap(page);
6459 +       memset(kaddr, 0, PAGE_SIZE);
6460 +       kaddr[0] = 0x44000002U; /* sc */
6461 +       __flush_dcache_icache(kaddr);
6462 +       kunmap(page);
6463 +       if (type)
6464 +               *type = VM_FAULT_MAJOR;
6465 +       return page;
6466 +}
6467 +
6468 +static struct vm_operations_struct pax_vm_ops = {
6469 +       .close = pax_syscall_close,
6470 +       .nopage = pax_syscall_nopage,
6471 +};
6472 +
6473 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6474 +{
6475 +       int ret;
6476 +
6477 +       memset(vma, 0, sizeof(*vma));
6478 +       vma->vm_mm = current->mm;
6479 +       vma->vm_start = addr;
6480 +       vma->vm_end = addr + PAGE_SIZE;
6481 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6482 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6483 +       vma->vm_ops = &pax_vm_ops;
6484 +
6485 +       ret = insert_vm_struct(current->mm, vma);
6486 +       if (ret)
6487 +               return ret;
6488 +
6489 +       ++current->mm->total_vm;
6490 +       return 0;
6491 +}
6492 +#endif
6493 +
6494 +#ifdef CONFIG_PAX_PAGEEXEC
6495 +/*
6496 + * PaX: decide what to do with offenders (regs->nip = fault address)
6497 + *
6498 + * returns 1 when task should be killed
6499 + *         2 when patched GOT trampoline was detected
6500 + *         3 when patched PLT trampoline was detected
6501 + *         4 when unpatched PLT trampoline was detected
6502 + *         5 when sigreturn trampoline was detected
6503 + *         7 when rt_sigreturn trampoline was detected
6504 + */
6505 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6506 +{
6507 +
6508 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
6509 +       int err;
6510 +#endif
6511 +
6512 +#ifdef CONFIG_PAX_EMUPLT
6513 +       do { /* PaX: patched GOT emulation */
6514 +               unsigned int blrl;
6515 +
6516 +               err = get_user(blrl, (unsigned int*)regs->nip);
6517 +
6518 +               if (!err && blrl == 0x4E800021U) {
6519 +                       unsigned long temp = regs->nip;
6520 +
6521 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
6522 +                       regs->link = temp + 4UL;
6523 +                       return 2;
6524 +               }
6525 +       } while (0);
6526 +
6527 +       do { /* PaX: patched PLT emulation #1 */
6528 +               unsigned int b;
6529 +
6530 +               err = get_user(b, (unsigned int *)regs->nip);
6531 +
6532 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
6533 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
6534 +                       return 3;
6535 +               }
6536 +       } while (0);
6537 +
6538 +       do { /* PaX: unpatched PLT emulation #1 */
6539 +               unsigned int li, b;
6540 +
6541 +               err = get_user(li, (unsigned int *)regs->nip);
6542 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
6543 +
6544 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6545 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6546 +                       unsigned long addr = b | 0xFC000000UL;
6547 +
6548 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6549 +                       err = get_user(rlwinm, (unsigned int*)addr);
6550 +                       err |= get_user(add, (unsigned int*)(addr+4));
6551 +                       err |= get_user(li2, (unsigned int*)(addr+8));
6552 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
6553 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
6554 +                       err |= get_user(li3, (unsigned int*)(addr+20));
6555 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
6556 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
6557 +
6558 +                       if (err)
6559 +                               break;
6560 +
6561 +                       if (rlwinm == 0x556C083CU &&
6562 +                           add == 0x7D6C5A14U &&
6563 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
6564 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6565 +                           mtctr == 0x7D8903A6U &&
6566 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
6567 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6568 +                           bctr == 0x4E800420U)
6569 +                       {
6570 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6571 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6572 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6573 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6574 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
6575 +                               regs->nip = regs->ctr;
6576 +                               return 4;
6577 +                       }
6578 +               }
6579 +       } while (0);
6580 +
6581 +#if 0
6582 +       do { /* PaX: unpatched PLT emulation #2 */
6583 +               unsigned int lis, lwzu, b, bctr;
6584 +
6585 +               err = get_user(lis, (unsigned int *)regs->nip);
6586 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
6587 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
6588 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
6589 +
6590 +               if (err)
6591 +                       break;
6592 +
6593 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
6594 +                   (lwzu & 0xU) == 0xU &&
6595 +                   (b & 0xFC000003U) == 0x48000000U &&
6596 +                   bctr == 0x4E800420U)
6597 +               {
6598 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6599 +                       unsigned long addr = b | 0xFC000000UL;
6600 +
6601 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6602 +                       err = get_user(addis, (unsigned int*)addr);
6603 +                       err |= get_user(addi, (unsigned int*)(addr+4));
6604 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
6605 +                       err |= get_user(add, (unsigned int*)(addr+12));
6606 +                       err |= get_user(li2, (unsigned int*)(addr+16));
6607 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
6608 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
6609 +                       err |= get_user(li3, (unsigned int*)(addr+28));
6610 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
6611 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
6612 +
6613 +                       if (err)
6614 +                               break;
6615 +
6616 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6617 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
6618 +                           rlwinm == 0x556C083CU &&
6619 +                           add == 0x7D6C5A14U &&
6620 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
6621 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6622 +                           mtctr == 0x7D8903A6U &&
6623 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
6624 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6625 +                           bctr == 0x4E800420U)
6626 +                       {
6627 +                               regs->gpr[PT_R11] = 
6628 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6629 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6630 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6631 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6632 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
6633 +                               regs->nip = regs->ctr;
6634 +                               return 4;
6635 +                       }
6636 +               }
6637 +       } while (0);
6638 +#endif
6639 +
6640 +       do { /* PaX: unpatched PLT emulation #3 */
6641 +               unsigned int li, b;
6642 +
6643 +               err = get_user(li, (unsigned int *)regs->nip);
6644 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
6645 +
6646 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6647 +                       unsigned int addis, lwz, mtctr, bctr;
6648 +                       unsigned long addr = b | 0xFC000000UL;
6649 +
6650 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6651 +                       err = get_user(addis, (unsigned int*)addr);
6652 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
6653 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
6654 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
6655 +
6656 +                       if (err)
6657 +                               break;
6658 +
6659 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6660 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
6661 +                           mtctr == 0x7D6903A6U &&
6662 +                           bctr == 0x4E800420U)
6663 +                       {
6664 +                               unsigned int r11;
6665 +
6666 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6667 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6668 +
6669 +                               err = get_user(r11, (unsigned int*)addr);
6670 +                               if (err)
6671 +                                       break;
6672 +
6673 +                               regs->gpr[PT_R11] = r11;
6674 +                               regs->ctr = r11;
6675 +                               regs->nip = r11;
6676 +                               return 4;
6677 +                       }
6678 +               }
6679 +       } while (0);
6680 +#endif
6681 +
6682 +#ifdef CONFIG_PAX_EMUSIGRT
6683 +       do { /* PaX: sigreturn emulation */
6684 +               unsigned int li, sc;
6685 +
6686 +               err = get_user(li, (unsigned int *)regs->nip);
6687 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
6688 +
6689 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
6690 +                       struct vm_area_struct *vma;
6691 +                       unsigned long call_syscall;
6692 +
6693 +                       down_read(&current->mm->mmap_sem);
6694 +                       call_syscall = current->mm->call_syscall;
6695 +                       up_read(&current->mm->mmap_sem);
6696 +                       if (likely(call_syscall))
6697 +                               goto emulate;
6698 +
6699 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6700 +
6701 +                       down_write(&current->mm->mmap_sem);
6702 +                       if (current->mm->call_syscall) {
6703 +                               call_syscall = current->mm->call_syscall;
6704 +                               up_write(&current->mm->mmap_sem);
6705 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6706 +                               goto emulate;
6707 +                       }
6708 +
6709 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6710 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
6711 +                               up_write(&current->mm->mmap_sem);
6712 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6713 +                               return 1;
6714 +                       }
6715 +
6716 +                       if (pax_insert_vma(vma, call_syscall)) {
6717 +                               up_write(&current->mm->mmap_sem);
6718 +                               kmem_cache_free(vm_area_cachep, vma);
6719 +                               return 1;
6720 +                       }
6721 +
6722 +                       current->mm->call_syscall = call_syscall;
6723 +                       up_write(&current->mm->mmap_sem);
6724 +
6725 +emulate:
6726 +                       regs->gpr[PT_R0] = __NR_sigreturn;
6727 +                       regs->nip = call_syscall;
6728 +                       return 5;
6729 +               }
6730 +       } while (0);
6731 +
6732 +       do { /* PaX: rt_sigreturn emulation */
6733 +               unsigned int li, sc;
6734 +
6735 +               err = get_user(li, (unsigned int *)regs->nip);
6736 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
6737 +
6738 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
6739 +                       struct vm_area_struct *vma;
6740 +                       unsigned int call_syscall;
6741 +
6742 +                       down_read(&current->mm->mmap_sem);
6743 +                       call_syscall = current->mm->call_syscall;
6744 +                       up_read(&current->mm->mmap_sem);
6745 +                       if (likely(call_syscall))
6746 +                               goto rt_emulate;
6747 +
6748 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6749 +
6750 +                       down_write(&current->mm->mmap_sem);
6751 +                       if (current->mm->call_syscall) {
6752 +                               call_syscall = current->mm->call_syscall;
6753 +                               up_write(&current->mm->mmap_sem);
6754 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6755 +                               goto rt_emulate;
6756 +                       }
6757 +
6758 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6759 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
6760 +                               up_write(&current->mm->mmap_sem);
6761 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6762 +                               return 1;
6763 +                       }
6764 +
6765 +                       if (pax_insert_vma(vma, call_syscall)) {
6766 +                               up_write(&current->mm->mmap_sem);
6767 +                               kmem_cache_free(vm_area_cachep, vma);
6768 +                               return 1;
6769 +                       }
6770 +
6771 +                       current->mm->call_syscall = call_syscall;
6772 +                       up_write(&current->mm->mmap_sem);
6773 +
6774 +rt_emulate:
6775 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
6776 +                       regs->nip = call_syscall;
6777 +                       return 6;
6778 +               }
6779 +       } while (0);
6780 +#endif
6781 +
6782 +       return 1;
6783 +}
6784 +
6785 +void pax_report_insns(void *pc, void *sp)
6786 +{
6787 +       unsigned long i;
6788 +
6789 +       printk(KERN_ERR "PAX: bytes at PC: ");
6790 +       for (i = 0; i < 5; i++) {
6791 +               unsigned int c;
6792 +               if (get_user(c, (unsigned int*)pc+i))
6793 +                       printk("???????? ");
6794 +               else
6795 +                       printk("%08x ", c);
6796 +       }
6797 +       printk("\n");
6798 +}
6799 +#endif
6800 +
6801  /*
6802   * Check whether the instruction at regs->nip is a store using
6803   * an update addressing form which will update r1.
6804 @@ -168,7 +532,7 @@ int __kprobes do_page_fault(struct pt_re
6805          * indicate errors in DSISR but can validly be set in SRR1.
6806          */
6807         if (trap == 0x400)
6808 -               error_code &= 0x48200000;
6809 +               error_code &= 0x58200000;
6810         else
6811                 is_write = error_code & DSISR_ISSTORE;
6812  #else
6813 @@ -295,9 +659,9 @@ good_area:
6814                 /* protection fault */
6815                 if (error_code & DSISR_PROTFAULT)
6816                         goto bad_area;
6817 +#endif
6818                 if (!(vma->vm_flags & VM_EXEC))
6819                         goto bad_area;
6820 -#endif
6821  #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
6822                 pte_t *ptep;
6823                 pmd_t *pmdp;
6824 @@ -368,6 +732,37 @@ bad_area:
6825  bad_area_nosemaphore:
6826         /* User mode accesses cause a SIGSEGV */
6827         if (user_mode(regs)) {
6828 +
6829 +#ifdef CONFIG_PAX_PAGEEXEC
6830 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
6831 +#ifdef CONFIG_PPC64
6832 +                       if (is_exec && (error_code & DSISR_PROTFAULT)) {
6833 +#else
6834 +                       if (is_exec && regs->nip == address) {
6835 +#endif
6836 +                               switch (pax_handle_fetch_fault(regs)) {
6837 +
6838 +#ifdef CONFIG_PAX_EMUPLT
6839 +                               case 2:
6840 +                               case 3:
6841 +                               case 4:
6842 +                                       return 0;
6843 +#endif
6844 +
6845 +#ifdef CONFIG_PAX_EMUSIGRT
6846 +                               case 5:
6847 +                               case 6:
6848 +                                       return 0;
6849 +#endif
6850 +
6851 +                               }
6852 +
6853 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
6854 +                               do_exit(SIGKILL);
6855 +                       }
6856 +               }
6857 +#endif
6858 +
6859                 _exception(SIGSEGV, regs, code, address);
6860                 return 0;
6861         }
6862 diff -urNp linux-2.6.18/arch/powerpc/mm/hugetlbpage.c linux-2.6.18/arch/powerpc/mm/hugetlbpage.c
6863 --- linux-2.6.18/arch/powerpc/mm/hugetlbpage.c  2006-09-19 23:42:06.000000000 -0400
6864 +++ linux-2.6.18/arch/powerpc/mm/hugetlbpage.c  2006-09-22 20:45:03.000000000 -0400
6865 @@ -562,6 +562,10 @@ unsigned long arch_get_unmapped_area(str
6866         if (len > TASK_SIZE)
6867                 return -ENOMEM;
6868  
6869 +#ifdef CONFIG_PAX_RANDMMAP
6870 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6871 +#endif
6872 +
6873         if (addr) {
6874                 addr = PAGE_ALIGN(addr);
6875                 vma = find_vma(mm, addr);
6876 @@ -573,7 +577,7 @@ unsigned long arch_get_unmapped_area(str
6877         if (len > mm->cached_hole_size) {
6878                 start_addr = addr = mm->free_area_cache;
6879         } else {
6880 -               start_addr = addr = TASK_UNMAPPED_BASE;
6881 +               start_addr = addr = mm->mmap_base;
6882                 mm->cached_hole_size = 0;
6883         }
6884  
6885 @@ -606,8 +610,8 @@ full_search:
6886         }
6887  
6888         /* Make sure we didn't miss any holes */
6889 -       if (start_addr != TASK_UNMAPPED_BASE) {
6890 -               start_addr = addr = TASK_UNMAPPED_BASE;
6891 +       if (start_addr != mm->mmap_base) {
6892 +               start_addr = addr = mm->mmap_base;
6893                 mm->cached_hole_size = 0;
6894                 goto full_search;
6895         }
6896 @@ -642,6 +646,11 @@ arch_get_unmapped_area_topdown(struct fi
6897                 mm->free_area_cache = base;
6898  
6899         /* requesting a specific address */
6900 +
6901 +#ifdef CONFIG_PAX_RANDMMAP
6902 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6903 +#endif
6904 +
6905         if (addr) {
6906                 addr = PAGE_ALIGN(addr);
6907                 vma = find_vma(mm, addr);
6908 @@ -721,12 +730,20 @@ fail:
6909          * can happen with large stack limits and large mmap()
6910          * allocations.
6911          */
6912 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
6913 +       mm->mmap_base = TASK_UNMAPPED_BASE;
6914 +
6915 +#ifdef CONFIG_PAX_RANDMMAP
6916 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
6917 +               mm->mmap_base += mm->delta_mmap;
6918 +#endif
6919 +
6920 +       mm->free_area_cache = mm->mmap_base;
6921         mm->cached_hole_size = ~0UL;
6922         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6923         /*
6924          * Restore the topdown base:
6925          */
6926 +       mm->mmap_base = base;
6927         mm->free_area_cache = base;
6928         mm->cached_hole_size = ~0UL;
6929  
6930 diff -urNp linux-2.6.18/arch/powerpc/mm/mmap.c linux-2.6.18/arch/powerpc/mm/mmap.c
6931 --- linux-2.6.18/arch/powerpc/mm/mmap.c 2006-09-19 23:42:06.000000000 -0400
6932 +++ linux-2.6.18/arch/powerpc/mm/mmap.c 2006-09-22 20:45:03.000000000 -0400
6933 @@ -74,10 +74,22 @@ void arch_pick_mmap_layout(struct mm_str
6934          */
6935         if (mmap_is_legacy()) {
6936                 mm->mmap_base = TASK_UNMAPPED_BASE;
6937 +
6938 +#ifdef CONFIG_PAX_RANDMMAP
6939 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6940 +                       mm->mmap_base += mm->delta_mmap;
6941 +#endif
6942 +
6943                 mm->get_unmapped_area = arch_get_unmapped_area;
6944                 mm->unmap_area = arch_unmap_area;
6945         } else {
6946                 mm->mmap_base = mmap_base();
6947 +
6948 +#ifdef CONFIG_PAX_RANDMMAP
6949 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6950 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
6951 +#endif
6952 +
6953                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
6954                 mm->unmap_area = arch_unmap_area_topdown;
6955         }
6956 diff -urNp linux-2.6.18/arch/ppc/mm/fault.c linux-2.6.18/arch/ppc/mm/fault.c
6957 --- linux-2.6.18/arch/ppc/mm/fault.c    2006-09-19 23:42:06.000000000 -0400
6958 +++ linux-2.6.18/arch/ppc/mm/fault.c    2006-09-22 20:45:03.000000000 -0400
6959 @@ -25,6 +25,11 @@
6960  #include <linux/interrupt.h>
6961  #include <linux/highmem.h>
6962  #include <linux/module.h>
6963 +#include <linux/slab.h>
6964 +#include <linux/pagemap.h>
6965 +#include <linux/compiler.h>
6966 +#include <linux/binfmts.h>
6967 +#include <linux/unistd.h>
6968  
6969  #include <asm/page.h>
6970  #include <asm/pgtable.h>
6971 @@ -48,6 +53,379 @@ unsigned long pte_misses;   /* updated by 
6972  unsigned long pte_errors;      /* updated by do_page_fault() */
6973  unsigned int probingmem;
6974  
6975 +#ifdef CONFIG_PAX_EMUSIGRT
6976 +void pax_syscall_close(struct vm_area_struct * vma)
6977 +{
6978 +       vma->vm_mm->call_syscall = 0UL;
6979 +}
6980 +
6981 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6982 +{
6983 +       struct page* page;
6984 +       unsigned int *kaddr;
6985 +
6986 +       page = alloc_page(GFP_HIGHUSER);
6987 +       if (!page)
6988 +               return NOPAGE_OOM;
6989 +
6990 +       kaddr = kmap(page);
6991 +       memset(kaddr, 0, PAGE_SIZE);
6992 +       kaddr[0] = 0x44000002U; /* sc */
6993 +       __flush_dcache_icache(kaddr);
6994 +       kunmap(page);
6995 +       if (type)
6996 +               *type = VM_FAULT_MAJOR;
6997 +       return page;
6998 +}
6999 +
7000 +static struct vm_operations_struct pax_vm_ops = {
7001 +       .close = pax_syscall_close,
7002 +       .nopage = pax_syscall_nopage,
7003 +};
7004 +
7005 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7006 +{
7007 +       int ret;
7008 +
7009 +       memset(vma, 0, sizeof(*vma));
7010 +       vma->vm_mm = current->mm;
7011 +       vma->vm_start = addr;
7012 +       vma->vm_end = addr + PAGE_SIZE;
7013 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7014 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
7015 +       vma->vm_ops = &pax_vm_ops;
7016 +
7017 +       ret = insert_vm_struct(current->mm, vma);
7018 +       if (ret)
7019 +               return ret;
7020 +
7021 +       ++current->mm->total_vm;
7022 +       return 0;
7023 +}
7024 +#endif
7025 +
7026 +#ifdef CONFIG_PAX_PAGEEXEC
7027 +/*
7028 + * PaX: decide what to do with offenders (regs->nip = fault address)
7029 + *
7030 + * returns 1 when task should be killed
7031 + *         2 when patched GOT trampoline was detected
7032 + *         3 when patched PLT trampoline was detected
7033 + *         4 when unpatched PLT trampoline was detected
7034 + *         5 when sigreturn trampoline was detected
7035 + *         7 when rt_sigreturn trampoline was detected
7036 + */
7037 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7038 +{
7039 +
7040 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
7041 +       int err;
7042 +#endif
7043 +
7044 +#ifdef CONFIG_PAX_EMUPLT
7045 +       do { /* PaX: patched GOT emulation */
7046 +               unsigned int blrl;
7047 +
7048 +               err = get_user(blrl, (unsigned int*)regs->nip);
7049 +
7050 +               if (!err && blrl == 0x4E800021U) {
7051 +                       unsigned long temp = regs->nip;
7052 +
7053 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
7054 +                       regs->link = temp + 4UL;
7055 +                       return 2;
7056 +               }
7057 +       } while (0);
7058 +
7059 +       do { /* PaX: patched PLT emulation #1 */
7060 +               unsigned int b;
7061 +
7062 +               err = get_user(b, (unsigned int *)regs->nip);
7063 +
7064 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
7065 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
7066 +                       return 3;
7067 +               }
7068 +       } while (0);
7069 +
7070 +       do { /* PaX: unpatched PLT emulation #1 */
7071 +               unsigned int li, b;
7072 +
7073 +               err = get_user(li, (unsigned int *)regs->nip);
7074 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
7075 +
7076 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7077 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7078 +                       unsigned long addr = b | 0xFC000000UL;
7079 +
7080 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7081 +                       err = get_user(rlwinm, (unsigned int*)addr);
7082 +                       err |= get_user(add, (unsigned int*)(addr+4));
7083 +                       err |= get_user(li2, (unsigned int*)(addr+8));
7084 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
7085 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
7086 +                       err |= get_user(li3, (unsigned int*)(addr+20));
7087 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
7088 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
7089 +
7090 +                       if (err)
7091 +                               break;
7092 +
7093 +                       if (rlwinm == 0x556C083CU &&
7094 +                           add == 0x7D6C5A14U &&
7095 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
7096 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7097 +                           mtctr == 0x7D8903A6U &&
7098 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
7099 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7100 +                           bctr == 0x4E800420U)
7101 +                       {
7102 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7103 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7104 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7105 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7106 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
7107 +                               regs->nip = regs->ctr;
7108 +                               return 4;
7109 +                       }
7110 +               }
7111 +       } while (0);
7112 +
7113 +#if 0
7114 +       do { /* PaX: unpatched PLT emulation #2 */
7115 +               unsigned int lis, lwzu, b, bctr;
7116 +
7117 +               err = get_user(lis, (unsigned int *)regs->nip);
7118 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
7119 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
7120 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
7121 +
7122 +               if (err)
7123 +                       break;
7124 +
7125 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
7126 +                   (lwzu & 0xU) == 0xU &&
7127 +                   (b & 0xFC000003U) == 0x48000000U &&
7128 +                   bctr == 0x4E800420U)
7129 +               {
7130 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7131 +                       unsigned long addr = b | 0xFC000000UL;
7132 +
7133 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7134 +                       err = get_user(addis, (unsigned int*)addr);
7135 +                       err |= get_user(addi, (unsigned int*)(addr+4));
7136 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
7137 +                       err |= get_user(add, (unsigned int*)(addr+12));
7138 +                       err |= get_user(li2, (unsigned int*)(addr+16));
7139 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
7140 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
7141 +                       err |= get_user(li3, (unsigned int*)(addr+28));
7142 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
7143 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
7144 +
7145 +                       if (err)
7146 +                               break;
7147 +
7148 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7149 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
7150 +                           rlwinm == 0x556C083CU &&
7151 +                           add == 0x7D6C5A14U &&
7152 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
7153 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7154 +                           mtctr == 0x7D8903A6U &&
7155 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
7156 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7157 +                           bctr == 0x4E800420U)
7158 +                       {
7159 +                               regs->gpr[PT_R11] = 
7160 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7161 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7162 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7163 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7164 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
7165 +                               regs->nip = regs->ctr;
7166 +                               return 4;
7167 +                       }
7168 +               }
7169 +       } while (0);
7170 +#endif
7171 +
7172 +       do { /* PaX: unpatched PLT emulation #3 */
7173 +               unsigned int li, b;
7174 +
7175 +               err = get_user(li, (unsigned int *)regs->nip);
7176 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
7177 +
7178 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7179 +                       unsigned int addis, lwz, mtctr, bctr;
7180 +                       unsigned long addr = b | 0xFC000000UL;
7181 +
7182 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7183 +                       err = get_user(addis, (unsigned int*)addr);
7184 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
7185 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
7186 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
7187 +
7188 +                       if (err)
7189 +                               break;
7190 +
7191 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7192 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
7193 +                           mtctr == 0x7D6903A6U &&
7194 +                           bctr == 0x4E800420U)
7195 +                       {
7196 +                               unsigned int r11;
7197 +
7198 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7199 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7200 +
7201 +                               err = get_user(r11, (unsigned int*)addr);
7202 +                               if (err)
7203 +                                       break;
7204 +
7205 +                               regs->gpr[PT_R11] = r11;
7206 +                               regs->ctr = r11;
7207 +                               regs->nip = r11;
7208 +                               return 4;
7209 +                       }
7210 +               }
7211 +       } while (0);
7212 +#endif
7213 +
7214 +#ifdef CONFIG_PAX_EMUSIGRT
7215 +       do { /* PaX: sigreturn emulation */
7216 +               unsigned int li, sc;
7217 +
7218 +               err = get_user(li, (unsigned int *)regs->nip);
7219 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
7220 +
7221 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
7222 +                       struct vm_area_struct *vma;
7223 +                       unsigned long call_syscall;
7224 +
7225 +                       down_read(&current->mm->mmap_sem);
7226 +                       call_syscall = current->mm->call_syscall;
7227 +                       up_read(&current->mm->mmap_sem);
7228 +                       if (likely(call_syscall))
7229 +                               goto emulate;
7230 +
7231 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7232 +
7233 +                       down_write(&current->mm->mmap_sem);
7234 +                       if (current->mm->call_syscall) {
7235 +                               call_syscall = current->mm->call_syscall;
7236 +                               up_write(&current->mm->mmap_sem);
7237 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
7238 +                               goto emulate;
7239 +                       }
7240 +
7241 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7242 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
7243 +                               up_write(&current->mm->mmap_sem);
7244 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
7245 +                               return 1;
7246 +                       }
7247 +
7248 +                       if (pax_insert_vma(vma, call_syscall)) {
7249 +                               up_write(&current->mm->mmap_sem);
7250 +                               kmem_cache_free(vm_area_cachep, vma);
7251 +                               return 1;
7252 +                       }
7253 +
7254 +                       current->mm->call_syscall = call_syscall;
7255 +                       up_write(&current->mm->mmap_sem);
7256 +
7257 +emulate:
7258 +                       regs->gpr[PT_R0] = __NR_sigreturn;
7259 +                       regs->nip = call_syscall;
7260 +                       return 5;
7261 +               }
7262 +       } while (0);
7263 +
7264 +       do { /* PaX: rt_sigreturn emulation */
7265 +               unsigned int li, sc;
7266 +
7267 +               err = get_user(li, (unsigned int *)regs->nip);
7268 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
7269 +
7270 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
7271 +                       struct vm_area_struct *vma;
7272 +                       unsigned int call_syscall;
7273 +
7274 +                       down_read(&current->mm->mmap_sem);
7275 +                       call_syscall = current->mm->call_syscall;
7276 +                       up_read(&current->mm->mmap_sem);
7277 +                       if (likely(call_syscall))
7278 +                               goto rt_emulate;
7279 +
7280 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7281 +
7282 +                       down_write(&current->mm->mmap_sem);
7283 +                       if (current->mm->call_syscall) {
7284 +                               call_syscall = current->mm->call_syscall;
7285 +                               up_write(&current->mm->mmap_sem);
7286 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
7287 +                               goto rt_emulate;
7288 +                       }
7289 +
7290 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7291 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
7292 +                               up_write(&current->mm->mmap_sem);
7293 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
7294 +                               return 1;
7295 +                       }
7296 +
7297 +                       if (pax_insert_vma(vma, call_syscall)) {
7298 +                               up_write(&current->mm->mmap_sem);
7299 +                               kmem_cache_free(vm_area_cachep, vma);
7300 +                               return 1;
7301 +                       }
7302 +
7303 +                       current->mm->call_syscall = call_syscall;
7304 +                       up_write(&current->mm->mmap_sem);
7305 +
7306 +rt_emulate:
7307 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
7308 +                       regs->nip = call_syscall;
7309 +                       return 6;
7310 +               }
7311 +       } while (0);
7312 +#endif
7313 +
7314 +       return 1;
7315 +}
7316 +
7317 +/*
7318 + * PaX: decide what to do with offenders (regs->nip = fault address)
7319 + *
7320 + * returns 1 when task should be killed
7321 + */
7322 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7323 +{
7324 +
7325 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
7326 +       int err;
7327 +#endif
7328 +
7329 +       return 1;
7330 +}
7331 +
7332 +void pax_report_insns(void *pc, void *sp)
7333 +{
7334 +       unsigned long i;
7335 +
7336 +       printk(KERN_ERR "PAX: bytes at PC: ");
7337 +       for (i = 0; i < 5; i++) {
7338 +               unsigned int c;
7339 +               if (get_user(c, (unsigned int*)pc+i))
7340 +                       printk("???????? ");
7341 +               else
7342 +                       printk("%08x ", c);
7343 +       }
7344 +       printk("\n");
7345 +}
7346 +#endif
7347 +
7348  /*
7349   * Check whether the instruction at regs->nip is a store using
7350   * an update addressing form which will update r1.
7351 @@ -108,7 +486,7 @@ int do_page_fault(struct pt_regs *regs, 
7352          * indicate errors in DSISR but can validly be set in SRR1.
7353          */
7354         if (TRAP(regs) == 0x400)
7355 -               error_code &= 0x48200000;
7356 +               error_code &= 0x58200000;
7357         else
7358                 is_write = error_code & 0x02000000;
7359  #endif /* CONFIG_4xx || CONFIG_BOOKE */
7360 @@ -203,15 +581,14 @@ good_area:
7361                 pte_t *ptep;
7362                 pmd_t *pmdp;
7363  
7364 -#if 0
7365 +#if 1
7366                 /* It would be nice to actually enforce the VM execute
7367                    permission on CPUs which can do so, but far too
7368                    much stuff in userspace doesn't get the permissions
7369                    right, so we let any page be executed for now. */
7370                 if (! (vma->vm_flags & VM_EXEC))
7371                         goto bad_area;
7372 -#endif
7373 -
7374 +#else
7375                 /* Since 4xx/Book-E supports per-page execute permission,
7376                  * we lazily flush dcache to icache. */
7377                 ptep = NULL;
7378 @@ -234,6 +611,7 @@ good_area:
7379                         pte_unmap_unlock(ptep, ptl);
7380                 }
7381  #endif
7382 +#endif
7383         /* a read */
7384         } else {
7385                 /* protection fault */
7386 @@ -279,6 +657,33 @@ bad_area:
7387  
7388         /* User mode accesses cause a SIGSEGV */
7389         if (user_mode(regs)) {
7390 +
7391 +#ifdef CONFIG_PAX_PAGEEXEC
7392 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
7393 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
7394 +                               switch (pax_handle_fetch_fault(regs)) {
7395 +
7396 +#ifdef CONFIG_PAX_EMUPLT
7397 +                               case 2:
7398 +                               case 3:
7399 +                               case 4:
7400 +                                       return 0;
7401 +#endif
7402 +
7403 +#ifdef CONFIG_PAX_EMUSIGRT
7404 +                               case 5:
7405 +                               case 6:
7406 +                                       return 0;
7407 +#endif
7408 +
7409 +                               }
7410 +
7411 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
7412 +                               do_exit(SIGKILL);
7413 +                       }
7414 +               }
7415 +#endif
7416 +
7417                 _exception(SIGSEGV, regs, code, address);
7418                 return 0;
7419         }
7420 diff -urNp linux-2.6.18/arch/s390/kernel/module.c linux-2.6.18/arch/s390/kernel/module.c
7421 --- linux-2.6.18/arch/s390/kernel/module.c      2006-09-19 23:42:06.000000000 -0400
7422 +++ linux-2.6.18/arch/s390/kernel/module.c      2006-09-22 20:45:03.000000000 -0400
7423 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
7424  
7425         /* Increase core size by size of got & plt and set start
7426            offsets for got and plt. */
7427 -       me->core_size = ALIGN(me->core_size, 4);
7428 -       me->arch.got_offset = me->core_size;
7429 -       me->core_size += me->arch.got_size;
7430 -       me->arch.plt_offset = me->core_size;
7431 -       me->core_size += me->arch.plt_size;
7432 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
7433 +       me->arch.got_offset = me->core_size_rw;
7434 +       me->core_size_rw += me->arch.got_size;
7435 +       me->arch.plt_offset = me->core_size_rx;
7436 +       me->core_size_rx += me->arch.plt_size;
7437         return 0;
7438  }
7439  
7440 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7441                 if (info->got_initialized == 0) {
7442                         Elf_Addr *gotent;
7443  
7444 -                       gotent = me->module_core + me->arch.got_offset +
7445 +                       gotent = me->module_core_rw + me->arch.got_offset +
7446                                 info->got_offset;
7447                         *gotent = val;
7448                         info->got_initialized = 1;
7449 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7450                 else if (r_type == R_390_GOTENT ||
7451                          r_type == R_390_GOTPLTENT)
7452                         *(unsigned int *) loc =
7453 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
7454 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
7455                 else if (r_type == R_390_GOT64 ||
7456                          r_type == R_390_GOTPLT64)
7457                         *(unsigned long *) loc = val;
7458 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7459         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
7460                 if (info->plt_initialized == 0) {
7461                         unsigned int *ip;
7462 -                       ip = me->module_core + me->arch.plt_offset +
7463 +                       ip = me->module_core_rx + me->arch.plt_offset +
7464                                 info->plt_offset;
7465  #ifndef CONFIG_64BIT
7466                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
7467 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7468                         val = me->arch.plt_offset - me->arch.got_offset +
7469                                 info->plt_offset + rela->r_addend;
7470                 else
7471 -                       val =  (Elf_Addr) me->module_core +
7472 +                       val =  (Elf_Addr) me->module_core_rx +
7473                                 me->arch.plt_offset + info->plt_offset + 
7474                                 rela->r_addend - loc;
7475                 if (r_type == R_390_PLT16DBL)
7476 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7477         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
7478         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
7479                 val = val + rela->r_addend -
7480 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
7481 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
7482                 if (r_type == R_390_GOTOFF16)
7483                         *(unsigned short *) loc = val;
7484                 else if (r_type == R_390_GOTOFF32)
7485 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7486                 break;
7487         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
7488         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
7489 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
7490 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
7491                         rela->r_addend - loc;
7492                 if (r_type == R_390_GOTPC)
7493                         *(unsigned int *) loc = val;
7494 diff -urNp linux-2.6.18/arch/sparc/kernel/ptrace.c linux-2.6.18/arch/sparc/kernel/ptrace.c
7495 --- linux-2.6.18/arch/sparc/kernel/ptrace.c     2006-09-19 23:42:06.000000000 -0400
7496 +++ linux-2.6.18/arch/sparc/kernel/ptrace.c     2006-09-22 20:04:35.000000000 -0400
7497 @@ -19,6 +19,7 @@
7498  #include <linux/smp_lock.h>
7499  #include <linux/security.h>
7500  #include <linux/signal.h>
7501 +#include <linux/grsecurity.h>
7502  
7503  #include <asm/pgtable.h>
7504  #include <asm/system.h>
7505 @@ -300,6 +301,11 @@ asmlinkage void do_ptrace(struct pt_regs
7506                 goto out;
7507         }
7508  
7509 +       if (gr_handle_ptrace(child, request)) {
7510 +               pt_error_return(regs, EPERM);
7511 +               goto out_tsk;
7512 +       }
7513 +
7514         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
7515             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
7516                 if (ptrace_attach(child)) {
7517 diff -urNp linux-2.6.18/arch/sparc/kernel/sys_sparc.c linux-2.6.18/arch/sparc/kernel/sys_sparc.c
7518 --- linux-2.6.18/arch/sparc/kernel/sys_sparc.c  2006-09-19 23:42:06.000000000 -0400
7519 +++ linux-2.6.18/arch/sparc/kernel/sys_sparc.c  2006-09-22 20:45:03.000000000 -0400
7520 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
7521         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
7522                 return -ENOMEM;
7523         if (!addr)
7524 -               addr = TASK_UNMAPPED_BASE;
7525 +               addr = current->mm->mmap_base;
7526  
7527         if (flags & MAP_SHARED)
7528                 addr = COLOUR_ALIGN(addr);
7529 diff -urNp linux-2.6.18/arch/sparc/Makefile linux-2.6.18/arch/sparc/Makefile
7530 --- linux-2.6.18/arch/sparc/Makefile    2006-09-19 23:42:06.000000000 -0400
7531 +++ linux-2.6.18/arch/sparc/Makefile    2006-09-22 20:04:35.000000000 -0400
7532 @@ -34,7 +34,7 @@ libs-y += arch/sparc/prom/ arch/sparc/li
7533  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
7534  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
7535  CORE_Y         := $(core-y)
7536 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
7537 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
7538  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
7539  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
7540  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
7541 diff -urNp linux-2.6.18/arch/sparc/mm/fault.c linux-2.6.18/arch/sparc/mm/fault.c
7542 --- linux-2.6.18/arch/sparc/mm/fault.c  2006-09-19 23:42:06.000000000 -0400
7543 +++ linux-2.6.18/arch/sparc/mm/fault.c  2006-09-22 20:45:03.000000000 -0400
7544 @@ -21,6 +21,10 @@
7545  #include <linux/smp_lock.h>
7546  #include <linux/interrupt.h>
7547  #include <linux/module.h>
7548 +#include <linux/slab.h>
7549 +#include <linux/pagemap.h>
7550 +#include <linux/compiler.h>
7551 +#include <linux/binfmts.h>
7552  
7553  #include <asm/system.h>
7554  #include <asm/page.h>
7555 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
7556         return safe_compute_effective_address(regs, insn);
7557  }
7558  
7559 +#ifdef CONFIG_PAX_PAGEEXEC
7560 +void pax_emuplt_close(struct vm_area_struct * vma)
7561 +{
7562 +       vma->vm_mm->call_dl_resolve = 0UL;
7563 +}
7564 +
7565 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7566 +{
7567 +       struct page* page;
7568 +       unsigned int *kaddr;
7569 +
7570 +       page = alloc_page(GFP_HIGHUSER);
7571 +       if (!page)
7572 +               return NOPAGE_OOM;
7573 +
7574 +       kaddr = kmap(page);
7575 +       memset(kaddr, 0, PAGE_SIZE);
7576 +       kaddr[0] = 0x9DE3BFA8U; /* save */
7577 +       flush_dcache_page(page);
7578 +       kunmap(page);
7579 +       if (type)
7580 +               *type = VM_FAULT_MAJOR;
7581 +
7582 +       return page;
7583 +}
7584 +
7585 +static struct vm_operations_struct pax_vm_ops = {
7586 +       .close = pax_emuplt_close,
7587 +       .nopage = pax_emuplt_nopage,
7588 +};
7589 +
7590 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7591 +{
7592 +       int ret;
7593 +
7594 +       memset(vma, 0, sizeof(*vma));
7595 +       vma->vm_mm = current->mm;
7596 +       vma->vm_start = addr;
7597 +       vma->vm_end = addr + PAGE_SIZE;
7598 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7599 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
7600 +       vma->vm_ops = &pax_vm_ops;
7601 +
7602 +       ret = insert_vm_struct(current->mm, vma);
7603 +       if (ret)
7604 +               return ret;
7605 +
7606 +       ++current->mm->total_vm;
7607 +       return 0;
7608 +}
7609 +
7610 +/*
7611 + * PaX: decide what to do with offenders (regs->pc = fault address)
7612 + *
7613 + * returns 1 when task should be killed
7614 + *         2 when patched PLT trampoline was detected
7615 + *         3 when unpatched PLT trampoline was detected
7616 + */
7617 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7618 +{
7619 +
7620 +#ifdef CONFIG_PAX_EMUPLT
7621 +       int err;
7622 +
7623 +       do { /* PaX: patched PLT emulation #1 */
7624 +               unsigned int sethi1, sethi2, jmpl;
7625 +
7626 +               err = get_user(sethi1, (unsigned int*)regs->pc);
7627 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
7628 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
7629 +
7630 +               if (err)
7631 +                       break;
7632 +
7633 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
7634 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
7635 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
7636 +               {
7637 +                       unsigned int addr;
7638 +
7639 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
7640 +                       addr = regs->u_regs[UREG_G1];
7641 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7642 +                       regs->pc = addr;
7643 +                       regs->npc = addr+4;
7644 +                       return 2;
7645 +               }
7646 +       } while (0);
7647 +
7648 +       { /* PaX: patched PLT emulation #2 */
7649 +               unsigned int ba;
7650 +
7651 +               err = get_user(ba, (unsigned int*)regs->pc);
7652 +
7653 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
7654 +                       unsigned int addr;
7655 +
7656 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7657 +                       regs->pc = addr;
7658 +                       regs->npc = addr+4;
7659 +                       return 2;
7660 +               }
7661 +       }
7662 +
7663 +       do { /* PaX: patched PLT emulation #3 */
7664 +               unsigned int sethi, jmpl, nop;
7665 +
7666 +               err = get_user(sethi, (unsigned int*)regs->pc);
7667 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
7668 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
7669 +
7670 +               if (err)
7671 +                       break;
7672 +
7673 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
7674 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
7675 +                   nop == 0x01000000U)
7676 +               {
7677 +                       unsigned int addr;
7678 +
7679 +                       addr = (sethi & 0x003FFFFFU) << 10;
7680 +                       regs->u_regs[UREG_G1] = addr;
7681 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7682 +                       regs->pc = addr;
7683 +                       regs->npc = addr+4;
7684 +                       return 2;
7685 +               }
7686 +       } while (0);
7687 +
7688 +       do { /* PaX: unpatched PLT emulation step 1 */
7689 +               unsigned int sethi, ba, nop;
7690 +
7691 +               err = get_user(sethi, (unsigned int*)regs->pc);
7692 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
7693 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
7694 +
7695 +               if (err)
7696 +                       break;
7697 +
7698 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
7699 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
7700 +                   nop == 0x01000000U)
7701 +               {
7702 +                       unsigned int addr, save, call;
7703 +
7704 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
7705 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7706 +                       else
7707 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
7708 +
7709 +                       err = get_user(save, (unsigned int*)addr);
7710 +                       err |= get_user(call, (unsigned int*)(addr+4));
7711 +                       err |= get_user(nop, (unsigned int*)(addr+8));
7712 +                       if (err)
7713 +                               break;
7714 +
7715 +                       if (save == 0x9DE3BFA8U &&
7716 +                           (call & 0xC0000000U) == 0x40000000U &&
7717 +                           nop == 0x01000000U)
7718 +                       {
7719 +                               struct vm_area_struct *vma;
7720 +                               unsigned long call_dl_resolve;
7721 +
7722 +                               down_read(&current->mm->mmap_sem);
7723 +                               call_dl_resolve = current->mm->call_dl_resolve;
7724 +                               up_read(&current->mm->mmap_sem);
7725 +                               if (likely(call_dl_resolve))
7726 +                                       goto emulate;
7727 +
7728 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7729 +
7730 +                               down_write(&current->mm->mmap_sem);
7731 +                               if (current->mm->call_dl_resolve) {
7732 +                                       call_dl_resolve = current->mm->call_dl_resolve;
7733 +                                       up_write(&current->mm->mmap_sem);
7734 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
7735 +                                       goto emulate;
7736 +                               }
7737 +
7738 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7739 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
7740 +                                       up_write(&current->mm->mmap_sem);
7741 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
7742 +                                       return 1;
7743 +                               }
7744 +
7745 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
7746 +                                       up_write(&current->mm->mmap_sem);
7747 +                                       kmem_cache_free(vm_area_cachep, vma);
7748 +                                       return 1;
7749 +                               }
7750 +
7751 +                               current->mm->call_dl_resolve = call_dl_resolve;
7752 +                               up_write(&current->mm->mmap_sem);
7753 +
7754 +emulate:
7755 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
7756 +                               regs->pc = call_dl_resolve;
7757 +                               regs->npc = addr+4;
7758 +                               return 3;
7759 +                       }
7760 +               }
7761 +       } while (0);
7762 +
7763 +       do { /* PaX: unpatched PLT emulation step 2 */
7764 +               unsigned int save, call, nop;
7765 +
7766 +               err = get_user(save, (unsigned int*)(regs->pc-4));
7767 +               err |= get_user(call, (unsigned int*)regs->pc);
7768 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
7769 +               if (err)
7770 +                       break;
7771 +
7772 +               if (save == 0x9DE3BFA8U &&
7773 +                   (call & 0xC0000000U) == 0x40000000U &&
7774 +                   nop == 0x01000000U)
7775 +               {
7776 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
7777 +
7778 +                       regs->u_regs[UREG_RETPC] = regs->pc;
7779 +                       regs->pc = dl_resolve;
7780 +                       regs->npc = dl_resolve+4;
7781 +                       return 3;
7782 +               }
7783 +       } while (0);
7784 +#endif
7785 +
7786 +       return 1;
7787 +}
7788 +
7789 +void pax_report_insns(void *pc, void *sp)
7790 +{
7791 +       unsigned long i;
7792 +
7793 +       printk(KERN_ERR "PAX: bytes at PC: ");
7794 +       for (i = 0; i < 5; i++) {
7795 +               unsigned int c;
7796 +               if (get_user(c, (unsigned int*)pc+i))
7797 +                       printk("???????? ");
7798 +               else
7799 +                       printk("%08x ", c);
7800 +       }
7801 +       printk("\n");
7802 +}
7803 +#endif
7804 +
7805  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
7806                                unsigned long address)
7807  {
7808 @@ -280,6 +530,24 @@ good_area:
7809                 if(!(vma->vm_flags & VM_WRITE))
7810                         goto bad_area;
7811         } else {
7812 +
7813 +#ifdef CONFIG_PAX_PAGEEXEC
7814 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
7815 +                       up_read(&mm->mmap_sem);
7816 +                       switch (pax_handle_fetch_fault(regs)) {
7817 +
7818 +#ifdef CONFIG_PAX_EMUPLT
7819 +                       case 2:
7820 +                       case 3:
7821 +                               return;
7822 +#endif
7823 +
7824 +                       }
7825 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
7826 +                       do_exit(SIGKILL);
7827 +               }
7828 +#endif
7829 +
7830                 /* Allow reads even for write-only mappings */
7831                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
7832                         goto bad_area;
7833 diff -urNp linux-2.6.18/arch/sparc/mm/init.c linux-2.6.18/arch/sparc/mm/init.c
7834 --- linux-2.6.18/arch/sparc/mm/init.c   2006-09-19 23:42:06.000000000 -0400
7835 +++ linux-2.6.18/arch/sparc/mm/init.c   2006-09-22 20:45:03.000000000 -0400
7836 @@ -333,17 +333,17 @@ void __init paging_init(void)
7837  
7838         /* Initialize the protection map with non-constant, MMU dependent values. */
7839         protection_map[0] = PAGE_NONE;
7840 -       protection_map[1] = PAGE_READONLY;
7841 -       protection_map[2] = PAGE_COPY;
7842 -       protection_map[3] = PAGE_COPY;
7843 +       protection_map[1] = PAGE_READONLY_NOEXEC;
7844 +       protection_map[2] = PAGE_COPY_NOEXEC;
7845 +       protection_map[3] = PAGE_COPY_NOEXEC;
7846         protection_map[4] = PAGE_READONLY;
7847         protection_map[5] = PAGE_READONLY;
7848         protection_map[6] = PAGE_COPY;
7849         protection_map[7] = PAGE_COPY;
7850         protection_map[8] = PAGE_NONE;
7851 -       protection_map[9] = PAGE_READONLY;
7852 -       protection_map[10] = PAGE_SHARED;
7853 -       protection_map[11] = PAGE_SHARED;
7854 +       protection_map[9] = PAGE_READONLY_NOEXEC;
7855 +       protection_map[10] = PAGE_SHARED_NOEXEC;
7856 +       protection_map[11] = PAGE_SHARED_NOEXEC;
7857         protection_map[12] = PAGE_READONLY;
7858         protection_map[13] = PAGE_READONLY;
7859         protection_map[14] = PAGE_SHARED;
7860 diff -urNp linux-2.6.18/arch/sparc/mm/srmmu.c linux-2.6.18/arch/sparc/mm/srmmu.c
7861 --- linux-2.6.18/arch/sparc/mm/srmmu.c  2006-09-19 23:42:06.000000000 -0400
7862 +++ linux-2.6.18/arch/sparc/mm/srmmu.c  2006-09-22 20:45:03.000000000 -0400
7863 @@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
7864         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
7865         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
7866         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
7867 +
7868 +#ifdef CONFIG_PAX_PAGEEXEC
7869 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
7870 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
7871 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
7872 +#endif
7873 +
7874         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
7875         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
7876  
7877 diff -urNp linux-2.6.18/arch/sparc64/kernel/ptrace.c linux-2.6.18/arch/sparc64/kernel/ptrace.c
7878 --- linux-2.6.18/arch/sparc64/kernel/ptrace.c   2006-09-19 23:42:06.000000000 -0400
7879 +++ linux-2.6.18/arch/sparc64/kernel/ptrace.c   2006-09-22 20:04:35.000000000 -0400
7880 @@ -22,6 +22,7 @@
7881  #include <linux/seccomp.h>
7882  #include <linux/audit.h>
7883  #include <linux/signal.h>
7884 +#include <linux/grsecurity.h>
7885  
7886  #include <asm/asi.h>
7887  #include <asm/pgtable.h>
7888 @@ -213,6 +214,11 @@ asmlinkage void do_ptrace(struct pt_regs
7889                 goto out;
7890         }
7891  
7892 +       if (gr_handle_ptrace(child, (long)request)) {
7893 +               pt_error_return(regs, EPERM);
7894 +               goto out_tsk;
7895 +       }
7896 +
7897         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
7898             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
7899                 if (ptrace_attach(child)) {
7900 diff -urNp linux-2.6.18/arch/sparc64/kernel/sys_sparc.c linux-2.6.18/arch/sparc64/kernel/sys_sparc.c
7901 --- linux-2.6.18/arch/sparc64/kernel/sys_sparc.c        2006-09-19 23:42:06.000000000 -0400
7902 +++ linux-2.6.18/arch/sparc64/kernel/sys_sparc.c        2006-09-22 20:45:03.000000000 -0400
7903 @@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
7904         if (filp || (flags & MAP_SHARED))
7905                 do_color_align = 1;
7906  
7907 +#ifdef CONFIG_PAX_RANDMMAP
7908 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7909 +#endif
7910 +
7911         if (addr) {
7912                 if (do_color_align)
7913                         addr = COLOUR_ALIGN(addr, pgoff);
7914 @@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
7915         }
7916  
7917         if (len > mm->cached_hole_size) {
7918 -               start_addr = addr = mm->free_area_cache;
7919 +               start_addr = addr = mm->free_area_cache;
7920         } else {
7921 -               start_addr = addr = TASK_UNMAPPED_BASE;
7922 +               start_addr = addr = mm->mmap_base;
7923                 mm->cached_hole_size = 0;
7924         }
7925  
7926 @@ -174,8 +178,8 @@ full_search:
7927                         vma = find_vma(mm, VA_EXCLUDE_END);
7928                 }
7929                 if (unlikely(task_size < addr)) {
7930 -                       if (start_addr != TASK_UNMAPPED_BASE) {
7931 -                               start_addr = addr = TASK_UNMAPPED_BASE;
7932 +                       if (start_addr != mm->mmap_base) {
7933 +                               start_addr = addr = mm->mmap_base;
7934                                 mm->cached_hole_size = 0;
7935                                 goto full_search;
7936                         }
7937 @@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
7938             current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
7939             sysctl_legacy_va_layout) {
7940                 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
7941 +
7942 +#ifdef CONFIG_PAX_RANDMMAP
7943 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7944 +                       mm->mmap_base += mm->delta_mmap;
7945 +#endif
7946 +
7947                 mm->get_unmapped_area = arch_get_unmapped_area;
7948                 mm->unmap_area = arch_unmap_area;
7949         } else {
7950 @@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
7951                         gap = (task_size / 6 * 5);
7952  
7953                 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
7954 +
7955 +#ifdef CONFIG_PAX_RANDMMAP
7956 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7957 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7958 +#endif
7959 +
7960                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7961                 mm->unmap_area = arch_unmap_area_topdown;
7962         }
7963 diff -urNp linux-2.6.18/arch/sparc64/mm/fault.c linux-2.6.18/arch/sparc64/mm/fault.c
7964 --- linux-2.6.18/arch/sparc64/mm/fault.c        2006-09-19 23:42:06.000000000 -0400
7965 +++ linux-2.6.18/arch/sparc64/mm/fault.c        2006-09-22 20:45:03.000000000 -0400
7966 @@ -20,6 +20,10 @@
7967  #include <linux/interrupt.h>
7968  #include <linux/kprobes.h>
7969  #include <linux/kallsyms.h>
7970 +#include <linux/slab.h>
7971 +#include <linux/pagemap.h>
7972 +#include <linux/compiler.h>
7973 +#include <linux/binfmts.h>
7974  
7975  #include <asm/page.h>
7976  #include <asm/pgtable.h>
7977 @@ -290,6 +294,369 @@ cannot_handle:
7978         unhandled_fault (address, current, regs);
7979  }
7980  
7981 +#ifdef CONFIG_PAX_PAGEEXEC
7982 +#ifdef CONFIG_PAX_EMUPLT
7983 +static void pax_emuplt_close(struct vm_area_struct * vma)
7984 +{
7985 +       vma->vm_mm->call_dl_resolve = 0UL;
7986 +}
7987 +
7988 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7989 +{
7990 +       struct page* page;
7991 +       unsigned int *kaddr;
7992 +
7993 +       page = alloc_page(GFP_HIGHUSER);
7994 +       if (!page)
7995 +               return NOPAGE_OOM;
7996 +
7997 +       kaddr = kmap(page);
7998 +       memset(kaddr, 0, PAGE_SIZE);
7999 +       kaddr[0] = 0x9DE3BFA8U; /* save */
8000 +       flush_dcache_page(page);
8001 +       kunmap(page);
8002 +       if (type)
8003 +               *type = VM_FAULT_MAJOR;
8004 +       return page;
8005 +}
8006 +
8007 +static struct vm_operations_struct pax_vm_ops = {
8008 +       .close = pax_emuplt_close,
8009 +       .nopage = pax_emuplt_nopage,
8010 +};
8011 +
8012 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8013 +{
8014 +       int ret;
8015 +
8016 +       memset(vma, 0, sizeof(*vma));
8017 +       vma->vm_mm = current->mm;
8018 +       vma->vm_start = addr;
8019 +       vma->vm_end = addr + PAGE_SIZE;
8020 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8021 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
8022 +       vma->vm_ops = &pax_vm_ops;
8023 +
8024 +       ret = insert_vm_struct(current->mm, vma);
8025 +       if (ret)
8026 +               return ret;
8027 +
8028 +       ++current->mm->total_vm;
8029 +       return 0;
8030 +}
8031 +#endif
8032 +
8033 +/*
8034 + * PaX: decide what to do with offenders (regs->tpc = fault address)
8035 + *
8036 + * returns 1 when task should be killed
8037 + *         2 when patched PLT trampoline was detected
8038 + *         3 when unpatched PLT trampoline was detected
8039 + */
8040 +static int pax_handle_fetch_fault(struct pt_regs *regs)
8041 +{
8042 +
8043 +#ifdef CONFIG_PAX_EMUPLT
8044 +       int err;
8045 +
8046 +       do { /* PaX: patched PLT emulation #1 */
8047 +               unsigned int sethi1, sethi2, jmpl;
8048 +
8049 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
8050 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
8051 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
8052 +
8053 +               if (err)
8054 +                       break;
8055 +
8056 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8057 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
8058 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
8059 +               {
8060 +                       unsigned long addr;
8061 +
8062 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
8063 +                       addr = regs->u_regs[UREG_G1];
8064 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
8065 +                       regs->tpc = addr;
8066 +                       regs->tnpc = addr+4;
8067 +                       return 2;
8068 +               }
8069 +       } while (0);
8070 +
8071 +       { /* PaX: patched PLT emulation #2 */
8072 +               unsigned int ba;
8073 +
8074 +               err = get_user(ba, (unsigned int*)regs->tpc);
8075 +
8076 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
8077 +                       unsigned long addr;
8078 +
8079 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8080 +                       regs->tpc = addr;
8081 +                       regs->tnpc = addr+4;
8082 +                       return 2;
8083 +               }
8084 +       }
8085 +
8086 +       do { /* PaX: patched PLT emulation #3 */
8087 +               unsigned int sethi, jmpl, nop;
8088 +
8089 +               err = get_user(sethi, (unsigned int*)regs->tpc);
8090 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
8091 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
8092 +
8093 +               if (err)
8094 +                       break;
8095 +
8096 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
8097 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
8098 +                   nop == 0x01000000U)
8099 +               {
8100 +                       unsigned long addr;
8101 +
8102 +                       addr = (sethi & 0x003FFFFFU) << 10;
8103 +                       regs->u_regs[UREG_G1] = addr;
8104 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
8105 +                       regs->tpc = addr;
8106 +                       regs->tnpc = addr+4;
8107 +                       return 2;
8108 +               }
8109 +       } while (0);
8110 +
8111 +       do { /* PaX: patched PLT emulation #4 */
8112 +               unsigned int mov1, call, mov2;
8113 +
8114 +               err = get_user(mov1, (unsigned int*)regs->tpc);
8115 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
8116 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
8117 +
8118 +               if (err)
8119 +                       break;
8120 +
8121 +               if (mov1 == 0x8210000FU &&
8122 +                   (call & 0xC0000000U) == 0x40000000U &&
8123 +                   mov2 == 0x9E100001U)
8124 +               {
8125 +                       unsigned long addr;
8126 +
8127 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
8128 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
8129 +                       regs->tpc = addr;
8130 +                       regs->tnpc = addr+4;
8131 +                       return 2;
8132 +               }
8133 +       } while (0);
8134 +
8135 +       do { /* PaX: patched PLT emulation #5 */
8136 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
8137 +
8138 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
8139 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
8140 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
8141 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
8142 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
8143 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
8144 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
8145 +
8146 +               if (err)
8147 +                       break;
8148 +
8149 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8150 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
8151 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
8152 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
8153 +                   sllx == 0x83287020 &&
8154 +                   jmpl == 0x81C04005U &&
8155 +                   nop == 0x01000000U)
8156 +               {
8157 +                       unsigned long addr;
8158 +
8159 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
8160 +                       regs->u_regs[UREG_G1] <<= 32;
8161 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
8162 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
8163 +                       regs->tpc = addr;
8164 +                       regs->tnpc = addr+4;
8165 +                       return 2;
8166 +               }
8167 +       } while (0);
8168 +
8169 +       do { /* PaX: patched PLT emulation #6 */
8170 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
8171 +
8172 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
8173 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
8174 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
8175 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
8176 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
8177 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
8178 +
8179 +               if (err)
8180 +                       break;
8181 +
8182 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8183 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
8184 +                   sllx == 0x83287020 &&
8185 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
8186 +                   jmpl == 0x81C04005U &&
8187 +                   nop == 0x01000000U)
8188 +               {
8189 +                       unsigned long addr;
8190 +
8191 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
8192 +                       regs->u_regs[UREG_G1] <<= 32;
8193 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
8194 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
8195 +                       regs->tpc = addr;
8196 +                       regs->tnpc = addr+4;
8197 +                       return 2;
8198 +               }
8199 +       } while (0);
8200 +
8201 +       do { /* PaX: patched PLT emulation #7 */
8202 +               unsigned int sethi, ba, nop;
8203 +
8204 +               err = get_user(sethi, (unsigned int*)regs->tpc);
8205 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
8206 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
8207 +
8208 +               if (err)
8209 +                       break;
8210 +
8211 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
8212 +                   (ba & 0xFFF00000U) == 0x30600000U &&
8213 +                   nop == 0x01000000U)
8214 +               {
8215 +                       unsigned long addr;
8216 +
8217 +                       addr = (sethi & 0x003FFFFFU) << 10;
8218 +                       regs->u_regs[UREG_G1] = addr;
8219 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
8220 +                       regs->tpc = addr;
8221 +                       regs->tnpc = addr+4;
8222 +                       return 2;
8223 +               }
8224 +       } while (0);
8225 +
8226 +       do { /* PaX: unpatched PLT emulation step 1 */
8227 +               unsigned int sethi, ba, nop;
8228 +
8229 +               err = get_user(sethi, (unsigned int*)regs->tpc);
8230 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
8231 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
8232 +
8233 +               if (err)
8234 +                       break;
8235 +
8236 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
8237 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
8238 +                   nop == 0x01000000U)
8239 +               {
8240 +                       unsigned long addr;
8241 +                       unsigned int save, call;
8242 +
8243 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
8244 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8245 +                       else
8246 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
8247 +
8248 +                       err = get_user(save, (unsigned int*)addr);
8249 +                       err |= get_user(call, (unsigned int*)(addr+4));
8250 +                       err |= get_user(nop, (unsigned int*)(addr+8));
8251 +                       if (err)
8252 +                               break;
8253 +
8254 +                       if (save == 0x9DE3BFA8U &&
8255 +                           (call & 0xC0000000U) == 0x40000000U &&
8256 +                           nop == 0x01000000U)
8257 +                       {
8258 +                               struct vm_area_struct *vma;
8259 +                               unsigned long call_dl_resolve;
8260 +
8261 +                               down_read(&current->mm->mmap_sem);
8262 +                               call_dl_resolve = current->mm->call_dl_resolve;
8263 +                               up_read(&current->mm->mmap_sem);
8264 +                               if (likely(call_dl_resolve))
8265 +                                       goto emulate;
8266 +
8267 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8268 +
8269 +                               down_write(&current->mm->mmap_sem);
8270 +                               if (current->mm->call_dl_resolve) {
8271 +                                       call_dl_resolve = current->mm->call_dl_resolve;
8272 +                                       up_write(&current->mm->mmap_sem);
8273 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
8274 +                                       goto emulate;
8275 +                               }
8276 +
8277 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8278 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
8279 +                                       up_write(&current->mm->mmap_sem);
8280 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
8281 +                                       return 1;
8282 +                               }
8283 +
8284 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
8285 +                                       up_write(&current->mm->mmap_sem);
8286 +                                       kmem_cache_free(vm_area_cachep, vma);
8287 +                                       return 1;
8288 +                               }
8289 +
8290 +                               current->mm->call_dl_resolve = call_dl_resolve;
8291 +                               up_write(&current->mm->mmap_sem);
8292 +
8293 +emulate:
8294 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
8295 +                               regs->tpc = call_dl_resolve;
8296 +                               regs->tnpc = addr+4;
8297 +                               return 3;
8298 +                       }
8299 +               }
8300 +       } while (0);
8301 +
8302 +       do { /* PaX: unpatched PLT emulation step 2 */
8303 +               unsigned int save, call, nop;
8304 +
8305 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
8306 +               err |= get_user(call, (unsigned int*)regs->tpc);
8307 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
8308 +               if (err)
8309 +                       break;
8310 +
8311 +               if (save == 0x9DE3BFA8U &&
8312 +                   (call & 0xC0000000U) == 0x40000000U &&
8313 +                   nop == 0x01000000U)
8314 +               {
8315 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
8316 +
8317 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
8318 +                       regs->tpc = dl_resolve;
8319 +                       regs->tnpc = dl_resolve+4;
8320 +                       return 3;
8321 +               }
8322 +       } while (0);
8323 +#endif
8324 +
8325 +       return 1;
8326 +}
8327 +
8328 +void pax_report_insns(void *pc, void *sp)
8329 +{
8330 +       unsigned long i;
8331 +
8332 +       printk(KERN_ERR "PAX: bytes at PC: ");
8333 +       for (i = 0; i < 5; i++) {
8334 +               unsigned int c;
8335 +               if (get_user(c, (unsigned int*)pc+i))
8336 +                       printk("???????? ");
8337 +               else
8338 +                       printk("%08x ", c);
8339 +       }
8340 +       printk("\n");
8341 +}
8342 +#endif
8343 +
8344  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
8345  {
8346         struct mm_struct *mm = current->mm;
8347 @@ -332,8 +699,10 @@ asmlinkage void __kprobes do_sparc64_fau
8348                 goto intr_or_no_mm;
8349  
8350         if (test_thread_flag(TIF_32BIT)) {
8351 -               if (!(regs->tstate & TSTATE_PRIV))
8352 +               if (!(regs->tstate & TSTATE_PRIV)) {
8353                         regs->tpc &= 0xffffffff;
8354 +                       regs->tnpc &= 0xffffffff;
8355 +               }
8356                 address &= 0xffffffff;
8357         }
8358  
8359 @@ -350,6 +719,29 @@ asmlinkage void __kprobes do_sparc64_fau
8360         if (!vma)
8361                 goto bad_area;
8362  
8363 +#ifdef CONFIG_PAX_PAGEEXEC
8364 +       /* PaX: detect ITLB misses on non-exec pages */
8365 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
8366 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
8367 +       {
8368 +               if (address != regs->tpc)
8369 +                       goto good_area;
8370 +
8371 +               up_read(&mm->mmap_sem);
8372 +               switch (pax_handle_fetch_fault(regs)) {
8373 +
8374 +#ifdef CONFIG_PAX_EMUPLT
8375 +               case 2:
8376 +               case 3:
8377 +                       return;
8378 +#endif
8379 +
8380 +               }
8381 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
8382 +               do_exit(SIGKILL);
8383 +       }
8384 +#endif
8385 +
8386         /* Pure DTLB misses do not tell us whether the fault causing
8387          * load/store/atomic was a write or not, it only says that there
8388          * was no match.  So in such a case we (carefully) read the
8389 diff -urNp linux-2.6.18/arch/v850/kernel/module.c linux-2.6.18/arch/v850/kernel/module.c
8390 --- linux-2.6.18/arch/v850/kernel/module.c      2006-09-19 23:42:06.000000000 -0400
8391 +++ linux-2.6.18/arch/v850/kernel/module.c      2006-09-22 20:45:03.000000000 -0400
8392 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
8393         tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
8394  
8395         /* Init, or core PLT? */
8396 -       if (location >= mod->module_core
8397 -           && location < mod->module_core + mod->core_size)
8398 +       if (location >= mod->module_core_rx
8399 +           && location < mod->module_core_rx + mod->core_size_rx)
8400                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
8401         else
8402                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
8403 diff -urNp linux-2.6.18/arch/x86_64/boot/compressed/head.S linux-2.6.18/arch/x86_64/boot/compressed/head.S
8404 --- linux-2.6.18/arch/x86_64/boot/compressed/head.S     2006-09-19 23:42:06.000000000 -0400
8405 +++ linux-2.6.18/arch/x86_64/boot/compressed/head.S     2006-09-22 20:45:04.000000000 -0400
8406 @@ -41,11 +41,13 @@ startup_32:
8407         movl %eax,%gs
8408  
8409         lss stack_start,%esp
8410 +       movl 0x000000,%ecx
8411         xorl %eax,%eax
8412  1:     incl %eax               # check that A20 really IS enabled
8413         movl %eax,0x000000      # loop forever if it isn't
8414         cmpl %eax,0x100000
8415         je 1b
8416 +       movl %ecx,0x000000
8417  
8418  /*
8419   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
8420 diff -urNp linux-2.6.18/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.18/arch/x86_64/ia32/ia32_binfmt.c
8421 --- linux-2.6.18/arch/x86_64/ia32/ia32_binfmt.c 2006-09-19 23:42:06.000000000 -0400
8422 +++ linux-2.6.18/arch/x86_64/ia32/ia32_binfmt.c 2006-09-22 20:45:04.000000000 -0400
8423 @@ -191,6 +191,17 @@ struct elf_prpsinfo
8424  //#include <asm/ia32.h>
8425  #include <linux/elf.h>
8426  
8427 +#ifdef CONFIG_PAX_ASLR
8428 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
8429 +
8430 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
8431 +#define PAX_DELTA_MMAP_LEN(tsk)                16
8432 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
8433 +#define PAX_DELTA_EXEC_LEN(tsk)                16
8434 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
8435 +#define PAX_DELTA_STACK_LEN(tsk)       16
8436 +#endif
8437 +
8438  typedef struct user_i387_ia32_struct elf_fpregset_t;
8439  typedef struct user32_fxsr_struct elf_fpxregset_t;
8440  
8441 diff -urNp linux-2.6.18/arch/x86_64/ia32/mmap32.c linux-2.6.18/arch/x86_64/ia32/mmap32.c
8442 --- linux-2.6.18/arch/x86_64/ia32/mmap32.c      2006-09-19 23:42:06.000000000 -0400
8443 +++ linux-2.6.18/arch/x86_64/ia32/mmap32.c      2006-09-22 20:45:04.000000000 -0400
8444 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
8445                         (current->personality & ADDR_COMPAT_LAYOUT) ||
8446                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
8447                 mm->mmap_base = TASK_UNMAPPED_BASE;
8448 +
8449 +#ifdef CONFIG_PAX_RANDMMAP
8450 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
8451 +                       mm->mmap_base += mm->delta_mmap;
8452 +#endif
8453 +
8454                 mm->get_unmapped_area = arch_get_unmapped_area;
8455                 mm->unmap_area = arch_unmap_area;
8456         } else {
8457                 mm->mmap_base = mmap_base(mm);
8458 +
8459 +#ifdef CONFIG_PAX_RANDMMAP
8460 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
8461 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8462 +#endif
8463 +
8464                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8465                 mm->unmap_area = arch_unmap_area_topdown;
8466         }
8467 diff -urNp linux-2.6.18/arch/x86_64/ia32/syscall32.c linux-2.6.18/arch/x86_64/ia32/syscall32.c
8468 --- linux-2.6.18/arch/x86_64/ia32/syscall32.c   2006-09-19 23:42:06.000000000 -0400
8469 +++ linux-2.6.18/arch/x86_64/ia32/syscall32.c   2006-09-22 20:45:04.000000000 -0400
8470 @@ -49,11 +49,10 @@ int syscall32_setup_pages(struct linux_b
8471         struct mm_struct *mm = current->mm;
8472         int ret;
8473  
8474 -       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8475 +       vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
8476         if (!vma)
8477                 return -ENOMEM;
8478  
8479 -       memset(vma, 0, sizeof(struct vm_area_struct));
8480         /* Could randomize here */
8481         vma->vm_start = VSYSCALL32_BASE;
8482         vma->vm_end = VSYSCALL32_END;
8483 diff -urNp linux-2.6.18/arch/x86_64/kernel/process.c linux-2.6.18/arch/x86_64/kernel/process.c
8484 --- linux-2.6.18/arch/x86_64/kernel/process.c   2006-09-19 23:42:06.000000000 -0400
8485 +++ linux-2.6.18/arch/x86_64/kernel/process.c   2006-09-22 20:45:04.000000000 -0400
8486 @@ -832,9 +832,3 @@ int dump_task_regs(struct task_struct *t
8487         return 1;
8488  }
8489  
8490 -unsigned long arch_align_stack(unsigned long sp)
8491 -{
8492 -       if (randomize_va_space)
8493 -               sp -= get_random_int() % 8192;
8494 -       return sp & ~0xf;
8495 -}
8496 diff -urNp linux-2.6.18/arch/x86_64/kernel/ptrace.c linux-2.6.18/arch/x86_64/kernel/ptrace.c
8497 --- linux-2.6.18/arch/x86_64/kernel/ptrace.c    2006-09-19 23:42:06.000000000 -0400
8498 +++ linux-2.6.18/arch/x86_64/kernel/ptrace.c    2006-09-22 20:04:35.000000000 -0400
8499 @@ -19,6 +19,7 @@
8500  #include <linux/audit.h>
8501  #include <linux/seccomp.h>
8502  #include <linux/signal.h>
8503 +#include <linux/grsecurity.h>
8504  
8505  #include <asm/uaccess.h>
8506  #include <asm/pgtable.h>
8507 diff -urNp linux-2.6.18/arch/x86_64/kernel/setup64.c linux-2.6.18/arch/x86_64/kernel/setup64.c
8508 --- linux-2.6.18/arch/x86_64/kernel/setup64.c   2006-09-19 23:42:06.000000000 -0400
8509 +++ linux-2.6.18/arch/x86_64/kernel/setup64.c   2006-09-22 20:45:04.000000000 -0400
8510 @@ -38,7 +38,6 @@ char boot_cpu_stack[IRQSTACKSIZE] __attr
8511  
8512  unsigned long __supported_pte_mask __read_mostly = ~0UL;
8513  EXPORT_SYMBOL(__supported_pte_mask);
8514 -static int do_not_nx __cpuinitdata = 0;
8515  
8516  /* noexec=on|off
8517  Control non executable mappings for 64bit processes.
8518 @@ -50,16 +49,14 @@ int __init nonx_setup(char *str)
8519  {
8520         if (!strncmp(str, "on", 2)) {
8521                  __supported_pte_mask |= _PAGE_NX; 
8522 -               do_not_nx = 0; 
8523         } else if (!strncmp(str, "off", 3)) {
8524 -               do_not_nx = 1;
8525                 __supported_pte_mask &= ~_PAGE_NX;
8526          }
8527         return 1;
8528  } 
8529  __setup("noexec=", nonx_setup);        /* parsed early actually */
8530  
8531 -int force_personality32 = 0; 
8532 +int force_personality32;
8533  
8534  /* noexec32=on|off
8535  Control non executable heap for 32bit processes.
8536 @@ -173,7 +170,7 @@ void __cpuinit check_efer(void)
8537         unsigned long efer;
8538  
8539         rdmsrl(MSR_EFER, efer); 
8540 -        if (!(efer & EFER_NX) || do_not_nx) { 
8541 +        if (!(efer & EFER_NX)) { 
8542                  __supported_pte_mask &= ~_PAGE_NX; 
8543          }       
8544  }
8545 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
8546 --- linux-2.6.18/arch/x86_64/kernel/sys_x86_64.c        2006-09-19 23:42:06.000000000 -0400
8547 +++ linux-2.6.18/arch/x86_64/kernel/sys_x86_64.c        2006-09-22 20:45:04.000000000 -0400
8548 @@ -65,8 +65,8 @@ out:
8549         return error;
8550  }
8551  
8552 -static void find_start_end(unsigned long flags, unsigned long *begin,
8553 -                          unsigned long *end)
8554 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
8555 +                          unsigned long *begin, unsigned long *end)
8556  {
8557         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
8558                 /* This is usually used needed to map code in small
8559 @@ -79,7 +79,7 @@ static void find_start_end(unsigned long
8560                 *begin = 0x40000000; 
8561                 *end = 0x80000000;              
8562         } else {
8563 -               *begin = TASK_UNMAPPED_BASE;
8564 +               *begin = mm->mmap_base;
8565                 *end = TASK_SIZE; 
8566         }
8567  } 
8568 @@ -93,11 +93,15 @@ arch_get_unmapped_area(struct file *filp
8569         unsigned long start_addr;
8570         unsigned long begin, end;
8571         
8572 -       find_start_end(flags, &begin, &end); 
8573 +       find_start_end(mm, flags, &begin, &end); 
8574  
8575         if (len > end)
8576                 return -ENOMEM;
8577  
8578 +#ifdef CONFIG_PAX_RANDMMAP
8579 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8580 +#endif
8581 +
8582         if (addr) {
8583                 addr = PAGE_ALIGN(addr);
8584                 vma = find_vma(mm, addr);
8585 diff -urNp linux-2.6.18/arch/x86_64/mm/fault.c linux-2.6.18/arch/x86_64/mm/fault.c
8586 --- linux-2.6.18/arch/x86_64/mm/fault.c 2006-09-19 23:42:06.000000000 -0400
8587 +++ linux-2.6.18/arch/x86_64/mm/fault.c 2006-09-22 20:45:04.000000000 -0400
8588 @@ -23,6 +23,7 @@
8589  #include <linux/compiler.h>
8590  #include <linux/module.h>
8591  #include <linux/kprobes.h>
8592 +#include <linux/binfmts.h>
8593  
8594  #include <asm/system.h>
8595  #include <asm/uaccess.h>
8596 @@ -328,6 +329,33 @@ static int vmalloc_fault(unsigned long a
8597         return 0;
8598  }
8599  
8600 +#ifdef CONFIG_PAX_PAGEEXEC
8601 +void pax_report_insns(void *pc, void *sp)
8602 +{
8603 +       long i;
8604 +
8605 +       printk(KERN_ERR "PAX: bytes at PC: ");
8606 +       for (i = 0; i < 20; i++) {
8607 +               unsigned char c;
8608 +               if (get_user(c, (unsigned char __user *)pc+i))
8609 +                       printk("?? ");
8610 +               else
8611 +                       printk("%02x ", c);
8612 +       }
8613 +       printk("\n");
8614 +
8615 +       printk(KERN_ERR "PAX: bytes at SP-8: ");
8616 +       for (i = -1; i < 10; i++) {
8617 +               unsigned long c;
8618 +               if (get_user(c, (unsigned long __user *)sp+i))
8619 +                       printk("???????????????? ");
8620 +               else
8621 +                       printk("%016lx ", c);
8622 +       }
8623 +       printk("\n");
8624 +}
8625 +#endif
8626 +
8627  int page_fault_trace = 0;
8628  int exception_trace = 1;
8629  
8630 @@ -459,6 +487,8 @@ asmlinkage void __kprobes do_page_fault(
8631  good_area:
8632         info.si_code = SEGV_ACCERR;
8633         write = 0;
8634 +       if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
8635 +               goto bad_area;
8636         switch (error_code & (PF_PROT|PF_WRITE)) {
8637                 default:        /* 3: write, present */
8638                         /* fall through */
8639 @@ -525,7 +555,14 @@ bad_area_nosemaphore:
8640                                         tsk->comm, tsk->pid, address, regs->rip,
8641                                         regs->rsp, error_code);
8642                 }
8643 -       
8644 +
8645 +#ifdef CONFIG_PAX_PAGEEXEC
8646 +               if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
8647 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
8648 +                       do_exit(SIGKILL);
8649 +               }
8650 +#endif
8651 +
8652                 tsk->thread.cr2 = address;
8653                 /* Kernel addresses are always protection faults */
8654                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
8655 diff -urNp linux-2.6.18/arch/x86_64/mm/mmap.c linux-2.6.18/arch/x86_64/mm/mmap.c
8656 --- linux-2.6.18/arch/x86_64/mm/mmap.c  2006-09-19 23:42:06.000000000 -0400
8657 +++ linux-2.6.18/arch/x86_64/mm/mmap.c  2006-09-22 20:45:04.000000000 -0400
8658 @@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
8659                 unsigned rnd = get_random_int() & 0xfffffff;
8660                 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
8661         }
8662 +
8663 +#ifdef CONFIG_PAX_RANDMMAP
8664 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
8665 +               mm->mmap_base += mm->delta_mmap;
8666 +#endif
8667 +
8668         mm->get_unmapped_area = arch_get_unmapped_area;
8669         mm->unmap_area = arch_unmap_area;
8670  }
8671 diff -urNp linux-2.6.18/Documentation/dontdiff linux-2.6.18/Documentation/dontdiff
8672 --- linux-2.6.18/Documentation/dontdiff 2006-09-19 23:42:06.000000000 -0400
8673 +++ linux-2.6.18/Documentation/dontdiff 2006-09-22 20:45:03.000000000 -0400
8674 @@ -55,7 +55,7 @@ aic7*seq.h*
8675  aicasm
8676  aicdb.h*
8677  asm
8678 -asm-offsets.*
8679 +asm-offsets.h
8680  asm_offsets.*
8681  autoconf.h*
8682  bbootsect
8683 @@ -115,6 +115,7 @@ mkdep
8684  mktables
8685  modpost
8686  modversions.h*
8687 +netfilter*
8688  offset.h
8689  offsets.h
8690  oui.c*
8691 @@ -142,4 +143,5 @@ vmlinux.lds
8692  vsyscall.lds
8693  wanxlfw.inc
8694  uImage
8695 +utsrelease.h
8696  zImage
8697 diff -urNp linux-2.6.18/drivers/acpi/glue.c linux-2.6.18/drivers/acpi/glue.c
8698 --- linux-2.6.18/drivers/acpi/glue.c    2006-09-19 23:42:06.000000000 -0400
8699 +++ linux-2.6.18/drivers/acpi/glue.c    2006-09-22 20:45:04.000000000 -0400
8700 @@ -16,7 +16,7 @@
8701  #if ACPI_GLUE_DEBUG
8702  #define DBG(x...) printk(PREFIX x)
8703  #else
8704 -#define DBG(x...)
8705 +#define DBG(x...) do {} while (0)
8706  #endif
8707  static LIST_HEAD(bus_type_list);
8708  static DECLARE_RWSEM(bus_type_sem);
8709 diff -urNp linux-2.6.18/drivers/acpi/processor_core.c linux-2.6.18/drivers/acpi/processor_core.c
8710 --- linux-2.6.18/drivers/acpi/processor_core.c  2006-09-19 23:42:06.000000000 -0400
8711 +++ linux-2.6.18/drivers/acpi/processor_core.c  2006-09-22 20:45:04.000000000 -0400
8712 @@ -534,7 +534,7 @@ static int acpi_processor_start(struct a
8713                 return 0;
8714         }
8715  
8716 -       BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
8717 +       BUG_ON(pr->id >= NR_CPUS);
8718  
8719         /*
8720          * Buggy BIOS check
8721 diff -urNp linux-2.6.18/drivers/char/agp/frontend.c linux-2.6.18/drivers/char/agp/frontend.c
8722 --- linux-2.6.18/drivers/char/agp/frontend.c    2006-09-19 23:42:06.000000000 -0400
8723 +++ linux-2.6.18/drivers/char/agp/frontend.c    2006-09-22 20:45:04.000000000 -0400
8724 @@ -841,7 +841,7 @@ static int agpioc_reserve_wrap(struct ag
8725         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
8726                 return -EFAULT;
8727  
8728 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
8729 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
8730                 return -EFAULT;
8731  
8732         client = agp_find_client_by_pid(reserve.pid);
8733 diff -urNp linux-2.6.18/drivers/char/keyboard.c linux-2.6.18/drivers/char/keyboard.c
8734 --- linux-2.6.18/drivers/char/keyboard.c        2006-09-19 23:42:06.000000000 -0400
8735 +++ linux-2.6.18/drivers/char/keyboard.c        2006-09-22 20:45:04.000000000 -0400
8736 @@ -198,7 +198,7 @@ int setkeycode(unsigned int scancode, un
8737  
8738         if (scancode >= dev->keycodemax)
8739                 return -EINVAL;
8740 -       if (keycode < 0 || keycode > KEY_MAX)
8741 +       if (keycode > KEY_MAX)
8742                 return -EINVAL;
8743         if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
8744                 return -EINVAL;
8745 @@ -618,6 +618,16 @@ static void k_spec(struct vc_data *vc, u
8746              kbd->kbdmode == VC_MEDIUMRAW) &&
8747              value != KVAL(K_SAK))
8748                 return;         /* SAK is allowed even in raw mode */
8749 +
8750 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
8751 +       {
8752 +               void *func = fn_handler[value];
8753 +               if (func == fn_show_state || func == fn_show_ptregs ||
8754 +                   func == fn_show_mem)
8755 +                       return;
8756 +       }
8757 +#endif
8758 +
8759         fn_handler[value](vc, regs);
8760  }
8761  
8762 diff -urNp linux-2.6.18/drivers/char/mem.c linux-2.6.18/drivers/char/mem.c
8763 --- linux-2.6.18/drivers/char/mem.c     2006-09-19 23:42:06.000000000 -0400
8764 +++ linux-2.6.18/drivers/char/mem.c     2006-09-22 20:45:04.000000000 -0400
8765 @@ -26,6 +26,7 @@
8766  #include <linux/backing-dev.h>
8767  #include <linux/bootmem.h>
8768  #include <linux/pipe_fs_i.h>
8769 +#include <linux/grsecurity.h>
8770  
8771  #include <asm/uaccess.h>
8772  #include <asm/io.h>
8773 @@ -34,6 +35,10 @@
8774  # include <linux/efi.h>
8775  #endif
8776  
8777 +#ifdef CONFIG_GRKERNSEC
8778 +extern struct file_operations grsec_fops;
8779 +#endif
8780 +
8781  /*
8782   * Architectures vary in how they handle caching for addresses
8783   * outside of main memory.
8784 @@ -173,6 +178,11 @@ static ssize_t write_mem(struct file * f
8785         if (!valid_phys_addr_range(p, count))
8786                 return -EFAULT;
8787  
8788 +#ifdef CONFIG_GRKERNSEC_KMEM
8789 +       gr_handle_mem_write();
8790 +       return -EPERM;
8791 +#endif
8792 +
8793         written = 0;
8794  
8795  #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
8796 @@ -249,6 +259,11 @@ static int mmap_mem(struct file * file, 
8797                                                  size,
8798                                                  vma->vm_page_prot);
8799  
8800 +#ifdef CONFIG_GRKERNSEC_KMEM
8801 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
8802 +               return -EPERM;
8803 +#endif
8804 +
8805         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
8806         if (remap_pfn_range(vma,
8807                             vma->vm_start,
8808 @@ -476,6 +491,11 @@ static ssize_t write_kmem(struct file * 
8809         ssize_t written;
8810         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
8811  
8812 +#ifdef CONFIG_GRKERNSEC_KMEM
8813 +       gr_handle_kmem_write();
8814 +       return -EPERM;
8815 +#endif
8816 +
8817         if (p < (unsigned long) high_memory) {
8818  
8819                 wrote = count;
8820 @@ -616,7 +636,23 @@ static inline size_t read_zero_pagealign
8821                         count = size;
8822  
8823                 zap_page_range(vma, addr, count, NULL);
8824 -               zeromap_page_range(vma, addr, count, PAGE_COPY);
8825 +               zeromap_page_range(vma, addr, count, vma->vm_page_prot);
8826 +
8827 +#ifdef CONFIG_PAX_SEGMEXEC
8828 +               if (vma->vm_flags & VM_MIRROR) {
8829 +                       unsigned long addr_m;
8830 +                       struct vm_area_struct * vma_m;
8831 +
8832 +                       addr_m = vma->vm_start + vma->vm_mirror;
8833 +                       vma_m = find_vma(mm, addr_m);
8834 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
8835 +                               addr_m = addr + vma->vm_mirror;
8836 +                               zap_page_range(vma_m, addr_m, count, NULL);
8837 +                       } else
8838 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
8839 +                                      addr, vma->vm_start);
8840 +               }
8841 +#endif
8842  
8843                 size -= count;
8844                 buf += count;
8845 @@ -765,6 +801,16 @@ static loff_t memory_lseek(struct file *
8846  
8847  static int open_port(struct inode * inode, struct file * filp)
8848  {
8849 +#ifdef CONFIG_GRKERNSEC_KMEM
8850 +       gr_handle_open_port();
8851 +       return -EPERM;
8852 +#endif
8853 +
8854 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
8855 +}
8856 +
8857 +static int open_mem(struct inode * inode, struct file * filp)
8858 +{
8859         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
8860  }
8861  
8862 @@ -772,7 +818,6 @@ static int open_port(struct inode * inod
8863  #define full_lseek      null_lseek
8864  #define write_zero     write_null
8865  #define read_full       read_zero
8866 -#define open_mem       open_port
8867  #define open_kmem      open_mem
8868  #define open_oldmem    open_mem
8869  
8870 @@ -895,6 +940,11 @@ static int memory_open(struct inode * in
8871                         filp->f_op = &oldmem_fops;
8872                         break;
8873  #endif
8874 +#ifdef CONFIG_GRKERNSEC
8875 +               case 13:
8876 +                       filp->f_op = &grsec_fops;
8877 +                       break;
8878 +#endif
8879                 default:
8880                         return -ENXIO;
8881         }
8882 @@ -927,6 +977,9 @@ static const struct {
8883  #ifdef CONFIG_CRASH_DUMP
8884         {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
8885  #endif
8886 +#ifdef CONFIG_GRKERNSEC
8887 +       {13,"grsec",    S_IRUSR | S_IWUGO,          &grsec_fops},
8888 +#endif
8889  };
8890  
8891  static struct class *mem_class;
8892 diff -urNp linux-2.6.18/drivers/char/random.c linux-2.6.18/drivers/char/random.c
8893 --- linux-2.6.18/drivers/char/random.c  2006-09-19 23:42:06.000000000 -0400
8894 +++ linux-2.6.18/drivers/char/random.c  2006-09-22 20:45:04.000000000 -0400
8895 @@ -248,8 +248,13 @@
8896  /*
8897   * Configuration information
8898   */
8899 +#ifdef CONFIG_GRKERNSEC_RANDNET
8900 +#define INPUT_POOL_WORDS 512
8901 +#define OUTPUT_POOL_WORDS 128
8902 +#else
8903  #define INPUT_POOL_WORDS 128
8904  #define OUTPUT_POOL_WORDS 32
8905 +#endif
8906  #define SEC_XFER_SIZE 512
8907  
8908  /*
8909 @@ -286,10 +291,17 @@ static struct poolinfo {
8910         int poolwords;
8911         int tap1, tap2, tap3, tap4, tap5;
8912  } poolinfo_table[] = {
8913 +#ifdef CONFIG_GRKERNSEC_RANDNET
8914 +       /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
8915 +       { 512,  411,    308,    208,    104,    1 },
8916 +       /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
8917 +       { 128,  103,    76,     51,     25,     1 },
8918 +#else
8919         /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
8920         { 128,  103,    76,     51,     25,     1 },
8921         /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
8922         { 32,   26,     20,     14,     7,      1 },
8923 +#endif
8924  #if 0
8925         /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
8926         { 2048, 1638,   1231,   819,    411,    1 },
8927 @@ -1657,3 +1669,25 @@ randomize_range(unsigned long start, uns
8928                 return 0;
8929         return PAGE_ALIGN(get_random_int() % range + start);
8930  }
8931 +
8932 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
8933 +unsigned long pax_get_random_long(void)
8934 +{
8935 +       static time_t   rekey_time;
8936 +       static __u32    secret[12];
8937 +       time_t          t;
8938 +
8939 +       /*
8940 +        * Pick a random secret every REKEY_INTERVAL seconds.
8941 +        */
8942 +       t = get_seconds();
8943 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
8944 +               rekey_time = t;
8945 +               get_random_bytes(secret, sizeof(secret));
8946 +       }
8947 +
8948 +       secret[1] = half_md4_transform(secret+8, secret);
8949 +       secret[0] = half_md4_transform(secret+8, secret);
8950 +       return *(unsigned long *)secret;
8951 +}
8952 +#endif
8953 diff -urNp linux-2.6.18/drivers/char/vt_ioctl.c linux-2.6.18/drivers/char/vt_ioctl.c
8954 --- linux-2.6.18/drivers/char/vt_ioctl.c        2006-09-19 23:42:06.000000000 -0400
8955 +++ linux-2.6.18/drivers/char/vt_ioctl.c        2006-09-22 20:04:35.000000000 -0400
8956 @@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
8957         case KDSKBENT:
8958                 if (!perm)
8959                         return -EPERM;
8960 +
8961 +#ifdef CONFIG_GRKERNSEC
8962 +               if (!capable(CAP_SYS_TTY_CONFIG))
8963 +                       return -EPERM;
8964 +#endif
8965 +
8966                 if (!i && v == K_NOSUCHMAP) {
8967                         /* disallocate map */
8968                         key_map = key_maps[s];
8969 @@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
8970                         goto reterr;
8971                 }
8972  
8973 +#ifdef CONFIG_GRKERNSEC
8974 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
8975 +                       ret = -EPERM;
8976 +                       goto reterr;
8977 +               }
8978 +#endif
8979 +
8980                 q = func_table[i];
8981                 first_free = funcbufptr + (funcbufsize - funcbufleft);
8982                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
8983 diff -urNp linux-2.6.18/drivers/edac/edac_mc.h linux-2.6.18/drivers/edac/edac_mc.h
8984 --- linux-2.6.18/drivers/edac/edac_mc.h 2006-09-19 23:42:06.000000000 -0400
8985 +++ linux-2.6.18/drivers/edac/edac_mc.h 2006-09-22 20:45:04.000000000 -0400
8986 @@ -71,11 +71,11 @@ extern int edac_debug_level;
8987  
8988  #else  /* !CONFIG_EDAC_DEBUG */
8989  
8990 -#define debugf0( ... )
8991 -#define debugf1( ... )
8992 -#define debugf2( ... )
8993 -#define debugf3( ... )
8994 -#define debugf4( ... )
8995 +#define debugf0( ... ) do {} while (0)
8996 +#define debugf1( ... ) do {} while (0)
8997 +#define debugf2( ... ) do {} while (0)
8998 +#define debugf3( ... ) do {} while (0)
8999 +#define debugf4( ... ) do {} while (0)
9000  
9001  #endif  /* !CONFIG_EDAC_DEBUG */
9002  
9003 diff -urNp linux-2.6.18/drivers/hwmon/fscpos.c linux-2.6.18/drivers/hwmon/fscpos.c
9004 --- linux-2.6.18/drivers/hwmon/fscpos.c 2006-09-19 23:42:06.000000000 -0400
9005 +++ linux-2.6.18/drivers/hwmon/fscpos.c 2006-09-22 20:45:04.000000000 -0400
9006 @@ -230,7 +230,6 @@ static ssize_t set_pwm(struct i2c_client
9007         unsigned long v = simple_strtoul(buf, NULL, 10);
9008  
9009         /* Range: 0..255 */
9010 -       if (v < 0) v = 0;
9011         if (v > 255) v = 255;
9012  
9013         mutex_lock(&data->update_lock);
9014 diff -urNp linux-2.6.18/drivers/hwmon/w83791d.c linux-2.6.18/drivers/hwmon/w83791d.c
9015 --- linux-2.6.18/drivers/hwmon/w83791d.c        2006-09-19 23:42:06.000000000 -0400
9016 +++ linux-2.6.18/drivers/hwmon/w83791d.c        2006-09-22 20:45:04.000000000 -0400
9017 @@ -290,8 +290,8 @@ static int w83791d_attach_adapter(struct
9018  static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
9019  static int w83791d_detach_client(struct i2c_client *client);
9020  
9021 -static int w83791d_read(struct i2c_client *client, u8 register);
9022 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
9023 +static int w83791d_read(struct i2c_client *client, u8 reg);
9024 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
9025  static struct w83791d_data *w83791d_update_device(struct device *dev);
9026  
9027  #ifdef DEBUG
9028 diff -urNp linux-2.6.18/drivers/ide/ide-cd.c linux-2.6.18/drivers/ide/ide-cd.c
9029 --- linux-2.6.18/drivers/ide/ide-cd.c   2006-09-19 23:42:06.000000000 -0400
9030 +++ linux-2.6.18/drivers/ide/ide-cd.c   2006-09-22 20:45:04.000000000 -0400
9031 @@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
9032                         sector &= ~(bio_sectors -1);
9033                         valid = (sector - failed_command->sector) << 9;
9034  
9035 -                       if (valid < 0)
9036 -                               valid = 0;
9037                         if (sector < get_capacity(info->disk) &&
9038                                 drive->probed_capacity - sector < 4 * 75) {
9039                                 set_capacity(info->disk, sector);
9040 diff -urNp linux-2.6.18/drivers/ieee1394/dv1394.c linux-2.6.18/drivers/ieee1394/dv1394.c
9041 --- linux-2.6.18/drivers/ieee1394/dv1394.c      2006-09-19 23:42:06.000000000 -0400
9042 +++ linux-2.6.18/drivers/ieee1394/dv1394.c      2006-09-22 20:45:04.000000000 -0400
9043 @@ -142,7 +142,7 @@
9044  #if DV1394_DEBUG_LEVEL >= 1
9045  #define debug_printk( args... ) printk( args)
9046  #else
9047 -#define debug_printk( args... )
9048 +#define debug_printk( args... ) do {} while (0)
9049  #endif
9050  
9051  /* issue a dummy PCI read to force the preceding write
9052 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
9053         based upon DIF section and sequence
9054  */
9055  
9056 -static void inline
9057 +static inline void
9058  frame_put_packet (struct frame *f, struct packet *p)
9059  {
9060         int section_type = p->data[0] >> 5;           /* section type is in bits 5 - 7 */
9061 @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
9062                 /* default SYT offset is 3 cycles */
9063                 init->syt_offset = 3;
9064  
9065 -       if ( (init->channel > 63) || (init->channel < 0) )
9066 +       if (init->channel > 63)
9067                 init->channel = 63;
9068  
9069         chan_mask = (u64)1 << init->channel;
9070 diff -urNp linux-2.6.18/drivers/ieee1394/hosts.c linux-2.6.18/drivers/ieee1394/hosts.c
9071 --- linux-2.6.18/drivers/ieee1394/hosts.c       2006-09-19 23:42:06.000000000 -0400
9072 +++ linux-2.6.18/drivers/ieee1394/hosts.c       2006-09-22 20:45:04.000000000 -0400
9073 @@ -75,6 +75,7 @@ static int dummy_isoctl(struct hpsb_iso 
9074  }
9075  
9076  static struct hpsb_host_driver dummy_driver = {
9077 +       .name =            "dummy",
9078         .transmit_packet = dummy_transmit_packet,
9079         .devctl =          dummy_devctl,
9080         .isoctl =          dummy_isoctl
9081 diff -urNp linux-2.6.18/drivers/ieee1394/ohci1394.c linux-2.6.18/drivers/ieee1394/ohci1394.c
9082 --- linux-2.6.18/drivers/ieee1394/ohci1394.c    2006-09-19 23:42:06.000000000 -0400
9083 +++ linux-2.6.18/drivers/ieee1394/ohci1394.c    2006-09-22 20:45:04.000000000 -0400
9084 @@ -136,7 +136,7 @@
9085  #define DBGMSG(fmt, args...) \
9086  printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
9087  #else
9088 -#define DBGMSG(fmt, args...)
9089 +#define DBGMSG(fmt, args...) do {} while (0)
9090  #endif
9091  
9092  #ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
9093 @@ -161,9 +161,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
9094  printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
9095  
9096  /* Module Parameters */
9097 -static int phys_dma = 1;
9098 +static int phys_dma = 0;
9099  module_param(phys_dma, int, 0444);
9100 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
9101 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
9102  
9103  static void dma_trm_tasklet(unsigned long data);
9104  static void dma_trm_reset(struct dma_trm_ctx *d);
9105 diff -urNp linux-2.6.18/drivers/ieee1394/video1394.c linux-2.6.18/drivers/ieee1394/video1394.c
9106 --- linux-2.6.18/drivers/ieee1394/video1394.c   2006-09-19 23:42:06.000000000 -0400
9107 +++ linux-2.6.18/drivers/ieee1394/video1394.c   2006-09-22 20:45:04.000000000 -0400
9108 @@ -890,7 +890,7 @@ static int __video1394_ioctl(struct file
9109                 d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
9110                 if (d == NULL) return -EFAULT;
9111  
9112 -               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
9113 +               if (v.buffer>=d->num_desc - 1) {
9114                         PRINT(KERN_ERR, ohci->host->id,
9115                               "Buffer %d out of range",v.buffer);
9116                         return -EINVAL;
9117 @@ -955,7 +955,7 @@ static int __video1394_ioctl(struct file
9118                 d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
9119                 if (d == NULL) return -EFAULT;
9120  
9121 -               if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) {
9122 +               if (v.buffer>d->num_desc - 1) {
9123                         PRINT(KERN_ERR, ohci->host->id,
9124                               "Buffer %d out of range",v.buffer);
9125                         return -EINVAL;
9126 @@ -1026,7 +1026,7 @@ static int __video1394_ioctl(struct file
9127                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
9128                 if (d == NULL) return -EFAULT;
9129  
9130 -               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
9131 +               if (v.buffer>=d->num_desc - 1) {
9132                         PRINT(KERN_ERR, ohci->host->id,
9133                               "Buffer %d out of range",v.buffer);
9134                         return -EINVAL;
9135 @@ -1128,7 +1128,7 @@ static int __video1394_ioctl(struct file
9136                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
9137                 if (d == NULL) return -EFAULT;
9138  
9139 -               if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
9140 +               if (v.buffer>=d->num_desc-1) {
9141                         PRINT(KERN_ERR, ohci->host->id,
9142                               "Buffer %d out of range",v.buffer);
9143                         return -EINVAL;
9144 diff -urNp linux-2.6.18/drivers/md/bitmap.c linux-2.6.18/drivers/md/bitmap.c
9145 --- linux-2.6.18/drivers/md/bitmap.c    2006-09-19 23:42:06.000000000 -0400
9146 +++ linux-2.6.18/drivers/md/bitmap.c    2006-09-22 20:45:04.000000000 -0400
9147 @@ -57,7 +57,7 @@
9148  #  if DEBUG > 0
9149  #    define PRINTK(x...) printk(KERN_DEBUG x)
9150  #  else
9151 -#    define PRINTK(x...)
9152 +#    define PRINTK(x...) do {} while (0)
9153  #  endif
9154  #endif
9155  
9156 diff -urNp linux-2.6.18/drivers/mtd/devices/doc2001.c linux-2.6.18/drivers/mtd/devices/doc2001.c
9157 --- linux-2.6.18/drivers/mtd/devices/doc2001.c  2006-09-19 23:42:06.000000000 -0400
9158 +++ linux-2.6.18/drivers/mtd/devices/doc2001.c  2006-09-22 20:04:35.000000000 -0400
9159 @@ -401,6 +401,8 @@ static int doc_read (struct mtd_info *mt
9160         /* Don't allow read past end of device */
9161         if (from >= this->totlen)
9162                 return -EINVAL;
9163 +       if (!len)
9164 +               return -EINVAL;
9165  
9166         /* Don't allow a single read to cross a 512-byte block boundary */
9167         if (from + len > ((from | 0x1ff) + 1))
9168 diff -urNp linux-2.6.18/drivers/net/eepro100.c linux-2.6.18/drivers/net/eepro100.c
9169 --- linux-2.6.18/drivers/net/eepro100.c 2006-09-19 23:42:06.000000000 -0400
9170 +++ linux-2.6.18/drivers/net/eepro100.c 2006-09-22 20:45:04.000000000 -0400
9171 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
9172  # define rx_align(skb)         skb_reserve((skb), 2)
9173  # define RxFD_ALIGNMENT                __attribute__ ((aligned (2), packed))
9174  #else
9175 -# define rx_align(skb)
9176 +# define rx_align(skb) do {} while (0)
9177  # define RxFD_ALIGNMENT
9178  #endif
9179  
9180 diff -urNp linux-2.6.18/drivers/net/pcnet32.c linux-2.6.18/drivers/net/pcnet32.c
9181 --- linux-2.6.18/drivers/net/pcnet32.c  2006-09-19 23:42:06.000000000 -0400
9182 +++ linux-2.6.18/drivers/net/pcnet32.c  2006-09-22 20:45:04.000000000 -0400
9183 @@ -78,7 +78,7 @@ static int cards_found;
9184  /*
9185   * VLB I/O addresses
9186   */
9187 -static unsigned int pcnet32_portlist[] __initdata =
9188 +static unsigned int pcnet32_portlist[] __devinitdata =
9189      { 0x300, 0x320, 0x340, 0x360, 0 };
9190  
9191  static int pcnet32_debug = 0;
9192 diff -urNp linux-2.6.18/drivers/pci/proc.c linux-2.6.18/drivers/pci/proc.c
9193 --- linux-2.6.18/drivers/pci/proc.c     2006-09-19 23:42:06.000000000 -0400
9194 +++ linux-2.6.18/drivers/pci/proc.c     2006-09-22 20:04:35.000000000 -0400
9195 @@ -467,7 +467,15 @@ static int __init pci_proc_init(void)
9196  {
9197         struct proc_dir_entry *entry;
9198         struct pci_dev *dev = NULL;
9199 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9200 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9201 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
9202 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
9203 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
9204 +#endif
9205 +#else
9206         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
9207 +#endif
9208         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
9209         if (entry)
9210                 entry->proc_fops = &proc_bus_pci_dev_operations;
9211 diff -urNp linux-2.6.18/drivers/pnp/pnpbios/bioscalls.c linux-2.6.18/drivers/pnp/pnpbios/bioscalls.c
9212 --- linux-2.6.18/drivers/pnp/pnpbios/bioscalls.c        2006-09-19 23:42:06.000000000 -0400
9213 +++ linux-2.6.18/drivers/pnp/pnpbios/bioscalls.c        2006-09-22 20:45:04.000000000 -0400
9214 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
9215  set_limit(gdt[(selname) >> 3], size); \
9216  } while(0)
9217  
9218 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
9219 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
9220  
9221  /*
9222   * At some point we want to use this stack frame pointer to unwind
9223 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
9224         struct desc_struct save_desc_40;
9225         int cpu;
9226  
9227 +#ifdef CONFIG_PAX_KERNEXEC
9228 +       unsigned long cr0;
9229 +#endif
9230 +
9231         /*
9232          * PnP BIOSes are generally not terribly re-entrant.
9233          * Also, don't rely on them to save everything correctly.
9234 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
9235         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
9236         spin_lock_irqsave(&pnp_bios_lock, flags);
9237  
9238 +#ifdef CONFIG_PAX_KERNEXEC
9239 +       pax_open_kernel(cr0);
9240 +#endif
9241 +
9242         /* The lock prevents us bouncing CPU here */
9243         if (ts1_size)
9244                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
9245 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
9246                   "i" (0)
9247                 : "memory"
9248         );
9249 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
9250  
9251         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
9252 +
9253 +#ifdef CONFIG_PAX_KERNEXEC
9254 +       pax_close_kernel(cr0);
9255 +#endif
9256 +
9257 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
9258         put_cpu();
9259  
9260         /* If we get here and this is set then the PnP BIOS faulted on us. */
9261 diff -urNp linux-2.6.18/drivers/pnp/resource.c linux-2.6.18/drivers/pnp/resource.c
9262 --- linux-2.6.18/drivers/pnp/resource.c 2006-09-19 23:42:06.000000000 -0400
9263 +++ linux-2.6.18/drivers/pnp/resource.c 2006-09-22 20:45:04.000000000 -0400
9264 @@ -364,7 +364,7 @@ int pnp_check_irq(struct pnp_dev * dev, 
9265                 return 1;
9266  
9267         /* check if the resource is valid */
9268 -       if (*irq < 0 || *irq > 15)
9269 +       if (*irq > 15)
9270                 return 0;
9271  
9272         /* check if the resource is reserved */
9273 @@ -430,7 +430,7 @@ int pnp_check_dma(struct pnp_dev * dev, 
9274                 return 1;
9275  
9276         /* check if the resource is valid */
9277 -       if (*dma < 0 || *dma == 4 || *dma > 7)
9278 +       if (*dma == 4 || *dma > 7)
9279                 return 0;
9280  
9281         /* check if the resource is reserved */
9282 diff -urNp linux-2.6.18/drivers/rtc/rtc-v3020.c linux-2.6.18/drivers/rtc/rtc-v3020.c
9283 --- linux-2.6.18/drivers/rtc/rtc-v3020.c        2006-09-19 23:42:06.000000000 -0400
9284 +++ linux-2.6.18/drivers/rtc/rtc-v3020.c        2006-09-22 20:45:04.000000000 -0400
9285 @@ -198,9 +198,9 @@ static int rtc_probe(struct platform_dev
9286          * are all disabled */
9287         v3020_set_reg(chip, V3020_STATUS_0, 0x0);
9288  
9289 -       dev_info(&pdev->dev, "Chip available at physical address 0x%p,"
9290 +       dev_info(&pdev->dev, "Chip available at physical address 0x%Lx,"
9291                 "data connected to D%d\n",
9292 -               (void*)pdev->resource[0].start,
9293 +               pdev->resource[0].start,
9294                 chip->leftshift);
9295  
9296         platform_set_drvdata(pdev, chip);
9297 diff -urNp linux-2.6.18/drivers/scsi/scsi_logging.h linux-2.6.18/drivers/scsi/scsi_logging.h
9298 --- linux-2.6.18/drivers/scsi/scsi_logging.h    2006-09-19 23:42:06.000000000 -0400
9299 +++ linux-2.6.18/drivers/scsi/scsi_logging.h    2006-09-22 20:45:04.000000000 -0400
9300 @@ -51,7 +51,7 @@ do {                                                          \
9301                 } while (0);                                    \
9302  } while (0)
9303  #else
9304 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
9305 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
9306  #endif /* CONFIG_SCSI_LOGGING */
9307  
9308  /*
9309 diff -urNp linux-2.6.18/drivers/usb/storage/debug.h linux-2.6.18/drivers/usb/storage/debug.h
9310 --- linux-2.6.18/drivers/usb/storage/debug.h    2006-09-19 23:42:06.000000000 -0400
9311 +++ linux-2.6.18/drivers/usb/storage/debug.h    2006-09-22 20:45:04.000000000 -0400
9312 @@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char 
9313  #define US_DEBUGPX(x...) printk( x )
9314  #define US_DEBUG(x) x 
9315  #else
9316 -#define US_DEBUGP(x...)
9317 -#define US_DEBUGPX(x...)
9318 -#define US_DEBUG(x)
9319 +#define US_DEBUGP(x...) do {} while (0)
9320 +#define US_DEBUGPX(x...) do {} while (0)
9321 +#define US_DEBUG(x) do {} while (0)
9322  #endif
9323  
9324  #endif
9325 diff -urNp linux-2.6.18/drivers/video/fbcmap.c linux-2.6.18/drivers/video/fbcmap.c
9326 --- linux-2.6.18/drivers/video/fbcmap.c 2006-09-19 23:42:06.000000000 -0400
9327 +++ linux-2.6.18/drivers/video/fbcmap.c 2006-09-22 20:45:04.000000000 -0400
9328 @@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
9329         int rc, size = cmap->len * sizeof(u16);
9330         struct fb_cmap umap;
9331  
9332 -       if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
9333 -                               !info->fbops->fb_setcmap))
9334 +       if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
9335                 return -EINVAL;
9336  
9337         memset(&umap, 0, sizeof(struct fb_cmap));
9338 diff -urNp linux-2.6.18/drivers/video/fbmem.c linux-2.6.18/drivers/video/fbmem.c
9339 --- linux-2.6.18/drivers/video/fbmem.c  2006-09-19 23:42:06.000000000 -0400
9340 +++ linux-2.6.18/drivers/video/fbmem.c  2006-09-22 20:45:04.000000000 -0400
9341 @@ -935,9 +935,9 @@ fb_ioctl(struct inode *inode, struct fil
9342         case FBIOPUT_CON2FBMAP:
9343                 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
9344                         return - EFAULT;
9345 -               if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
9346 +               if (con2fb.console > MAX_NR_CONSOLES)
9347                     return -EINVAL;
9348 -               if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
9349 +               if (con2fb.framebuffer >= FB_MAX)
9350                     return -EINVAL;
9351  #ifdef CONFIG_KMOD
9352                 if (!registered_fb[con2fb.framebuffer])
9353 diff -urNp linux-2.6.18/drivers/video/fbmon.c linux-2.6.18/drivers/video/fbmon.c
9354 --- linux-2.6.18/drivers/video/fbmon.c  2006-09-19 23:42:06.000000000 -0400
9355 +++ linux-2.6.18/drivers/video/fbmon.c  2006-09-22 20:45:04.000000000 -0400
9356 @@ -45,7 +45,7 @@
9357  #ifdef DEBUG
9358  #define DPRINTK(fmt, args...) printk(fmt,## args)
9359  #else
9360 -#define DPRINTK(fmt, args...)
9361 +#define DPRINTK(fmt, args...) do {} while (0)
9362  #endif
9363  
9364  #define FBMON_FIX_HEADER 1
9365 diff -urNp linux-2.6.18/drivers/video/i810/i810_main.c linux-2.6.18/drivers/video/i810/i810_main.c
9366 --- linux-2.6.18/drivers/video/i810/i810_main.c 2006-09-19 23:42:06.000000000 -0400
9367 +++ linux-2.6.18/drivers/video/i810/i810_main.c 2006-09-22 20:04:35.000000000 -0400
9368 @@ -1506,7 +1506,7 @@ static int i810fb_cursor(struct fb_info 
9369                 int size = ((cursor->image.width + 7) >> 3) *
9370                         cursor->image.height;
9371                 int i;
9372 -               u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
9373 +               u8 *data = kmalloc(64 * 8, GFP_KERNEL);
9374  
9375                 if (data == NULL)
9376                         return -ENOMEM;
9377 diff -urNp linux-2.6.18/drivers/video/vesafb.c linux-2.6.18/drivers/video/vesafb.c
9378 --- linux-2.6.18/drivers/video/vesafb.c 2006-09-19 23:42:06.000000000 -0400
9379 +++ linux-2.6.18/drivers/video/vesafb.c 2006-09-22 20:45:04.000000000 -0400
9380 @@ -267,7 +267,7 @@ static int __init vesafb_probe(struct pl
9381                 size_remap = size_total;
9382         vesafb_fix.smem_len = size_remap;
9383  
9384 -#ifndef __i386__
9385 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
9386         screen_info.vesapm_seg = 0;
9387  #endif
9388  
9389 diff -urNp linux-2.6.18/fs/binfmt_aout.c linux-2.6.18/fs/binfmt_aout.c
9390 --- linux-2.6.18/fs/binfmt_aout.c       2006-09-19 23:42:06.000000000 -0400
9391 +++ linux-2.6.18/fs/binfmt_aout.c       2006-09-22 20:45:04.000000000 -0400
9392 @@ -24,6 +24,7 @@
9393  #include <linux/personality.h>
9394  #include <linux/init.h>
9395  #include <linux/vs_memory.h>
9396 +#include <linux/grsecurity.h>
9397  
9398  #include <asm/system.h>
9399  #include <asm/uaccess.h>
9400 @@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
9401  /* If the size of the dump file exceeds the rlimit, then see what would happen
9402     if we wrote the stack, but not the data area.  */
9403  #ifdef __sparc__
9404 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
9405         if ((dump.u_dsize+dump.u_ssize) >
9406             current->signal->rlim[RLIMIT_CORE].rlim_cur)
9407                 dump.u_dsize = 0;
9408  #else
9409 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
9410         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
9411             current->signal->rlim[RLIMIT_CORE].rlim_cur)
9412                 dump.u_dsize = 0;
9413 @@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
9414  
9415  /* Make sure we have enough room to write the stack and data areas. */
9416  #ifdef __sparc__
9417 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
9418         if ((dump.u_ssize) >
9419             current->signal->rlim[RLIMIT_CORE].rlim_cur)
9420                 dump.u_ssize = 0;
9421  #else
9422 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
9423         if ((dump.u_ssize+1) * PAGE_SIZE >
9424             current->signal->rlim[RLIMIT_CORE].rlim_cur)
9425                 dump.u_ssize = 0;
9426 @@ -287,6 +292,8 @@ static int load_aout_binary(struct linux
9427         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
9428         if (rlim >= RLIM_INFINITY)
9429                 rlim = ~0;
9430 +
9431 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
9432         if (ex.a_data + ex.a_bss > rlim)
9433                 return -ENOMEM;
9434  
9435 @@ -319,6 +326,28 @@ static int load_aout_binary(struct linux
9436         current->mm->mmap = NULL;
9437         compute_creds(bprm);
9438         current->flags &= ~PF_FORKNOEXEC;
9439 +
9440 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9441 +       current->mm->pax_flags = 0UL;
9442 +#endif
9443 +
9444 +#ifdef CONFIG_PAX_PAGEEXEC
9445 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
9446 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
9447 +
9448 +#ifdef CONFIG_PAX_EMUTRAMP
9449 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
9450 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
9451 +#endif
9452 +
9453 +#ifdef CONFIG_PAX_MPROTECT
9454 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
9455 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
9456 +#endif
9457 +
9458 +       }
9459 +#endif
9460 +
9461  #ifdef __sparc__
9462         if (N_MAGIC(ex) == NMAGIC) {
9463                 loff_t pos = fd_offset;
9464 @@ -414,7 +443,7 @@ static int load_aout_binary(struct linux
9465  
9466                 down_write(&current->mm->mmap_sem);
9467                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
9468 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
9469 +                               PROT_READ | PROT_WRITE,
9470                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
9471                                 fd_offset + ex.a_text);
9472                 up_write(&current->mm->mmap_sem);
9473 diff -urNp linux-2.6.18/fs/binfmt_elf.c linux-2.6.18/fs/binfmt_elf.c
9474 --- linux-2.6.18/fs/binfmt_elf.c        2006-09-19 23:42:06.000000000 -0400
9475 +++ linux-2.6.18/fs/binfmt_elf.c        2006-09-22 20:45:04.000000000 -0400
9476 @@ -39,10 +39,16 @@
9477  #include <linux/elf.h>
9478  #include <linux/vs_memory.h>
9479  #include <linux/vs_cvirt.h>
9480 +#include <linux/grsecurity.h>
9481 +
9482  #include <asm/uaccess.h>
9483  #include <asm/param.h>
9484  #include <asm/page.h>
9485  
9486 +#ifdef CONFIG_PAX_SEGMEXEC
9487 +#include <asm/desc.h>
9488 +#endif
9489 +
9490  static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
9491  static int load_elf_library(struct file *);
9492  static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
9493 @@ -88,6 +94,8 @@ static struct linux_binfmt elf_format = 
9494  
9495  static int set_brk(unsigned long start, unsigned long end)
9496  {
9497 +       unsigned long e = end;
9498 +
9499         start = ELF_PAGEALIGN(start);
9500         end = ELF_PAGEALIGN(end);
9501         if (end > start) {
9502 @@ -98,7 +106,7 @@ static int set_brk(unsigned long start, 
9503                 if (BAD_ADDR(addr))
9504                         return addr;
9505         }
9506 -       current->mm->start_brk = current->mm->brk = end;
9507 +       current->mm->start_brk = current->mm->brk = e;
9508         return 0;
9509  }
9510  
9511 @@ -316,10 +324,9 @@ static unsigned long load_elf_interp(str
9512  {
9513         struct elf_phdr *elf_phdata;
9514         struct elf_phdr *eppnt;
9515 -       unsigned long load_addr = 0;
9516 -       int load_addr_set = 0;
9517 +       unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
9518         unsigned long last_bss = 0, elf_bss = 0;
9519 -       unsigned long error = ~0UL;
9520 +       unsigned long error = -EINVAL;
9521         int retval, i, size;
9522  
9523         /* First of all, some simple consistency checks */
9524 @@ -358,66 +365,86 @@ static unsigned long load_elf_interp(str
9525                 goto out_close;
9526         }
9527  
9528 +#ifdef CONFIG_PAX_SEGMEXEC
9529 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
9530 +               task_size = SEGMEXEC_TASK_SIZE;
9531 +#endif
9532 +
9533         eppnt = elf_phdata;
9534 +       min_addr = task_size;
9535 +       max_addr = 0;
9536 +       error = -ENOMEM;
9537 +
9538         for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
9539 -               if (eppnt->p_type == PT_LOAD) {
9540 -                       int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
9541 -                       int elf_prot = 0;
9542 -                       unsigned long vaddr = 0;
9543 -                       unsigned long k, map_addr;
9544 -
9545 -                       if (eppnt->p_flags & PF_R)
9546 -                               elf_prot = PROT_READ;
9547 -                       if (eppnt->p_flags & PF_W)
9548 -                               elf_prot |= PROT_WRITE;
9549 -                       if (eppnt->p_flags & PF_X)
9550 -                               elf_prot |= PROT_EXEC;
9551 -                       vaddr = eppnt->p_vaddr;
9552 -                       if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
9553 -                               elf_type |= MAP_FIXED;
9554 -
9555 -                       map_addr = elf_map(interpreter, load_addr + vaddr,
9556 -                                          eppnt, elf_prot, elf_type);
9557 -                       error = map_addr;
9558 -                       if (BAD_ADDR(map_addr))
9559 -                               goto out_close;
9560 -
9561 -                       if (!load_addr_set &&
9562 -                           interp_elf_ex->e_type == ET_DYN) {
9563 -                               load_addr = map_addr - ELF_PAGESTART(vaddr);
9564 -                               load_addr_set = 1;
9565 -                       }
9566 +               if (eppnt->p_type != PT_LOAD)
9567 +                       continue;
9568  
9569 -                       /*
9570 -                        * Check to see if the section's size will overflow the
9571 -                        * allowed task size. Note that p_filesz must always be
9572 -                        * <= p_memsize so it's only necessary to check p_memsz.
9573 -                        */
9574 -                       k = load_addr + eppnt->p_vaddr;
9575 -                       if (BAD_ADDR(k) ||
9576 -                           eppnt->p_filesz > eppnt->p_memsz ||
9577 -                           eppnt->p_memsz > TASK_SIZE ||
9578 -                           TASK_SIZE - eppnt->p_memsz < k) {
9579 -                               error = -ENOMEM;
9580 -                               goto out_close;
9581 -                       }
9582 +               /*
9583 +                * Check to see if the section's size will overflow the
9584 +                * allowed task size. Note that p_filesz must always be
9585 +                * <= p_memsize so it is only necessary to check p_memsz.
9586 +                */
9587 +               if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
9588 +                       goto out_close;
9589  
9590 -                       /*
9591 -                        * Find the end of the file mapping for this phdr, and
9592 -                        * keep track of the largest address we see for this.
9593 -                        */
9594 -                       k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
9595 -                       if (k > elf_bss)
9596 -                               elf_bss = k;
9597 +               if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
9598 +                       min_addr = ELF_PAGESTART(eppnt->p_vaddr);
9599 +               if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
9600 +                       max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
9601 +       }
9602 +       if (min_addr >= max_addr || max_addr > task_size)
9603 +               goto out_close;
9604  
9605 -                       /*
9606 -                        * Do the same thing for the memory mapping - between
9607 -                        * elf_bss and last_bss is the bss section.
9608 -                        */
9609 -                       k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
9610 -                       if (k > last_bss)
9611 -                               last_bss = k;
9612 -               }
9613 +       if (interp_elf_ex->e_type == ET_DYN) {
9614 +               load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
9615 +
9616 +               if (load_addr >= task_size)
9617 +                       goto out_close;
9618 +
9619 +               load_addr -= min_addr;
9620 +       }
9621 +
9622 +       eppnt = elf_phdata;
9623 +       for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
9624 +               int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
9625 +               int elf_prot = 0;
9626 +               unsigned long vaddr = 0;
9627 +               unsigned long k, map_addr;
9628 +
9629 +               if (eppnt->p_type != PT_LOAD)
9630 +                       continue;
9631 +
9632 +               if (eppnt->p_flags & PF_R)
9633 +                       elf_prot = PROT_READ;
9634 +               if (eppnt->p_flags & PF_W)
9635 +                       elf_prot |= PROT_WRITE;
9636 +               if (eppnt->p_flags & PF_X)
9637 +                       elf_prot |= PROT_EXEC;
9638 +               vaddr = eppnt->p_vaddr;
9639 +
9640 +               map_addr = elf_map(interpreter, load_addr + vaddr,
9641 +                                  eppnt, elf_prot, elf_type);
9642 +               error = map_addr;
9643 +               if (BAD_ADDR(map_addr))
9644 +                       goto out_close;
9645 +
9646 +               k = load_addr + eppnt->p_vaddr;
9647 +
9648 +               /*
9649 +                * Find the end of the file mapping for this phdr, and
9650 +                * keep track of the largest address we see for this.
9651 +                */
9652 +               k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
9653 +               if (k > elf_bss)
9654 +                       elf_bss = k;
9655 +
9656 +               /*
9657 +                * Do the same thing for the memory mapping - between
9658 +                * elf_bss and last_bss is the bss section.
9659 +                */
9660 +               k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
9661 +               if (k > last_bss)
9662 +                       last_bss = k;
9663         }
9664  
9665         /*
9666 @@ -445,6 +472,8 @@ static unsigned long load_elf_interp(str
9667  
9668         *interp_load_addr = load_addr;
9669         error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
9670 +       if (BAD_ADDR(error))
9671 +               error = -EFAULT;
9672  
9673  out_close:
9674         kfree(elf_phdata);
9675 @@ -455,7 +484,7 @@ out:
9676  static unsigned long load_aout_interp(struct exec *interp_ex,
9677                 struct file *interpreter)
9678  {
9679 -       unsigned long text_data, elf_entry = ~0UL;
9680 +       unsigned long text_data, elf_entry = -EINVAL;
9681         char __user * addr;
9682         loff_t offset;
9683  
9684 @@ -498,6 +527,180 @@ out:
9685         return elf_entry;
9686  }
9687  
9688 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
9689 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
9690 +{
9691 +       unsigned long pax_flags = 0UL;
9692 +
9693 +#ifdef CONFIG_PAX_PAGEEXEC
9694 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
9695 +               pax_flags |= MF_PAX_PAGEEXEC;
9696 +#endif
9697 +
9698 +#ifdef CONFIG_PAX_SEGMEXEC
9699 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
9700 +               pax_flags |= MF_PAX_SEGMEXEC;
9701 +#endif
9702 +
9703 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9704 +       if (pax_flags & MF_PAX_PAGEEXEC)
9705 +               pax_flags &= ~MF_PAX_SEGMEXEC;
9706 +#endif
9707 +
9708 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9709 +       if (pax_flags & MF_PAX_SEGMEXEC)
9710 +               pax_flags &= ~MF_PAX_PAGEEXEC;
9711 +#endif
9712 +
9713 +#ifdef CONFIG_PAX_EMUTRAMP
9714 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
9715 +               pax_flags |= MF_PAX_EMUTRAMP;
9716 +#endif
9717 +
9718 +#ifdef CONFIG_PAX_MPROTECT
9719 +       if (elf_phdata->p_flags & PF_MPROTECT)
9720 +               pax_flags |= MF_PAX_MPROTECT;
9721 +#endif
9722 +
9723 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
9724 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
9725 +               pax_flags |= MF_PAX_RANDMMAP;
9726 +#endif
9727 +
9728 +       return pax_flags;
9729 +}
9730 +#endif
9731 +
9732 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
9733 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
9734 +{
9735 +       unsigned long pax_flags = 0UL;
9736 +
9737 +#ifdef CONFIG_PAX_PAGEEXEC
9738 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
9739 +               pax_flags |= MF_PAX_PAGEEXEC;
9740 +#endif
9741 +
9742 +#ifdef CONFIG_PAX_SEGMEXEC
9743 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
9744 +               pax_flags |= MF_PAX_SEGMEXEC;
9745 +#endif
9746 +
9747 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9748 +       if (pax_flags & MF_PAX_PAGEEXEC)
9749 +               pax_flags &= ~MF_PAX_SEGMEXEC;
9750 +#endif
9751 +
9752 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9753 +       if (pax_flags & MF_PAX_SEGMEXEC)
9754 +               pax_flags &= ~MF_PAX_PAGEEXEC;
9755 +#endif
9756 +
9757 +#ifdef CONFIG_PAX_EMUTRAMP
9758 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
9759 +               pax_flags |= MF_PAX_EMUTRAMP;
9760 +#endif
9761 +
9762 +#ifdef CONFIG_PAX_MPROTECT
9763 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
9764 +               pax_flags |= MF_PAX_MPROTECT;
9765 +#endif
9766 +
9767 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
9768 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
9769 +               pax_flags |= MF_PAX_RANDMMAP;
9770 +#endif
9771 +
9772 +       return pax_flags;
9773 +}
9774 +#endif
9775 +
9776 +#ifdef CONFIG_PAX_EI_PAX
9777 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
9778 +{
9779 +       unsigned long pax_flags = 0UL;
9780 +
9781 +#ifdef CONFIG_PAX_PAGEEXEC
9782 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
9783 +               pax_flags |= MF_PAX_PAGEEXEC;
9784 +#endif
9785 +
9786 +#ifdef CONFIG_PAX_SEGMEXEC
9787 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
9788 +               pax_flags |= MF_PAX_SEGMEXEC;
9789 +#endif
9790 +
9791 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9792 +       if (pax_flags & MF_PAX_PAGEEXEC)
9793 +               pax_flags &= ~MF_PAX_SEGMEXEC;
9794 +#endif
9795 +
9796 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9797 +       if (pax_flags & MF_PAX_SEGMEXEC)
9798 +               pax_flags &= ~MF_PAX_PAGEEXEC;
9799 +#endif
9800 +
9801 +#ifdef CONFIG_PAX_EMUTRAMP
9802 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
9803 +               pax_flags |= MF_PAX_EMUTRAMP;
9804 +#endif
9805 +
9806 +#ifdef CONFIG_PAX_MPROTECT
9807 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
9808 +               pax_flags |= MF_PAX_MPROTECT;
9809 +#endif
9810 +
9811 +#ifdef CONFIG_PAX_ASLR
9812 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
9813 +               pax_flags |= MF_PAX_RANDMMAP;
9814 +#endif
9815 +
9816 +       return pax_flags;
9817 +}
9818 +#endif
9819 +
9820 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
9821 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
9822 +{
9823 +       unsigned long pax_flags = 0UL;
9824 +
9825 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
9826 +       unsigned long i;
9827 +#endif
9828 +
9829 +#ifdef CONFIG_PAX_EI_PAX
9830 +       pax_flags = pax_parse_ei_pax(elf_ex);
9831 +#endif
9832 +
9833 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
9834 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
9835 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
9836 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
9837 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
9838 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
9839 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
9840 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
9841 +                               return -EINVAL;
9842 +
9843 +#ifdef CONFIG_PAX_SOFTMODE
9844 +                       if (pax_softmode)
9845 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
9846 +                       else
9847 +#endif
9848 +
9849 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
9850 +                       break;
9851 +               }
9852 +#endif
9853 +
9854 +       if (0 > pax_check_flags(&pax_flags))
9855 +               return -EINVAL;
9856 +
9857 +       current->mm->pax_flags = pax_flags;
9858 +       return 0;
9859 +}
9860 +#endif
9861 +
9862  /*
9863   * These are the functions used to load ELF style executables and shared
9864   * libraries.  There is no binary dependent code anywhere else.
9865 @@ -534,7 +737,7 @@ static int load_elf_binary(struct linux_
9866         char * elf_interpreter = NULL;
9867         unsigned int interpreter_type = INTERPRETER_NONE;
9868         unsigned char ibcs2_interpreter = 0;
9869 -       unsigned long error;
9870 +       unsigned long error = 0;
9871         struct elf_phdr *elf_ppnt, *elf_phdata;
9872         unsigned long elf_bss, elf_brk;
9873         int elf_exec_fileno;
9874 @@ -552,6 +755,7 @@ static int load_elf_binary(struct linux_
9875                 struct elfhdr interp_elf_ex;
9876                 struct exec interp_ex;
9877         } *loc;
9878 +       unsigned long task_size = TASK_SIZE;
9879  
9880         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
9881         if (!loc) {
9882 @@ -774,14 +978,88 @@ static int load_elf_binary(struct linux_
9883         current->mm->end_code = 0;
9884         current->mm->mmap = NULL;
9885         current->flags &= ~PF_FORKNOEXEC;
9886 +
9887 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9888 +       current->mm->pax_flags = 0UL;
9889 +#endif
9890 +
9891 +#ifdef CONFIG_PAX_DLRESOLVE
9892 +       current->mm->call_dl_resolve = 0UL;
9893 +#endif
9894 +
9895 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
9896 +       current->mm->call_syscall = 0UL;
9897 +#endif
9898 +
9899 +#ifdef CONFIG_PAX_ASLR
9900 +       current->mm->delta_mmap = 0UL;
9901 +       current->mm->delta_exec = 0UL;
9902 +       current->mm->delta_stack = 0UL;
9903 +#endif
9904 +
9905         current->mm->def_flags = def_flags;
9906  
9907 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
9908 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
9909 +               send_sig(SIGKILL, current, 0);
9910 +               goto out_free_dentry;
9911 +       }
9912 +#endif
9913 +
9914 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
9915 +       pax_set_initial_flags(bprm);
9916 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
9917 +       if (pax_set_initial_flags_func)
9918 +               (pax_set_initial_flags_func)(bprm);
9919 +#endif
9920 +
9921 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
9922 +       if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
9923 +               current->mm->context.user_cs_limit = PAGE_SIZE;
9924 +#endif
9925 +
9926 +#ifdef CONFIG_PAX_SEGMEXEC
9927 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
9928 +               int cpu = get_cpu();
9929 +
9930 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
9931 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
9932 +               set_user_cs(current->mm, cpu);
9933 +               put_cpu();
9934 +               task_size = SEGMEXEC_TASK_SIZE;
9935 +       }
9936 +#endif
9937 +
9938 +#ifdef CONFIG_PAX_ASLR
9939 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
9940 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
9941 +
9942 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
9943 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
9944 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
9945 +       }
9946 +#endif
9947 +
9948 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
9949 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
9950 +               executable_stack = EXSTACK_DEFAULT;
9951 +#endif
9952 +
9953         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
9954            may depend on the personality.  */
9955         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
9956 +
9957 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
9958 +       if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
9959 +#endif
9960 +
9961         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
9962                 current->personality |= READ_IMPLIES_EXEC;
9963  
9964 +#ifdef CONFIG_PAX_ASLR
9965 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
9966 +#endif
9967 +
9968         if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
9969                 current->flags |= PF_RANDOMIZE;
9970         arch_pick_mmap_layout(current->mm);
9971 @@ -857,6 +1135,15 @@ static int load_elf_binary(struct linux_
9972                          * might try to exec.  This is because the brk will
9973                          * follow the loader, and is not movable.  */
9974                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
9975 +
9976 +#ifdef CONFIG_PAX_RANDMMAP
9977 +                       /* PaX: randomize base address at the default exe base if requested */
9978 +                       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
9979 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
9980 +                               elf_flags |= MAP_FIXED;
9981 +                       }
9982 +#endif
9983 +
9984                 }
9985  
9986                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
9987 @@ -887,9 +1174,9 @@ static int load_elf_binary(struct linux_
9988                  * allowed task size. Note that p_filesz must always be
9989                  * <= p_memsz so it is only necessary to check p_memsz.
9990                  */
9991 -               if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
9992 -                   elf_ppnt->p_memsz > TASK_SIZE ||
9993 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
9994 +               if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
9995 +                   elf_ppnt->p_memsz > task_size ||
9996 +                   task_size - elf_ppnt->p_memsz < k) {
9997                         /* set_brk can never work. Avoid overflows. */
9998                         send_sig(SIGKILL, current, 0);
9999                         goto out_free_dentry;
10000 @@ -916,6 +1203,12 @@ static int load_elf_binary(struct linux_
10001         start_data += load_bias;
10002         end_data += load_bias;
10003  
10004 +#ifdef CONFIG_PAX_RANDMMAP
10005 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP)
10006 +               elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
10007 +#undef pax_delta_mask
10008 +#endif
10009 +
10010         /* Calling set_brk effectively mmaps the pages that we need
10011          * for the bss and break sections.  We must do this before
10012          * mapping in the interpreter, to make sure it doesn't wind
10013 @@ -1168,7 +1461,7 @@ static int dump_seek(struct file *file, 
10014   *
10015   * I think we should skip something. But I am not sure how. H.J.
10016   */
10017 -static int maydump(struct vm_area_struct *vma)
10018 +static int maydump(struct vm_area_struct *vma, long signr)
10019  {
10020         /* Do not dump I/O mapped devices or special mappings */
10021         if (vma->vm_flags & (VM_IO | VM_RESERVED))
10022 @@ -1179,7 +1472,7 @@ static int maydump(struct vm_area_struct
10023                 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
10024  
10025         /* If it hasn't been written to, don't write it out */
10026 -       if (!vma->anon_vma)
10027 +       if (signr != SIGKILL && !vma->anon_vma)
10028                 return 0;
10029  
10030         return 1;
10031 @@ -1231,8 +1524,11 @@ static int writenote(struct memelfnote *
10032  #undef DUMP_SEEK
10033  
10034  #define DUMP_WRITE(addr, nr)   \
10035 +       do { \
10036 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
10037         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
10038 -               goto end_coredump;
10039 +               goto end_coredump; \
10040 +       } while (0);
10041  #define DUMP_SEEK(off) \
10042         if (!dump_seek(file, (off))) \
10043                 goto end_coredump;
10044 @@ -1586,7 +1882,7 @@ static int elf_core_dump(long signr, str
10045                 phdr.p_offset = offset;
10046                 phdr.p_vaddr = vma->vm_start;
10047                 phdr.p_paddr = 0;
10048 -               phdr.p_filesz = maydump(vma) ? sz : 0;
10049 +               phdr.p_filesz = maydump(vma, signr) ? sz : 0;
10050                 phdr.p_memsz = sz;
10051                 offset += phdr.p_filesz;
10052                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
10053 @@ -1623,7 +1919,7 @@ static int elf_core_dump(long signr, str
10054         for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
10055                 unsigned long addr;
10056  
10057 -               if (!maydump(vma))
10058 +               if (!maydump(vma, signr))
10059                         continue;
10060  
10061                 for (addr = vma->vm_start;
10062 @@ -1643,6 +1939,7 @@ static int elf_core_dump(long signr, str
10063                                         flush_cache_page(vma, addr,
10064                                                          page_to_pfn(page));
10065                                         kaddr = kmap(page);
10066 +                                       gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
10067                                         if ((size += PAGE_SIZE) > limit ||
10068                                             !dump_write(file, kaddr,
10069                                             PAGE_SIZE)) {
10070 diff -urNp linux-2.6.18/fs/binfmt_flat.c linux-2.6.18/fs/binfmt_flat.c
10071 --- linux-2.6.18/fs/binfmt_flat.c       2006-09-19 23:42:06.000000000 -0400
10072 +++ linux-2.6.18/fs/binfmt_flat.c       2006-09-22 20:45:04.000000000 -0400
10073 @@ -551,7 +551,9 @@ static int load_flat_file(struct linux_b
10074                                 realdatastart = (unsigned long) -ENOMEM;
10075                         printk("Unable to allocate RAM for process data, errno %d\n",
10076                                         (int)-datapos);
10077 +                       down_write(&current->mm->mmap_sem);
10078                         do_munmap(current->mm, textpos, text_len);
10079 +                       up_write(&current->mm->mmap_sem);
10080                         ret = realdatastart;
10081                         goto err;
10082                 }
10083 @@ -573,8 +575,10 @@ static int load_flat_file(struct linux_b
10084                 }
10085                 if (result >= (unsigned long)-4096) {
10086                         printk("Unable to read data+bss, errno %d\n", (int)-result);
10087 +                       down_write(&current->mm->mmap_sem);
10088                         do_munmap(current->mm, textpos, text_len);
10089                         do_munmap(current->mm, realdatastart, data_len + extra);
10090 +                       up_write(&current->mm->mmap_sem);
10091                         ret = result;
10092                         goto err;
10093                 }
10094 @@ -638,8 +642,10 @@ static int load_flat_file(struct linux_b
10095                 }
10096                 if (result >= (unsigned long)-4096) {
10097                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
10098 +                       down_write(&current->mm->mmap_sem);
10099                         do_munmap(current->mm, textpos, text_len + data_len + extra +
10100                                 MAX_SHARED_LIBS * sizeof(unsigned long));
10101 +                       up_write(&current->mm->mmap_sem);
10102                         ret = result;
10103                         goto err;
10104                 }
10105 diff -urNp linux-2.6.18/fs/binfmt_misc.c linux-2.6.18/fs/binfmt_misc.c
10106 --- linux-2.6.18/fs/binfmt_misc.c       2006-09-19 23:42:06.000000000 -0400
10107 +++ linux-2.6.18/fs/binfmt_misc.c       2006-09-22 20:45:04.000000000 -0400
10108 @@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
10109         struct files_struct *files = NULL;
10110  
10111         retval = -ENOEXEC;
10112 -       if (!enabled)
10113 +       if (!enabled || bprm->misc)
10114                 goto _ret;
10115  
10116 +       bprm->misc++;
10117 +
10118         /* to keep locking time low, we copy the interpreter string */
10119         read_lock(&entries_lock);
10120         fmt = check_file(bprm);
10121 diff -urNp linux-2.6.18/fs/buffer.c linux-2.6.18/fs/buffer.c
10122 --- linux-2.6.18/fs/buffer.c    2006-09-19 23:42:06.000000000 -0400
10123 +++ linux-2.6.18/fs/buffer.c    2006-09-22 20:04:35.000000000 -0400
10124 @@ -41,6 +41,7 @@
10125  #include <linux/bitops.h>
10126  #include <linux/mpage.h>
10127  #include <linux/bit_spinlock.h>
10128 +#include <linux/grsecurity.h>
10129  
10130  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
10131  static void invalidate_bh_lrus(void);
10132 @@ -2164,6 +2165,7 @@ static int __generic_cont_expand(struct 
10133  
10134         err = -EFBIG;
10135          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
10136 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
10137         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
10138                 send_sig(SIGXFSZ, current, 0);
10139                 goto out;
10140 diff -urNp linux-2.6.18/fs/cifs/smbdes.c linux-2.6.18/fs/cifs/smbdes.c
10141 --- linux-2.6.18/fs/cifs/smbdes.c       2006-09-19 23:42:06.000000000 -0400
10142 +++ linux-2.6.18/fs/cifs/smbdes.c       2006-09-22 20:45:04.000000000 -0400
10143 @@ -196,15 +196,18 @@ dohash(char *out, char *in, char *key, i
10144         char c[28];
10145         char d[28];
10146         char *cd;
10147 -       char ki[16][48];
10148 +       char *ki;
10149         char *pd1;
10150         char l[32], r[32];
10151         char *rl;
10152 +       char *er;  /* er[48]  */
10153  
10154         /* Have to reduce stack usage */
10155 -       pk1 = kmalloc(56+56+64+64,GFP_KERNEL);
10156 -       if(pk1 == NULL)
10157 -               return;
10158 +       pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
10159 +       ki = kmalloc(16*48, GFP_KERNEL);
10160 +       er = kmalloc(48+48+32+32+32, GFP_KERNEL);
10161 +       if (!pk1 || !ki || !er)
10162 +               goto free;
10163  
10164         cd = pk1 + 56;
10165         pd1= cd  + 56;
10166 @@ -222,7 +225,7 @@ dohash(char *out, char *in, char *key, i
10167                 lshift(d, sc[i], 28);
10168  
10169                 concat(cd, c, d, 28, 28);
10170 -               permute(ki[i], cd, perm2, 48);
10171 +               permute(ki+48*i, cd, perm2, 48);
10172         }
10173  
10174         permute(pd1, in, perm3, 64);
10175 @@ -233,18 +236,12 @@ dohash(char *out, char *in, char *key, i
10176         }
10177  
10178         for (i = 0; i < 16; i++) {
10179 -               char *er;  /* er[48]  */
10180                 char *erk; /* erk[48] */
10181                 char b[8][6];
10182                 char *cb;  /* cb[32]  */
10183                 char *pcb; /* pcb[32] */
10184                 char *r2;  /* r2[32]  */
10185  
10186 -               er = kmalloc(48+48+32+32+32, GFP_KERNEL);
10187 -               if(er == NULL) {
10188 -                       kfree(pk1);
10189 -                       return;
10190 -               }
10191                 erk = er+48;
10192                 cb  = erk+48;
10193                 pcb = cb+32;
10194 @@ -252,7 +249,7 @@ dohash(char *out, char *in, char *key, i
10195  
10196                 permute(er, r, perm4, 48);
10197  
10198 -               xor(erk, er, ki[forw ? i : 15 - i], 48);
10199 +               xor(erk, er, ki+48*(forw ? i : 15 - i), 48);
10200  
10201                 for (j = 0; j < 8; j++)
10202                         for (k = 0; k < 6; k++)
10203 @@ -282,13 +279,15 @@ dohash(char *out, char *in, char *key, i
10204  
10205                 for (j = 0; j < 32; j++)
10206                         r[j] = r2[j];
10207 -
10208 -               kfree(er);
10209         }
10210  
10211         concat(rl, r, l, 32, 32);
10212  
10213         permute(out, rl, perm6, 64);
10214 +
10215 +free:
10216 +       kfree(er);
10217 +       kfree(ki);
10218         kfree(pk1);
10219  }
10220  
10221 diff -urNp linux-2.6.18/fs/compat.c linux-2.6.18/fs/compat.c
10222 --- linux-2.6.18/fs/compat.c    2006-09-19 23:42:06.000000000 -0400
10223 +++ linux-2.6.18/fs/compat.c    2006-09-22 20:04:35.000000000 -0400
10224 @@ -46,6 +46,7 @@
10225  #include <linux/rwsem.h>
10226  #include <linux/acct.h>
10227  #include <linux/mm.h>
10228 +#include <linux/grsecurity.h>
10229  
10230  #include <net/sock.h>          /* siocdevprivate_ioctl */
10231  
10232 @@ -1512,6 +1513,11 @@ int compat_do_execve(char * filename,
10233         struct file *file;
10234         int retval;
10235         int i;
10236 +#ifdef CONFIG_GRKERNSEC
10237 +       struct file *old_exec_file;
10238 +       struct acl_subject_label *old_acl;
10239 +       struct rlimit old_rlim[RLIM_NLIMITS];
10240 +#endif
10241  
10242         retval = -ENOMEM;
10243         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
10244 @@ -1529,6 +1535,15 @@ int compat_do_execve(char * filename,
10245         bprm->file = file;
10246         bprm->filename = filename;
10247         bprm->interp = filename;
10248 +
10249 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
10250 +       retval = -EAGAIN;
10251 +       if (gr_handle_nproc())
10252 +               goto out_file;
10253 +       retval = -EACCES;
10254 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
10255 +               goto out_file;
10256 +
10257         bprm->mm = mm_alloc();
10258         retval = -ENOMEM;
10259         if (!bprm->mm)
10260 @@ -1567,10 +1582,39 @@ int compat_do_execve(char * filename,
10261         if (retval < 0)
10262                 goto out;
10263  
10264 +       if (!gr_tpe_allow(file)) {
10265 +               retval = -EACCES;
10266 +               goto out;
10267 +       }
10268 +
10269 +       if (gr_check_crash_exec(file)) {
10270 +               retval = -EACCES;
10271 +               goto out;
10272 +       }
10273 +
10274 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
10275 +
10276 +       gr_handle_exec_args(bprm, (char __user * __user *)argv);
10277 +
10278 +#ifdef CONFIG_GRKERNSEC
10279 +       old_acl = current->acl;
10280 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
10281 +       old_exec_file = current->exec_file;
10282 +       get_file(file);
10283 +       current->exec_file = file;
10284 +#endif
10285 +
10286 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
10287 +
10288         retval = search_binary_handler(bprm, regs);
10289         if (retval >= 0) {
10290                 free_arg_pages(bprm);
10291  
10292 +#ifdef CONFIG_GRKERNSEC
10293 +               if (old_exec_file)
10294 +                       fput(old_exec_file);
10295 +#endif
10296 +
10297                 /* execve success */
10298                 security_bprm_free(bprm);
10299                 acct_update_integrals(current);
10300 @@ -1578,6 +1622,13 @@ int compat_do_execve(char * filename,
10301                 return retval;
10302         }
10303  
10304 +#ifdef CONFIG_GRKERNSEC
10305 +       current->acl = old_acl;
10306 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
10307 +       fput(current->exec_file);
10308 +       current->exec_file = old_exec_file;
10309 +#endif
10310 +
10311  out:
10312         /* Something went wrong, return the inode and free the argument pages*/
10313         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10314 diff -urNp linux-2.6.18/fs/dcache.c linux-2.6.18/fs/dcache.c
10315 --- linux-2.6.18/fs/dcache.c    2006-09-19 23:42:06.000000000 -0400
10316 +++ linux-2.6.18/fs/dcache.c    2006-09-22 20:04:35.000000000 -0400
10317 @@ -1402,7 +1402,7 @@ already_unhashed:
10318   *
10319   * "buflen" should be positive. Caller holds the dcache_lock.
10320   */
10321 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
10322 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
10323                         struct dentry *root, struct vfsmount *rootmnt,
10324                         char *buffer, int buflen)
10325  {
10326 diff -urNp linux-2.6.18/fs/exec.c linux-2.6.18/fs/exec.c
10327 --- linux-2.6.18/fs/exec.c      2006-09-19 23:42:06.000000000 -0400
10328 +++ linux-2.6.18/fs/exec.c      2006-09-22 22:13:47.000000000 -0400
10329 @@ -49,6 +49,8 @@
10330  #include <linux/audit.h>
10331  #include <linux/vs_memory.h>
10332  #include <linux/vs_cvirt.h>
10333 +#include <linux/random.h>
10334 +#include <linux/grsecurity.h>
10335  
10336  #include <asm/uaccess.h>
10337  #include <asm/mmu_context.h>
10338 @@ -67,6 +69,15 @@ EXPORT_SYMBOL(suid_dumpable);
10339  static struct linux_binfmt *formats;
10340  static DEFINE_RWLOCK(binfmt_lock);
10341  
10342 +#ifdef CONFIG_PAX_SOFTMODE
10343 +unsigned int pax_softmode;
10344 +#endif
10345 +
10346 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
10347 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
10348 +EXPORT_SYMBOL(pax_set_initial_flags_func);
10349 +#endif
10350 +
10351  int register_binfmt(struct linux_binfmt * fmt)
10352  {
10353         struct linux_binfmt ** tmp = &formats;
10354 @@ -312,6 +323,10 @@ void install_arg_page(struct vm_area_str
10355         if (unlikely(anon_vma_prepare(vma)))
10356                 goto out;
10357  
10358 +#ifdef CONFIG_PAX_SEGMEXEC
10359 +       if (page_count(page) == 1)
10360 +#endif
10361 +
10362         flush_dcache_page(page);
10363         pte = get_locked_pte(mm, address, &ptl);
10364         if (!pte)
10365 @@ -321,9 +336,21 @@ void install_arg_page(struct vm_area_str
10366                 goto out;
10367         }
10368         inc_mm_counter(mm, anon_rss);
10369 +
10370 +#ifdef CONFIG_PAX_SEGMEXEC
10371 +       if (page_count(page) == 1)
10372 +#endif
10373 +
10374         lru_cache_add_active(page);
10375         set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
10376                                         page, vma->vm_page_prot))));
10377 +
10378 +#ifdef CONFIG_PAX_SEGMEXEC
10379 +       if (page_count(page) != 1)
10380 +               page_add_anon_rmap(page, vma, address);
10381 +       else
10382 +#endif
10383 +
10384         page_add_new_anon_rmap(page, vma, address);
10385         pte_unmap_unlock(pte, ptl);
10386  
10387 @@ -346,6 +373,10 @@ int setup_arg_pages(struct linux_binprm 
10388         int i, ret;
10389         long arg_size;
10390  
10391 +#ifdef CONFIG_PAX_SEGMEXEC
10392 +       struct vm_area_struct *mpnt_m = NULL;
10393 +#endif
10394 +
10395  #ifdef CONFIG_STACK_GROWSUP
10396         /* Move the argument and environment strings to the bottom of the
10397          * stack space.
10398 @@ -404,11 +435,19 @@ int setup_arg_pages(struct linux_binprm 
10399                 bprm->loader += stack_base;
10400         bprm->exec += stack_base;
10401  
10402 -       mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
10403 +       mpnt = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
10404         if (!mpnt)
10405                 return -ENOMEM;
10406  
10407 -       memset(mpnt, 0, sizeof(*mpnt));
10408 +#ifdef CONFIG_PAX_SEGMEXEC
10409 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
10410 +               mpnt_m = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
10411 +               if (!mpnt_m) {
10412 +                       kmem_cache_free(vm_area_cachep, mpnt);
10413 +                       return -ENOMEM;
10414 +               }
10415 +       }
10416 +#endif
10417  
10418         down_write(&mm->mmap_sem);
10419         {
10420 @@ -430,14 +469,51 @@ int setup_arg_pages(struct linux_binprm 
10421                 else
10422                         mpnt->vm_flags = VM_STACK_FLAGS;
10423                 mpnt->vm_flags |= mm->def_flags;
10424 -               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
10425 +
10426 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
10427 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
10428 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
10429 +               else
10430 +#endif
10431 +
10432 +               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
10433                 if ((ret = insert_vm_struct(mm, mpnt))) {
10434                         up_write(&mm->mmap_sem);
10435                         kmem_cache_free(vm_area_cachep, mpnt);
10436 +
10437 +#ifdef CONFIG_PAX_SEGMEXEC
10438 +                       if (mpnt_m)
10439 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
10440 +#endif
10441 +
10442                         return ret;
10443                 }
10444                 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
10445                 mm->stack_vm = mm->total_vm;
10446 +
10447 +#ifdef CONFIG_PAX_SEGMEXEC
10448 +               if (mpnt_m) {
10449 +                       *mpnt_m = *mpnt;
10450 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
10451 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
10452 +                               mpnt_m->vm_page_prot = PAGE_NONE;
10453 +                       }
10454 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
10455 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
10456 +                       if ((ret = insert_vm_struct(mm, mpnt_m))) {
10457 +                               up_write(&mm->mmap_sem);
10458 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
10459 +                               return ret;
10460 +                       }
10461 +                       mpnt_m->vm_flags |= VM_MIRROR;
10462 +                       mpnt->vm_flags |= VM_MIRROR;
10463 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
10464 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
10465 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
10466 +                       mm->total_vm += vma_pages(mpnt_m);
10467 +               }
10468 +#endif
10469 +
10470         }
10471  
10472         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10473 @@ -444,6 +520,14 @@ int setup_arg_pages(struct linux_binprm 
10474                 if (page) {
10475                         bprm->page[i] = NULL;
10476                         install_arg_page(mpnt, page, stack_base);
10477 +
10478 +#ifdef CONFIG_PAX_SEGMEXEC
10479 +                       if (mpnt_m) {
10480 +                               page_cache_get(page);
10481 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
10482 +                       }
10483 +#endif
10484 +
10485                 }
10486                 stack_base += PAGE_SIZE;
10487         }
10488 @@ -1132,6 +1216,11 @@ int do_execve(char * filename,
10489         struct file *file;
10490         int retval;
10491         int i;
10492 +#ifdef CONFIG_GRKERNSEC
10493 +       struct file *old_exec_file;
10494 +       struct acl_subject_label *old_acl;
10495 +       struct rlimit old_rlim[RLIM_NLIMITS];
10496 +#endif
10497  
10498         retval = -ENOMEM;
10499         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
10500 @@ -1143,10 +1232,29 @@ int do_execve(char * filename,
10501         if (IS_ERR(file))
10502                 goto out_kfree;
10503  
10504 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
10505 +
10506 +       if (gr_handle_nproc()) {
10507 +               allow_write_access(file);
10508 +               fput(file);
10509 +               return -EAGAIN;
10510 +       }
10511 +
10512 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
10513 +               allow_write_access(file);
10514 +               fput(file);
10515 +               return -EACCES;
10516 +       }
10517 +
10518         sched_exec();
10519  
10520         bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
10521  
10522 +#ifdef CONFIG_PAX_RANDUSTACK
10523 +       if (randomize_va_space)
10524 +               bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
10525 +#endif
10526 +
10527         bprm->file = file;
10528         bprm->filename = filename;
10529         bprm->interp = filename;
10530 @@ -1188,8 +1296,38 @@ int do_execve(char * filename,
10531         if (retval < 0)
10532                 goto out;
10533  
10534 +       if (!gr_tpe_allow(file)) {
10535 +               retval = -EACCES;
10536 +               goto out;
10537 +       }
10538 +
10539 +       if (gr_check_crash_exec(file)) {
10540 +               retval = -EACCES;
10541 +               goto out;
10542 +       }
10543 +
10544 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
10545 +
10546 +       gr_handle_exec_args(bprm, argv);
10547 +
10548 +#ifdef CONFIG_GRKERNSEC
10549 +       old_acl = current->acl;
10550 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
10551 +       old_exec_file = current->exec_file;
10552 +       get_file(file);
10553 +       current->exec_file = file;
10554 +#endif
10555 +
10556 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
10557 +       if (retval < 0)
10558 +               goto out_fail;
10559 +
10560         retval = search_binary_handler(bprm,regs);
10561         if (retval >= 0) {
10562 +#ifdef CONFIG_GRKERNSEC
10563 +               if (old_exec_file)
10564 +                       fput(old_exec_file);
10565 +#endif
10566                 free_arg_pages(bprm);
10567  
10568                 /* execve success */
10569 @@ -1199,6 +1337,14 @@ int do_execve(char * filename,
10570                 return retval;
10571         }
10572  
10573 +out_fail:
10574 +#ifdef CONFIG_GRKERNSEC
10575 +       current->acl = old_acl;
10576 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
10577 +       fput(current->exec_file);
10578 +       current->exec_file = old_exec_file;
10579 +#endif
10580 +
10581  out:
10582         /* Something went wrong, return the inode and free the argument pages*/
10583         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10584 @@ -1359,6 +1505,114 @@ static void format_corename(char *corena
10585         *out_ptr = 0;
10586  }
10587  
10588 +int pax_check_flags(unsigned long * flags)
10589 +{
10590 +       int retval = 0;
10591 +
10592 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
10593 +       if (*flags & MF_PAX_SEGMEXEC)
10594 +       {
10595 +               *flags &= ~MF_PAX_SEGMEXEC;
10596 +               retval = -EINVAL;
10597 +       }
10598 +#endif
10599 +
10600 +       if ((*flags & MF_PAX_PAGEEXEC)
10601 +
10602 +#ifdef CONFIG_PAX_PAGEEXEC
10603 +           &&  (*flags & MF_PAX_SEGMEXEC)
10604 +#endif
10605 +
10606 +          )
10607 +       {
10608 +               *flags &= ~MF_PAX_PAGEEXEC;
10609 +               retval = -EINVAL;
10610 +       }
10611 +
10612 +       if ((*flags & MF_PAX_MPROTECT)
10613 +
10614 +#ifdef CONFIG_PAX_MPROTECT
10615 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
10616 +#endif
10617 +
10618 +          )
10619 +       {
10620 +               *flags &= ~MF_PAX_MPROTECT;
10621 +               retval = -EINVAL;
10622 +       }
10623 +
10624 +       if ((*flags & MF_PAX_EMUTRAMP)
10625 +
10626 +#ifdef CONFIG_PAX_EMUTRAMP
10627 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
10628 +#endif
10629 +
10630 +          )
10631 +       {
10632 +               *flags &= ~MF_PAX_EMUTRAMP;
10633 +               retval = -EINVAL;
10634 +       }
10635 +
10636 +       return retval;
10637 +}
10638 +
10639 +EXPORT_SYMBOL(pax_check_flags);
10640 +
10641 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10642 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
10643 +{
10644 +       struct task_struct *tsk = current;
10645 +       struct mm_struct *mm = current->mm;
10646 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
10647 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
10648 +       char* path_exec=NULL;
10649 +       char* path_fault=NULL;
10650 +       unsigned long start=0UL, end=0UL, offset=0UL;
10651 +
10652 +       if (buffer_exec && buffer_fault) {
10653 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
10654 +
10655 +               down_read(&mm->mmap_sem);
10656 +               vma = mm->mmap;
10657 +               while (vma && (!vma_exec || !vma_fault)) {
10658 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
10659 +                               vma_exec = vma;
10660 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
10661 +                               vma_fault = vma;
10662 +                       vma = vma->vm_next;
10663 +               }
10664 +               if (vma_exec) {
10665 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
10666 +                       if (IS_ERR(path_exec))
10667 +                               path_exec = "<path too long>";
10668 +               }
10669 +               if (vma_fault) {
10670 +                       start = vma_fault->vm_start;
10671 +                       end = vma_fault->vm_end;
10672 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
10673 +                       if (vma_fault->vm_file) {
10674 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
10675 +                               if (IS_ERR(path_fault))
10676 +                                       path_fault = "<path too long>";
10677 +                       } else
10678 +                               path_fault = "<anonymous mapping>";
10679 +               }
10680 +               up_read(&mm->mmap_sem);
10681 +       }
10682 +       if (tsk->signal->curr_ip)
10683 +               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);
10684 +       else
10685 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
10686 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
10687 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
10688 +                       tsk->uid, tsk->euid, pc, sp);
10689 +       free_page((unsigned long)buffer_exec);
10690 +       free_page((unsigned long)buffer_fault);
10691 +       pax_report_insns(pc, sp);
10692 +       do_coredump(SIGKILL, SIGKILL, regs);
10693 +}
10694 +#endif
10695 +
10696  static void zap_process(struct task_struct *start)
10697  {
10698         struct task_struct *t;
10699 @@ -1498,6 +1752,10 @@ int do_coredump(long signr, int exit_cod
10700          */
10701         clear_thread_flag(TIF_SIGPENDING);
10702  
10703 +       if (signr == SIGKILL || signr == SIGILL)
10704 +               gr_handle_brute_attach(current);
10705 +
10706 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
10707         if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
10708                 goto fail_unlock;
10709  
10710 diff -urNp linux-2.6.18/fs/ext3/xattr.c linux-2.6.18/fs/ext3/xattr.c
10711 --- linux-2.6.18/fs/ext3/xattr.c        2006-09-19 23:42:06.000000000 -0400
10712 +++ linux-2.6.18/fs/ext3/xattr.c        2006-09-22 20:45:04.000000000 -0400
10713 @@ -89,8 +89,8 @@
10714                 printk("\n"); \
10715         } while (0)
10716  #else
10717 -# define ea_idebug(f...)
10718 -# define ea_bdebug(f...)
10719 +# define ea_idebug(f...) do {} while (0)
10720 +# define ea_bdebug(f...) do {} while (0)
10721  #endif
10722  
10723  static void ext3_xattr_cache_insert(struct buffer_head *);
10724 diff -urNp linux-2.6.18/fs/fcntl.c linux-2.6.18/fs/fcntl.c
10725 --- linux-2.6.18/fs/fcntl.c     2006-09-19 23:42:06.000000000 -0400
10726 +++ linux-2.6.18/fs/fcntl.c     2006-09-22 20:04:35.000000000 -0400
10727 @@ -18,6 +18,7 @@
10728  #include <linux/signal.h>
10729  #include <linux/rcupdate.h>
10730  #include <linux/vs_limit.h>
10731 +#include <linux/grsecurity.h>
10732  
10733  #include <asm/poll.h>
10734  #include <asm/siginfo.h>
10735 @@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
10736         struct fdtable *fdt;
10737  
10738         error = -EINVAL;
10739 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
10740         if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
10741                 goto out;
10742  
10743 @@ -83,6 +85,7 @@ repeat:
10744         }
10745         
10746         error = -EMFILE;
10747 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
10748         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
10749                 goto out;
10750         if (!vx_files_avail(1))
10751 @@ -141,6 +144,8 @@ asmlinkage long sys_dup2(unsigned int ol
10752         struct files_struct * files = current->files;
10753         struct fdtable *fdt;
10754  
10755 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
10756 +
10757         spin_lock(&files->file_lock);
10758         if (!(file = fcheck(oldfd)))
10759                 goto out_unlock;
10760 @@ -427,7 +432,8 @@ static inline int sigio_perm(struct task
10761         return (((fown->euid == 0) ||
10762                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
10763                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
10764 -               !security_file_send_sigiotask(p, fown, sig));
10765 +               !security_file_send_sigiotask(p, fown, sig) &&
10766 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
10767  }
10768  
10769  static void send_sigio_to_task(struct task_struct *p,
10770 diff -urNp linux-2.6.18/fs/Kconfig linux-2.6.18/fs/Kconfig
10771 --- linux-2.6.18/fs/Kconfig     2006-09-19 23:42:06.000000000 -0400
10772 +++ linux-2.6.18/fs/Kconfig     2006-09-22 20:04:35.000000000 -0400
10773 @@ -817,7 +817,7 @@ config PROC_FS
10774  
10775  config PROC_KCORE
10776         bool "/proc/kcore support" if !ARM
10777 -       depends on PROC_FS && MMU
10778 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
10779  
10780  config PROC_VMCORE
10781          bool "/proc/vmcore support (EXPERIMENTAL)"
10782 diff -urNp linux-2.6.18/fs/namei.c linux-2.6.18/fs/namei.c
10783 --- linux-2.6.18/fs/namei.c     2006-09-19 23:42:06.000000000 -0400
10784 +++ linux-2.6.18/fs/namei.c     2006-09-22 20:04:35.000000000 -0400
10785 @@ -32,6 +32,7 @@
10786  #include <linux/vs_tag.h>
10787  #include <linux/vserver/debug.h>
10788  #include <linux/vs_cowbl.h>
10789 +#include <linux/grsecurity.h>
10790  #include <asm/namei.h>
10791  #include <asm/uaccess.h>
10792  
10793 @@ -618,6 +619,13 @@ static inline int do_follow_link(struct 
10794         err = security_inode_follow_link(path->dentry, nd);
10795         if (err)
10796                 goto loop;
10797 +
10798 +       if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
10799 +                                 path->dentry->d_inode, path->dentry, nd->mnt)) {
10800 +               err = -EACCES;
10801 +               goto loop;
10802 +       }
10803 +
10804         current->link_count++;
10805         current->total_link_count++;
10806         nd->depth++;
10807 @@ -961,11 +969,18 @@ return_reval:
10808                                 break;
10809                 }
10810  return_base:
10811 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
10812 +                       path_release(nd);
10813 +                       return -ENOENT;
10814 +               }
10815                 return 0;
10816  out_dput:
10817                 dput_path(&next, nd);
10818                 break;
10819         }
10820 +       if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
10821 +               err = -ENOENT;
10822 +
10823         path_release(nd);
10824  return_err:
10825         return err;
10826 @@ -1608,6 +1623,17 @@ int open_namei(int dfd, const char *path
10827                                          nd, flag);
10828                 if (error)
10829                         return error;
10830 +
10831 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
10832 +                       error = -EPERM;
10833 +                       goto exit;
10834 +               }
10835 +
10836 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
10837 +                       error = -EACCES;
10838 +                       goto exit;
10839 +               }
10840 +
10841                 goto ok;
10842         }
10843  
10844 @@ -1648,9 +1674,16 @@ do_last:
10845  
10846         /* Negative dentry, just create the file */
10847         if (!path.dentry->d_inode) {
10848 +               if (!gr_acl_handle_creat(path.dentry, nd->dentry, nd->mnt, flag, mode)) {
10849 +                       error = -EACCES;
10850 +                       mutex_unlock(&dir->d_inode->i_mutex);
10851 +                       goto exit_dput;
10852 +               }
10853                 if (!IS_POSIXACL(dir->d_inode))
10854                         mode &= ~current->fs->umask;
10855                 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
10856 +               if (!error)
10857 +                       gr_handle_create(path.dentry, nd->mnt);
10858                 mutex_unlock(&dir->d_inode->i_mutex);
10859                 dput(nd->dentry);
10860                 nd->dentry = path.dentry;
10861 @@ -1665,6 +1698,23 @@ do_last:
10862         /*
10863          * It already exists.
10864          */
10865 +
10866 +       if (gr_handle_rawio(path.dentry->d_inode)) {
10867 +               mutex_unlock(&dir->d_inode->i_mutex);
10868 +               error = -EPERM;
10869 +               goto exit_dput;
10870 +       }
10871 +       if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
10872 +               mutex_unlock(&dir->d_inode->i_mutex);
10873 +               error = -EACCES;
10874 +               goto exit_dput;
10875 +       }
10876 +       if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
10877 +               mutex_unlock(&dir->d_inode->i_mutex);
10878 +               error = -EACCES;
10879 +               goto exit_dput;
10880 +       }
10881 +
10882         mutex_unlock(&dir->d_inode->i_mutex);
10883         audit_inode_update(path.dentry->d_inode);
10884  
10885 @@ -1720,6 +1770,13 @@ do_link:
10886         error = security_inode_follow_link(path.dentry, nd);
10887         if (error)
10888                 goto exit_dput;
10889 +
10890 +       if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
10891 +                                 path.dentry, nd->mnt)) {
10892 +               error = -EACCES;
10893 +               goto exit_dput;
10894 +       }
10895 +
10896         error = __do_follow_link(&path, nd);
10897         if (error) {
10898                 /* Does someone understand code flow here? Or it is only
10899 @@ -1848,6 +1905,22 @@ asmlinkage long sys_mknodat(int dfd, con
10900         if (!IS_POSIXACL(nd.dentry->d_inode))
10901                 mode &= ~current->fs->umask;
10902         if (!IS_ERR(dentry)) {
10903 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
10904 +                       error = -EPERM;
10905 +                       dput(dentry);
10906 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
10907 +                       path_release(&nd);
10908 +                       goto out;
10909 +               }
10910 +
10911 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
10912 +                       error = -EACCES;
10913 +                       dput(dentry);
10914 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
10915 +                       path_release(&nd);
10916 +                       goto out;
10917 +               }
10918 +
10919                 switch (mode & S_IFMT) {
10920                 case 0: case S_IFREG:
10921                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
10922 @@ -1865,6 +1938,10 @@ asmlinkage long sys_mknodat(int dfd, con
10923                 default:
10924                         error = -EINVAL;
10925                 }
10926 +
10927 +               if (!error)
10928 +                       gr_handle_create(dentry, nd.mnt);
10929 +
10930                 dput(dentry);
10931         }
10932         mutex_unlock(&nd.dentry->d_inode->i_mutex);
10933 @@ -1919,10 +1996,20 @@ asmlinkage long sys_mkdirat(int dfd, con
10934                 dentry = lookup_create(&nd, 1);
10935                 error = PTR_ERR(dentry);
10936                 if (!IS_ERR(dentry)) {
10937 +                       error = 0;
10938                         if (!IS_POSIXACL(nd.dentry->d_inode))
10939                                 mode &= ~current->fs->umask;
10940 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
10941 -                               mode, &nd);
10942 +
10943 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
10944 +                               error = -EACCES;
10945 +
10946 +                       if (!error)
10947 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry,
10948 +                                       mode, &nd);
10949 +
10950 +                       if (!error)
10951 +                               gr_handle_create(dentry, nd.mnt);
10952 +
10953                         dput(dentry);
10954                 }
10955                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
10956 @@ -2005,6 +2092,8 @@ static long do_rmdir(int dfd, const char
10957         char * name;
10958         struct dentry *dentry;
10959         struct nameidata nd;
10960 +       ino_t saved_ino = 0;
10961 +       dev_t saved_dev = 0;
10962  
10963         name = getname(pathname);
10964         if(IS_ERR(name))
10965 @@ -2029,7 +2118,21 @@ static long do_rmdir(int dfd, const char
10966         dentry = lookup_hash(&nd);
10967         error = PTR_ERR(dentry);
10968         if (!IS_ERR(dentry)) {
10969 -               error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
10970 +               error = 0;
10971 +               if (dentry->d_inode) {
10972 +                       if (dentry->d_inode->i_nlink <= 1) {
10973 +                               saved_ino = dentry->d_inode->i_ino;
10974 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
10975 +                       }
10976 +
10977 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
10978 +                               error = -EACCES;
10979 +               }
10980 +
10981 +               if (!error)
10982 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
10983 +               if (!error && (saved_dev || saved_ino))
10984 +                       gr_handle_delete(saved_ino, saved_dev);
10985                 dput(dentry);
10986         }
10987         mutex_unlock(&nd.dentry->d_inode->i_mutex);
10988 @@ -2088,6 +2191,8 @@ static long do_unlinkat(int dfd, const c
10989         struct dentry *dentry;
10990         struct nameidata nd;
10991         struct inode *inode = NULL;
10992 +       ino_t saved_ino = 0;
10993 +       dev_t saved_dev = 0;
10994  
10995         name = getname(pathname);
10996         if(IS_ERR(name))
10997 @@ -2103,13 +2208,26 @@ static long do_unlinkat(int dfd, const c
10998         dentry = lookup_hash(&nd);
10999         error = PTR_ERR(dentry);
11000         if (!IS_ERR(dentry)) {
11001 +               error = 0;
11002                 /* Why not before? Because we want correct error value */
11003                 if (nd.last.name[nd.last.len])
11004                         goto slashes;
11005                 inode = dentry->d_inode;
11006 -               if (inode)
11007 +               if (inode) {
11008 +                       if (inode->i_nlink <= 1) {
11009 +                               saved_ino = inode->i_ino;
11010 +                               saved_dev = inode->i_sb->s_dev;
11011 +                       }
11012 +
11013 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
11014 +                               error = -EACCES;
11015 +
11016                         atomic_inc(&inode->i_count);
11017 -               error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
11018 +               }
11019 +               if (!error)
11020 +                       error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
11021 +               if (!error && (saved_ino || saved_dev))
11022 +                       gr_handle_delete(saved_ino, saved_dev);
11023         exit2:
11024                 dput(dentry);
11025         }
11026 @@ -2187,8 +2305,15 @@ asmlinkage long sys_symlinkat(const char
11027                 dentry = lookup_create(&nd, 0);
11028                 error = PTR_ERR(dentry);
11029                 if (!IS_ERR(dentry)) {
11030 -                       error = vfs_symlink(nd.dentry->d_inode, dentry,
11031 -                               from, S_IALLUGO, &nd);
11032 +                       error = 0;
11033 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
11034 +                               error = -EACCES;
11035 +
11036 +                       if (!error)
11037 +                               error = vfs_symlink(nd.dentry->d_inode, dentry,
11038 +                                       from, S_IALLUGO, &nd);
11039 +                       if (!error)
11040 +                               gr_handle_create(dentry, nd.mnt);
11041                         dput(dentry);
11042                 }
11043                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
11044 @@ -2281,8 +2407,20 @@ asmlinkage long sys_linkat(int olddfd, c
11045         new_dentry = lookup_create(&nd, 0);
11046         error = PTR_ERR(new_dentry);
11047         if (!IS_ERR(new_dentry)) {
11048 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode,
11049 -                       new_dentry, &nd);
11050 +               error = 0;
11051 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
11052 +                                      old_nd.dentry->d_inode,
11053 +                                      old_nd.dentry->d_inode->i_mode, to))
11054 +                       error = -EPERM;
11055 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
11056 +                                       old_nd.dentry, old_nd.mnt, to))
11057 +                       error = -EACCES;
11058 +               if (!error)
11059 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry,
11060 +                               &nd);
11061 +               if (!error)
11062 +                       gr_handle_create(new_dentry, nd.mnt);
11063 +
11064                 dput(new_dentry);
11065         }
11066         mutex_unlock(&nd.dentry->d_inode->i_mutex);
11067 @@ -2507,8 +2646,16 @@ static int do_rename(int olddfd, const c
11068         if (new_dentry == trap)
11069                 goto exit5;
11070  
11071 -       error = vfs_rename(old_dir->d_inode, old_dentry,
11072 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
11073 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
11074 +                                    newname);
11075 +
11076 +       if (!error)
11077 +               error = vfs_rename(old_dir->d_inode, old_dentry,
11078                                    new_dir->d_inode, new_dentry);
11079 +       if (!error)
11080 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
11081 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
11082  exit5:
11083         dput(new_dentry);
11084  exit4:
11085 diff -urNp linux-2.6.18/fs/namespace.c linux-2.6.18/fs/namespace.c
11086 --- linux-2.6.18/fs/namespace.c 2006-09-19 23:42:06.000000000 -0400
11087 +++ linux-2.6.18/fs/namespace.c 2006-09-22 20:04:35.000000000 -0400
11088 @@ -22,6 +22,8 @@
11089  #include <linux/mount.h>
11090  #include <linux/vserver/namespace.h>
11091  #include <linux/vserver/tag.h>
11092 +#include <linux/sched.h>
11093 +#include <linux/grsecurity.h>
11094  #include <asm/uaccess.h>
11095  #include <asm/unistd.h>
11096  #include "pnode.h"
11097 @@ -606,6 +608,8 @@ static int do_umount(struct vfsmount *mn
11098                         DQUOT_OFF(sb);
11099                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
11100                         unlock_kernel();
11101 +
11102 +                       gr_log_remount(mnt->mnt_devname, retval);
11103                 }
11104                 up_write(&sb->s_umount);
11105                 return retval;
11106 @@ -626,6 +630,9 @@ static int do_umount(struct vfsmount *mn
11107                 security_sb_umount_busy(mnt);
11108         up_write(&namespace_sem);
11109         release_mounts(&umount_list);
11110 +
11111 +       gr_log_unmount(mnt->mnt_devname, retval);
11112 +
11113         return retval;
11114  }
11115  
11116 @@ -1426,6 +1433,11 @@ long do_mount(char *dev_name, char *dir_
11117         if (retval)
11118                 goto dput_out;
11119  
11120 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
11121 +               retval = -EPERM;
11122 +               goto dput_out;
11123 +       }
11124 +
11125         if (flags & MS_REMOUNT)
11126                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
11127                                     data_page);
11128 @@ -1440,6 +1452,9 @@ long do_mount(char *dev_name, char *dir_
11129                                       dev_name, data_page);
11130  dput_out:
11131         path_release(&nd);
11132 +
11133 +       gr_log_mount(dev_name, dir_name, retval);
11134 +
11135         return retval;
11136  }
11137  
11138 @@ -1692,6 +1707,9 @@ asmlinkage long sys_pivot_root(const cha
11139         if (!capable(CAP_SYS_ADMIN))
11140                 return -EPERM;
11141  
11142 +       if (gr_handle_chroot_pivot())
11143 +               return -EPERM;
11144 +
11145         lock_kernel();
11146  
11147         error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
11148 diff -urNp linux-2.6.18/fs/open.c linux-2.6.18/fs/open.c
11149 --- linux-2.6.18/fs/open.c      2006-09-19 23:42:06.000000000 -0400
11150 +++ linux-2.6.18/fs/open.c      2006-09-22 20:15:13.000000000 -0400
11151 @@ -28,6 +28,7 @@
11152  #include <linux/vs_limit.h>
11153  #include <linux/vs_dlimit.h>
11154  #include <linux/vserver/tag.h>
11155 +#include <linux/grsecurity.h>
11156  
11157  #include <asm/unistd.h>
11158  
11159 @@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
11160         if (length < 0)
11161                 return -EINVAL;
11162  
11163 +       if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
11164 +               return -EACCES;
11165 +
11166         newattrs.ia_size = length;
11167         newattrs.ia_valid = ATTR_SIZE | time_attrs;
11168         if (filp) {
11169 @@ -407,6 +411,12 @@ asmlinkage long sys_utime(char __user * 
11170                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
11171                         goto dput_and_out;
11172         }
11173 +
11174 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
11175 +               error = -EACCES;
11176 +               goto dput_and_out;
11177 +       }
11178 +
11179         mutex_lock(&inode->i_mutex);
11180         error = notify_change(nd.dentry, &newattrs);
11181         mutex_unlock(&inode->i_mutex);
11182 @@ -460,6 +470,12 @@ long do_utimes(int dfd, char __user *fil
11183                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
11184                         goto dput_and_out;
11185         }
11186 +
11187 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
11188 +               error = -EACCES;
11189 +               goto dput_and_out;
11190 +       }
11191 +
11192         mutex_lock(&inode->i_mutex);
11193         error = notify_change(nd.dentry, &newattrs);
11194         mutex_unlock(&inode->i_mutex);
11195 @@ -526,6 +542,10 @@ asmlinkage long sys_faccessat(int dfd, c
11196                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
11197                    && !special_file(nd.dentry->d_inode->i_mode))
11198                         res = -EROFS;
11199 +
11200 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
11201 +                       res = -EACCES;
11202 +
11203                 path_release(&nd);
11204         }
11205  
11206 @@ -554,6 +574,8 @@ asmlinkage long sys_chdir(const char __u
11207         if (error)
11208                 goto dput_and_out;
11209  
11210 +       gr_log_chdir(nd.dentry, nd.mnt);
11211 +
11212         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
11213  
11214  dput_and_out:
11215 @@ -584,6 +606,13 @@ asmlinkage long sys_fchdir(unsigned int 
11216                 goto out_putf;
11217  
11218         error = file_permission(file, MAY_EXEC);
11219 +
11220 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
11221 +               error = -EPERM;
11222 +
11223 +       if (!error)
11224 +               gr_log_chdir(dentry, mnt);
11225 +
11226         if (!error)
11227                 set_fs_pwd(current->fs, mnt, dentry);
11228  out_putf:
11229 @@ -609,8 +638,16 @@ asmlinkage long sys_chroot(const char __
11230         if (!capable(CAP_SYS_CHROOT))
11231                 goto dput_and_out;
11232  
11233 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
11234 +               goto dput_and_out;
11235 +
11236         set_fs_root(current->fs, nd.mnt, nd.dentry);
11237         set_fs_altroot();
11238 +
11239 +       gr_handle_chroot_caps(current);
11240 +
11241 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
11242 +
11243         error = 0;
11244  dput_and_out:
11245         path_release(&nd);
11246 @@ -641,9 +678,22 @@ asmlinkage long sys_fchmod(unsigned int 
11247         err = -EPERM;
11248         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
11249                 goto out_putf;
11250 +
11251 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
11252 +               err = -EACCES;
11253 +               goto out_putf;
11254 +       }
11255 +
11256         mutex_lock(&inode->i_mutex);
11257         if (mode == (mode_t) -1)
11258                 mode = inode->i_mode;
11259 +
11260 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
11261 +               err = -EPERM;
11262 +               mutex_unlock(&inode->i_mutex);
11263 +               goto out_putf;
11264 +       }
11265 +
11266         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
11267         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
11268         err = notify_change(dentry, &newattrs);
11269 @@ -676,9 +726,21 @@ asmlinkage long sys_fchmodat(int dfd, co
11270         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
11271                 goto dput_and_out;
11272  
11273 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
11274 +               error = -EACCES;
11275 +               goto dput_and_out;
11276 +       };
11277 +
11278         mutex_lock(&inode->i_mutex);
11279         if (mode == (mode_t) -1)
11280                 mode = inode->i_mode;
11281 +
11282 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
11283 +               error = -EACCES;
11284 +               mutex_unlock(&inode->i_mutex);
11285 +               goto dput_and_out;
11286 +       }
11287 +
11288         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
11289         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
11290         error = notify_change(nd.dentry, &newattrs);
11291 @@ -712,6 +774,12 @@ static int chown_common(struct dentry * 
11292         error = -EPERM;
11293         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
11294                 goto out;
11295 +
11296 +       if (!gr_acl_handle_chown(dentry, mnt)) {
11297 +               error = -EACCES;
11298 +               goto out;
11299 +       }
11300 +
11301         newattrs.ia_valid =  ATTR_CTIME;
11302         if (user != (uid_t) -1) {
11303                 newattrs.ia_valid |= ATTR_UID;
11304 @@ -995,6 +1063,7 @@ repeat:
11305          * N.B. For clone tasks sharing a files structure, this test
11306          * will limit the total number of files that can be opened.
11307          */
11308 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
11309         if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
11310                 goto out;
11311  
11312 diff -urNp linux-2.6.18/fs/partitions/efi.c linux-2.6.18/fs/partitions/efi.c
11313 --- linux-2.6.18/fs/partitions/efi.c    2006-09-19 23:42:06.000000000 -0400
11314 +++ linux-2.6.18/fs/partitions/efi.c    2006-09-22 20:45:04.000000000 -0400
11315 @@ -99,7 +99,7 @@
11316  #ifdef EFI_DEBUG
11317  #define Dprintk(x...) printk(KERN_DEBUG x)
11318  #else
11319 -#define Dprintk(x...)
11320 +#define Dprintk(x...) do {} while (0)
11321  #endif
11322  
11323  /* This allows a kernel command line option 'gpt' to override
11324 diff -urNp linux-2.6.18/fs/pipe.c linux-2.6.18/fs/pipe.c
11325 --- linux-2.6.18/fs/pipe.c      2006-09-19 23:42:06.000000000 -0400
11326 +++ linux-2.6.18/fs/pipe.c      2006-09-22 20:04:35.000000000 -0400
11327 @@ -842,7 +842,7 @@ void free_pipe_info(struct inode *inode)
11328         inode->i_pipe = NULL;
11329  }
11330  
11331 -static struct vfsmount *pipe_mnt __read_mostly;
11332 +struct vfsmount *pipe_mnt __read_mostly;
11333  static int pipefs_delete_dentry(struct dentry *dentry)
11334  {
11335         return 1;
11336 diff -urNp linux-2.6.18/fs/proc/array.c linux-2.6.18/fs/proc/array.c
11337 --- linux-2.6.18/fs/proc/array.c        2006-09-19 23:42:06.000000000 -0400
11338 +++ linux-2.6.18/fs/proc/array.c        2006-09-22 20:45:04.000000000 -0400
11339 @@ -293,6 +293,21 @@ static inline char *task_cap(struct task
11340                             cap_t(p->cap_effective));
11341  }
11342  
11343 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
11344 +static inline char *task_pax(struct task_struct *p, char *buffer)
11345 +{
11346 +       if (p->mm)
11347 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
11348 +                               p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
11349 +                               p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
11350 +                               p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
11351 +                               p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
11352 +                               p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
11353 +       else
11354 +               return buffer + sprintf(buffer, "PaX:\t-----\n");
11355 +}
11356 +#endif
11357 +
11358  int proc_pid_status(struct task_struct *task, char * buffer)
11359  {
11360         char * orig = buffer;
11361 @@ -311,9 +326,20 @@ int proc_pid_status(struct task_struct *
11362  #if defined(CONFIG_S390)
11363         buffer = task_show_regs(task, buffer);
11364  #endif
11365 +
11366 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
11367 +       buffer = task_pax(task, buffer);
11368 +#endif
11369 +
11370         return buffer - orig;
11371  }
11372  
11373 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11374 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
11375 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
11376 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
11377 +#endif
11378 +
11379  static int do_task_stat(struct task_struct *task, char * buffer, int whole)
11380  {
11381         unsigned long vsize, eip, esp, wchan = ~0UL;
11382 @@ -398,6 +424,19 @@ static int do_task_stat(struct task_stru
11383                 stime = task->stime;
11384         }
11385  
11386 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11387 +       if (PAX_RAND_FLAGS(mm)) {
11388 +               eip = 0;
11389 +               esp = 0;
11390 +               wchan = 0;
11391 +       }
11392 +#endif
11393 +#ifdef CONFIG_GRKERNSEC_HIDESYM
11394 +       wchan = 0;
11395 +       eip =0;
11396 +       esp =0;
11397 +#endif
11398 +
11399         /* scale priority and nice values from timeslices to -20..20 */
11400         /* to make it look like a "normal" Unix priority/nice value  */
11401         priority = task_prio(task);
11402 @@ -437,9 +476,15 @@ static int do_task_stat(struct task_stru
11403                 vsize,
11404                 mm ? get_mm_rss(mm) : 0,
11405                 rsslim,
11406 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11407 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
11408 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
11409 +               PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
11410 +#else
11411                 mm ? mm->start_code : 0,
11412                 mm ? mm->end_code : 0,
11413                 mm ? mm->start_stack : 0,
11414 +#endif
11415                 esp,
11416                 eip,
11417                 /* The signal information here is obsolete.
11418 @@ -486,3 +531,14 @@ int proc_pid_statm(struct task_struct *t
11419         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
11420                        size, resident, shared, text, lib, data, 0);
11421  }
11422 +
11423 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11424 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
11425 +{
11426 +       int len;
11427 +
11428 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
11429 +       return len;
11430 +}
11431 +#endif
11432 +
11433 diff -urNp linux-2.6.18/fs/proc/base.c linux-2.6.18/fs/proc/base.c
11434 --- linux-2.6.18/fs/proc/base.c 2006-09-19 23:42:06.000000000 -0400
11435 +++ linux-2.6.18/fs/proc/base.c 2006-09-30 15:58:34.000000000 -0400
11436 @@ -71,6 +71,7 @@
11437  #include <linux/vs_context.h>
11438  #include <linux/vs_network.h>
11439  #include <linux/vs_pid.h>
11440 +#include <linux/grsecurity.h>
11441  #include "internal.h"
11442  
11443  /* NOTE:
11444 @@ -136,6 +137,9 @@ enum pid_directory_inos {
11445  #ifdef CONFIG_AUDITSYSCALL
11446         PROC_TGID_LOGINUID,
11447  #endif
11448 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11449 +       PROC_TGID_IPADDR,
11450 +#endif
11451         PROC_TGID_OOM_SCORE,
11452         PROC_TGID_OOM_ADJUST,
11453         PROC_TID_INO,
11454 @@ -220,6 +224,9 @@ static struct pid_entry tgid_base_stuff[
11455         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
11456         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
11457         E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
11458 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11459 +       E(PROC_TGID_IPADDR,     "ipaddr", S_IFREG|S_IRUSR),
11460 +#endif
11461  #ifdef CONFIG_MMU
11462         E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
11463  #endif
11464 @@ -410,7 +417,7 @@ static int proc_root_link(struct inode *
11465         (task->parent == current && \
11466         (task->ptrace & PT_PTRACED) && \
11467          (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
11468 -        security_ptrace(current,task) == 0))
11469 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
11470  
11471  static int proc_pid_environ(struct task_struct *task, char * buffer)
11472  {
11473 @@ -546,6 +553,8 @@ static int proc_fd_access_allowed(struct
11474         task = get_proc_task(inode);
11475         if (task) {
11476                 allowed = ptrace_may_attach(task);
11477 +               if (allowed != 0)
11478 +                       allowed = !gr_acl_handle_procpidmem(task);
11479                 put_task_struct(task);
11480         }
11481         return allowed;
11482 @@ -736,7 +745,7 @@ static ssize_t mem_read(struct file * fi
11483         if (!task)
11484                 goto out_no_task;
11485  
11486 -       if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
11487 +       if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
11488                 goto out;
11489  
11490         ret = -ENOMEM;
11491 @@ -806,7 +815,7 @@ static ssize_t mem_write(struct file * f
11492         if (!task)
11493                 goto out_no_task;
11494  
11495 -       if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
11496 +       if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
11497                 goto out;
11498  
11499         copied = -ENOMEM;
11500 @@ -1165,6 +1174,8 @@ static int proc_readfd(struct file * fil
11501                                 goto out;
11502                         filp->f_pos++;
11503                 default:
11504 +                       if (gr_acl_handle_procpidmem(p))
11505 +                               goto out;
11506                         files = get_files_struct(p);
11507                         if (!files)
11508                                 goto out;
11509 @@ -1321,7 +1332,11 @@ static struct inode *proc_pid_make_inode
11510         if (task_dumpable(task)) {
11511                 inode->i_uid = task->euid;
11512                 inode->i_gid = task->egid;
11513 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11514 +               inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11515 +#endif
11516         }
11517 +
11518         /* procfs is xid tagged */
11519         inode->i_tag = (tag_t)vx_task_xid(task);
11520         security_task_to_inode(task, inode);
11521 @@ -1353,18 +1368,37 @@ static int pid_revalidate(struct dentry 
11522  {
11523         struct inode *inode = dentry->d_inode;
11524         struct task_struct *task = get_proc_task(inode);
11525 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11526 +       struct task_struct *tmp = current;
11527 +#endif
11528         int ret = 0;
11529  
11530 -       if (task) {
11531 +       if (task &&
11532 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11533 +           (!tmp->uid || (tmp->uid == task->uid)
11534 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11535 +           || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
11536 +#endif
11537 +           ) &&
11538 +#endif
11539 +           !gr_check_hidden_task(task)) {
11540                 ret = 1;
11541                 /* discard wrong fakeinit */
11542                 if (!vx_check(vx_task_xid(task), VX_IDENT))
11543                         goto out_drop;
11544  
11545                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
11546 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11547 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
11548 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11549 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
11550 +#endif
11551                     task_dumpable(task)) {
11552                         inode->i_uid = task->euid;
11553                         inode->i_gid = task->egid;
11554 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11555 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11556 +#endif
11557                 } else {
11558                         inode->i_uid = 0;
11559                         inode->i_gid = 0;
11560 @@ -1383,9 +1418,17 @@ static int pid_getattr(struct vfsmount *
11561         task = pid_task(proc_pid(inode), PIDTYPE_PID);
11562         if (task) {
11563                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
11564 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11565 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
11566 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11567 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
11568 +#endif
11569                     task_dumpable(task)) {
11570                         stat->uid = task->euid;
11571                         stat->gid = task->egid;
11572 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11573 +                       stat->gid = CONFIG_GRKERNSEC_PROC_GID;
11574 +#endif
11575                 }
11576         }
11577         rcu_read_unlock();
11578 @@ -1488,6 +1531,9 @@ static struct dentry *proc_lookupfd(stru
11579         if (fd == ~0U)
11580                 goto out;
11581  
11582 +       if (gr_acl_handle_procpidmem(task))
11583 +               goto out;
11584 +
11585         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd);
11586         if (!inode)
11587                 goto out;
11588 @@ -1721,6 +1767,12 @@ static struct dentry *proc_pident_lookup
11589                         inode->i_fop = &proc_info_file_operations;
11590                         ei->op.proc_read = proc_pid_status;
11591                         break;
11592 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11593 +               case PROC_TGID_IPADDR:
11594 +                       inode->i_fop = &proc_info_file_operations;
11595 +                       ei->op.proc_read = proc_pid_ipaddr;
11596 +                       break;
11597 +#endif
11598                 case PROC_TID_STAT:
11599                         inode->i_fop = &proc_info_file_operations;
11600                         ei->op.proc_read = proc_tid_stat;
11601 @@ -2057,11 +2109,21 @@ struct dentry *proc_pid_lookup(struct in
11602         if (!task)
11603                 goto out;
11604  
11605 +       if (gr_check_hidden_task(task))
11606 +               goto out_put_task;
11607 +
11608         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
11609         if (!inode)
11610                 goto out_put_task;
11611  
11612 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11613 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
11614 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11615 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11616 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
11617 +#else
11618         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
11619 +#endif
11620         inode->i_op = &proc_tgid_base_inode_operations;
11621         inode->i_fop = &proc_tgid_base_operations;
11622         inode->i_flags|=S_IMMUTABLE;
11623 @@ -2155,12 +2217,27 @@ out_no_task:
11624  static struct task_struct *first_tgid(int tgid, unsigned int nr)
11625  {
11626         struct task_struct *pos;
11627 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11628 +       struct task_struct *tmp = current;
11629 +#endif
11630         rcu_read_lock();
11631         if (tgid && nr) {
11632                 pos = find_task_by_pid(tgid);
11633 +               if (pos && (gr_pid_is_chrooted(pos) || gr_check_hidden_task(pos)
11634 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11635 +                   || (tmp->uid && (pos->uid != tmp->uid)
11636 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11637 +                       && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
11638 +#endif
11639 +                       )
11640 +#endif
11641 +               ))
11642 +                       goto not_found;
11643 +
11644                 if (pos && thread_group_leader(pos))
11645                         goto found;
11646         }
11647 +not_found:
11648         /* If nr exceeds the number of processes get out quickly */
11649         pos = NULL;
11650         if (nr && nr >= nr_processes())
11651 @@ -2175,6 +2252,16 @@ static struct task_struct *first_tgid(in
11652                         pos = NULL;
11653                         goto done;
11654                 }
11655 +               if (pos && (gr_pid_is_chrooted(pos) || gr_check_hidden_task(pos)
11656 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11657 +                   || (tmp->uid && (pos->uid != tmp->uid)
11658 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11659 +                       && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
11660 +#endif
11661 +                       )
11662 +#endif
11663 +               ))
11664 +                       nr++;
11665         }
11666  found:
11667         get_task_struct(pos);
11668 @@ -2212,6 +2299,9 @@ int proc_pid_readdir(struct file * filp,
11669  {
11670         char buf[PROC_NUMBUF];
11671         unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
11672 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11673 +       struct task_struct *tmp = current;
11674 +#endif
11675         struct task_struct *task;
11676         int tgid;
11677  
11678 @@ -2234,6 +2324,19 @@ int proc_pid_readdir(struct file * filp,
11679              task = next_tgid(task), filp->f_pos++) {
11680                 int len;
11681                 ino_t ino;
11682 +
11683 +               if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)
11684 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11685 +                   || (tmp->uid && (task->uid != tmp->uid)
11686 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11687 +                       && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
11688 +#endif
11689 +                       )
11690 +#endif
11691 +               ) {
11692 +                       continue;
11693 +               }
11694 +
11695                 tgid = vx_map_tgid(task->pid);
11696                 len = snprintf(buf, sizeof(buf), "%d", tgid);
11697                 ino = fake_ino(tgid, PROC_TGID_INO);
11698 diff -urNp linux-2.6.18/fs/proc/inode.c linux-2.6.18/fs/proc/inode.c
11699 --- linux-2.6.18/fs/proc/inode.c        2006-09-19 23:42:06.000000000 -0400
11700 +++ linux-2.6.18/fs/proc/inode.c        2006-09-22 20:04:35.000000000 -0400
11701 @@ -166,7 +166,11 @@ struct inode *proc_get_inode(struct supe
11702                 if (de->mode) {
11703                         inode->i_mode = de->mode;
11704                         inode->i_uid = de->uid;
11705 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11706 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11707 +#else
11708                         inode->i_gid = de->gid;
11709 +#endif
11710                 }
11711                 if (de->size)
11712                         inode->i_size = de->size;
11713 diff -urNp linux-2.6.18/fs/proc/internal.h linux-2.6.18/fs/proc/internal.h
11714 --- linux-2.6.18/fs/proc/internal.h     2006-09-19 23:42:06.000000000 -0400
11715 +++ linux-2.6.18/fs/proc/internal.h     2006-09-22 20:04:35.000000000 -0400
11716 @@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
11717  extern int proc_tgid_stat(struct task_struct *, char *);
11718  extern int proc_pid_status(struct task_struct *, char *);
11719  extern int proc_pid_statm(struct task_struct *, char *);
11720 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11721 +extern int proc_pid_ipaddr(struct task_struct*,char*);
11722 +#endif
11723  
11724  extern struct file_operations proc_maps_operations;
11725  extern struct file_operations proc_numa_maps_operations;
11726 diff -urNp linux-2.6.18/fs/proc/proc_misc.c linux-2.6.18/fs/proc/proc_misc.c
11727 --- linux-2.6.18/fs/proc/proc_misc.c    2006-09-19 23:42:06.000000000 -0400
11728 +++ linux-2.6.18/fs/proc/proc_misc.c    2006-09-22 20:04:35.000000000 -0400
11729 @@ -655,6 +655,8 @@ void create_seq_entry(char *name, mode_t
11730  void __init proc_misc_init(void)
11731  {
11732         struct proc_dir_entry *entry;
11733 +       int gr_mode = 0;
11734 +
11735         static struct {
11736                 char *name;
11737                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
11738 @@ -670,7 +672,9 @@ void __init proc_misc_init(void)
11739                 {"stram",       stram_read_proc},
11740  #endif
11741                 {"filesystems", filesystems_read_proc},
11742 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
11743                 {"cmdline",     cmdline_read_proc},
11744 +#endif
11745                 {"locks",       locks_read_proc},
11746                 {"execdomains", execdomains_read_proc},
11747                 {NULL,}
11748 @@ -678,19 +682,36 @@ void __init proc_misc_init(void)
11749         for (p = simple_ones; p->name; p++)
11750                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
11751  
11752 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11753 +       gr_mode = S_IRUSR;
11754 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11755 +       gr_mode = S_IRUSR | S_IRGRP;
11756 +#endif
11757 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11758 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
11759 +#endif
11760 +
11761         proc_symlink("mounts", NULL, "self/mounts");
11762  
11763         /* And now for trickier ones */
11764         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
11765         if (entry)
11766                 entry->proc_fops = &proc_kmsg_operations;
11767 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11768 +       create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
11769 +#else
11770         create_seq_entry("devices", 0, &proc_devinfo_operations);
11771 +#endif
11772         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
11773         create_seq_entry("partitions", 0, &proc_partitions_operations);
11774         create_seq_entry("stat", 0, &proc_stat_operations);
11775         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
11776  #ifdef CONFIG_SLAB
11777 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11778 +       create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
11779 +#else
11780         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
11781 +#endif
11782  #ifdef CONFIG_DEBUG_SLAB_LEAK
11783         create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
11784  #endif
11785 @@ -705,7 +726,7 @@ void __init proc_misc_init(void)
11786  #ifdef CONFIG_SCHEDSTATS
11787         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
11788  #endif
11789 -#ifdef CONFIG_PROC_KCORE
11790 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
11791         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
11792         if (proc_root_kcore) {
11793                 proc_root_kcore->proc_fops = &proc_kcore_operations;
11794 diff -urNp linux-2.6.18/fs/proc/root.c linux-2.6.18/fs/proc/root.c
11795 --- linux-2.6.18/fs/proc/root.c 2006-09-19 23:42:06.000000000 -0400
11796 +++ linux-2.6.18/fs/proc/root.c 2006-09-22 20:04:35.000000000 -0400
11797 @@ -52,7 +52,13 @@ void __init proc_root_init(void)
11798                 return;
11799         }
11800         proc_misc_init();
11801 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11802 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
11803 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11804 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
11805 +#else
11806         proc_net = proc_mkdir("net", NULL);
11807 +#endif
11808         proc_net_stat = proc_mkdir("net/stat", NULL);
11809  
11810  #ifdef CONFIG_SYSVIPC
11811 @@ -76,7 +82,15 @@ void __init proc_root_init(void)
11812  #ifdef CONFIG_PROC_DEVICETREE
11813         proc_device_tree_init();
11814  #endif
11815 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11816 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11817 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
11818 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11819 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
11820 +#endif
11821 +#else
11822         proc_bus = proc_mkdir("bus", NULL);
11823 +#endif
11824         proc_vx_init();
11825  }
11826  
11827 diff -urNp linux-2.6.18/fs/proc/task_mmu.c linux-2.6.18/fs/proc/task_mmu.c
11828 --- linux-2.6.18/fs/proc/task_mmu.c     2006-09-19 23:42:06.000000000 -0400
11829 +++ linux-2.6.18/fs/proc/task_mmu.c     2006-09-22 20:45:04.000000000 -0400
11830 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
11831                 "VmStk:\t%8lu kB\n"
11832                 "VmExe:\t%8lu kB\n"
11833                 "VmLib:\t%8lu kB\n"
11834 -               "VmPTE:\t%8lu kB\n",
11835 -               hiwater_vm << (PAGE_SHIFT-10),
11836 +               "VmPTE:\t%8lu kB\n"
11837 +
11838 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
11839 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
11840 +#endif
11841 +
11842 +               ,hiwater_vm << (PAGE_SHIFT-10),
11843                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
11844                 mm->locked_vm << (PAGE_SHIFT-10),
11845                 hiwater_rss << (PAGE_SHIFT-10),
11846                 total_rss << (PAGE_SHIFT-10),
11847                 data << (PAGE_SHIFT-10),
11848                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
11849 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
11850 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
11851 +
11852 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
11853 +               , mm->context.user_cs_base, mm->context.user_cs_limit
11854 +#endif
11855 +
11856 +       );
11857 +
11858         return buffer;
11859  }
11860  
11861 @@ -127,6 +139,12 @@ __attribute__((weak)) const char *arch_v
11862         return NULL;
11863  }
11864  
11865 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11866 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
11867 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
11868 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
11869 +#endif
11870 +
11871  static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
11872  {
11873         struct proc_maps_private *priv = m->private;
11874 @@ -146,13 +164,30 @@ static int show_map_internal(struct seq_
11875         }
11876  
11877         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
11878 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11879 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
11880 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
11881 +#else
11882                         vma->vm_start,
11883                         vma->vm_end,
11884 +#endif
11885 +
11886 +#if 0
11887 +                       flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
11888 +                       flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
11889 +                       flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
11890 +#else
11891                         flags & VM_READ ? 'r' : '-',
11892                         flags & VM_WRITE ? 'w' : '-',
11893                         flags & VM_EXEC ? 'x' : '-',
11894 +#endif
11895 +
11896                         flags & VM_MAYSHARE ? 's' : 'p',
11897 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11898 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
11899 +#else
11900                         vma->vm_pgoff << PAGE_SHIFT,
11901 +#endif
11902                         MAJOR(dev), MINOR(dev), ino, &len);
11903  
11904         /*
11905 @@ -166,11 +201,11 @@ static int show_map_internal(struct seq_
11906                 const char *name = arch_vma_name(vma);
11907                 if (!name) {
11908                         if (mm) {
11909 -                               if (vma->vm_start <= mm->start_brk &&
11910 -                                               vma->vm_end >= mm->brk) {
11911 +                               if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
11912                                         name = "[heap]";
11913 -                               } else if (vma->vm_start <= mm->start_stack &&
11914 -                                          vma->vm_end >= mm->start_stack) {
11915 +                               } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
11916 +                                          (vma->vm_start <= mm->start_stack &&
11917 +                                           vma->vm_end >= mm->start_stack)) {
11918                                         name = "[stack]";
11919                                 }
11920                         } else {
11921 @@ -184,7 +219,25 @@ static int show_map_internal(struct seq_
11922         }
11923         seq_putc(m, '\n');
11924  
11925 -       if (mss)
11926 +       
11927 +       if (mss) {
11928 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11929 +           if (PAX_RAND_FLAGS(mm))
11930 +               seq_printf(m,
11931 +                          "Size:          %8lu kB\n"
11932 +                          "Rss:           %8lu kB\n"
11933 +                          "Shared_Clean:  %8lu kB\n"
11934 +                          "Shared_Dirty:  %8lu kB\n"
11935 +                          "Private_Clean: %8lu kB\n"
11936 +                          "Private_Dirty: %8lu kB\n",
11937 +                          0UL,
11938 +                          0UL,
11939 +                          0UL,
11940 +                          0UL,
11941 +                          0UL,
11942 +                          0UL);
11943 +           else
11944 +#endif
11945                 seq_printf(m,
11946                            "Size:          %8lu kB\n"
11947                            "Rss:           %8lu kB\n"
11948 @@ -198,6 +251,7 @@ static int show_map_internal(struct seq_
11949                            mss->shared_dirty  >> 10,
11950                            mss->private_clean >> 10,
11951                            mss->private_dirty >> 10);
11952 +       }
11953  
11954         if (m->count < m->size)  /* vma is copied successfully */
11955                 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
11956 diff -urNp linux-2.6.18/fs/readdir.c linux-2.6.18/fs/readdir.c
11957 --- linux-2.6.18/fs/readdir.c   2006-09-19 23:42:06.000000000 -0400
11958 +++ linux-2.6.18/fs/readdir.c   2006-09-22 20:04:35.000000000 -0400
11959 @@ -16,6 +16,8 @@
11960  #include <linux/security.h>
11961  #include <linux/syscalls.h>
11962  #include <linux/unistd.h>
11963 +#include <linux/namei.h>
11964 +#include <linux/grsecurity.h>
11965  
11966  #include <asm/uaccess.h>
11967  
11968 @@ -65,6 +67,7 @@ struct old_linux_dirent {
11969  
11970  struct readdir_callback {
11971         struct old_linux_dirent __user * dirent;
11972 +       struct file * file;
11973         int result;
11974  };
11975  
11976 @@ -76,6 +79,10 @@ static int fillonedir(void * __buf, cons
11977  
11978         if (buf->result)
11979                 return -EINVAL;
11980 +
11981 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
11982 +               return 0;
11983 +
11984         buf->result++;
11985         dirent = buf->dirent;
11986         if (!access_ok(VERIFY_WRITE, dirent,
11987 @@ -107,6 +114,7 @@ asmlinkage long old_readdir(unsigned int
11988  
11989         buf.result = 0;
11990         buf.dirent = dirent;
11991 +       buf.file = file;
11992  
11993         error = vfs_readdir(file, fillonedir, &buf);
11994         if (error >= 0)
11995 @@ -133,6 +141,7 @@ struct linux_dirent {
11996  struct getdents_callback {
11997         struct linux_dirent __user * current_dir;
11998         struct linux_dirent __user * previous;
11999 +       struct file * file;
12000         int count;
12001         int error;
12002  };
12003 @@ -147,6 +156,10 @@ static int filldir(void * __buf, const c
12004         buf->error = -EINVAL;   /* only used if we fail.. */
12005         if (reclen > buf->count)
12006                 return -EINVAL;
12007 +
12008 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
12009 +               return 0;
12010 +
12011         dirent = buf->previous;
12012         if (dirent) {
12013                 if (__put_user(offset, &dirent->d_off))
12014 @@ -191,6 +204,7 @@ asmlinkage long sys_getdents(unsigned in
12015  
12016         buf.current_dir = dirent;
12017         buf.previous = NULL;
12018 +       buf.file = file;
12019         buf.count = count;
12020         buf.error = 0;
12021  
12022 @@ -217,6 +231,7 @@ out:
12023  struct getdents_callback64 {
12024         struct linux_dirent64 __user * current_dir;
12025         struct linux_dirent64 __user * previous;
12026 +       struct file * file;
12027         int count;
12028         int error;
12029  };
12030 @@ -231,6 +246,10 @@ static int filldir64(void * __buf, const
12031         buf->error = -EINVAL;   /* only used if we fail.. */
12032         if (reclen > buf->count)
12033                 return -EINVAL;
12034 +
12035 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
12036 +               return 0;
12037 +
12038         dirent = buf->previous;
12039         if (dirent) {
12040                 if (__put_user(offset, &dirent->d_off))
12041 @@ -277,6 +296,7 @@ asmlinkage long sys_getdents64(unsigned 
12042  
12043         buf.current_dir = dirent;
12044         buf.previous = NULL;
12045 +       buf.file = file;
12046         buf.count = count;
12047         buf.error = 0;
12048  
12049 diff -urNp linux-2.6.18/fs/udf/balloc.c linux-2.6.18/fs/udf/balloc.c
12050 --- linux-2.6.18/fs/udf/balloc.c        2006-09-19 23:42:06.000000000 -0400
12051 +++ linux-2.6.18/fs/udf/balloc.c        2006-09-22 20:45:04.000000000 -0400
12052 @@ -153,8 +153,7 @@ static void udf_bitmap_free_blocks(struc
12053         unsigned long overflow;
12054  
12055         mutex_lock(&sbi->s_alloc_mutex);
12056 -       if (bloc.logicalBlockNum < 0 ||
12057 -               (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
12058 +       if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
12059         {
12060                 udf_debug("%d < %d || %d + %d > %d\n",
12061                         bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
12062 @@ -227,7 +226,7 @@ static int udf_bitmap_prealloc_blocks(st
12063         struct buffer_head *bh;
12064  
12065         mutex_lock(&sbi->s_alloc_mutex);
12066 -       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
12067 +       if (first_block >= UDF_SB_PARTLEN(sb, partition))
12068                 goto out;
12069  
12070         if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
12071 @@ -294,7 +293,7 @@ static int udf_bitmap_new_block(struct s
12072         mutex_lock(&sbi->s_alloc_mutex);
12073  
12074  repeat:
12075 -       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
12076 +       if (goal >= UDF_SB_PARTLEN(sb, partition))
12077                 goal = 0;
12078  
12079         nr_groups = bitmap->s_nr_groups;
12080 @@ -434,8 +433,7 @@ static void udf_table_free_blocks(struct
12081         int i;
12082  
12083         mutex_lock(&sbi->s_alloc_mutex);
12084 -       if (bloc.logicalBlockNum < 0 ||
12085 -               (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
12086 +       if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
12087         {
12088                 udf_debug("%d < %d || %d + %d > %d\n",
12089                         bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
12090 @@ -682,7 +680,7 @@ static int udf_table_prealloc_blocks(str
12091         struct buffer_head *bh;
12092         int8_t etype = -1;
12093  
12094 -       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
12095 +       if (first_block >= UDF_SB_PARTLEN(sb, partition))
12096                 return 0;
12097  
12098         if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
12099 @@ -762,7 +760,7 @@ static int udf_table_new_block(struct su
12100                 return newblock;
12101  
12102         mutex_lock(&sbi->s_alloc_mutex);
12103 -       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
12104 +       if (goal >= UDF_SB_PARTLEN(sb, partition))
12105                 goal = 0;
12106  
12107         /* We search for the closest matching block to goal. If we find a exact hit,
12108 diff -urNp linux-2.6.18/fs/udf/inode.c linux-2.6.18/fs/udf/inode.c
12109 --- linux-2.6.18/fs/udf/inode.c 2006-09-19 23:42:06.000000000 -0400
12110 +++ linux-2.6.18/fs/udf/inode.c 2006-09-22 20:45:04.000000000 -0400
12111 @@ -300,9 +300,6 @@ static int udf_get_block(struct inode *i
12112  
12113         lock_kernel();
12114  
12115 -       if (block < 0)
12116 -               goto abort_negative;
12117 -
12118         if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
12119         {
12120                 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
12121 @@ -323,10 +320,6 @@ static int udf_get_block(struct inode *i
12122  abort:
12123         unlock_kernel();
12124         return err;
12125 -
12126 -abort_negative:
12127 -       udf_warning(inode->i_sb, "udf_get_block", "block < 0");
12128 -       goto abort;
12129  }
12130  
12131  static struct buffer_head *
12132 diff -urNp linux-2.6.18/fs/ufs/inode.c linux-2.6.18/fs/ufs/inode.c
12133 --- linux-2.6.18/fs/ufs/inode.c 2006-09-19 23:42:06.000000000 -0400
12134 +++ linux-2.6.18/fs/ufs/inode.c 2006-09-22 20:45:04.000000000 -0400
12135 @@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
12136  
12137  
12138         UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
12139 -       if (i_block < 0) {
12140 -               ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
12141 -       } else if (i_block < direct_blocks) {
12142 +       if (i_block < direct_blocks) {
12143                 offsets[n++] = i_block;
12144         } else if ((i_block -= direct_blocks) < indirect_blocks) {
12145                 offsets[n++] = UFS_IND_BLOCK;
12146 @@ -454,8 +452,6 @@ int ufs_getfrag_block(struct inode *inod
12147         lock_kernel();
12148  
12149         UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
12150 -       if (fragment < 0)
12151 -               goto abort_negative;
12152         if (fragment >
12153             ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
12154              << uspi->s_fpbshift))
12155 @@ -516,10 +512,6 @@ abort:
12156         unlock_kernel();
12157         return err;
12158  
12159 -abort_negative:
12160 -       ufs_warning(sb, "ufs_get_block", "block < 0");
12161 -       goto abort;
12162 -
12163  abort_too_big:
12164         ufs_warning(sb, "ufs_get_block", "block > big");
12165         goto abort;
12166 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
12167 --- linux-2.6.18/fs/xfs/linux-2.6/xfs_file.c    2006-09-19 23:42:06.000000000 -0400
12168 +++ linux-2.6.18/fs/xfs/linux-2.6/xfs_file.c    2006-09-22 20:45:04.000000000 -0400
12169 @@ -432,6 +432,12 @@ xfs_file_mmap(
12170         struct file     *filp,
12171         struct vm_area_struct *vma)
12172  {
12173 +
12174 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
12175 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
12176 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
12177 +#endif
12178 +
12179         vma->vm_ops = &xfs_file_vm_ops;
12180  
12181  #ifdef CONFIG_XFS_DMAPI
12182 diff -urNp linux-2.6.18/fs/xfs/xfs_bmap.c linux-2.6.18/fs/xfs/xfs_bmap.c
12183 --- linux-2.6.18/fs/xfs/xfs_bmap.c      2006-09-19 23:42:06.000000000 -0400
12184 +++ linux-2.6.18/fs/xfs/xfs_bmap.c      2006-09-22 20:45:04.000000000 -0400
12185 @@ -376,7 +376,7 @@ xfs_bmap_validate_ret(
12186         int                     nmap,
12187         int                     ret_nmap);
12188  #else
12189 -#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
12190 +#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
12191  #endif /* DEBUG */
12192  
12193  #if defined(XFS_RW_TRACE)
12194 diff -urNp linux-2.6.18/grsecurity/gracl_alloc.c linux-2.6.18/grsecurity/gracl_alloc.c
12195 --- linux-2.6.18/grsecurity/gracl_alloc.c       1969-12-31 19:00:00.000000000 -0500
12196 +++ linux-2.6.18/grsecurity/gracl_alloc.c       2006-09-22 20:04:35.000000000 -0400
12197 @@ -0,0 +1,91 @@
12198 +#include <linux/kernel.h>
12199 +#include <linux/mm.h>
12200 +#include <linux/slab.h>
12201 +#include <linux/vmalloc.h>
12202 +#include <linux/gracl.h>
12203 +#include <linux/grsecurity.h>
12204 +
12205 +static unsigned long alloc_stack_next = 1;
12206 +static unsigned long alloc_stack_size = 1;
12207 +static void **alloc_stack;
12208 +
12209 +static __inline__ int
12210 +alloc_pop(void)
12211 +{
12212 +       if (alloc_stack_next == 1)
12213 +               return 0;
12214 +
12215 +       kfree(alloc_stack[alloc_stack_next - 2]);
12216 +
12217 +       alloc_stack_next--;
12218 +
12219 +       return 1;
12220 +}
12221 +
12222 +static __inline__ void
12223 +alloc_push(void *buf)
12224 +{
12225 +       if (alloc_stack_next >= alloc_stack_size)
12226 +               BUG();
12227 +
12228 +       alloc_stack[alloc_stack_next - 1] = buf;
12229 +
12230 +       alloc_stack_next++;
12231 +
12232 +       return;
12233 +}
12234 +
12235 +void *
12236 +acl_alloc(unsigned long len)
12237 +{
12238 +       void *ret;
12239 +
12240 +       if (len > PAGE_SIZE)
12241 +               BUG();
12242 +
12243 +       ret = kmalloc(len, GFP_KERNEL);
12244 +
12245 +       if (ret)
12246 +               alloc_push(ret);
12247 +
12248 +       return ret;
12249 +}
12250 +
12251 +void
12252 +acl_free_all(void)
12253 +{
12254 +       if (gr_acl_is_enabled() || !alloc_stack)
12255 +               return;
12256 +
12257 +       while (alloc_pop()) ;
12258 +
12259 +       if (alloc_stack) {
12260 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
12261 +                       kfree(alloc_stack);
12262 +               else
12263 +                       vfree(alloc_stack);
12264 +       }
12265 +
12266 +       alloc_stack = NULL;
12267 +       alloc_stack_size = 1;
12268 +       alloc_stack_next = 1;
12269 +
12270 +       return;
12271 +}
12272 +
12273 +int
12274 +acl_alloc_stack_init(unsigned long size)
12275 +{
12276 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
12277 +               alloc_stack =
12278 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
12279 +       else
12280 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
12281 +
12282 +       alloc_stack_size = size;
12283 +
12284 +       if (!alloc_stack)
12285 +               return 0;
12286 +       else
12287 +               return 1;
12288 +}
12289 diff -urNp linux-2.6.18/grsecurity/gracl.c linux-2.6.18/grsecurity/gracl.c
12290 --- linux-2.6.18/grsecurity/gracl.c     1969-12-31 19:00:00.000000000 -0500
12291 +++ linux-2.6.18/grsecurity/gracl.c     2006-09-22 20:04:35.000000000 -0400
12292 @@ -0,0 +1,3547 @@
12293 +#include <linux/kernel.h>
12294 +#include <linux/module.h>
12295 +#include <linux/sched.h>
12296 +#include <linux/mm.h>
12297 +#include <linux/file.h>
12298 +#include <linux/fs.h>
12299 +#include <linux/namei.h>
12300 +#include <linux/mount.h>
12301 +#include <linux/tty.h>
12302 +#include <linux/proc_fs.h>
12303 +#include <linux/smp_lock.h>
12304 +#include <linux/slab.h>
12305 +#include <linux/vmalloc.h>
12306 +#include <linux/types.h>
12307 +#include <linux/capability.h>
12308 +#include <linux/sysctl.h>
12309 +#include <linux/netdevice.h>
12310 +#include <linux/ptrace.h>
12311 +#include <linux/gracl.h>
12312 +#include <linux/gralloc.h>
12313 +#include <linux/grsecurity.h>
12314 +#include <linux/grinternal.h>
12315 +#include <linux/percpu.h>
12316 +
12317 +#include <asm/uaccess.h>
12318 +#include <asm/errno.h>
12319 +#include <asm/mman.h>
12320 +
12321 +static struct acl_role_db acl_role_set;
12322 +static struct name_db name_set;
12323 +static struct inodev_db inodev_set;
12324 +
12325 +/* for keeping track of userspace pointers used for subjects, so we
12326 +   can share references in the kernel as well
12327 +*/
12328 +
12329 +static struct dentry *real_root;
12330 +static struct vfsmount *real_root_mnt;
12331 +
12332 +static struct acl_subj_map_db subj_map_set;
12333 +
12334 +static struct acl_role_label *default_role;
12335 +
12336 +static u16 acl_sp_role_value;
12337 +
12338 +extern char *gr_shared_page[4];
12339 +static DECLARE_MUTEX(gr_dev_sem);
12340 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
12341 +
12342 +struct gr_arg *gr_usermode;
12343 +
12344 +static unsigned int gr_status = GR_STATUS_INIT;
12345 +
12346 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
12347 +extern void gr_clear_learn_entries(void);
12348 +
12349 +#ifdef CONFIG_GRKERNSEC_RESLOG
12350 +extern void gr_log_resource(const struct task_struct *task,
12351 +                           const int res, const unsigned long wanted, const int gt);
12352 +#endif
12353 +
12354 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
12355 +                        struct dentry *root, struct vfsmount *rootmnt,
12356 +                        char *buffer, int buflen);
12357 +
12358 +unsigned char *gr_system_salt;
12359 +unsigned char *gr_system_sum;
12360 +
12361 +static struct sprole_pw **acl_special_roles = NULL;
12362 +static __u16 num_sprole_pws = 0;
12363 +
12364 +static struct acl_role_label *kernel_role = NULL;
12365 +
12366 +static unsigned int gr_auth_attempts = 0;
12367 +static unsigned long gr_auth_expires = 0UL;
12368 +
12369 +extern struct vfsmount *sock_mnt;
12370 +extern struct vfsmount *pipe_mnt;
12371 +extern struct vfsmount *shm_mnt;
12372 +static struct acl_object_label *fakefs_obj;
12373 +
12374 +extern int gr_init_uidset(void);
12375 +extern void gr_free_uidset(void);
12376 +extern void gr_remove_uid(uid_t uid);
12377 +extern int gr_find_uid(uid_t uid);
12378 +
12379 +__inline__ int
12380 +gr_acl_is_enabled(void)
12381 +{
12382 +       return (gr_status & GR_READY);
12383 +}
12384 +
12385 +char gr_roletype_to_char(void)
12386 +{
12387 +       switch (current->role->roletype &
12388 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
12389 +                GR_ROLE_SPECIAL)) {
12390 +       case GR_ROLE_DEFAULT:
12391 +               return 'D';
12392 +       case GR_ROLE_USER:
12393 +               return 'U';
12394 +       case GR_ROLE_GROUP:
12395 +               return 'G';
12396 +       case GR_ROLE_SPECIAL:
12397 +               return 'S';
12398 +       }
12399 +
12400 +       return 'X';
12401 +}
12402 +
12403 +__inline__ int
12404 +gr_acl_tpe_check(void)
12405 +{
12406 +       if (unlikely(!(gr_status & GR_READY)))
12407 +               return 0;
12408 +       if (current->role->roletype & GR_ROLE_TPE)
12409 +               return 1;
12410 +       else
12411 +               return 0;
12412 +}
12413 +
12414 +int
12415 +gr_handle_rawio(const struct inode *inode)
12416 +{
12417 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12418 +       if (inode && S_ISBLK(inode->i_mode) &&
12419 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
12420 +           !capable(CAP_SYS_RAWIO))
12421 +               return 1;
12422 +#endif
12423 +       return 0;
12424 +}
12425 +
12426 +static int
12427 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
12428 +{
12429 +       int i;
12430 +       unsigned long *l1;
12431 +       unsigned long *l2;
12432 +       unsigned char *c1;
12433 +       unsigned char *c2;
12434 +       int num_longs;
12435 +
12436 +       if (likely(lena != lenb))
12437 +               return 0;
12438 +
12439 +       l1 = (unsigned long *)a;
12440 +       l2 = (unsigned long *)b;
12441 +
12442 +       num_longs = lena / sizeof(unsigned long);
12443 +
12444 +       for (i = num_longs; i--; l1++, l2++) {
12445 +               if (unlikely(*l1 != *l2))
12446 +                       return 0;
12447 +       }
12448 +
12449 +       c1 = (unsigned char *) l1;
12450 +       c2 = (unsigned char *) l2;
12451 +
12452 +       i = lena - (num_longs * sizeof(unsigned long)); 
12453 +
12454 +       for (; i--; c1++, c2++) {
12455 +               if (unlikely(*c1 != *c2))
12456 +                       return 0;
12457 +       }
12458 +
12459 +       return 1;
12460 +}
12461 +               
12462 +static char *
12463 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
12464 +              struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
12465 +{
12466 +       char *end = buf + buflen;
12467 +       char *retval;
12468 +       int namelen = 0;
12469 +
12470 +       *--end = '\0';
12471 +
12472 +       retval = end - 1;
12473 +       *retval = '/';
12474 +
12475 +       if (dentry == root && vfsmnt == rootmnt)
12476 +               return retval;
12477 +       if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
12478 +               namelen = strlen(dentry->d_name.name);
12479 +               buflen -= namelen;
12480 +               if (buflen < 2)
12481 +                       goto err;
12482 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
12483 +                       buflen--;
12484 +       }
12485 +
12486 +       retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
12487 +       if (unlikely(IS_ERR(retval)))
12488 +err:
12489 +               retval = strcpy(buf, "<path too long>");
12490 +       else if (namelen != 0) {
12491 +               end = buf + buflen - 1; // accounts for null termination
12492 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
12493 +                       *end++ = '/'; // accounted for above with buflen--
12494 +               memcpy(end, dentry->d_name.name, namelen);
12495 +       }
12496 +
12497 +       return retval;
12498 +}
12499 +
12500 +static char *
12501 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
12502 +               char *buf, int buflen)
12503 +{
12504 +       char *res;
12505 +
12506 +       /* we can use real_root, real_root_mnt, because this is only called
12507 +          by the RBAC system */
12508 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
12509 +
12510 +       return res;
12511 +}
12512 +
12513 +static char *
12514 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
12515 +           char *buf, int buflen)
12516 +{
12517 +       char *res;
12518 +       struct dentry *root;
12519 +       struct vfsmount *rootmnt;
12520 +
12521 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
12522 +       read_lock(&child_reaper->fs->lock);
12523 +       root = dget(child_reaper->fs->root);
12524 +       rootmnt = mntget(child_reaper->fs->rootmnt);
12525 +       read_unlock(&child_reaper->fs->lock);
12526 +
12527 +       spin_lock(&dcache_lock);
12528 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
12529 +       spin_unlock(&dcache_lock);
12530 +
12531 +       dput(root);
12532 +       mntput(rootmnt);
12533 +       return res;
12534 +}
12535 +
12536 +static char *
12537 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
12538 +{
12539 +       char *ret;
12540 +       spin_lock(&dcache_lock);
12541 +       ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
12542 +                            PAGE_SIZE);
12543 +       spin_unlock(&dcache_lock);
12544 +       return ret;
12545 +}
12546 +
12547 +char *
12548 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
12549 +{
12550 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
12551 +                            PAGE_SIZE);
12552 +}
12553 +
12554 +char *
12555 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
12556 +{
12557 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
12558 +                          PAGE_SIZE);
12559 +}
12560 +
12561 +char *
12562 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
12563 +{
12564 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
12565 +                          PAGE_SIZE);
12566 +}
12567 +
12568 +char *
12569 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
12570 +{
12571 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
12572 +                          PAGE_SIZE);
12573 +}
12574 +
12575 +char *
12576 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
12577 +{
12578 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
12579 +                          PAGE_SIZE);
12580 +}
12581 +
12582 +__inline__ __u32
12583 +to_gr_audit(const __u32 reqmode)
12584 +{
12585 +       /* masks off auditable permission flags, then shifts them to create
12586 +          auditing flags, and adds the special case of append auditing if
12587 +          we're requesting write */
12588 +       return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
12589 +}
12590 +
12591 +struct acl_subject_label *
12592 +lookup_subject_map(const struct acl_subject_label *userp)
12593 +{
12594 +       unsigned int index = shash(userp, subj_map_set.s_size);
12595 +       struct subject_map *match;
12596 +
12597 +       match = subj_map_set.s_hash[index];
12598 +
12599 +       while (match && match->user != userp)
12600 +               match = match->next;
12601 +
12602 +       if (match != NULL)
12603 +               return match->kernel;
12604 +       else
12605 +               return NULL;
12606 +}
12607 +
12608 +static void
12609 +insert_subj_map_entry(struct subject_map *subjmap)
12610 +{
12611 +       unsigned int index = shash(subjmap->user, subj_map_set.s_size);
12612 +       struct subject_map **curr;
12613 +
12614 +       subjmap->prev = NULL;
12615 +
12616 +       curr = &subj_map_set.s_hash[index];
12617 +       if (*curr != NULL)
12618 +               (*curr)->prev = subjmap;
12619 +
12620 +       subjmap->next = *curr;
12621 +       *curr = subjmap;
12622 +
12623 +       return;
12624 +}
12625 +
12626 +static struct acl_role_label *
12627 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
12628 +                     const gid_t gid)
12629 +{
12630 +       unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
12631 +       struct acl_role_label *match;
12632 +       struct role_allowed_ip *ipp;
12633 +       unsigned int x;
12634 +
12635 +       match = acl_role_set.r_hash[index];
12636 +
12637 +       while (match) {
12638 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
12639 +                       for (x = 0; x < match->domain_child_num; x++) {
12640 +                               if (match->domain_children[x] == uid)
12641 +                                       goto found;
12642 +                       }
12643 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
12644 +                       break;
12645 +               match = match->next;
12646 +       }
12647 +found:
12648 +       if (match == NULL) {
12649 +             try_group:
12650 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
12651 +               match = acl_role_set.r_hash[index];
12652 +
12653 +               while (match) {
12654 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
12655 +                               for (x = 0; x < match->domain_child_num; x++) {
12656 +                                       if (match->domain_children[x] == gid)
12657 +                                               goto found2;
12658 +                               }
12659 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
12660 +                               break;
12661 +                       match = match->next;
12662 +               }
12663 +found2:
12664 +               if (match == NULL)
12665 +                       match = default_role;
12666 +               if (match->allowed_ips == NULL)
12667 +                       return match;
12668 +               else {
12669 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
12670 +                               if (likely
12671 +                                   ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
12672 +                                    (ntohl(ipp->addr) & ipp->netmask)))
12673 +                                       return match;
12674 +                       }
12675 +                       match = default_role;
12676 +               }
12677 +       } else if (match->allowed_ips == NULL) {
12678 +               return match;
12679 +       } else {
12680 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
12681 +                       if (likely
12682 +                           ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
12683 +                            (ntohl(ipp->addr) & ipp->netmask)))
12684 +                               return match;
12685 +               }
12686 +               goto try_group;
12687 +       }
12688 +
12689 +       return match;
12690 +}
12691 +
12692 +struct acl_subject_label *
12693 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
12694 +                     const struct acl_role_label *role)
12695 +{
12696 +       unsigned int index = fhash(ino, dev, role->subj_hash_size);
12697 +       struct acl_subject_label *match;
12698 +
12699 +       match = role->subj_hash[index];
12700 +
12701 +       while (match && (match->inode != ino || match->device != dev ||
12702 +              (match->mode & GR_DELETED))) {
12703 +               match = match->next;
12704 +       }
12705 +
12706 +       if (match && !(match->mode & GR_DELETED))
12707 +               return match;
12708 +       else
12709 +               return NULL;
12710 +}
12711 +
12712 +static struct acl_object_label *
12713 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
12714 +                    const struct acl_subject_label *subj)
12715 +{
12716 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
12717 +       struct acl_object_label *match;
12718 +
12719 +       match = subj->obj_hash[index];
12720 +
12721 +       while (match && (match->inode != ino || match->device != dev ||
12722 +              (match->mode & GR_DELETED))) {
12723 +               match = match->next;
12724 +       }
12725 +
12726 +       if (match && !(match->mode & GR_DELETED))
12727 +               return match;
12728 +       else
12729 +               return NULL;
12730 +}
12731 +
12732 +static struct acl_object_label *
12733 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
12734 +                    const struct acl_subject_label *subj)
12735 +{
12736 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
12737 +       struct acl_object_label *match;
12738 +
12739 +       match = subj->obj_hash[index];
12740 +
12741 +       while (match && (match->inode != ino || match->device != dev ||
12742 +              !(match->mode & GR_DELETED))) {
12743 +               match = match->next;
12744 +       }
12745 +
12746 +       if (match && (match->mode & GR_DELETED))
12747 +               return match;
12748 +
12749 +       match = subj->obj_hash[index];
12750 +
12751 +       while (match && (match->inode != ino || match->device != dev ||
12752 +              (match->mode & GR_DELETED))) {
12753 +               match = match->next;
12754 +       }
12755 +
12756 +       if (match && !(match->mode & GR_DELETED))
12757 +               return match;
12758 +       else
12759 +               return NULL;
12760 +}
12761 +
12762 +static struct name_entry *
12763 +lookup_name_entry(const char *name)
12764 +{
12765 +       unsigned int len = strlen(name);
12766 +       unsigned int key = full_name_hash(name, len);
12767 +       unsigned int index = key % name_set.n_size;
12768 +       struct name_entry *match;
12769 +
12770 +       match = name_set.n_hash[index];
12771 +
12772 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
12773 +               match = match->next;
12774 +
12775 +       return match;
12776 +}
12777 +
12778 +static struct inodev_entry *
12779 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
12780 +{
12781 +       unsigned int index = fhash(ino, dev, inodev_set.i_size);
12782 +       struct inodev_entry *match;
12783 +
12784 +       match = inodev_set.i_hash[index];
12785 +
12786 +       while (match && (match->nentry->inode != ino || match->nentry->device != dev))
12787 +               match = match->next;
12788 +
12789 +       return match;
12790 +}
12791 +
12792 +static void
12793 +insert_inodev_entry(struct inodev_entry *entry)
12794 +{
12795 +       unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
12796 +                                   inodev_set.i_size);
12797 +       struct inodev_entry **curr;
12798 +
12799 +       entry->prev = NULL;
12800 +
12801 +       curr = &inodev_set.i_hash[index];
12802 +       if (*curr != NULL)
12803 +               (*curr)->prev = entry;
12804 +       
12805 +       entry->next = *curr;
12806 +       *curr = entry;
12807 +
12808 +       return;
12809 +}
12810 +
12811 +static void
12812 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
12813 +{
12814 +       unsigned int index =
12815 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
12816 +       struct acl_role_label **curr;
12817 +
12818 +       role->prev = NULL;
12819 +
12820 +       curr = &acl_role_set.r_hash[index];
12821 +       if (*curr != NULL)
12822 +               (*curr)->prev = role;
12823 +
12824 +       role->next = *curr;
12825 +       *curr = role;
12826 +
12827 +       return;
12828 +}
12829 +
12830 +static void
12831 +insert_acl_role_label(struct acl_role_label *role)
12832 +{
12833 +       int i;
12834 +
12835 +       if (role->roletype & GR_ROLE_DOMAIN) {
12836 +               for (i = 0; i < role->domain_child_num; i++)
12837 +                       __insert_acl_role_label(role, role->domain_children[i]);
12838 +       } else
12839 +               __insert_acl_role_label(role, role->uidgid);
12840 +}
12841 +                                       
12842 +static int
12843 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
12844 +{
12845 +       struct name_entry **curr, *nentry;
12846 +       struct inodev_entry *ientry;
12847 +       unsigned int len = strlen(name);
12848 +       unsigned int key = full_name_hash(name, len);
12849 +       unsigned int index = key % name_set.n_size;
12850 +
12851 +       curr = &name_set.n_hash[index];
12852 +
12853 +       while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
12854 +               curr = &((*curr)->next);
12855 +
12856 +       if (*curr != NULL)
12857 +               return 1;
12858 +
12859 +       nentry = acl_alloc(sizeof (struct name_entry));
12860 +       if (nentry == NULL)
12861 +               return 0;
12862 +       ientry = acl_alloc(sizeof (struct inodev_entry));
12863 +       if (ientry == NULL)
12864 +               return 0;
12865 +       ientry->nentry = nentry;
12866 +
12867 +       nentry->key = key;
12868 +       nentry->name = name;
12869 +       nentry->inode = inode;
12870 +       nentry->device = device;
12871 +       nentry->len = len;
12872 +
12873 +       nentry->prev = NULL;
12874 +       curr = &name_set.n_hash[index];
12875 +       if (*curr != NULL)
12876 +               (*curr)->prev = nentry;
12877 +       nentry->next = *curr;
12878 +       *curr = nentry;
12879 +
12880 +       /* insert us into the table searchable by inode/dev */
12881 +       insert_inodev_entry(ientry);
12882 +
12883 +       return 1;
12884 +}
12885 +
12886 +static void
12887 +insert_acl_obj_label(struct acl_object_label *obj,
12888 +                    struct acl_subject_label *subj)
12889 +{
12890 +       unsigned int index =
12891 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
12892 +       struct acl_object_label **curr;
12893 +
12894 +       
12895 +       obj->prev = NULL;
12896 +
12897 +       curr = &subj->obj_hash[index];
12898 +       if (*curr != NULL)
12899 +               (*curr)->prev = obj;
12900 +
12901 +       obj->next = *curr;
12902 +       *curr = obj;
12903 +
12904 +       return;
12905 +}
12906 +
12907 +static void
12908 +insert_acl_subj_label(struct acl_subject_label *obj,
12909 +                     struct acl_role_label *role)
12910 +{
12911 +       unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
12912 +       struct acl_subject_label **curr;
12913 +
12914 +       obj->prev = NULL;
12915 +
12916 +       curr = &role->subj_hash[index];
12917 +       if (*curr != NULL)
12918 +               (*curr)->prev = obj;
12919 +
12920 +       obj->next = *curr;
12921 +       *curr = obj;
12922 +
12923 +       return;
12924 +}
12925 +
12926 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
12927 +
12928 +static void *
12929 +create_table(__u32 * len, int elementsize)
12930 +{
12931 +       unsigned int table_sizes[] = {
12932 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
12933 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
12934 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
12935 +               268435399, 536870909, 1073741789, 2147483647
12936 +       };
12937 +       void *newtable = NULL;
12938 +       unsigned int pwr = 0;
12939 +
12940 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
12941 +              table_sizes[pwr] <= *len)
12942 +               pwr++;
12943 +
12944 +       if (table_sizes[pwr] <= *len)
12945 +               return newtable;
12946 +
12947 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
12948 +               newtable =
12949 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
12950 +       else
12951 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
12952 +
12953 +       *len = table_sizes[pwr];
12954 +
12955 +       return newtable;
12956 +}
12957 +
12958 +static int
12959 +init_variables(const struct gr_arg *arg)
12960 +{
12961 +       unsigned int stacksize;
12962 +
12963 +       subj_map_set.s_size = arg->role_db.num_subjects;
12964 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
12965 +       name_set.n_size = arg->role_db.num_objects;
12966 +       inodev_set.i_size = arg->role_db.num_objects;
12967 +
12968 +       if (!subj_map_set.s_size || !acl_role_set.r_size ||
12969 +           !name_set.n_size || !inodev_set.i_size)
12970 +               return 1;
12971 +
12972 +       if (!gr_init_uidset())
12973 +               return 1;
12974 +
12975 +       /* set up the stack that holds allocation info */
12976 +
12977 +       stacksize = arg->role_db.num_pointers + 5;
12978 +
12979 +       if (!acl_alloc_stack_init(stacksize))
12980 +               return 1;
12981 +
12982 +       /* grab reference for the real root dentry and vfsmount */
12983 +       read_lock(&child_reaper->fs->lock);
12984 +       real_root_mnt = mntget(child_reaper->fs->rootmnt);
12985 +       real_root = dget(child_reaper->fs->root);
12986 +       read_unlock(&child_reaper->fs->lock);
12987 +       
12988 +       fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
12989 +       if (fakefs_obj == NULL)
12990 +               return 1;
12991 +       fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
12992 +
12993 +       subj_map_set.s_hash =
12994 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
12995 +       acl_role_set.r_hash =
12996 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
12997 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
12998 +       inodev_set.i_hash =
12999 +           (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
13000 +
13001 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
13002 +           !name_set.n_hash || !inodev_set.i_hash)
13003 +               return 1;
13004 +
13005 +       memset(subj_map_set.s_hash, 0,
13006 +              sizeof(struct subject_map *) * subj_map_set.s_size);
13007 +       memset(acl_role_set.r_hash, 0,
13008 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
13009 +       memset(name_set.n_hash, 0,
13010 +              sizeof (struct name_entry *) * name_set.n_size);
13011 +       memset(inodev_set.i_hash, 0,
13012 +              sizeof (struct inodev_entry *) * inodev_set.i_size);
13013 +
13014 +       return 0;
13015 +}
13016 +
13017 +/* free information not needed after startup
13018 +   currently contains user->kernel pointer mappings for subjects
13019 +*/
13020 +
13021 +static void
13022 +free_init_variables(void)
13023 +{
13024 +       __u32 i;
13025 +
13026 +       if (subj_map_set.s_hash) {
13027 +               for (i = 0; i < subj_map_set.s_size; i++) {
13028 +                       if (subj_map_set.s_hash[i]) {
13029 +                               kfree(subj_map_set.s_hash[i]);
13030 +                               subj_map_set.s_hash[i] = NULL;
13031 +                       }
13032 +               }
13033 +
13034 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
13035 +                   PAGE_SIZE)
13036 +                       kfree(subj_map_set.s_hash);
13037 +               else
13038 +                       vfree(subj_map_set.s_hash);
13039 +       }
13040 +
13041 +       return;
13042 +}
13043 +
13044 +static void
13045 +free_variables(void)
13046 +{
13047 +       struct acl_subject_label *s;
13048 +       struct acl_role_label *r;
13049 +       struct task_struct *task, *task2;
13050 +       unsigned int i, x;
13051 +
13052 +       gr_clear_learn_entries();
13053 +
13054 +       read_lock(&tasklist_lock);
13055 +       do_each_thread(task2, task) {
13056 +               task->acl_sp_role = 0;
13057 +               task->acl_role_id = 0;
13058 +               task->acl = NULL;
13059 +               task->role = NULL;
13060 +       } while_each_thread(task2, task);
13061 +       read_unlock(&tasklist_lock);
13062 +
13063 +       /* release the reference to the real root dentry and vfsmount */
13064 +       if (real_root)
13065 +               dput(real_root);
13066 +       real_root = NULL;
13067 +       if (real_root_mnt)
13068 +               mntput(real_root_mnt);
13069 +       real_root_mnt = NULL;
13070 +
13071 +       /* free all object hash tables */
13072 +
13073 +       FOR_EACH_ROLE_START(r, i)
13074 +               if (r->subj_hash == NULL)
13075 +                       break;
13076 +               FOR_EACH_SUBJECT_START(r, s, x)
13077 +                       if (s->obj_hash == NULL)
13078 +                               break;
13079 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
13080 +                               kfree(s->obj_hash);
13081 +                       else
13082 +                               vfree(s->obj_hash);
13083 +               FOR_EACH_SUBJECT_END(s, x)
13084 +               FOR_EACH_NESTED_SUBJECT_START(r, s)
13085 +                       if (s->obj_hash == NULL)
13086 +                               break;
13087 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
13088 +                               kfree(s->obj_hash);
13089 +                       else
13090 +                               vfree(s->obj_hash);
13091 +               FOR_EACH_NESTED_SUBJECT_END(s)
13092 +               if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
13093 +                       kfree(r->subj_hash);
13094 +               else
13095 +                       vfree(r->subj_hash);
13096 +               r->subj_hash = NULL;
13097 +       FOR_EACH_ROLE_END(r,i)
13098 +
13099 +       acl_free_all();
13100 +
13101 +       if (acl_role_set.r_hash) {
13102 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
13103 +                   PAGE_SIZE)
13104 +                       kfree(acl_role_set.r_hash);
13105 +               else
13106 +                       vfree(acl_role_set.r_hash);
13107 +       }
13108 +       if (name_set.n_hash) {
13109 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
13110 +                   PAGE_SIZE)
13111 +                       kfree(name_set.n_hash);
13112 +               else
13113 +                       vfree(name_set.n_hash);
13114 +       }
13115 +
13116 +       if (inodev_set.i_hash) {
13117 +               if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
13118 +                   PAGE_SIZE)
13119 +                       kfree(inodev_set.i_hash);
13120 +               else
13121 +                       vfree(inodev_set.i_hash);
13122 +       }
13123 +
13124 +       gr_free_uidset();
13125 +
13126 +       memset(&name_set, 0, sizeof (struct name_db));
13127 +       memset(&inodev_set, 0, sizeof (struct inodev_db));
13128 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
13129 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
13130 +
13131 +       default_role = NULL;
13132 +
13133 +       return;
13134 +}
13135 +
13136 +static __u32
13137 +count_user_objs(struct acl_object_label *userp)
13138 +{
13139 +       struct acl_object_label o_tmp;
13140 +       __u32 num = 0;
13141 +
13142 +       while (userp) {
13143 +               if (copy_from_user(&o_tmp, userp,
13144 +                                  sizeof (struct acl_object_label)))
13145 +                       break;
13146 +
13147 +               userp = o_tmp.prev;
13148 +               num++;
13149 +       }
13150 +
13151 +       return num;
13152 +}
13153 +
13154 +static struct acl_subject_label *
13155 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
13156 +
13157 +static int
13158 +copy_user_glob(struct acl_object_label *obj)
13159 +{
13160 +       struct acl_object_label *g_tmp, **guser;
13161 +       unsigned int len;
13162 +       char *tmp;
13163 +
13164 +       if (obj->globbed == NULL)
13165 +               return 0;
13166 +
13167 +       guser = &obj->globbed;
13168 +       while (*guser) {
13169 +               g_tmp = (struct acl_object_label *)
13170 +                       acl_alloc(sizeof (struct acl_object_label));
13171 +               if (g_tmp == NULL)
13172 +                       return -ENOMEM;
13173 +
13174 +               if (copy_from_user(g_tmp, *guser,
13175 +                                  sizeof (struct acl_object_label)))
13176 +                       return -EFAULT;
13177 +
13178 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
13179 +
13180 +               if (!len || len >= PATH_MAX)
13181 +                       return -EINVAL;
13182 +
13183 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
13184 +                       return -ENOMEM;
13185 +
13186 +               if (copy_from_user(tmp, g_tmp->filename, len))
13187 +                       return -EFAULT;
13188 +
13189 +               g_tmp->filename = tmp;
13190 +
13191 +               *guser = g_tmp;
13192 +               guser = &(g_tmp->next);
13193 +       }
13194 +
13195 +       return 0;
13196 +}
13197 +
13198 +static int
13199 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
13200 +              struct acl_role_label *role)
13201 +{
13202 +       struct acl_object_label *o_tmp;
13203 +       unsigned int len;
13204 +       int ret;
13205 +       char *tmp;
13206 +
13207 +       while (userp) {
13208 +               if ((o_tmp = (struct acl_object_label *)
13209 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
13210 +                       return -ENOMEM;
13211 +
13212 +               if (copy_from_user(o_tmp, userp,
13213 +                                  sizeof (struct acl_object_label)))
13214 +                       return -EFAULT;
13215 +
13216 +               userp = o_tmp->prev;
13217 +
13218 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
13219 +
13220 +               if (!len || len >= PATH_MAX)
13221 +                       return -EINVAL;
13222 +
13223 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
13224 +                       return -ENOMEM;
13225 +
13226 +               if (copy_from_user(tmp, o_tmp->filename, len))
13227 +                       return -EFAULT;
13228 +
13229 +               o_tmp->filename = tmp;
13230 +
13231 +               insert_acl_obj_label(o_tmp, subj);
13232 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
13233 +                                      o_tmp->device))
13234 +                       return -ENOMEM;
13235 +
13236 +               ret = copy_user_glob(o_tmp);
13237 +               if (ret)
13238 +                       return ret;
13239 +
13240 +               if (o_tmp->nested) {
13241 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
13242 +                       if (IS_ERR(o_tmp->nested))
13243 +                               return PTR_ERR(o_tmp->nested);
13244 +
13245 +                       /* insert into nested subject list */
13246 +                       o_tmp->nested->next = role->hash->first;
13247 +                       role->hash->first = o_tmp->nested;
13248 +               }
13249 +       }
13250 +
13251 +       return 0;
13252 +}
13253 +
13254 +static __u32
13255 +count_user_subjs(struct acl_subject_label *userp)
13256 +{
13257 +       struct acl_subject_label s_tmp;
13258 +       __u32 num = 0;
13259 +
13260 +       while (userp) {
13261 +               if (copy_from_user(&s_tmp, userp,
13262 +                                  sizeof (struct acl_subject_label)))
13263 +                       break;
13264 +
13265 +               userp = s_tmp.prev;
13266 +               /* do not count nested subjects against this count, since
13267 +                  they are not included in the hash table, but are
13268 +                  attached to objects.  We have already counted
13269 +                  the subjects in userspace for the allocation 
13270 +                  stack
13271 +               */
13272 +               if (!(s_tmp.mode & GR_NESTED))
13273 +                       num++;
13274 +       }
13275 +
13276 +       return num;
13277 +}
13278 +
13279 +static int
13280 +copy_user_allowedips(struct acl_role_label *rolep)
13281 +{
13282 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
13283 +
13284 +       ruserip = rolep->allowed_ips;
13285 +
13286 +       while (ruserip) {
13287 +               rlast = rtmp;
13288 +
13289 +               if ((rtmp = (struct role_allowed_ip *)
13290 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
13291 +                       return -ENOMEM;
13292 +
13293 +               if (copy_from_user(rtmp, ruserip,
13294 +                                  sizeof (struct role_allowed_ip)))
13295 +                       return -EFAULT;
13296 +
13297 +               ruserip = rtmp->prev;
13298 +
13299 +               if (!rlast) {
13300 +                       rtmp->prev = NULL;
13301 +                       rolep->allowed_ips = rtmp;
13302 +               } else {
13303 +                       rlast->next = rtmp;
13304 +                       rtmp->prev = rlast;
13305 +               }
13306 +
13307 +               if (!ruserip)
13308 +                       rtmp->next = NULL;
13309 +       }
13310 +
13311 +       return 0;
13312 +}
13313 +
13314 +static int
13315 +copy_user_transitions(struct acl_role_label *rolep)
13316 +{
13317 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
13318 +       
13319 +       unsigned int len;
13320 +       char *tmp;
13321 +
13322 +       rusertp = rolep->transitions;
13323 +
13324 +       while (rusertp) {
13325 +               rlast = rtmp;
13326 +
13327 +               if ((rtmp = (struct role_transition *)
13328 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
13329 +                       return -ENOMEM;
13330 +
13331 +               if (copy_from_user(rtmp, rusertp,
13332 +                                  sizeof (struct role_transition)))
13333 +                       return -EFAULT;
13334 +
13335 +               rusertp = rtmp->prev;
13336 +
13337 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
13338 +
13339 +               if (!len || len >= GR_SPROLE_LEN)
13340 +                       return -EINVAL;
13341 +
13342 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
13343 +                       return -ENOMEM;
13344 +
13345 +               if (copy_from_user(tmp, rtmp->rolename, len))
13346 +                       return -EFAULT;
13347 +
13348 +               rtmp->rolename = tmp;
13349 +
13350 +               if (!rlast) {
13351 +                       rtmp->prev = NULL;
13352 +                       rolep->transitions = rtmp;
13353 +               } else {
13354 +                       rlast->next = rtmp;
13355 +                       rtmp->prev = rlast;
13356 +               }
13357 +
13358 +               if (!rusertp)
13359 +                       rtmp->next = NULL;
13360 +       }
13361 +
13362 +       return 0;
13363 +}
13364 +
13365 +static struct acl_subject_label *
13366 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
13367 +{
13368 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
13369 +       unsigned int len;
13370 +       char *tmp;
13371 +       __u32 num_objs;
13372 +       struct acl_ip_label **i_tmp, *i_utmp2;
13373 +       struct gr_hash_struct ghash;
13374 +       struct subject_map *subjmap;
13375 +       unsigned int i_num;
13376 +       int err;
13377 +
13378 +       s_tmp = lookup_subject_map(userp);
13379 +
13380 +       /* we've already copied this subject into the kernel, just return
13381 +          the reference to it, and don't copy it over again
13382 +       */
13383 +       if (s_tmp)
13384 +               return(s_tmp);
13385 +
13386 +       if ((s_tmp = (struct acl_subject_label *)
13387 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
13388 +               return ERR_PTR(-ENOMEM);
13389 +
13390 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
13391 +       if (subjmap == NULL)
13392 +               return ERR_PTR(-ENOMEM);
13393 +
13394 +       subjmap->user = userp;
13395 +       subjmap->kernel = s_tmp;
13396 +       insert_subj_map_entry(subjmap);
13397 +
13398 +       if (copy_from_user(s_tmp, userp,
13399 +                          sizeof (struct acl_subject_label)))
13400 +               return ERR_PTR(-EFAULT);
13401 +
13402 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
13403 +
13404 +       if (!len || len >= PATH_MAX)
13405 +               return ERR_PTR(-EINVAL);
13406 +
13407 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
13408 +               return ERR_PTR(-ENOMEM);
13409 +
13410 +       if (copy_from_user(tmp, s_tmp->filename, len))
13411 +               return ERR_PTR(-EFAULT);
13412 +
13413 +       s_tmp->filename = tmp;
13414 +
13415 +       if (!strcmp(s_tmp->filename, "/"))
13416 +               role->root_label = s_tmp;
13417 +
13418 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
13419 +               return ERR_PTR(-EFAULT);
13420 +
13421 +       /* copy user and group transition tables */
13422 +
13423 +       if (s_tmp->user_trans_num) {
13424 +               uid_t *uidlist;
13425 +
13426 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
13427 +               if (uidlist == NULL)
13428 +                       return ERR_PTR(-ENOMEM);
13429 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
13430 +                       return ERR_PTR(-EFAULT);
13431 +
13432 +               s_tmp->user_transitions = uidlist;
13433 +       }
13434 +
13435 +       if (s_tmp->group_trans_num) {
13436 +               gid_t *gidlist;
13437 +
13438 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
13439 +               if (gidlist == NULL)
13440 +                       return ERR_PTR(-ENOMEM);
13441 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
13442 +                       return ERR_PTR(-EFAULT);
13443 +
13444 +               s_tmp->group_transitions = gidlist;
13445 +       }
13446 +
13447 +       /* set up object hash table */
13448 +       num_objs = count_user_objs(ghash.first);
13449 +
13450 +       s_tmp->obj_hash_size = num_objs;
13451 +       s_tmp->obj_hash =
13452 +           (struct acl_object_label **)
13453 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
13454 +
13455 +       if (!s_tmp->obj_hash)
13456 +               return ERR_PTR(-ENOMEM);
13457 +
13458 +       memset(s_tmp->obj_hash, 0,
13459 +              s_tmp->obj_hash_size *
13460 +              sizeof (struct acl_object_label *));
13461 +
13462 +       /* add in objects */
13463 +       err = copy_user_objs(ghash.first, s_tmp, role);
13464 +
13465 +       if (err)
13466 +               return ERR_PTR(err);
13467 +
13468 +       /* set pointer for parent subject */
13469 +       if (s_tmp->parent_subject) {
13470 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
13471 +
13472 +               if (IS_ERR(s_tmp2))
13473 +                       return s_tmp2;
13474 +
13475 +               s_tmp->parent_subject = s_tmp2;
13476 +       }
13477 +
13478 +       /* add in ip acls */
13479 +
13480 +       if (!s_tmp->ip_num) {
13481 +               s_tmp->ips = NULL;
13482 +               goto insert;
13483 +       }
13484 +
13485 +       i_tmp =
13486 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
13487 +                                              sizeof (struct
13488 +                                                      acl_ip_label *));
13489 +
13490 +       if (!i_tmp)
13491 +               return ERR_PTR(-ENOMEM);
13492 +
13493 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
13494 +               *(i_tmp + i_num) =
13495 +                   (struct acl_ip_label *)
13496 +                   acl_alloc(sizeof (struct acl_ip_label));
13497 +               if (!*(i_tmp + i_num))
13498 +                       return ERR_PTR(-ENOMEM);
13499 +
13500 +               if (copy_from_user
13501 +                   (&i_utmp2, s_tmp->ips + i_num,
13502 +                    sizeof (struct acl_ip_label *)))
13503 +                       return ERR_PTR(-EFAULT);
13504 +
13505 +               if (copy_from_user
13506 +                   (*(i_tmp + i_num), i_utmp2,
13507 +                    sizeof (struct acl_ip_label)))
13508 +                       return ERR_PTR(-EFAULT);
13509 +               
13510 +               if ((*(i_tmp + i_num))->iface == NULL)
13511 +                       continue;
13512 +
13513 +               len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
13514 +               if (!len || len >= IFNAMSIZ)
13515 +                       return ERR_PTR(-EINVAL);
13516 +               tmp = acl_alloc(len);
13517 +               if (tmp == NULL)
13518 +                       return ERR_PTR(-ENOMEM);
13519 +               if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
13520 +                       return ERR_PTR(-EFAULT);
13521 +               (*(i_tmp + i_num))->iface = tmp;
13522 +       }
13523 +
13524 +       s_tmp->ips = i_tmp;
13525 +
13526 +insert:
13527 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
13528 +                              s_tmp->device))
13529 +               return ERR_PTR(-ENOMEM);
13530 +
13531 +       return s_tmp;
13532 +}
13533 +
13534 +static int
13535 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
13536 +{
13537 +       struct acl_subject_label s_pre;
13538 +       struct acl_subject_label * ret;
13539 +       int err;
13540 +
13541 +       while (userp) {
13542 +               if (copy_from_user(&s_pre, userp,
13543 +                                  sizeof (struct acl_subject_label)))
13544 +                       return -EFAULT;
13545 +               
13546 +               /* do not add nested subjects here, add
13547 +                  while parsing objects
13548 +               */
13549 +
13550 +               if (s_pre.mode & GR_NESTED) {
13551 +                       userp = s_pre.prev;
13552 +                       continue;
13553 +               }
13554 +
13555 +               ret = do_copy_user_subj(userp, role);
13556 +
13557 +               err = PTR_ERR(ret);
13558 +               if (IS_ERR(ret))
13559 +                       return err;
13560 +
13561 +               insert_acl_subj_label(ret, role);
13562 +
13563 +               userp = s_pre.prev;
13564 +       }
13565 +
13566 +       return 0;
13567 +}
13568 +
13569 +static int
13570 +copy_user_acl(struct gr_arg *arg)
13571 +{
13572 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
13573 +       struct sprole_pw *sptmp;
13574 +       struct gr_hash_struct *ghash;
13575 +       uid_t *domainlist;
13576 +       unsigned int r_num;
13577 +       unsigned int len;
13578 +       char *tmp;
13579 +       int err = 0;
13580 +       __u16 i;
13581 +       __u32 num_subjs;
13582 +
13583 +       /* we need a default and kernel role */
13584 +       if (arg->role_db.num_roles < 2)
13585 +               return -EINVAL;
13586 +
13587 +       /* copy special role authentication info from userspace */
13588 +
13589 +       num_sprole_pws = arg->num_sprole_pws;
13590 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
13591 +
13592 +       if (!acl_special_roles) {
13593 +               err = -ENOMEM;
13594 +               goto cleanup;
13595 +       }
13596 +
13597 +       for (i = 0; i < num_sprole_pws; i++) {
13598 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
13599 +               if (!sptmp) {
13600 +                       err = -ENOMEM;
13601 +                       goto cleanup;
13602 +               }
13603 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
13604 +                                  sizeof (struct sprole_pw))) {
13605 +                       err = -EFAULT;
13606 +                       goto cleanup;
13607 +               }
13608 +
13609 +               len =
13610 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
13611 +
13612 +               if (!len || len >= GR_SPROLE_LEN) {
13613 +                       err = -EINVAL;
13614 +                       goto cleanup;
13615 +               }
13616 +
13617 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
13618 +                       err = -ENOMEM;
13619 +                       goto cleanup;
13620 +               }
13621 +
13622 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
13623 +                       err = -EFAULT;
13624 +                       goto cleanup;
13625 +               }
13626 +
13627 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13628 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
13629 +#endif
13630 +               sptmp->rolename = tmp;
13631 +               acl_special_roles[i] = sptmp;
13632 +       }
13633 +
13634 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
13635 +
13636 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
13637 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
13638 +
13639 +               if (!r_tmp) {
13640 +                       err = -ENOMEM;
13641 +                       goto cleanup;
13642 +               }
13643 +
13644 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
13645 +                                  sizeof (struct acl_role_label *))) {
13646 +                       err = -EFAULT;
13647 +                       goto cleanup;
13648 +               }
13649 +
13650 +               if (copy_from_user(r_tmp, r_utmp2,
13651 +                                  sizeof (struct acl_role_label))) {
13652 +                       err = -EFAULT;
13653 +                       goto cleanup;
13654 +               }
13655 +
13656 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
13657 +
13658 +               if (!len || len >= PATH_MAX) {
13659 +                       err = -EINVAL;
13660 +                       goto cleanup;
13661 +               }
13662 +
13663 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
13664 +                       err = -ENOMEM;
13665 +                       goto cleanup;
13666 +               }
13667 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
13668 +                       err = -EFAULT;
13669 +                       goto cleanup;
13670 +               }
13671 +               r_tmp->rolename = tmp;
13672 +
13673 +               if (!strcmp(r_tmp->rolename, "default")
13674 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
13675 +                       default_role = r_tmp;
13676 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
13677 +                       kernel_role = r_tmp;
13678 +               }
13679 +
13680 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
13681 +                       err = -ENOMEM;
13682 +                       goto cleanup;
13683 +               }
13684 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
13685 +                       err = -EFAULT;
13686 +                       goto cleanup;
13687 +               }
13688 +
13689 +               r_tmp->hash = ghash;
13690 +
13691 +               num_subjs = count_user_subjs(r_tmp->hash->first);
13692 +
13693 +               r_tmp->subj_hash_size = num_subjs;
13694 +               r_tmp->subj_hash =
13695 +                   (struct acl_subject_label **)
13696 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
13697 +
13698 +               if (!r_tmp->subj_hash) {
13699 +                       err = -ENOMEM;
13700 +                       goto cleanup;
13701 +               }
13702 +
13703 +               err = copy_user_allowedips(r_tmp);
13704 +               if (err)
13705 +                       goto cleanup;
13706 +
13707 +               /* copy domain info */
13708 +               if (r_tmp->domain_children != NULL) {
13709 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
13710 +                       if (domainlist == NULL) {
13711 +                               err = -ENOMEM;
13712 +                               goto cleanup;
13713 +                       }
13714 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
13715 +                               err = -EFAULT;
13716 +                               goto cleanup;
13717 +                       }
13718 +                       r_tmp->domain_children = domainlist;
13719 +               }
13720 +
13721 +               err = copy_user_transitions(r_tmp);
13722 +               if (err)
13723 +                       goto cleanup;
13724 +
13725 +               memset(r_tmp->subj_hash, 0,
13726 +                      r_tmp->subj_hash_size *
13727 +                      sizeof (struct acl_subject_label *));
13728 +
13729 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
13730 +
13731 +               if (err)
13732 +                       goto cleanup;
13733 +
13734 +               /* set nested subject list to null */
13735 +               r_tmp->hash->first = NULL;
13736 +
13737 +               insert_acl_role_label(r_tmp);
13738 +       }
13739 +
13740 +       goto return_err;
13741 +      cleanup:
13742 +       free_variables();
13743 +      return_err:
13744 +       return err;
13745 +
13746 +}
13747 +
13748 +static int
13749 +gracl_init(struct gr_arg *args)
13750 +{
13751 +       int error = 0;
13752 +
13753 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
13754 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
13755 +
13756 +       if (init_variables(args)) {
13757 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
13758 +               error = -ENOMEM;
13759 +               free_variables();
13760 +               goto out;
13761 +       }
13762 +
13763 +       error = copy_user_acl(args);
13764 +       free_init_variables();
13765 +       if (error) {
13766 +               free_variables();
13767 +               goto out;
13768 +       }
13769 +
13770 +       if ((error = gr_set_acls(0))) {
13771 +               free_variables();
13772 +               goto out;
13773 +       }
13774 +
13775 +       gr_status |= GR_READY;
13776 +      out:
13777 +       return error;
13778 +}
13779 +
13780 +/* derived from glibc fnmatch() 0: match, 1: no match*/
13781 +
13782 +static int
13783 +glob_match(const char *p, const char *n)
13784 +{
13785 +       char c;
13786 +
13787 +       while ((c = *p++) != '\0') {
13788 +       switch (c) {
13789 +               case '?':
13790 +                       if (*n == '\0')
13791 +                               return 1;
13792 +                       else if (*n == '/')
13793 +                               return 1;
13794 +                       break;
13795 +               case '\\':
13796 +                       if (*n != c)
13797 +                               return 1;
13798 +                       break;
13799 +               case '*':
13800 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
13801 +                               if (*n == '/')
13802 +                                       return 1;
13803 +                               else if (c == '?') {
13804 +                                       if (*n == '\0')
13805 +                                               return 1;
13806 +                                       else
13807 +                                               ++n;
13808 +                               }
13809 +                       }
13810 +                       if (c == '\0') {
13811 +                               return 0;
13812 +                       } else {
13813 +                               const char *endp;
13814 +
13815 +                               if ((endp = strchr(n, '/')) == NULL)
13816 +                                       endp = n + strlen(n);
13817 +
13818 +                               if (c == '[') {
13819 +                                       for (--p; n < endp; ++n)
13820 +                                               if (!glob_match(p, n))
13821 +                                                       return 0;
13822 +                               } else if (c == '/') {
13823 +                                       while (*n != '\0' && *n != '/')
13824 +                                               ++n;
13825 +                                       if (*n == '/' && !glob_match(p, n + 1))
13826 +                                               return 0;
13827 +                               } else {
13828 +                                       for (--p; n < endp; ++n)
13829 +                                               if (*n == c && !glob_match(p, n))
13830 +                                                       return 0;
13831 +                               }
13832 +
13833 +                               return 1;
13834 +                       }
13835 +               case '[':
13836 +                       {
13837 +                       int not;
13838 +                       char cold;
13839 +
13840 +                       if (*n == '\0' || *n == '/')
13841 +                               return 1;
13842 +
13843 +                       not = (*p == '!' || *p == '^');
13844 +                       if (not)
13845 +                               ++p;
13846 +
13847 +                       c = *p++;
13848 +                       for (;;) {
13849 +                               unsigned char fn = (unsigned char)*n;
13850 +
13851 +                               if (c == '\0')
13852 +                                       return 1;
13853 +                               else {
13854 +                                       if (c == fn)
13855 +                                               goto matched;
13856 +                                       cold = c;
13857 +                                       c = *p++;
13858 +
13859 +                                       if (c == '-' && *p != ']') {
13860 +                                               unsigned char cend = *p++;
13861 +
13862 +                                               if (cend == '\0')
13863 +                                                       return 1;
13864 +
13865 +                                               if (cold <= fn && fn <= cend)
13866 +                                                       goto matched;
13867 +
13868 +                                               c = *p++;
13869 +                                       }
13870 +                               }
13871 +
13872 +                               if (c == ']')
13873 +                                       break;
13874 +                       }
13875 +                       if (!not)
13876 +                               return 1;
13877 +                       break;
13878 +               matched:
13879 +                       while (c != ']') {
13880 +                               if (c == '\0')
13881 +                                       return 1;
13882 +
13883 +                               c = *p++;
13884 +                       }
13885 +                       if (not)
13886 +                               return 1;
13887 +               }
13888 +               break;
13889 +       default:
13890 +               if (c != *n)
13891 +                       return 1;
13892 +       }
13893 +
13894 +       ++n;
13895 +       }
13896 +
13897 +       if (*n == '\0')
13898 +               return 0;
13899 +
13900 +       if (*n == '/')
13901 +               return 0;
13902 +
13903 +       return 1;
13904 +}
13905 +
13906 +static struct acl_object_label *
13907 +chk_glob_label(struct acl_object_label *globbed,
13908 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
13909 +{
13910 +       struct acl_object_label *tmp;
13911 +
13912 +       if (*path == NULL)
13913 +               *path = gr_to_filename_nolock(dentry, mnt);
13914 +
13915 +       tmp = globbed;
13916 +
13917 +       while (tmp) {
13918 +               if (!glob_match(tmp->filename, *path))
13919 +                       return tmp;
13920 +               tmp = tmp->next;
13921 +       }
13922 +
13923 +       return NULL;
13924 +}
13925 +
13926 +static struct acl_object_label *
13927 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
13928 +           const ino_t curr_ino, const dev_t curr_dev,
13929 +           const struct acl_subject_label *subj, char **path)
13930 +{
13931 +       struct acl_subject_label *tmpsubj;
13932 +       struct acl_object_label *retval;
13933 +       struct acl_object_label *retval2;
13934 +
13935 +       tmpsubj = (struct acl_subject_label *) subj;
13936 +       read_lock(&gr_inode_lock);
13937 +       do {
13938 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
13939 +               if (retval) {
13940 +                       if (retval->globbed) {
13941 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
13942 +                                               (struct vfsmount *)orig_mnt, path);
13943 +                               if (retval2)
13944 +                                       retval = retval2;
13945 +                       }
13946 +                       break;
13947 +               }
13948 +       } while ((tmpsubj = tmpsubj->parent_subject));
13949 +       read_unlock(&gr_inode_lock);
13950 +
13951 +       return retval;
13952 +}
13953 +
13954 +static __inline__ struct acl_object_label *
13955 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
13956 +           const struct dentry *curr_dentry,
13957 +           const struct acl_subject_label *subj, char **path)
13958 +{
13959 +       return __full_lookup(orig_dentry, orig_mnt,
13960 +                            curr_dentry->d_inode->i_ino, 
13961 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
13962 +}
13963 +
13964 +static struct acl_object_label *
13965 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
13966 +             const struct acl_subject_label *subj, char *path)
13967 +{
13968 +       struct dentry *dentry = (struct dentry *) l_dentry;
13969 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
13970 +       struct acl_object_label *retval;
13971 +
13972 +       spin_lock(&dcache_lock);
13973 +
13974 +       if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt)) {
13975 +               retval = fakefs_obj;
13976 +               goto out;
13977 +       }
13978 +
13979 +       for (;;) {
13980 +               if (dentry == real_root && mnt == real_root_mnt)
13981 +                       break;
13982 +
13983 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
13984 +                       if (mnt->mnt_parent == mnt)
13985 +                               break;
13986 +
13987 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
13988 +                       if (retval != NULL)
13989 +                               goto out;
13990 +
13991 +                       dentry = mnt->mnt_mountpoint;
13992 +                       mnt = mnt->mnt_parent;
13993 +                       continue;
13994 +               }
13995 +
13996 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
13997 +               if (retval != NULL)
13998 +                       goto out;
13999 +
14000 +               dentry = dentry->d_parent;
14001 +       }
14002 +
14003 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
14004 +
14005 +       if (retval == NULL)
14006 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
14007 +out:
14008 +       spin_unlock(&dcache_lock);
14009 +       return retval;
14010 +}
14011 +
14012 +static __inline__ struct acl_object_label *
14013 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
14014 +             const struct acl_subject_label *subj)
14015 +{
14016 +       char *path = NULL;
14017 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
14018 +}
14019 +
14020 +static __inline__ struct acl_object_label *
14021 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
14022 +                    const struct acl_subject_label *subj, char *path)
14023 +{
14024 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
14025 +}
14026 +
14027 +static struct acl_subject_label *
14028 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
14029 +              const struct acl_role_label *role)
14030 +{
14031 +       struct dentry *dentry = (struct dentry *) l_dentry;
14032 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
14033 +       struct acl_subject_label *retval;
14034 +
14035 +       spin_lock(&dcache_lock);
14036 +
14037 +       for (;;) {
14038 +               if (dentry == real_root && mnt == real_root_mnt)
14039 +                       break;
14040 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
14041 +                       if (mnt->mnt_parent == mnt)
14042 +                               break;
14043 +
14044 +                       read_lock(&gr_inode_lock);
14045 +                       retval =
14046 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
14047 +                                               dentry->d_inode->i_sb->s_dev, role);
14048 +                       read_unlock(&gr_inode_lock);
14049 +                       if (retval != NULL)
14050 +                               goto out;
14051 +
14052 +                       dentry = mnt->mnt_mountpoint;
14053 +                       mnt = mnt->mnt_parent;
14054 +                       continue;
14055 +               }
14056 +
14057 +               read_lock(&gr_inode_lock);
14058 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
14059 +                                         dentry->d_inode->i_sb->s_dev, role);
14060 +               read_unlock(&gr_inode_lock);
14061 +               if (retval != NULL)
14062 +                       goto out;
14063 +
14064 +               dentry = dentry->d_parent;
14065 +       }
14066 +
14067 +       read_lock(&gr_inode_lock);
14068 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
14069 +                                 dentry->d_inode->i_sb->s_dev, role);
14070 +       read_unlock(&gr_inode_lock);
14071 +
14072 +       if (unlikely(retval == NULL)) {
14073 +               read_lock(&gr_inode_lock);
14074 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
14075 +                                         real_root->d_inode->i_sb->s_dev, role);
14076 +               read_unlock(&gr_inode_lock);
14077 +       }
14078 +out:
14079 +       spin_unlock(&dcache_lock);
14080 +
14081 +       return retval;
14082 +}
14083 +
14084 +static void
14085 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
14086 +{
14087 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
14088 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
14089 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
14090 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
14091 +
14092 +       return;
14093 +}
14094 +
14095 +static void
14096 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
14097 +                      const unsigned int effective, const unsigned int fs)
14098 +{
14099 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
14100 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
14101 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
14102 +                      type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
14103 +
14104 +       return;
14105 +}
14106 +
14107 +__u32
14108 +gr_check_link(const struct dentry * new_dentry,
14109 +             const struct dentry * parent_dentry,
14110 +             const struct vfsmount * parent_mnt,
14111 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
14112 +{
14113 +       struct acl_object_label *obj;
14114 +       __u32 oldmode, newmode;
14115 +       __u32 needmode;
14116 +
14117 +       if (unlikely(!(gr_status & GR_READY)))
14118 +               return (GR_CREATE | GR_LINK);
14119 +
14120 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
14121 +       oldmode = obj->mode;
14122 +
14123 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
14124 +               oldmode |= (GR_CREATE | GR_LINK);
14125 +
14126 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
14127 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
14128 +               needmode |= GR_SETID | GR_AUDIT_SETID;
14129 +
14130 +       newmode =
14131 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
14132 +                           oldmode | needmode);
14133 +
14134 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
14135 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
14136 +                             GR_INHERIT | GR_AUDIT_INHERIT);
14137 +
14138 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
14139 +               goto bad;
14140 +
14141 +       if ((oldmode & needmode) != needmode)
14142 +               goto bad;
14143 +
14144 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
14145 +       if ((newmode & needmode) != needmode)
14146 +               goto bad;
14147 +
14148 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
14149 +               return newmode;
14150 +bad:
14151 +       needmode = oldmode;
14152 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
14153 +               needmode |= GR_SETID;
14154 +       
14155 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
14156 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
14157 +               return (GR_CREATE | GR_LINK);
14158 +       } else if (newmode & GR_SUPPRESS)
14159 +               return GR_SUPPRESS;
14160 +       else
14161 +               return 0;
14162 +}
14163 +
14164 +__u32
14165 +gr_search_file(const struct dentry * dentry, const __u32 mode,
14166 +              const struct vfsmount * mnt)
14167 +{
14168 +       __u32 retval = mode;
14169 +       struct acl_subject_label *curracl;
14170 +       struct acl_object_label *currobj;
14171 +
14172 +       if (unlikely(!(gr_status & GR_READY)))
14173 +               return (mode & ~GR_AUDITS);
14174 +
14175 +       curracl = current->acl;
14176 +
14177 +       currobj = chk_obj_label(dentry, mnt, curracl);
14178 +       retval = currobj->mode & mode;
14179 +
14180 +       if (unlikely
14181 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
14182 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
14183 +               __u32 new_mode = mode;
14184 +
14185 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14186 +
14187 +               retval = new_mode;
14188 +
14189 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
14190 +                       new_mode |= GR_INHERIT;
14191 +
14192 +               if (!(mode & GR_NOLEARN))
14193 +                       gr_log_learn(current, dentry, mnt, new_mode);
14194 +       }
14195 +
14196 +       return retval;
14197 +}
14198 +
14199 +__u32
14200 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
14201 +               const struct vfsmount * mnt, const __u32 mode)
14202 +{
14203 +       struct name_entry *match;
14204 +       struct acl_object_label *matchpo;
14205 +       struct acl_subject_label *curracl;
14206 +       char *path;
14207 +       __u32 retval;
14208 +
14209 +       if (unlikely(!(gr_status & GR_READY)))
14210 +               return (mode & ~GR_AUDITS);
14211 +
14212 +       preempt_disable();
14213 +       path = gr_to_filename_rbac(new_dentry, mnt);
14214 +       match = lookup_name_entry(path);
14215 +
14216 +       if (!match)
14217 +               goto check_parent;
14218 +
14219 +       curracl = current->acl;
14220 +
14221 +       read_lock(&gr_inode_lock);
14222 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
14223 +       read_unlock(&gr_inode_lock);
14224 +
14225 +       if (matchpo) {
14226 +               if ((matchpo->mode & mode) !=
14227 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
14228 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
14229 +                       __u32 new_mode = mode;
14230 +
14231 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14232 +
14233 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
14234 +
14235 +                       preempt_enable();
14236 +                       return new_mode;
14237 +               }
14238 +               preempt_enable();
14239 +               return (matchpo->mode & mode);
14240 +       }
14241 +
14242 +      check_parent:
14243 +       curracl = current->acl;
14244 +
14245 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
14246 +       retval = matchpo->mode & mode;
14247 +
14248 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
14249 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
14250 +               __u32 new_mode = mode;
14251 +
14252 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14253 +
14254 +               gr_log_learn(current, new_dentry, mnt, new_mode);
14255 +               preempt_enable();
14256 +               return new_mode;
14257 +       }
14258 +
14259 +       preempt_enable();
14260 +       return retval;
14261 +}
14262 +
14263 +int
14264 +gr_check_hidden_task(const struct task_struct *task)
14265 +{
14266 +       if (unlikely(!(gr_status & GR_READY)))
14267 +               return 0;
14268 +
14269 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
14270 +               return 1;
14271 +
14272 +       return 0;
14273 +}
14274 +
14275 +int
14276 +gr_check_protected_task(const struct task_struct *task)
14277 +{
14278 +       if (unlikely(!(gr_status & GR_READY) || !task))
14279 +               return 0;
14280 +
14281 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
14282 +           task->acl != current->acl)
14283 +               return 1;
14284 +
14285 +       return 0;
14286 +}
14287 +
14288 +void
14289 +gr_copy_label(struct task_struct *tsk)
14290 +{
14291 +       tsk->signal->used_accept = 0;
14292 +       tsk->acl_sp_role = 0;
14293 +       tsk->acl_role_id = current->acl_role_id;
14294 +       tsk->acl = current->acl;
14295 +       tsk->role = current->role;
14296 +       tsk->signal->curr_ip = current->signal->curr_ip;
14297 +       if (current->exec_file)
14298 +               get_file(current->exec_file);
14299 +       tsk->exec_file = current->exec_file;
14300 +       tsk->is_writable = current->is_writable;
14301 +       if (unlikely(current->signal->used_accept))
14302 +               current->signal->curr_ip = 0;
14303 +
14304 +       return;
14305 +}
14306 +
14307 +static void
14308 +gr_set_proc_res(struct task_struct *task)
14309 +{
14310 +       struct acl_subject_label *proc;
14311 +       unsigned short i;
14312 +
14313 +       proc = task->acl;
14314 +
14315 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
14316 +               return;
14317 +
14318 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
14319 +               if (!(proc->resmask & (1 << i)))
14320 +                       continue;
14321 +
14322 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
14323 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
14324 +       }
14325 +
14326 +       return;
14327 +}
14328 +
14329 +int
14330 +gr_check_user_change(int real, int effective, int fs)
14331 +{
14332 +       unsigned int i;
14333 +       __u16 num;
14334 +       uid_t *uidlist;
14335 +       int curuid;
14336 +       int realok = 0;
14337 +       int effectiveok = 0;
14338 +       int fsok = 0;
14339 +
14340 +       if (unlikely(!(gr_status & GR_READY)))
14341 +               return 0;
14342 +
14343 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
14344 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
14345 +
14346 +       num = current->acl->user_trans_num;
14347 +       uidlist = current->acl->user_transitions;
14348 +
14349 +       if (uidlist == NULL)
14350 +               return 0;
14351 +
14352 +       if (real == -1)
14353 +               realok = 1;
14354 +       if (effective == -1)
14355 +               effectiveok = 1;
14356 +       if (fs == -1)
14357 +               fsok = 1;
14358 +
14359 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
14360 +               for (i = 0; i < num; i++) {
14361 +                       curuid = (int)uidlist[i];
14362 +                       if (real == curuid)
14363 +                               realok = 1;
14364 +                       if (effective == curuid)
14365 +                               effectiveok = 1;
14366 +                       if (fs == curuid)
14367 +                               fsok = 1;
14368 +               }
14369 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
14370 +               for (i = 0; i < num; i++) {
14371 +                       curuid = (int)uidlist[i];
14372 +                       if (real == curuid)
14373 +                               break;
14374 +                       if (effective == curuid)
14375 +                               break;
14376 +                       if (fs == curuid)
14377 +                               break;
14378 +               }
14379 +               /* not in deny list */
14380 +               if (i == num) {
14381 +                       realok = 1;
14382 +                       effectiveok = 1;
14383 +                       fsok = 1;
14384 +               }
14385 +       }
14386 +
14387 +       if (realok && effectiveok && fsok)
14388 +               return 0;
14389 +       else {
14390 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
14391 +               return 1;
14392 +       }
14393 +}
14394 +
14395 +int
14396 +gr_check_group_change(int real, int effective, int fs)
14397 +{
14398 +       unsigned int i;
14399 +       __u16 num;
14400 +       gid_t *gidlist;
14401 +       int curgid;
14402 +       int realok = 0;
14403 +       int effectiveok = 0;
14404 +       int fsok = 0;
14405 +
14406 +       if (unlikely(!(gr_status & GR_READY)))
14407 +               return 0;
14408 +
14409 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
14410 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
14411 +
14412 +       num = current->acl->group_trans_num;
14413 +       gidlist = current->acl->group_transitions;
14414 +
14415 +       if (gidlist == NULL)
14416 +               return 0;
14417 +
14418 +       if (real == -1)
14419 +               realok = 1;
14420 +       if (effective == -1)
14421 +               effectiveok = 1;
14422 +       if (fs == -1)
14423 +               fsok = 1;
14424 +
14425 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
14426 +               for (i = 0; i < num; i++) {
14427 +                       curgid = (int)gidlist[i];
14428 +                       if (real == curgid)
14429 +                               realok = 1;
14430 +                       if (effective == curgid)
14431 +                               effectiveok = 1;
14432 +                       if (fs == curgid)
14433 +                               fsok = 1;
14434 +               }
14435 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
14436 +               for (i = 0; i < num; i++) {
14437 +                       curgid = (int)gidlist[i];
14438 +                       if (real == curgid)
14439 +                               break;
14440 +                       if (effective == curgid)
14441 +                               break;
14442 +                       if (fs == curgid)
14443 +                               break;
14444 +               }
14445 +               /* not in deny list */
14446 +               if (i == num) {
14447 +                       realok = 1;
14448 +                       effectiveok = 1;
14449 +                       fsok = 1;
14450 +               }
14451 +       }
14452 +
14453 +       if (realok && effectiveok && fsok)
14454 +               return 0;
14455 +       else {
14456 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
14457 +               return 1;
14458 +       }
14459 +}
14460 +
14461 +void
14462 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
14463 +{
14464 +       struct acl_role_label *role = task->role;
14465 +       struct acl_subject_label *subj = NULL;
14466 +       struct acl_object_label *obj;
14467 +       struct file *filp;
14468 +
14469 +       if (unlikely(!(gr_status & GR_READY)))
14470 +               return;
14471 +
14472 +       filp = task->exec_file;
14473 +
14474 +       /* kernel process, we'll give them the kernel role */
14475 +       if (unlikely(!filp)) {
14476 +               task->role = kernel_role;
14477 +               task->acl = kernel_role->root_label;
14478 +               return;
14479 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
14480 +               role = lookup_acl_role_label(task, uid, gid);
14481 +
14482 +       /* perform subject lookup in possibly new role
14483 +          we can use this result below in the case where role == task->role
14484 +       */
14485 +       subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
14486 +
14487 +       /* if we changed uid/gid, but result in the same role
14488 +          and are using inheritance, don't lose the inherited subject
14489 +          if current subject is other than what normal lookup
14490 +          would result in, we arrived via inheritance, don't
14491 +          lose subject
14492 +       */
14493 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
14494 +                                  (subj == task->acl)))
14495 +               task->acl = subj;
14496 +
14497 +       task->role = role;
14498 +
14499 +       task->is_writable = 0;
14500 +
14501 +       /* ignore additional mmap checks for processes that are writable 
14502 +          by the default ACL */
14503 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
14504 +       if (unlikely(obj->mode & GR_WRITE))
14505 +               task->is_writable = 1;
14506 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
14507 +       if (unlikely(obj->mode & GR_WRITE))
14508 +               task->is_writable = 1;
14509 +
14510 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
14511 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
14512 +#endif
14513 +
14514 +       gr_set_proc_res(task);
14515 +
14516 +       return;
14517 +}
14518 +
14519 +int
14520 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
14521 +{
14522 +       struct task_struct *task = current;
14523 +       struct acl_subject_label *newacl;
14524 +       struct acl_object_label *obj;
14525 +       __u32 retmode;
14526 +
14527 +       if (unlikely(!(gr_status & GR_READY)))
14528 +               return 0;
14529 +
14530 +       newacl = chk_subj_label(dentry, mnt, task->role);
14531 +
14532 +       task_lock(task);
14533 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
14534 +            GR_POVERRIDE) && (task->acl != newacl) &&
14535 +            !(task->role->roletype & GR_ROLE_GOD) &&
14536 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
14537 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
14538 +           (atomic_read(&task->fs->count) > 1 ||
14539 +            atomic_read(&task->files->count) > 1 ||
14540 +            atomic_read(&task->sighand->count) > 1)) {
14541 +                task_unlock(task);
14542 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
14543 +               return -EACCES;
14544 +       }
14545 +       task_unlock(task);
14546 +
14547 +       obj = chk_obj_label(dentry, mnt, task->acl);
14548 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
14549 +
14550 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
14551 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
14552 +               if (obj->nested)
14553 +                       task->acl = obj->nested;
14554 +               else
14555 +                       task->acl = newacl;
14556 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
14557 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
14558 +
14559 +       task->is_writable = 0;
14560 +
14561 +       /* ignore additional mmap checks for processes that are writable 
14562 +          by the default ACL */
14563 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
14564 +       if (unlikely(obj->mode & GR_WRITE))
14565 +               task->is_writable = 1;
14566 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
14567 +       if (unlikely(obj->mode & GR_WRITE))
14568 +               task->is_writable = 1;
14569 +
14570 +       gr_set_proc_res(task);
14571 +
14572 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
14573 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
14574 +#endif
14575 +       return 0;
14576 +}
14577 +
14578 +static void
14579 +do_handle_delete(const ino_t ino, const dev_t dev)
14580 +{
14581 +       struct acl_object_label *matchpo;
14582 +       struct acl_subject_label *matchps;
14583 +       struct acl_subject_label *subj;
14584 +       struct acl_role_label *role;
14585 +       unsigned int i, x;
14586 +
14587 +       FOR_EACH_ROLE_START(role, i)
14588 +               FOR_EACH_SUBJECT_START(role, subj, x)
14589 +                       if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
14590 +                               matchpo->mode |= GR_DELETED;
14591 +               FOR_EACH_SUBJECT_END(subj,x)
14592 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
14593 +                       if (subj->inode == ino && subj->device == dev)
14594 +                               subj->mode |= GR_DELETED;
14595 +               FOR_EACH_NESTED_SUBJECT_END(subj)
14596 +               if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
14597 +                       matchps->mode |= GR_DELETED;
14598 +       FOR_EACH_ROLE_END(role,i)
14599 +
14600 +       return;
14601 +}
14602 +
14603 +void
14604 +gr_handle_delete(const ino_t ino, const dev_t dev)
14605 +{
14606 +       if (unlikely(!(gr_status & GR_READY)))
14607 +               return;
14608 +
14609 +       write_lock(&gr_inode_lock);
14610 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
14611 +               do_handle_delete(ino, dev);
14612 +       write_unlock(&gr_inode_lock);
14613 +
14614 +       return;
14615 +}
14616 +
14617 +static void
14618 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
14619 +                    const ino_t newinode, const dev_t newdevice,
14620 +                    struct acl_subject_label *subj)
14621 +{
14622 +       unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
14623 +       struct acl_object_label *match;
14624 +
14625 +       match = subj->obj_hash[index];
14626 +
14627 +       while (match && (match->inode != oldinode ||
14628 +              match->device != olddevice ||
14629 +              !(match->mode & GR_DELETED)))
14630 +               match = match->next;
14631 +
14632 +       if (match && (match->inode == oldinode)
14633 +           && (match->device == olddevice)
14634 +           && (match->mode & GR_DELETED)) {
14635 +               if (match->prev == NULL) {
14636 +                       subj->obj_hash[index] = match->next;
14637 +                       if (match->next != NULL)
14638 +                               match->next->prev = NULL;
14639 +               } else {
14640 +                       match->prev->next = match->next;
14641 +                       if (match->next != NULL)
14642 +                               match->next->prev = match->prev;
14643 +               }
14644 +               match->prev = NULL;
14645 +               match->next = NULL;
14646 +               match->inode = newinode;
14647 +               match->device = newdevice;
14648 +               match->mode &= ~GR_DELETED;
14649 +
14650 +               insert_acl_obj_label(match, subj);
14651 +       }
14652 +
14653 +       return;
14654 +}
14655 +
14656 +static void
14657 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
14658 +                     const ino_t newinode, const dev_t newdevice,
14659 +                     struct acl_role_label *role)
14660 +{
14661 +       unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
14662 +       struct acl_subject_label *match;
14663 +
14664 +       match = role->subj_hash[index];
14665 +
14666 +       while (match && (match->inode != oldinode ||
14667 +              match->device != olddevice ||
14668 +              !(match->mode & GR_DELETED)))
14669 +               match = match->next;
14670 +
14671 +       if (match && (match->inode == oldinode)
14672 +           && (match->device == olddevice)
14673 +           && (match->mode & GR_DELETED)) {
14674 +               if (match->prev == NULL) {
14675 +                       role->subj_hash[index] = match->next;
14676 +                       if (match->next != NULL)
14677 +                               match->next->prev = NULL;
14678 +               } else {
14679 +                       match->prev->next = match->next;
14680 +                       if (match->next != NULL)
14681 +                               match->next->prev = match->prev;
14682 +               }
14683 +               match->prev = NULL;
14684 +               match->next = NULL;
14685 +               match->inode = newinode;
14686 +               match->device = newdevice;
14687 +               match->mode &= ~GR_DELETED;
14688 +
14689 +               insert_acl_subj_label(match, role);
14690 +       }
14691 +
14692 +       return;
14693 +}
14694 +
14695 +static void
14696 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
14697 +                   const ino_t newinode, const dev_t newdevice)
14698 +{
14699 +       unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
14700 +       struct inodev_entry *match;
14701 +
14702 +       match = inodev_set.i_hash[index];
14703 +
14704 +       while (match && (match->nentry->inode != oldinode ||
14705 +              match->nentry->device != olddevice))
14706 +               match = match->next;
14707 +
14708 +       if (match && (match->nentry->inode == oldinode)
14709 +           && (match->nentry->device == olddevice)) {
14710 +               if (match->prev == NULL) {
14711 +                       inodev_set.i_hash[index] = match->next;
14712 +                       if (match->next != NULL)
14713 +                               match->next->prev = NULL;
14714 +               } else {
14715 +                       match->prev->next = match->next;
14716 +                       if (match->next != NULL)
14717 +                               match->next->prev = match->prev;
14718 +               }
14719 +               match->prev = NULL;
14720 +               match->next = NULL;
14721 +               match->nentry->inode = newinode;
14722 +               match->nentry->device = newdevice;
14723 +
14724 +               insert_inodev_entry(match);
14725 +       }
14726 +
14727 +       return;
14728 +}
14729 +
14730 +static void
14731 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
14732 +                const struct vfsmount *mnt)
14733 +{
14734 +       struct acl_subject_label *subj;
14735 +       struct acl_role_label *role;
14736 +       unsigned int i, x;
14737 +
14738 +       FOR_EACH_ROLE_START(role, i)
14739 +               update_acl_subj_label(matchn->inode, matchn->device,
14740 +                                     dentry->d_inode->i_ino,
14741 +                                     dentry->d_inode->i_sb->s_dev, role);
14742 +
14743 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
14744 +                       if ((subj->inode == dentry->d_inode->i_ino) &&
14745 +                           (subj->device == dentry->d_inode->i_sb->s_dev)) {
14746 +                               subj->inode = dentry->d_inode->i_ino;
14747 +                               subj->device = dentry->d_inode->i_sb->s_dev;
14748 +                       }
14749 +               FOR_EACH_NESTED_SUBJECT_END(subj)
14750 +               FOR_EACH_SUBJECT_START(role, subj, x)
14751 +                       update_acl_obj_label(matchn->inode, matchn->device,
14752 +                                            dentry->d_inode->i_ino,
14753 +                                            dentry->d_inode->i_sb->s_dev, subj);
14754 +               FOR_EACH_SUBJECT_END(subj,x)
14755 +       FOR_EACH_ROLE_END(role,i)
14756 +
14757 +       update_inodev_entry(matchn->inode, matchn->device,
14758 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
14759 +
14760 +       return;
14761 +}
14762 +
14763 +void
14764 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
14765 +{
14766 +       struct name_entry *matchn;
14767 +
14768 +       if (unlikely(!(gr_status & GR_READY)))
14769 +               return;
14770 +
14771 +       preempt_disable();
14772 +       matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
14773 +
14774 +       if (unlikely((unsigned long)matchn)) {
14775 +               write_lock(&gr_inode_lock);
14776 +               do_handle_create(matchn, dentry, mnt);
14777 +               write_unlock(&gr_inode_lock);
14778 +       }
14779 +       preempt_enable();
14780 +
14781 +       return;
14782 +}
14783 +
14784 +void
14785 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
14786 +                struct dentry *old_dentry,
14787 +                struct dentry *new_dentry,
14788 +                struct vfsmount *mnt, const __u8 replace)
14789 +{
14790 +       struct name_entry *matchn;
14791 +
14792 +       if (unlikely(!(gr_status & GR_READY)))
14793 +               return;
14794 +
14795 +       preempt_disable();
14796 +       matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
14797 +
14798 +       /* we wouldn't have to check d_inode if it weren't for
14799 +          NFS silly-renaming
14800 +        */
14801 +
14802 +       write_lock(&gr_inode_lock);
14803 +       if (unlikely(replace && new_dentry->d_inode)) {
14804 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
14805 +                                       new_dentry->d_inode->i_sb->s_dev) &&
14806 +                   (old_dentry->d_inode->i_nlink <= 1)))
14807 +                       do_handle_delete(new_dentry->d_inode->i_ino,
14808 +                                        new_dentry->d_inode->i_sb->s_dev);
14809 +       }
14810 +
14811 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
14812 +                               old_dentry->d_inode->i_sb->s_dev) &&
14813 +           (old_dentry->d_inode->i_nlink <= 1)))
14814 +               do_handle_delete(old_dentry->d_inode->i_ino,
14815 +                                old_dentry->d_inode->i_sb->s_dev);
14816 +
14817 +       if (unlikely((unsigned long)matchn))
14818 +               do_handle_create(matchn, old_dentry, mnt);
14819 +
14820 +       write_unlock(&gr_inode_lock);
14821 +       preempt_enable();
14822 +
14823 +       return;
14824 +}
14825 +
14826 +static int
14827 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
14828 +                        unsigned char **sum)
14829 +{
14830 +       struct acl_role_label *r;
14831 +       struct role_allowed_ip *ipp;
14832 +       struct role_transition *trans;
14833 +       unsigned int i;
14834 +       int found = 0;
14835 +
14836 +       /* check transition table */
14837 +
14838 +       for (trans = current->role->transitions; trans; trans = trans->next) {
14839 +               if (!strcmp(rolename, trans->rolename)) {
14840 +                       found = 1;
14841 +                       break;
14842 +               }
14843 +       }
14844 +
14845 +       if (!found)
14846 +               return 0;
14847 +
14848 +       /* handle special roles that do not require authentication
14849 +          and check ip */
14850 +
14851 +       FOR_EACH_ROLE_START(r, i)
14852 +               if (!strcmp(rolename, r->rolename) &&
14853 +                   (r->roletype & GR_ROLE_SPECIAL)) {
14854 +                       found = 0;
14855 +                       if (r->allowed_ips != NULL) {
14856 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
14857 +                                       if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
14858 +                                            (ntohl(ipp->addr) & ipp->netmask))
14859 +                                               found = 1;
14860 +                               }
14861 +                       } else
14862 +                               found = 2;
14863 +                       if (!found)
14864 +                               return 0;
14865 +
14866 +                       if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
14867 +                           ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
14868 +                               *salt = NULL;
14869 +                               *sum = NULL;
14870 +                               return 1;
14871 +                       }
14872 +               }
14873 +       FOR_EACH_ROLE_END(r,i)
14874 +
14875 +       for (i = 0; i < num_sprole_pws; i++) {
14876 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
14877 +                       *salt = acl_special_roles[i]->salt;
14878 +                       *sum = acl_special_roles[i]->sum;
14879 +                       return 1;
14880 +               }
14881 +       }
14882 +
14883 +       return 0;
14884 +}
14885 +
14886 +static void
14887 +assign_special_role(char *rolename)
14888 +{
14889 +       struct acl_object_label *obj;
14890 +       struct acl_role_label *r;
14891 +       struct acl_role_label *assigned = NULL;
14892 +       struct task_struct *tsk;
14893 +       struct file *filp;
14894 +       unsigned int i;
14895 +
14896 +       FOR_EACH_ROLE_START(r, i)
14897 +               if (!strcmp(rolename, r->rolename) &&
14898 +                   (r->roletype & GR_ROLE_SPECIAL))
14899 +                       assigned = r;
14900 +       FOR_EACH_ROLE_END(r,i)
14901 +
14902 +       if (!assigned)
14903 +               return;
14904 +
14905 +       read_lock(&tasklist_lock);
14906 +       read_lock(&grsec_exec_file_lock);
14907 +
14908 +       tsk = current->parent;
14909 +       if (tsk == NULL)
14910 +               goto out_unlock;
14911 +
14912 +       filp = tsk->exec_file;
14913 +       if (filp == NULL)
14914 +               goto out_unlock;
14915 +
14916 +       tsk->is_writable = 0;
14917 +
14918 +       tsk->acl_sp_role = 1;
14919 +       tsk->acl_role_id = ++acl_sp_role_value;
14920 +       tsk->role = assigned;
14921 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
14922 +
14923 +       /* ignore additional mmap checks for processes that are writable 
14924 +          by the default ACL */
14925 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
14926 +       if (unlikely(obj->mode & GR_WRITE))
14927 +               tsk->is_writable = 1;
14928 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
14929 +       if (unlikely(obj->mode & GR_WRITE))
14930 +               tsk->is_writable = 1;
14931 +
14932 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
14933 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
14934 +#endif
14935 +
14936 +out_unlock:
14937 +       read_unlock(&grsec_exec_file_lock);
14938 +       read_unlock(&tasklist_lock);
14939 +       return;
14940 +}
14941 +
14942 +int gr_check_secure_terminal(struct task_struct *task)
14943 +{
14944 +       struct task_struct *p, *p2, *p3;
14945 +       struct files_struct *files;
14946 +       struct fdtable *fdt;
14947 +       struct file *our_file = NULL, *file;
14948 +       int i;
14949 +
14950 +       if (task->signal->tty == NULL)
14951 +               return 1;
14952 +
14953 +       files = get_files_struct(task);
14954 +       if (files != NULL) {
14955 +               rcu_read_lock();
14956 +               fdt = files_fdtable(files);
14957 +               for (i=0; i < fdt->max_fds; i++) {
14958 +                       file = fcheck_files(files, i);
14959 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
14960 +                               get_file(file);
14961 +                               our_file = file;
14962 +                       }
14963 +               }
14964 +               rcu_read_unlock();
14965 +               put_files_struct(files);
14966 +       }
14967 +
14968 +       if (our_file == NULL)
14969 +               return 1;
14970 +
14971 +       read_lock(&tasklist_lock);
14972 +       do_each_thread(p2, p) {
14973 +               files = get_files_struct(p);
14974 +               if (files == NULL ||
14975 +                   (p->signal && p->signal->tty == task->signal->tty)) {
14976 +                       if (files != NULL)
14977 +                               put_files_struct(files);
14978 +                       continue;
14979 +               }
14980 +               rcu_read_lock();
14981 +               fdt = files_fdtable(files);
14982 +               for (i=0; i < fdt->max_fds; i++) {
14983 +                       file = fcheck_files(files, i);
14984 +                       if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
14985 +                           file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
14986 +                               p3 = task;
14987 +                               while (p3->pid > 0) {
14988 +                                       if (p3 == p)
14989 +                                               break;
14990 +                                       p3 = p3->parent;
14991 +                               }
14992 +                               if (p3 == p)
14993 +                                       break;
14994 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
14995 +                               gr_handle_alertkill(p);
14996 +                               rcu_read_unlock();
14997 +                               put_files_struct(files);
14998 +                               read_unlock(&tasklist_lock);
14999 +                               fput(our_file);
15000 +                               return 0;
15001 +                       }
15002 +               }
15003 +               rcu_read_unlock();
15004 +               put_files_struct(files);
15005 +       } while_each_thread(p2, p);
15006 +       read_unlock(&tasklist_lock);
15007 +
15008 +       fput(our_file);
15009 +       return 1;
15010 +}
15011 +
15012 +ssize_t
15013 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
15014 +{
15015 +       struct gr_arg_wrapper uwrap;
15016 +       unsigned char *sprole_salt;
15017 +       unsigned char *sprole_sum;
15018 +       int error = sizeof (struct gr_arg_wrapper);
15019 +       int error2 = 0;
15020 +
15021 +       down(&gr_dev_sem);
15022 +
15023 +       if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
15024 +               error = -EPERM;
15025 +               goto out;
15026 +       }
15027 +
15028 +       if (count != sizeof (struct gr_arg_wrapper)) {
15029 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
15030 +               error = -EINVAL;
15031 +               goto out;
15032 +       }
15033 +
15034 +       
15035 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
15036 +               gr_auth_expires = 0;
15037 +               gr_auth_attempts = 0;
15038 +       }
15039 +
15040 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
15041 +               error = -EFAULT;
15042 +               goto out;
15043 +       }
15044 +
15045 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
15046 +               error = -EINVAL;
15047 +               goto out;
15048 +       }
15049 +
15050 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
15051 +               error = -EFAULT;
15052 +               goto out;
15053 +       }
15054 +
15055 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
15056 +           gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
15057 +           time_after(gr_auth_expires, get_seconds())) {
15058 +               error = -EBUSY;
15059 +               goto out;
15060 +       }
15061 +
15062 +       /* if non-root trying to do anything other than use a special role,
15063 +          do not attempt authentication, do not count towards authentication
15064 +          locking
15065 +        */
15066 +
15067 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
15068 +           gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
15069 +           current->uid) {
15070 +               error = -EPERM;
15071 +               goto out;
15072 +       }
15073 +
15074 +       /* ensure pw and special role name are null terminated */
15075 +
15076 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
15077 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
15078 +
15079 +       /* Okay. 
15080 +        * We have our enough of the argument structure..(we have yet
15081 +        * to copy_from_user the tables themselves) . Copy the tables
15082 +        * only if we need them, i.e. for loading operations. */
15083 +
15084 +       switch (gr_usermode->mode) {
15085 +       case STATUS:
15086 +                       if (gr_status & GR_READY) {
15087 +                               error = 1;
15088 +                               if (!gr_check_secure_terminal(current))
15089 +                                       error = 3;
15090 +                       } else
15091 +                               error = 2;
15092 +                       goto out;
15093 +       case SHUTDOWN:
15094 +               if ((gr_status & GR_READY)
15095 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
15096 +                       gr_status &= ~GR_READY;
15097 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
15098 +                       free_variables();
15099 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
15100 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
15101 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
15102 +               } else if (gr_status & GR_READY) {
15103 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
15104 +                       error = -EPERM;
15105 +               } else {
15106 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
15107 +                       error = -EAGAIN;
15108 +               }
15109 +               break;
15110 +       case ENABLE:
15111 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
15112 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
15113 +               else {
15114 +                       if (gr_status & GR_READY)
15115 +                               error = -EAGAIN;
15116 +                       else
15117 +                               error = error2;
15118 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
15119 +               }
15120 +               break;
15121 +       case RELOAD:
15122 +               if (!(gr_status & GR_READY)) {
15123 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
15124 +                       error = -EAGAIN;
15125 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
15126 +                       lock_kernel();
15127 +                       gr_status &= ~GR_READY;
15128 +                       free_variables();
15129 +                       if (!(error2 = gracl_init(gr_usermode))) {
15130 +                               unlock_kernel();
15131 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
15132 +                       } else {
15133 +                               unlock_kernel();
15134 +                               error = error2;
15135 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
15136 +                       }
15137 +               } else {
15138 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
15139 +                       error = -EPERM;
15140 +               }
15141 +               break;
15142 +       case SEGVMOD:
15143 +               if (unlikely(!(gr_status & GR_READY))) {
15144 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
15145 +                       error = -EAGAIN;
15146 +                       break;
15147 +               }
15148 +
15149 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
15150 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
15151 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
15152 +                               struct acl_subject_label *segvacl;
15153 +                               segvacl =
15154 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
15155 +                                                         gr_usermode->segv_device,
15156 +                                                         current->role);
15157 +                               if (segvacl) {
15158 +                                       segvacl->crashes = 0;
15159 +                                       segvacl->expires = 0;
15160 +                               }
15161 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
15162 +                               gr_remove_uid(gr_usermode->segv_uid);
15163 +                       }
15164 +               } else {
15165 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
15166 +                       error = -EPERM;
15167 +               }
15168 +               break;
15169 +       case SPROLE:
15170 +       case SPROLEPAM:
15171 +               if (unlikely(!(gr_status & GR_READY))) {
15172 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
15173 +                       error = -EAGAIN;
15174 +                       break;
15175 +               }
15176 +
15177 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
15178 +                       current->role->expires = 0;
15179 +                       current->role->auth_attempts = 0;
15180 +               }
15181 +
15182 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
15183 +                   time_after(current->role->expires, get_seconds())) {
15184 +                       error = -EBUSY;
15185 +                       goto out;
15186 +               }
15187 +
15188 +               if (lookup_special_role_auth
15189 +                   (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
15190 +                   && ((!sprole_salt && !sprole_sum)
15191 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
15192 +                       char *p = "";
15193 +                       assign_special_role(gr_usermode->sp_role);
15194 +                       read_lock(&tasklist_lock);
15195 +                       if (current->parent)
15196 +                               p = current->parent->role->rolename;
15197 +                       read_unlock(&tasklist_lock);
15198 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
15199 +                                       p, acl_sp_role_value);
15200 +               } else {
15201 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
15202 +                       error = -EPERM;
15203 +                       if(!(current->role->auth_attempts++))
15204 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
15205 +
15206 +                       goto out;
15207 +               }
15208 +               break;
15209 +       case UNSPROLE:
15210 +               if (unlikely(!(gr_status & GR_READY))) {
15211 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
15212 +                       error = -EAGAIN;
15213 +                       break;
15214 +               }
15215 +
15216 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
15217 +                       char *p = "";
15218 +                       int i = 0;
15219 +
15220 +                       read_lock(&tasklist_lock);
15221 +                       if (current->parent) {
15222 +                               p = current->parent->role->rolename;
15223 +                               i = current->parent->acl_role_id;
15224 +                       }
15225 +                       read_unlock(&tasklist_lock);
15226 +
15227 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
15228 +                       gr_set_acls(1);
15229 +               } else {
15230 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
15231 +                       error = -EPERM;
15232 +                       goto out;
15233 +               }
15234 +               break;
15235 +       default:
15236 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
15237 +               error = -EINVAL;
15238 +               break;
15239 +       }
15240 +
15241 +       if (error != -EPERM)
15242 +               goto out;
15243 +
15244 +       if(!(gr_auth_attempts++))
15245 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
15246 +
15247 +      out:
15248 +       up(&gr_dev_sem);
15249 +       return error;
15250 +}
15251 +
15252 +int
15253 +gr_set_acls(const int type)
15254 +{
15255 +       struct acl_object_label *obj;
15256 +       struct task_struct *task, *task2;
15257 +       struct file *filp;
15258 +       struct acl_role_label *role = current->role;
15259 +       __u16 acl_role_id = current->acl_role_id;
15260 +
15261 +       read_lock(&tasklist_lock);
15262 +       read_lock(&grsec_exec_file_lock);
15263 +       do_each_thread(task2, task) {
15264 +               /* check to see if we're called from the exit handler,
15265 +                  if so, only replace ACLs that have inherited the admin
15266 +                  ACL */
15267 +
15268 +               if (type && (task->role != role ||
15269 +                            task->acl_role_id != acl_role_id))
15270 +                       continue;
15271 +
15272 +               task->acl_role_id = 0;
15273 +               task->acl_sp_role = 0;
15274 +
15275 +               if ((filp = task->exec_file)) {
15276 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
15277 +
15278 +                       task->acl =
15279 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
15280 +                                          task->role);
15281 +                       if (task->acl) {
15282 +                               struct acl_subject_label *curr;
15283 +                               curr = task->acl;
15284 +
15285 +                               task->is_writable = 0;
15286 +                               /* ignore additional mmap checks for processes that are writable 
15287 +                                  by the default ACL */
15288 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
15289 +                               if (unlikely(obj->mode & GR_WRITE))
15290 +                                       task->is_writable = 1;
15291 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
15292 +                               if (unlikely(obj->mode & GR_WRITE))
15293 +                                       task->is_writable = 1;
15294 +
15295 +                               gr_set_proc_res(task);
15296 +
15297 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
15298 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
15299 +#endif
15300 +                       } else {
15301 +                               read_unlock(&grsec_exec_file_lock);
15302 +                               read_unlock(&tasklist_lock);
15303 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
15304 +                               return 1;
15305 +                       }
15306 +               } else {
15307 +                       // it's a kernel process
15308 +                       task->role = kernel_role;
15309 +                       task->acl = kernel_role->root_label;
15310 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
15311 +                       task->acl->mode &= ~GR_PROCFIND;
15312 +#endif
15313 +               }
15314 +       } while_each_thread(task2, task);
15315 +       read_unlock(&grsec_exec_file_lock);
15316 +       read_unlock(&tasklist_lock);
15317 +       return 0;
15318 +}
15319 +
15320 +void
15321 +gr_learn_resource(const struct task_struct *task,
15322 +                 const int res, const unsigned long wanted, const int gt)
15323 +{
15324 +       struct acl_subject_label *acl;
15325 +
15326 +       if (unlikely((gr_status & GR_READY) &&
15327 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
15328 +               goto skip_reslog;
15329 +
15330 +#ifdef CONFIG_GRKERNSEC_RESLOG
15331 +       gr_log_resource(task, res, wanted, gt);
15332 +#endif
15333 +      skip_reslog:
15334 +
15335 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
15336 +               return;
15337 +
15338 +       acl = task->acl;
15339 +
15340 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
15341 +                  !(acl->resmask & (1 << (unsigned short) res))))
15342 +               return;
15343 +
15344 +       if (wanted >= acl->res[res].rlim_cur) {
15345 +               unsigned long res_add;
15346 +
15347 +               res_add = wanted;
15348 +               switch (res) {
15349 +               case RLIMIT_CPU:
15350 +                       res_add += GR_RLIM_CPU_BUMP;
15351 +                       break;
15352 +               case RLIMIT_FSIZE:
15353 +                       res_add += GR_RLIM_FSIZE_BUMP;
15354 +                       break;
15355 +               case RLIMIT_DATA:
15356 +                       res_add += GR_RLIM_DATA_BUMP;
15357 +                       break;
15358 +               case RLIMIT_STACK:
15359 +                       res_add += GR_RLIM_STACK_BUMP;
15360 +                       break;
15361 +               case RLIMIT_CORE:
15362 +                       res_add += GR_RLIM_CORE_BUMP;
15363 +                       break;
15364 +               case RLIMIT_RSS:
15365 +                       res_add += GR_RLIM_RSS_BUMP;
15366 +                       break;
15367 +               case RLIMIT_NPROC:
15368 +                       res_add += GR_RLIM_NPROC_BUMP;
15369 +                       break;
15370 +               case RLIMIT_NOFILE:
15371 +                       res_add += GR_RLIM_NOFILE_BUMP;
15372 +                       break;
15373 +               case RLIMIT_MEMLOCK:
15374 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
15375 +                       break;
15376 +               case RLIMIT_AS:
15377 +                       res_add += GR_RLIM_AS_BUMP;
15378 +                       break;
15379 +               case RLIMIT_LOCKS:
15380 +                       res_add += GR_RLIM_LOCKS_BUMP;
15381 +                       break;
15382 +               }
15383 +
15384 +               acl->res[res].rlim_cur = res_add;
15385 +
15386 +               if (wanted > acl->res[res].rlim_max)
15387 +                       acl->res[res].rlim_max = res_add;
15388 +
15389 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
15390 +                              task->role->roletype, acl->filename,
15391 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
15392 +                              "", (unsigned long) res);
15393 +       }
15394 +
15395 +       return;
15396 +}
15397 +
15398 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
15399 +void
15400 +pax_set_initial_flags(struct linux_binprm *bprm)
15401 +{
15402 +       struct task_struct *task = current;
15403 +        struct acl_subject_label *proc;
15404 +       unsigned long flags;
15405 +
15406 +        if (unlikely(!(gr_status & GR_READY)))
15407 +                return;
15408 +
15409 +       flags = pax_get_flags(task);
15410 +
15411 +        proc = task->acl;
15412 +
15413 +       if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
15414 +               flags &= ~MF_PAX_PAGEEXEC;
15415 +       if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
15416 +               flags &= ~MF_PAX_SEGMEXEC;
15417 +       if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
15418 +               flags &= ~MF_PAX_RANDMMAP;
15419 +       if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
15420 +               flags &= ~MF_PAX_EMUTRAMP;
15421 +       if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
15422 +               flags &= ~MF_PAX_MPROTECT;
15423 +
15424 +       if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
15425 +               flags |= MF_PAX_PAGEEXEC;
15426 +       if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
15427 +               flags |= MF_PAX_SEGMEXEC;
15428 +       if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
15429 +               flags |= MF_PAX_RANDMMAP;
15430 +       if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
15431 +               flags |= MF_PAX_EMUTRAMP;
15432 +       if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
15433 +               flags |= MF_PAX_MPROTECT;
15434 +
15435 +       pax_set_flags(task, flags);
15436 +
15437 +        return;
15438 +}
15439 +#endif
15440 +
15441 +#ifdef CONFIG_SYSCTL
15442 +extern struct proc_dir_entry *proc_sys_root;
15443 +
15444 +/* the following function is called under the BKL */
15445 +
15446 +__u32
15447 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
15448 +                const void *newval)
15449 +{
15450 +       struct proc_dir_entry *tmp;
15451 +       struct nameidata nd;
15452 +       const char *proc_sys = "/proc/sys";
15453 +       char *path;
15454 +       struct acl_object_label *obj;
15455 +       unsigned short len = 0, pos = 0, depth = 0, i;
15456 +       __u32 err = 0;
15457 +       __u32 mode = 0;
15458 +
15459 +       if (unlikely(!(gr_status & GR_READY)))
15460 +               return 1;
15461 +
15462 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
15463 +
15464 +       if (oldval)
15465 +               mode |= GR_READ;
15466 +       if (newval)
15467 +               mode |= GR_WRITE;
15468 +
15469 +       /* convert the requested sysctl entry into a pathname */
15470 +
15471 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
15472 +               len += strlen(tmp->name);
15473 +               len++;
15474 +               depth++;
15475 +       }
15476 +
15477 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
15478 +               return 0;       /* deny */
15479 +
15480 +       memset(path, 0, PAGE_SIZE);
15481 +
15482 +       memcpy(path, proc_sys, strlen(proc_sys));
15483 +
15484 +       pos += strlen(proc_sys);
15485 +
15486 +       for (; depth > 0; depth--) {
15487 +               path[pos] = '/';
15488 +               pos++;
15489 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
15490 +                    tmp = tmp->parent) {
15491 +                       if (depth == i) {
15492 +                               memcpy(path + pos, tmp->name,
15493 +                                      strlen(tmp->name));
15494 +                               pos += strlen(tmp->name);
15495 +                       }
15496 +                       i++;
15497 +               }
15498 +       }
15499 +
15500 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
15501 +
15502 +       if (err)
15503 +               goto out;
15504 +
15505 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
15506 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
15507 +
15508 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
15509 +                    ((err & mode) != mode))) {
15510 +               __u32 new_mode = mode;
15511 +
15512 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
15513 +
15514 +               err = new_mode;
15515 +               gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
15516 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
15517 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
15518 +                              path, (mode & GR_READ) ? " reading" : "",
15519 +                              (mode & GR_WRITE) ? " writing" : "");
15520 +               err = 0;
15521 +       } else if ((err & mode) != mode) {
15522 +               err = 0;
15523 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
15524 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
15525 +                              path, (mode & GR_READ) ? " reading" : "",
15526 +                              (mode & GR_WRITE) ? " writing" : "");
15527 +       }
15528 +
15529 +       path_release(&nd);
15530 +
15531 +      out:
15532 +       return err;
15533 +}
15534 +#endif
15535 +
15536 +int
15537 +gr_handle_proc_ptrace(struct task_struct *task)
15538 +{
15539 +       struct file *filp;
15540 +       struct task_struct *tmp = task;
15541 +       struct task_struct *curtemp = current;
15542 +       __u32 retmode;
15543 +
15544 +       if (unlikely(!(gr_status & GR_READY)))
15545 +               return 0;
15546 +
15547 +       read_lock(&tasklist_lock);
15548 +       read_lock(&grsec_exec_file_lock);
15549 +       filp = task->exec_file;
15550 +
15551 +       while (tmp->pid > 0) {
15552 +               if (tmp == curtemp)
15553 +                       break;
15554 +               tmp = tmp->parent;
15555 +       }
15556 +
15557 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
15558 +               read_unlock(&grsec_exec_file_lock);
15559 +               read_unlock(&tasklist_lock);
15560 +               return 1;
15561 +       }
15562 +
15563 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
15564 +       read_unlock(&grsec_exec_file_lock);
15565 +       read_unlock(&tasklist_lock);
15566 +
15567 +       if (retmode & GR_NOPTRACE)
15568 +               return 1;
15569 +
15570 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
15571 +           && (current->acl != task->acl || (current->acl != current->role->root_label
15572 +           && current->pid != task->pid)))
15573 +               return 1;
15574 +
15575 +       return 0;
15576 +}
15577 +
15578 +int
15579 +gr_handle_ptrace(struct task_struct *task, const long request)
15580 +{
15581 +       struct task_struct *tmp = task;
15582 +       struct task_struct *curtemp = current;
15583 +       __u32 retmode;
15584 +
15585 +       if (unlikely(!(gr_status & GR_READY)))
15586 +               return 0;
15587 +
15588 +       read_lock(&tasklist_lock);
15589 +       while (tmp->pid > 0) {
15590 +               if (tmp == curtemp)
15591 +                       break;
15592 +               tmp = tmp->parent;
15593 +       }
15594 +
15595 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
15596 +               read_unlock(&tasklist_lock);
15597 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15598 +               return 1;
15599 +       }
15600 +       read_unlock(&tasklist_lock);
15601 +
15602 +       read_lock(&grsec_exec_file_lock);
15603 +       if (unlikely(!task->exec_file)) {
15604 +               read_unlock(&grsec_exec_file_lock);
15605 +               return 0;
15606 +       }
15607 +
15608 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
15609 +       read_unlock(&grsec_exec_file_lock);
15610 +
15611 +       if (retmode & GR_NOPTRACE) {
15612 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15613 +               return 1;
15614 +       }
15615 +               
15616 +       if (retmode & GR_PTRACERD) {
15617 +               switch (request) {
15618 +               case PTRACE_POKETEXT:
15619 +               case PTRACE_POKEDATA:
15620 +               case PTRACE_POKEUSR:
15621 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
15622 +               case PTRACE_SETREGS:
15623 +               case PTRACE_SETFPREGS:
15624 +#endif
15625 +#ifdef CONFIG_X86
15626 +               case PTRACE_SETFPXREGS:
15627 +#endif
15628 +#ifdef CONFIG_ALTIVEC
15629 +               case PTRACE_SETVRREGS:
15630 +#endif
15631 +                       return 1;
15632 +               default:
15633 +                       return 0;
15634 +               }
15635 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
15636 +                  !(current->role->roletype & GR_ROLE_GOD) &&
15637 +                  (current->acl != task->acl)) {
15638 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15639 +               return 1;
15640 +       }
15641 +
15642 +       return 0;
15643 +}
15644 +
15645 +static int is_writable_mmap(const struct file *filp)
15646 +{
15647 +       struct task_struct *task = current;
15648 +       struct acl_object_label *obj, *obj2;
15649 +
15650 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
15651 +           !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
15652 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
15653 +               obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
15654 +                                    task->role->root_label);
15655 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
15656 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
15657 +                       return 1;
15658 +               }
15659 +       }
15660 +       return 0;
15661 +}
15662 +
15663 +int
15664 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
15665 +{
15666 +       __u32 mode;
15667 +
15668 +       if (unlikely(!file || !(prot & PROT_EXEC)))
15669 +               return 1;
15670 +
15671 +       if (is_writable_mmap(file))
15672 +               return 0;
15673 +
15674 +       mode =
15675 +           gr_search_file(file->f_dentry,
15676 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
15677 +                          file->f_vfsmnt);
15678 +
15679 +       if (!gr_tpe_allow(file))
15680 +               return 0;
15681 +
15682 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
15683 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15684 +               return 0;
15685 +       } else if (unlikely(!(mode & GR_EXEC))) {
15686 +               return 0;
15687 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
15688 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15689 +               return 1;
15690 +       }
15691 +
15692 +       return 1;
15693 +}
15694 +
15695 +int
15696 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
15697 +{
15698 +       __u32 mode;
15699 +
15700 +       if (unlikely(!file || !(prot & PROT_EXEC)))
15701 +               return 1;
15702 +
15703 +       if (is_writable_mmap(file))
15704 +               return 0;
15705 +
15706 +       mode =
15707 +           gr_search_file(file->f_dentry,
15708 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
15709 +                          file->f_vfsmnt);
15710 +
15711 +       if (!gr_tpe_allow(file))
15712 +               return 0;
15713 +
15714 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
15715 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15716 +               return 0;
15717 +       } else if (unlikely(!(mode & GR_EXEC))) {
15718 +               return 0;
15719 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
15720 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15721 +               return 1;
15722 +       }
15723 +
15724 +       return 1;
15725 +}
15726 +
15727 +void
15728 +gr_acl_handle_psacct(struct task_struct *task, const long code)
15729 +{
15730 +       unsigned long runtime;
15731 +       unsigned long cputime;
15732 +       unsigned int wday, cday;
15733 +       __u8 whr, chr;
15734 +       __u8 wmin, cmin;
15735 +       __u8 wsec, csec;
15736 +
15737 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
15738 +                    !(task->acl->mode & GR_PROCACCT)))
15739 +               return;
15740 +
15741 +       runtime = xtime.tv_sec - task->start_time.tv_sec;
15742 +       wday = runtime / (3600 * 24);
15743 +       runtime -= wday * (3600 * 24);
15744 +       whr = runtime / 3600;
15745 +       runtime -= whr * 3600;
15746 +       wmin = runtime / 60;
15747 +       runtime -= wmin * 60;
15748 +       wsec = runtime;
15749 +
15750 +       cputime = (task->utime + task->stime) / HZ;
15751 +       cday = cputime / (3600 * 24);
15752 +       cputime -= cday * (3600 * 24);
15753 +       chr = cputime / 3600;
15754 +       cputime -= chr * 3600;
15755 +       cmin = cputime / 60;
15756 +       cputime -= cmin * 60;
15757 +       csec = cputime;
15758 +
15759 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
15760 +
15761 +       return;
15762 +}
15763 +
15764 +void gr_set_kernel_label(struct task_struct *task)
15765 +{
15766 +       if (gr_status & GR_READY) {
15767 +               task->role = kernel_role;
15768 +               task->acl = kernel_role->root_label;
15769 +       }
15770 +       return;
15771 +}
15772 +
15773 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
15774 +{
15775 +       struct task_struct *task = current;
15776 +       struct dentry *dentry = file->f_dentry;
15777 +       struct vfsmount *mnt = file->f_vfsmnt;
15778 +       struct acl_object_label *obj, *tmp;
15779 +       struct acl_subject_label *subj;
15780 +       unsigned int bufsize;
15781 +       int is_not_root;
15782 +       char *path;
15783 +
15784 +       if (unlikely(!(gr_status & GR_READY)))
15785 +               return 1;
15786 +
15787 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
15788 +               return 1;
15789 +
15790 +       subj = task->acl;
15791 +       do {
15792 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
15793 +               if (obj != NULL)
15794 +                       return (obj->mode & GR_FIND) ? 1 : 0;
15795 +       } while ((subj = subj->parent_subject));
15796 +       
15797 +       obj = chk_obj_label(dentry, mnt, task->acl);
15798 +       if (obj->globbed == NULL)
15799 +               return (obj->mode & GR_FIND) ? 1 : 0;
15800 +
15801 +       is_not_root = ((obj->filename[0] == '/') &&
15802 +                  (obj->filename[1] == '\0')) ? 0 : 1;
15803 +       bufsize = PAGE_SIZE - namelen - is_not_root;
15804 +
15805 +       /* check bufsize > PAGE_SIZE || bufsize == 0 */
15806 +       if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
15807 +               return 1;
15808 +
15809 +       preempt_disable();
15810 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
15811 +                          bufsize);
15812 +
15813 +       bufsize = strlen(path);
15814 +
15815 +       /* if base is "/", don't append an additional slash */
15816 +       if (is_not_root)
15817 +               *(path + bufsize) = '/';
15818 +       memcpy(path + bufsize + is_not_root, name, namelen);
15819 +       *(path + bufsize + namelen + is_not_root) = '\0';
15820 +
15821 +       tmp = obj->globbed;
15822 +       while (tmp) {
15823 +               if (!glob_match(tmp->filename, path)) {
15824 +                       preempt_enable();
15825 +                       return (tmp->mode & GR_FIND) ? 1 : 0;
15826 +               }
15827 +               tmp = tmp->next;
15828 +       }
15829 +       preempt_enable();
15830 +       return (obj->mode & GR_FIND) ? 1 : 0;
15831 +}
15832 +
15833 +EXPORT_SYMBOL(gr_learn_resource);
15834 +EXPORT_SYMBOL(gr_set_kernel_label);
15835 +#ifdef CONFIG_SECURITY
15836 +EXPORT_SYMBOL(gr_check_user_change);
15837 +EXPORT_SYMBOL(gr_check_group_change);
15838 +#endif
15839 +
15840 diff -urNp linux-2.6.18/grsecurity/gracl_cap.c linux-2.6.18/grsecurity/gracl_cap.c
15841 --- linux-2.6.18/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
15842 +++ linux-2.6.18/grsecurity/gracl_cap.c 2006-09-22 20:04:35.000000000 -0400
15843 @@ -0,0 +1,110 @@
15844 +#include <linux/kernel.h>
15845 +#include <linux/module.h>
15846 +#include <linux/sched.h>
15847 +#include <linux/capability.h>
15848 +#include <linux/gracl.h>
15849 +#include <linux/grsecurity.h>
15850 +#include <linux/grinternal.h>
15851 +
15852 +static const char *captab_log[] = {
15853 +       "CAP_CHOWN",
15854 +       "CAP_DAC_OVERRIDE",
15855 +       "CAP_DAC_READ_SEARCH",
15856 +       "CAP_FOWNER",
15857 +       "CAP_FSETID",
15858 +       "CAP_KILL",
15859 +       "CAP_SETGID",
15860 +       "CAP_SETUID",
15861 +       "CAP_SETPCAP",
15862 +       "CAP_LINUX_IMMUTABLE",
15863 +       "CAP_NET_BIND_SERVICE",
15864 +       "CAP_NET_BROADCAST",
15865 +       "CAP_NET_ADMIN",
15866 +       "CAP_NET_RAW",
15867 +       "CAP_IPC_LOCK",
15868 +       "CAP_IPC_OWNER",
15869 +       "CAP_SYS_MODULE",
15870 +       "CAP_SYS_RAWIO",
15871 +       "CAP_SYS_CHROOT",
15872 +       "CAP_SYS_PTRACE",
15873 +       "CAP_SYS_PACCT",
15874 +       "CAP_SYS_ADMIN",
15875 +       "CAP_SYS_BOOT",
15876 +       "CAP_SYS_NICE",
15877 +       "CAP_SYS_RESOURCE",
15878 +       "CAP_SYS_TIME",
15879 +       "CAP_SYS_TTY_CONFIG",
15880 +       "CAP_MKNOD",
15881 +       "CAP_LEASE"
15882 +};
15883 +
15884 +EXPORT_SYMBOL(gr_task_is_capable);
15885 +
15886 +int
15887 +gr_task_is_capable(struct task_struct *task, const int cap)
15888 +{
15889 +       struct acl_subject_label *curracl;
15890 +       __u32 cap_drop = 0, cap_mask = 0;
15891 +
15892 +       if (!gr_acl_is_enabled())
15893 +               return 1;
15894 +
15895 +       curracl = task->acl;
15896 +
15897 +       cap_drop = curracl->cap_lower;
15898 +       cap_mask = curracl->cap_mask;
15899 +
15900 +       while ((curracl = curracl->parent_subject)) {
15901 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
15902 +                       cap_drop |= curracl->cap_lower & (1 << cap);
15903 +               cap_mask |= curracl->cap_mask;
15904 +       }
15905 +
15906 +       if (!cap_raised(cap_drop, cap))
15907 +               return 1;
15908 +
15909 +       curracl = task->acl;
15910 +
15911 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
15912 +           && cap_raised(task->cap_effective, cap)) {
15913 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
15914 +                              task->role->roletype, task->uid,
15915 +                              task->gid, task->exec_file ?
15916 +                              gr_to_filename(task->exec_file->f_dentry,
15917 +                              task->exec_file->f_vfsmnt) : curracl->filename,
15918 +                              curracl->filename, 0UL,
15919 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
15920 +               return 1;
15921 +       }
15922 +
15923 +       if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
15924 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
15925 +
15926 +       return 0;
15927 +}
15928 +
15929 +int
15930 +gr_is_capable_nolog(const int cap)
15931 +{
15932 +       struct acl_subject_label *curracl;
15933 +       __u32 cap_drop = 0, cap_mask = 0;
15934 +
15935 +       if (!gr_acl_is_enabled())
15936 +               return 1;
15937 +
15938 +       curracl = current->acl;
15939 +
15940 +       cap_drop = curracl->cap_lower;
15941 +       cap_mask = curracl->cap_mask;
15942 +
15943 +       while ((curracl = curracl->parent_subject)) {
15944 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
15945 +               cap_mask |= curracl->cap_mask;
15946 +       }
15947 +
15948 +       if (!cap_raised(cap_drop, cap))
15949 +               return 1;
15950 +
15951 +       return 0;
15952 +}
15953 +
15954 diff -urNp linux-2.6.18/grsecurity/gracl_fs.c linux-2.6.18/grsecurity/gracl_fs.c
15955 --- linux-2.6.18/grsecurity/gracl_fs.c  1969-12-31 19:00:00.000000000 -0500
15956 +++ linux-2.6.18/grsecurity/gracl_fs.c  2006-09-22 20:04:35.000000000 -0400
15957 @@ -0,0 +1,423 @@
15958 +#include <linux/kernel.h>
15959 +#include <linux/sched.h>
15960 +#include <linux/types.h>
15961 +#include <linux/fs.h>
15962 +#include <linux/file.h>
15963 +#include <linux/stat.h>
15964 +#include <linux/grsecurity.h>
15965 +#include <linux/grinternal.h>
15966 +#include <linux/gracl.h>
15967 +
15968 +__u32
15969 +gr_acl_handle_hidden_file(const struct dentry * dentry,
15970 +                         const struct vfsmount * mnt)
15971 +{
15972 +       __u32 mode;
15973 +
15974 +       if (unlikely(!dentry->d_inode))
15975 +               return GR_FIND;
15976 +
15977 +       mode =
15978 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
15979 +
15980 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
15981 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
15982 +               return mode;
15983 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
15984 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
15985 +               return 0;
15986 +       } else if (unlikely(!(mode & GR_FIND)))
15987 +               return 0;
15988 +
15989 +       return GR_FIND;
15990 +}
15991 +
15992 +__u32
15993 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
15994 +                  const int fmode)
15995 +{
15996 +       __u32 reqmode = GR_FIND;
15997 +       __u32 mode;
15998 +
15999 +       if (unlikely(!dentry->d_inode))
16000 +               return reqmode;
16001 +
16002 +       if (unlikely(fmode & O_APPEND))
16003 +               reqmode |= GR_APPEND;
16004 +       else if (unlikely(fmode & FMODE_WRITE))
16005 +               reqmode |= GR_WRITE;
16006 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
16007 +               reqmode |= GR_READ;
16008 +
16009 +       mode =
16010 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
16011 +                          mnt);
16012 +
16013 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
16014 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
16015 +                              reqmode & GR_READ ? " reading" : "",
16016 +                              reqmode & GR_WRITE ? " writing" : reqmode &
16017 +                              GR_APPEND ? " appending" : "");
16018 +               return reqmode;
16019 +       } else
16020 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
16021 +       {
16022 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
16023 +                              reqmode & GR_READ ? " reading" : "",
16024 +                              reqmode & GR_WRITE ? " writing" : reqmode &
16025 +                              GR_APPEND ? " appending" : "");
16026 +               return 0;
16027 +       } else if (unlikely((mode & reqmode) != reqmode))
16028 +               return 0;
16029 +
16030 +       return reqmode;
16031 +}
16032 +
16033 +__u32
16034 +gr_acl_handle_creat(const struct dentry * dentry,
16035 +                   const struct dentry * p_dentry,
16036 +                   const struct vfsmount * p_mnt, const int fmode,
16037 +                   const int imode)
16038 +{
16039 +       __u32 reqmode = GR_WRITE | GR_CREATE;
16040 +       __u32 mode;
16041 +
16042 +       if (unlikely(fmode & O_APPEND))
16043 +               reqmode |= GR_APPEND;
16044 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
16045 +               reqmode |= GR_READ;
16046 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
16047 +               reqmode |= GR_SETID;
16048 +
16049 +       mode =
16050 +           gr_check_create(dentry, p_dentry, p_mnt,
16051 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
16052 +
16053 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
16054 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
16055 +                              reqmode & GR_READ ? " reading" : "",
16056 +                              reqmode & GR_WRITE ? " writing" : reqmode &
16057 +                              GR_APPEND ? " appending" : "");
16058 +               return reqmode;
16059 +       } else
16060 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
16061 +       {
16062 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
16063 +                              reqmode & GR_READ ? " reading" : "",
16064 +                              reqmode & GR_WRITE ? " writing" : reqmode &
16065 +                              GR_APPEND ? " appending" : "");
16066 +               return 0;
16067 +       } else if (unlikely((mode & reqmode) != reqmode))
16068 +               return 0;
16069 +
16070 +       return reqmode;
16071 +}
16072 +
16073 +__u32
16074 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
16075 +                    const int fmode)
16076 +{
16077 +       __u32 mode, reqmode = GR_FIND;
16078 +
16079 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
16080 +               reqmode |= GR_EXEC;
16081 +       if (fmode & S_IWOTH)
16082 +               reqmode |= GR_WRITE;
16083 +       if (fmode & S_IROTH)
16084 +               reqmode |= GR_READ;
16085 +
16086 +       mode =
16087 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
16088 +                          mnt);
16089 +
16090 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
16091 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
16092 +                              reqmode & GR_READ ? " reading" : "",
16093 +                              reqmode & GR_WRITE ? " writing" : "",
16094 +                              reqmode & GR_EXEC ? " executing" : "");
16095 +               return reqmode;
16096 +       } else
16097 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
16098 +       {
16099 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
16100 +                              reqmode & GR_READ ? " reading" : "",
16101 +                              reqmode & GR_WRITE ? " writing" : "",
16102 +                              reqmode & GR_EXEC ? " executing" : "");
16103 +               return 0;
16104 +       } else if (unlikely((mode & reqmode) != reqmode))
16105 +               return 0;
16106 +
16107 +       return reqmode;
16108 +}
16109 +
16110 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
16111 +{
16112 +       __u32 mode;
16113 +
16114 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
16115 +
16116 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
16117 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
16118 +               return mode;
16119 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
16120 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
16121 +               return 0;
16122 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
16123 +               return 0;
16124 +
16125 +       return (reqmode);
16126 +}
16127 +
16128 +__u32
16129 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
16130 +{
16131 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
16132 +}
16133 +
16134 +__u32
16135 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
16136 +{
16137 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
16138 +}
16139 +
16140 +__u32
16141 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
16142 +{
16143 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
16144 +}
16145 +
16146 +__u32
16147 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
16148 +{
16149 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
16150 +}
16151 +
16152 +__u32
16153 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
16154 +                    mode_t mode)
16155 +{
16156 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
16157 +               return 1;
16158 +
16159 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
16160 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
16161 +                                  GR_FCHMOD_ACL_MSG);
16162 +       } else {
16163 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
16164 +       }
16165 +}
16166 +
16167 +__u32
16168 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
16169 +                   mode_t mode)
16170 +{
16171 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
16172 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
16173 +                                  GR_CHMOD_ACL_MSG);
16174 +       } else {
16175 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
16176 +       }
16177 +}
16178 +
16179 +__u32
16180 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
16181 +{
16182 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
16183 +}
16184 +
16185 +__u32
16186 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
16187 +{
16188 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
16189 +}
16190 +
16191 +__u32
16192 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
16193 +{
16194 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
16195 +                          GR_UNIXCONNECT_ACL_MSG);
16196 +}
16197 +
16198 +/* hardlinks require at minimum create permission,
16199 +   any additional privilege required is based on the
16200 +   privilege of the file being linked to
16201 +*/
16202 +__u32
16203 +gr_acl_handle_link(const struct dentry * new_dentry,
16204 +                  const struct dentry * parent_dentry,
16205 +                  const struct vfsmount * parent_mnt,
16206 +                  const struct dentry * old_dentry,
16207 +                  const struct vfsmount * old_mnt, const char *to)
16208 +{
16209 +       __u32 mode;
16210 +       __u32 needmode = GR_CREATE | GR_LINK;
16211 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
16212 +
16213 +       mode =
16214 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
16215 +                         old_mnt);
16216 +
16217 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
16218 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
16219 +               return mode;
16220 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
16221 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
16222 +               return 0;
16223 +       } else if (unlikely((mode & needmode) != needmode))
16224 +               return 0;
16225 +
16226 +       return 1;
16227 +}
16228 +
16229 +__u32
16230 +gr_acl_handle_symlink(const struct dentry * new_dentry,
16231 +                     const struct dentry * parent_dentry,
16232 +                     const struct vfsmount * parent_mnt, const char *from)
16233 +{
16234 +       __u32 needmode = GR_WRITE | GR_CREATE;
16235 +       __u32 mode;
16236 +
16237 +       mode =
16238 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
16239 +                           GR_CREATE | GR_AUDIT_CREATE |
16240 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
16241 +
16242 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
16243 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
16244 +               return mode;
16245 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
16246 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
16247 +               return 0;
16248 +       } else if (unlikely((mode & needmode) != needmode))
16249 +               return 0;
16250 +
16251 +       return (GR_WRITE | GR_CREATE);
16252 +}
16253 +
16254 +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)
16255 +{
16256 +       __u32 mode;
16257 +
16258 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
16259 +
16260 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
16261 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
16262 +               return mode;
16263 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
16264 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
16265 +               return 0;
16266 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
16267 +               return 0;
16268 +
16269 +       return (reqmode);
16270 +}
16271 +
16272 +__u32
16273 +gr_acl_handle_mknod(const struct dentry * new_dentry,
16274 +                   const struct dentry * parent_dentry,
16275 +                   const struct vfsmount * parent_mnt,
16276 +                   const int mode)
16277 +{
16278 +       __u32 reqmode = GR_WRITE | GR_CREATE;
16279 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
16280 +               reqmode |= GR_SETID;
16281 +
16282 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
16283 +                                 reqmode, GR_MKNOD_ACL_MSG);
16284 +}
16285 +
16286 +__u32
16287 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
16288 +                   const struct dentry *parent_dentry,
16289 +                   const struct vfsmount *parent_mnt)
16290 +{
16291 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
16292 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
16293 +}
16294 +
16295 +#define RENAME_CHECK_SUCCESS(old, new) \
16296 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
16297 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
16298 +
16299 +int
16300 +gr_acl_handle_rename(struct dentry *new_dentry,
16301 +                    struct dentry *parent_dentry,
16302 +                    const struct vfsmount *parent_mnt,
16303 +                    struct dentry *old_dentry,
16304 +                    struct inode *old_parent_inode,
16305 +                    struct vfsmount *old_mnt, const char *newname)
16306 +{
16307 +       __u32 comp1, comp2;
16308 +       int error = 0;
16309 +
16310 +       if (unlikely(!gr_acl_is_enabled()))
16311 +               return 0;
16312 +
16313 +       if (!new_dentry->d_inode) {
16314 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
16315 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
16316 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
16317 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
16318 +                                      GR_DELETE | GR_AUDIT_DELETE |
16319 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
16320 +                                      GR_SUPPRESS, old_mnt);
16321 +       } else {
16322 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
16323 +                                      GR_CREATE | GR_DELETE |
16324 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
16325 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
16326 +                                      GR_SUPPRESS, parent_mnt);
16327 +               comp2 =
16328 +                   gr_search_file(old_dentry,
16329 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
16330 +                                  GR_DELETE | GR_AUDIT_DELETE |
16331 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
16332 +       }
16333 +
16334 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
16335 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
16336 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
16337 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
16338 +                && !(comp2 & GR_SUPPRESS)) {
16339 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
16340 +               error = -EACCES;
16341 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
16342 +               error = -EACCES;
16343 +
16344 +       return error;
16345 +}
16346 +
16347 +void
16348 +gr_acl_handle_exit(void)
16349 +{
16350 +       u16 id;
16351 +       char *rolename;
16352 +       struct file *exec_file;
16353 +
16354 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
16355 +               id = current->acl_role_id;
16356 +               rolename = current->role->rolename;
16357 +               gr_set_acls(1);
16358 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
16359 +       }
16360 +
16361 +       write_lock(&grsec_exec_file_lock);
16362 +       exec_file = current->exec_file;
16363 +       current->exec_file = NULL;
16364 +       write_unlock(&grsec_exec_file_lock);
16365 +
16366 +       if (exec_file)
16367 +               fput(exec_file);
16368 +}
16369 +
16370 +int
16371 +gr_acl_handle_procpidmem(const struct task_struct *task)
16372 +{
16373 +       if (unlikely(!gr_acl_is_enabled()))
16374 +               return 0;
16375 +
16376 +       if (task->acl->mode & GR_PROTPROCFD)
16377 +               return -EACCES;
16378 +
16379 +       return 0;
16380 +}
16381 diff -urNp linux-2.6.18/grsecurity/gracl_ip.c linux-2.6.18/grsecurity/gracl_ip.c
16382 --- linux-2.6.18/grsecurity/gracl_ip.c  1969-12-31 19:00:00.000000000 -0500
16383 +++ linux-2.6.18/grsecurity/gracl_ip.c  2006-09-22 20:04:35.000000000 -0400
16384 @@ -0,0 +1,313 @@
16385 +#include <linux/kernel.h>
16386 +#include <asm/uaccess.h>
16387 +#include <asm/errno.h>
16388 +#include <net/sock.h>
16389 +#include <linux/file.h>
16390 +#include <linux/fs.h>
16391 +#include <linux/net.h>
16392 +#include <linux/in.h>
16393 +#include <linux/skbuff.h>
16394 +#include <linux/ip.h>
16395 +#include <linux/udp.h>
16396 +#include <linux/smp_lock.h>
16397 +#include <linux/types.h>
16398 +#include <linux/sched.h>
16399 +#include <linux/netdevice.h>
16400 +#include <linux/inetdevice.h>
16401 +#include <linux/gracl.h>
16402 +#include <linux/grsecurity.h>
16403 +#include <linux/grinternal.h>
16404 +
16405 +#define GR_BIND        0x01
16406 +#define GR_CONNECT     0x02
16407 +#define GR_INVERT      0x04
16408 +
16409 +static const char * gr_protocols[256] = {
16410 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
16411 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
16412 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
16413 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
16414 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
16415 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
16416 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
16417 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
16418 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
16419 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
16420 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
16421 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
16422 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
16423 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
16424 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
16425 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
16426 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
16427 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
16428 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
16429 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
16430 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
16431 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
16432 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
16433 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
16434 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
16435 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
16436 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
16437 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
16438 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
16439 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
16440 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
16441 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
16442 +       };
16443 +
16444 +static const char * gr_socktypes[11] = {
16445 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
16446 +       "unknown:7", "unknown:8", "unknown:9", "packet"
16447 +       };
16448 +
16449 +const char *
16450 +gr_proto_to_name(unsigned char proto)
16451 +{
16452 +       return gr_protocols[proto];
16453 +}
16454 +
16455 +const char *
16456 +gr_socktype_to_name(unsigned char type)
16457 +{
16458 +       return gr_socktypes[type];
16459 +}
16460 +
16461 +int
16462 +gr_search_socket(const int domain, const int type, const int protocol)
16463 +{
16464 +       struct acl_subject_label *curr;
16465 +
16466 +       if (unlikely(!gr_acl_is_enabled()))
16467 +               goto exit;
16468 +
16469 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
16470 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
16471 +               goto exit;      // let the kernel handle it
16472 +
16473 +       curr = current->acl;
16474 +
16475 +       if (!curr->ips)
16476 +               goto exit;
16477 +
16478 +       if ((curr->ip_type & (1 << type)) &&
16479 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
16480 +               goto exit;
16481 +
16482 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
16483 +               /* we don't place acls on raw sockets , and sometimes
16484 +                  dgram/ip sockets are opened for ioctl and not
16485 +                  bind/connect, so we'll fake a bind learn log */
16486 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
16487 +                       __u32 fakeip = 0;
16488 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
16489 +                                      current->role->roletype, current->uid,
16490 +                                      current->gid, current->exec_file ?
16491 +                                      gr_to_filename(current->exec_file->f_dentry,
16492 +                                      current->exec_file->f_vfsmnt) :
16493 +                                      curr->filename, curr->filename,
16494 +                                      NIPQUAD(fakeip), 0, type,
16495 +                                      protocol, GR_CONNECT, 
16496 +NIPQUAD(current->signal->curr_ip));
16497 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
16498 +                       __u32 fakeip = 0;
16499 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
16500 +                                      current->role->roletype, current->uid,
16501 +                                      current->gid, current->exec_file ?
16502 +                                      gr_to_filename(current->exec_file->f_dentry,
16503 +                                      current->exec_file->f_vfsmnt) :
16504 +                                      curr->filename, curr->filename,
16505 +                                      NIPQUAD(fakeip), 0, type,
16506 +                                      protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
16507 +               }
16508 +               /* we'll log when they use connect or bind */
16509 +               goto exit;
16510 +       }
16511 +
16512 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
16513 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
16514 +
16515 +       return 0;
16516 +      exit:
16517 +       return 1;
16518 +}
16519 +
16520 +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)
16521 +{
16522 +       if ((ip->mode & mode) &&
16523 +           (ip_port >= ip->low) &&
16524 +           (ip_port <= ip->high) &&
16525 +           ((ntohl(ip_addr) & our_netmask) ==
16526 +            (ntohl(our_addr) & our_netmask))
16527 +           && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
16528 +           && (ip->type & (1 << type))) {
16529 +               if (ip->mode & GR_INVERT)
16530 +                       return 2; // specifically denied
16531 +               else
16532 +                       return 1; // allowed
16533 +       }
16534 +
16535 +       return 0; // not specifically allowed, may continue parsing
16536 +}
16537 +
16538 +static int
16539 +gr_search_connectbind(const int mode, const struct sock *sk,
16540 +                     const struct sockaddr_in *addr, const int type)
16541 +{
16542 +       char iface[IFNAMSIZ] = {0};
16543 +       struct acl_subject_label *curr;
16544 +       struct acl_ip_label *ip;
16545 +       struct net_device *dev;
16546 +       struct in_device *idev;
16547 +       unsigned long i;
16548 +       int ret;
16549 +       __u32 ip_addr = 0;
16550 +       __u32 our_addr;
16551 +       __u32 our_netmask;
16552 +       char *p;
16553 +       __u16 ip_port = 0;
16554 +
16555 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
16556 +               return 1;
16557 +
16558 +       curr = current->acl;
16559 +
16560 +       if (!curr->ips)
16561 +               return 1;
16562 +
16563 +       ip_addr = addr->sin_addr.s_addr;
16564 +       ip_port = ntohs(addr->sin_port);
16565 +
16566 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
16567 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
16568 +                              current->role->roletype, current->uid,
16569 +                              current->gid, current->exec_file ?
16570 +                              gr_to_filename(current->exec_file->f_dentry,
16571 +                              current->exec_file->f_vfsmnt) :
16572 +                              curr->filename, curr->filename,
16573 +                              NIPQUAD(ip_addr), ip_port, type,
16574 +                              sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
16575 +               return 1;
16576 +       }
16577 +
16578 +       for (i = 0; i < curr->ip_num; i++) {
16579 +               ip = *(curr->ips + i);
16580 +               if (ip->iface != NULL) {
16581 +                       strncpy(iface, ip->iface, IFNAMSIZ - 1);
16582 +                       p = strchr(iface, ':');
16583 +                       if (p != NULL)
16584 +                               *p = '\0';
16585 +                       dev = dev_get_by_name(iface);
16586 +                       if (dev == NULL)
16587 +                               continue;
16588 +                       idev = in_dev_get(dev);
16589 +                       if (idev == NULL) {
16590 +                               dev_put(dev);
16591 +                               continue;
16592 +                       }
16593 +                       rcu_read_lock();
16594 +                       for_ifa(idev) {
16595 +                               if (!strcmp(ip->iface, ifa->ifa_label)) {
16596 +                                       our_addr = ifa->ifa_address;
16597 +                                       our_netmask = 0xffffffff;
16598 +                                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
16599 +                                       if (ret == 1) {
16600 +                                               rcu_read_unlock();
16601 +                                               in_dev_put(idev);
16602 +                                               dev_put(dev);
16603 +                                               return 1;
16604 +                                       } else if (ret == 2) {
16605 +                                               rcu_read_unlock();
16606 +                                               in_dev_put(idev);
16607 +                                               dev_put(dev);
16608 +                                               goto denied;
16609 +                                       }
16610 +                               }
16611 +                       } endfor_ifa(idev);
16612 +                       rcu_read_unlock();
16613 +                       in_dev_put(idev);
16614 +                       dev_put(dev);
16615 +               } else {
16616 +                       our_addr = ip->addr;
16617 +                       our_netmask = ip->netmask;
16618 +                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
16619 +                       if (ret == 1)
16620 +                               return 1;
16621 +                       else if (ret == 2)
16622 +                               goto denied;
16623 +               }
16624 +       }
16625 +
16626 +denied:
16627 +       if (mode == GR_BIND)
16628 +               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));
16629 +       else if (mode == GR_CONNECT)
16630 +               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));
16631 +
16632 +       return 0;
16633 +}
16634 +
16635 +int
16636 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
16637 +{
16638 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
16639 +}
16640 +
16641 +int
16642 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
16643 +{
16644 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
16645 +}
16646 +
16647 +int gr_search_listen(const struct socket *sock)
16648 +{
16649 +       struct sock *sk = sock->sk;
16650 +       struct sockaddr_in addr;
16651 +
16652 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
16653 +       addr.sin_port = inet_sk(sk)->sport;
16654 +
16655 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
16656 +}
16657 +
16658 +int gr_search_accept(const struct socket *sock)
16659 +{
16660 +       struct sock *sk = sock->sk;
16661 +       struct sockaddr_in addr;
16662 +
16663 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
16664 +       addr.sin_port = inet_sk(sk)->sport;
16665 +
16666 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
16667 +}
16668 +
16669 +int
16670 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
16671 +{
16672 +       if (addr)
16673 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
16674 +       else {
16675 +               struct sockaddr_in sin;
16676 +               const struct inet_sock *inet = inet_sk(sk);
16677 +
16678 +               sin.sin_addr.s_addr = inet->daddr;
16679 +               sin.sin_port = inet->dport;
16680 +
16681 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
16682 +       }
16683 +}
16684 +
16685 +int
16686 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
16687 +{
16688 +       struct sockaddr_in sin;
16689 +
16690 +       if (unlikely(skb->len < sizeof (struct udphdr)))
16691 +               return 1;       // skip this packet
16692 +
16693 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
16694 +       sin.sin_port = skb->h.uh->source;
16695 +
16696 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
16697 +}
16698 diff -urNp linux-2.6.18/grsecurity/gracl_learn.c linux-2.6.18/grsecurity/gracl_learn.c
16699 --- linux-2.6.18/grsecurity/gracl_learn.c       1969-12-31 19:00:00.000000000 -0500
16700 +++ linux-2.6.18/grsecurity/gracl_learn.c       2006-09-22 20:04:35.000000000 -0400
16701 @@ -0,0 +1,204 @@
16702 +#include <linux/kernel.h>
16703 +#include <linux/mm.h>
16704 +#include <linux/sched.h>
16705 +#include <linux/poll.h>
16706 +#include <linux/smp_lock.h>
16707 +#include <linux/string.h>
16708 +#include <linux/file.h>
16709 +#include <linux/types.h>
16710 +#include <linux/vmalloc.h>
16711 +#include <linux/grinternal.h>
16712 +
16713 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
16714 +                                  size_t count, loff_t *ppos);
16715 +extern int gr_acl_is_enabled(void);
16716 +
16717 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
16718 +static int gr_learn_attached;
16719 +
16720 +/* use a 512k buffer */
16721 +#define LEARN_BUFFER_SIZE (512 * 1024)
16722 +
16723 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
16724 +static DECLARE_MUTEX(gr_learn_user_sem);
16725 +
16726 +/* we need to maintain two buffers, so that the kernel context of grlearn
16727 +   uses a semaphore around the userspace copying, and the other kernel contexts
16728 +   use a spinlock when copying into the buffer, since they cannot sleep
16729 +*/
16730 +static char *learn_buffer;
16731 +static char *learn_buffer_user;
16732 +static int learn_buffer_len;
16733 +static int learn_buffer_user_len;
16734 +
16735 +static ssize_t
16736 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
16737 +{
16738 +       DECLARE_WAITQUEUE(wait, current);
16739 +       ssize_t retval = 0;
16740 +
16741 +       add_wait_queue(&learn_wait, &wait);
16742 +       set_current_state(TASK_INTERRUPTIBLE);
16743 +       do {
16744 +               down(&gr_learn_user_sem);
16745 +               spin_lock(&gr_learn_lock);
16746 +               if (learn_buffer_len)
16747 +                       break;
16748 +               spin_unlock(&gr_learn_lock);
16749 +               up(&gr_learn_user_sem);
16750 +               if (file->f_flags & O_NONBLOCK) {
16751 +                       retval = -EAGAIN;
16752 +                       goto out;
16753 +               }
16754 +               if (signal_pending(current)) {
16755 +                       retval = -ERESTARTSYS;
16756 +                       goto out;
16757 +               }
16758 +
16759 +               schedule();
16760 +       } while (1);
16761 +
16762 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
16763 +       learn_buffer_user_len = learn_buffer_len;
16764 +       retval = learn_buffer_len;
16765 +       learn_buffer_len = 0;
16766 +
16767 +       spin_unlock(&gr_learn_lock);
16768 +
16769 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
16770 +               retval = -EFAULT;
16771 +
16772 +       up(&gr_learn_user_sem);
16773 +out:
16774 +       set_current_state(TASK_RUNNING);
16775 +       remove_wait_queue(&learn_wait, &wait);
16776 +       return retval;
16777 +}
16778 +
16779 +static unsigned int
16780 +poll_learn(struct file * file, poll_table * wait)
16781 +{
16782 +       poll_wait(file, &learn_wait, wait);
16783 +
16784 +       if (learn_buffer_len)
16785 +               return (POLLIN | POLLRDNORM);
16786 +
16787 +       return 0;
16788 +}
16789 +
16790 +void
16791 +gr_clear_learn_entries(void)
16792 +{
16793 +       char *tmp;
16794 +
16795 +       down(&gr_learn_user_sem);
16796 +       if (learn_buffer != NULL) {
16797 +               spin_lock(&gr_learn_lock);
16798 +               tmp = learn_buffer;
16799 +               learn_buffer = NULL;
16800 +               spin_unlock(&gr_learn_lock);
16801 +               vfree(learn_buffer);
16802 +       }
16803 +       if (learn_buffer_user != NULL) {
16804 +               vfree(learn_buffer_user);
16805 +               learn_buffer_user = NULL;
16806 +       }
16807 +       learn_buffer_len = 0;
16808 +       up(&gr_learn_user_sem);
16809 +
16810 +       return;
16811 +}
16812 +
16813 +void
16814 +gr_add_learn_entry(const char *fmt, ...)
16815 +{
16816 +       va_list args;
16817 +       unsigned int len;
16818 +
16819 +       if (!gr_learn_attached)
16820 +               return;
16821 +
16822 +       spin_lock(&gr_learn_lock);
16823 +
16824 +       /* leave a gap at the end so we know when it's "full" but don't have to
16825 +          compute the exact length of the string we're trying to append
16826 +       */
16827 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
16828 +               spin_unlock(&gr_learn_lock);
16829 +               wake_up_interruptible(&learn_wait);
16830 +               return;
16831 +       }
16832 +       if (learn_buffer == NULL) {
16833 +               spin_unlock(&gr_learn_lock);
16834 +               return;
16835 +       }
16836 +
16837 +       va_start(args, fmt);
16838 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
16839 +       va_end(args);
16840 +
16841 +       learn_buffer_len += len + 1;
16842 +
16843 +       spin_unlock(&gr_learn_lock);
16844 +       wake_up_interruptible(&learn_wait);
16845 +
16846 +       return;
16847 +}
16848 +
16849 +static int
16850 +open_learn(struct inode *inode, struct file *file)
16851 +{
16852 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
16853 +               return -EBUSY;
16854 +       if (file->f_mode & FMODE_READ) {
16855 +               down(&gr_learn_user_sem);
16856 +               if (learn_buffer == NULL)
16857 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
16858 +               if (learn_buffer_user == NULL)
16859 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
16860 +               if (learn_buffer == NULL)
16861 +                       return -ENOMEM;
16862 +               if (learn_buffer_user == NULL)
16863 +                       return -ENOMEM;
16864 +               learn_buffer_len = 0;
16865 +               learn_buffer_user_len = 0;
16866 +               gr_learn_attached = 1;
16867 +               up(&gr_learn_user_sem);
16868 +       }
16869 +       return 0;
16870 +}
16871 +
16872 +static int
16873 +close_learn(struct inode *inode, struct file *file)
16874 +{
16875 +       char *tmp;
16876 +
16877 +       if (file->f_mode & FMODE_READ) {
16878 +               down(&gr_learn_user_sem);
16879 +               if (learn_buffer != NULL) {
16880 +                       spin_lock(&gr_learn_lock);
16881 +                       tmp = learn_buffer;
16882 +                       learn_buffer = NULL;
16883 +                       spin_unlock(&gr_learn_lock);
16884 +                       vfree(tmp);
16885 +               }
16886 +               if (learn_buffer_user != NULL) {
16887 +                       vfree(learn_buffer_user);
16888 +                       learn_buffer_user = NULL;
16889 +               }
16890 +               learn_buffer_len = 0;
16891 +               learn_buffer_user_len = 0;
16892 +               gr_learn_attached = 0;
16893 +               up(&gr_learn_user_sem);
16894 +       }
16895 +
16896 +       return 0;
16897 +}
16898 +               
16899 +struct file_operations grsec_fops = {
16900 +       .read           = read_learn,
16901 +       .write          = write_grsec_handler,
16902 +       .open           = open_learn,
16903 +       .release        = close_learn,
16904 +       .poll           = poll_learn,
16905 +};
16906 diff -urNp linux-2.6.18/grsecurity/gracl_res.c linux-2.6.18/grsecurity/gracl_res.c
16907 --- linux-2.6.18/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
16908 +++ linux-2.6.18/grsecurity/gracl_res.c 2006-09-22 20:04:35.000000000 -0400
16909 @@ -0,0 +1,45 @@
16910 +#include <linux/kernel.h>
16911 +#include <linux/sched.h>
16912 +#include <linux/gracl.h>
16913 +#include <linux/grinternal.h>
16914 +
16915 +static const char *restab_log[] = {
16916 +       [RLIMIT_CPU] = "RLIMIT_CPU",
16917 +       [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
16918 +       [RLIMIT_DATA] = "RLIMIT_DATA",
16919 +       [RLIMIT_STACK] = "RLIMIT_STACK",
16920 +       [RLIMIT_CORE] = "RLIMIT_CORE",
16921 +       [RLIMIT_RSS] = "RLIMIT_RSS",
16922 +       [RLIMIT_NPROC] = "RLIMIT_NPROC",
16923 +       [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
16924 +       [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
16925 +       [RLIMIT_AS] = "RLIMIT_AS",
16926 +       [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
16927 +       [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
16928 +};
16929 +
16930 +void
16931 +gr_log_resource(const struct task_struct *task,
16932 +               const int res, const unsigned long wanted, const int gt)
16933 +{
16934 +       if (res == RLIMIT_NPROC && 
16935 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
16936 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
16937 +               return;
16938 +       else if (res == RLIMIT_MEMLOCK &&
16939 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
16940 +               return;
16941 +
16942 +       if (!gr_acl_is_enabled() && !grsec_resource_logging)
16943 +               return;
16944 +
16945 +       preempt_disable();
16946 +
16947 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
16948 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
16949 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
16950 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
16951 +       preempt_enable_no_resched();
16952 +
16953 +       return;
16954 +}
16955 diff -urNp linux-2.6.18/grsecurity/gracl_segv.c linux-2.6.18/grsecurity/gracl_segv.c
16956 --- linux-2.6.18/grsecurity/gracl_segv.c        1969-12-31 19:00:00.000000000 -0500
16957 +++ linux-2.6.18/grsecurity/gracl_segv.c        2006-09-22 20:04:35.000000000 -0400
16958 @@ -0,0 +1,295 @@
16959 +#include <linux/kernel.h>
16960 +#include <linux/mm.h>
16961 +#include <asm/uaccess.h>
16962 +#include <asm/errno.h>
16963 +#include <asm/mman.h>
16964 +#include <net/sock.h>
16965 +#include <linux/file.h>
16966 +#include <linux/fs.h>
16967 +#include <linux/net.h>
16968 +#include <linux/in.h>
16969 +#include <linux/smp_lock.h>
16970 +#include <linux/slab.h>
16971 +#include <linux/types.h>
16972 +#include <linux/sched.h>
16973 +#include <linux/timer.h>
16974 +#include <linux/gracl.h>
16975 +#include <linux/grsecurity.h>
16976 +#include <linux/grinternal.h>
16977 +
16978 +static struct crash_uid *uid_set;
16979 +static unsigned short uid_used;
16980 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
16981 +extern rwlock_t gr_inode_lock;
16982 +extern struct acl_subject_label *
16983 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
16984 +                             struct acl_role_label *role);
16985 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
16986 +
16987 +int
16988 +gr_init_uidset(void)
16989 +{
16990 +       uid_set =
16991 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
16992 +       uid_used = 0;
16993 +
16994 +       return uid_set ? 1 : 0;
16995 +}
16996 +
16997 +void
16998 +gr_free_uidset(void)
16999 +{
17000 +       if (uid_set)
17001 +               kfree(uid_set);
17002 +
17003 +       return;
17004 +}
17005 +
17006 +int
17007 +gr_find_uid(const uid_t uid)
17008 +{
17009 +       struct crash_uid *tmp = uid_set;
17010 +       uid_t buid;
17011 +       int low = 0, high = uid_used - 1, mid;
17012 +
17013 +       while (high >= low) {
17014 +               mid = (low + high) >> 1;
17015 +               buid = tmp[mid].uid;
17016 +               if (buid == uid)
17017 +                       return mid;
17018 +               if (buid > uid)
17019 +                       high = mid - 1;
17020 +               if (buid < uid)
17021 +                       low = mid + 1;
17022 +       }
17023 +
17024 +       return -1;
17025 +}
17026 +
17027 +static __inline__ void
17028 +gr_insertsort(void)
17029 +{
17030 +       unsigned short i, j;
17031 +       struct crash_uid index;
17032 +
17033 +       for (i = 1; i < uid_used; i++) {
17034 +               index = uid_set[i];
17035 +               j = i;
17036 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
17037 +                       uid_set[j] = uid_set[j - 1];
17038 +                       j--;
17039 +               }
17040 +               uid_set[j] = index;
17041 +       }
17042 +
17043 +       return;
17044 +}
17045 +
17046 +static __inline__ void
17047 +gr_insert_uid(const uid_t uid, const unsigned long expires)
17048 +{
17049 +       int loc;
17050 +
17051 +       if (uid_used == GR_UIDTABLE_MAX)
17052 +               return;
17053 +
17054 +       loc = gr_find_uid(uid);
17055 +
17056 +       if (loc >= 0) {
17057 +               uid_set[loc].expires = expires;
17058 +               return;
17059 +       }
17060 +
17061 +       uid_set[uid_used].uid = uid;
17062 +       uid_set[uid_used].expires = expires;
17063 +       uid_used++;
17064 +
17065 +       gr_insertsort();
17066 +
17067 +       return;
17068 +}
17069 +
17070 +void
17071 +gr_remove_uid(const unsigned short loc)
17072 +{
17073 +       unsigned short i;
17074 +
17075 +       for (i = loc + 1; i < uid_used; i++)
17076 +               uid_set[i - 1] = uid_set[i];
17077 +
17078 +       uid_used--;
17079 +
17080 +       return;
17081 +}
17082 +
17083 +int
17084 +gr_check_crash_uid(const uid_t uid)
17085 +{
17086 +       int loc;
17087 +       int ret = 0;
17088 +
17089 +       if (unlikely(!gr_acl_is_enabled()))
17090 +               return 0;
17091 +
17092 +       spin_lock(&gr_uid_lock);
17093 +       loc = gr_find_uid(uid);
17094 +
17095 +       if (loc < 0)
17096 +               goto out_unlock;
17097 +
17098 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
17099 +               gr_remove_uid(loc);
17100 +       else
17101 +               ret = 1;
17102 +
17103 +out_unlock:
17104 +       spin_unlock(&gr_uid_lock);
17105 +       return ret;
17106 +}
17107 +
17108 +static __inline__ int
17109 +proc_is_setxid(const struct task_struct *task)
17110 +{
17111 +       if (task->uid != task->euid || task->uid != task->suid ||
17112 +           task->uid != task->fsuid)
17113 +               return 1;
17114 +       if (task->gid != task->egid || task->gid != task->sgid ||
17115 +           task->gid != task->fsgid)
17116 +               return 1;
17117 +
17118 +       return 0;
17119 +}
17120 +static __inline__ int
17121 +gr_fake_force_sig(int sig, struct task_struct *t)
17122 +{
17123 +       unsigned long int flags;
17124 +       int ret;
17125 +
17126 +       spin_lock_irqsave(&t->sighand->siglock, flags);
17127 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
17128 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
17129 +               sigdelset(&t->blocked, sig);
17130 +               recalc_sigpending_tsk(t);
17131 +       }
17132 +       ret = specific_send_sig_info(sig, (void*)1L, t);
17133 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
17134 +
17135 +       return ret;
17136 +}
17137 +
17138 +void
17139 +gr_handle_crash(struct task_struct *task, const int sig)
17140 +{
17141 +       struct acl_subject_label *curr;
17142 +       struct acl_subject_label *curr2;
17143 +       struct task_struct *tsk, *tsk2;
17144 +
17145 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
17146 +               return;
17147 +
17148 +       if (unlikely(!gr_acl_is_enabled()))
17149 +               return;
17150 +
17151 +       curr = task->acl;
17152 +
17153 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
17154 +               return;
17155 +
17156 +       if (time_before_eq(curr->expires, get_seconds())) {
17157 +               curr->expires = 0;
17158 +               curr->crashes = 0;
17159 +       }
17160 +
17161 +       curr->crashes++;
17162 +
17163 +       if (!curr->expires)
17164 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
17165 +
17166 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
17167 +           time_after(curr->expires, get_seconds())) {
17168 +               if (task->uid && proc_is_setxid(task)) {
17169 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
17170 +                       spin_lock(&gr_uid_lock);
17171 +                       gr_insert_uid(task->uid, curr->expires);
17172 +                       spin_unlock(&gr_uid_lock);
17173 +                       curr->expires = 0;
17174 +                       curr->crashes = 0;
17175 +                       read_lock(&tasklist_lock);
17176 +                       do_each_thread(tsk2, tsk) {
17177 +                               if (tsk != task && tsk->uid == task->uid)
17178 +                                       gr_fake_force_sig(SIGKILL, tsk);
17179 +                       } while_each_thread(tsk2, tsk);
17180 +                       read_unlock(&tasklist_lock);
17181 +               } else {
17182 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
17183 +                       read_lock(&tasklist_lock);
17184 +                       do_each_thread(tsk2, tsk) {
17185 +                               if (likely(tsk != task)) {
17186 +                                       curr2 = tsk->acl;
17187 +
17188 +                                       if (curr2->device == curr->device &&
17189 +                                           curr2->inode == curr->inode)
17190 +                                               gr_fake_force_sig(SIGKILL, tsk);
17191 +                               }
17192 +                       } while_each_thread(tsk2, tsk);
17193 +                       read_unlock(&tasklist_lock);
17194 +               }
17195 +       }
17196 +
17197 +       return;
17198 +}
17199 +
17200 +int
17201 +gr_check_crash_exec(const struct file *filp)
17202 +{
17203 +       struct acl_subject_label *curr;
17204 +
17205 +       if (unlikely(!gr_acl_is_enabled()))
17206 +               return 0;
17207 +
17208 +       read_lock(&gr_inode_lock);
17209 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
17210 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
17211 +                                    current->role);
17212 +       read_unlock(&gr_inode_lock);
17213 +
17214 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
17215 +           (!curr->crashes && !curr->expires))
17216 +               return 0;
17217 +
17218 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
17219 +           time_after(curr->expires, get_seconds()))
17220 +               return 1;
17221 +       else if (time_before_eq(curr->expires, get_seconds())) {
17222 +               curr->crashes = 0;
17223 +               curr->expires = 0;
17224 +       }
17225 +
17226 +       return 0;
17227 +}
17228 +
17229 +void
17230 +gr_handle_alertkill(struct task_struct *task)
17231 +{
17232 +       struct acl_subject_label *curracl;
17233 +       __u32 curr_ip;
17234 +       struct task_struct *p, *p2;
17235 +
17236 +       if (unlikely(!gr_acl_is_enabled()))
17237 +               return;
17238 +
17239 +       curracl = task->acl;
17240 +       curr_ip = task->signal->curr_ip;
17241 +
17242 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
17243 +               read_lock(&tasklist_lock);
17244 +               do_each_thread(p2, p) {
17245 +                       if (p->signal->curr_ip == curr_ip)
17246 +                               gr_fake_force_sig(SIGKILL, p);
17247 +               } while_each_thread(p2, p);
17248 +               read_unlock(&tasklist_lock);
17249 +       } else if (curracl->mode & GR_KILLPROC)
17250 +               gr_fake_force_sig(SIGKILL, task);
17251 +
17252 +       return;
17253 +}
17254 diff -urNp linux-2.6.18/grsecurity/gracl_shm.c linux-2.6.18/grsecurity/gracl_shm.c
17255 --- linux-2.6.18/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
17256 +++ linux-2.6.18/grsecurity/gracl_shm.c 2006-09-22 20:04:35.000000000 -0400
17257 @@ -0,0 +1,33 @@
17258 +#include <linux/kernel.h>
17259 +#include <linux/mm.h>
17260 +#include <linux/sched.h>
17261 +#include <linux/file.h>
17262 +#include <linux/ipc.h>
17263 +#include <linux/gracl.h>
17264 +#include <linux/grsecurity.h>
17265 +#include <linux/grinternal.h>
17266 +
17267 +int
17268 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
17269 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
17270 +{
17271 +       struct task_struct *task;
17272 +
17273 +       if (!gr_acl_is_enabled())
17274 +               return 1;
17275 +
17276 +       task = find_task_by_pid(shm_cprid);
17277 +
17278 +       if (unlikely(!task))
17279 +               task = find_task_by_pid(shm_lapid);
17280 +
17281 +       if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
17282 +                             (task->pid == shm_lapid)) &&
17283 +                    (task->acl->mode & GR_PROTSHM) &&
17284 +                    (task->acl != current->acl))) {
17285 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
17286 +               return 0;
17287 +       }
17288 +
17289 +       return 1;
17290 +}
17291 diff -urNp linux-2.6.18/grsecurity/grsec_chdir.c linux-2.6.18/grsecurity/grsec_chdir.c
17292 --- linux-2.6.18/grsecurity/grsec_chdir.c       1969-12-31 19:00:00.000000000 -0500
17293 +++ linux-2.6.18/grsecurity/grsec_chdir.c       2006-09-22 20:04:35.000000000 -0400
17294 @@ -0,0 +1,19 @@
17295 +#include <linux/kernel.h>
17296 +#include <linux/sched.h>
17297 +#include <linux/fs.h>
17298 +#include <linux/file.h>
17299 +#include <linux/grsecurity.h>
17300 +#include <linux/grinternal.h>
17301 +
17302 +void
17303 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
17304 +{
17305 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
17306 +       if ((grsec_enable_chdir && grsec_enable_group &&
17307 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
17308 +                                             !grsec_enable_group)) {
17309 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
17310 +       }
17311 +#endif
17312 +       return;
17313 +}
17314 diff -urNp linux-2.6.18/grsecurity/grsec_chroot.c linux-2.6.18/grsecurity/grsec_chroot.c
17315 --- linux-2.6.18/grsecurity/grsec_chroot.c      1969-12-31 19:00:00.000000000 -0500
17316 +++ linux-2.6.18/grsecurity/grsec_chroot.c      2006-09-22 20:04:35.000000000 -0400
17317 @@ -0,0 +1,332 @@
17318 +#include <linux/kernel.h>
17319 +#include <linux/module.h>
17320 +#include <linux/sched.h>
17321 +#include <linux/file.h>
17322 +#include <linux/fs.h>
17323 +#include <linux/mount.h>
17324 +#include <linux/types.h>
17325 +#include <linux/grinternal.h>
17326 +
17327 +int
17328 +gr_handle_chroot_unix(const pid_t pid)
17329 +{
17330 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
17331 +       struct pid *spid = NULL;
17332 +
17333 +       if (unlikely(!grsec_enable_chroot_unix))
17334 +               return 1;
17335 +
17336 +       if (likely(!proc_is_chrooted(current)))
17337 +               return 1;
17338 +
17339 +       read_lock(&tasklist_lock);
17340 +
17341 +       spid = find_pid(pid);
17342 +       if (spid) {
17343 +               struct task_struct *p;
17344 +               p = pid_task(spid, PIDTYPE_PID);
17345 +               task_lock(p);
17346 +               if (unlikely(!have_same_root(current, p))) {
17347 +                       task_unlock(p);
17348 +                       read_unlock(&tasklist_lock);
17349 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
17350 +                       return 0;
17351 +               }
17352 +               task_unlock(p);
17353 +       }
17354 +       read_unlock(&tasklist_lock);
17355 +#endif
17356 +       return 1;
17357 +}
17358 +
17359 +int
17360 +gr_handle_chroot_nice(void)
17361 +{
17362 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17363 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
17364 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
17365 +               return -EPERM;
17366 +       }
17367 +#endif
17368 +       return 0;
17369 +}
17370 +
17371 +int
17372 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
17373 +{
17374 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17375 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
17376 +                       && proc_is_chrooted(current)) {
17377 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
17378 +               return -EACCES;
17379 +       }
17380 +#endif
17381 +       return 0;
17382 +}
17383 +
17384 +int
17385 +gr_handle_chroot_rawio(const struct inode *inode)
17386 +{
17387 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17388 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
17389 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
17390 +               return 1;
17391 +#endif
17392 +       return 0;
17393 +}
17394 +
17395 +int
17396 +gr_pid_is_chrooted(struct task_struct *p)
17397 +{
17398 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
17399 +       if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !p)
17400 +               return 0;
17401 +
17402 +       task_lock(p);
17403 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
17404 +           !have_same_root(current, p)) {
17405 +               task_unlock(p);
17406 +               return 1;
17407 +       }
17408 +       task_unlock(p);
17409 +#endif
17410 +       return 0;
17411 +}
17412 +
17413 +EXPORT_SYMBOL(gr_pid_is_chrooted);
17414 +
17415 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
17416 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
17417 +{
17418 +       struct dentry *dentry = (struct dentry *)u_dentry;
17419 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
17420 +       struct dentry *realroot;
17421 +       struct vfsmount *realrootmnt;
17422 +       struct dentry *currentroot;
17423 +       struct vfsmount *currentmnt;
17424 +       int ret = 1;
17425 +
17426 +       read_lock(&child_reaper->fs->lock);
17427 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
17428 +       realroot = dget(child_reaper->fs->root);
17429 +       read_unlock(&child_reaper->fs->lock);
17430 +
17431 +       read_lock(&current->fs->lock);
17432 +       currentmnt = mntget(current->fs->rootmnt);
17433 +       currentroot = dget(current->fs->root);
17434 +       read_unlock(&current->fs->lock);
17435 +
17436 +       spin_lock(&dcache_lock);
17437 +       for (;;) {
17438 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
17439 +                    || (dentry == currentroot && mnt == currentmnt)))
17440 +                       break;
17441 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
17442 +                       if (mnt->mnt_parent == mnt)
17443 +                               break;
17444 +                       dentry = mnt->mnt_mountpoint;
17445 +                       mnt = mnt->mnt_parent;
17446 +                       continue;
17447 +               }
17448 +               dentry = dentry->d_parent;
17449 +       }
17450 +       spin_unlock(&dcache_lock);
17451 +
17452 +       dput(currentroot);
17453 +       mntput(currentmnt);
17454 +
17455 +       /* access is outside of chroot */
17456 +       if (dentry == realroot && mnt == realrootmnt)
17457 +               ret = 0;
17458 +
17459 +       dput(realroot);
17460 +       mntput(realrootmnt);
17461 +       return ret;
17462 +}
17463 +#endif
17464 +
17465 +int
17466 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
17467 +{
17468 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
17469 +       if (!grsec_enable_chroot_fchdir)
17470 +               return 1;
17471 +
17472 +       if (!proc_is_chrooted(current))
17473 +               return 1;
17474 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
17475 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
17476 +               return 0;
17477 +       }
17478 +#endif
17479 +       return 1;
17480 +}
17481 +
17482 +int
17483 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
17484 +               const time_t shm_createtime)
17485 +{
17486 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
17487 +       struct pid *pid = NULL;
17488 +       time_t starttime;
17489 +
17490 +       if (unlikely(!grsec_enable_chroot_shmat))
17491 +               return 1;
17492 +
17493 +       if (likely(!proc_is_chrooted(current)))
17494 +               return 1;
17495 +
17496 +       read_lock(&tasklist_lock);
17497 +
17498 +       pid = find_pid(shm_cprid);
17499 +       if (pid) {
17500 +               struct task_struct *p;
17501 +               p = pid_task(pid, PIDTYPE_PID);
17502 +               task_lock(p);
17503 +               starttime = p->start_time.tv_sec;
17504 +               if (unlikely(!have_same_root(current, p) &&
17505 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
17506 +                       task_unlock(p);
17507 +                       read_unlock(&tasklist_lock);
17508 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
17509 +                       return 0;
17510 +               }
17511 +               task_unlock(p);
17512 +       } else {
17513 +               pid = find_pid(shm_lapid);
17514 +               if (pid) {
17515 +                       struct task_struct *p;
17516 +                       p = pid_task(pid, PIDTYPE_PID);
17517 +                       task_lock(p);
17518 +                       if (unlikely(!have_same_root(current, p))) {
17519 +                               task_unlock(p);
17520 +                               read_unlock(&tasklist_lock);
17521 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
17522 +                               return 0;
17523 +                       }
17524 +                       task_unlock(p);
17525 +               }
17526 +       }
17527 +
17528 +       read_unlock(&tasklist_lock);
17529 +#endif
17530 +       return 1;
17531 +}
17532 +
17533 +void
17534 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
17535 +{
17536 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
17537 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
17538 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
17539 +#endif
17540 +       return;
17541 +}
17542 +
17543 +int
17544 +gr_handle_chroot_mknod(const struct dentry *dentry,
17545 +                      const struct vfsmount *mnt, const int mode)
17546 +{
17547 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
17548 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
17549 +           proc_is_chrooted(current)) {
17550 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
17551 +               return -EPERM;
17552 +       }
17553 +#endif
17554 +       return 0;
17555 +}
17556 +
17557 +int
17558 +gr_handle_chroot_mount(const struct dentry *dentry,
17559 +                      const struct vfsmount *mnt, const char *dev_name)
17560 +{
17561 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
17562 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
17563 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
17564 +               return -EPERM;
17565 +       }
17566 +#endif
17567 +       return 0;
17568 +}
17569 +
17570 +int
17571 +gr_handle_chroot_pivot(void)
17572 +{
17573 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
17574 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
17575 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
17576 +               return -EPERM;
17577 +       }
17578 +#endif
17579 +       return 0;
17580 +}
17581 +
17582 +int
17583 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
17584 +{
17585 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17586 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
17587 +           !gr_is_outside_chroot(dentry, mnt)) {
17588 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
17589 +               return -EPERM;
17590 +       }
17591 +#endif
17592 +       return 0;
17593 +}
17594 +
17595 +void
17596 +gr_handle_chroot_caps(struct task_struct *task)
17597 +{
17598 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17599 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
17600 +               task->cap_permitted =
17601 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
17602 +               task->cap_inheritable =
17603 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
17604 +               task->cap_effective =
17605 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
17606 +       }
17607 +#endif
17608 +       return;
17609 +}
17610 +
17611 +int
17612 +gr_handle_chroot_sysctl(const int op)
17613 +{
17614 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17615 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
17616 +           && (op & 002))
17617 +               return -EACCES;
17618 +#endif
17619 +       return 0;
17620 +}
17621 +
17622 +void
17623 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
17624 +{
17625 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17626 +       if (grsec_enable_chroot_chdir)
17627 +               set_fs_pwd(current->fs, mnt, dentry);
17628 +#endif
17629 +       return;
17630 +}
17631 +
17632 +int
17633 +gr_handle_chroot_chmod(const struct dentry *dentry,
17634 +                      const struct vfsmount *mnt, const int mode)
17635 +{
17636 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17637 +       if (grsec_enable_chroot_chmod &&
17638 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
17639 +           proc_is_chrooted(current)) {
17640 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
17641 +               return -EPERM;
17642 +       }
17643 +#endif
17644 +       return 0;
17645 +}
17646 +
17647 +#ifdef CONFIG_SECURITY
17648 +EXPORT_SYMBOL(gr_handle_chroot_caps);
17649 +#endif
17650 diff -urNp linux-2.6.18/grsecurity/grsec_disabled.c linux-2.6.18/grsecurity/grsec_disabled.c
17651 --- linux-2.6.18/grsecurity/grsec_disabled.c    1969-12-31 19:00:00.000000000 -0500
17652 +++ linux-2.6.18/grsecurity/grsec_disabled.c    2006-09-22 20:04:35.000000000 -0400
17653 @@ -0,0 +1,418 @@
17654 +#include <linux/kernel.h>
17655 +#include <linux/module.h>
17656 +#include <linux/config.h>
17657 +#include <linux/sched.h>
17658 +#include <linux/file.h>
17659 +#include <linux/fs.h>
17660 +#include <linux/kdev_t.h>
17661 +#include <linux/net.h>
17662 +#include <linux/in.h>
17663 +#include <linux/ip.h>
17664 +#include <linux/skbuff.h>
17665 +#include <linux/sysctl.h>
17666 +
17667 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
17668 +void
17669 +pax_set_initial_flags(struct linux_binprm *bprm)
17670 +{
17671 +       return;
17672 +}
17673 +#endif
17674 +
17675 +#ifdef CONFIG_SYSCTL
17676 +__u32
17677 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
17678 +{
17679 +       return mode;
17680 +}
17681 +#endif
17682 +
17683 +int
17684 +gr_acl_is_enabled(void)
17685 +{
17686 +       return 0;
17687 +}
17688 +
17689 +int
17690 +gr_handle_rawio(const struct inode *inode)
17691 +{
17692 +       return 0;
17693 +}
17694 +
17695 +void
17696 +gr_acl_handle_psacct(struct task_struct *task, const long code)
17697 +{
17698 +       return;
17699 +}
17700 +
17701 +int
17702 +gr_handle_ptrace(struct task_struct *task, const long request)
17703 +{
17704 +       return 0;
17705 +}
17706 +
17707 +int
17708 +gr_handle_proc_ptrace(struct task_struct *task)
17709 +{
17710 +       return 0;
17711 +}
17712 +
17713 +void
17714 +gr_learn_resource(const struct task_struct *task,
17715 +                 const int res, const unsigned long wanted, const int gt)
17716 +{
17717 +       return;
17718 +}
17719 +
17720 +int
17721 +gr_set_acls(const int type)
17722 +{
17723 +       return 0;
17724 +}
17725 +
17726 +int
17727 +gr_check_hidden_task(const struct task_struct *tsk)
17728 +{
17729 +       return 0;
17730 +}
17731 +
17732 +int
17733 +gr_check_protected_task(const struct task_struct *task)
17734 +{
17735 +       return 0;
17736 +}
17737 +
17738 +void
17739 +gr_copy_label(struct task_struct *tsk)
17740 +{
17741 +       return;
17742 +}
17743 +
17744 +void
17745 +gr_set_pax_flags(struct task_struct *task)
17746 +{
17747 +       return;
17748 +}
17749 +
17750 +int
17751 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
17752 +{
17753 +       return 0;
17754 +}
17755 +
17756 +void
17757 +gr_handle_delete(const ino_t ino, const dev_t dev)
17758 +{
17759 +       return;
17760 +}
17761 +
17762 +void
17763 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
17764 +{
17765 +       return;
17766 +}
17767 +
17768 +void
17769 +gr_handle_crash(struct task_struct *task, const int sig)
17770 +{
17771 +       return;
17772 +}
17773 +
17774 +int
17775 +gr_check_crash_exec(const struct file *filp)
17776 +{
17777 +       return 0;
17778 +}
17779 +
17780 +int
17781 +gr_check_crash_uid(const uid_t uid)
17782 +{
17783 +       return 0;
17784 +}
17785 +
17786 +void
17787 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
17788 +                struct dentry *old_dentry,
17789 +                struct dentry *new_dentry,
17790 +                struct vfsmount *mnt, const __u8 replace)
17791 +{
17792 +       return;
17793 +}
17794 +
17795 +int
17796 +gr_search_socket(const int family, const int type, const int protocol)
17797 +{
17798 +       return 1;
17799 +}
17800 +
17801 +int
17802 +gr_search_connectbind(const int mode, const struct socket *sock,
17803 +                     const struct sockaddr_in *addr)
17804 +{
17805 +       return 1;
17806 +}
17807 +
17808 +int
17809 +gr_task_is_capable(struct task_struct *task, const int cap)
17810 +{
17811 +       return 1;
17812 +}
17813 +
17814 +int
17815 +gr_is_capable_nolog(const int cap)
17816 +{
17817 +       return 1;
17818 +}
17819 +
17820 +void
17821 +gr_handle_alertkill(struct task_struct *task)
17822 +{
17823 +       return;
17824 +}
17825 +
17826 +__u32
17827 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
17828 +{
17829 +       return 1;
17830 +}
17831 +
17832 +__u32
17833 +gr_acl_handle_hidden_file(const struct dentry * dentry,
17834 +                         const struct vfsmount * mnt)
17835 +{
17836 +       return 1;
17837 +}
17838 +
17839 +__u32
17840 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
17841 +                  const int fmode)
17842 +{
17843 +       return 1;
17844 +}
17845 +
17846 +__u32
17847 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
17848 +{
17849 +       return 1;
17850 +}
17851 +
17852 +__u32
17853 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
17854 +{
17855 +       return 1;
17856 +}
17857 +
17858 +int
17859 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
17860 +                  unsigned int *vm_flags)
17861 +{
17862 +       return 1;
17863 +}
17864 +
17865 +__u32
17866 +gr_acl_handle_truncate(const struct dentry * dentry,
17867 +                      const struct vfsmount * mnt)
17868 +{
17869 +       return 1;
17870 +}
17871 +
17872 +__u32
17873 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
17874 +{
17875 +       return 1;
17876 +}
17877 +
17878 +__u32
17879 +gr_acl_handle_access(const struct dentry * dentry,
17880 +                    const struct vfsmount * mnt, const int fmode)
17881 +{
17882 +       return 1;
17883 +}
17884 +
17885 +__u32
17886 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
17887 +                    mode_t mode)
17888 +{
17889 +       return 1;
17890 +}
17891 +
17892 +__u32
17893 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
17894 +                   mode_t mode)
17895 +{
17896 +       return 1;
17897 +}
17898 +
17899 +__u32
17900 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
17901 +{
17902 +       return 1;
17903 +}
17904 +
17905 +void
17906 +grsecurity_init(void)
17907 +{
17908 +       return;
17909 +}
17910 +
17911 +__u32
17912 +gr_acl_handle_mknod(const struct dentry * new_dentry,
17913 +                   const struct dentry * parent_dentry,
17914 +                   const struct vfsmount * parent_mnt,
17915 +                   const int mode)
17916 +{
17917 +       return 1;
17918 +}
17919 +
17920 +__u32
17921 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
17922 +                   const struct dentry * parent_dentry,
17923 +                   const struct vfsmount * parent_mnt)
17924 +{
17925 +       return 1;
17926 +}
17927 +
17928 +__u32
17929 +gr_acl_handle_symlink(const struct dentry * new_dentry,
17930 +                     const struct dentry * parent_dentry,
17931 +                     const struct vfsmount * parent_mnt, const char *from)
17932 +{
17933 +       return 1;
17934 +}
17935 +
17936 +__u32
17937 +gr_acl_handle_link(const struct dentry * new_dentry,
17938 +                  const struct dentry * parent_dentry,
17939 +                  const struct vfsmount * parent_mnt,
17940 +                  const struct dentry * old_dentry,
17941 +                  const struct vfsmount * old_mnt, const char *to)
17942 +{
17943 +       return 1;
17944 +}
17945 +
17946 +int
17947 +gr_acl_handle_rename(const struct dentry *new_dentry,
17948 +                    const struct dentry *parent_dentry,
17949 +                    const struct vfsmount *parent_mnt,
17950 +                    const struct dentry *old_dentry,
17951 +                    const struct inode *old_parent_inode,
17952 +                    const struct vfsmount *old_mnt, const char *newname)
17953 +{
17954 +       return 0;
17955 +}
17956 +
17957 +int
17958 +gr_acl_handle_filldir(const struct file *file, const char *name,
17959 +                     const int namelen, const ino_t ino)
17960 +{
17961 +       return 1;
17962 +}
17963 +
17964 +int
17965 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
17966 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
17967 +{
17968 +       return 1;
17969 +}
17970 +
17971 +int
17972 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
17973 +{
17974 +       return 1;
17975 +}
17976 +
17977 +int
17978 +gr_search_accept(const struct socket *sock)
17979 +{
17980 +       return 1;
17981 +}
17982 +
17983 +int
17984 +gr_search_listen(const struct socket *sock)
17985 +{
17986 +       return 1;
17987 +}
17988 +
17989 +int
17990 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
17991 +{
17992 +       return 1;
17993 +}
17994 +
17995 +__u32
17996 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
17997 +{
17998 +       return 1;
17999 +}
18000 +
18001 +__u32
18002 +gr_acl_handle_creat(const struct dentry * dentry,
18003 +                   const struct dentry * p_dentry,
18004 +                   const struct vfsmount * p_mnt, const int fmode,
18005 +                   const int imode)
18006 +{
18007 +       return 1;
18008 +}
18009 +
18010 +void
18011 +gr_acl_handle_exit(void)
18012 +{
18013 +       return;
18014 +}
18015 +
18016 +int
18017 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
18018 +{
18019 +       return 1;
18020 +}
18021 +
18022 +void
18023 +gr_set_role_label(const uid_t uid, const gid_t gid)
18024 +{
18025 +       return;
18026 +}
18027 +
18028 +int
18029 +gr_acl_handle_procpidmem(const struct task_struct *task)
18030 +{
18031 +       return 0;
18032 +}
18033 +
18034 +int
18035 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
18036 +{
18037 +       return 1;
18038 +}
18039 +
18040 +int
18041 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
18042 +{
18043 +       return 1;
18044 +}
18045 +
18046 +void
18047 +gr_set_kernel_label(struct task_struct *task)
18048 +{
18049 +       return;
18050 +}
18051 +
18052 +int
18053 +gr_check_user_change(int real, int effective, int fs)
18054 +{
18055 +       return 0;
18056 +}
18057 +
18058 +int
18059 +gr_check_group_change(int real, int effective, int fs)
18060 +{
18061 +       return 0;
18062 +}
18063 +
18064 +
18065 +EXPORT_SYMBOL(gr_task_is_capable);
18066 +EXPORT_SYMBOL(gr_learn_resource);
18067 +EXPORT_SYMBOL(gr_set_kernel_label);
18068 +#ifdef CONFIG_SECURITY
18069 +EXPORT_SYMBOL(gr_check_user_change);
18070 +EXPORT_SYMBOL(gr_check_group_change);
18071 +#endif
18072 diff -urNp linux-2.6.18/grsecurity/grsec_exec.c linux-2.6.18/grsecurity/grsec_exec.c
18073 --- linux-2.6.18/grsecurity/grsec_exec.c        1969-12-31 19:00:00.000000000 -0500
18074 +++ linux-2.6.18/grsecurity/grsec_exec.c        2006-09-22 20:04:35.000000000 -0400
18075 @@ -0,0 +1,88 @@
18076 +#include <linux/kernel.h>
18077 +#include <linux/sched.h>
18078 +#include <linux/file.h>
18079 +#include <linux/binfmts.h>
18080 +#include <linux/smp_lock.h>
18081 +#include <linux/fs.h>
18082 +#include <linux/types.h>
18083 +#include <linux/grdefs.h>
18084 +#include <linux/grinternal.h>
18085 +#include <linux/capability.h>
18086 +
18087 +#include <asm/uaccess.h>
18088 +
18089 +#ifdef CONFIG_GRKERNSEC_EXECLOG
18090 +static char gr_exec_arg_buf[132];
18091 +static DECLARE_MUTEX(gr_exec_arg_sem);
18092 +#endif
18093 +
18094 +int
18095 +gr_handle_nproc(void)
18096 +{
18097 +#ifdef CONFIG_GRKERNSEC_EXECVE
18098 +       if (grsec_enable_execve && current->user &&
18099 +           (atomic_read(&current->user->processes) >
18100 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
18101 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
18102 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
18103 +               return -EAGAIN;
18104 +       }
18105 +#endif
18106 +       return 0;
18107 +}
18108 +
18109 +void
18110 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
18111 +{
18112 +#ifdef CONFIG_GRKERNSEC_EXECLOG
18113 +       char *grarg = gr_exec_arg_buf;
18114 +       unsigned int i, x, execlen = 0;
18115 +       char c;
18116 +
18117 +       if (!((grsec_enable_execlog && grsec_enable_group &&
18118 +              in_group_p(grsec_audit_gid))
18119 +             || (grsec_enable_execlog && !grsec_enable_group)))
18120 +               return;
18121 +
18122 +       down(&gr_exec_arg_sem);
18123 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
18124 +
18125 +       if (unlikely(argv == NULL))
18126 +               goto log;
18127 +
18128 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
18129 +               const char __user *p;
18130 +               unsigned int len;
18131 +
18132 +               if (copy_from_user(&p, argv + i, sizeof(p)))
18133 +                       goto log;
18134 +               if (!p)
18135 +                       goto log;
18136 +               len = strnlen_user(p, 128 - execlen);
18137 +               if (len > 128 - execlen)
18138 +                       len = 128 - execlen;
18139 +               else if (len > 0)
18140 +                       len--;
18141 +               if (copy_from_user(grarg + execlen, p, len))
18142 +                       goto log;
18143 +
18144 +               /* rewrite unprintable characters */
18145 +               for (x = 0; x < len; x++) {
18146 +                       c = *(grarg + execlen + x);
18147 +                       if (c < 32 || c > 126)
18148 +                               *(grarg + execlen + x) = ' ';
18149 +               }
18150 +
18151 +               execlen += len;
18152 +               *(grarg + execlen) = ' ';
18153 +               *(grarg + execlen + 1) = '\0';
18154 +               execlen++;
18155 +       }
18156 +
18157 +      log:
18158 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
18159 +                       bprm->file->f_vfsmnt, grarg);
18160 +       up(&gr_exec_arg_sem);
18161 +#endif
18162 +       return;
18163 +}
18164 diff -urNp linux-2.6.18/grsecurity/grsec_fifo.c linux-2.6.18/grsecurity/grsec_fifo.c
18165 --- linux-2.6.18/grsecurity/grsec_fifo.c        1969-12-31 19:00:00.000000000 -0500
18166 +++ linux-2.6.18/grsecurity/grsec_fifo.c        2006-09-22 20:04:35.000000000 -0400
18167 @@ -0,0 +1,22 @@
18168 +#include <linux/kernel.h>
18169 +#include <linux/sched.h>
18170 +#include <linux/fs.h>
18171 +#include <linux/file.h>
18172 +#include <linux/grinternal.h>
18173 +
18174 +int
18175 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
18176 +              const struct dentry *dir, const int flag, const int acc_mode)
18177 +{
18178 +#ifdef CONFIG_GRKERNSEC_FIFO
18179 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
18180 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
18181 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
18182 +           (current->fsuid != dentry->d_inode->i_uid)) {
18183 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
18184 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
18185 +               return -EACCES;
18186 +       }
18187 +#endif
18188 +       return 0;
18189 +}
18190 diff -urNp linux-2.6.18/grsecurity/grsec_fork.c linux-2.6.18/grsecurity/grsec_fork.c
18191 --- linux-2.6.18/grsecurity/grsec_fork.c        1969-12-31 19:00:00.000000000 -0500
18192 +++ linux-2.6.18/grsecurity/grsec_fork.c        2006-09-22 20:04:35.000000000 -0400
18193 @@ -0,0 +1,15 @@
18194 +#include <linux/kernel.h>
18195 +#include <linux/sched.h>
18196 +#include <linux/grsecurity.h>
18197 +#include <linux/grinternal.h>
18198 +#include <linux/errno.h>
18199 +
18200 +void
18201 +gr_log_forkfail(const int retval)
18202 +{
18203 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
18204 +       if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
18205 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
18206 +#endif
18207 +       return;
18208 +}
18209 diff -urNp linux-2.6.18/grsecurity/grsec_init.c linux-2.6.18/grsecurity/grsec_init.c
18210 --- linux-2.6.18/grsecurity/grsec_init.c        1969-12-31 19:00:00.000000000 -0500
18211 +++ linux-2.6.18/grsecurity/grsec_init.c        2006-09-22 20:04:35.000000000 -0400
18212 @@ -0,0 +1,236 @@
18213 +#include <linux/kernel.h>
18214 +#include <linux/sched.h>
18215 +#include <linux/mm.h>
18216 +#include <linux/smp_lock.h>
18217 +#include <linux/gracl.h>
18218 +#include <linux/slab.h>
18219 +#include <linux/vmalloc.h>
18220 +#include <linux/percpu.h>
18221 +
18222 +int grsec_enable_shm;
18223 +int grsec_enable_link;
18224 +int grsec_enable_dmesg;
18225 +int grsec_enable_fifo;
18226 +int grsec_enable_execve;
18227 +int grsec_enable_execlog;
18228 +int grsec_enable_signal;
18229 +int grsec_enable_forkfail;
18230 +int grsec_enable_time;
18231 +int grsec_enable_audit_textrel;
18232 +int grsec_enable_group;
18233 +int grsec_audit_gid;
18234 +int grsec_enable_chdir;
18235 +int grsec_enable_audit_ipc;
18236 +int grsec_enable_mount;
18237 +int grsec_enable_chroot_findtask;
18238 +int grsec_enable_chroot_mount;
18239 +int grsec_enable_chroot_shmat;
18240 +int grsec_enable_chroot_fchdir;
18241 +int grsec_enable_chroot_double;
18242 +int grsec_enable_chroot_pivot;
18243 +int grsec_enable_chroot_chdir;
18244 +int grsec_enable_chroot_chmod;
18245 +int grsec_enable_chroot_mknod;
18246 +int grsec_enable_chroot_nice;
18247 +int grsec_enable_chroot_execlog;
18248 +int grsec_enable_chroot_caps;
18249 +int grsec_enable_chroot_sysctl;
18250 +int grsec_enable_chroot_unix;
18251 +int grsec_enable_tpe;
18252 +int grsec_tpe_gid;
18253 +int grsec_enable_tpe_all;
18254 +int grsec_enable_randpid;
18255 +int grsec_enable_socket_all;
18256 +int grsec_socket_all_gid;
18257 +int grsec_enable_socket_client;
18258 +int grsec_socket_client_gid;
18259 +int grsec_enable_socket_server;
18260 +int grsec_socket_server_gid;
18261 +int grsec_resource_logging;
18262 +int grsec_lock;
18263 +
18264 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
18265 +unsigned long grsec_alert_wtime = 0;
18266 +unsigned long grsec_alert_fyet = 0;
18267 +
18268 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
18269 +
18270 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
18271 +
18272 +char *gr_shared_page[4];
18273 +
18274 +char *gr_alert_log_fmt;
18275 +char *gr_audit_log_fmt;
18276 +char *gr_alert_log_buf;
18277 +char *gr_audit_log_buf;
18278 +
18279 +extern struct gr_arg *gr_usermode;
18280 +extern unsigned char *gr_system_salt;
18281 +extern unsigned char *gr_system_sum;
18282 +
18283 +void
18284 +grsecurity_init(void)
18285 +{
18286 +       int j;
18287 +       /* create the per-cpu shared pages */
18288 +
18289 +       preempt_disable();
18290 +       for (j = 0; j < 4; j++) {
18291 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
18292 +               if (gr_shared_page[j] == NULL) {
18293 +                       panic("Unable to allocate grsecurity shared page");
18294 +                       return;
18295 +               }
18296 +       }
18297 +       preempt_enable();
18298 +
18299 +       /* allocate log buffers */
18300 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
18301 +       if (!gr_alert_log_fmt) {
18302 +               panic("Unable to allocate grsecurity alert log format buffer");
18303 +               return;
18304 +       }
18305 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
18306 +       if (!gr_audit_log_fmt) {
18307 +               panic("Unable to allocate grsecurity audit log format buffer");
18308 +               return;
18309 +       }
18310 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
18311 +       if (!gr_alert_log_buf) {
18312 +               panic("Unable to allocate grsecurity alert log buffer");
18313 +               return;
18314 +       }
18315 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
18316 +       if (!gr_audit_log_buf) {
18317 +               panic("Unable to allocate grsecurity audit log buffer");
18318 +               return;
18319 +       }
18320 +
18321 +       /* allocate memory for authentication structure */
18322 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
18323 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
18324 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
18325 +
18326 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
18327 +               panic("Unable to allocate grsecurity authentication structure");
18328 +               return;
18329 +       }
18330 +
18331 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
18332 +#ifndef CONFIG_GRKERNSEC_SYSCTL
18333 +       grsec_lock = 1;
18334 +#endif
18335 +#ifdef CONFIG_GRKERNSEC_SHM
18336 +       grsec_enable_shm = 1;
18337 +#endif
18338 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
18339 +       grsec_enable_audit_textrel = 1;
18340 +#endif
18341 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
18342 +       grsec_enable_group = 1;
18343 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
18344 +#endif
18345 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
18346 +       grsec_enable_chdir = 1;
18347 +#endif
18348 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18349 +       grsec_enable_audit_ipc = 1;
18350 +#endif
18351 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18352 +       grsec_enable_mount = 1;
18353 +#endif
18354 +#ifdef CONFIG_GRKERNSEC_LINK
18355 +       grsec_enable_link = 1;
18356 +#endif
18357 +#ifdef CONFIG_GRKERNSEC_DMESG
18358 +       grsec_enable_dmesg = 1;
18359 +#endif
18360 +#ifdef CONFIG_GRKERNSEC_FIFO
18361 +       grsec_enable_fifo = 1;
18362 +#endif
18363 +#ifdef CONFIG_GRKERNSEC_EXECVE
18364 +       grsec_enable_execve = 1;
18365 +#endif
18366 +#ifdef CONFIG_GRKERNSEC_EXECLOG
18367 +       grsec_enable_execlog = 1;
18368 +#endif
18369 +#ifdef CONFIG_GRKERNSEC_SIGNAL
18370 +       grsec_enable_signal = 1;
18371 +#endif
18372 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
18373 +       grsec_enable_forkfail = 1;
18374 +#endif
18375 +#ifdef CONFIG_GRKERNSEC_TIME
18376 +       grsec_enable_time = 1;
18377 +#endif
18378 +#ifdef CONFIG_GRKERNSEC_RESLOG
18379 +       grsec_resource_logging = 1;
18380 +#endif
18381 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
18382 +       grsec_enable_chroot_findtask = 1;
18383 +#endif
18384 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
18385 +       grsec_enable_chroot_unix = 1;
18386 +#endif
18387 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
18388 +       grsec_enable_chroot_mount = 1;
18389 +#endif
18390 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
18391 +       grsec_enable_chroot_fchdir = 1;
18392 +#endif
18393 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
18394 +       grsec_enable_chroot_shmat = 1;
18395 +#endif
18396 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
18397 +       grsec_enable_chroot_double = 1;
18398 +#endif
18399 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
18400 +       grsec_enable_chroot_pivot = 1;
18401 +#endif
18402 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
18403 +       grsec_enable_chroot_chdir = 1;
18404 +#endif
18405 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
18406 +       grsec_enable_chroot_chmod = 1;
18407 +#endif
18408 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
18409 +       grsec_enable_chroot_mknod = 1;
18410 +#endif
18411 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
18412 +       grsec_enable_chroot_nice = 1;
18413 +#endif
18414 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
18415 +       grsec_enable_chroot_execlog = 1;
18416 +#endif
18417 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
18418 +       grsec_enable_chroot_caps = 1;
18419 +#endif
18420 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
18421 +       grsec_enable_chroot_sysctl = 1;
18422 +#endif
18423 +#ifdef CONFIG_GRKERNSEC_TPE
18424 +       grsec_enable_tpe = 1;
18425 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
18426 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
18427 +       grsec_enable_tpe_all = 1;
18428 +#endif
18429 +#endif
18430 +#ifdef CONFIG_GRKERNSEC_RANDPID
18431 +       grsec_enable_randpid = 1;
18432 +#endif
18433 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
18434 +       grsec_enable_socket_all = 1;
18435 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
18436 +#endif
18437 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
18438 +       grsec_enable_socket_client = 1;
18439 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
18440 +#endif
18441 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18442 +       grsec_enable_socket_server = 1;
18443 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
18444 +#endif
18445 +#endif
18446 +
18447 +       return;
18448 +}
18449 diff -urNp linux-2.6.18/grsecurity/grsec_ipc.c linux-2.6.18/grsecurity/grsec_ipc.c
18450 --- linux-2.6.18/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
18451 +++ linux-2.6.18/grsecurity/grsec_ipc.c 2006-09-22 20:04:35.000000000 -0400
18452 @@ -0,0 +1,81 @@
18453 +#include <linux/kernel.h>
18454 +#include <linux/sched.h>
18455 +#include <linux/types.h>
18456 +#include <linux/ipc.h>
18457 +#include <linux/grsecurity.h>
18458 +#include <linux/grinternal.h>
18459 +
18460 +void
18461 +gr_log_msgget(const int ret, const int msgflg)
18462 +{
18463 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18464 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18465 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
18466 +                                         !grsec_enable_group)) && (ret >= 0)
18467 +           && (msgflg & IPC_CREAT))
18468 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
18469 +#endif
18470 +       return;
18471 +}
18472 +
18473 +void
18474 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
18475 +{
18476 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18477 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18478 +            grsec_enable_audit_ipc) ||
18479 +           (grsec_enable_audit_ipc && !grsec_enable_group))
18480 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
18481 +#endif
18482 +       return;
18483 +}
18484 +
18485 +void
18486 +gr_log_semget(const int err, const int semflg)
18487 +{
18488 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18489 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18490 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
18491 +                                         !grsec_enable_group)) && (err >= 0)
18492 +           && (semflg & IPC_CREAT))
18493 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
18494 +#endif
18495 +       return;
18496 +}
18497 +
18498 +void
18499 +gr_log_semrm(const uid_t uid, const uid_t cuid)
18500 +{
18501 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18502 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18503 +            grsec_enable_audit_ipc) ||
18504 +           (grsec_enable_audit_ipc && !grsec_enable_group))
18505 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
18506 +#endif
18507 +       return;
18508 +}
18509 +
18510 +void
18511 +gr_log_shmget(const int err, const int shmflg, const size_t size)
18512 +{
18513 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18514 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18515 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
18516 +                                         !grsec_enable_group)) && (err >= 0)
18517 +           && (shmflg & IPC_CREAT))
18518 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
18519 +#endif
18520 +       return;
18521 +}
18522 +
18523 +void
18524 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
18525 +{
18526 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18527 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18528 +            grsec_enable_audit_ipc) ||
18529 +           (grsec_enable_audit_ipc && !grsec_enable_group))
18530 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
18531 +#endif
18532 +       return;
18533 +}
18534 diff -urNp linux-2.6.18/grsecurity/grsec_link.c linux-2.6.18/grsecurity/grsec_link.c
18535 --- linux-2.6.18/grsecurity/grsec_link.c        1969-12-31 19:00:00.000000000 -0500
18536 +++ linux-2.6.18/grsecurity/grsec_link.c        2006-09-22 20:04:35.000000000 -0400
18537 @@ -0,0 +1,39 @@
18538 +#include <linux/kernel.h>
18539 +#include <linux/sched.h>
18540 +#include <linux/fs.h>
18541 +#include <linux/file.h>
18542 +#include <linux/grinternal.h>
18543 +
18544 +int
18545 +gr_handle_follow_link(const struct inode *parent,
18546 +                     const struct inode *inode,
18547 +                     const struct dentry *dentry, const struct vfsmount *mnt)
18548 +{
18549 +#ifdef CONFIG_GRKERNSEC_LINK
18550 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
18551 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
18552 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
18553 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
18554 +               return -EACCES;
18555 +       }
18556 +#endif
18557 +       return 0;
18558 +}
18559 +
18560 +int
18561 +gr_handle_hardlink(const struct dentry *dentry,
18562 +                  const struct vfsmount *mnt,
18563 +                  struct inode *inode, const int mode, const char *to)
18564 +{
18565 +#ifdef CONFIG_GRKERNSEC_LINK
18566 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
18567 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
18568 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
18569 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
18570 +           !capable(CAP_FOWNER) && current->uid) {
18571 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
18572 +               return -EPERM;
18573 +       }
18574 +#endif
18575 +       return 0;
18576 +}
18577 diff -urNp linux-2.6.18/grsecurity/grsec_log.c linux-2.6.18/grsecurity/grsec_log.c
18578 --- linux-2.6.18/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
18579 +++ linux-2.6.18/grsecurity/grsec_log.c 2006-09-22 20:04:35.000000000 -0400
18580 @@ -0,0 +1,265 @@
18581 +#include <linux/kernel.h>
18582 +#include <linux/sched.h>
18583 +#include <linux/file.h>
18584 +#include <linux/tty.h>
18585 +#include <linux/fs.h>
18586 +#include <linux/grinternal.h>
18587 +
18588 +#define BEGIN_LOCKS(x) \
18589 +       read_lock(&tasklist_lock); \
18590 +       read_lock(&grsec_exec_file_lock); \
18591 +       if (x != GR_DO_AUDIT) \
18592 +               spin_lock(&grsec_alert_lock); \
18593 +       else \
18594 +               spin_lock(&grsec_audit_lock)
18595 +
18596 +#define END_LOCKS(x) \
18597 +       if (x != GR_DO_AUDIT) \
18598 +               spin_unlock(&grsec_alert_lock); \
18599 +       else \
18600 +               spin_unlock(&grsec_audit_lock); \
18601 +       read_unlock(&grsec_exec_file_lock); \
18602 +       read_unlock(&tasklist_lock); \
18603 +       if (x == GR_DONT_AUDIT) \
18604 +               gr_handle_alertkill(current)
18605 +
18606 +enum {
18607 +       FLOODING,
18608 +       NO_FLOODING
18609 +};
18610 +
18611 +extern char *gr_alert_log_fmt;
18612 +extern char *gr_audit_log_fmt;
18613 +extern char *gr_alert_log_buf;
18614 +extern char *gr_audit_log_buf;
18615 +
18616 +static int gr_log_start(int audit)
18617 +{
18618 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
18619 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
18620 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18621 +
18622 +       if (audit == GR_DO_AUDIT)
18623 +               goto set_fmt;
18624 +
18625 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
18626 +               grsec_alert_wtime = jiffies;
18627 +               grsec_alert_fyet = 0;
18628 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
18629 +               grsec_alert_fyet++;
18630 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
18631 +               grsec_alert_wtime = jiffies;
18632 +               grsec_alert_fyet++;
18633 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
18634 +               return FLOODING;
18635 +       } else return FLOODING;
18636 +
18637 +set_fmt:
18638 +       memset(buf, 0, PAGE_SIZE);
18639 +       if (current->signal->curr_ip && gr_acl_is_enabled()) {
18640 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
18641 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
18642 +       } else if (current->signal->curr_ip) {
18643 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
18644 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
18645 +       } else if (gr_acl_is_enabled()) {
18646 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
18647 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
18648 +       } else {
18649 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
18650 +               strcpy(buf, fmt);
18651 +       }
18652 +
18653 +       return NO_FLOODING;
18654 +}
18655 +
18656 +static void gr_log_middle(int audit, const char *msg, va_list ap)
18657 +{
18658 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18659 +       unsigned int len = strlen(buf);
18660 +
18661 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
18662 +
18663 +       return;
18664 +}
18665 +
18666 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
18667 +{
18668 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18669 +       unsigned int len = strlen(buf);
18670 +       va_list ap;
18671 +
18672 +       va_start(ap, msg);
18673 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
18674 +       va_end(ap);
18675 +
18676 +       return;
18677 +}
18678 +
18679 +static void gr_log_end(int audit)
18680 +{
18681 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18682 +       unsigned int len = strlen(buf);
18683 +
18684 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
18685 +       printk("%s\n", buf);
18686 +
18687 +       return;
18688 +}
18689 +
18690 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
18691 +{
18692 +       int logtype;
18693 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
18694 +       char *str1, *str2, *str3;
18695 +       int num1, num2;
18696 +       unsigned long ulong1, ulong2;
18697 +       struct dentry *dentry;
18698 +       struct vfsmount *mnt;
18699 +       struct file *file;
18700 +       struct task_struct *task;
18701 +       va_list ap;
18702 +
18703 +       BEGIN_LOCKS(audit);
18704 +       logtype = gr_log_start(audit);
18705 +       if (logtype == FLOODING) {
18706 +               END_LOCKS(audit);
18707 +               return;
18708 +       }
18709 +       va_start(ap, argtypes);
18710 +       switch (argtypes) {
18711 +       case GR_TTYSNIFF:
18712 +               task = va_arg(ap, struct task_struct *);
18713 +               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);
18714 +               break;
18715 +       case GR_RBAC:
18716 +               dentry = va_arg(ap, struct dentry *);
18717 +               mnt = va_arg(ap, struct vfsmount *);
18718 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
18719 +               break;
18720 +       case GR_RBAC_STR:
18721 +               dentry = va_arg(ap, struct dentry *);
18722 +               mnt = va_arg(ap, struct vfsmount *);
18723 +               str1 = va_arg(ap, char *);
18724 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
18725 +               break;
18726 +       case GR_STR_RBAC:
18727 +               str1 = va_arg(ap, char *);
18728 +               dentry = va_arg(ap, struct dentry *);
18729 +               mnt = va_arg(ap, struct vfsmount *);
18730 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
18731 +               break;
18732 +       case GR_RBAC_MODE2:
18733 +               dentry = va_arg(ap, struct dentry *);
18734 +               mnt = va_arg(ap, struct vfsmount *);
18735 +               str1 = va_arg(ap, char *);
18736 +               str2 = va_arg(ap, char *);
18737 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
18738 +               break;
18739 +       case GR_RBAC_MODE3:
18740 +               dentry = va_arg(ap, struct dentry *);
18741 +               mnt = va_arg(ap, struct vfsmount *);
18742 +               str1 = va_arg(ap, char *);
18743 +               str2 = va_arg(ap, char *);
18744 +               str3 = va_arg(ap, char *);
18745 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
18746 +               break;
18747 +       case GR_FILENAME:
18748 +               dentry = va_arg(ap, struct dentry *);
18749 +               mnt = va_arg(ap, struct vfsmount *);
18750 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
18751 +               break;
18752 +       case GR_STR_FILENAME:
18753 +               str1 = va_arg(ap, char *);
18754 +               dentry = va_arg(ap, struct dentry *);
18755 +               mnt = va_arg(ap, struct vfsmount *);
18756 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
18757 +               break;
18758 +       case GR_FILENAME_STR:
18759 +               dentry = va_arg(ap, struct dentry *);
18760 +               mnt = va_arg(ap, struct vfsmount *);
18761 +               str1 = va_arg(ap, char *);
18762 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
18763 +               break;
18764 +       case GR_FILENAME_TWO_INT:
18765 +               dentry = va_arg(ap, struct dentry *);
18766 +               mnt = va_arg(ap, struct vfsmount *);
18767 +               num1 = va_arg(ap, int);
18768 +               num2 = va_arg(ap, int);
18769 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
18770 +               break;
18771 +       case GR_FILENAME_TWO_INT_STR:
18772 +               dentry = va_arg(ap, struct dentry *);
18773 +               mnt = va_arg(ap, struct vfsmount *);
18774 +               num1 = va_arg(ap, int);
18775 +               num2 = va_arg(ap, int);
18776 +               str1 = va_arg(ap, char *);
18777 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
18778 +               break;
18779 +       case GR_TEXTREL:
18780 +               file = va_arg(ap, struct file *);
18781 +               ulong1 = va_arg(ap, unsigned long);
18782 +               ulong2 = va_arg(ap, unsigned long);
18783 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
18784 +               break;
18785 +       case GR_PTRACE:
18786 +               task = va_arg(ap, struct task_struct *);
18787 +               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);
18788 +               break;
18789 +       case GR_RESOURCE:
18790 +               task = va_arg(ap, struct task_struct *);
18791 +               ulong1 = va_arg(ap, unsigned long);
18792 +               str1 = va_arg(ap, char *);
18793 +               ulong2 = va_arg(ap, unsigned long);
18794 +               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);
18795 +               break;
18796 +       case GR_CAP:
18797 +               task = va_arg(ap, struct task_struct *);
18798 +               str1 = va_arg(ap, char *);
18799 +               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);
18800 +               break;
18801 +       case GR_SIG:
18802 +               task = va_arg(ap, struct task_struct *);
18803 +               num1 = va_arg(ap, int);
18804 +               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);
18805 +               break;
18806 +       case GR_CRASH1:
18807 +               task = va_arg(ap, struct task_struct *);
18808 +               ulong1 = va_arg(ap, unsigned long);
18809 +               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);
18810 +               break;
18811 +       case GR_CRASH2:
18812 +               task = va_arg(ap, struct task_struct *);
18813 +               ulong1 = va_arg(ap, unsigned long);
18814 +               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);
18815 +               break;
18816 +       case GR_PSACCT:
18817 +               {
18818 +                       unsigned int wday, cday;
18819 +                       __u8 whr, chr;
18820 +                       __u8 wmin, cmin;
18821 +                       __u8 wsec, csec;
18822 +                       char cur_tty[64] = { 0 };
18823 +                       char parent_tty[64] = { 0 };
18824 +
18825 +                       task = va_arg(ap, struct task_struct *);
18826 +                       wday = va_arg(ap, unsigned int);
18827 +                       cday = va_arg(ap, unsigned int);
18828 +                       whr = va_arg(ap, int);
18829 +                       chr = va_arg(ap, int);
18830 +                       wmin = va_arg(ap, int);
18831 +                       cmin = va_arg(ap, int);
18832 +                       wsec = va_arg(ap, int);
18833 +                       csec = va_arg(ap, int);
18834 +                       ulong1 = va_arg(ap, unsigned long);
18835 +
18836 +                       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);
18837 +               }
18838 +               break;
18839 +       default:
18840 +               gr_log_middle(audit, msg, ap);
18841 +       }
18842 +       va_end(ap);
18843 +       gr_log_end(audit);
18844 +       END_LOCKS(audit);
18845 +}
18846 diff -urNp linux-2.6.18/grsecurity/grsec_mem.c linux-2.6.18/grsecurity/grsec_mem.c
18847 --- linux-2.6.18/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
18848 +++ linux-2.6.18/grsecurity/grsec_mem.c 2006-09-22 20:04:35.000000000 -0400
18849 @@ -0,0 +1,71 @@
18850 +#include <linux/kernel.h>
18851 +#include <linux/sched.h>
18852 +#include <linux/mm.h>
18853 +#include <linux/mman.h>
18854 +#include <linux/grinternal.h>
18855 +
18856 +void
18857 +gr_handle_ioperm(void)
18858 +{
18859 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
18860 +       return;
18861 +}
18862 +
18863 +void
18864 +gr_handle_iopl(void)
18865 +{
18866 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
18867 +       return;
18868 +}
18869 +
18870 +void
18871 +gr_handle_mem_write(void)
18872 +{
18873 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
18874 +       return;
18875 +}
18876 +
18877 +void
18878 +gr_handle_kmem_write(void)
18879 +{
18880 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
18881 +       return;
18882 +}
18883 +
18884 +void
18885 +gr_handle_open_port(void)
18886 +{
18887 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
18888 +       return;
18889 +}
18890 +
18891 +int
18892 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
18893 +{
18894 +       unsigned long start, end;
18895 +
18896 +       start = offset;
18897 +       end = start + vma->vm_end - vma->vm_start;
18898 +
18899 +       if (start > end) {
18900 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
18901 +               return -EPERM;
18902 +       }
18903 +
18904 +       /* allowed ranges : ISA I/O BIOS */
18905 +       if ((start >= __pa(high_memory))
18906 +#ifdef CONFIG_X86
18907 +           || (start >= 0x000a0000 && end <= 0x00100000)
18908 +           || (start >= 0x00000000 && end <= 0x00001000)
18909 +#endif
18910 +       )
18911 +               return 0;
18912 +
18913 +       if (vma->vm_flags & VM_WRITE) {
18914 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
18915 +               return -EPERM;
18916 +       } else
18917 +               vma->vm_flags &= ~VM_MAYWRITE;
18918 +
18919 +       return 0;
18920 +}
18921 diff -urNp linux-2.6.18/grsecurity/grsec_mount.c linux-2.6.18/grsecurity/grsec_mount.c
18922 --- linux-2.6.18/grsecurity/grsec_mount.c       1969-12-31 19:00:00.000000000 -0500
18923 +++ linux-2.6.18/grsecurity/grsec_mount.c       2006-09-22 20:04:35.000000000 -0400
18924 @@ -0,0 +1,34 @@
18925 +#include <linux/kernel.h>
18926 +#include <linux/sched.h>
18927 +#include <linux/grsecurity.h>
18928 +#include <linux/grinternal.h>
18929 +
18930 +void
18931 +gr_log_remount(const char *devname, const int retval)
18932 +{
18933 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18934 +       if (grsec_enable_mount && (retval >= 0))
18935 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
18936 +#endif
18937 +       return;
18938 +}
18939 +
18940 +void
18941 +gr_log_unmount(const char *devname, const int retval)
18942 +{
18943 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18944 +       if (grsec_enable_mount && (retval >= 0))
18945 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
18946 +#endif
18947 +       return;
18948 +}
18949 +
18950 +void
18951 +gr_log_mount(const char *from, const char *to, const int retval)
18952 +{
18953 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18954 +       if (grsec_enable_mount && (retval >= 0))
18955 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
18956 +#endif
18957 +       return;
18958 +}
18959 diff -urNp linux-2.6.18/grsecurity/grsec_rand.c linux-2.6.18/grsecurity/grsec_rand.c
18960 --- linux-2.6.18/grsecurity/grsec_rand.c        1969-12-31 19:00:00.000000000 -0500
18961 +++ linux-2.6.18/grsecurity/grsec_rand.c        2006-09-22 20:04:35.000000000 -0400
18962 @@ -0,0 +1,26 @@
18963 +#include <linux/kernel.h>
18964 +#include <linux/sched.h>
18965 +#include <linux/smp_lock.h>
18966 +#include <linux/grsecurity.h>
18967 +#include <linux/grinternal.h>
18968 +
18969 +extern int pid_max;
18970 +
18971 +int
18972 +gr_random_pid(void)
18973 +{
18974 +#ifdef CONFIG_GRKERNSEC_RANDPID
18975 +       int pid;
18976 +
18977 +       if (grsec_enable_randpid && current->fs->root) {
18978 +               /* return a pid in the range 1 ... pid_max - 1
18979 +                  optimize this so we don't have to do a real division
18980 +               */
18981 +               pid = 1 + (get_random_long() % pid_max);
18982 +               if (pid == pid_max)
18983 +                       pid = pid_max - 1;
18984 +               return pid;
18985 +       }
18986 +#endif
18987 +       return 0;
18988 +}
18989 diff -urNp linux-2.6.18/grsecurity/grsec_sig.c linux-2.6.18/grsecurity/grsec_sig.c
18990 --- linux-2.6.18/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
18991 +++ linux-2.6.18/grsecurity/grsec_sig.c 2006-09-22 20:04:35.000000000 -0400
18992 @@ -0,0 +1,59 @@
18993 +#include <linux/kernel.h>
18994 +#include <linux/sched.h>
18995 +#include <linux/grsecurity.h>
18996 +#include <linux/grinternal.h>
18997 +
18998 +void
18999 +gr_log_signal(const int sig, const struct task_struct *t)
19000 +{
19001 +#ifdef CONFIG_GRKERNSEC_SIGNAL
19002 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
19003 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
19004 +               if (t->pid == current->pid) {
19005 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
19006 +               } else {
19007 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
19008 +               }
19009 +       }
19010 +#endif
19011 +       return;
19012 +}
19013 +
19014 +int
19015 +gr_handle_signal(const struct task_struct *p, const int sig)
19016 +{
19017 +#ifdef CONFIG_GRKERNSEC
19018 +       if (current->pid > 1 && gr_check_protected_task(p)) {
19019 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
19020 +               return -EPERM;
19021 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
19022 +               return -EPERM;
19023 +       }
19024 +#endif
19025 +       return 0;
19026 +}
19027 +
19028 +void gr_handle_brute_attach(struct task_struct *p)
19029 +{
19030 +#ifdef CONFIG_GRKERNSEC_BRUTE
19031 +       read_lock(&tasklist_lock);
19032 +       read_lock(&grsec_exec_file_lock);
19033 +       if (p->parent && p->parent->exec_file == p->exec_file)
19034 +               p->parent->brute = 1;
19035 +       read_unlock(&grsec_exec_file_lock);
19036 +       read_unlock(&tasklist_lock);
19037 +#endif
19038 +       return;
19039 +}
19040 +
19041 +void gr_handle_brute_check(void)
19042 +{
19043 +#ifdef CONFIG_GRKERNSEC_BRUTE
19044 +       if (current->brute) {
19045 +               set_current_state(TASK_UNINTERRUPTIBLE);
19046 +               schedule_timeout(30 * HZ);
19047 +       }
19048 +#endif
19049 +       return;
19050 +}
19051 +
19052 diff -urNp linux-2.6.18/grsecurity/grsec_sock.c linux-2.6.18/grsecurity/grsec_sock.c
19053 --- linux-2.6.18/grsecurity/grsec_sock.c        1969-12-31 19:00:00.000000000 -0500
19054 +++ linux-2.6.18/grsecurity/grsec_sock.c        2006-09-22 20:04:35.000000000 -0400
19055 @@ -0,0 +1,263 @@
19056 +#include <linux/kernel.h>
19057 +#include <linux/module.h>
19058 +#include <linux/sched.h>
19059 +#include <linux/file.h>
19060 +#include <linux/net.h>
19061 +#include <linux/in.h>
19062 +#include <linux/ip.h>
19063 +#include <net/sock.h>
19064 +#include <net/inet_sock.h>
19065 +#include <linux/grsecurity.h>
19066 +#include <linux/grinternal.h>
19067 +#include <linux/gracl.h>
19068 +
19069 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
19070 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
19071 +EXPORT_SYMBOL(udp_v4_lookup);
19072 +#endif
19073 +
19074 +EXPORT_SYMBOL(gr_cap_rtnetlink);
19075 +
19076 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
19077 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
19078 +
19079 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
19080 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
19081 +
19082 +#ifdef CONFIG_UNIX_MODULE
19083 +EXPORT_SYMBOL(gr_acl_handle_unix);
19084 +EXPORT_SYMBOL(gr_acl_handle_mknod);
19085 +EXPORT_SYMBOL(gr_handle_chroot_unix);
19086 +EXPORT_SYMBOL(gr_handle_create);
19087 +#endif
19088 +
19089 +#ifdef CONFIG_GRKERNSEC
19090 +#define gr_conn_table_size 32749
19091 +struct conn_table_entry {
19092 +       struct conn_table_entry *next;
19093 +       struct signal_struct *sig;
19094 +};
19095 +
19096 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
19097 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
19098 +
19099 +extern const char * gr_socktype_to_name(unsigned char type);
19100 +extern const char * gr_proto_to_name(unsigned char proto);
19101 +
19102 +static __inline__ int 
19103 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
19104 +{
19105 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
19106 +}
19107 +
19108 +static __inline__ int
19109 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, 
19110 +          __u16 sport, __u16 dport)
19111 +{
19112 +       if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
19113 +                    sig->gr_sport == sport && sig->gr_dport == dport))
19114 +               return 1;
19115 +       else
19116 +               return 0;
19117 +}
19118 +
19119 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
19120 +{
19121 +       struct conn_table_entry **match;
19122 +       unsigned int index;
19123 +
19124 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
19125 +                         sig->gr_sport, sig->gr_dport, 
19126 +                         gr_conn_table_size);
19127 +
19128 +       newent->sig = sig;
19129 +       
19130 +       match = &gr_conn_table[index];
19131 +       newent->next = *match;
19132 +       *match = newent;
19133 +
19134 +       return;
19135 +}
19136 +
19137 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
19138 +{
19139 +       struct conn_table_entry *match, *last = NULL;
19140 +       unsigned int index;
19141 +
19142 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
19143 +                         sig->gr_sport, sig->gr_dport, 
19144 +                         gr_conn_table_size);
19145 +
19146 +       match = gr_conn_table[index];
19147 +       while (match && !conn_match(match->sig, 
19148 +               sig->gr_saddr, sig->gr_daddr, sig->gr_sport, 
19149 +               sig->gr_dport)) {
19150 +               last = match;
19151 +               match = match->next;
19152 +       }
19153 +
19154 +       if (match) {
19155 +               if (last)
19156 +                       last->next = match->next;
19157 +               else
19158 +                       gr_conn_table[index] = NULL;
19159 +               kfree(match);
19160 +       }
19161 +
19162 +       return;
19163 +}
19164 +
19165 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
19166 +                                            __u16 sport, __u16 dport)
19167 +{
19168 +       struct conn_table_entry *match;
19169 +       unsigned int index;
19170 +
19171 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
19172 +
19173 +       match = gr_conn_table[index];
19174 +       while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
19175 +               match = match->next;
19176 +
19177 +       if (match)
19178 +               return match->sig;
19179 +       else
19180 +               return NULL;
19181 +}
19182 +
19183 +#endif
19184 +
19185 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
19186 +{
19187 +#ifdef CONFIG_GRKERNSEC
19188 +       struct signal_struct *sig = task->signal;
19189 +       struct conn_table_entry *newent;
19190 +
19191 +       newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
19192 +       if (newent == NULL)
19193 +               return;
19194 +       /* no bh lock needed since we are called with bh disabled */
19195 +       spin_lock(&gr_conn_table_lock);
19196 +       gr_del_task_from_ip_table_nolock(sig);
19197 +       sig->gr_saddr = inet->rcv_saddr;
19198 +       sig->gr_daddr = inet->daddr;
19199 +       sig->gr_sport = inet->sport;
19200 +       sig->gr_dport = inet->dport;
19201 +       gr_add_to_task_ip_table_nolock(sig, newent);
19202 +       spin_unlock(&gr_conn_table_lock);
19203 +#endif
19204 +       return;
19205 +}
19206 +
19207 +void gr_del_task_from_ip_table(struct task_struct *task)
19208 +{
19209 +#ifdef CONFIG_GRKERNSEC
19210 +       spin_lock(&gr_conn_table_lock);
19211 +       gr_del_task_from_ip_table_nolock(task->signal);
19212 +       spin_unlock(&gr_conn_table_lock);
19213 +#endif
19214 +       return;
19215 +}
19216 +
19217 +void
19218 +gr_attach_curr_ip(const struct sock *sk)
19219 +{
19220 +#ifdef CONFIG_GRKERNSEC
19221 +       struct signal_struct *p, *set;
19222 +       const struct inet_sock *inet = inet_sk(sk);     
19223 +
19224 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
19225 +               return;
19226 +
19227 +       set = current->signal;
19228 +
19229 +       spin_lock_bh(&gr_conn_table_lock);
19230 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
19231 +                                   inet->dport, inet->sport);
19232 +       if (unlikely(p != NULL)) {
19233 +               set->curr_ip = p->curr_ip;
19234 +               set->used_accept = 1;
19235 +               gr_del_task_from_ip_table_nolock(p);
19236 +               spin_unlock_bh(&gr_conn_table_lock);
19237 +               return;
19238 +       }
19239 +       spin_unlock_bh(&gr_conn_table_lock);
19240 +
19241 +       set->curr_ip = inet->daddr;
19242 +       set->used_accept = 1;
19243 +#endif
19244 +       return;
19245 +}
19246 +
19247 +int
19248 +gr_handle_sock_all(const int family, const int type, const int protocol)
19249 +{
19250 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
19251 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
19252 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
19253 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
19254 +               return -EACCES;
19255 +       }
19256 +#endif
19257 +       return 0;
19258 +}
19259 +
19260 +int
19261 +gr_handle_sock_server(const struct sockaddr *sck)
19262 +{
19263 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
19264 +       if (grsec_enable_socket_server &&
19265 +           in_group_p(grsec_socket_server_gid) &&
19266 +           sck && (sck->sa_family != AF_UNIX) &&
19267 +           (sck->sa_family != AF_LOCAL)) {
19268 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
19269 +               return -EACCES;
19270 +       }
19271 +#endif
19272 +       return 0;
19273 +}
19274 +
19275 +int
19276 +gr_handle_sock_server_other(const struct sock *sck)
19277 +{
19278 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
19279 +       if (grsec_enable_socket_server &&
19280 +           in_group_p(grsec_socket_server_gid) &&
19281 +           sck && (sck->sk_family != AF_UNIX) &&
19282 +           (sck->sk_family != AF_LOCAL)) {
19283 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
19284 +               return -EACCES;
19285 +       }
19286 +#endif
19287 +       return 0;
19288 +}
19289 +
19290 +int
19291 +gr_handle_sock_client(const struct sockaddr *sck)
19292 +{
19293 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
19294 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
19295 +           sck && (sck->sa_family != AF_UNIX) &&
19296 +           (sck->sa_family != AF_LOCAL)) {
19297 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
19298 +               return -EACCES;
19299 +       }
19300 +#endif
19301 +       return 0;
19302 +}
19303 +
19304 +__u32
19305 +gr_cap_rtnetlink(void)
19306 +{
19307 +#ifdef CONFIG_GRKERNSEC
19308 +       if (!gr_acl_is_enabled())
19309 +               return current->cap_effective;
19310 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
19311 +                gr_task_is_capable(current, CAP_NET_ADMIN))
19312 +               return current->cap_effective;
19313 +       else
19314 +               return 0;
19315 +#else
19316 +       return current->cap_effective;
19317 +#endif
19318 +}
19319 diff -urNp linux-2.6.18/grsecurity/grsec_sysctl.c linux-2.6.18/grsecurity/grsec_sysctl.c
19320 --- linux-2.6.18/grsecurity/grsec_sysctl.c      1969-12-31 19:00:00.000000000 -0500
19321 +++ linux-2.6.18/grsecurity/grsec_sysctl.c      2006-09-22 20:04:35.000000000 -0400
19322 @@ -0,0 +1,466 @@
19323 +#include <linux/kernel.h>
19324 +#include <linux/sched.h>
19325 +#include <linux/sysctl.h>
19326 +#include <linux/grsecurity.h>
19327 +#include <linux/grinternal.h>
19328 +
19329 +#ifdef CONFIG_GRKERNSEC_MODSTOP
19330 +int grsec_modstop;
19331 +#endif
19332 +
19333 +int
19334 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
19335 +{
19336 +#ifdef CONFIG_GRKERNSEC_SYSCTL
19337 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
19338 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
19339 +               return -EACCES;
19340 +       }
19341 +#endif
19342 +#ifdef CONFIG_GRKERNSEC_MODSTOP
19343 +       if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
19344 +           grsec_modstop && (op & 002)) {
19345 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
19346 +               return -EACCES;
19347 +       }
19348 +#endif
19349 +       return 0;
19350 +}
19351 +
19352 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
19353 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
19354 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
19355 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
19356 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
19357 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
19358 +GS_RANDPID, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
19359 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, 
19360 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
19361 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
19362 +
19363 +
19364 +ctl_table grsecurity_table[] = {
19365 +#ifdef CONFIG_GRKERNSEC_SYSCTL
19366 +#ifdef CONFIG_GRKERNSEC_LINK
19367 +       {
19368 +               .ctl_name       = GS_LINK,
19369 +               .procname       = "linking_restrictions",
19370 +               .data           = &grsec_enable_link,
19371 +               .maxlen         = sizeof(int),
19372 +               .mode           = 0600,
19373 +               .proc_handler   = &proc_dointvec,
19374 +       },
19375 +#endif
19376 +#ifdef CONFIG_GRKERNSEC_FIFO
19377 +       {
19378 +               .ctl_name       = GS_FIFO,
19379 +               .procname       = "fifo_restrictions",
19380 +               .data           = &grsec_enable_fifo,
19381 +               .maxlen         = sizeof(int),
19382 +               .mode           = 0600,
19383 +               .proc_handler   = &proc_dointvec,
19384 +       },
19385 +#endif
19386 +#ifdef CONFIG_GRKERNSEC_EXECVE
19387 +       {
19388 +               .ctl_name       = GS_EXECVE,
19389 +               .procname       = "execve_limiting",
19390 +               .data           = &grsec_enable_execve,
19391 +               .maxlen         = sizeof(int),
19392 +               .mode           = 0600,
19393 +               .proc_handler   = &proc_dointvec,
19394 +       },
19395 +#endif
19396 +#ifdef CONFIG_GRKERNSEC_EXECLOG
19397 +       {
19398 +               .ctl_name       = GS_EXECLOG,
19399 +               .procname       = "exec_logging",
19400 +               .data           = &grsec_enable_execlog,
19401 +               .maxlen         = sizeof(int),
19402 +               .mode           = 0600,
19403 +               .proc_handler   = &proc_dointvec,
19404 +       },
19405 +#endif
19406 +#ifdef CONFIG_GRKERNSEC_SIGNAL
19407 +       {
19408 +               .ctl_name       = GS_SIGNAL,
19409 +               .procname       = "signal_logging",
19410 +               .data           = &grsec_enable_signal,
19411 +               .maxlen         = sizeof(int),
19412 +               .mode           = 0600,
19413 +               .proc_handler   = &proc_dointvec,
19414 +       },
19415 +#endif
19416 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
19417 +       {
19418 +               .ctl_name       = GS_FORKFAIL,
19419 +               .procname       = "forkfail_logging",
19420 +               .data           = &grsec_enable_forkfail,
19421 +               .maxlen         = sizeof(int),
19422 +               .mode           = 0600,
19423 +               .proc_handler   = &proc_dointvec,
19424 +       },
19425 +#endif
19426 +#ifdef CONFIG_GRKERNSEC_TIME
19427 +       {
19428 +               .ctl_name       = GS_TIME,
19429 +               .procname       = "timechange_logging",
19430 +               .data           = &grsec_enable_time,
19431 +               .maxlen         = sizeof(int),
19432 +               .mode           = 0600,
19433 +               .proc_handler   = &proc_dointvec,
19434 +       },
19435 +#endif
19436 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
19437 +       {
19438 +               .ctl_name       = GS_CHROOT_SHMAT,
19439 +               .procname       = "chroot_deny_shmat",
19440 +               .data           = &grsec_enable_chroot_shmat,
19441 +               .maxlen         = sizeof(int),
19442 +               .mode           = 0600,
19443 +               .proc_handler   = &proc_dointvec,
19444 +       },
19445 +#endif
19446 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
19447 +       {
19448 +               .ctl_name       = GS_CHROOT_UNIX,
19449 +               .procname       = "chroot_deny_unix",
19450 +               .data           = &grsec_enable_chroot_unix,
19451 +               .maxlen         = sizeof(int),
19452 +               .mode           = 0600,
19453 +               .proc_handler   = &proc_dointvec,
19454 +       },
19455 +#endif
19456 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
19457 +       {
19458 +               .ctl_name       = GS_CHROOT_MNT,
19459 +               .procname       = "chroot_deny_mount",
19460 +               .data           = &grsec_enable_chroot_mount,
19461 +               .maxlen         = sizeof(int),
19462 +               .mode           = 0600,
19463 +               .proc_handler   = &proc_dointvec,
19464 +       },
19465 +#endif
19466 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
19467 +       {
19468 +               .ctl_name       = GS_CHROOT_FCHDIR,
19469 +               .procname       = "chroot_deny_fchdir",
19470 +               .data           = &grsec_enable_chroot_fchdir,
19471 +               .maxlen         = sizeof(int),
19472 +               .mode           = 0600,
19473 +               .proc_handler   = &proc_dointvec,
19474 +       },
19475 +#endif
19476 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
19477 +       {
19478 +               .ctl_name       = GS_CHROOT_DBL,
19479 +               .procname       = "chroot_deny_chroot",
19480 +               .data           = &grsec_enable_chroot_double,
19481 +               .maxlen         = sizeof(int),
19482 +               .mode           = 0600,
19483 +               .proc_handler   = &proc_dointvec,
19484 +       },
19485 +#endif
19486 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
19487 +       {
19488 +               .ctl_name       = GS_CHROOT_PVT,
19489 +               .procname       = "chroot_deny_pivot",
19490 +               .data           = &grsec_enable_chroot_pivot,
19491 +               .maxlen         = sizeof(int),
19492 +               .mode           = 0600,
19493 +               .proc_handler   = &proc_dointvec,
19494 +       },
19495 +#endif
19496 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
19497 +       {
19498 +               .ctl_name       = GS_CHROOT_CD,
19499 +               .procname       = "chroot_enforce_chdir",
19500 +               .data           = &grsec_enable_chroot_chdir,
19501 +               .maxlen         = sizeof(int),
19502 +               .mode           = 0600,
19503 +               .proc_handler   = &proc_dointvec,
19504 +       },
19505 +#endif
19506 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
19507 +       {
19508 +               .ctl_name       = GS_CHROOT_CM,
19509 +               .procname       = "chroot_deny_chmod",
19510 +               .data           = &grsec_enable_chroot_chmod,
19511 +               .maxlen         = sizeof(int),
19512 +               .mode           = 0600,
19513 +               .proc_handler   = &proc_dointvec,
19514 +       },
19515 +#endif
19516 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
19517 +       {
19518 +               .ctl_name       = GS_CHROOT_MK,
19519 +               .procname       = "chroot_deny_mknod",
19520 +               .data           = &grsec_enable_chroot_mknod,
19521 +               .maxlen         = sizeof(int),
19522 +               .mode           = 0600,
19523 +               .proc_handler   = &proc_dointvec,
19524 +       },
19525 +#endif
19526 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
19527 +       {
19528 +               .ctl_name       = GS_CHROOT_NI,
19529 +               .procname       = "chroot_restrict_nice",
19530 +               .data           = &grsec_enable_chroot_nice,
19531 +               .maxlen         = sizeof(int),
19532 +               .mode           = 0600,
19533 +               .proc_handler   = &proc_dointvec,
19534 +       },
19535 +#endif
19536 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
19537 +       {
19538 +               .ctl_name       = GS_CHROOT_EXECLOG,
19539 +               .procname       = "chroot_execlog",
19540 +               .data           = &grsec_enable_chroot_execlog,
19541 +               .maxlen         = sizeof(int),
19542 +               .mode           = 0600,
19543 +               .proc_handler   = &proc_dointvec,
19544 +       },
19545 +#endif
19546 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
19547 +       {
19548 +               .ctl_name       = GS_CHROOT_CAPS,
19549 +               .procname       = "chroot_caps",
19550 +               .data           = &grsec_enable_chroot_caps,
19551 +               .maxlen         = sizeof(int),
19552 +               .mode           = 0600,
19553 +               .proc_handler   = &proc_dointvec,
19554 +       },
19555 +#endif
19556 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
19557 +       {
19558 +               .ctl_name       = GS_CHROOT_SYSCTL,
19559 +               .procname       = "chroot_deny_sysctl",
19560 +               .data           = &grsec_enable_chroot_sysctl,
19561 +               .maxlen         = sizeof(int),
19562 +               .mode           = 0600,
19563 +               .proc_handler   = &proc_dointvec,
19564 +       },
19565 +#endif
19566 +#ifdef CONFIG_GRKERNSEC_TPE
19567 +       {
19568 +               .ctl_name       = GS_TPE,
19569 +               .procname       = "tpe",
19570 +               .data           = &grsec_enable_tpe,
19571 +               .maxlen         = sizeof(int),
19572 +               .mode           = 0600,
19573 +               .proc_handler   = &proc_dointvec,
19574 +       },
19575 +       {
19576 +               .ctl_name       = GS_TPE_GID,
19577 +               .procname       = "tpe_gid",
19578 +               .data           = &grsec_tpe_gid,
19579 +               .maxlen         = sizeof(int),
19580 +               .mode           = 0600,
19581 +               .proc_handler   = &proc_dointvec,
19582 +       },
19583 +#endif
19584 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
19585 +       {
19586 +               .ctl_name       = GS_TPE_ALL,
19587 +               .procname       = "tpe_restrict_all",
19588 +               .data           = &grsec_enable_tpe_all,
19589 +               .maxlen         = sizeof(int),
19590 +               .mode           = 0600,
19591 +               .proc_handler   = &proc_dointvec,
19592 +       },
19593 +#endif
19594 +#ifdef CONFIG_GRKERNSEC_RANDPID
19595 +       {
19596 +               .ctl_name       = GS_RANDPID,
19597 +               .procname       = "rand_pids",
19598 +               .data           = &grsec_enable_randpid,
19599 +               .maxlen         = sizeof(int),
19600 +               .mode           = 0600,
19601 +               .proc_handler   = &proc_dointvec,
19602 +       },
19603 +#endif
19604 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
19605 +       {
19606 +               .ctl_name       = GS_SOCKET_ALL,
19607 +               .procname       = "socket_all",
19608 +               .data           = &grsec_enable_socket_all,
19609 +               .maxlen         = sizeof(int),
19610 +               .mode           = 0600,
19611 +               .proc_handler   = &proc_dointvec,
19612 +       },
19613 +       {
19614 +               .ctl_name       = GS_SOCKET_ALL_GID,
19615 +               .procname       = "socket_all_gid",
19616 +               .data           = &grsec_socket_all_gid,
19617 +               .maxlen         = sizeof(int),
19618 +               .mode           = 0600,
19619 +               .proc_handler   = &proc_dointvec,
19620 +       },
19621 +#endif
19622 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
19623 +       {
19624 +               .ctl_name       = GS_SOCKET_CLIENT,
19625 +               .procname       = "socket_client",
19626 +               .data           = &grsec_enable_socket_client,
19627 +               .maxlen         = sizeof(int),
19628 +               .mode           = 0600,
19629 +               .proc_handler   = &proc_dointvec,
19630 +       },
19631 +       {
19632 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
19633 +               .procname       = "socket_client_gid",
19634 +               .data           = &grsec_socket_client_gid,
19635 +               .maxlen         = sizeof(int),
19636 +               .mode           = 0600,
19637 +               .proc_handler   = &proc_dointvec,
19638 +       },
19639 +#endif
19640 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
19641 +       {
19642 +               .ctl_name       = GS_SOCKET_SERVER,
19643 +               .procname       = "socket_server",
19644 +               .data           = &grsec_enable_socket_server,
19645 +               .maxlen         = sizeof(int),
19646 +               .mode           = 0600,
19647 +               .proc_handler   = &proc_dointvec,
19648 +       },
19649 +       {
19650 +               .ctl_name       = GS_SOCKET_SERVER_GID,
19651 +               .procname       = "socket_server_gid",
19652 +               .data           = &grsec_socket_server_gid,
19653 +               .maxlen         = sizeof(int),
19654 +               .mode           = 0600,
19655 +               .proc_handler   = &proc_dointvec,
19656 +       },
19657 +#endif
19658 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
19659 +       {
19660 +               .ctl_name       = GS_GROUP,
19661 +               .procname       = "audit_group",
19662 +               .data           = &grsec_enable_group,
19663 +               .maxlen         = sizeof(int),
19664 +               .mode           = 0600,
19665 +               .proc_handler   = &proc_dointvec,
19666 +       },
19667 +       {
19668 +               .ctl_name       = GS_GID,
19669 +               .procname       = "audit_gid",
19670 +               .data           = &grsec_audit_gid,
19671 +               .maxlen         = sizeof(int),
19672 +               .mode           = 0600,
19673 +               .proc_handler   = &proc_dointvec,
19674 +       },
19675 +#endif
19676 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
19677 +       {
19678 +               .ctl_name       = GS_ACHDIR,
19679 +               .procname       = "audit_chdir",
19680 +               .data           = &grsec_enable_chdir,
19681 +               .maxlen         = sizeof(int),
19682 +               .mode           = 0600,
19683 +               .proc_handler   = &proc_dointvec,
19684 +       },
19685 +#endif
19686 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
19687 +       {
19688 +               .ctl_name       = GS_AMOUNT,
19689 +               .procname       = "audit_mount",
19690 +               .data           = &grsec_enable_mount,
19691 +               .maxlen         = sizeof(int),
19692 +               .mode           = 0600,
19693 +               .proc_handler   = &proc_dointvec,
19694 +       },
19695 +#endif
19696 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
19697 +       {
19698 +               .ctl_name       = GS_AIPC,
19699 +               .procname       = "audit_ipc",
19700 +               .data           = &grsec_enable_audit_ipc,
19701 +               .maxlen         = sizeof(int),
19702 +               .mode           = 0600,
19703 +               .proc_handler   = &proc_dointvec,
19704 +       },
19705 +#endif
19706 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
19707 +       {
19708 +               .ctl_name       = GS_TEXTREL,
19709 +               .procname       = "audit_textrel",
19710 +               .data           = &grsec_enable_audit_textrel,
19711 +               .maxlen         = sizeof(int),
19712 +               .mode           = 0600,
19713 +               .proc_handler   = &proc_dointvec,
19714 +       },
19715 +#endif
19716 +#ifdef CONFIG_GRKERNSEC_DMESG
19717 +       {
19718 +               .ctl_name       = GS_DMSG,
19719 +               .procname       = "dmesg",
19720 +               .data           = &grsec_enable_dmesg,
19721 +               .maxlen         = sizeof(int),
19722 +               .mode           = 0600,
19723 +               .proc_handler   = &proc_dointvec,
19724 +       },
19725 +#endif
19726 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
19727 +       {
19728 +               .ctl_name       = GS_FINDTASK,
19729 +               .procname       = "chroot_findtask",
19730 +               .data           = &grsec_enable_chroot_findtask,
19731 +               .maxlen         = sizeof(int),
19732 +               .mode           = 0600,
19733 +               .proc_handler   = &proc_dointvec,
19734 +       },
19735 +#endif
19736 +#ifdef CONFIG_GRKERNSEC_SHM
19737 +       {
19738 +               .ctl_name       = GS_SHM,
19739 +               .procname       = "destroy_unused_shm",
19740 +               .data           = &grsec_enable_shm,
19741 +               .maxlen         = sizeof(int),
19742 +               .mode           = 0600,
19743 +               .proc_handler   = &proc_dointvec,
19744 +       },
19745 +#endif
19746 +#ifdef CONFIG_GRKERNSEC_RESLOG
19747 +       {
19748 +               .ctl_name       = GS_RESLOG,
19749 +               .procname       = "resource_logging",
19750 +               .data           = &grsec_resource_logging,
19751 +               .maxlen         = sizeof(int),
19752 +               .mode           = 0600,
19753 +               .proc_handler   = &proc_dointvec,
19754 +       },
19755 +#endif
19756 +       {
19757 +               .ctl_name       = GS_LOCK,
19758 +               .procname       = "grsec_lock",
19759 +               .data           = &grsec_lock,
19760 +               .maxlen         = sizeof(int),
19761 +               .mode           = 0600,
19762 +               .proc_handler   = &proc_dointvec,
19763 +       },
19764 +#endif
19765 +#ifdef CONFIG_GRKERNSEC_MODSTOP
19766 +       {
19767 +               .ctl_name       = GS_MODSTOP,
19768 +               .procname       = "disable_modules",
19769 +               .data           = &grsec_modstop,
19770 +               .maxlen         = sizeof(int),
19771 +               .mode           = 0600,
19772 +               .proc_handler   = &proc_dointvec,
19773 +       },
19774 +#endif
19775 +       { .ctl_name = 0 }
19776 +};
19777 +#endif
19778 +
19779 +int gr_check_modstop(void)
19780 +{
19781 +#ifdef CONFIG_GRKERNSEC_MODSTOP
19782 +       if (grsec_modstop == 1) {
19783 +               gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
19784 +               return 1;
19785 +       }
19786 +#endif
19787 +       return 0;
19788 +}
19789 diff -urNp linux-2.6.18/grsecurity/grsec_textrel.c linux-2.6.18/grsecurity/grsec_textrel.c
19790 --- linux-2.6.18/grsecurity/grsec_textrel.c     1969-12-31 19:00:00.000000000 -0500
19791 +++ linux-2.6.18/grsecurity/grsec_textrel.c     2006-09-22 20:04:35.000000000 -0400
19792 @@ -0,0 +1,16 @@
19793 +#include <linux/kernel.h>
19794 +#include <linux/sched.h>
19795 +#include <linux/mm.h>
19796 +#include <linux/file.h>
19797 +#include <linux/grinternal.h>
19798 +#include <linux/grsecurity.h>
19799 +
19800 +void
19801 +gr_log_textrel(struct vm_area_struct * vma)
19802 +{
19803 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
19804 +       if (grsec_enable_audit_textrel)
19805 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
19806 +#endif
19807 +       return;
19808 +}
19809 diff -urNp linux-2.6.18/grsecurity/grsec_time.c linux-2.6.18/grsecurity/grsec_time.c
19810 --- linux-2.6.18/grsecurity/grsec_time.c        1969-12-31 19:00:00.000000000 -0500
19811 +++ linux-2.6.18/grsecurity/grsec_time.c        2006-09-22 20:04:35.000000000 -0400
19812 @@ -0,0 +1,13 @@
19813 +#include <linux/kernel.h>
19814 +#include <linux/sched.h>
19815 +#include <linux/grinternal.h>
19816 +
19817 +void
19818 +gr_log_timechange(void)
19819 +{
19820 +#ifdef CONFIG_GRKERNSEC_TIME
19821 +       if (grsec_enable_time)
19822 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
19823 +#endif
19824 +       return;
19825 +}
19826 diff -urNp linux-2.6.18/grsecurity/grsec_tpe.c linux-2.6.18/grsecurity/grsec_tpe.c
19827 --- linux-2.6.18/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
19828 +++ linux-2.6.18/grsecurity/grsec_tpe.c 2006-09-22 20:04:35.000000000 -0400
19829 @@ -0,0 +1,37 @@
19830 +#include <linux/kernel.h>
19831 +#include <linux/sched.h>
19832 +#include <linux/file.h>
19833 +#include <linux/fs.h>
19834 +#include <linux/grinternal.h>
19835 +
19836 +extern int gr_acl_tpe_check(void);
19837 +
19838 +int
19839 +gr_tpe_allow(const struct file *file)
19840 +{
19841 +#ifdef CONFIG_GRKERNSEC
19842 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
19843 +
19844 +       if (current->uid && ((grsec_enable_tpe &&
19845 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
19846 +           !in_group_p(grsec_tpe_gid)
19847 +#else
19848 +           in_group_p(grsec_tpe_gid)
19849 +#endif
19850 +           ) || gr_acl_tpe_check()) &&
19851 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
19852 +                                               (inode->i_mode & S_IWOTH))))) {
19853 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
19854 +               return 0;
19855 +       }
19856 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
19857 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
19858 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
19859 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
19860 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
19861 +               return 0;
19862 +       }
19863 +#endif
19864 +#endif
19865 +       return 1;
19866 +}
19867 diff -urNp linux-2.6.18/grsecurity/grsum.c linux-2.6.18/grsecurity/grsum.c
19868 --- linux-2.6.18/grsecurity/grsum.c     1969-12-31 19:00:00.000000000 -0500
19869 +++ linux-2.6.18/grsecurity/grsum.c     2006-09-22 20:04:35.000000000 -0400
19870 @@ -0,0 +1,59 @@
19871 +#include <linux/kernel.h>
19872 +#include <linux/sched.h>
19873 +#include <linux/mm.h>
19874 +#include <asm/scatterlist.h>
19875 +#include <linux/crypto.h>
19876 +#include <linux/gracl.h>
19877 +
19878 +
19879 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
19880 +#error "crypto and sha256 must be built into the kernel"
19881 +#endif
19882 +
19883 +int
19884 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
19885 +{
19886 +       char *p;
19887 +       struct crypto_tfm *tfm;
19888 +       unsigned char temp_sum[GR_SHA_LEN];
19889 +       struct scatterlist sg[2];
19890 +       volatile int retval = 0;
19891 +       volatile int dummy = 0;
19892 +       unsigned int i;
19893 +
19894 +       tfm = crypto_alloc_tfm("sha256", 0);
19895 +       if (tfm == NULL) {
19896 +               /* should never happen, since sha256 should be built in */
19897 +               return 1;
19898 +       }
19899 +
19900 +       crypto_digest_init(tfm);
19901 +
19902 +       p = salt;
19903 +       sg[0].page = virt_to_page(p);
19904 +       sg[0].offset = ((long) p & ~PAGE_MASK);
19905 +       sg[0].length = GR_SALT_LEN;
19906 +       
19907 +       crypto_digest_update(tfm, sg, 1);
19908 +
19909 +       p = entry->pw;
19910 +       sg[0].page = virt_to_page(p);
19911 +       sg[0].offset = ((long) p & ~PAGE_MASK);
19912 +       sg[0].length = strlen(entry->pw);
19913 +
19914 +       crypto_digest_update(tfm, sg, 1);
19915 +
19916 +       crypto_digest_final(tfm, temp_sum);
19917 +
19918 +       memset(entry->pw, 0, GR_PW_LEN);
19919 +
19920 +       for (i = 0; i < GR_SHA_LEN; i++)
19921 +               if (sum[i] != temp_sum[i])
19922 +                       retval = 1;
19923 +               else
19924 +                       dummy = 1;      // waste a cycle
19925 +
19926 +       crypto_free_tfm(tfm);
19927 +
19928 +       return retval;
19929 +}
19930 diff -urNp linux-2.6.18/grsecurity/Kconfig linux-2.6.18/grsecurity/Kconfig
19931 --- linux-2.6.18/grsecurity/Kconfig     1969-12-31 19:00:00.000000000 -0500
19932 +++ linux-2.6.18/grsecurity/Kconfig     2006-09-22 22:12:27.000000000 -0400
19933 @@ -0,0 +1,888 @@
19934 +#
19935 +# grecurity configuration
19936 +#
19937 +
19938 +menu "Grsecurity"
19939 +
19940 +config GRKERNSEC
19941 +       bool "Grsecurity"
19942 +       select CRYPTO
19943 +       select CRYPTO_SHA256
19944 +       help
19945 +         If you say Y here, you will be able to configure many features
19946 +         that will enhance the security of your system.  It is highly
19947 +         recommended that you say Y here and read through the help
19948 +         for each option so that you fully understand the features and
19949 +         can evaluate their usefulness for your machine.
19950 +
19951 +choice
19952 +       prompt "Security Level"
19953 +       depends GRKERNSEC
19954 +       default GRKERNSEC_CUSTOM
19955 +
19956 +config GRKERNSEC_LOW
19957 +       bool "Low"
19958 +       select GRKERNSEC_LINK
19959 +       select GRKERNSEC_FIFO
19960 +       select GRKERNSEC_RANDPID
19961 +       select GRKERNSEC_EXECVE
19962 +       select GRKERNSEC_RANDNET
19963 +       select GRKERNSEC_DMESG
19964 +       select GRKERNSEC_CHROOT_CHDIR
19965 +       select GRKERNSEC_MODSTOP if (MODULES)
19966 +
19967 +       help
19968 +         If you choose this option, several of the grsecurity options will
19969 +         be enabled that will give you greater protection against a number
19970 +         of attacks, while assuring that none of your software will have any
19971 +         conflicts with the additional security measures.  If you run a lot
19972 +         of unusual software, or you are having problems with the higher
19973 +         security levels, you should say Y here.  With this option, the
19974 +         following features are enabled:
19975 +
19976 +         - Linking restrictions
19977 +         - FIFO restrictions
19978 +         - Randomized PIDs
19979 +         - Enforcing RLIMIT_NPROC on execve
19980 +         - Restricted dmesg
19981 +         - Enforced chdir("/") on chroot
19982 +         - Runtime module disabling
19983 +
19984 +config GRKERNSEC_MEDIUM
19985 +       bool "Medium"
19986 +       select PAX
19987 +       select PAX_EI_PAX
19988 +       select PAX_PT_PAX_FLAGS
19989 +       select PAX_HAVE_ACL_FLAGS
19990 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
19991 +       select GRKERNSEC_CHROOT_SYSCTL
19992 +       select GRKERNSEC_LINK
19993 +       select GRKERNSEC_FIFO
19994 +       select GRKERNSEC_RANDPID
19995 +       select GRKERNSEC_EXECVE
19996 +       select GRKERNSEC_DMESG
19997 +       select GRKERNSEC_RANDNET
19998 +       select GRKERNSEC_FORKFAIL
19999 +       select GRKERNSEC_TIME
20000 +       select GRKERNSEC_SIGNAL
20001 +       select GRKERNSEC_CHROOT
20002 +       select GRKERNSEC_CHROOT_UNIX
20003 +       select GRKERNSEC_CHROOT_MOUNT
20004 +       select GRKERNSEC_CHROOT_PIVOT
20005 +       select GRKERNSEC_CHROOT_DOUBLE
20006 +       select GRKERNSEC_CHROOT_CHDIR
20007 +       select GRKERNSEC_CHROOT_MKNOD
20008 +       select GRKERNSEC_PROC
20009 +       select GRKERNSEC_PROC_USERGROUP
20010 +       select GRKERNSEC_MODSTOP if (MODULES)
20011 +       select PAX_RANDUSTACK
20012 +       select PAX_ASLR
20013 +       select PAX_RANDMMAP
20014 +
20015 +       help
20016 +         If you say Y here, several features in addition to those included
20017 +         in the low additional security level will be enabled.  These
20018 +         features provide even more security to your system, though in rare
20019 +         cases they may be incompatible with very old or poorly written
20020 +         software.  If you enable this option, make sure that your auth
20021 +         service (identd) is running as gid 1001.  With this option, 
20022 +         the following features (in addition to those provided in the 
20023 +         low additional security level) will be enabled:
20024 +
20025 +         - Randomized TCP source ports
20026 +         - Failed fork logging
20027 +         - Time change logging
20028 +         - Signal logging
20029 +         - Deny mounts in chroot
20030 +         - Deny double chrooting
20031 +         - Deny sysctl writes in chroot
20032 +         - Deny mknod in chroot
20033 +         - Deny access to abstract AF_UNIX sockets out of chroot
20034 +         - Deny pivot_root in chroot
20035 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
20036 +         - /proc restrictions with special GID set to 10 (usually wheel)
20037 +         - Address Space Layout Randomization (ASLR)
20038 +
20039 +config GRKERNSEC_HIGH
20040 +       bool "High"
20041 +       select GRKERNSEC_LINK
20042 +       select GRKERNSEC_FIFO
20043 +       select GRKERNSEC_RANDPID
20044 +       select GRKERNSEC_EXECVE
20045 +       select GRKERNSEC_DMESG
20046 +       select GRKERNSEC_FORKFAIL
20047 +       select GRKERNSEC_TIME
20048 +       select GRKERNSEC_SIGNAL
20049 +       select GRKERNSEC_CHROOT_SHMAT
20050 +       select GRKERNSEC_CHROOT_UNIX
20051 +       select GRKERNSEC_CHROOT_MOUNT
20052 +       select GRKERNSEC_CHROOT_FCHDIR
20053 +       select GRKERNSEC_CHROOT_PIVOT
20054 +       select GRKERNSEC_CHROOT_DOUBLE
20055 +       select GRKERNSEC_CHROOT_CHDIR
20056 +       select GRKERNSEC_CHROOT_MKNOD
20057 +       select GRKERNSEC_CHROOT_CAPS
20058 +       select GRKERNSEC_CHROOT_SYSCTL
20059 +       select GRKERNSEC_CHROOT_FINDTASK
20060 +       select GRKERNSEC_PROC
20061 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
20062 +       select GRKERNSEC_HIDESYM
20063 +       select GRKERNSEC_BRUTE
20064 +       select GRKERNSEC_SHM if (SYSVIPC)
20065 +       select GRKERNSEC_PROC_USERGROUP
20066 +       select GRKERNSEC_KMEM
20067 +       select GRKERNSEC_RESLOG
20068 +       select GRKERNSEC_RANDNET
20069 +       select GRKERNSEC_PROC_ADD
20070 +       select GRKERNSEC_CHROOT_CHMOD
20071 +       select GRKERNSEC_CHROOT_NICE
20072 +       select GRKERNSEC_AUDIT_MOUNT
20073 +       select GRKERNSEC_MODSTOP if (MODULES)
20074 +       select PAX
20075 +       select PAX_RANDUSTACK
20076 +       select PAX_ASLR
20077 +       select PAX_RANDMMAP
20078 +       select PAX_NOEXEC
20079 +       select PAX_MPROTECT
20080 +       select PAX_EI_PAX
20081 +       select PAX_PT_PAX_FLAGS
20082 +       select PAX_HAVE_ACL_FLAGS
20083 +       select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
20084 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
20085 +       select PAX_SEGMEXEC if (X86 && !X86_64)
20086 +       select PAX_PAGEEXEC if (!X86)
20087 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
20088 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
20089 +       select PAX_SYSCALL if (PPC32)
20090 +       select PAX_EMUTRAMP if (PARISC)
20091 +       select PAX_EMUSIGRT if (PARISC)
20092 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
20093 +       help
20094 +         If you say Y here, many of the features of grsecurity will be
20095 +         enabled, which will protect you against many kinds of attacks
20096 +         against your system.  The heightened security comes at a cost
20097 +         of an increased chance of incompatibilities with rare software
20098 +         on your machine.  Since this security level enables PaX, you should
20099 +         view <http://pax.grsecurity.net> and read about the PaX
20100 +         project.  While you are there, download chpax and run it on
20101 +         binaries that cause problems with PaX.  Also remember that
20102 +         since the /proc restrictions are enabled, you must run your
20103 +         identd as gid 1001.  This security level enables the following 
20104 +         features in addition to those listed in the low and medium 
20105 +         security levels:
20106 +
20107 +         - Additional /proc restrictions
20108 +         - Chmod restrictions in chroot
20109 +         - No signals, ptrace, or viewing of processes outside of chroot
20110 +         - Capability restrictions in chroot
20111 +         - Deny fchdir out of chroot
20112 +         - Priority restrictions in chroot
20113 +         - Segmentation-based implementation of PaX
20114 +         - Mprotect restrictions
20115 +         - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
20116 +         - Kernel stack randomization
20117 +         - Mount/unmount/remount logging
20118 +         - Kernel symbol hiding
20119 +         - Destroy unused shared memory        
20120 +         - Prevention of memory exhaustion-based exploits
20121 +config GRKERNSEC_CUSTOM
20122 +       bool "Custom"
20123 +       help
20124 +         If you say Y here, you will be able to configure every grsecurity
20125 +         option, which allows you to enable many more features that aren't
20126 +         covered in the basic security levels.  These additional features
20127 +         include TPE, socket restrictions, and the sysctl system for
20128 +         grsecurity.  It is advised that you read through the help for
20129 +         each option to determine its usefulness in your situation.
20130 +
20131 +endchoice
20132 +
20133 +menu "Address Space Protection"
20134 +depends on GRKERNSEC
20135 +
20136 +config GRKERNSEC_KMEM
20137 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
20138 +       help
20139 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
20140 +         be written to via mmap or otherwise to modify the running kernel.
20141 +         /dev/port will also not be allowed to be opened. If you have module
20142 +         support disabled, enabling this will close up four ways that are
20143 +         currently used  to insert malicious code into the running kernel.
20144 +         Even with all these features enabled, we still highly recommend that
20145 +         you use the RBAC system, as it is still possible for an attacker to
20146 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
20147 +         If you are not using XFree86, you may be able to stop this additional
20148 +         case by enabling the 'Disable privileged I/O' option. Though nothing
20149 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
20150 +         but only to video memory, which is the only writing we allow in this
20151 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
20152 +         not be allowed to mprotect it with PROT_WRITE later.
20153 +         It is highly recommended that you say Y here if you meet all the
20154 +         conditions above.
20155 +
20156 +config GRKERNSEC_IO
20157 +       bool "Disable privileged I/O"
20158 +       depends on X86
20159 +       select RTC
20160 +       help
20161 +         If you say Y here, all ioperm and iopl calls will return an error.
20162 +         Ioperm and iopl can be used to modify the running kernel.
20163 +         Unfortunately, some programs need this access to operate properly,
20164 +         the most notable of which are XFree86 and hwclock.  hwclock can be
20165 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
20166 +         enabled if this option is enabled, to ensure that hwclock operates
20167 +         correctly.  XFree86 still will not operate correctly with this option
20168 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
20169 +         and you still want to protect your kernel against modification,
20170 +         use the RBAC system.
20171 +
20172 +config GRKERNSEC_PROC_MEMMAP
20173 +       bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
20174 +       depends on PAX_NOEXEC || PAX_ASLR
20175 +       help
20176 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
20177 +         give no information about the addresses of its mappings if
20178 +         PaX features that rely on random addresses are enabled on the task.
20179 +         If you use PaX it is greatly recommended that you say Y here as it
20180 +         closes up a hole that makes the full ASLR useless for suid
20181 +         binaries.
20182 +
20183 +config GRKERNSEC_BRUTE
20184 +       bool "Deter exploit bruteforcing"
20185 +       help
20186 +         If you say Y here, attempts to bruteforce exploits against forking
20187 +         daemons such as apache or sshd will be deterred.  When a child of a
20188 +         forking daemon is killed by PaX or crashes due to an illegal
20189 +         instruction, the parent process will be delayed 30 seconds upon every
20190 +         subsequent fork until the administrator is able to assess the
20191 +         situation and restart the daemon.  It is recommended that you also
20192 +         enable signal logging in the auditing section so that logs are
20193 +         generated when a process performs an illegal instruction.
20194 +
20195 +config GRKERNSEC_MODSTOP
20196 +       bool "Runtime module disabling"
20197 +       depends on MODULES
20198 +       help
20199 +         If you say Y here, you will be able to disable the ability to (un)load
20200 +         modules at runtime.  This feature is useful if you need the ability
20201 +         to load kernel modules at boot time, but do not want to allow an
20202 +         attacker to load a rootkit kernel module into the system, or to remove
20203 +         a loaded kernel module important to system functioning.  You should
20204 +         enable the /dev/mem protection feature as well, since rootkits can be
20205 +         inserted into the kernel via other methods than kernel modules.  Since
20206 +         an untrusted module could still be loaded by modifying init scripts and
20207 +         rebooting the system, it is also recommended that you enable the RBAC
20208 +         system.  If you enable this option, a sysctl option with name
20209 +         "disable_modules" will be created.  Setting this option to "1" disables
20210 +         module loading.  After this option is set, no further writes to it are
20211 +         allowed until the system is rebooted.
20212 +
20213 +config GRKERNSEC_HIDESYM
20214 +       bool "Hide kernel symbols"
20215 +       help
20216 +         If you say Y here, getting information on loaded modules, and
20217 +         displaying all kernel symbols through a syscall will be restricted
20218 +         to users with CAP_SYS_MODULE.  This option is only effective
20219 +         provided the following conditions are met:
20220 +         1) The kernel using grsecurity is not precompiled by some distribution
20221 +         2) You are using the RBAC system and hiding other files such as your
20222 +            kernel image and System.map
20223 +         3) You have the additional /proc restrictions enabled, which removes
20224 +            /proc/kcore
20225 +         If the above conditions are met, this option will aid to provide a
20226 +         useful protection against local and remote kernel exploitation of
20227 +         overflows and arbitrary read/write vulnerabilities.
20228 +
20229 +endmenu
20230 +menu "Role Based Access Control Options"
20231 +depends on GRKERNSEC
20232 +
20233 +config GRKERNSEC_ACL_HIDEKERN
20234 +       bool "Hide kernel processes"
20235 +       help
20236 +         If you say Y here, all kernel threads will be hidden to all
20237 +         processes but those whose subject has the "view hidden processes"
20238 +         flag.
20239 +
20240 +config GRKERNSEC_ACL_MAXTRIES
20241 +       int "Maximum tries before password lockout"
20242 +       default 3
20243 +       help
20244 +         This option enforces the maximum number of times a user can attempt
20245 +         to authorize themselves with the grsecurity RBAC system before being
20246 +         denied the ability to attempt authorization again for a specified time.
20247 +         The lower the number, the harder it will be to brute-force a password.
20248 +
20249 +config GRKERNSEC_ACL_TIMEOUT
20250 +       int "Time to wait after max password tries, in seconds"
20251 +       default 30
20252 +       help
20253 +         This option specifies the time the user must wait after attempting to
20254 +         authorize to the RBAC system with the maximum number of invalid
20255 +         passwords.  The higher the number, the harder it will be to brute-force
20256 +         a password.
20257 +
20258 +endmenu
20259 +menu "Filesystem Protections"
20260 +depends on GRKERNSEC
20261 +
20262 +config GRKERNSEC_PROC
20263 +       bool "Proc restrictions"
20264 +       help
20265 +         If you say Y here, the permissions of the /proc filesystem
20266 +         will be altered to enhance system security and privacy.  You MUST
20267 +         choose either a user only restriction or a user and group restriction.
20268 +         Depending upon the option you choose, you can either restrict users to
20269 +         see only the processes they themselves run, or choose a group that can
20270 +         view all processes and files normally restricted to root if you choose
20271 +         the "restrict to user only" option.  NOTE: If you're running identd as
20272 +         a non-root user, you will have to run it as the group you specify here.
20273 +
20274 +config GRKERNSEC_PROC_USER
20275 +       bool "Restrict /proc to user only"
20276 +       depends on GRKERNSEC_PROC
20277 +       help
20278 +         If you say Y here, non-root users will only be able to view their own
20279 +         processes, and restricts them from viewing network-related information,
20280 +         and viewing kernel symbol and module information.
20281 +
20282 +config GRKERNSEC_PROC_USERGROUP
20283 +       bool "Allow special group"
20284 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
20285 +       help
20286 +         If you say Y here, you will be able to select a group that will be
20287 +         able to view all processes, network-related information, and
20288 +         kernel and symbol information.  This option is useful if you want
20289 +         to run identd as a non-root user.
20290 +
20291 +config GRKERNSEC_PROC_GID
20292 +       int "GID for special group"
20293 +       depends on GRKERNSEC_PROC_USERGROUP
20294 +       default 1001
20295 +
20296 +config GRKERNSEC_PROC_ADD
20297 +       bool "Additional restrictions"
20298 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
20299 +       help
20300 +         If you say Y here, additional restrictions will be placed on
20301 +         /proc that keep normal users from viewing device information and 
20302 +         slabinfo information that could be useful for exploits.
20303 +
20304 +config GRKERNSEC_LINK
20305 +       bool "Linking restrictions"
20306 +       help
20307 +         If you say Y here, /tmp race exploits will be prevented, since users
20308 +         will no longer be able to follow symlinks owned by other users in
20309 +         world-writable +t directories (i.e. /tmp), unless the owner of the
20310 +         symlink is the owner of the directory. users will also not be
20311 +         able to hardlink to files they do not own.  If the sysctl option is
20312 +         enabled, a sysctl option with name "linking_restrictions" is created.
20313 +
20314 +config GRKERNSEC_FIFO
20315 +       bool "FIFO restrictions"
20316 +       help
20317 +         If you say Y here, users will not be able to write to FIFOs they don't
20318 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
20319 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
20320 +         option is enabled, a sysctl option with name "fifo_restrictions" is
20321 +         created.
20322 +
20323 +config GRKERNSEC_CHROOT
20324 +       bool "Chroot jail restrictions"
20325 +       help
20326 +         If you say Y here, you will be able to choose several options that will
20327 +         make breaking out of a chrooted jail much more difficult.  If you
20328 +         encounter no software incompatibilities with the following options, it
20329 +         is recommended that you enable each one.
20330 +
20331 +config GRKERNSEC_CHROOT_MOUNT
20332 +       bool "Deny mounts"
20333 +       depends on GRKERNSEC_CHROOT
20334 +       help
20335 +         If you say Y here, processes inside a chroot will not be able to
20336 +         mount or remount filesystems.  If the sysctl option is enabled, a
20337 +         sysctl option with name "chroot_deny_mount" is created.
20338 +
20339 +config GRKERNSEC_CHROOT_DOUBLE
20340 +       bool "Deny double-chroots"
20341 +       depends on GRKERNSEC_CHROOT
20342 +       help
20343 +         If you say Y here, processes inside a chroot will not be able to chroot
20344 +         again outside the chroot.  This is a widely used method of breaking
20345 +         out of a chroot jail and should not be allowed.  If the sysctl 
20346 +         option is enabled, a sysctl option with name 
20347 +         "chroot_deny_chroot" is created.
20348 +
20349 +config GRKERNSEC_CHROOT_PIVOT
20350 +       bool "Deny pivot_root in chroot"
20351 +       depends on GRKERNSEC_CHROOT
20352 +       help
20353 +         If you say Y here, processes inside a chroot will not be able to use
20354 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
20355 +         works similar to chroot in that it changes the root filesystem.  This
20356 +         function could be misused in a chrooted process to attempt to break out
20357 +         of the chroot, and therefore should not be allowed.  If the sysctl
20358 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
20359 +         created.
20360 +
20361 +config GRKERNSEC_CHROOT_CHDIR
20362 +       bool "Enforce chdir(\"/\") on all chroots"
20363 +       depends on GRKERNSEC_CHROOT
20364 +       help
20365 +         If you say Y here, the current working directory of all newly-chrooted
20366 +         applications will be set to the the root directory of the chroot.
20367 +         The man page on chroot(2) states:
20368 +         Note that this call does not change  the  current  working
20369 +         directory,  so  that `.' can be outside the tree rooted at
20370 +         `/'.  In particular, the  super-user  can  escape  from  a
20371 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
20372 +
20373 +         It is recommended that you say Y here, since it's not known to break
20374 +         any software.  If the sysctl option is enabled, a sysctl option with
20375 +         name "chroot_enforce_chdir" is created.
20376 +
20377 +config GRKERNSEC_CHROOT_CHMOD
20378 +       bool "Deny (f)chmod +s"
20379 +       depends on GRKERNSEC_CHROOT
20380 +       help
20381 +         If you say Y here, processes inside a chroot will not be able to chmod
20382 +         or fchmod files to make them have suid or sgid bits.  This protects
20383 +         against another published method of breaking a chroot.  If the sysctl
20384 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
20385 +         created.
20386 +
20387 +config GRKERNSEC_CHROOT_FCHDIR
20388 +       bool "Deny fchdir out of chroot"
20389 +       depends on GRKERNSEC_CHROOT
20390 +       help
20391 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
20392 +         to a file descriptor of the chrooting process that points to a directory
20393 +         outside the filesystem will be stopped.  If the sysctl option
20394 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
20395 +
20396 +config GRKERNSEC_CHROOT_MKNOD
20397 +       bool "Deny mknod"
20398 +       depends on GRKERNSEC_CHROOT
20399 +       help
20400 +         If you say Y here, processes inside a chroot will not be allowed to
20401 +         mknod.  The problem with using mknod inside a chroot is that it
20402 +         would allow an attacker to create a device entry that is the same
20403 +         as one on the physical root of your system, which could range from
20404 +         anything from the console device to a device for your harddrive (which
20405 +         they could then use to wipe the drive or steal data).  It is recommended
20406 +         that you say Y here, unless you run into software incompatibilities.
20407 +         If the sysctl option is enabled, a sysctl option with name
20408 +         "chroot_deny_mknod" is created.
20409 +
20410 +config GRKERNSEC_CHROOT_SHMAT
20411 +       bool "Deny shmat() out of chroot"
20412 +       depends on GRKERNSEC_CHROOT
20413 +       help
20414 +         If you say Y here, processes inside a chroot will not be able to attach
20415 +         to shared memory segments that were created outside of the chroot jail.
20416 +         It is recommended that you say Y here.  If the sysctl option is enabled,
20417 +         a sysctl option with name "chroot_deny_shmat" is created.
20418 +
20419 +config GRKERNSEC_CHROOT_UNIX
20420 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
20421 +       depends on GRKERNSEC_CHROOT
20422 +       help
20423 +         If you say Y here, processes inside a chroot will not be able to
20424 +         connect to abstract (meaning not belonging to a filesystem) Unix
20425 +         domain sockets that were bound outside of a chroot.  It is recommended
20426 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
20427 +         with name "chroot_deny_unix" is created.
20428 +
20429 +config GRKERNSEC_CHROOT_FINDTASK
20430 +       bool "Protect outside processes"
20431 +       depends on GRKERNSEC_CHROOT
20432 +       help
20433 +         If you say Y here, processes inside a chroot will not be able to
20434 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
20435 +         getsid, or view any process outside of the chroot.  If the sysctl
20436 +         option is enabled, a sysctl option with name "chroot_findtask" is
20437 +         created.
20438 +
20439 +config GRKERNSEC_CHROOT_NICE
20440 +       bool "Restrict priority changes"
20441 +       depends on GRKERNSEC_CHROOT
20442 +       help
20443 +         If you say Y here, processes inside a chroot will not be able to raise
20444 +         the priority of processes in the chroot, or alter the priority of
20445 +         processes outside the chroot.  This provides more security than simply
20446 +         removing CAP_SYS_NICE from the process' capability set.  If the
20447 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
20448 +         is created.
20449 +
20450 +config GRKERNSEC_CHROOT_SYSCTL
20451 +       bool "Deny sysctl writes"
20452 +       depends on GRKERNSEC_CHROOT
20453 +       help
20454 +         If you say Y here, an attacker in a chroot will not be able to
20455 +         write to sysctl entries, either by sysctl(2) or through a /proc
20456 +         interface.  It is strongly recommended that you say Y here. If the
20457 +         sysctl option is enabled, a sysctl option with name
20458 +         "chroot_deny_sysctl" is created.
20459 +
20460 +config GRKERNSEC_CHROOT_CAPS
20461 +       bool "Capability restrictions"
20462 +       depends on GRKERNSEC_CHROOT
20463 +       help
20464 +         If you say Y here, the capabilities on all root processes within a
20465 +         chroot jail will be lowered to stop module insertion, raw i/o,
20466 +         system and net admin tasks, rebooting the system, modifying immutable
20467 +         files, modifying IPC owned by another, and changing the system time.
20468 +         This is left an option because it can break some apps.  Disable this
20469 +         if your chrooted apps are having problems performing those kinds of
20470 +         tasks.  If the sysctl option is enabled, a sysctl option with
20471 +         name "chroot_caps" is created.
20472 +
20473 +endmenu
20474 +menu "Kernel Auditing"
20475 +depends on GRKERNSEC
20476 +
20477 +config GRKERNSEC_AUDIT_GROUP
20478 +       bool "Single group for auditing"
20479 +       help
20480 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
20481 +         will only operate on a group you specify.  This option is recommended
20482 +         if you only want to watch certain users instead of having a large
20483 +         amount of logs from the entire system.  If the sysctl option is enabled,
20484 +         a sysctl option with name "audit_group" is created.
20485 +
20486 +config GRKERNSEC_AUDIT_GID
20487 +       int "GID for auditing"
20488 +       depends on GRKERNSEC_AUDIT_GROUP
20489 +       default 1007
20490 +
20491 +config GRKERNSEC_EXECLOG
20492 +       bool "Exec logging"
20493 +       help
20494 +         If you say Y here, all execve() calls will be logged (since the
20495 +         other exec*() calls are frontends to execve(), all execution
20496 +         will be logged).  Useful for shell-servers that like to keep track
20497 +         of their users.  If the sysctl option is enabled, a sysctl option with
20498 +         name "exec_logging" is created.
20499 +         WARNING: This option when enabled will produce a LOT of logs, especially
20500 +         on an active system.
20501 +
20502 +config GRKERNSEC_RESLOG
20503 +       bool "Resource logging"
20504 +       help
20505 +         If you say Y here, all attempts to overstep resource limits will
20506 +         be logged with the resource name, the requested size, and the current
20507 +         limit.  It is highly recommended that you say Y here.  If the sysctl
20508 +         option is enabled, a sysctl option with name "resource_logging" is
20509 +         created.  If the RBAC system is enabled, the sysctl value is ignored.
20510 +
20511 +config GRKERNSEC_CHROOT_EXECLOG
20512 +       bool "Log execs within chroot"
20513 +       help
20514 +         If you say Y here, all executions inside a chroot jail will be logged
20515 +         to syslog.  This can cause a large amount of logs if certain
20516 +         applications (eg. djb's daemontools) are installed on the system, and
20517 +         is therefore left as an option.  If the sysctl option is enabled, a
20518 +         sysctl option with name "chroot_execlog" is created.
20519 +
20520 +config GRKERNSEC_AUDIT_CHDIR
20521 +       bool "Chdir logging"
20522 +       help
20523 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
20524 +         option is enabled, a sysctl option with name "audit_chdir" is created.
20525 +
20526 +config GRKERNSEC_AUDIT_MOUNT
20527 +       bool "(Un)Mount logging"
20528 +       help
20529 +         If you say Y here, all mounts and unmounts will be logged.  If the
20530 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
20531 +         created.
20532 +
20533 +config GRKERNSEC_AUDIT_IPC
20534 +       bool "IPC logging"
20535 +       help
20536 +         If you say Y here, creation and removal of message queues, semaphores,
20537 +         and shared memory will be logged.  If the sysctl option is enabled, a
20538 +         sysctl option with name "audit_ipc" is created.
20539 +
20540 +config GRKERNSEC_SIGNAL
20541 +       bool "Signal logging"
20542 +       help
20543 +         If you say Y here, certain important signals will be logged, such as
20544 +         SIGSEGV, which will as a result inform you of when a error in a program
20545 +         occurred, which in some cases could mean a possible exploit attempt.
20546 +         If the sysctl option is enabled, a sysctl option with name
20547 +         "signal_logging" is created.
20548 +
20549 +config GRKERNSEC_FORKFAIL
20550 +       bool "Fork failure logging"
20551 +       help
20552 +         If you say Y here, all failed fork() attempts will be logged.
20553 +         This could suggest a fork bomb, or someone attempting to overstep
20554 +         their process limit.  If the sysctl option is enabled, a sysctl option
20555 +         with name "forkfail_logging" is created.
20556 +
20557 +config GRKERNSEC_TIME
20558 +       bool "Time change logging"
20559 +       help
20560 +         If you say Y here, any changes of the system clock will be logged.
20561 +         If the sysctl option is enabled, a sysctl option with name
20562 +         "timechange_logging" is created.
20563 +
20564 +config GRKERNSEC_PROC_IPADDR
20565 +       bool "/proc/<pid>/ipaddr support"
20566 +       help
20567 +         If you say Y here, a new entry will be added to each /proc/<pid>
20568 +         directory that contains the IP address of the person using the task.
20569 +         The IP is carried across local TCP and AF_UNIX stream sockets.
20570 +         This information can be useful for IDS/IPSes to perform remote response
20571 +         to a local attack.  The entry is readable by only the owner of the
20572 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
20573 +         the RBAC system), and thus does not create privacy concerns.
20574 +
20575 +config GRKERNSEC_AUDIT_TEXTREL
20576 +       bool 'ELF text relocations logging (READ HELP)'
20577 +       depends on PAX_MPROTECT
20578 +       help
20579 +         If you say Y here, text relocations will be logged with the filename
20580 +         of the offending library or binary.  The purpose of the feature is
20581 +         to help Linux distribution developers get rid of libraries and
20582 +         binaries that need text relocations which hinder the future progress
20583 +         of PaX.  Only Linux distribution developers should say Y here, and
20584 +         never on a production machine, as this option creates an information
20585 +         leak that could aid an attacker in defeating the randomization of
20586 +         a single memory region.  If the sysctl option is enabled, a sysctl
20587 +         option with name "audit_textrel" is created.
20588 +
20589 +endmenu
20590 +
20591 +menu "Executable Protections"
20592 +depends on GRKERNSEC
20593 +
20594 +config GRKERNSEC_EXECVE
20595 +       bool "Enforce RLIMIT_NPROC on execs"
20596 +       help
20597 +         If you say Y here, users with a resource limit on processes will
20598 +         have the value checked during execve() calls.  The current system
20599 +         only checks the system limit during fork() calls.  If the sysctl option
20600 +         is enabled, a sysctl option with name "execve_limiting" is created.
20601 +
20602 +config GRKERNSEC_SHM
20603 +       bool "Destroy unused shared memory"
20604 +       depends on SYSVIPC
20605 +       help
20606 +         If you say Y here, shared memory will be destroyed when no one is
20607 +         attached to it.  Otherwise, resources involved with the shared
20608 +         memory can be used up and not be associated with any process (as the
20609 +         shared memory still exists, and the creating process has exited).  If
20610 +         the sysctl option is enabled, a sysctl option with name
20611 +         "destroy_unused_shm" is created.
20612 +
20613 +config GRKERNSEC_DMESG
20614 +       bool "Dmesg(8) restriction"
20615 +       help
20616 +         If you say Y here, non-root users will not be able to use dmesg(8)
20617 +         to view up to the last 4kb of messages in the kernel's log buffer.
20618 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
20619 +         created.
20620 +
20621 +config GRKERNSEC_RANDPID
20622 +       bool "Randomized PIDs"
20623 +       help
20624 +         If you say Y here, all PIDs created on the system will be
20625 +         pseudo-randomly generated.  This is extremely effective along
20626 +         with the /proc restrictions to disallow an attacker from guessing
20627 +         pids of daemons, etc.  PIDs are also used in some cases as part
20628 +         of a naming system for temporary files, so this option would keep
20629 +         those filenames from being predicted as well.  We also use code
20630 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
20631 +         option is enabled, a sysctl option with name "rand_pids" is created.
20632 +
20633 +config GRKERNSEC_TPE
20634 +       bool "Trusted Path Execution (TPE)"
20635 +       help
20636 +         If you say Y here, you will be able to choose a gid to add to the
20637 +         supplementary groups of users you want to mark as "untrusted."
20638 +         These users will not be able to execute any files that are not in
20639 +         root-owned directories writable only by root.  If the sysctl option
20640 +         is enabled, a sysctl option with name "tpe" is created.
20641 +
20642 +config GRKERNSEC_TPE_ALL
20643 +       bool "Partially restrict non-root users"
20644 +       depends on GRKERNSEC_TPE
20645 +       help
20646 +         If you say Y here, All non-root users other than the ones in the
20647 +         group specified in the main TPE option will only be allowed to
20648 +         execute files in directories they own that are not group or
20649 +         world-writable, or in directories owned by root and writable only by
20650 +         root.  If the sysctl option is enabled, a sysctl option with name
20651 +         "tpe_restrict_all" is created.
20652 +
20653 +config GRKERNSEC_TPE_INVERT
20654 +       bool "Invert GID option"
20655 +       depends on GRKERNSEC_TPE
20656 +       help
20657 +         If you say Y here, the group you specify in the TPE configuration will
20658 +         decide what group TPE restrictions will be *disabled* for.  This
20659 +         option is useful if you want TPE restrictions to be applied to most
20660 +         users on the system.
20661 +
20662 +config GRKERNSEC_TPE_GID
20663 +       int "GID for untrusted users"
20664 +       depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
20665 +       default 1005
20666 +       help
20667 +         If you have selected the "Invert GID option" above, setting this
20668 +         GID determines what group TPE restrictions will be *disabled* for.
20669 +         If you have not selected the "Invert GID option" above, setting this
20670 +         GID determines what group TPE restrictions will be *enabled* for.
20671 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
20672 +         is created.
20673 +
20674 +config GRKERNSEC_TPE_GID
20675 +       int "GID for trusted users"
20676 +       depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
20677 +       default 1005
20678 +       help
20679 +         If you have selected the "Invert GID option" above, setting this
20680 +         GID determines what group TPE restrictions will be *disabled* for.
20681 +         If you have not selected the "Invert GID option" above, setting this
20682 +         GID determines what group TPE restrictions will be *enabled* for.
20683 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
20684 +         is created.
20685 +
20686 +endmenu
20687 +menu "Network Protections"
20688 +depends on GRKERNSEC
20689 +
20690 +config GRKERNSEC_RANDNET
20691 +       bool "Larger entropy pools"
20692 +       help
20693 +         If you say Y here, the entropy pools used for many features of Linux
20694 +         and grsecurity will be doubled in size.  Since several grsecurity
20695 +         features use additional randomness, it is recommended that you say Y
20696 +         here.  Saying Y here has a similar effect as modifying
20697 +         /proc/sys/kernel/random/poolsize.
20698 +
20699 +config GRKERNSEC_SOCKET
20700 +       bool "Socket restrictions"
20701 +       help
20702 +         If you say Y here, you will be able to choose from several options.
20703 +         If you assign a GID on your system and add it to the supplementary
20704 +         groups of users you want to restrict socket access to, this patch
20705 +         will perform up to three things, based on the option(s) you choose.
20706 +
20707 +config GRKERNSEC_SOCKET_ALL
20708 +       bool "Deny any sockets to group"
20709 +       depends on GRKERNSEC_SOCKET
20710 +       help
20711 +         If you say Y here, you will be able to choose a GID of whose users will
20712 +         be unable to connect to other hosts from your machine or run server
20713 +         applications from your machine.  If the sysctl option is enabled, a
20714 +         sysctl option with name "socket_all" is created.
20715 +
20716 +config GRKERNSEC_SOCKET_ALL_GID
20717 +       int "GID to deny all sockets for"
20718 +       depends on GRKERNSEC_SOCKET_ALL
20719 +       default 1004
20720 +       help
20721 +         Here you can choose the GID to disable socket access for. Remember to
20722 +         add the users you want socket access disabled for to the GID
20723 +         specified here.  If the sysctl option is enabled, a sysctl option
20724 +         with name "socket_all_gid" is created.
20725 +
20726 +config GRKERNSEC_SOCKET_CLIENT
20727 +       bool "Deny client sockets to group"
20728 +       depends on GRKERNSEC_SOCKET
20729 +       help
20730 +         If you say Y here, you will be able to choose a GID of whose users will
20731 +         be unable to connect to other hosts from your machine, but will be
20732 +         able to run servers.  If this option is enabled, all users in the group
20733 +         you specify will have to use passive mode when initiating ftp transfers
20734 +         from the shell on your machine.  If the sysctl option is enabled, a
20735 +         sysctl option with name "socket_client" is created.
20736 +
20737 +config GRKERNSEC_SOCKET_CLIENT_GID
20738 +       int "GID to deny client sockets for"
20739 +       depends on GRKERNSEC_SOCKET_CLIENT
20740 +       default 1003
20741 +       help
20742 +         Here you can choose the GID to disable client socket access for.
20743 +         Remember to add the users you want client socket access disabled for to
20744 +         the GID specified here.  If the sysctl option is enabled, a sysctl
20745 +         option with name "socket_client_gid" is created.
20746 +
20747 +config GRKERNSEC_SOCKET_SERVER
20748 +       bool "Deny server sockets to group"
20749 +       depends on GRKERNSEC_SOCKET
20750 +       help
20751 +         If you say Y here, you will be able to choose a GID of whose users will
20752 +         be unable to run server applications from your machine.  If the sysctl
20753 +         option is enabled, a sysctl option with name "socket_server" is created.
20754 +
20755 +config GRKERNSEC_SOCKET_SERVER_GID
20756 +       int "GID to deny server sockets for"
20757 +       depends on GRKERNSEC_SOCKET_SERVER
20758 +       default 1002
20759 +       help
20760 +         Here you can choose the GID to disable server socket access for.
20761 +         Remember to add the users you want server socket access disabled for to
20762 +         the GID specified here.  If the sysctl option is enabled, a sysctl
20763 +         option with name "socket_server_gid" is created.
20764 +
20765 +endmenu
20766 +menu "Sysctl support"
20767 +depends on GRKERNSEC && SYSCTL
20768 +
20769 +config GRKERNSEC_SYSCTL
20770 +       bool "Sysctl support"
20771 +       help
20772 +         If you say Y here, you will be able to change the options that
20773 +         grsecurity runs with at bootup, without having to recompile your
20774 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
20775 +         to enable (1) or disable (0) various features.  All the sysctl entries
20776 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
20777 +         All features enabled in the kernel configuration are disabled at boot
20778 +         if you do not say Y to the "Turn on features by default" option.
20779 +         All options should be set at startup, and the grsec_lock entry should
20780 +         be set to a non-zero value after all the options are set.
20781 +         *THIS IS EXTREMELY IMPORTANT*
20782 +
20783 +config GRKERNSEC_SYSCTL_ON
20784 +       bool "Turn on features by default"
20785 +       depends on GRKERNSEC_SYSCTL
20786 +       help
20787 +         If you say Y here, instead of having all features enabled in the
20788 +         kernel configuration disabled at boot time, the features will be
20789 +         enabled at boot time.  It is recommended you say Y here unless
20790 +         there is some reason you would want all sysctl-tunable features to
20791 +         be disabled by default.  As mentioned elsewhere, it is important
20792 +         to enable the grsec_lock entry once you have finished modifying
20793 +         the sysctl entries.
20794 +
20795 +endmenu
20796 +menu "Logging Options"
20797 +depends on GRKERNSEC
20798 +
20799 +config GRKERNSEC_FLOODTIME
20800 +       int "Seconds in between log messages (minimum)"
20801 +       default 10
20802 +       help
20803 +         This option allows you to enforce the number of seconds between
20804 +         grsecurity log messages.  The default should be suitable for most
20805 +         people, however, if you choose to change it, choose a value small enough
20806 +         to allow informative logs to be produced, but large enough to
20807 +         prevent flooding.
20808 +
20809 +config GRKERNSEC_FLOODBURST
20810 +       int "Number of messages in a burst (maximum)"
20811 +       default 4
20812 +       help
20813 +         This option allows you to choose the maximum number of messages allowed
20814 +         within the flood time interval you chose in a separate option.  The
20815 +         default should be suitable for most people, however if you find that
20816 +         many of your logs are being interpreted as flooding, you may want to
20817 +         raise this value.
20818 +
20819 +endmenu
20820 +
20821 +endmenu
20822 diff -urNp linux-2.6.18/grsecurity/Makefile linux-2.6.18/grsecurity/Makefile
20823 --- linux-2.6.18/grsecurity/Makefile    1969-12-31 19:00:00.000000000 -0500
20824 +++ linux-2.6.18/grsecurity/Makefile    2006-09-22 20:04:35.000000000 -0400
20825 @@ -0,0 +1,20 @@
20826 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
20827 +# during 2001-2005 it has been completely redesigned by Brad Spengler
20828 +# into an RBAC system
20829 +#
20830 +# All code in this directory and various hooks inserted throughout the kernel
20831 +# are copyright Brad Spengler, and released under the GPL v2 or higher
20832 +
20833 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
20834 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
20835 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
20836 +
20837 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
20838 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
20839 +       gracl_learn.o grsec_log.o
20840 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
20841 +
20842 +ifndef CONFIG_GRKERNSEC
20843 +obj-y += grsec_disabled.o
20844 +endif
20845 +
20846 diff -urNp linux-2.6.18/include/acpi/acmacros.h linux-2.6.18/include/acpi/acmacros.h
20847 --- linux-2.6.18/include/acpi/acmacros.h        2006-09-19 23:42:06.000000000 -0400
20848 +++ linux-2.6.18/include/acpi/acmacros.h        2006-09-22 20:45:04.000000000 -0400
20849 @@ -672,7 +672,7 @@
20850  #define ACPI_DUMP_PATHNAME(a,b,c,d)
20851  #define ACPI_DUMP_RESOURCE_LIST(a)
20852  #define ACPI_DUMP_BUFFER(a,b)
20853 -#define ACPI_DEBUG_PRINT(pl)
20854 +#define ACPI_DEBUG_PRINT(pl) do {} while (0)
20855  #define ACPI_DEBUG_PRINT_RAW(pl)
20856  
20857  #define return_VOID                     return
20858 diff -urNp linux-2.6.18/include/asm-alpha/a.out.h linux-2.6.18/include/asm-alpha/a.out.h
20859 --- linux-2.6.18/include/asm-alpha/a.out.h      2006-09-19 23:42:06.000000000 -0400
20860 +++ linux-2.6.18/include/asm-alpha/a.out.h      2006-09-22 20:45:04.000000000 -0400
20861 @@ -98,7 +98,7 @@ struct exec
20862         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
20863                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
20864  
20865 -#define STACK_TOP \
20866 +#define __STACK_TOP \
20867    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
20868  
20869  #endif
20870 diff -urNp linux-2.6.18/include/asm-alpha/elf.h linux-2.6.18/include/asm-alpha/elf.h
20871 --- linux-2.6.18/include/asm-alpha/elf.h        2006-09-19 23:42:06.000000000 -0400
20872 +++ linux-2.6.18/include/asm-alpha/elf.h        2006-09-22 20:45:04.000000000 -0400
20873 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
20874  
20875  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
20876  
20877 +#ifdef CONFIG_PAX_ASLR
20878 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
20879 +
20880 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20881 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
20882 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20883 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
20884 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20885 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
20886 +#endif
20887 +
20888  /* $0 is set by ld.so to a pointer to a function which might be 
20889     registered using atexit.  This provides a mean for the dynamic
20890     linker to call DT_FINI functions for shared libraries that have
20891 diff -urNp linux-2.6.18/include/asm-alpha/kmap_types.h linux-2.6.18/include/asm-alpha/kmap_types.h
20892 --- linux-2.6.18/include/asm-alpha/kmap_types.h 2006-09-19 23:42:06.000000000 -0400
20893 +++ linux-2.6.18/include/asm-alpha/kmap_types.h 2006-09-22 20:45:04.000000000 -0400
20894 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
20895  D(10)  KM_IRQ1,
20896  D(11)  KM_SOFTIRQ0,
20897  D(12)  KM_SOFTIRQ1,
20898 -D(13)  KM_TYPE_NR
20899 +D(13)  KM_CLEARPAGE,
20900 +D(14)  KM_TYPE_NR
20901  };
20902  
20903  #undef D
20904 diff -urNp linux-2.6.18/include/asm-alpha/page.h linux-2.6.18/include/asm-alpha/page.h
20905 --- linux-2.6.18/include/asm-alpha/page.h       2006-09-19 23:42:06.000000000 -0400
20906 +++ linux-2.6.18/include/asm-alpha/page.h       2006-09-22 20:45:04.000000000 -0400
20907 @@ -93,6 +93,15 @@ typedef unsigned long pgprot_t;
20908  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
20909                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20910  
20911 +#ifdef CONFIG_PAX_PAGEEXEC
20912 +#ifdef CONFIG_PAX_MPROTECT
20913 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20914 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20915 +#else
20916 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20917 +#endif
20918 +#endif
20919 +
20920  #include <asm-generic/memory_model.h>
20921  #include <asm-generic/page.h>
20922  
20923 diff -urNp linux-2.6.18/include/asm-alpha/pgtable.h linux-2.6.18/include/asm-alpha/pgtable.h
20924 --- linux-2.6.18/include/asm-alpha/pgtable.h    2006-09-19 23:42:06.000000000 -0400
20925 +++ linux-2.6.18/include/asm-alpha/pgtable.h    2006-09-22 20:45:04.000000000 -0400
20926 @@ -101,6 +101,17 @@ struct vm_area_struct;
20927  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
20928  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
20929  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
20930 +
20931 +#ifdef CONFIG_PAX_PAGEEXEC
20932 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
20933 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
20934 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
20935 +#else
20936 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20937 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20938 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20939 +#endif
20940 +
20941  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
20942  
20943  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
20944 diff -urNp linux-2.6.18/include/asm-arm/a.out.h linux-2.6.18/include/asm-arm/a.out.h
20945 --- linux-2.6.18/include/asm-arm/a.out.h        2006-09-19 23:42:06.000000000 -0400
20946 +++ linux-2.6.18/include/asm-arm/a.out.h        2006-09-22 20:45:04.000000000 -0400
20947 @@ -28,7 +28,7 @@ struct exec
20948  #define M_ARM 103
20949  
20950  #ifdef __KERNEL__
20951 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
20952 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
20953                          TASK_SIZE : TASK_SIZE_26)
20954  #endif
20955  
20956 diff -urNp linux-2.6.18/include/asm-arm/elf.h linux-2.6.18/include/asm-arm/elf.h
20957 --- linux-2.6.18/include/asm-arm/elf.h  2006-09-19 23:42:06.000000000 -0400
20958 +++ linux-2.6.18/include/asm-arm/elf.h  2006-09-22 20:45:04.000000000 -0400
20959 @@ -57,6 +57,17 @@ typedef struct user_fp elf_fpregset_t;
20960  
20961  #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
20962  
20963 +#ifdef CONFIG_PAX_ASLR
20964 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x00008000UL
20965 +
20966 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20967 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
20968 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20969 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
20970 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20971 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
20972 +#endif
20973 +
20974  /* When the program starts, a1 contains a pointer to a function to be 
20975     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
20976     have no such handler.  */
20977 diff -urNp linux-2.6.18/include/asm-arm/kmap_types.h linux-2.6.18/include/asm-arm/kmap_types.h
20978 --- linux-2.6.18/include/asm-arm/kmap_types.h   2006-09-19 23:42:06.000000000 -0400
20979 +++ linux-2.6.18/include/asm-arm/kmap_types.h   2006-09-22 20:45:04.000000000 -0400
20980 @@ -18,6 +18,7 @@ enum km_type {
20981         KM_IRQ1,
20982         KM_SOFTIRQ0,
20983         KM_SOFTIRQ1,
20984 +       KM_CLEARPAGE,
20985         KM_TYPE_NR
20986  };
20987  
20988 diff -urNp linux-2.6.18/include/asm-arm26/kmap_types.h linux-2.6.18/include/asm-arm26/kmap_types.h
20989 --- linux-2.6.18/include/asm-arm26/kmap_types.h 2006-09-19 23:42:06.000000000 -0400
20990 +++ linux-2.6.18/include/asm-arm26/kmap_types.h 2006-09-22 20:45:04.000000000 -0400
20991 @@ -6,7 +6,8 @@
20992   */
20993  enum km_type {
20994          KM_IRQ0,
20995 -        KM_USER1
20996 +        KM_USER1,
20997 +        KM_CLEARPAGE
20998  };
20999  
21000  #endif
21001 diff -urNp linux-2.6.18/include/asm-cris/kmap_types.h linux-2.6.18/include/asm-cris/kmap_types.h
21002 --- linux-2.6.18/include/asm-cris/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
21003 +++ linux-2.6.18/include/asm-cris/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
21004 @@ -19,6 +19,7 @@ enum km_type {
21005         KM_IRQ1,
21006         KM_SOFTIRQ0,
21007         KM_SOFTIRQ1,
21008 +       KM_CLEARPAGE,
21009         KM_TYPE_NR
21010  };
21011  
21012 diff -urNp linux-2.6.18/include/asm-frv/kmap_types.h linux-2.6.18/include/asm-frv/kmap_types.h
21013 --- linux-2.6.18/include/asm-frv/kmap_types.h   2006-09-19 23:42:06.000000000 -0400
21014 +++ linux-2.6.18/include/asm-frv/kmap_types.h   2006-09-22 20:45:04.000000000 -0400
21015 @@ -23,6 +23,7 @@ enum km_type {
21016         KM_IRQ1,
21017         KM_SOFTIRQ0,
21018         KM_SOFTIRQ1,
21019 +       KM_CLEARPAGE,
21020         KM_TYPE_NR
21021  };
21022  
21023 diff -urNp linux-2.6.18/include/asm-h8300/kmap_types.h linux-2.6.18/include/asm-h8300/kmap_types.h
21024 --- linux-2.6.18/include/asm-h8300/kmap_types.h 2006-09-19 23:42:06.000000000 -0400
21025 +++ linux-2.6.18/include/asm-h8300/kmap_types.h 2006-09-22 20:45:04.000000000 -0400
21026 @@ -15,6 +15,7 @@ enum km_type {
21027         KM_IRQ1,
21028         KM_SOFTIRQ0,
21029         KM_SOFTIRQ1,
21030 +       KM_CLEARPAGE,
21031         KM_TYPE_NR
21032  };
21033  
21034 diff -urNp linux-2.6.18/include/asm-i386/alternative.h linux-2.6.18/include/asm-i386/alternative.h
21035 --- linux-2.6.18/include/asm-i386/alternative.h 2006-09-19 23:42:06.000000000 -0400
21036 +++ linux-2.6.18/include/asm-i386/alternative.h 2006-09-22 20:45:04.000000000 -0400
21037 @@ -57,7 +57,7 @@ static inline void alternatives_smp_swit
21038                       "  .byte 662b-661b\n"       /* sourcelen */       \
21039                       "  .byte 664f-663f\n"       /* replacementlen */  \
21040                       ".previous\n"                                     \
21041 -                     ".section .altinstr_replacement,\"ax\"\n"         \
21042 +                     ".section .altinstr_replacement,\"a\"\n"          \
21043                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
21044                       ".previous" :: "i" (feature) : "memory")
21045  
21046 @@ -81,7 +81,7 @@ static inline void alternatives_smp_swit
21047                       "  .byte 662b-661b\n"       /* sourcelen */       \
21048                       "  .byte 664f-663f\n"       /* replacementlen */  \
21049                       ".previous\n"                                     \
21050 -                     ".section .altinstr_replacement,\"ax\"\n"         \
21051 +                     ".section .altinstr_replacement,\"a\"\n"          \
21052                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
21053                       ".previous" :: "i" (feature), ##input)
21054  
21055 diff -urNp linux-2.6.18/include/asm-i386/a.out.h linux-2.6.18/include/asm-i386/a.out.h
21056 --- linux-2.6.18/include/asm-i386/a.out.h       2006-09-19 23:42:06.000000000 -0400
21057 +++ linux-2.6.18/include/asm-i386/a.out.h       2006-09-22 20:45:04.000000000 -0400
21058 @@ -19,7 +19,11 @@ struct exec
21059  
21060  #ifdef __KERNEL__
21061  
21062 -#define STACK_TOP      TASK_SIZE
21063 +#ifdef CONFIG_PAX_SEGMEXEC
21064 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
21065 +#else
21066 +#define __STACK_TOP TASK_SIZE
21067 +#endif
21068  
21069  #endif
21070  
21071 diff -urNp linux-2.6.18/include/asm-i386/apic.h linux-2.6.18/include/asm-i386/apic.h
21072 --- linux-2.6.18/include/asm-i386/apic.h        2006-09-19 23:42:06.000000000 -0400
21073 +++ linux-2.6.18/include/asm-i386/apic.h        2006-09-22 20:45:04.000000000 -0400
21074 @@ -7,7 +7,7 @@
21075  #include <asm/processor.h>
21076  #include <asm/system.h>
21077  
21078 -#define Dprintk(x...)
21079 +#define Dprintk(x...) do {} while (0)
21080  
21081  /*
21082   * Debugging macros
21083 diff -urNp linux-2.6.18/include/asm-i386/bug.h linux-2.6.18/include/asm-i386/bug.h
21084 --- linux-2.6.18/include/asm-i386/bug.h 2006-09-19 23:42:06.000000000 -0400
21085 +++ linux-2.6.18/include/asm-i386/bug.h 2006-09-22 20:45:04.000000000 -0400
21086 @@ -11,10 +11,9 @@
21087  #ifdef CONFIG_BUG
21088  #define HAVE_ARCH_BUG
21089  #ifdef CONFIG_DEBUG_BUGVERBOSE
21090 -#define BUG()                          \
21091 - __asm__ __volatile__( "ud2\n"         \
21092 -                       "\t.word %c0\n" \
21093 -                       "\t.long %c1\n" \
21094 +#define BUG()                                  \
21095 + __asm__ __volatile__( "ud2\n\t"               \
21096 +                       "ljmp %0, %1\n\t"       \
21097                          : : "i" (__LINE__), "i" (__FILE__))
21098  #else
21099  #define BUG() __asm__ __volatile__("ud2\n")
21100 diff -urNp linux-2.6.18/include/asm-i386/checksum.h linux-2.6.18/include/asm-i386/checksum.h
21101 --- linux-2.6.18/include/asm-i386/checksum.h    2006-09-19 23:42:06.000000000 -0400
21102 +++ linux-2.6.18/include/asm-i386/checksum.h    2006-09-22 20:45:04.000000000 -0400
21103 @@ -30,6 +30,12 @@ asmlinkage unsigned int csum_partial(con
21104  asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned char *dst,
21105                                                   int len, int sum, int *src_err_ptr, int *dst_err_ptr);
21106  
21107 +asmlinkage unsigned int csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
21108 +                                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
21109 +
21110 +asmlinkage unsigned int csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
21111 +                                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
21112 +
21113  /*
21114   *     Note: when you get a NULL pointer exception here this means someone
21115   *     passed in an incorrect kernel address to one of these functions.
21116 @@ -49,7 +55,7 @@ unsigned int csum_partial_copy_from_user
21117                                                 int len, int sum, int *err_ptr)
21118  {
21119         might_sleep();
21120 -       return csum_partial_copy_generic((__force unsigned char *)src, dst,
21121 +       return csum_partial_copy_generic_from_user((__force unsigned char *)src, dst,
21122                                         len, sum, err_ptr, NULL);
21123  }
21124  
21125 @@ -183,7 +189,7 @@ static __inline__ unsigned int csum_and_
21126  {
21127         might_sleep();
21128         if (access_ok(VERIFY_WRITE, dst, len))
21129 -               return csum_partial_copy_generic(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
21130 +               return csum_partial_copy_generic_to_user(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
21131  
21132         if (len)
21133                 *err_ptr = -EFAULT;
21134 diff -urNp linux-2.6.18/include/asm-i386/desc.h linux-2.6.18/include/asm-i386/desc.h
21135 --- linux-2.6.18/include/asm-i386/desc.h        2006-09-19 23:42:06.000000000 -0400
21136 +++ linux-2.6.18/include/asm-i386/desc.h        2006-09-22 20:45:04.000000000 -0400
21137 @@ -10,11 +10,13 @@
21138  
21139  #include <linux/preempt.h>
21140  #include <linux/smp.h>
21141 -#include <linux/percpu.h>
21142 +#include <linux/sched.h>
21143  
21144  #include <asm/mmu.h>
21145 +#include <asm/pgtable.h>
21146 +#include <asm/tlbflush.h>
21147  
21148 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
21149 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
21150  
21151  DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
21152  
21153 @@ -24,13 +26,53 @@ struct Xgt_desc_struct {
21154         unsigned short pad;
21155  } __attribute__ ((packed));
21156  
21157 -extern struct Xgt_desc_struct idt_descr;
21158 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
21159 -
21160 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
21161  
21162  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
21163  {
21164 -       return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
21165 +       return cpu_gdt_table[cpu];
21166 +}
21167 +
21168 +#define pax_open_kernel(cr0)           \
21169 +do {                                   \
21170 +       typecheck(unsigned long,cr0);   \
21171 +       preempt_disable();              \
21172 +       cr0 = read_cr0();               \
21173 +       write_cr0(cr0 & ~0x10000UL);    \
21174 +} while(0)
21175 +
21176 +#define pax_close_kernel(cr0)          \
21177 +do {                                   \
21178 +       typecheck(unsigned long,cr0);   \
21179 +       write_cr0(cr0);                 \
21180 +       preempt_enable_no_resched();    \
21181 +} while(0)
21182 +
21183 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
21184 +{
21185 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21186 +       unsigned long base = mm->context.user_cs_base;
21187 +       unsigned long limit = mm->context.user_cs_limit;
21188 +
21189 +#ifdef CONFIG_PAX_KERNEXEC
21190 +       unsigned long cr0;
21191 +
21192 +       pax_open_kernel(cr0);
21193 +#endif
21194 +
21195 +       if (likely(limit)) {
21196 +               limit -= 1UL;
21197 +               limit >>= 12;
21198 +       }
21199 +
21200 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
21201 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
21202 +
21203 +#ifdef CONFIG_PAX_KERNEXEC
21204 +       pax_close_kernel(cr0);
21205 +#endif
21206 +
21207 +#endif
21208  }
21209  
21210  #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
21211 @@ -50,7 +92,7 @@ static inline struct desc_struct *get_cp
21212   * This is the ldt that every process will get unless we need
21213   * something other than this.
21214   */
21215 -extern struct desc_struct default_ldt[];
21216 +extern const struct desc_struct default_ldt[];
21217  extern void set_intr_gate(unsigned int irq, void * addr);
21218  
21219  #define _set_tssldt_desc(n,addr,limit,type) \
21220 @@ -64,7 +106,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
21221         "rorl $16,%1" \
21222         : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
21223  
21224 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
21225 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
21226  {
21227         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
21228                 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
21229 @@ -72,11 +114,28 @@ static inline void __set_tss_desc(unsign
21230  
21231  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
21232  
21233 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
21234 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
21235  {
21236         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
21237  }
21238  
21239 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
21240 +{
21241 +
21242 +#ifdef CONFIG_PAX_KERNEXEC
21243 +       unsigned long cr0;
21244 +
21245 +       pax_open_kernel(cr0);
21246 +#endif
21247 +
21248 +       _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
21249 +
21250 +#ifdef CONFIG_PAX_KERNEXEC
21251 +       pax_close_kernel(cr0);
21252 +#endif
21253 +
21254 +}
21255 +
21256  #define LDT_entry_a(info) \
21257         ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
21258  
21259 @@ -90,7 +149,7 @@ static inline void set_ldt_desc(unsigned
21260         ((info)->seg_32bit << 22) | \
21261         ((info)->limit_in_pages << 23) | \
21262         ((info)->useable << 20) | \
21263 -       0x7000)
21264 +       0x7100)
21265  
21266  #define LDT_empty(info) (\
21267         (info)->base_addr       == 0    && \
21268 @@ -134,7 +193,7 @@ static inline void clear_LDT(void)
21269   */
21270  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
21271  {
21272 -       void *segments = pc->ldt;
21273 +       const void *segments = pc->ldt;
21274         int count = pc->size;
21275  
21276         if (likely(!count)) {
21277 @@ -162,6 +221,22 @@ static inline unsigned long get_desc_bas
21278         return base;
21279  }
21280  
21281 +static inline void _load_LDT(mm_context_t *pc)
21282 +{
21283 +       int cpu = get_cpu();
21284 +       const void *segments = pc->ldt;
21285 +       int count = pc->size;
21286 +
21287 +       if (likely(!count)) {
21288 +               segments = &default_ldt[0];
21289 +               count = 5;
21290 +       }
21291 +               
21292 +       __set_ldt_desc(cpu, segments, count);
21293 +       load_LDT_desc();
21294 +       put_cpu();
21295 +}
21296 +
21297  #endif /* !__ASSEMBLY__ */
21298  
21299  #endif
21300 diff -urNp linux-2.6.18/include/asm-i386/elf.h linux-2.6.18/include/asm-i386/elf.h
21301 --- linux-2.6.18/include/asm-i386/elf.h 2006-09-19 23:42:06.000000000 -0400
21302 +++ linux-2.6.18/include/asm-i386/elf.h 2006-09-22 20:45:04.000000000 -0400
21303 @@ -75,7 +75,22 @@ typedef struct user_fxsr_struct elf_fpxr
21304     the loader.  We need to make sure that it is out of the way of the program
21305     that it will "exec", and that there is sufficient room for the brk.  */
21306  
21307 +#ifdef CONFIG_PAX_SEGMEXEC
21308 +#define ELF_ET_DYN_BASE                ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
21309 +#else
21310  #define ELF_ET_DYN_BASE                ((TASK_UNMAPPED_BASE) * 2)
21311 +#endif
21312 +
21313 +#ifdef CONFIG_PAX_ASLR
21314 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
21315 +
21316 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
21317 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
21318 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
21319 +#define PAX_DELTA_EXEC_LEN(tsk)                15
21320 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
21321 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
21322 +#endif
21323  
21324  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
21325     now struct_user_regs, they are different) */
21326 diff -urNp linux-2.6.18/include/asm-i386/i387.h linux-2.6.18/include/asm-i386/i387.h
21327 --- linux-2.6.18/include/asm-i386/i387.h        2006-09-19 23:42:06.000000000 -0400
21328 +++ linux-2.6.18/include/asm-i386/i387.h        2006-09-22 20:45:04.000000000 -0400
21329 @@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
21330  #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
21331  
21332  /* We need a safe address that is cheap to find and that is already
21333 -   in L1 during context switch. The best choices are unfortunately
21334 -   different for UP and SMP */
21335 -#ifdef CONFIG_SMP
21336 -#define safe_address (__per_cpu_offset[0])
21337 -#else
21338 -#define safe_address (kstat_cpu(0).cpustat.user)
21339 -#endif
21340 +   in L1 during context switch. */
21341 +#define safe_address (init_tss[smp_processor_id()].esp0)
21342  
21343  /*
21344   * These must be called with preempt disabled
21345 diff -urNp linux-2.6.18/include/asm-i386/kmap_types.h linux-2.6.18/include/asm-i386/kmap_types.h
21346 --- linux-2.6.18/include/asm-i386/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
21347 +++ linux-2.6.18/include/asm-i386/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
21348 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
21349  D(10)  KM_IRQ1,
21350  D(11)  KM_SOFTIRQ0,
21351  D(12)  KM_SOFTIRQ1,
21352 -D(13)  KM_TYPE_NR
21353 +D(13)  KM_CLEARPAGE,
21354 +D(14)  KM_TYPE_NR
21355  };
21356  
21357  #undef D
21358 diff -urNp linux-2.6.18/include/asm-i386/mach-default/apm.h linux-2.6.18/include/asm-i386/mach-default/apm.h
21359 --- linux-2.6.18/include/asm-i386/mach-default/apm.h    2006-09-19 23:42:06.000000000 -0400
21360 +++ linux-2.6.18/include/asm-i386/mach-default/apm.h    2006-09-22 20:45:04.000000000 -0400
21361 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
21362         __asm__ __volatile__(APM_DO_ZERO_SEGS
21363                 "pushl %%edi\n\t"
21364                 "pushl %%ebp\n\t"
21365 -               "lcall *%%cs:apm_bios_entry\n\t"
21366 +               "lcall *%%ss:apm_bios_entry\n\t"
21367                 "setc %%al\n\t"
21368                 "popl %%ebp\n\t"
21369                 "popl %%edi\n\t"
21370 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
21371         __asm__ __volatile__(APM_DO_ZERO_SEGS
21372                 "pushl %%edi\n\t"
21373                 "pushl %%ebp\n\t"
21374 -               "lcall *%%cs:apm_bios_entry\n\t"
21375 +               "lcall *%%ss:apm_bios_entry\n\t"
21376                 "setc %%bl\n\t"
21377                 "popl %%ebp\n\t"
21378                 "popl %%edi\n\t"
21379 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
21380 --- linux-2.6.18/include/asm-i386/mach-default/do_timer.h       2006-09-19 23:42:06.000000000 -0400
21381 +++ linux-2.6.18/include/asm-i386/mach-default/do_timer.h       2006-09-22 20:45:04.000000000 -0400
21382 @@ -18,7 +18,7 @@ static inline void do_timer_interrupt_ho
21383  {
21384         do_timer(regs);
21385  #ifndef CONFIG_SMP
21386 -       update_process_times(user_mode_vm(regs));
21387 +       update_process_times(user_mode(regs));
21388  #endif
21389  /*
21390   * In the SMP case we use the local APIC timer interrupt to do the
21391 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
21392 --- linux-2.6.18/include/asm-i386/mach-visws/do_timer.h 2006-09-19 23:42:06.000000000 -0400
21393 +++ linux-2.6.18/include/asm-i386/mach-visws/do_timer.h 2006-09-22 20:45:04.000000000 -0400
21394 @@ -11,7 +11,7 @@ static inline void do_timer_interrupt_ho
21395  
21396         do_timer(regs);
21397  #ifndef CONFIG_SMP
21398 -       update_process_times(user_mode_vm(regs));
21399 +       update_process_times(user_mode(regs));
21400  #endif
21401  /*
21402   * In the SMP case we use the local APIC timer interrupt to do the
21403 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
21404 --- linux-2.6.18/include/asm-i386/mach-voyager/do_timer.h       2006-09-19 23:42:06.000000000 -0400
21405 +++ linux-2.6.18/include/asm-i386/mach-voyager/do_timer.h       2006-09-22 20:45:04.000000000 -0400
21406 @@ -5,7 +5,7 @@ static inline void do_timer_interrupt_ho
21407  {
21408         do_timer(regs);
21409  #ifndef CONFIG_SMP
21410 -       update_process_times(user_mode_vm(regs));
21411 +       update_process_times(user_mode(regs));
21412  #endif
21413  
21414         voyager_timer_interrupt(regs);
21415 diff -urNp linux-2.6.18/include/asm-i386/mman.h linux-2.6.18/include/asm-i386/mman.h
21416 --- linux-2.6.18/include/asm-i386/mman.h        2006-09-19 23:42:06.000000000 -0400
21417 +++ linux-2.6.18/include/asm-i386/mman.h        2006-09-22 20:45:04.000000000 -0400
21418 @@ -11,6 +11,10 @@
21419  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
21420  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
21421  
21422 +#ifdef CONFIG_PAX_SEGMEXEC
21423 +#define MAP_MIRROR     0x20000
21424 +#endif
21425 +
21426  #define MCL_CURRENT    1               /* lock all current mappings */
21427  #define MCL_FUTURE     2               /* lock all future mappings */
21428  
21429 diff -urNp linux-2.6.18/include/asm-i386/mmu_context.h linux-2.6.18/include/asm-i386/mmu_context.h
21430 --- linux-2.6.18/include/asm-i386/mmu_context.h 2006-09-19 23:42:06.000000000 -0400
21431 +++ linux-2.6.18/include/asm-i386/mmu_context.h 2006-09-22 23:33:51.000000000 -0400
21432 @@ -45,6 +45,17 @@ static inline void switch_mm(struct mm_s
21433                  */
21434                 if (unlikely(prev->context.ldt != next->context.ldt))
21435                         load_LDT_nolock(&next->context, cpu);
21436 +
21437 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
21438 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
21439 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
21440 +#endif
21441 +
21442 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21443 +               if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
21444 +                            prev->context.user_cs_limit != next->context.user_cs_limit))
21445 +#endif
21446 +                       set_user_cs(next, cpu);
21447         }
21448  #ifdef CONFIG_SMP
21449         else {
21450 @@ -57,6 +68,12 @@ static inline void switch_mm(struct mm_s
21451                          */
21452                         load_cr3(next->pgd);
21453                         load_LDT_nolock(&next->context, cpu);
21454 +
21455 +#ifdef CONFIG_PAX_PAGEEXEC
21456 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
21457 +#endif
21458 +
21459 +                       set_user_cs(next, cpu);
21460                 }
21461         }
21462  #endif
21463 diff -urNp linux-2.6.18/include/asm-i386/mmu.h linux-2.6.18/include/asm-i386/mmu.h
21464 --- linux-2.6.18/include/asm-i386/mmu.h 2006-09-19 23:42:06.000000000 -0400
21465 +++ linux-2.6.18/include/asm-i386/mmu.h 2006-09-22 20:45:04.000000000 -0400
21466 @@ -13,6 +13,17 @@ typedef struct { 
21467         struct semaphore sem;
21468         void *ldt;
21469         void *vdso;
21470 +
21471 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21472 +       unsigned long user_cs_base;
21473 +       unsigned long user_cs_limit;
21474 +
21475 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
21476 +       cpumask_t cpu_user_cs_mask;
21477 +#endif
21478 +
21479 +#endif
21480 +
21481  } mm_context_t;
21482  
21483  #endif
21484 diff -urNp linux-2.6.18/include/asm-i386/module.h linux-2.6.18/include/asm-i386/module.h
21485 --- linux-2.6.18/include/asm-i386/module.h      2006-09-19 23:42:06.000000000 -0400
21486 +++ linux-2.6.18/include/asm-i386/module.h      2006-09-22 20:04:35.000000000 -0400
21487 @@ -72,6 +72,12 @@ struct mod_arch_specific
21488  #define MODULE_STACKSIZE ""
21489  #endif
21490  
21491 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
21492 +#ifdef CONFIG_GRKERNSEC
21493 +#define MODULE_GRSEC "GRSECURITY "
21494 +#else
21495 +#define MODULE_GRSEC ""
21496 +#endif
21497 +
21498 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
21499  
21500  #endif /* _ASM_I386_MODULE_H */
21501 diff -urNp linux-2.6.18/include/asm-i386/page.h linux-2.6.18/include/asm-i386/page.h
21502 --- linux-2.6.18/include/asm-i386/page.h        2006-09-19 23:42:06.000000000 -0400
21503 +++ linux-2.6.18/include/asm-i386/page.h        2006-09-22 20:45:04.000000000 -0400
21504 @@ -51,13 +51,14 @@ typedef struct { unsigned long long pgpr
21505  #define pmd_val(x)     ((x).pmd)
21506  #define pte_val(x)     ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
21507  #define __pmd(x) ((pmd_t) { (x) } )
21508 +#define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
21509  #define HPAGE_SHIFT    21
21510  #else
21511  typedef struct { unsigned long pte_low; } pte_t;
21512  typedef struct { unsigned long pgd; } pgd_t;
21513  typedef struct { unsigned long pgprot; } pgprot_t;
21514 -#define boot_pte_t pte_t /* or would you rather have a typedef */
21515  #define pte_val(x)     ((x).pte_low)
21516 +#define __pte(x) ((pte_t) { (x) } )
21517  #define HPAGE_SHIFT    22
21518  #endif
21519  #define PTE_MASK       PAGE_MASK
21520 @@ -72,7 +73,6 @@ typedef struct { unsigned long pgprot; }
21521  #define pgd_val(x)     ((x).pgd)
21522  #define pgprot_val(x)  ((x).pgprot)
21523  
21524 -#define __pte(x) ((pte_t) { (x) } )
21525  #define __pgd(x) ((pgd_t) { (x) } )
21526  #define __pgprot(x)    ((pgprot_t) { (x) } )
21527  
21528 @@ -119,6 +119,15 @@ extern int page_is_ram(unsigned long pag
21529  #endif
21530  #define __KERNEL_START         (__PAGE_OFFSET + __PHYSICAL_START)
21531  
21532 +#ifdef CONFIG_PAX_KERNEXEC
21533 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + ((__PHYSICAL_START + ~(4*1024*1024)) & (4*1024*1024)))
21534 +#ifndef __ASSEMBLY__
21535 +extern unsigned char MODULES_VADDR[];
21536 +extern unsigned char MODULES_END[];
21537 +#endif
21538 +#else
21539 +#define __KERNEL_TEXT_OFFSET   (0)
21540 +#endif
21541  
21542  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
21543  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
21544 @@ -138,6 +147,19 @@ extern int page_is_ram(unsigned long pag
21545         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
21546                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21547  
21548 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21549 +#ifdef CONFIG_PAX_MPROTECT
21550 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21551 +                         ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
21552 +#else
21553 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
21554 +#endif
21555 +#endif
21556 +
21557 +#ifdef CONFIG_PAX_PAGEEXEC
21558 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
21559 +#endif
21560 +
21561  #include <asm-generic/memory_model.h>
21562  #include <asm-generic/page.h>
21563  
21564 diff -urNp linux-2.6.18/include/asm-i386/pgalloc.h linux-2.6.18/include/asm-i386/pgalloc.h
21565 --- linux-2.6.18/include/asm-i386/pgalloc.h     2006-09-19 23:42:06.000000000 -0400
21566 +++ linux-2.6.18/include/asm-i386/pgalloc.h     2006-09-22 20:45:04.000000000 -0400
21567 @@ -2,11 +2,17 @@
21568  #define _I386_PGALLOC_H
21569  
21570  #include <asm/fixmap.h>
21571 +#include <asm/desc.h>
21572  #include <linux/threads.h>
21573  #include <linux/mm.h>          /* for struct page */
21574  
21575 +#ifdef CONFIG_COMPAT_VDSO
21576  #define pmd_populate_kernel(mm, pmd, pte) \
21577                 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
21578 +#else
21579 +#define pmd_populate_kernel(mm, pmd, pte) \
21580 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
21581 +#endif
21582  
21583  #define pmd_populate(mm, pmd, pte)                             \
21584         set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
21585 diff -urNp linux-2.6.18/include/asm-i386/pgtable.h linux-2.6.18/include/asm-i386/pgtable.h
21586 --- linux-2.6.18/include/asm-i386/pgtable.h     2006-09-19 23:42:06.000000000 -0400
21587 +++ linux-2.6.18/include/asm-i386/pgtable.h     2006-09-22 20:45:04.000000000 -0400
21588 @@ -33,7 +33,6 @@ struct vm_area_struct;
21589   */
21590  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
21591  extern unsigned long empty_zero_page[1024];
21592 -extern pgd_t swapper_pg_dir[1024];
21593  extern kmem_cache_t *pgd_cache;
21594  extern kmem_cache_t *pmd_cache;
21595  extern spinlock_t pgd_lock;
21596 @@ -58,6 +57,11 @@ void paging_init(void);
21597  # include <asm/pgtable-2level-defs.h>
21598  #endif
21599  
21600 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
21601 +#ifdef CONFIG_X86_PAE
21602 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
21603 +#endif
21604 +
21605  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
21606  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
21607  
21608 @@ -67,9 +71,11 @@ void paging_init(void);
21609  #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
21610  #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
21611  
21612 +#ifndef CONFIG_X86_PAE
21613  #define TWOLEVEL_PGDIR_SHIFT   22
21614  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
21615  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
21616 +#endif
21617  
21618  /* Just any arbitrary offset to the start of the vmalloc VM area: the
21619   * current 8MB value just means that there will be a 8MB "hole" after the
21620 @@ -140,17 +146,26 @@ void paging_init(void);
21621  
21622  #define PAGE_SHARED_EXEC \
21623         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
21624 -#define PAGE_COPY_NOEXEC \
21625 -       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21626  #define PAGE_COPY_EXEC \
21627         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
21628 -#define PAGE_COPY \
21629 -       PAGE_COPY_NOEXEC
21630  #define PAGE_READONLY \
21631         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21632  #define PAGE_READONLY_EXEC \
21633         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
21634  
21635 +#ifdef CONFIG_PAX_PAGEEXEC
21636 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
21637 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
21638 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
21639 +#else
21640 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
21641 +# define PAGE_COPY_NOEXEC \
21642 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21643 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
21644 +#endif
21645 +
21646 +#define PAGE_COPY \
21647 +       PAGE_COPY_NOEXEC
21648  #define _PAGE_KERNEL \
21649         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
21650  #define _PAGE_KERNEL_EXEC \
21651 @@ -175,18 +190,18 @@ extern unsigned long long __PAGE_KERNEL,
21652   * This is the closest we can get..
21653   */
21654  #define __P000 PAGE_NONE
21655 -#define __P001 PAGE_READONLY
21656 -#define __P010 PAGE_COPY
21657 -#define __P011 PAGE_COPY
21658 +#define __P001 PAGE_READONLY_NOEXEC
21659 +#define __P010 PAGE_COPY_NOEXEC
21660 +#define __P011 PAGE_COPY_NOEXEC
21661  #define __P100 PAGE_READONLY_EXEC
21662  #define __P101 PAGE_READONLY_EXEC
21663  #define __P110 PAGE_COPY_EXEC
21664  #define __P111 PAGE_COPY_EXEC
21665  
21666  #define __S000 PAGE_NONE
21667 -#define __S001 PAGE_READONLY
21668 -#define __S010 PAGE_SHARED
21669 -#define __S011 PAGE_SHARED
21670 +#define __S001 PAGE_READONLY_NOEXEC
21671 +#define __S010 PAGE_SHARED_NOEXEC
21672 +#define __S011 PAGE_SHARED_NOEXEC
21673  #define __S100 PAGE_READONLY_EXEC
21674  #define __S101 PAGE_READONLY_EXEC
21675  #define __S110 PAGE_SHARED_EXEC
21676 @@ -430,6 +445,9 @@ extern void noexec_setup(const char *str
21677  
21678  #endif /* !__ASSEMBLY__ */
21679  
21680 +#define HAVE_ARCH_UNMAPPED_AREA
21681 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
21682 +
21683  #ifdef CONFIG_FLATMEM
21684  #define kern_addr_valid(addr)  (1)
21685  #endif /* CONFIG_FLATMEM */
21686 diff -urNp linux-2.6.18/include/asm-i386/processor.h linux-2.6.18/include/asm-i386/processor.h
21687 --- linux-2.6.18/include/asm-i386/processor.h   2006-09-19 23:42:06.000000000 -0400
21688 +++ linux-2.6.18/include/asm-i386/processor.h   2006-09-22 20:45:04.000000000 -0400
21689 @@ -18,7 +18,6 @@
21690  #include <asm/system.h>
21691  #include <linux/cache.h>
21692  #include <linux/threads.h>
21693 -#include <asm/percpu.h>
21694  #include <linux/cpumask.h>
21695  
21696  /* flag for disabling the tsc */
21697 @@ -97,8 +96,6 @@ struct cpuinfo_x86 {
21698  
21699  extern struct cpuinfo_x86 boot_cpu_data;
21700  extern struct cpuinfo_x86 new_cpu_data;
21701 -extern struct tss_struct doublefault_tss;
21702 -DECLARE_PER_CPU(struct tss_struct, init_tss);
21703  
21704  #ifdef CONFIG_SMP
21705  extern struct cpuinfo_x86 cpu_data[];
21706 @@ -327,10 +324,19 @@ extern int bootloader_type;
21707   */
21708  #define TASK_SIZE      (PAGE_OFFSET)
21709  
21710 +#ifdef CONFIG_PAX_SEGMEXEC
21711 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
21712 +#endif
21713 +
21714  /* This decides where the kernel will search for a free chunk of vm
21715   * space during mmap's.
21716   */
21717 +
21718 +#ifdef CONFIG_PAX_SEGMEXEC
21719 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
21720 +#else
21721  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
21722 +#endif
21723  
21724  #define HAVE_ARCH_PICK_MMAP_LAYOUT
21725  
21726 @@ -446,6 +452,9 @@ struct tss_struct {
21727  
21728  #define ARCH_MIN_TASKALIGN     16
21729  
21730 +extern struct tss_struct doublefault_tss;
21731 +extern struct tss_struct init_tss[NR_CPUS];
21732 +
21733  struct thread_struct {
21734  /* cached TLS descriptors. */
21735         struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
21736 @@ -474,6 +483,7 @@ struct thread_struct {
21737  };
21738  
21739  #define INIT_THREAD  {                                                 \
21740 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
21741         .vm86_info = NULL,                                              \
21742         .sysenter_cs = __KERNEL_CS,                                     \
21743         .io_bitmap_ptr = NULL,                                          \
21744 @@ -486,7 +496,7 @@ struct thread_struct {
21745   * be within the limit.
21746   */
21747  #define INIT_TSS  {                                                    \
21748 -       .esp0           = sizeof(init_stack) + (long)&init_stack,       \
21749 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
21750         .ss0            = __KERNEL_DS,                                  \
21751         .ss1            = __KERNEL_CS,                                  \
21752         .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,                     \
21753 @@ -562,11 +572,7 @@ void show_trace(struct task_struct *task
21754  unsigned long get_wchan(struct task_struct *p);
21755  
21756  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
21757 -#define KSTK_TOP(info)                                                 \
21758 -({                                                                     \
21759 -       unsigned long *__ptr = (unsigned long *)(info);                 \
21760 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
21761 -})
21762 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
21763  
21764  /*
21765   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
21766 @@ -581,7 +587,7 @@ unsigned long get_wchan(struct task_stru
21767  #define task_pt_regs(task)                                             \
21768  ({                                                                     \
21769         struct pt_regs *__regs__;                                       \
21770 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
21771 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
21772         __regs__ - 1;                                                   \
21773  })
21774  
21775 diff -urNp linux-2.6.18/include/asm-i386/ptrace.h linux-2.6.18/include/asm-i386/ptrace.h
21776 --- linux-2.6.18/include/asm-i386/ptrace.h      2006-09-19 23:42:06.000000000 -0400
21777 +++ linux-2.6.18/include/asm-i386/ptrace.h      2006-09-22 20:45:04.000000000 -0400
21778 @@ -65,17 +65,18 @@ struct task_struct;
21779  extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
21780  
21781  /*
21782 - * user_mode_vm(regs) determines whether a register set came from user mode.
21783 + * user_mode(regs) determines whether a register set came from user mode.
21784   * This is true if V8086 mode was enabled OR if the register set was from
21785   * protected mode with RPL-3 CS value.  This tricky test checks that with
21786   * one comparison.  Many places in the kernel can bypass this full check
21787 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
21788 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
21789 + * be used.
21790   */
21791 -static inline int user_mode(struct pt_regs *regs)
21792 +static inline int user_mode_novm(struct pt_regs *regs)
21793  {
21794         return (regs->xcs & 3) != 0;
21795  }
21796 -static inline int user_mode_vm(struct pt_regs *regs)
21797 +static inline int user_mode(struct pt_regs *regs)
21798  {
21799         return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
21800  }
21801 diff -urNp linux-2.6.18/include/asm-i386/system.h linux-2.6.18/include/asm-i386/system.h
21802 --- linux-2.6.18/include/asm-i386/system.h      2006-09-19 23:42:06.000000000 -0400
21803 +++ linux-2.6.18/include/asm-i386/system.h      2006-09-22 20:45:04.000000000 -0400
21804 @@ -4,6 +4,7 @@
21805  #include <linux/kernel.h>
21806  #include <asm/segment.h>
21807  #include <asm/cpufeature.h>
21808 +#include <asm/page.h>
21809  #include <linux/bitops.h> /* for LOCK_PREFIX */
21810  
21811  #ifdef __KERNEL__
21812 @@ -155,7 +156,7 @@ static inline unsigned long get_limit(un
21813         unsigned long __limit;
21814         __asm__("lsll %1,%0"
21815                 :"=r" (__limit):"r" (segment));
21816 -       return __limit+1;
21817 +       return __limit;
21818  }
21819  
21820  #define nop() __asm__ __volatile__ ("nop")
21821 @@ -480,7 +481,7 @@ static inline void sched_cacheflush(void
21822         wbinvd();
21823  }
21824  
21825 -extern unsigned long arch_align_stack(unsigned long sp);
21826 +#define arch_align_stack(x) (x)
21827  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
21828  
21829  void default_idle(void);
21830 diff -urNp linux-2.6.18/include/asm-i386/uaccess.h linux-2.6.18/include/asm-i386/uaccess.h
21831 --- linux-2.6.18/include/asm-i386/uaccess.h     2006-09-19 23:42:06.000000000 -0400
21832 +++ linux-2.6.18/include/asm-i386/uaccess.h     2006-09-22 20:45:04.000000000 -0400
21833 @@ -9,6 +9,8 @@
21834  #include <linux/prefetch.h>
21835  #include <linux/string.h>
21836  #include <asm/page.h>
21837 +#include <asm/segment.h>
21838 +#include <asm/desc.h>
21839  
21840  #define VERIFY_READ 0
21841  #define VERIFY_WRITE 1
21842 @@ -29,7 +31,8 @@
21843  
21844  #define get_ds()       (KERNEL_DS)
21845  #define get_fs()       (current_thread_info()->addr_limit)
21846 -#define set_fs(x)      (current_thread_info()->addr_limit = (x))
21847 +void __set_fs(mm_segment_t x, int cpu);
21848 +void set_fs(mm_segment_t x);
21849  
21850  #define segment_eq(a,b)        ((a).seg == (b).seg)
21851  
21852 @@ -280,9 +283,12 @@ extern void __put_user_8(void);
21853  
21854  #define __put_user_u64(x, addr, err)                           \
21855         __asm__ __volatile__(                                   \
21856 -               "1:     movl %%eax,0(%2)\n"                     \
21857 -               "2:     movl %%edx,4(%2)\n"                     \
21858 +               "       movw %w5,%%ds\n"                        \
21859 +               "1:     movl %%eax,%%ds:0(%2)\n"                \
21860 +               "2:     movl %%edx,%%ds:4(%2)\n"                \
21861                 "3:\n"                                          \
21862 +               "       pushl %%ss\n"                           \
21863 +               "       popl %%ds\n"                            \
21864                 ".section .fixup,\"ax\"\n"                      \
21865                 "4:     movl %3,%0\n"                           \
21866                 "       jmp 3b\n"                               \
21867 @@ -293,7 +299,8 @@ extern void __put_user_8(void);
21868                 "       .long 2b,4b\n"                          \
21869                 ".previous"                                     \
21870                 : "=r"(err)                                     \
21871 -               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
21872 +               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err),  \
21873 +                 "r"(__USER_DS))
21874  
21875  #ifdef CONFIG_X86_WP_WORKS_OK
21876  
21877 @@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
21878   */
21879  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
21880         __asm__ __volatile__(                                           \
21881 -               "1:     mov"itype" %"rtype"1,%2\n"                      \
21882 +               "       movw %w5,%%ds\n"                                \
21883 +               "1:     mov"itype" %"rtype"1,%%ds:%2\n"                 \
21884                 "2:\n"                                                  \
21885 +               "       pushl %%ss\n"                                   \
21886 +               "       popl %%ds\n"                                    \
21887                 ".section .fixup,\"ax\"\n"                              \
21888                 "3:     movl %3,%0\n"                                   \
21889                 "       jmp 2b\n"                                       \
21890 @@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
21891                 "       .long 1b,3b\n"                                  \
21892                 ".previous"                                             \
21893                 : "=r"(err)                                             \
21894 -               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
21895 +               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err),     \
21896 +                 "r"(__USER_DS))
21897  
21898  
21899  #define __get_user_nocheck(x,ptr,size)                         \
21900 @@ -371,8 +382,11 @@ do {                                                                       \
21901  
21902  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
21903         __asm__ __volatile__(                                           \
21904 -               "1:     mov"itype" %2,%"rtype"1\n"                      \
21905 +               "       movw %w5,%%ds\n"                                \
21906 +               "1:     mov"itype" %%ds:%2,%"rtype"1\n"                 \
21907                 "2:\n"                                                  \
21908 +               "       pushl %%ss\n"                                   \
21909 +               "       popl %%ds\n"                                    \
21910                 ".section .fixup,\"ax\"\n"                              \
21911                 "3:     movl %3,%0\n"                                   \
21912                 "       xor"itype" %"rtype"1,%"rtype"1\n"               \
21913 @@ -383,7 +397,7 @@ do {                                                                        \
21914                 "       .long 1b,3b\n"                                  \
21915                 ".previous"                                             \
21916                 : "=r"(err), ltype (x)                                  \
21917 -               : "m"(__m(addr)), "i"(errret), "0"(err))
21918 +               : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
21919  
21920  
21921  unsigned long __must_check __copy_to_user_ll(void __user *to,
21922 diff -urNp linux-2.6.18/include/asm-i386/unwind.h linux-2.6.18/include/asm-i386/unwind.h
21923 --- linux-2.6.18/include/asm-i386/unwind.h      2006-09-19 23:42:06.000000000 -0400
21924 +++ linux-2.6.18/include/asm-i386/unwind.h      2006-09-22 20:45:04.000000000 -0400
21925 @@ -45,7 +45,7 @@ struct unwind_frame_info
21926  static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
21927                                              /*const*/ struct pt_regs *regs)
21928  {
21929 -       if (user_mode_vm(regs))
21930 +       if (user_mode(regs))
21931                 info->regs = *regs;
21932         else {
21933                 memcpy(&info->regs, regs, offsetof(struct pt_regs, esp));
21934 @@ -62,8 +62,8 @@ static inline void arch_unw_init_blocked
21935         __get_user(info->regs.ebp, (long *)info->task->thread.esp);
21936         info->regs.esp = info->task->thread.esp;
21937         info->regs.xss = __KERNEL_DS;
21938 -       info->regs.xds = __USER_DS;
21939 -       info->regs.xes = __USER_DS;
21940 +       info->regs.xds = __KERNEL_DS;
21941 +       info->regs.xes = __KERNEL_DS;
21942  }
21943  
21944  extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,
21945 @@ -75,9 +75,9 @@ static inline int arch_unw_user_mode(con
21946  {
21947  #if 0 /* This can only work when selector register and EFLAGS saves/restores
21948           are properly annotated (and tracked in UNW_REGISTER_INFO). */
21949 -       return user_mode_vm(&info->regs);
21950 +       return user_mode(&info->regs);
21951  #else
21952 -       return info->regs.eip < PAGE_OFFSET
21953 +       return (info->regs.eip < PAGE_OFFSET && (info->regs.xcs & 0xFFFF) != __KERNEL_CS)
21954                || (info->regs.eip >= __fix_to_virt(FIX_VDSO)
21955                     && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE)
21956                || info->regs.esp < PAGE_OFFSET;
21957 diff -urNp linux-2.6.18/include/asm-ia64/elf.h linux-2.6.18/include/asm-ia64/elf.h
21958 --- linux-2.6.18/include/asm-ia64/elf.h 2006-09-19 23:42:06.000000000 -0400
21959 +++ linux-2.6.18/include/asm-ia64/elf.h 2006-09-22 20:45:04.000000000 -0400
21960 @@ -162,6 +162,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
21961  typedef struct ia64_fpreg elf_fpreg_t;
21962  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
21963  
21964 +#ifdef CONFIG_PAX_ASLR
21965 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
21966 +
21967 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
21968 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
21969 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
21970 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
21971 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
21972 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
21973 +#endif
21974  
21975  
21976  struct pt_regs;        /* forward declaration... */
21977 diff -urNp linux-2.6.18/include/asm-ia64/kmap_types.h linux-2.6.18/include/asm-ia64/kmap_types.h
21978 --- linux-2.6.18/include/asm-ia64/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
21979 +++ linux-2.6.18/include/asm-ia64/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
21980 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
21981  D(10)  KM_IRQ1,
21982  D(11)  KM_SOFTIRQ0,
21983  D(12)  KM_SOFTIRQ1,
21984 -D(13)  KM_TYPE_NR
21985 +D(13)  KM_CLEARPAGE,
21986 +D(14)  KM_TYPE_NR
21987  };
21988  
21989  #undef D
21990 diff -urNp linux-2.6.18/include/asm-ia64/page.h linux-2.6.18/include/asm-ia64/page.h
21991 --- linux-2.6.18/include/asm-ia64/page.h        2006-09-19 23:42:06.000000000 -0400
21992 +++ linux-2.6.18/include/asm-ia64/page.h        2006-09-22 20:45:04.000000000 -0400
21993 @@ -227,5 +227,14 @@ get_order (unsigned long size)
21994                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
21995                                           ? VM_EXEC : 0))
21996  
21997 +#ifdef CONFIG_PAX_PAGEEXEC
21998 +#ifdef CONFIG_PAX_MPROTECT
21999 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22000 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22001 +#else
22002 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22003 +#endif
22004 +#endif
22005 +
22006  # endif /* __KERNEL__ */
22007  #endif /* _ASM_IA64_PAGE_H */
22008 diff -urNp linux-2.6.18/include/asm-ia64/pgtable.h linux-2.6.18/include/asm-ia64/pgtable.h
22009 --- linux-2.6.18/include/asm-ia64/pgtable.h     2006-09-19 23:42:06.000000000 -0400
22010 +++ linux-2.6.18/include/asm-ia64/pgtable.h     2006-09-22 20:45:04.000000000 -0400
22011 @@ -143,6 +143,17 @@
22012  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
22013  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
22014  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
22015 +
22016 +#ifdef CONFIG_PAX_PAGEEXEC
22017 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
22018 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
22019 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
22020 +#else
22021 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
22022 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
22023 +# define PAGE_COPY_NOEXEC      PAGE_COPY
22024 +#endif
22025 +
22026  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
22027  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
22028  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
22029 diff -urNp linux-2.6.18/include/asm-ia64/processor.h linux-2.6.18/include/asm-ia64/processor.h
22030 --- linux-2.6.18/include/asm-ia64/processor.h   2006-09-19 23:42:06.000000000 -0400
22031 +++ linux-2.6.18/include/asm-ia64/processor.h   2006-09-22 20:45:04.000000000 -0400
22032 @@ -283,7 +283,7 @@ struct thread_struct {
22033         .on_ustack =    0,                                      \
22034         .ksp =          0,                                      \
22035         .map_base =     DEFAULT_MAP_BASE,                       \
22036 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
22037 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
22038         .task_size =    DEFAULT_TASK_SIZE,                      \
22039         .last_fph_cpu =  -1,                                    \
22040         INIT_THREAD_IA32                                        \
22041 diff -urNp linux-2.6.18/include/asm-ia64/ustack.h linux-2.6.18/include/asm-ia64/ustack.h
22042 --- linux-2.6.18/include/asm-ia64/ustack.h      2006-09-19 23:42:06.000000000 -0400
22043 +++ linux-2.6.18/include/asm-ia64/ustack.h      2006-09-22 20:45:04.000000000 -0400
22044 @@ -10,10 +10,10 @@
22045  
22046  /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
22047  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
22048 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
22049 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
22050  #endif
22051  
22052 -/* Make a default stack size of 2GiB */
22053 +/* Make a default stack size of 2GB */
22054  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
22055  
22056  #endif /* _ASM_IA64_USTACK_H */
22057 diff -urNp linux-2.6.18/include/asm-m32r/kmap_types.h linux-2.6.18/include/asm-m32r/kmap_types.h
22058 --- linux-2.6.18/include/asm-m32r/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
22059 +++ linux-2.6.18/include/asm-m32r/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
22060 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
22061  D(10)  KM_IRQ1,
22062  D(11)  KM_SOFTIRQ0,
22063  D(12)  KM_SOFTIRQ1,
22064 -D(13)  KM_TYPE_NR
22065 +D(13)  KM_CLEARPAGE,
22066 +D(14)  KM_TYPE_NR
22067  };
22068  
22069  #undef D
22070 diff -urNp linux-2.6.18/include/asm-m68k/kmap_types.h linux-2.6.18/include/asm-m68k/kmap_types.h
22071 --- linux-2.6.18/include/asm-m68k/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
22072 +++ linux-2.6.18/include/asm-m68k/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
22073 @@ -15,6 +15,7 @@ enum km_type {
22074         KM_IRQ1,
22075         KM_SOFTIRQ0,
22076         KM_SOFTIRQ1,
22077 +       KM_CLEARPAGE,
22078         KM_TYPE_NR
22079  };
22080  
22081 diff -urNp linux-2.6.18/include/asm-m68knommu/kmap_types.h linux-2.6.18/include/asm-m68knommu/kmap_types.h
22082 --- linux-2.6.18/include/asm-m68knommu/kmap_types.h     2006-09-19 23:42:06.000000000 -0400
22083 +++ linux-2.6.18/include/asm-m68knommu/kmap_types.h     2006-09-22 20:45:04.000000000 -0400
22084 @@ -15,6 +15,7 @@ enum km_type {
22085         KM_IRQ1,
22086         KM_SOFTIRQ0,
22087         KM_SOFTIRQ1,
22088 +       KM_CLEARPAGE,
22089         KM_TYPE_NR
22090  };
22091  
22092 diff -urNp linux-2.6.18/include/asm-mips/a.out.h linux-2.6.18/include/asm-mips/a.out.h
22093 --- linux-2.6.18/include/asm-mips/a.out.h       2006-09-19 23:42:06.000000000 -0400
22094 +++ linux-2.6.18/include/asm-mips/a.out.h       2006-09-22 20:45:04.000000000 -0400
22095 @@ -35,10 +35,10 @@ struct exec
22096  #ifdef __KERNEL__
22097  
22098  #ifdef CONFIG_32BIT
22099 -#define STACK_TOP      TASK_SIZE
22100 +#define __STACK_TOP    TASK_SIZE
22101  #endif
22102  #ifdef CONFIG_64BIT
22103 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
22104 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
22105  #endif
22106  
22107  #endif
22108 diff -urNp linux-2.6.18/include/asm-mips/elf.h linux-2.6.18/include/asm-mips/elf.h
22109 --- linux-2.6.18/include/asm-mips/elf.h 2006-09-19 23:42:06.000000000 -0400
22110 +++ linux-2.6.18/include/asm-mips/elf.h 2006-09-22 20:45:04.000000000 -0400
22111 @@ -371,4 +371,15 @@ extern int dump_task_fpu(struct task_str
22112  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
22113  #endif
22114  
22115 +#ifdef CONFIG_PAX_ASLR
22116 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
22117 +
22118 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
22119 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
22120 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
22121 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
22122 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22123 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
22124 +#endif
22125 +
22126  #endif /* _ASM_ELF_H */
22127 diff -urNp linux-2.6.18/include/asm-mips/kmap_types.h linux-2.6.18/include/asm-mips/kmap_types.h
22128 --- linux-2.6.18/include/asm-mips/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
22129 +++ linux-2.6.18/include/asm-mips/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
22130 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
22131  D(10)  KM_IRQ1,
22132  D(11)  KM_SOFTIRQ0,
22133  D(12)  KM_SOFTIRQ1,
22134 -D(13)  KM_TYPE_NR
22135 +D(13)  KM_CLEARPAGE,
22136 +D(14)  KM_TYPE_NR
22137  };
22138  
22139  #undef D
22140 diff -urNp linux-2.6.18/include/asm-mips/page.h linux-2.6.18/include/asm-mips/page.h
22141 --- linux-2.6.18/include/asm-mips/page.h        2006-09-19 23:42:06.000000000 -0400
22142 +++ linux-2.6.18/include/asm-mips/page.h        2006-09-22 20:45:04.000000000 -0400
22143 @@ -74,15 +74,17 @@ static inline void copy_user_page(void *
22144    #ifdef CONFIG_CPU_MIPS32
22145      typedef struct { unsigned long pte_low, pte_high; } pte_t;
22146      #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
22147 +    #define __pte(x)   ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
22148    #else
22149       typedef struct { unsigned long long pte; } pte_t;
22150       #define pte_val(x)        ((x).pte)
22151 +     #define __pte(x)  ((pte_t) { (x) } )
22152    #endif
22153  #else
22154  typedef struct { unsigned long pte; } pte_t;
22155  #define pte_val(x)     ((x).pte)
22156 -#endif
22157  #define __pte(x)       ((pte_t) { (x) } )
22158 +#endif
22159  
22160  /*
22161   * For 3-level pagetables we defines these ourselves, for 2-level the
22162 @@ -161,6 +163,15 @@ typedef struct { unsigned long pgprot; }
22163  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
22164                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22165  
22166 +#ifdef CONFIG_PAX_PAGEEXEC
22167 +#ifdef CONFIG_PAX_MPROTECT
22168 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22169 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22170 +#else
22171 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22172 +#endif
22173 +#endif
22174 +
22175  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
22176  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
22177  
22178 diff -urNp linux-2.6.18/include/asm-parisc/a.out.h linux-2.6.18/include/asm-parisc/a.out.h
22179 --- linux-2.6.18/include/asm-parisc/a.out.h     2006-09-19 23:42:06.000000000 -0400
22180 +++ linux-2.6.18/include/asm-parisc/a.out.h     2006-09-22 20:45:04.000000000 -0400
22181 @@ -22,7 +22,7 @@ struct exec
22182  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
22183   * prumpf */
22184  
22185 -#define STACK_TOP      TASK_SIZE
22186 +#define __STACK_TOP    TASK_SIZE
22187  
22188  #endif
22189  
22190 diff -urNp linux-2.6.18/include/asm-parisc/elf.h linux-2.6.18/include/asm-parisc/elf.h
22191 --- linux-2.6.18/include/asm-parisc/elf.h       2006-09-19 23:42:06.000000000 -0400
22192 +++ linux-2.6.18/include/asm-parisc/elf.h       2006-09-22 20:45:04.000000000 -0400
22193 @@ -337,6 +337,17 @@ struct pt_regs;    /* forward declaration..
22194  
22195  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
22196  
22197 +#ifdef CONFIG_PAX_ASLR
22198 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
22199 +
22200 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
22201 +#define PAX_DELTA_MMAP_LEN(tsk)                16
22202 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
22203 +#define PAX_DELTA_EXEC_LEN(tsk)                16
22204 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22205 +#define PAX_DELTA_STACK_LEN(tsk)       16
22206 +#endif
22207 +
22208  /* This yields a mask that user programs can use to figure out what
22209     instruction set this CPU supports.  This could be done in user space,
22210     but it's not easy, and we've already done it here.  */
22211 diff -urNp linux-2.6.18/include/asm-parisc/kmap_types.h linux-2.6.18/include/asm-parisc/kmap_types.h
22212 --- linux-2.6.18/include/asm-parisc/kmap_types.h        2006-09-19 23:42:06.000000000 -0400
22213 +++ linux-2.6.18/include/asm-parisc/kmap_types.h        2006-09-22 20:45:04.000000000 -0400
22214 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
22215  D(10)  KM_IRQ1,
22216  D(11)  KM_SOFTIRQ0,
22217  D(12)  KM_SOFTIRQ1,
22218 -D(13)  KM_TYPE_NR
22219 +D(13)  KM_CLEARPAGE,
22220 +D(14)  KM_TYPE_NR
22221  };
22222  
22223  #undef D
22224 diff -urNp linux-2.6.18/include/asm-parisc/page.h linux-2.6.18/include/asm-parisc/page.h
22225 --- linux-2.6.18/include/asm-parisc/page.h      2006-09-19 23:42:06.000000000 -0400
22226 +++ linux-2.6.18/include/asm-parisc/page.h      2006-09-22 20:45:04.000000000 -0400
22227 @@ -180,6 +180,15 @@ extern int npmem_ranges;
22228  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
22229                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22230  
22231 +#ifdef CONFIG_PAX_PAGEEXEC
22232 +#ifdef CONFIG_PAX_MPROTECT
22233 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22234 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22235 +#else
22236 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22237 +#endif
22238 +#endif
22239 +
22240  #include <asm-generic/memory_model.h>
22241  #include <asm-generic/page.h>
22242  
22243 diff -urNp linux-2.6.18/include/asm-parisc/pgtable.h linux-2.6.18/include/asm-parisc/pgtable.h
22244 --- linux-2.6.18/include/asm-parisc/pgtable.h   2006-09-19 23:42:06.000000000 -0400
22245 +++ linux-2.6.18/include/asm-parisc/pgtable.h   2006-09-22 20:45:04.000000000 -0400
22246 @@ -219,6 +219,17 @@ extern  void *vmalloc_start;
22247  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
22248  #define PAGE_COPY       PAGE_EXECREAD
22249  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
22250 +
22251 +#ifdef CONFIG_PAX_PAGEEXEC
22252 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
22253 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
22254 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
22255 +#else
22256 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
22257 +# define PAGE_COPY_NOEXEC      PAGE_COPY
22258 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
22259 +#endif
22260 +
22261  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
22262  #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
22263  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
22264 diff -urNp linux-2.6.18/include/asm-powerpc/a.out.h linux-2.6.18/include/asm-powerpc/a.out.h
22265 --- linux-2.6.18/include/asm-powerpc/a.out.h    2006-09-19 23:42:06.000000000 -0400
22266 +++ linux-2.6.18/include/asm-powerpc/a.out.h    2006-09-22 20:45:04.000000000 -0400
22267 @@ -23,12 +23,12 @@ struct exec
22268  #define STACK_TOP_USER64 TASK_SIZE_USER64
22269  #define STACK_TOP_USER32 TASK_SIZE_USER32
22270  
22271 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22272 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22273                    STACK_TOP_USER32 : STACK_TOP_USER64)
22274  
22275  #else /* __powerpc64__ */
22276  
22277 -#define STACK_TOP TASK_SIZE
22278 +#define __STACK_TOP TASK_SIZE
22279  
22280  #endif /* __powerpc64__ */
22281  #endif /* __KERNEL__ */
22282 diff -urNp linux-2.6.18/include/asm-powerpc/elf.h linux-2.6.18/include/asm-powerpc/elf.h
22283 --- linux-2.6.18/include/asm-powerpc/elf.h      2006-09-19 23:42:06.000000000 -0400
22284 +++ linux-2.6.18/include/asm-powerpc/elf.h      2006-09-22 20:45:04.000000000 -0400
22285 @@ -161,6 +161,26 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
22286  typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
22287  #endif
22288  
22289 +#ifdef CONFIG_PAX_ASLR
22290 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
22291 +
22292 +#ifdef __powerpc64__
22293 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
22294 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
22295 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
22296 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
22297 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22298 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 16 : 28)
22299 +#else
22300 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
22301 +#define PAX_DELTA_MMAP_LEN(tsk)                15
22302 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
22303 +#define PAX_DELTA_EXEC_LEN(tsk)                15
22304 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22305 +#define PAX_DELTA_STACK_LEN(tsk)       15
22306 +#endif
22307 +#endif
22308 +
22309  #ifdef __KERNEL__
22310  /*
22311   * This is used to ensure we don't load something for the wrong architecture.
22312 diff -urNp linux-2.6.18/include/asm-powerpc/kmap_types.h linux-2.6.18/include/asm-powerpc/kmap_types.h
22313 --- linux-2.6.18/include/asm-powerpc/kmap_types.h       2006-09-19 23:42:06.000000000 -0400
22314 +++ linux-2.6.18/include/asm-powerpc/kmap_types.h       2006-09-22 20:45:04.000000000 -0400
22315 @@ -26,6 +26,7 @@ enum km_type {
22316         KM_SOFTIRQ1,
22317         KM_PPC_SYNC_PAGE,
22318         KM_PPC_SYNC_ICACHE,
22319 +       KM_CLEARPAGE,
22320         KM_TYPE_NR
22321  };
22322  
22323 diff -urNp linux-2.6.18/include/asm-powerpc/page_64.h linux-2.6.18/include/asm-powerpc/page_64.h
22324 --- linux-2.6.18/include/asm-powerpc/page_64.h  2006-09-19 23:42:06.000000000 -0400
22325 +++ linux-2.6.18/include/asm-powerpc/page_64.h  2006-09-22 20:45:04.000000000 -0400
22326 @@ -160,15 +160,18 @@ extern unsigned int HPAGE_SHIFT;
22327   * stack by default, so in the absense of a PT_GNU_STACK program header
22328   * we turn execute permission off.
22329   */
22330 -#define VM_STACK_DEFAULT_FLAGS32       (VM_READ | VM_WRITE | VM_EXEC | \
22331 -                                        VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22332 +#define VM_STACK_DEFAULT_FLAGS32 \
22333 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
22334 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22335  
22336  #define VM_STACK_DEFAULT_FLAGS64       (VM_READ | VM_WRITE | \
22337                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22338  
22339 +#ifndef CONFIG_PAX_PAGEEXEC
22340  #define VM_STACK_DEFAULT_FLAGS \
22341         (test_thread_flag(TIF_32BIT) ? \
22342          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
22343 +#endif
22344  
22345  #include <asm-generic/page.h>
22346  
22347 diff -urNp linux-2.6.18/include/asm-powerpc/page.h linux-2.6.18/include/asm-powerpc/page.h
22348 --- linux-2.6.18/include/asm-powerpc/page.h     2006-09-19 23:42:06.000000000 -0400
22349 +++ linux-2.6.18/include/asm-powerpc/page.h     2006-09-22 20:45:04.000000000 -0400
22350 @@ -77,8 +77,9 @@
22351   * and needs to be executable.  This means the whole heap ends
22352   * up being executable.
22353   */
22354 -#define VM_DATA_DEFAULT_FLAGS32        (VM_READ | VM_WRITE | VM_EXEC | \
22355 -                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22356 +#define VM_DATA_DEFAULT_FLAGS32 \
22357 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
22358 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22359  
22360  #define VM_DATA_DEFAULT_FLAGS64        (VM_READ | VM_WRITE | \
22361                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22362 @@ -89,6 +90,15 @@
22363  #include <asm/page_32.h>
22364  #endif
22365  
22366 +#ifdef CONFIG_PAX_PAGEEXEC
22367 +#ifdef CONFIG_PAX_MPROTECT
22368 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22369 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22370 +#else
22371 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22372 +#endif
22373 +#endif
22374 +
22375  /* align addr on a size boundary - adjust address up/down if needed */
22376  #define _ALIGN_UP(addr,size)   (((addr)+((size)-1))&(~((size)-1)))
22377  #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
22378 diff -urNp linux-2.6.18/include/asm-ppc/page.h linux-2.6.18/include/asm-ppc/page.h
22379 --- linux-2.6.18/include/asm-ppc/page.h 2006-09-19 23:42:06.000000000 -0400
22380 +++ linux-2.6.18/include/asm-ppc/page.h 2006-09-22 20:45:04.000000000 -0400
22381 @@ -173,6 +173,15 @@ extern __inline__ int get_order(unsigned
22382  /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
22383  #define __HAVE_ARCH_GATE_AREA          1
22384  
22385 +#ifdef CONFIG_PAX_PAGEEXEC
22386 +#ifdef CONFIG_PAX_MPROTECT
22387 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22388 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22389 +#else
22390 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22391 +#endif
22392 +#endif
22393 +
22394  #include <asm-generic/memory_model.h>
22395  #endif /* __KERNEL__ */
22396  #endif /* _PPC_PAGE_H */
22397 diff -urNp linux-2.6.18/include/asm-ppc/pgtable.h linux-2.6.18/include/asm-ppc/pgtable.h
22398 --- linux-2.6.18/include/asm-ppc/pgtable.h      2006-09-19 23:42:06.000000000 -0400
22399 +++ linux-2.6.18/include/asm-ppc/pgtable.h      2006-09-22 20:45:04.000000000 -0400
22400 @@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
22401  
22402  #define PAGE_NONE      __pgprot(_PAGE_BASE)
22403  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
22404 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
22405 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
22406  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
22407 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
22408 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
22409  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
22410 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
22411 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
22412 +
22413 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
22414 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
22415 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
22416 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
22417 +#else
22418 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
22419 +# define PAGE_COPY_NOEXEC      PAGE_COPY
22420 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
22421 +#endif
22422  
22423  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
22424  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
22425 @@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
22426   * This is the closest we can get..
22427   */
22428  #define __P000 PAGE_NONE
22429 -#define __P001 PAGE_READONLY_X
22430 -#define __P010 PAGE_COPY
22431 -#define __P011 PAGE_COPY_X
22432 -#define __P100 PAGE_READONLY
22433 +#define __P001 PAGE_READONLY_NOEXEC
22434 +#define __P010 PAGE_COPY_NOEXEC
22435 +#define __P011 PAGE_COPY_NOEXEC
22436 +#define __P100 PAGE_READONLY_X
22437  #define __P101 PAGE_READONLY_X
22438 -#define __P110 PAGE_COPY
22439 +#define __P110 PAGE_COPY_X
22440  #define __P111 PAGE_COPY_X
22441  
22442  #define __S000 PAGE_NONE
22443 -#define __S001 PAGE_READONLY_X
22444 -#define __S010 PAGE_SHARED
22445 -#define __S011 PAGE_SHARED_X
22446 -#define __S100 PAGE_READONLY
22447 +#define __S001 PAGE_READONLY_NOEXEC
22448 +#define __S010 PAGE_SHARED_NOEXEC
22449 +#define __S011 PAGE_SHARED_NOEXEC
22450 +#define __S100 PAGE_READONLY_X
22451  #define __S101 PAGE_READONLY_X
22452 -#define __S110 PAGE_SHARED
22453 +#define __S110 PAGE_SHARED_X
22454  #define __S111 PAGE_SHARED_X
22455  
22456  #ifndef __ASSEMBLY__
22457 diff -urNp linux-2.6.18/include/asm-s390/kmap_types.h linux-2.6.18/include/asm-s390/kmap_types.h
22458 --- linux-2.6.18/include/asm-s390/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
22459 +++ linux-2.6.18/include/asm-s390/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
22460 @@ -16,6 +16,7 @@ enum km_type {
22461         KM_IRQ1,
22462         KM_SOFTIRQ0,
22463         KM_SOFTIRQ1,    
22464 +       KM_CLEARPAGE,
22465         KM_TYPE_NR
22466  };
22467  
22468 diff -urNp linux-2.6.18/include/asm-sh/kmap_types.h linux-2.6.18/include/asm-sh/kmap_types.h
22469 --- linux-2.6.18/include/asm-sh/kmap_types.h    2006-09-19 23:42:06.000000000 -0400
22470 +++ linux-2.6.18/include/asm-sh/kmap_types.h    2006-09-22 20:45:04.000000000 -0400
22471 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
22472  D(10)  KM_IRQ1,
22473  D(11)  KM_SOFTIRQ0,
22474  D(12)  KM_SOFTIRQ1,
22475 -D(13)  KM_TYPE_NR
22476 +D(13)  KM_CLEARPAGE,
22477 +D(14)  KM_TYPE_NR
22478  };
22479  
22480  #undef D
22481 diff -urNp linux-2.6.18/include/asm-sparc/a.out.h linux-2.6.18/include/asm-sparc/a.out.h
22482 --- linux-2.6.18/include/asm-sparc/a.out.h      2006-09-19 23:42:06.000000000 -0400
22483 +++ linux-2.6.18/include/asm-sparc/a.out.h      2006-09-22 20:45:04.000000000 -0400
22484 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
22485  
22486  #include <asm/page.h>
22487  
22488 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
22489 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
22490  
22491  #endif /* __KERNEL__ */
22492  
22493 diff -urNp linux-2.6.18/include/asm-sparc/elf.h linux-2.6.18/include/asm-sparc/elf.h
22494 --- linux-2.6.18/include/asm-sparc/elf.h        2006-09-19 23:42:06.000000000 -0400
22495 +++ linux-2.6.18/include/asm-sparc/elf.h        2006-09-22 20:45:04.000000000 -0400
22496 @@ -144,6 +144,17 @@ typedef struct {
22497  
22498  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
22499  
22500 +#ifdef CONFIG_PAX_ASLR
22501 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
22502 +
22503 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
22504 +#define PAX_DELTA_MMAP_LEN(tsk)                16
22505 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
22506 +#define PAX_DELTA_EXEC_LEN(tsk)                16
22507 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22508 +#define PAX_DELTA_STACK_LEN(tsk)       16
22509 +#endif
22510 +
22511  /* This yields a mask that user programs can use to figure out what
22512     instruction set this cpu supports.  This can NOT be done in userspace
22513     on Sparc.  */
22514 diff -urNp linux-2.6.18/include/asm-sparc/kmap_types.h linux-2.6.18/include/asm-sparc/kmap_types.h
22515 --- linux-2.6.18/include/asm-sparc/kmap_types.h 2006-09-19 23:42:06.000000000 -0400
22516 +++ linux-2.6.18/include/asm-sparc/kmap_types.h 2006-09-22 20:45:04.000000000 -0400
22517 @@ -15,6 +15,7 @@ enum km_type {
22518         KM_IRQ1,
22519         KM_SOFTIRQ0,
22520         KM_SOFTIRQ1,
22521 +       KM_CLEARPAGE,
22522         KM_TYPE_NR
22523  };
22524  
22525 diff -urNp linux-2.6.18/include/asm-sparc/page.h linux-2.6.18/include/asm-sparc/page.h
22526 --- linux-2.6.18/include/asm-sparc/page.h       2006-09-19 23:42:06.000000000 -0400
22527 +++ linux-2.6.18/include/asm-sparc/page.h       2006-09-22 20:45:04.000000000 -0400
22528 @@ -160,6 +160,15 @@ extern unsigned long pfn_base;
22529  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
22530                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22531  
22532 +#ifdef CONFIG_PAX_PAGEEXEC
22533 +#ifdef CONFIG_PAX_MPROTECT
22534 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22535 +                        ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22536 +#else
22537 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22538 +#endif
22539 +#endif
22540 +
22541  #endif /* __KERNEL__ */
22542  
22543  #include <asm-generic/memory_model.h>
22544 diff -urNp linux-2.6.18/include/asm-sparc/pgtable.h linux-2.6.18/include/asm-sparc/pgtable.h
22545 --- linux-2.6.18/include/asm-sparc/pgtable.h    2006-09-19 23:42:06.000000000 -0400
22546 +++ linux-2.6.18/include/asm-sparc/pgtable.h    2006-09-22 20:45:04.000000000 -0400
22547 @@ -49,6 +49,13 @@ BTFIXUPDEF_INT(page_none)
22548  BTFIXUPDEF_INT(page_shared)
22549  BTFIXUPDEF_INT(page_copy)
22550  BTFIXUPDEF_INT(page_readonly)
22551 +
22552 +#ifdef CONFIG_PAX_PAGEEXEC
22553 +BTFIXUPDEF_INT(page_shared_noexec)
22554 +BTFIXUPDEF_INT(page_copy_noexec)
22555 +BTFIXUPDEF_INT(page_readonly_noexec)
22556 +#endif
22557 +
22558  BTFIXUPDEF_INT(page_kernel)
22559  
22560  #define PMD_SHIFT              SUN4C_PMD_SHIFT
22561 @@ -70,6 +77,16 @@ BTFIXUPDEF_INT(page_kernel)
22562  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
22563  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
22564  
22565 +#ifdef CONFIG_PAX_PAGEEXEC
22566 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
22567 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
22568 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
22569 +#else
22570 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
22571 +# define PAGE_COPY_NOEXEC      PAGE_COPY
22572 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
22573 +#endif
22574 +
22575  extern unsigned long page_kernel;
22576  
22577  #ifdef MODULE
22578 diff -urNp linux-2.6.18/include/asm-sparc/pgtsrmmu.h linux-2.6.18/include/asm-sparc/pgtsrmmu.h
22579 --- linux-2.6.18/include/asm-sparc/pgtsrmmu.h   2006-09-19 23:42:06.000000000 -0400
22580 +++ linux-2.6.18/include/asm-sparc/pgtsrmmu.h   2006-09-22 20:45:04.000000000 -0400
22581 @@ -115,6 +115,16 @@
22582                                     SRMMU_EXEC | SRMMU_REF)
22583  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22584                                     SRMMU_EXEC | SRMMU_REF)
22585 +
22586 +#ifdef CONFIG_PAX_PAGEEXEC
22587 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22588 +                                          SRMMU_WRITE | SRMMU_REF)
22589 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22590 +                                          SRMMU_REF)
22591 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22592 +                                          SRMMU_REF)
22593 +#endif
22594 +
22595  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
22596                                     SRMMU_DIRTY | SRMMU_REF)
22597  
22598 diff -urNp linux-2.6.18/include/asm-sparc/uaccess.h linux-2.6.18/include/asm-sparc/uaccess.h
22599 --- linux-2.6.18/include/asm-sparc/uaccess.h    2006-09-19 23:42:06.000000000 -0400
22600 +++ linux-2.6.18/include/asm-sparc/uaccess.h    2006-09-22 20:45:04.000000000 -0400
22601 @@ -41,7 +41,7 @@
22602   * No one can read/write anything from userland in the kernel space by setting
22603   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
22604   */
22605 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
22606 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
22607  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
22608  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
22609  #define access_ok(type, addr, size)                                    \
22610 diff -urNp linux-2.6.18/include/asm-sparc64/a.out.h linux-2.6.18/include/asm-sparc64/a.out.h
22611 --- linux-2.6.18/include/asm-sparc64/a.out.h    2006-09-19 23:42:06.000000000 -0400
22612 +++ linux-2.6.18/include/asm-sparc64/a.out.h    2006-09-22 20:45:04.000000000 -0400
22613 @@ -98,7 +98,7 @@ struct relocation_info /* used when head
22614  #define STACK_TOP32    ((1UL << 32UL) - PAGE_SIZE)
22615  #define STACK_TOP64    (0x0000080000000000UL - (1UL << 32UL))
22616  
22617 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22618 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22619                    STACK_TOP32 : STACK_TOP64)
22620  
22621  #endif
22622 diff -urNp linux-2.6.18/include/asm-sparc64/elf.h linux-2.6.18/include/asm-sparc64/elf.h
22623 --- linux-2.6.18/include/asm-sparc64/elf.h      2006-09-19 23:42:06.000000000 -0400
22624 +++ linux-2.6.18/include/asm-sparc64/elf.h      2006-09-22 20:45:04.000000000 -0400
22625 @@ -142,6 +142,16 @@ typedef struct {
22626  #define ELF_ET_DYN_BASE         0x0000010000000000UL
22627  #endif
22628  
22629 +#ifdef CONFIG_PAX_ASLR
22630 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
22631 +
22632 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
22633 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
22634 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
22635 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
22636 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22637 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
22638 +#endif
22639  
22640  /* This yields a mask that user programs can use to figure out what
22641     instruction set this cpu supports.  */
22642 diff -urNp linux-2.6.18/include/asm-sparc64/kmap_types.h linux-2.6.18/include/asm-sparc64/kmap_types.h
22643 --- linux-2.6.18/include/asm-sparc64/kmap_types.h       2006-09-19 23:42:06.000000000 -0400
22644 +++ linux-2.6.18/include/asm-sparc64/kmap_types.h       2006-09-22 20:45:04.000000000 -0400
22645 @@ -19,6 +19,7 @@ enum km_type {
22646         KM_IRQ1,
22647         KM_SOFTIRQ0,
22648         KM_SOFTIRQ1,
22649 +       KM_CLEARPAGE,
22650         KM_TYPE_NR
22651  };
22652  
22653 diff -urNp linux-2.6.18/include/asm-sparc64/page.h linux-2.6.18/include/asm-sparc64/page.h
22654 --- linux-2.6.18/include/asm-sparc64/page.h     2006-09-19 23:42:06.000000000 -0400
22655 +++ linux-2.6.18/include/asm-sparc64/page.h     2006-09-22 20:45:04.000000000 -0400
22656 @@ -141,6 +141,15 @@ typedef unsigned long pgprot_t;
22657  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
22658                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22659  
22660 +#ifdef CONFIG_PAX_PAGEEXEC
22661 +#ifdef CONFIG_PAX_MPROTECT
22662 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22663 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22664 +#else
22665 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22666 +#endif
22667 +#endif
22668 +
22669  #endif /* !(__KERNEL__) */
22670  
22671  #include <asm-generic/page.h>
22672 diff -urNp linux-2.6.18/include/asm-v850/kmap_types.h linux-2.6.18/include/asm-v850/kmap_types.h
22673 --- linux-2.6.18/include/asm-v850/kmap_types.h  2006-09-19 23:42:06.000000000 -0400
22674 +++ linux-2.6.18/include/asm-v850/kmap_types.h  2006-09-22 20:45:04.000000000 -0400
22675 @@ -13,6 +13,7 @@ enum km_type {
22676         KM_PTE1,
22677         KM_IRQ0,
22678         KM_IRQ1,
22679 +       KM_CLEARPAGE,
22680         KM_TYPE_NR
22681  };
22682  
22683 diff -urNp linux-2.6.18/include/asm-x86_64/a.out.h linux-2.6.18/include/asm-x86_64/a.out.h
22684 --- linux-2.6.18/include/asm-x86_64/a.out.h     2006-09-19 23:42:06.000000000 -0400
22685 +++ linux-2.6.18/include/asm-x86_64/a.out.h     2006-09-22 20:45:04.000000000 -0400
22686 @@ -21,7 +21,7 @@ struct exec
22687  
22688  #ifdef __KERNEL__
22689  #include <linux/thread_info.h>
22690 -#define STACK_TOP TASK_SIZE
22691 +#define __STACK_TOP TASK_SIZE
22692  #endif
22693  
22694  #endif /* __A_OUT_GNU_H__ */
22695 diff -urNp linux-2.6.18/include/asm-x86_64/elf.h linux-2.6.18/include/asm-x86_64/elf.h
22696 --- linux-2.6.18/include/asm-x86_64/elf.h       2006-09-19 23:42:06.000000000 -0400
22697 +++ linux-2.6.18/include/asm-x86_64/elf.h       2006-09-22 20:45:04.000000000 -0400
22698 @@ -93,6 +93,17 @@ typedef struct user_i387_struct elf_fpre
22699  
22700  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
22701  
22702 +#ifdef CONFIG_PAX_ASLR
22703 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
22704 +
22705 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
22706 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
22707 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
22708 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
22709 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
22710 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 32)
22711 +#endif
22712 +
22713  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
22714     now struct_user_regs, they are different). Assumes current is the process
22715     getting dumped. */
22716 diff -urNp linux-2.6.18/include/asm-x86_64/ia32.h linux-2.6.18/include/asm-x86_64/ia32.h
22717 --- linux-2.6.18/include/asm-x86_64/ia32.h      2006-09-19 23:42:06.000000000 -0400
22718 +++ linux-2.6.18/include/asm-x86_64/ia32.h      2006-09-22 20:45:04.000000000 -0400
22719 @@ -156,7 +156,13 @@ struct ustat32 {
22720         char                    f_fpack[6];
22721  };
22722  
22723 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
22724 +#ifdef CONFIG_PAX_RANDUSTACK
22725 +#define IA32_DELTA_STACK (current->mm->delta_stack)
22726 +#else
22727 +#define IA32_DELTA_STACK 0UL
22728 +#endif
22729 +
22730 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
22731  
22732  #ifdef __KERNEL__
22733  struct user_desc;
22734 diff -urNp linux-2.6.18/include/asm-x86_64/kmap_types.h linux-2.6.18/include/asm-x86_64/kmap_types.h
22735 --- linux-2.6.18/include/asm-x86_64/kmap_types.h        2006-09-19 23:42:06.000000000 -0400
22736 +++ linux-2.6.18/include/asm-x86_64/kmap_types.h        2006-09-22 20:45:04.000000000 -0400
22737 @@ -13,6 +13,7 @@ enum km_type {
22738         KM_IRQ1,
22739         KM_SOFTIRQ0,
22740         KM_SOFTIRQ1,
22741 +       KM_CLEARPAGE,
22742         KM_TYPE_NR
22743  };
22744  
22745 diff -urNp linux-2.6.18/include/asm-x86_64/page.h linux-2.6.18/include/asm-x86_64/page.h
22746 --- linux-2.6.18/include/asm-x86_64/page.h      2006-09-19 23:42:06.000000000 -0400
22747 +++ linux-2.6.18/include/asm-x86_64/page.h      2006-09-22 20:45:04.000000000 -0400
22748 @@ -88,6 +88,8 @@ typedef struct { unsigned long pgprot; }
22749  #define __PAGE_OFFSET           0xffff810000000000
22750  #endif /* !__ASSEMBLY__ */
22751  
22752 +#define __KERNEL_TEXT_OFFSET   (0)
22753 +
22754  /* to align the pointer to the (next) page boundary */
22755  #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
22756  
22757 @@ -133,6 +135,15 @@ typedef struct { unsigned long pgprot; }
22758         (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
22759          VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22760  
22761 +#ifdef CONFIG_PAX_PAGEEXEC
22762 +#ifdef CONFIG_PAX_MPROTECT
22763 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22764 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22765 +#else
22766 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22767 +#endif
22768 +#endif
22769 +
22770  #define __HAVE_ARCH_GATE_AREA 1        
22771  
22772  #include <asm-generic/memory_model.h>
22773 diff -urNp linux-2.6.18/include/asm-x86_64/pci-direct.h linux-2.6.18/include/asm-x86_64/pci-direct.h
22774 --- linux-2.6.18/include/asm-x86_64/pci-direct.h        2006-09-19 23:42:06.000000000 -0400
22775 +++ linux-2.6.18/include/asm-x86_64/pci-direct.h        2006-09-22 20:45:04.000000000 -0400
22776 @@ -7,7 +7,7 @@
22777  /* Direct PCI access. This is used for PCI accesses in early boot before
22778     the PCI subsystem works. */ 
22779  
22780 -#define PDprintk(x...)
22781 +#define PDprintk(x...) do {} while (0)
22782  
22783  static inline u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
22784  {
22785 diff -urNp linux-2.6.18/include/asm-x86_64/pgalloc.h linux-2.6.18/include/asm-x86_64/pgalloc.h
22786 --- linux-2.6.18/include/asm-x86_64/pgalloc.h   2006-09-19 23:42:06.000000000 -0400
22787 +++ linux-2.6.18/include/asm-x86_64/pgalloc.h   2006-09-22 20:45:04.000000000 -0400
22788 @@ -7,7 +7,7 @@
22789  #include <linux/mm.h>
22790  
22791  #define pmd_populate_kernel(mm, pmd, pte) \
22792 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
22793 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
22794  #define pud_populate(mm, pud, pmd) \
22795                 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
22796  #define pgd_populate(mm, pgd, pud) \
22797 diff -urNp linux-2.6.18/include/asm-x86_64/pgtable.h linux-2.6.18/include/asm-x86_64/pgtable.h
22798 --- linux-2.6.18/include/asm-x86_64/pgtable.h   2006-09-19 23:42:06.000000000 -0400
22799 +++ linux-2.6.18/include/asm-x86_64/pgtable.h   2006-09-22 20:45:04.000000000 -0400
22800 @@ -180,6 +180,10 @@ static inline pte_t ptep_get_and_clear_f
22801  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
22802  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
22803  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
22804 +
22805 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
22806 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
22807 +
22808  #define __PAGE_KERNEL \
22809         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
22810  #define __PAGE_KERNEL_EXEC \
22811 @@ -268,7 +272,13 @@ static inline pte_t pfn_pte(unsigned lon
22812  #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
22813  static inline int pte_user(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
22814  static inline int pte_read(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
22815 -static inline int pte_exec(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
22816 +extern inline int pte_exec(pte_t pte)
22817 +{
22818 +       if (__supported_pte_mask & _PAGE_NX)
22819 +               return pte_val(pte) & _PAGE_NX;
22820 +       else
22821 +               return pte_val(pte) & _PAGE_USER;
22822 +}
22823  static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
22824  static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
22825  static inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_RW; }
22826 @@ -276,12 +286,26 @@ static inline int pte_file(pte_t pte)             {
22827  static inline int pte_huge(pte_t pte)          { return pte_val(pte) & _PAGE_PSE; }
22828  
22829  static inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
22830 -static inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
22831 +extern inline pte_t pte_exprotect(pte_t pte)
22832 +{
22833 +       if (__supported_pte_mask & _PAGE_NX)
22834 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
22835 +       else
22836 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
22837 +       return pte;
22838 +}
22839  static inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
22840  static inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
22841  static inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
22842  static inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
22843 -static inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
22844 +extern inline pte_t pte_mkexec(pte_t pte)
22845 +{
22846 +       if (__supported_pte_mask & _PAGE_NX)
22847 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
22848 +       else
22849 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
22850 +       return pte;
22851 +}
22852  static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
22853  static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
22854  static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
22855 diff -urNp linux-2.6.18/include/asm-x86_64/system.h linux-2.6.18/include/asm-x86_64/system.h
22856 --- linux-2.6.18/include/asm-x86_64/system.h    2006-09-19 23:42:06.000000000 -0400
22857 +++ linux-2.6.18/include/asm-x86_64/system.h    2006-09-22 20:45:04.000000000 -0400
22858 @@ -247,7 +247,7 @@ static inline unsigned long __cmpxchg(vo
22859  
22860  void cpu_idle_wait(void);
22861  
22862 -extern unsigned long arch_align_stack(unsigned long sp);
22863 +#define arch_align_stack(x) (x)
22864  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
22865  
22866  #endif
22867 diff -urNp linux-2.6.18/include/asm-xtensa/kmap_types.h linux-2.6.18/include/asm-xtensa/kmap_types.h
22868 --- linux-2.6.18/include/asm-xtensa/kmap_types.h        2006-09-19 23:42:06.000000000 -0400
22869 +++ linux-2.6.18/include/asm-xtensa/kmap_types.h        2006-09-22 20:45:04.000000000 -0400
22870 @@ -25,6 +25,7 @@ enum km_type {
22871    KM_IRQ1,
22872    KM_SOFTIRQ0,
22873    KM_SOFTIRQ1,
22874 +  KM_CLEARPAGE,
22875    KM_TYPE_NR
22876  };
22877  
22878 diff -urNp linux-2.6.18/include/linux/a.out.h linux-2.6.18/include/linux/a.out.h
22879 --- linux-2.6.18/include/linux/a.out.h  2006-09-19 23:42:06.000000000 -0400
22880 +++ linux-2.6.18/include/linux/a.out.h  2006-09-22 20:45:04.000000000 -0400
22881 @@ -7,6 +7,16 @@
22882  
22883  #include <asm/a.out.h>
22884  
22885 +#ifdef CONFIG_PAX_RANDUSTACK
22886 +#define __DELTA_STACK (current->mm->delta_stack)
22887 +#else
22888 +#define __DELTA_STACK 0UL
22889 +#endif
22890 +
22891 +#ifndef STACK_TOP
22892 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
22893 +#endif
22894 +
22895  #endif /* __STRUCT_EXEC_OVERRIDE__ */
22896  
22897  /* these go in the N_MACHTYPE field */
22898 @@ -37,6 +47,14 @@ enum machine_type {
22899    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
22900  };
22901  
22902 +/* Constants for the N_FLAGS field */
22903 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
22904 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
22905 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
22906 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
22907 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
22908 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
22909 +
22910  #if !defined (N_MAGIC)
22911  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
22912  #endif
22913 diff -urNp linux-2.6.18/include/linux/binfmts.h linux-2.6.18/include/linux/binfmts.h
22914 --- linux-2.6.18/include/linux/binfmts.h        2006-09-19 23:42:06.000000000 -0400
22915 +++ linux-2.6.18/include/linux/binfmts.h        2006-09-22 20:45:04.000000000 -0400
22916 @@ -7,10 +7,10 @@ struct pt_regs;
22917  
22918  /*
22919   * MAX_ARG_PAGES defines the number of pages allocated for arguments
22920 - * and envelope for the new program. 32 should suffice, this gives
22921 - * a maximum env+arg of 128kB w/4KB pages!
22922 + * and envelope for the new program. 33 should suffice, this gives
22923 + * a maximum env+arg of 132kB w/4KB pages!
22924   */
22925 -#define MAX_ARG_PAGES 32
22926 +#define MAX_ARG_PAGES 33
22927  
22928  /* sizeof(linux_binprm->buf) */
22929  #define BINPRM_BUF_SIZE 128
22930 @@ -38,6 +38,7 @@ struct linux_binprm{
22931         unsigned interp_flags;
22932         unsigned interp_data;
22933         unsigned long loader, exec;
22934 +       int misc;
22935  };
22936  
22937  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
22938 @@ -87,5 +88,8 @@ extern void compute_creds(struct linux_b
22939  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
22940  extern int set_binfmt(struct linux_binfmt *new);
22941  
22942 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
22943 +void pax_report_insns(void *pc, void *sp);
22944 +
22945  #endif /* __KERNEL__ */
22946  #endif /* _LINUX_BINFMTS_H */
22947 diff -urNp linux-2.6.18/include/linux/capability.h linux-2.6.18/include/linux/capability.h
22948 --- linux-2.6.18/include/linux/capability.h     2006-09-19 23:42:06.000000000 -0400
22949 +++ linux-2.6.18/include/linux/capability.h     2006-09-22 20:04:35.000000000 -0400
22950 @@ -358,6 +358,7 @@ static inline kernel_cap_t cap_invert(ke
22951  #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
22952  
22953  int capable(int cap);
22954 +int capable_nolog(int cap);
22955  int __capable(struct task_struct *t, int cap);
22956  
22957  #endif /* __KERNEL__ */
22958 diff -urNp linux-2.6.18/include/linux/elf.h linux-2.6.18/include/linux/elf.h
22959 --- linux-2.6.18/include/linux/elf.h    2006-09-19 23:42:06.000000000 -0400
22960 +++ linux-2.6.18/include/linux/elf.h    2006-09-22 20:45:04.000000000 -0400
22961 @@ -6,6 +6,10 @@
22962  #include <linux/elf-em.h>
22963  #include <asm/elf.h>
22964  
22965 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22966 +#undef elf_read_implies_exec
22967 +#endif
22968 +
22969  #ifndef elf_read_implies_exec
22970    /* Executables for which elf_read_implies_exec() returns TRUE will
22971       have the READ_IMPLIES_EXEC personality flag set automatically.
22972 @@ -47,6 +51,16 @@ typedef __s64        Elf64_Sxword;
22973  
22974  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
22975  
22976 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
22977 +
22978 +/* Constants for the e_flags field */
22979 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
22980 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
22981 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
22982 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
22983 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
22984 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
22985 +
22986  /* These constants define the different elf file types */
22987  #define ET_NONE   0
22988  #define ET_REL    1
22989 @@ -81,6 +95,8 @@ typedef __s64 Elf64_Sxword;
22990  #define DT_DEBUG       21
22991  #define DT_TEXTREL     22
22992  #define DT_JMPREL      23
22993 +#define DT_FLAGS       30
22994 +  #define DF_TEXTREL   0x00000004
22995  #define DT_LOPROC      0x70000000
22996  #define DT_HIPROC      0x7fffffff
22997  
22998 @@ -210,6 +226,19 @@ typedef struct elf64_hdr {
22999  #define PF_W           0x2
23000  #define PF_X           0x1
23001  
23002 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
23003 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
23004 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
23005 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
23006 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
23007 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
23008 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
23009 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
23010 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
23011 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
23012 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
23013 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
23014 +
23015  typedef struct elf32_phdr{
23016    Elf32_Word   p_type;
23017    Elf32_Off    p_offset;
23018 @@ -302,6 +331,8 @@ typedef struct elf64_shdr {
23019  #define        EI_OSABI        7
23020  #define        EI_PAD          8
23021  
23022 +#define        EI_PAX          14
23023 +
23024  #define        ELFMAG0         0x7f            /* EI_MAG */
23025  #define        ELFMAG1         'E'
23026  #define        ELFMAG2         'L'
23027 @@ -358,6 +389,7 @@ extern Elf32_Dyn _DYNAMIC [];
23028  #define elfhdr         elf32_hdr
23029  #define elf_phdr       elf32_phdr
23030  #define elf_note       elf32_note
23031 +#define elf_dyn                Elf32_Dyn
23032  
23033  #else
23034  
23035 @@ -365,6 +397,7 @@ extern Elf64_Dyn _DYNAMIC [];
23036  #define elfhdr         elf64_hdr
23037  #define elf_phdr       elf64_phdr
23038  #define elf_note       elf64_note
23039 +#define elf_dyn                Elf64_Dyn
23040  
23041  #endif
23042  
23043 diff -urNp linux-2.6.18/include/linux/gracl.h linux-2.6.18/include/linux/gracl.h
23044 --- linux-2.6.18/include/linux/gracl.h  1969-12-31 19:00:00.000000000 -0500
23045 +++ linux-2.6.18/include/linux/gracl.h  2006-09-22 20:04:35.000000000 -0400
23046 @@ -0,0 +1,316 @@
23047 +#ifndef GR_ACL_H
23048 +#define GR_ACL_H
23049 +
23050 +#include <linux/grdefs.h>
23051 +#include <linux/resource.h>
23052 +#include <linux/dcache.h>
23053 +#include <asm/resource.h>
23054 +
23055 +/* Major status information */
23056 +
23057 +#define GR_VERSION  "grsecurity 2.1.9"
23058 +#define GRSECURITY_VERSION 0x219
23059 +
23060 +enum {
23061 +
23062 +       SHUTDOWN = 0,
23063 +       ENABLE = 1,
23064 +       SPROLE = 2,
23065 +       RELOAD = 3,
23066 +       SEGVMOD = 4,
23067 +       STATUS = 5,
23068 +       UNSPROLE = 6,
23069 +       PASSSET = 7,
23070 +       SPROLEPAM = 8
23071 +};
23072 +
23073 +/* Password setup definitions
23074 + * kernel/grhash.c */
23075 +enum {
23076 +       GR_PW_LEN = 128,
23077 +       GR_SALT_LEN = 16,
23078 +       GR_SHA_LEN = 32,
23079 +};
23080 +
23081 +enum {
23082 +       GR_SPROLE_LEN = 64,
23083 +};
23084 +
23085 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
23086 +
23087 +/* Begin Data Structures */
23088 +
23089 +struct sprole_pw {
23090 +       unsigned char *rolename;
23091 +       unsigned char salt[GR_SALT_LEN];
23092 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
23093 +};
23094 +
23095 +struct name_entry {
23096 +       __u32 key;
23097 +       ino_t inode;
23098 +       dev_t device;
23099 +       char *name;
23100 +       __u16 len;
23101 +       struct name_entry *prev;
23102 +       struct name_entry *next;
23103 +};
23104 +
23105 +struct inodev_entry {
23106 +       struct name_entry *nentry;
23107 +       struct inodev_entry *prev;
23108 +       struct inodev_entry *next;
23109 +};
23110 +
23111 +struct acl_role_db {
23112 +       struct acl_role_label **r_hash;
23113 +       __u32 r_size;
23114 +};
23115 +
23116 +struct inodev_db {
23117 +       struct inodev_entry **i_hash;
23118 +       __u32 i_size;
23119 +};
23120 +
23121 +struct name_db {
23122 +       struct name_entry **n_hash;
23123 +       __u32 n_size;
23124 +};
23125 +
23126 +struct crash_uid {
23127 +       uid_t uid;
23128 +       unsigned long expires;
23129 +};
23130 +
23131 +struct gr_hash_struct {
23132 +       void **table;
23133 +       void **nametable;
23134 +       void *first;
23135 +       __u32 table_size;
23136 +       __u32 used_size;
23137 +       int type;
23138 +};
23139 +
23140 +/* Userspace Grsecurity ACL data structures */
23141 +
23142 +struct acl_subject_label {
23143 +       char *filename;
23144 +       ino_t inode;
23145 +       dev_t device;
23146 +       __u32 mode;
23147 +       __u32 cap_mask;
23148 +       __u32 cap_lower;
23149 +
23150 +       struct rlimit res[GR_NLIMITS];
23151 +       __u16 resmask;
23152 +
23153 +       __u8 user_trans_type;
23154 +       __u8 group_trans_type;
23155 +       uid_t *user_transitions;
23156 +       gid_t *group_transitions;
23157 +       __u16 user_trans_num;
23158 +       __u16 group_trans_num;
23159 +
23160 +       __u32 ip_proto[8];
23161 +       __u32 ip_type;
23162 +       struct acl_ip_label **ips;
23163 +       __u32 ip_num;
23164 +
23165 +       __u32 crashes;
23166 +       unsigned long expires;
23167 +
23168 +       struct acl_subject_label *parent_subject;
23169 +       struct gr_hash_struct *hash;
23170 +       struct acl_subject_label *prev;
23171 +       struct acl_subject_label *next;
23172 +
23173 +       struct acl_object_label **obj_hash;
23174 +       __u32 obj_hash_size;
23175 +       __u16 pax_flags;
23176 +};
23177 +
23178 +struct role_allowed_ip {
23179 +       __u32 addr;
23180 +       __u32 netmask;
23181 +
23182 +       struct role_allowed_ip *prev;
23183 +       struct role_allowed_ip *next;
23184 +};
23185 +
23186 +struct role_transition {
23187 +       char *rolename;
23188 +
23189 +       struct role_transition *prev;
23190 +       struct role_transition *next;
23191 +};
23192 +
23193 +struct acl_role_label {
23194 +       char *rolename;
23195 +       uid_t uidgid;
23196 +       __u16 roletype;
23197 +
23198 +       __u16 auth_attempts;
23199 +       unsigned long expires;
23200 +
23201 +       struct acl_subject_label *root_label;
23202 +       struct gr_hash_struct *hash;
23203 +
23204 +       struct acl_role_label *prev;
23205 +       struct acl_role_label *next;
23206 +
23207 +       struct role_transition *transitions;
23208 +       struct role_allowed_ip *allowed_ips;
23209 +       uid_t *domain_children;
23210 +       __u16 domain_child_num;
23211 +
23212 +       struct acl_subject_label **subj_hash;
23213 +       __u32 subj_hash_size;
23214 +};
23215 +
23216 +struct user_acl_role_db {
23217 +       struct acl_role_label **r_table;
23218 +       __u32 num_pointers;             /* Number of allocations to track */
23219 +       __u32 num_roles;                /* Number of roles */
23220 +       __u32 num_domain_children;      /* Number of domain children */
23221 +       __u32 num_subjects;             /* Number of subjects */
23222 +       __u32 num_objects;              /* Number of objects */
23223 +};
23224 +
23225 +struct acl_object_label {
23226 +       char *filename;
23227 +       ino_t inode;
23228 +       dev_t device;
23229 +       __u32 mode;
23230 +
23231 +       struct acl_subject_label *nested;
23232 +       struct acl_object_label *globbed;
23233 +
23234 +       /* next two structures not used */
23235 +
23236 +       struct acl_object_label *prev;
23237 +       struct acl_object_label *next;
23238 +};
23239 +
23240 +struct acl_ip_label {
23241 +       char *iface;
23242 +       __u32 addr;
23243 +       __u32 netmask;
23244 +       __u16 low, high;
23245 +       __u8 mode;
23246 +       __u32 type;
23247 +       __u32 proto[8];
23248 +
23249 +       /* next two structures not used */
23250 +
23251 +       struct acl_ip_label *prev;
23252 +       struct acl_ip_label *next;
23253 +};
23254 +
23255 +struct gr_arg {
23256 +       struct user_acl_role_db role_db;
23257 +       unsigned char pw[GR_PW_LEN];
23258 +       unsigned char salt[GR_SALT_LEN];
23259 +       unsigned char sum[GR_SHA_LEN];
23260 +       unsigned char sp_role[GR_SPROLE_LEN];
23261 +       struct sprole_pw *sprole_pws;
23262 +       dev_t segv_device;
23263 +       ino_t segv_inode;
23264 +       uid_t segv_uid;
23265 +       __u16 num_sprole_pws;
23266 +       __u16 mode;
23267 +};
23268 +
23269 +struct gr_arg_wrapper {
23270 +       struct gr_arg *arg;
23271 +       __u32 version;
23272 +       __u32 size;
23273 +};
23274 +
23275 +struct subject_map {
23276 +       struct acl_subject_label *user;
23277 +       struct acl_subject_label *kernel;
23278 +       struct subject_map *prev;
23279 +       struct subject_map *next;
23280 +};
23281 +
23282 +struct acl_subj_map_db {
23283 +       struct subject_map **s_hash;
23284 +       __u32 s_size;
23285 +};
23286 +
23287 +/* End Data Structures Section */
23288 +
23289 +/* Hash functions generated by empirical testing by Brad Spengler
23290 +   Makes good use of the low bits of the inode.  Generally 0-1 times
23291 +   in loop for successful match.  0-3 for unsuccessful match.
23292 +   Shift/add algorithm with modulus of table size and an XOR*/
23293 +
23294 +static __inline__ unsigned int
23295 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
23296 +{
23297 +       return (((uid << type) + (uid ^ type)) % sz);
23298 +}
23299 +
23300 + static __inline__ unsigned int
23301 +shash(const struct acl_subject_label *userp, const unsigned int sz)
23302 +{
23303 +       return ((const unsigned long)userp % sz);
23304 +}
23305 +
23306 +static __inline__ unsigned int
23307 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
23308 +{
23309 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
23310 +}
23311 +
23312 +static __inline__ unsigned int
23313 +nhash(const char *name, const __u16 len, const unsigned int sz)
23314 +{
23315 +       return full_name_hash(name, len) % sz;
23316 +}
23317 +
23318 +#define FOR_EACH_ROLE_START(role,iter) \
23319 +       role = NULL; \
23320 +       iter = 0; \
23321 +       while (iter < acl_role_set.r_size) { \
23322 +               if (role == NULL) \
23323 +                       role = acl_role_set.r_hash[iter]; \
23324 +               if (role == NULL) { \
23325 +                       iter++; \
23326 +                       continue; \
23327 +               }
23328 +
23329 +#define FOR_EACH_ROLE_END(role,iter) \
23330 +               role = role->next; \
23331 +               if (role == NULL) \
23332 +                       iter++; \
23333 +       }
23334 +
23335 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
23336 +       subj = NULL; \
23337 +       iter = 0; \
23338 +       while (iter < role->subj_hash_size) { \
23339 +               if (subj == NULL) \
23340 +                       subj = role->subj_hash[iter]; \
23341 +               if (subj == NULL) { \
23342 +                       iter++; \
23343 +                       continue; \
23344 +               }
23345 +
23346 +#define FOR_EACH_SUBJECT_END(subj,iter) \
23347 +               subj = subj->next; \
23348 +               if (subj == NULL) \
23349 +                       iter++; \
23350 +       }
23351 +
23352 +
23353 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
23354 +       subj = role->hash->first; \
23355 +       while (subj != NULL) {
23356 +
23357 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
23358 +               subj = subj->next; \
23359 +       }
23360 +
23361 +#endif
23362 +
23363 diff -urNp linux-2.6.18/include/linux/gralloc.h linux-2.6.18/include/linux/gralloc.h
23364 --- linux-2.6.18/include/linux/gralloc.h        1969-12-31 19:00:00.000000000 -0500
23365 +++ linux-2.6.18/include/linux/gralloc.h        2006-09-22 20:04:35.000000000 -0400
23366 @@ -0,0 +1,8 @@
23367 +#ifndef __GRALLOC_H
23368 +#define __GRALLOC_H
23369 +
23370 +void acl_free_all(void);
23371 +int acl_alloc_stack_init(unsigned long size);
23372 +void *acl_alloc(unsigned long len);
23373 +
23374 +#endif
23375 diff -urNp linux-2.6.18/include/linux/grdefs.h linux-2.6.18/include/linux/grdefs.h
23376 --- linux-2.6.18/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
23377 +++ linux-2.6.18/include/linux/grdefs.h 2006-09-22 20:04:35.000000000 -0400
23378 @@ -0,0 +1,131 @@
23379 +#ifndef GRDEFS_H
23380 +#define GRDEFS_H
23381 +
23382 +/* Begin grsecurity status declarations */
23383 +
23384 +enum {
23385 +       GR_READY = 0x01,
23386 +       GR_STATUS_INIT = 0x00   // disabled state
23387 +};
23388 +
23389 +/* Begin  ACL declarations */
23390 +
23391 +/* Role flags */
23392 +
23393 +enum {
23394 +       GR_ROLE_USER = 0x0001,
23395 +       GR_ROLE_GROUP = 0x0002,
23396 +       GR_ROLE_DEFAULT = 0x0004,
23397 +       GR_ROLE_SPECIAL = 0x0008,
23398 +       GR_ROLE_AUTH = 0x0010,
23399 +       GR_ROLE_NOPW = 0x0020,
23400 +       GR_ROLE_GOD = 0x0040,
23401 +       GR_ROLE_LEARN = 0x0080,
23402 +       GR_ROLE_TPE = 0x0100,
23403 +       GR_ROLE_DOMAIN = 0x0200,
23404 +       GR_ROLE_PAM = 0x0400
23405 +};
23406 +
23407 +/* ACL Subject and Object mode flags */
23408 +enum {
23409 +       GR_DELETED = 0x80000000
23410 +};
23411 +
23412 +/* ACL Object-only mode flags */
23413 +enum {
23414 +       GR_READ         = 0x00000001,
23415 +       GR_APPEND       = 0x00000002,
23416 +       GR_WRITE        = 0x00000004,
23417 +       GR_EXEC         = 0x00000008,
23418 +       GR_FIND         = 0x00000010,
23419 +       GR_INHERIT      = 0x00000020,
23420 +       GR_SETID        = 0x00000040,
23421 +       GR_CREATE       = 0x00000080,
23422 +       GR_DELETE       = 0x00000100,
23423 +       GR_LINK         = 0x00000200,
23424 +       GR_AUDIT_READ   = 0x00000400,
23425 +       GR_AUDIT_APPEND = 0x00000800,
23426 +       GR_AUDIT_WRITE  = 0x00001000,
23427 +       GR_AUDIT_EXEC   = 0x00002000,
23428 +       GR_AUDIT_FIND   = 0x00004000,
23429 +       GR_AUDIT_INHERIT= 0x00008000,
23430 +       GR_AUDIT_SETID  = 0x00010000,
23431 +       GR_AUDIT_CREATE = 0x00020000,
23432 +       GR_AUDIT_DELETE = 0x00040000,
23433 +       GR_AUDIT_LINK   = 0x00080000,
23434 +       GR_PTRACERD     = 0x00100000,
23435 +       GR_NOPTRACE     = 0x00200000,
23436 +       GR_SUPPRESS     = 0x00400000,
23437 +       GR_NOLEARN      = 0x00800000
23438 +};
23439 +
23440 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
23441 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
23442 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
23443 +
23444 +/* ACL subject-only mode flags */
23445 +enum {
23446 +       GR_KILL         = 0x00000001,
23447 +       GR_VIEW         = 0x00000002,
23448 +       GR_PROTECTED    = 0x00000004,
23449 +       GR_LEARN        = 0x00000008,
23450 +       GR_OVERRIDE     = 0x00000010,
23451 +       /* just a placeholder, this mode is only used in userspace */
23452 +       GR_DUMMY        = 0x00000020,
23453 +       GR_PROTSHM      = 0x00000040,
23454 +       GR_KILLPROC     = 0x00000080,
23455 +       GR_KILLIPPROC   = 0x00000100,
23456 +       /* just a placeholder, this mode is only used in userspace */
23457 +       GR_NOTROJAN     = 0x00000200,
23458 +       GR_PROTPROCFD   = 0x00000400,
23459 +       GR_PROCACCT     = 0x00000800,
23460 +       GR_RELAXPTRACE  = 0x00001000,
23461 +       GR_NESTED       = 0x00002000,
23462 +       GR_INHERITLEARN = 0x00004000,
23463 +       GR_PROCFIND     = 0x00008000,
23464 +       GR_POVERRIDE    = 0x00010000,
23465 +       GR_KERNELAUTH   = 0x00020000,
23466 +};
23467 +
23468 +enum {
23469 +       GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
23470 +       GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
23471 +       GR_PAX_ENABLE_MPROTECT  = 0x0004,
23472 +       GR_PAX_ENABLE_RANDMMAP  = 0x0008,
23473 +       GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
23474 +       GR_PAX_DISABLE_SEGMEXEC = 0x8001,
23475 +       GR_PAX_DISABLE_PAGEEXEC = 0x8002,
23476 +       GR_PAX_DISABLE_MPROTECT = 0x8004,
23477 +       GR_PAX_DISABLE_RANDMMAP = 0x8008,
23478 +       GR_PAX_DISABLE_EMUTRAMP = 0x8010,
23479 +};
23480 +
23481 +enum {
23482 +       GR_ID_USER      = 0x01,
23483 +       GR_ID_GROUP     = 0x02,
23484 +};
23485 +
23486 +enum {
23487 +       GR_ID_ALLOW     = 0x01,
23488 +       GR_ID_DENY      = 0x02,
23489 +};
23490 +
23491 +#define GR_CRASH_RES   11
23492 +#define GR_UIDTABLE_MAX 500
23493 +
23494 +/* begin resource learning section */
23495 +enum {
23496 +       GR_RLIM_CPU_BUMP = 60,
23497 +       GR_RLIM_FSIZE_BUMP = 50000,
23498 +       GR_RLIM_DATA_BUMP = 10000,
23499 +       GR_RLIM_STACK_BUMP = 1000,
23500 +       GR_RLIM_CORE_BUMP = 10000,
23501 +       GR_RLIM_RSS_BUMP = 500000,
23502 +       GR_RLIM_NPROC_BUMP = 1,
23503 +       GR_RLIM_NOFILE_BUMP = 5,
23504 +       GR_RLIM_MEMLOCK_BUMP = 50000,
23505 +       GR_RLIM_AS_BUMP = 500000,
23506 +       GR_RLIM_LOCKS_BUMP = 2
23507 +};
23508 +
23509 +#endif
23510 diff -urNp linux-2.6.18/include/linux/grinternal.h linux-2.6.18/include/linux/grinternal.h
23511 --- linux-2.6.18/include/linux/grinternal.h     1969-12-31 19:00:00.000000000 -0500
23512 +++ linux-2.6.18/include/linux/grinternal.h     2006-09-22 20:04:35.000000000 -0400
23513 @@ -0,0 +1,211 @@
23514 +#ifndef __GRINTERNAL_H
23515 +#define __GRINTERNAL_H
23516 +
23517 +#ifdef CONFIG_GRKERNSEC
23518 +
23519 +#include <linux/fs.h>
23520 +#include <linux/gracl.h>
23521 +#include <linux/grdefs.h>
23522 +#include <linux/grmsg.h>
23523 +
23524 +extern void gr_add_learn_entry(const char *fmt, ...);
23525 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
23526 +                           const struct vfsmount *mnt);
23527 +extern __u32 gr_check_create(const struct dentry *new_dentry,
23528 +                            const struct dentry *parent,
23529 +                            const struct vfsmount *mnt, const __u32 mode);
23530 +extern int gr_check_protected_task(const struct task_struct *task);
23531 +extern __u32 to_gr_audit(const __u32 reqmode);
23532 +extern int gr_set_acls(const int type);
23533 +
23534 +extern int gr_acl_is_enabled(void);
23535 +extern char gr_roletype_to_char(void);
23536 +
23537 +extern void gr_handle_alertkill(struct task_struct *task);
23538 +extern char *gr_to_filename(const struct dentry *dentry,
23539 +                           const struct vfsmount *mnt);
23540 +extern char *gr_to_filename1(const struct dentry *dentry,
23541 +                           const struct vfsmount *mnt);
23542 +extern char *gr_to_filename2(const struct dentry *dentry,
23543 +                           const struct vfsmount *mnt);
23544 +extern char *gr_to_filename3(const struct dentry *dentry,
23545 +                           const struct vfsmount *mnt);
23546 +
23547 +extern int grsec_enable_link;
23548 +extern int grsec_enable_fifo;
23549 +extern int grsec_enable_execve;
23550 +extern int grsec_enable_shm;
23551 +extern int grsec_enable_execlog;
23552 +extern int grsec_enable_signal;
23553 +extern int grsec_enable_forkfail;
23554 +extern int grsec_enable_time;
23555 +extern int grsec_enable_chroot_shmat;
23556 +extern int grsec_enable_chroot_findtask;
23557 +extern int grsec_enable_chroot_mount;
23558 +extern int grsec_enable_chroot_double;
23559 +extern int grsec_enable_chroot_pivot;
23560 +extern int grsec_enable_chroot_chdir;
23561 +extern int grsec_enable_chroot_chmod;
23562 +extern int grsec_enable_chroot_mknod;
23563 +extern int grsec_enable_chroot_fchdir;
23564 +extern int grsec_enable_chroot_nice;
23565 +extern int grsec_enable_chroot_execlog;
23566 +extern int grsec_enable_chroot_caps;
23567 +extern int grsec_enable_chroot_sysctl;
23568 +extern int grsec_enable_chroot_unix;
23569 +extern int grsec_enable_tpe;
23570 +extern int grsec_tpe_gid;
23571 +extern int grsec_enable_tpe_all;
23572 +extern int grsec_enable_sidcaps;
23573 +extern int grsec_enable_randpid;
23574 +extern int grsec_enable_socket_all;
23575 +extern int grsec_socket_all_gid;
23576 +extern int grsec_enable_socket_client;
23577 +extern int grsec_socket_client_gid;
23578 +extern int grsec_enable_socket_server;
23579 +extern int grsec_socket_server_gid;
23580 +extern int grsec_audit_gid;
23581 +extern int grsec_enable_group;
23582 +extern int grsec_enable_audit_ipc;
23583 +extern int grsec_enable_audit_textrel;
23584 +extern int grsec_enable_mount;
23585 +extern int grsec_enable_chdir;
23586 +extern int grsec_resource_logging;
23587 +extern int grsec_lock;
23588 +
23589 +extern struct task_struct *child_reaper;
23590 +
23591 +extern spinlock_t grsec_alert_lock;
23592 +extern unsigned long grsec_alert_wtime;
23593 +extern unsigned long grsec_alert_fyet;
23594 +
23595 +extern spinlock_t grsec_audit_lock;
23596 +
23597 +extern rwlock_t grsec_exec_file_lock;
23598 +
23599 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
23600 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
23601 +                       tsk->exec_file->f_vfsmnt) : "/")
23602 +
23603 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
23604 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
23605 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
23606 +
23607 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
23608 +                       gr_to_filename(tsk->exec_file->f_dentry, \
23609 +                       tsk->exec_file->f_vfsmnt) : "/")
23610 +
23611 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
23612 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
23613 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
23614 +
23615 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
23616 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
23617 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
23618 +                         (tsk_a->fs->root->d_inode->i_ino != \
23619 +                         child_reaper->fs->root->d_inode->i_ino)))
23620 +
23621 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
23622 +                         (tsk_a->fs->root->d_inode->i_sb->s_dev == \
23623 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
23624 +                         (tsk_a->fs->root->d_inode->i_ino == \
23625 +                         tsk_b->fs->root->d_inode->i_ino))
23626 +
23627 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
23628 +                      task->pid, task->uid, \
23629 +                      task->euid, task->gid, task->egid, \
23630 +                      gr_parent_task_fullpath(task), \
23631 +                      task->parent->comm, task->parent->pid, \
23632 +                      task->parent->uid, task->parent->euid, \
23633 +                      task->parent->gid, task->parent->egid
23634 +
23635 +#define GR_CHROOT_CAPS ( \
23636 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
23637 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
23638 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
23639 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
23640 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
23641 +       CAP_TO_MASK(CAP_IPC_OWNER))
23642 +
23643 +#define security_learn(normal_msg,args...) \
23644 +({ \
23645 +       read_lock(&grsec_exec_file_lock); \
23646 +       gr_add_learn_entry(normal_msg "\n", ## args); \
23647 +       read_unlock(&grsec_exec_file_lock); \
23648 +})
23649 +
23650 +enum {
23651 +       GR_DO_AUDIT,
23652 +       GR_DONT_AUDIT,
23653 +       GR_DONT_AUDIT_GOOD
23654 +};
23655 +
23656 +enum {
23657 +       GR_TTYSNIFF,
23658 +       GR_RBAC,
23659 +       GR_RBAC_STR,
23660 +       GR_STR_RBAC,
23661 +       GR_RBAC_MODE2,
23662 +       GR_RBAC_MODE3,
23663 +       GR_FILENAME,
23664 +       GR_NOARGS,
23665 +       GR_ONE_INT,
23666 +       GR_ONE_INT_TWO_STR,
23667 +       GR_ONE_STR,
23668 +       GR_STR_INT,
23669 +       GR_TWO_INT,
23670 +       GR_THREE_INT,
23671 +       GR_FIVE_INT_TWO_STR,
23672 +       GR_TWO_STR,
23673 +       GR_THREE_STR,
23674 +       GR_FOUR_STR,
23675 +       GR_STR_FILENAME,
23676 +       GR_FILENAME_STR,
23677 +       GR_FILENAME_TWO_INT,
23678 +       GR_FILENAME_TWO_INT_STR,
23679 +       GR_TEXTREL,
23680 +       GR_PTRACE,
23681 +       GR_RESOURCE,
23682 +       GR_CAP,
23683 +       GR_SIG,
23684 +       GR_CRASH1,
23685 +       GR_CRASH2,
23686 +       GR_PSACCT
23687 +};
23688 +
23689 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
23690 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
23691 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
23692 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
23693 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
23694 +#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)
23695 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
23696 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
23697 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
23698 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
23699 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
23700 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
23701 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
23702 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
23703 +#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)
23704 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
23705 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
23706 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
23707 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
23708 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
23709 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
23710 +#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)
23711 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
23712 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
23713 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
23714 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
23715 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
23716 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
23717 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
23718 +#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)
23719 +
23720 +extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
23721 +
23722 +#endif
23723 +
23724 +#endif
23725 diff -urNp linux-2.6.18/include/linux/grmsg.h linux-2.6.18/include/linux/grmsg.h
23726 --- linux-2.6.18/include/linux/grmsg.h  1969-12-31 19:00:00.000000000 -0500
23727 +++ linux-2.6.18/include/linux/grmsg.h  2006-09-22 20:04:35.000000000 -0400
23728 @@ -0,0 +1,108 @@
23729 +#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"
23730 +#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"
23731 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
23732 +#define GR_STOPMOD_MSG "denied modification of module state by "
23733 +#define GR_IOPERM_MSG "denied use of ioperm() by "
23734 +#define GR_IOPL_MSG "denied use of iopl() by "
23735 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
23736 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
23737 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
23738 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
23739 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
23740 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
23741 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
23742 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
23743 +#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"
23744 +#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"
23745 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
23746 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
23747 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
23748 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
23749 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
23750 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
23751 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
23752 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
23753 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
23754 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
23755 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
23756 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
23757 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
23758 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
23759 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
23760 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
23761 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
23762 +#define GR_NPROC_MSG "denied overstep of process limit by "
23763 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
23764 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
23765 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
23766 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
23767 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
23768 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
23769 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
23770 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
23771 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
23772 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
23773 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
23774 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
23775 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
23776 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
23777 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
23778 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
23779 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
23780 +#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"
23781 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
23782 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
23783 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
23784 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
23785 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
23786 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
23787 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
23788 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
23789 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
23790 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
23791 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
23792 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
23793 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
23794 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
23795 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
23796 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
23797 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
23798 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
23799 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
23800 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
23801 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
23802 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
23803 +#define GR_NICE_CHROOT_MSG "denied priority change by "
23804 +#define GR_UNISIGLOG_MSG "signal %d sent to "
23805 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
23806 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
23807 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
23808 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
23809 +#define GR_TIME_MSG "time set by "
23810 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
23811 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
23812 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
23813 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
23814 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
23815 +#define GR_BIND_MSG "denied bind() by "
23816 +#define GR_CONNECT_MSG "denied connect() by "
23817 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
23818 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
23819 +#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"
23820 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
23821 +#define GR_CAP_ACL_MSG "use of %s denied for "
23822 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
23823 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
23824 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
23825 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
23826 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
23827 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
23828 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
23829 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
23830 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
23831 +#define GR_SEM_AUDIT_MSG "semaphore created by "
23832 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
23833 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
23834 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
23835 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
23836 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
23837 diff -urNp linux-2.6.18/include/linux/grsecurity.h linux-2.6.18/include/linux/grsecurity.h
23838 --- linux-2.6.18/include/linux/grsecurity.h     1969-12-31 19:00:00.000000000 -0500
23839 +++ linux-2.6.18/include/linux/grsecurity.h     2006-09-22 20:04:35.000000000 -0400
23840 @@ -0,0 +1,196 @@
23841 +#ifndef GR_SECURITY_H
23842 +#define GR_SECURITY_H
23843 +#include <linux/fs.h>
23844 +#include <linux/binfmts.h>
23845 +#include <linux/gracl.h>
23846 +
23847 +extern void gr_handle_brute_attach(struct task_struct *p);
23848 +extern void gr_handle_brute_check(void);
23849 +
23850 +extern char gr_roletype_to_char(void);
23851 +
23852 +extern int gr_check_user_change(int real, int effective, int fs);
23853 +extern int gr_check_group_change(int real, int effective, int fs);
23854 +
23855 +extern void gr_del_task_from_ip_table(struct task_struct *p);
23856 +
23857 +extern int gr_pid_is_chrooted(struct task_struct *p);
23858 +extern int gr_handle_chroot_nice(void);
23859 +extern int gr_handle_chroot_sysctl(const int op);
23860 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
23861 +                                       const int niceval);
23862 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
23863 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
23864 +                                  const struct vfsmount *mnt);
23865 +extern void gr_handle_chroot_caps(struct task_struct *task);
23866 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
23867 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
23868 +                                 const struct vfsmount *mnt, const int mode);
23869 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
23870 +                                 const struct vfsmount *mnt, const int mode);
23871 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
23872 +                                 const struct vfsmount *mnt,
23873 +                                 const char *dev_name);
23874 +extern int gr_handle_chroot_pivot(void);
23875 +extern int gr_handle_chroot_unix(const pid_t pid);
23876 +
23877 +extern int gr_handle_rawio(const struct inode *inode);
23878 +extern int gr_handle_nproc(void);
23879 +
23880 +extern void gr_handle_ioperm(void);
23881 +extern void gr_handle_iopl(void);
23882 +
23883 +extern int gr_tpe_allow(const struct file *file);
23884 +
23885 +extern int gr_random_pid(void);
23886 +
23887 +extern void gr_log_forkfail(const int retval);
23888 +extern void gr_log_timechange(void);
23889 +extern void gr_log_signal(const int sig, const struct task_struct *t);
23890 +extern void gr_log_chdir(const struct dentry *dentry,
23891 +                        const struct vfsmount *mnt);
23892 +extern void gr_log_chroot_exec(const struct dentry *dentry,
23893 +                              const struct vfsmount *mnt);
23894 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
23895 +extern void gr_log_remount(const char *devname, const int retval);
23896 +extern void gr_log_unmount(const char *devname, const int retval);
23897 +extern void gr_log_mount(const char *from, const char *to, const int retval);
23898 +extern void gr_log_msgget(const int ret, const int msgflg);
23899 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
23900 +extern void gr_log_semget(const int err, const int semflg);
23901 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
23902 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
23903 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
23904 +extern void gr_log_textrel(struct vm_area_struct *vma);
23905 +
23906 +extern int gr_handle_follow_link(const struct inode *parent,
23907 +                                const struct inode *inode,
23908 +                                const struct dentry *dentry,
23909 +                                const struct vfsmount *mnt);
23910 +extern int gr_handle_fifo(const struct dentry *dentry,
23911 +                         const struct vfsmount *mnt,
23912 +                         const struct dentry *dir, const int flag,
23913 +                         const int acc_mode);
23914 +extern int gr_handle_hardlink(const struct dentry *dentry,
23915 +                             const struct vfsmount *mnt,
23916 +                             struct inode *inode,
23917 +                             const int mode, const char *to);
23918 +
23919 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
23920 +extern int gr_is_capable_nolog(const int cap);
23921 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
23922 +                             const unsigned long wanted, const int gt);
23923 +extern void gr_copy_label(struct task_struct *tsk);
23924 +extern void gr_handle_crash(struct task_struct *task, const int sig);
23925 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
23926 +extern int gr_check_crash_uid(const uid_t uid);
23927 +extern int gr_check_protected_task(const struct task_struct *task);
23928 +extern int gr_acl_handle_mmap(const struct file *file,
23929 +                             const unsigned long prot);
23930 +extern int gr_acl_handle_mprotect(const struct file *file,
23931 +                                 const unsigned long prot);
23932 +extern int gr_check_hidden_task(const struct task_struct *tsk);
23933 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
23934 +                                   const struct vfsmount *mnt);
23935 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
23936 +                                const struct vfsmount *mnt);
23937 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
23938 +                                 const struct vfsmount *mnt, const int fmode);
23939 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
23940 +                                 const struct vfsmount *mnt, mode_t mode);
23941 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
23942 +                                const struct vfsmount *mnt, mode_t mode);
23943 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
23944 +                                const struct vfsmount *mnt);
23945 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
23946 +extern int gr_handle_proc_ptrace(struct task_struct *task);
23947 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
23948 +                                 const struct vfsmount *mnt);
23949 +extern int gr_check_crash_exec(const struct file *filp);
23950 +extern int gr_acl_is_enabled(void);
23951 +extern void gr_set_kernel_label(struct task_struct *task);
23952 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
23953 +                             const gid_t gid);
23954 +extern int gr_set_proc_label(const struct dentry *dentry,
23955 +                             const struct vfsmount *mnt);
23956 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
23957 +                                      const struct vfsmount *mnt);
23958 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
23959 +                               const struct vfsmount *mnt, const int fmode);
23960 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
23961 +                                const struct dentry *p_dentry,
23962 +                                const struct vfsmount *p_mnt, const int fmode,
23963 +                                const int imode);
23964 +extern void gr_handle_create(const struct dentry *dentry,
23965 +                            const struct vfsmount *mnt);
23966 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
23967 +                                const struct dentry *parent_dentry,
23968 +                                const struct vfsmount *parent_mnt,
23969 +                                const int mode);
23970 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
23971 +                                const struct dentry *parent_dentry,
23972 +                                const struct vfsmount *parent_mnt);
23973 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
23974 +                                const struct vfsmount *mnt);
23975 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
23976 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
23977 +                                 const struct vfsmount *mnt);
23978 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
23979 +                                  const struct dentry *parent_dentry,
23980 +                                  const struct vfsmount *parent_mnt,
23981 +                                  const char *from);
23982 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
23983 +                               const struct dentry *parent_dentry,
23984 +                               const struct vfsmount *parent_mnt,
23985 +                               const struct dentry *old_dentry,
23986 +                               const struct vfsmount *old_mnt, const char *to);
23987 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
23988 +                               struct dentry *parent_dentry,
23989 +                               const struct vfsmount *parent_mnt,
23990 +                               struct dentry *old_dentry,
23991 +                               struct inode *old_parent_inode,
23992 +                               struct vfsmount *old_mnt, const char *newname);
23993 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
23994 +                               struct dentry *old_dentry,
23995 +                               struct dentry *new_dentry,
23996 +                               struct vfsmount *mnt, const __u8 replace);
23997 +extern __u32 gr_check_link(const struct dentry *new_dentry,
23998 +                          const struct dentry *parent_dentry,
23999 +                          const struct vfsmount *parent_mnt,
24000 +                          const struct dentry *old_dentry,
24001 +                          const struct vfsmount *old_mnt);
24002 +extern int gr_acl_handle_filldir(const struct file *file, const char *name,
24003 +                                const unsigned int namelen, const ino_t ino);
24004 +
24005 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
24006 +                               const struct vfsmount *mnt);
24007 +extern void gr_acl_handle_exit(void);
24008 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
24009 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
24010 +extern __u32 gr_cap_rtnetlink(void);
24011 +
24012 +#ifdef CONFIG_SYSVIPC
24013 +extern void gr_shm_exit(struct task_struct *task);
24014 +#else
24015 +static inline void gr_shm_exit(struct task_struct *task)
24016 +{
24017 +       return;
24018 +}
24019 +#endif
24020 +
24021 +#ifdef CONFIG_GRKERNSEC
24022 +extern void gr_handle_mem_write(void);
24023 +extern void gr_handle_kmem_write(void);
24024 +extern void gr_handle_open_port(void);
24025 +extern int gr_handle_mem_mmap(const unsigned long offset,
24026 +                             struct vm_area_struct *vma);
24027 +
24028 +extern unsigned long pax_get_random_long(void);
24029 +#define get_random_long() pax_get_random_long()
24030 +
24031 +extern int grsec_enable_dmesg;
24032 +extern int grsec_enable_randsrc;
24033 +extern int grsec_enable_shm;
24034 +#endif
24035 +
24036 +#endif
24037 diff -urNp linux-2.6.18/include/linux/highmem.h linux-2.6.18/include/linux/highmem.h
24038 --- linux-2.6.18/include/linux/highmem.h        2006-09-19 23:42:06.000000000 -0400
24039 +++ linux-2.6.18/include/linux/highmem.h        2006-09-22 20:45:04.000000000 -0400
24040 @@ -69,9 +69,9 @@ alloc_zeroed_user_highpage(struct vm_are
24041  
24042  static inline void clear_highpage(struct page *page)
24043  {
24044 -       void *kaddr = kmap_atomic(page, KM_USER0);
24045 +       void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
24046         clear_page(kaddr);
24047 -       kunmap_atomic(kaddr, KM_USER0);
24048 +       kunmap_atomic(kaddr, KM_CLEARPAGE);
24049  }
24050  
24051  /*
24052 diff -urNp linux-2.6.18/include/linux/jbd.h linux-2.6.18/include/linux/jbd.h
24053 --- linux-2.6.18/include/linux/jbd.h    2006-09-19 23:42:06.000000000 -0400
24054 +++ linux-2.6.18/include/linux/jbd.h    2006-09-22 20:45:04.000000000 -0400
24055 @@ -68,7 +68,7 @@ extern int journal_enable_debug;
24056                 }                                                       \
24057         } while (0)
24058  #else
24059 -#define jbd_debug(f, a...)     /**/
24060 +#define jbd_debug(f, a...)     do {} while (0)
24061  #endif
24062  
24063  extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
24064 diff -urNp linux-2.6.18/include/linux/mman.h linux-2.6.18/include/linux/mman.h
24065 --- linux-2.6.18/include/linux/mman.h   2006-09-19 23:42:06.000000000 -0400
24066 +++ linux-2.6.18/include/linux/mman.h   2006-09-22 20:45:04.000000000 -0400
24067 @@ -61,6 +61,11 @@ static inline unsigned long
24068  calc_vm_flag_bits(unsigned long flags)
24069  {
24070         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
24071 +
24072 +#ifdef CONFIG_PAX_SEGMEXEC
24073 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
24074 +#endif
24075 +
24076                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
24077                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
24078                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
24079 diff -urNp linux-2.6.18/include/linux/mm.h linux-2.6.18/include/linux/mm.h
24080 --- linux-2.6.18/include/linux/mm.h     2006-09-19 23:42:06.000000000 -0400
24081 +++ linux-2.6.18/include/linux/mm.h     2006-09-22 20:45:04.000000000 -0400
24082 @@ -37,6 +37,7 @@ extern int sysctl_legacy_va_layout;
24083  #include <asm/page.h>
24084  #include <asm/pgtable.h>
24085  #include <asm/processor.h>
24086 +#include <asm/mman.h>
24087  
24088  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
24089  
24090 @@ -110,8 +111,43 @@ struct vm_area_struct {
24091  #ifdef CONFIG_NUMA
24092         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
24093  #endif
24094 +
24095 +       unsigned long vm_mirror;        /* PaX: mirror distance */
24096  };
24097  
24098 +#ifdef CONFIG_PAX_SOFTMODE
24099 +extern unsigned int pax_softmode;
24100 +#endif
24101 +
24102 +extern int pax_check_flags(unsigned long *);
24103 +
24104 +/* if tsk != current then task_lock must be held on it */
24105 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
24106 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
24107 +{
24108 +       if (likely(tsk->mm))
24109 +               return tsk->mm->pax_flags;
24110 +       else
24111 +               return 0UL;
24112 +}
24113 +
24114 +/* if tsk != current then task_lock must be held on it */
24115 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
24116 +{
24117 +       if (likely(tsk->mm)) {
24118 +               tsk->mm->pax_flags = flags;
24119 +               return 0;
24120 +       }
24121 +       return -EINVAL;
24122 +}
24123 +#endif
24124 +
24125 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
24126 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
24127 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
24128 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
24129 +#endif
24130 +
24131  /*
24132   * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
24133   * disabled, then there's a single shared list of VMAs maintained by the
24134 @@ -165,6 +201,18 @@ extern unsigned int kobjsize(const void 
24135  #define VM_MAPPED_COPY 0x01000000      /* T if mapped copy of data (nommu mmap) */
24136  #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
24137  
24138 +#ifdef CONFIG_PAX_SEGMEXEC
24139 +#define VM_MIRROR      0x04000000      /* vma is mirroring another */
24140 +#endif
24141 +
24142 +#ifdef CONFIG_PAX_MPROTECT
24143 +#define VM_MAYNOTWRITE 0x08000000      /* vma cannot be granted VM_WRITE any more */
24144 +#endif
24145 +
24146 +#ifdef __VM_STACK_FLAGS
24147 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
24148 +#endif
24149 +
24150  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
24151  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
24152  #endif
24153 @@ -1073,5 +1121,11 @@ extern int randomize_va_space;
24154  
24155  const char *arch_vma_name(struct vm_area_struct *vma);
24156  
24157 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24158 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
24159 +#else
24160 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
24161 +#endif
24162 +
24163  #endif /* __KERNEL__ */
24164  #endif /* _LINUX_MM_H */
24165 diff -urNp linux-2.6.18/include/linux/module.h linux-2.6.18/include/linux/module.h
24166 --- linux-2.6.18/include/linux/module.h 2006-09-19 23:42:06.000000000 -0400
24167 +++ linux-2.6.18/include/linux/module.h 2006-09-22 20:45:04.000000000 -0400
24168 @@ -292,16 +292,16 @@ struct module
24169         int (*init)(void);
24170  
24171         /* If this is non-NULL, vfree after init() returns */
24172 -       void *module_init;
24173 +       void *module_init_rx, *module_init_rw;
24174  
24175         /* Here is the actual code + data, vfree'd on unload. */
24176 -       void *module_core;
24177 +       void *module_core_rx, *module_core_rw;
24178  
24179         /* Here are the sizes of the init and core sections */
24180 -       unsigned long init_size, core_size;
24181 +       unsigned long init_size_rw, core_size_rw;
24182  
24183         /* The size of the executable code in each section.  */
24184 -       unsigned long init_text_size, core_text_size;
24185 +       unsigned long init_size_rx, core_size_rx;
24186  
24187         /* The handle returned from unwind_add_table. */
24188         void *unwind_info;
24189 diff -urNp linux-2.6.18/include/linux/moduleloader.h linux-2.6.18/include/linux/moduleloader.h
24190 --- linux-2.6.18/include/linux/moduleloader.h   2006-09-19 23:42:06.000000000 -0400
24191 +++ linux-2.6.18/include/linux/moduleloader.h   2006-09-22 20:45:04.000000000 -0400
24192 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
24193     sections.  Returns NULL on failure. */
24194  void *module_alloc(unsigned long size);
24195  
24196 +#ifdef CONFIG_PAX_KERNEXEC
24197 +void *module_alloc_exec(unsigned long size);
24198 +#else
24199 +#define module_alloc_exec(x) module_alloc(x)
24200 +#endif
24201 +
24202  /* Free memory returned from module_alloc. */
24203  void module_free(struct module *mod, void *module_region);
24204  
24205 +#ifdef CONFIG_PAX_KERNEXEC
24206 +void module_free_exec(struct module *mod, void *module_region);
24207 +#else
24208 +#define module_free_exec(x, y) module_free(x, y)
24209 +#endif
24210 +
24211  /* Apply the given relocation to the (simplified) ELF.  Return -error
24212     or 0. */
24213  int apply_relocate(Elf_Shdr *sechdrs,
24214 diff -urNp linux-2.6.18/include/linux/random.h linux-2.6.18/include/linux/random.h
24215 --- linux-2.6.18/include/linux/random.h 2006-09-19 23:42:06.000000000 -0400
24216 +++ linux-2.6.18/include/linux/random.h 2006-09-22 20:45:04.000000000 -0400
24217 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
24218  extern u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
24219                                        __u16 sport, __u16 dport);
24220  
24221 +extern unsigned long pax_get_random_long(void);
24222 +
24223  #ifndef MODULE
24224  extern struct file_operations random_fops, urandom_fops;
24225  #endif
24226 diff -urNp linux-2.6.18/include/linux/sched.h linux-2.6.18/include/linux/sched.h
24227 --- linux-2.6.18/include/linux/sched.h  2006-09-19 23:42:06.000000000 -0400
24228 +++ linux-2.6.18/include/linux/sched.h  2006-09-22 20:45:04.000000000 -0400
24229 @@ -85,6 +85,7 @@ struct sched_param {
24230  
24231  struct exec_domain;
24232  struct futex_pi_state;
24233 +struct linux_binprm;
24234  
24235  /*
24236   * List of flags we want to share for kernel threads,
24237 @@ -353,8 +354,34 @@ struct mm_struct {
24238         /* aio bits */
24239         rwlock_t                ioctx_list_lock;
24240         struct kioctx           *ioctx_list;
24241 +
24242 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
24243 +       unsigned long pax_flags;
24244 +#endif
24245 +
24246 +#ifdef CONFIG_PAX_DLRESOLVE
24247 +       unsigned long call_dl_resolve;
24248 +#endif
24249 +
24250 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
24251 +       unsigned long call_syscall;
24252 +#endif
24253 +
24254 +#ifdef CONFIG_PAX_ASLR
24255 +       unsigned long delta_mmap;               /* randomized offset */
24256 +       unsigned long delta_exec;               /* randomized offset */
24257 +       unsigned long delta_stack;              /* randomized offset */
24258 +#endif
24259 +
24260  };
24261  
24262 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
24263 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
24264 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
24265 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
24266 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
24267 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
24268 +
24269  struct sighand_struct {
24270         atomic_t                count;
24271         struct k_sigaction      action[_NSIG];
24272 @@ -467,6 +494,15 @@ struct signal_struct {
24273         spinlock_t stats_lock;
24274         struct taskstats *stats;
24275  #endif
24276 +
24277 +#ifdef CONFIG_GRKERNSEC
24278 +       u32 curr_ip;
24279 +       u32 gr_saddr;
24280 +       u32 gr_daddr;
24281 +       u16 gr_sport;
24282 +       u16 gr_dport;
24283 +       u8 used_accept:1;
24284 +#endif
24285  };
24286  
24287  /* Context switch must be unlocked if interrupts are to be enabled */
24288 @@ -986,6 +1022,17 @@ struct task_struct {
24289         struct list_head pi_state_list;
24290         struct futex_pi_state *pi_state_cache;
24291  
24292 +#ifdef CONFIG_GRKERNSEC
24293 +       /* grsecurity */
24294 +       struct acl_subject_label *acl;
24295 +       struct acl_role_label *role;
24296 +       struct file *exec_file;
24297 +       u16 acl_role_id;
24298 +       u8 acl_sp_role:1;
24299 +       u8 is_writable:1;
24300 +       u8 brute:1;
24301 +#endif
24302 +
24303         atomic_t fs_excl;       /* holding fs exclusive resources */
24304         struct rcu_head rcu;
24305  
24306 @@ -1515,6 +1562,12 @@ extern void arch_pick_mmap_layout(struct
24307  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
24308  {
24309         mm->mmap_base = TASK_UNMAPPED_BASE;
24310 +
24311 +#ifdef CONFIG_PAX_RANDMMAP
24312 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
24313 +               mm->mmap_base += mm->delta_mmap;
24314 +#endif
24315 +
24316         mm->get_unmapped_area = arch_get_unmapped_area;
24317         mm->unmap_area = arch_unmap_area;
24318  }
24319 diff -urNp linux-2.6.18/include/linux/shm.h linux-2.6.18/include/linux/shm.h
24320 --- linux-2.6.18/include/linux/shm.h    2006-09-19 23:42:06.000000000 -0400
24321 +++ linux-2.6.18/include/linux/shm.h    2006-09-22 20:04:35.000000000 -0400
24322 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
24323         pid_t                   shm_cprid;
24324         pid_t                   shm_lprid;
24325         struct user_struct      *mlock_user;
24326 +#ifdef CONFIG_GRKERNSEC
24327 +       time_t                  shm_createtime;
24328 +       pid_t                   shm_lapid;
24329 +#endif
24330  };
24331  
24332  /* shm_mode upper byte flags */
24333 diff -urNp linux-2.6.18/include/linux/skbuff.h linux-2.6.18/include/linux/skbuff.h
24334 --- linux-2.6.18/include/linux/skbuff.h 2006-09-19 23:42:06.000000000 -0400
24335 +++ linux-2.6.18/include/linux/skbuff.h 2006-09-22 20:45:04.000000000 -0400
24336 @@ -371,7 +371,7 @@ extern void       skb_truesize_bug(struc
24337  
24338  static inline void skb_truesize_check(struct sk_buff *skb)
24339  {
24340 -       if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
24341 +       if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
24342                 skb_truesize_bug(skb);
24343  }
24344  
24345 diff -urNp linux-2.6.18/include/linux/sysctl.h linux-2.6.18/include/linux/sysctl.h
24346 --- linux-2.6.18/include/linux/sysctl.h 2006-09-19 23:42:06.000000000 -0400
24347 +++ linux-2.6.18/include/linux/sysctl.h 2006-09-22 20:45:04.000000000 -0400
24348 @@ -150,9 +150,21 @@ enum
24349         KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */
24350         KERN_COMPAT_LOG=73,     /* int: print compat layer  messages */
24351         KERN_MAX_LOCK_DEPTH=74,
24352 -};
24353 +#ifdef CONFIG_GRKERNSEC
24354 +       KERN_GRSECURITY=98,     /* grsecurity */
24355 +#endif
24356 +
24357 +#ifdef CONFIG_PAX_SOFTMODE
24358 +       KERN_PAX=99,            /* PaX control */
24359 +#endif
24360  
24361 +};
24362  
24363 +#ifdef CONFIG_PAX_SOFTMODE
24364 +enum {
24365 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
24366 +};
24367 +#endif
24368  
24369  /* CTL_VM names: */
24370  enum
24371 diff -urNp linux-2.6.18/include/linux/udf_fs.h linux-2.6.18/include/linux/udf_fs.h
24372 --- linux-2.6.18/include/linux/udf_fs.h 2006-09-19 23:42:06.000000000 -0400
24373 +++ linux-2.6.18/include/linux/udf_fs.h 2006-09-22 20:45:04.000000000 -0400
24374 @@ -45,7 +45,7 @@
24375                 printk (f, ##a); \
24376         }
24377  #else
24378 -#define udf_debug(f, a...) /**/
24379 +#define udf_debug(f, a...) do {} while (0)
24380  #endif
24381  
24382  #define udf_info(f, a...) \
24383 diff -urNp linux-2.6.18/include/net/sctp/sctp.h linux-2.6.18/include/net/sctp/sctp.h
24384 --- linux-2.6.18/include/net/sctp/sctp.h        2006-09-19 23:42:06.000000000 -0400
24385 +++ linux-2.6.18/include/net/sctp/sctp.h        2006-09-22 20:45:04.000000000 -0400
24386 @@ -250,8 +250,8 @@ extern int sctp_debug_flag;
24387  
24388  #else  /* SCTP_DEBUG */
24389  
24390 -#define SCTP_DEBUG_PRINTK(whatever...)
24391 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
24392 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
24393 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
24394  #define SCTP_ENABLE_DEBUG
24395  #define SCTP_DISABLE_DEBUG
24396  #define SCTP_ASSERT(expr, str, func)
24397 diff -urNp linux-2.6.18/include/sound/core.h linux-2.6.18/include/sound/core.h
24398 --- linux-2.6.18/include/sound/core.h   2006-09-19 23:42:06.000000000 -0400
24399 +++ linux-2.6.18/include/sound/core.h   2006-09-22 20:45:04.000000000 -0400
24400 @@ -349,9 +349,9 @@ void snd_verbose_printd(const char *file
24401  
24402  #else /* !CONFIG_SND_DEBUG */
24403  
24404 -#define snd_printd(fmt, args...)       /* nothing */
24405 +#define snd_printd(fmt, args...)       do {} while (0)
24406  #define snd_assert(expr, args...)      (void)(expr)
24407 -#define snd_BUG()                      /* nothing */
24408 +#define snd_BUG()                      do {} while (0)
24409  
24410  #endif /* CONFIG_SND_DEBUG */
24411  
24412 diff -urNp linux-2.6.18/init/Kconfig linux-2.6.18/init/Kconfig
24413 --- linux-2.6.18/init/Kconfig   2006-09-19 23:42:06.000000000 -0400
24414 +++ linux-2.6.18/init/Kconfig   2006-09-22 20:04:35.000000000 -0400
24415 @@ -292,6 +292,7 @@ config SYSCTL
24416  config KALLSYMS
24417          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
24418          default y
24419 +        depends on !GRKERNSEC_HIDESYM
24420          help
24421            Say Y here to let the kernel print out symbolic crash information and
24422            symbolic stack backtraces. This increases the size of the kernel
24423 diff -urNp linux-2.6.18/init/main.c linux-2.6.18/init/main.c
24424 --- linux-2.6.18/init/main.c    2006-09-19 23:42:06.000000000 -0400
24425 +++ linux-2.6.18/init/main.c    2006-09-22 20:45:04.000000000 -0400
24426 @@ -103,6 +103,7 @@ static inline void mark_rodata_ro(void) 
24427  #ifdef CONFIG_TC
24428  extern void tc_init(void);
24429  #endif
24430 +extern void grsecurity_init(void);
24431  
24432  enum system_states system_state;
24433  EXPORT_SYMBOL(system_state);
24434 @@ -153,6 +154,15 @@ static int __init maxcpus(char *str)
24435  
24436  __setup("maxcpus=", maxcpus);
24437  
24438 +#ifdef CONFIG_PAX_SOFTMODE
24439 +static int __init setup_pax_softmode(char *str)
24440 +{
24441 +       get_option(&str, &pax_softmode);
24442 +       return 1;
24443 +}
24444 +__setup("pax_softmode=", setup_pax_softmode);
24445 +#endif
24446 +
24447  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
24448  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
24449  static const char *panic_later, *panic_param;
24450 @@ -729,6 +739,8 @@ static int init(void * unused)
24451                 prepare_namespace();
24452         }
24453  
24454 +       grsecurity_init();
24455 +
24456         /*
24457          * Ok, we have completed the initial bootup, and
24458          * we're essentially up and running. Get rid of the
24459 diff -urNp linux-2.6.18/ipc/msg.c linux-2.6.18/ipc/msg.c
24460 --- linux-2.6.18/ipc/msg.c      2006-09-19 23:42:06.000000000 -0400
24461 +++ linux-2.6.18/ipc/msg.c      2006-09-22 20:08:16.000000000 -0400
24462 @@ -31,6 +31,7 @@
24463  #include <linux/audit.h>
24464  #include <linux/seq_file.h>
24465  #include <linux/mutex.h>
24466 +#include <linux/grsecurity.h>
24467  
24468  #include <asm/current.h>
24469  #include <asm/uaccess.h>
24470 @@ -239,6 +240,8 @@ asmlinkage long sys_msgget(key_t key, in
24471         }
24472         mutex_unlock(&msg_ids.mutex);
24473  
24474 +       gr_log_msgget(ret, msgflg);
24475 +
24476         return ret;
24477  }
24478  
24479 @@ -503,6 +506,7 @@ asmlinkage long sys_msgctl(int msqid, in
24480                 break;
24481         }
24482         case IPC_RMID:
24483 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
24484                 freeque(msq, msqid);
24485                 break;
24486         }
24487 diff -urNp linux-2.6.18/ipc/sem.c linux-2.6.18/ipc/sem.c
24488 --- linux-2.6.18/ipc/sem.c      2006-09-19 23:42:06.000000000 -0400
24489 +++ linux-2.6.18/ipc/sem.c      2006-09-22 20:04:35.000000000 -0400
24490 @@ -78,6 +78,7 @@
24491  #include <linux/seq_file.h>
24492  #include <linux/mutex.h>
24493  #include <linux/vs_limit.h>
24494 +#include <linux/grsecurity.h>
24495  
24496  #include <asm/uaccess.h>
24497  #include "util.h"
24498 @@ -246,6 +247,9 @@ asmlinkage long sys_semget (key_t key, i
24499         }
24500  
24501         mutex_unlock(&sem_ids.mutex);
24502 +
24503 +       gr_log_semget(err, semflg);
24504 +
24505         return err;
24506  }
24507  
24508 @@ -844,6 +848,8 @@ static int semctl_down(int semid, int se
24509  
24510         switch(cmd){
24511         case IPC_RMID:
24512 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
24513 +
24514                 freeary(sma, semid);
24515                 err = 0;
24516                 break;
24517 diff -urNp linux-2.6.18/ipc/shm.c linux-2.6.18/ipc/shm.c
24518 --- linux-2.6.18/ipc/shm.c      2006-09-19 23:42:06.000000000 -0400
24519 +++ linux-2.6.18/ipc/shm.c      2006-09-22 20:04:35.000000000 -0400
24520 @@ -32,6 +32,7 @@
24521  #include <linux/mutex.h>
24522  #include <linux/vs_context.h>
24523  #include <linux/vs_limit.h>
24524 +#include <linux/grsecurity.h>
24525  
24526  #include <asm/uaccess.h>
24527  
24528 @@ -55,6 +56,14 @@ static void shm_close (struct vm_area_st
24529  static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
24530  #endif
24531  
24532 +#ifdef CONFIG_GRKERNSEC
24533 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
24534 +                          const time_t shm_createtime, const uid_t cuid,
24535 +                          const int shmid);
24536 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
24537 +                          const time_t shm_createtime);
24538 +#endif
24539 +
24540  size_t shm_ctlmax = SHMMAX;
24541  size_t         shm_ctlall = SHMALL;
24542  int    shm_ctlmni = SHMMNI;
24543 @@ -148,6 +157,17 @@ static void shm_close (struct vm_area_st
24544         shp->shm_lprid = current->tgid;
24545         shp->shm_dtim = get_seconds();
24546         shp->shm_nattch--;
24547 +#ifdef CONFIG_GRKERNSEC_SHM
24548 +       if (grsec_enable_shm) {
24549 +               if (shp->shm_nattch == 0) {
24550 +                       shp->shm_perm.mode |= SHM_DEST;
24551 +                       shm_destroy(shp);
24552 +               } else
24553 +                       shm_unlock(shp);
24554 +               mutex_unlock(&shm_ids.mutex);
24555 +               return;
24556 +       }
24557 +#endif
24558         if(shp->shm_nattch == 0 &&
24559            shp->shm_perm.mode & SHM_DEST)
24560                 shm_destroy (shp);
24561 @@ -247,6 +267,9 @@ static int newseg (key_t key, int shmflg
24562         shp->shm_lprid = 0;
24563         shp->shm_atim = shp->shm_dtim = 0;
24564         shp->shm_ctim = get_seconds();
24565 +#ifdef CONFIG_GRKERNSEC
24566 +       shp->shm_createtime = get_seconds();
24567 +#endif
24568         shp->shm_segsz = size;
24569         shp->shm_nattch = 0;
24570         shp->id = shm_buildid(id,shp->shm_perm.seq);
24571 @@ -301,6 +324,8 @@ asmlinkage long sys_shmget (key_t key, s
24572         }
24573         mutex_unlock(&shm_ids.mutex);
24574  
24575 +       gr_log_shmget(err, shmflg, size);
24576 +
24577         return err;
24578  }
24579  
24580 @@ -614,6 +639,8 @@ asmlinkage long sys_shmctl (int shmid, i
24581                 if (err)
24582                         goto out_unlock_up;
24583  
24584 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
24585 +
24586                 if (shp->shm_nattch){
24587                         shp->shm_perm.mode |= SHM_DEST;
24588                         /* Do not find it any more */
24589 @@ -759,9 +786,27 @@ long do_shmat(int shmid, char __user *sh
24590                 return err;
24591         }
24592                 
24593 +#ifdef CONFIG_GRKERNSEC
24594 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
24595 +                            shp->shm_perm.cuid, shmid)) {
24596 +               shm_unlock(shp);
24597 +               return -EACCES;
24598 +       }
24599 +
24600 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
24601 +               shm_unlock(shp);
24602 +               return -EACCES;
24603 +       }
24604 +#endif
24605 +
24606         file = shp->shm_file;
24607         size = i_size_read(file->f_dentry->d_inode);
24608         shp->shm_nattch++;
24609 +
24610 +#ifdef CONFIG_GRKERNSEC
24611 +       shp->shm_lapid = current->pid;
24612 +#endif
24613 +
24614         shm_unlock(shp);
24615  
24616         down_write(&current->mm->mmap_sem);
24617 @@ -931,3 +976,24 @@ static int sysvipc_shm_proc_show(struct 
24618                           shp->shm_ctim);
24619  }
24620  #endif
24621 +
24622 +void gr_shm_exit(struct task_struct *task)
24623 +{
24624 +#ifdef CONFIG_GRKERNSEC_SHM
24625 +       int i;
24626 +       struct shmid_kernel *shp;
24627 +
24628 +       if (!grsec_enable_shm)
24629 +               return;
24630 +
24631 +       for (i = 0; i <= shm_ids.max_id; i++) {
24632 +               shp = shm_get(i);
24633 +               if (shp && (shp->shm_cprid == task->pid) &&
24634 +                   (shp->shm_nattch <= 0)) {
24635 +                       shp->shm_perm.mode |= SHM_DEST;
24636 +                       shm_destroy(shp);
24637 +               }
24638 +       }
24639 +#endif
24640 +       return;
24641 +}
24642 diff -urNp linux-2.6.18/kernel/capability.c linux-2.6.18/kernel/capability.c
24643 --- linux-2.6.18/kernel/capability.c    2006-09-19 23:42:06.000000000 -0400
24644 +++ linux-2.6.18/kernel/capability.c    2006-09-22 20:04:35.000000000 -0400
24645 @@ -12,6 +12,7 @@
24646  #include <linux/security.h>
24647  #include <linux/syscalls.h>
24648  #include <linux/vs_pid.h>
24649 +#include <linux/grsecurity.h>
24650  #include <asm/uaccess.h>
24651  
24652  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
24653 @@ -234,14 +235,25 @@ out:
24654       return ret;
24655  }
24656  
24657 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
24658 +extern int gr_is_capable_nolog(const int cap);
24659 +
24660  int __capable(struct task_struct *t, int cap)
24661  {
24662 -       if (security_capable(t, cap) == 0) {
24663 +       if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
24664                 t->flags |= PF_SUPERPRIV;
24665                 return 1;
24666         }
24667         return 0;
24668  }
24669 +int capable_nolog(int cap)
24670 +{
24671 +       if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
24672 +               current->flags |= PF_SUPERPRIV;
24673 +               return 1;
24674 +       }
24675 +       return 0;
24676 +}
24677  EXPORT_SYMBOL(__capable);
24678  
24679  int capable(int cap)
24680 @@ -249,3 +261,4 @@ int capable(int cap)
24681         return __capable(current, cap);
24682  }
24683  EXPORT_SYMBOL(capable);
24684 +EXPORT_SYMBOL(capable_nolog);
24685 diff -urNp linux-2.6.18/kernel/configs.c linux-2.6.18/kernel/configs.c
24686 --- linux-2.6.18/kernel/configs.c       2006-09-19 23:42:06.000000000 -0400
24687 +++ linux-2.6.18/kernel/configs.c       2006-09-22 20:04:35.000000000 -0400
24688 @@ -88,8 +88,16 @@ static int __init ikconfig_init(void)
24689         struct proc_dir_entry *entry;
24690  
24691         /* create the current config file */
24692 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
24693 +#ifdef CONFIG_GRKERNSEC_PROC_USER
24694 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
24695 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
24696 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
24697 +#endif
24698 +#else
24699         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
24700                                   &proc_root);
24701 +#endif
24702         if (!entry)
24703                 return -ENOMEM;
24704  
24705 diff -urNp linux-2.6.18/kernel/exit.c linux-2.6.18/kernel/exit.c
24706 --- linux-2.6.18/kernel/exit.c  2006-09-19 23:42:06.000000000 -0400
24707 +++ linux-2.6.18/kernel/exit.c  2006-09-22 20:21:45.000000000 -0400
24708 @@ -38,6 +38,11 @@
24709  #include <linux/vs_context.h>
24710  #include <linux/vs_network.h>
24711  #include <linux/vs_pid.h>
24712 +#include <linux/grsecurity.h>
24713 +
24714 +#ifdef CONFIG_GRKERNSEC
24715 +extern rwlock_t grsec_exec_file_lock;
24716 +#endif
24717  
24718  #include <asm/uaccess.h>
24719  #include <asm/unistd.h>
24720 @@ -115,6 +120,7 @@ static void __exit_signal(struct task_st
24721  
24722         __unhash_process(tsk);
24723  
24724 +       gr_del_task_from_ip_table(tsk);
24725         tsk->signal = NULL;
24726         tsk->sighand = NULL;
24727         spin_unlock(&sighand->siglock);
24728 @@ -282,6 +288,15 @@ static void reparent_to_init(void)
24729  {
24730         write_lock_irq(&tasklist_lock);
24731  
24732 +#ifdef CONFIG_GRKERNSEC
24733 +       write_lock(&grsec_exec_file_lock);
24734 +       if (current->exec_file) {
24735 +               fput(current->exec_file);
24736 +               current->exec_file = NULL;
24737 +       }
24738 +       write_unlock(&grsec_exec_file_lock);
24739 +#endif
24740 +
24741         ptrace_unlink(current);
24742         /* Reparent to init */
24743         remove_parent(current);
24744 @@ -289,6 +304,8 @@ static void reparent_to_init(void)
24745         current->real_parent = child_reaper;
24746         add_parent(current);
24747  
24748 +       gr_set_kernel_label(current);
24749 +
24750         /* Set the exit signal to SIGCHLD so we signal init on exit */
24751         current->exit_signal = SIGCHLD;
24752  
24753 @@ -385,6 +402,17 @@ void daemonize(const char *name, ...)
24754         vsnprintf(current->comm, sizeof(current->comm), name, args);
24755         va_end(args);
24756  
24757 +#ifdef CONFIG_GRKERNSEC
24758 +       write_lock(&grsec_exec_file_lock);
24759 +       if (current->exec_file) {
24760 +               fput(current->exec_file);
24761 +               current->exec_file = NULL;
24762 +       }
24763 +       write_unlock(&grsec_exec_file_lock);
24764 +#endif
24765 +
24766 +       gr_set_kernel_label(current);
24767 +
24768         /*
24769          * If we were started as result of loading a module, close all of the
24770          * user space pages.  We don't need them, and if we didn't close them
24771 @@ -909,11 +937,15 @@ fastcall NORET_TYPE void do_exit(long co
24772         taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
24773         taskstats_exit_free(tidstats);
24774  
24775 +       gr_acl_handle_psacct(tsk, code);
24776 +       gr_acl_handle_exit();
24777 +
24778         exit_mm(tsk);
24779  
24780         if (group_dead)
24781                 acct_process();
24782         exit_sem(tsk);
24783 +       gr_shm_exit(tsk);
24784         __exit_files(tsk);
24785         __exit_fs(tsk);
24786         exit_namespace(tsk);
24787 diff -urNp linux-2.6.18/kernel/fork.c linux-2.6.18/kernel/fork.c
24788 --- linux-2.6.18/kernel/fork.c  2006-09-19 23:42:06.000000000 -0400
24789 +++ linux-2.6.18/kernel/fork.c  2006-09-22 20:45:04.000000000 -0400
24790 @@ -45,6 +45,7 @@
24791  #include <linux/vs_network.h>
24792  #include <linux/vs_limit.h>
24793  #include <linux/vs_memory.h>
24794 +#include <linux/grsecurity.h>
24795  
24796  #include <asm/pgtable.h>
24797  #include <asm/pgalloc.h>
24798 @@ -202,8 +203,8 @@ static inline int dup_mmap(struct mm_str
24799         mm->locked_vm = 0;
24800         mm->mmap = NULL;
24801         mm->mmap_cache = NULL;
24802 -       mm->free_area_cache = oldmm->mmap_base;
24803 -       mm->cached_hole_size = ~0UL;
24804 +       mm->free_area_cache = oldmm->free_area_cache;
24805 +       mm->cached_hole_size = oldmm->cached_hole_size;
24806         mm->map_count = 0;
24807         cpus_clear(mm->cpu_vm_mask);
24808         mm->mm_rb = RB_ROOT;
24809 @@ -328,7 +329,7 @@ static struct mm_struct * mm_init(struct
24810         spin_lock_init(&mm->page_table_lock);
24811         rwlock_init(&mm->ioctx_list_lock);
24812         mm->ioctx_list = NULL;
24813 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
24814 +       mm->free_area_cache = ~0UL;
24815         mm->cached_hole_size = ~0UL;
24816  
24817         if (likely(!mm_alloc_pgd(mm))) {
24818 @@ -980,6 +981,8 @@ static struct task_struct *copy_process(
24819         if (!vx_nproc_avail(1))
24820                 goto bad_fork_cleanup_vm;
24821  
24822 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
24823 +
24824         if (atomic_read(&p->user->processes) >=
24825                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
24826                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
24827 @@ -1110,6 +1114,8 @@ static struct task_struct *copy_process(
24828         if (retval)
24829                 goto bad_fork_cleanup_namespace;
24830  
24831 +       gr_copy_label(p);
24832 +
24833         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
24834         /*
24835          * Clear TID on mm_release()?
24836 @@ -1291,6 +1297,8 @@ bad_fork_cleanup_count:
24837  bad_fork_free:
24838         free_task(p);
24839  fork_out:
24840 +       gr_log_forkfail(retval);
24841 +
24842         return ERR_PTR(retval);
24843  }
24844  
24845 @@ -1364,6 +1372,8 @@ long do_fork(unsigned long clone_flags,
24846         if (!IS_ERR(p)) {
24847                 struct completion vfork;
24848  
24849 +               gr_handle_brute_check();
24850 +
24851                 if (clone_flags & CLONE_VFORK) {
24852                         p->vfork_done = &vfork;
24853                         init_completion(&vfork);
24854 diff -urNp linux-2.6.18/kernel/futex.c linux-2.6.18/kernel/futex.c
24855 --- linux-2.6.18/kernel/futex.c 2006-09-19 23:42:06.000000000 -0400
24856 +++ linux-2.6.18/kernel/futex.c 2006-09-22 20:45:04.000000000 -0400
24857 @@ -183,6 +183,11 @@ static int get_futex_key(u32 __user *uad
24858         struct page *page;
24859         int err;
24860  
24861 +#ifdef CONFIG_PAX_SEGMEXEC
24862 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((unsigned long)uaddr >= SEGMEXEC_TASK_SIZE))
24863 +               return -EFAULT;
24864 +#endif
24865 +
24866         /*
24867          * The futex address must be "naturally" aligned.
24868          */
24869 diff -urNp linux-2.6.18/kernel/kallsyms.c linux-2.6.18/kernel/kallsyms.c
24870 --- linux-2.6.18/kernel/kallsyms.c      2006-09-19 23:42:06.000000000 -0400
24871 +++ linux-2.6.18/kernel/kallsyms.c      2006-09-22 20:45:04.000000000 -0400
24872 @@ -301,7 +301,6 @@ static unsigned long get_ksymbol_core(st
24873  
24874  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
24875  {
24876 -       iter->name[0] = '\0';
24877         iter->nameoff = get_symbol_offset(new_pos);
24878         iter->pos = new_pos;
24879  }
24880 @@ -380,7 +379,7 @@ static int kallsyms_open(struct inode *i
24881         struct kallsym_iter *iter;
24882         int ret;
24883  
24884 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
24885 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
24886         if (!iter)
24887                 return -ENOMEM;
24888         reset_iter(iter, 0);
24889 @@ -411,7 +410,15 @@ static int __init kallsyms_init(void)
24890  {
24891         struct proc_dir_entry *entry;
24892  
24893 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
24894 +#ifdef CONFIG_GRKERNSEC_PROC_USER
24895 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
24896 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
24897 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
24898 +#endif
24899 +#else
24900         entry = create_proc_entry("kallsyms", 0444, NULL);
24901 +#endif
24902         if (entry)
24903                 entry->proc_fops = &kallsyms_operations;
24904         return 0;
24905 diff -urNp linux-2.6.18/kernel/kprobes.c linux-2.6.18/kernel/kprobes.c
24906 --- linux-2.6.18/kernel/kprobes.c       2006-09-19 23:42:06.000000000 -0400
24907 +++ linux-2.6.18/kernel/kprobes.c       2006-09-22 20:45:04.000000000 -0400
24908 @@ -112,7 +112,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
24909          * kernel image and loaded module images reside. This is required
24910          * so x86_64 can correctly handle the %rip-relative fixups.
24911          */
24912 -       kip->insns = module_alloc(PAGE_SIZE);
24913 +       kip->insns = module_alloc_exec(PAGE_SIZE);
24914         if (!kip->insns) {
24915                 kfree(kip);
24916                 return NULL;
24917 diff -urNp linux-2.6.18/kernel/module.c linux-2.6.18/kernel/module.c
24918 --- linux-2.6.18/kernel/module.c        2006-09-19 23:42:06.000000000 -0400
24919 +++ linux-2.6.18/kernel/module.c        2006-09-22 20:45:04.000000000 -0400
24920 @@ -43,6 +43,11 @@
24921  #include <asm/uaccess.h>
24922  #include <asm/semaphore.h>
24923  #include <asm/cacheflush.h>
24924 +
24925 +#ifdef CONFIG_PAX_KERNEXEC
24926 +#include <asm/desc.h>
24927 +#endif
24928 +
24929  #include <linux/license.h>
24930  
24931  #if 0
24932 @@ -67,6 +72,8 @@ static LIST_HEAD(modules);
24933  
24934  static BLOCKING_NOTIFIER_HEAD(module_notify_list);
24935  
24936 +extern int gr_check_modstop(void);
24937 +
24938  int register_module_notifier(struct notifier_block * nb)
24939  {
24940         return blocking_notifier_chain_register(&module_notify_list, nb);
24941 @@ -650,6 +657,9 @@ sys_delete_module(const char __user *nam
24942         char name[MODULE_NAME_LEN];
24943         int ret, forced = 0;
24944  
24945 +       if (gr_check_modstop())
24946 +               return -EPERM;
24947 +
24948         if (!capable(CAP_SYS_MODULE))
24949                 return -EPERM;
24950  
24951 @@ -1116,7 +1126,8 @@ static void free_module(struct module *m
24952         module_unload_free(mod);
24953  
24954         /* This may be NULL, but that's OK */
24955 -       module_free(mod, mod->module_init);
24956 +       module_free(mod, mod->module_init_rw);
24957 +       module_free_exec(mod, mod->module_init_rx);
24958         kfree(mod->args);
24959         if (mod->percpu)
24960                 percpu_modfree(mod->percpu);
24961 @@ -1125,7 +1136,8 @@ static void free_module(struct module *m
24962         lockdep_free_key_range(mod->module_core, mod->core_size);
24963  
24964         /* Finally, free the core (containing the module structure) */
24965 -       module_free(mod, mod->module_core);
24966 +       module_free_exec(mod, mod->module_core_rx);
24967 +       module_free(mod, mod->module_core_rw);
24968  }
24969  
24970  void *__symbol_get(const char *symbol)
24971 @@ -1282,11 +1294,14 @@ static void layout_sections(struct modul
24972                             || strncmp(secstrings + s->sh_name,
24973                                        ".init", 5) == 0)
24974                                 continue;
24975 -                       s->sh_entsize = get_offset(&mod->core_size, s);
24976 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
24977 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
24978 +                       else
24979 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
24980                         DEBUGP("\t%s\n", secstrings + s->sh_name);
24981                 }
24982                 if (m == 0)
24983 -                       mod->core_text_size = mod->core_size;
24984 +                       mod->core_size_rx = mod->core_size_rx;
24985         }
24986  
24987         DEBUGP("Init section allocation order:\n");
24988 @@ -1300,12 +1315,15 @@ static void layout_sections(struct modul
24989                             || strncmp(secstrings + s->sh_name,
24990                                        ".init", 5) != 0)
24991                                 continue;
24992 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
24993 -                                        | INIT_OFFSET_MASK);
24994 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
24995 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
24996 +                       else
24997 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
24998 +                       s->sh_entsize |= INIT_OFFSET_MASK;
24999                         DEBUGP("\t%s\n", secstrings + s->sh_name);
25000                 }
25001                 if (m == 0)
25002 -                       mod->init_text_size = mod->init_size;
25003 +                       mod->init_size_rx = mod->init_size_rx;
25004         }
25005  }
25006  
25007 @@ -1487,6 +1505,10 @@ static struct module *load_module(void _
25008         struct exception_table_entry *extable;
25009         mm_segment_t old_fs;
25010  
25011 +#ifdef CONFIG_PAX_KERNEXEC
25012 +       unsigned long cr0;
25013 +#endif
25014 +
25015         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
25016                umod, len, uargs);
25017         if (len < sizeof(*hdr))
25018 @@ -1645,21 +1667,57 @@ static struct module *load_module(void _
25019         layout_sections(mod, hdr, sechdrs, secstrings);
25020  
25021         /* Do the allocs. */
25022 -       ptr = module_alloc(mod->core_size);
25023 +       ptr = module_alloc(mod->core_size_rw);
25024         if (!ptr) {
25025                 err = -ENOMEM;
25026                 goto free_percpu;
25027         }
25028 -       memset(ptr, 0, mod->core_size);
25029 -       mod->module_core = ptr;
25030 +       memset(ptr, 0, mod->core_size_rw);
25031 +       mod->module_core_rw = ptr;
25032 +
25033 +       ptr = module_alloc(mod->init_size_rw);
25034 +       if (!ptr && mod->init_size_rw) {
25035 +               err = -ENOMEM;
25036 +               goto free_core_rw;
25037 +       }
25038 +       memset(ptr, 0, mod->init_size_rw);
25039 +       mod->module_init_rw = ptr;
25040 +
25041 +       ptr = module_alloc_exec(mod->core_size_rx);
25042 +       if (!ptr) {
25043 +               err = -ENOMEM;
25044 +               goto free_init_rw;
25045 +       }
25046  
25047 -       ptr = module_alloc(mod->init_size);
25048 -       if (!ptr && mod->init_size) {
25049 +#ifdef CONFIG_PAX_KERNEXEC
25050 +       pax_open_kernel(cr0);
25051 +#endif
25052 +
25053 +       memset(ptr, 0, mod->core_size_rx);
25054 +
25055 +#ifdef CONFIG_PAX_KERNEXEC
25056 +       pax_close_kernel(cr0);
25057 +#endif
25058 +
25059 +       mod->module_core_rx = ptr;
25060 +
25061 +       ptr = module_alloc_exec(mod->init_size_rx);
25062 +       if (!ptr && mod->init_size_rx) {
25063                 err = -ENOMEM;
25064 -               goto free_core;
25065 +               goto free_core_rx;
25066         }
25067 -       memset(ptr, 0, mod->init_size);
25068 -       mod->module_init = ptr;
25069 +
25070 +#ifdef CONFIG_PAX_KERNEXEC
25071 +       pax_open_kernel(cr0);
25072 +#endif
25073 +
25074 +       memset(ptr, 0, mod->init_size_rx);
25075 +
25076 +#ifdef CONFIG_PAX_KERNEXEC
25077 +       pax_close_kernel(cr0);
25078 +#endif
25079 +
25080 +       mod->module_init_rx = ptr;
25081  
25082         /* Transfer each section which specifies SHF_ALLOC */
25083         DEBUGP("final section addresses:\n");
25084 @@ -1669,17 +1727,44 @@ static struct module *load_module(void _
25085                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
25086                         continue;
25087  
25088 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
25089 -                       dest = mod->module_init
25090 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
25091 -               else
25092 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
25093 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
25094 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
25095 +                               dest = mod->module_init_rw
25096 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
25097 +                       else
25098 +                               dest = mod->module_init_rx
25099 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
25100 +               } else {
25101 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
25102 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
25103 +                       else
25104 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
25105 +               }
25106 +
25107 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
25108  
25109 -               if (sechdrs[i].sh_type != SHT_NOBITS)
25110 -                       memcpy(dest, (void *)sechdrs[i].sh_addr,
25111 -                              sechdrs[i].sh_size);
25112 +#ifdef CONFIG_PAX_KERNEXEC
25113 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
25114 +                               pax_open_kernel(cr0);
25115 +#endif
25116 +
25117 +                       memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
25118 +
25119 +#ifdef CONFIG_PAX_KERNEXEC
25120 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
25121 +                               pax_close_kernel(cr0);
25122 +#endif
25123 +
25124 +               }
25125                 /* Update sh_addr to point to copy in image. */
25126 -               sechdrs[i].sh_addr = (unsigned long)dest;
25127 +
25128 +#ifdef CONFIG_PAX_KERNEXEC
25129 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
25130 +                       sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
25131 +               else
25132 +#endif
25133 +
25134 +                       sechdrs[i].sh_addr = (unsigned long)dest;
25135                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
25136         }
25137         /* Module has been moved. */
25138 @@ -1700,8 +1785,18 @@ static struct module *load_module(void _
25139         setup_modinfo(mod, sechdrs, infoindex);
25140  
25141         /* Fix up syms, so that st_value is a pointer to location. */
25142 +
25143 +#ifdef CONFIG_PAX_KERNEXEC
25144 +       pax_open_kernel(cr0);
25145 +#endif
25146 +
25147         err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
25148                                mod);
25149 +
25150 +#ifdef CONFIG_PAX_KERNEXEC
25151 +       pax_close_kernel(cr0);
25152 +#endif
25153 +
25154         if (err < 0)
25155                 goto cleanup;
25156  
25157 @@ -1756,11 +1851,20 @@ static struct module *load_module(void _
25158                 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
25159                         continue;
25160  
25161 +#ifdef CONFIG_PAX_KERNEXEC
25162 +       pax_open_kernel(cr0);
25163 +#endif
25164 +
25165                 if (sechdrs[i].sh_type == SHT_REL)
25166                         err = apply_relocate(sechdrs, strtab, symindex, i,mod);
25167                 else if (sechdrs[i].sh_type == SHT_RELA)
25168                         err = apply_relocate_add(sechdrs, strtab, symindex, i,
25169                                                  mod);
25170 +
25171 +#ifdef CONFIG_PAX_KERNEXEC
25172 +       pax_close_kernel(cr0);
25173 +#endif
25174 +
25175                 if (err < 0)
25176                         goto cleanup;
25177         }
25178 @@ -1774,14 +1878,31 @@ static struct module *load_module(void _
25179         /* Set up and sort exception table */
25180         mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
25181         mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
25182 +
25183 +#ifdef CONFIG_PAX_KERNEXEC
25184 +       pax_open_kernel(cr0);
25185 +#endif
25186 +
25187         sort_extable(extable, extable + mod->num_exentries);
25188  
25189 +#ifdef CONFIG_PAX_KERNEXEC
25190 +       pax_close_kernel(cr0);
25191 +#endif
25192 +
25193         /* Finally, copy percpu area over. */
25194         percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
25195                        sechdrs[pcpuindex].sh_size);
25196  
25197 +#ifdef CONFIG_PAX_KERNEXEC
25198 +       pax_open_kernel(cr0);
25199 +#endif
25200 +
25201         add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
25202  
25203 +#ifdef CONFIG_PAX_KERNEXEC
25204 +       pax_close_kernel(cr0);
25205 +#endif
25206 +
25207         err = module_finalize(hdr, sechdrs, mod);
25208         if (err < 0)
25209                 goto cleanup;
25210 @@ -1795,12 +1916,12 @@ static struct module *load_module(void _
25211          * Do it before processing of module parameters, so the module
25212          * can provide parameter accessor functions of its own.
25213          */
25214 -       if (mod->module_init)
25215 -               flush_icache_range((unsigned long)mod->module_init,
25216 -                                  (unsigned long)mod->module_init
25217 -                                  + mod->init_size);
25218 -       flush_icache_range((unsigned long)mod->module_core,
25219 -                          (unsigned long)mod->module_core + mod->core_size);
25220 +       if (mod->module_init_rx)
25221 +               flush_icache_range((unsigned long)mod->module_init_rx,
25222 +                                  (unsigned long)mod->module_init_rx
25223 +                                  + mod->init_size_rx);
25224 +       flush_icache_range((unsigned long)mod->module_core_rx,
25225 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
25226  
25227         set_fs(old_fs);
25228  
25229 @@ -1843,9 +1964,13 @@ static struct module *load_module(void _
25230         module_arch_cleanup(mod);
25231   cleanup:
25232         module_unload_free(mod);
25233 -       module_free(mod, mod->module_init);
25234 - free_core:
25235 -       module_free(mod, mod->module_core);
25236 +       module_free_exec(mod, mod->module_init_rx);
25237 + free_core_rx:
25238 +       module_free_exec(mod, mod->module_core_rx);
25239 + free_init_rw:
25240 +       module_free(mod, mod->module_init_rw);
25241 + free_core_rw:
25242 +       module_free(mod, mod->module_core_rw);
25243   free_percpu:
25244         if (percpu)
25245                 percpu_modfree(percpu);
25246 @@ -1881,6 +2006,9 @@ sys_init_module(void __user *umod,
25247         struct module *mod;
25248         int ret = 0;
25249  
25250 +       if (gr_check_modstop())
25251 +               return -EPERM;
25252 +
25253         /* Must have permission */
25254         if (!capable(CAP_SYS_MODULE))
25255                 return -EPERM;
25256 @@ -1932,10 +2060,12 @@ sys_init_module(void __user *umod,
25257         /* Drop initial reference. */
25258         module_put(mod);
25259         unwind_remove_table(mod->unwind_info, 1);
25260 -       module_free(mod, mod->module_init);
25261 -       mod->module_init = NULL;
25262 -       mod->init_size = 0;
25263 -       mod->init_text_size = 0;
25264 +       module_free(mod, mod->module_init_rw);
25265 +       module_free_exec(mod, mod->module_init_rx);
25266 +       mod->module_init_rw = NULL;
25267 +       mod->module_init_rx = NULL;
25268 +       mod->init_size_rw = 0;
25269 +       mod->init_size_rx = 0;
25270         mutex_unlock(&module_mutex);
25271  
25272         return 0;
25273 @@ -1966,10 +2096,14 @@ static const char *get_ksymbol(struct mo
25274         unsigned long nextval;
25275  
25276         /* At worse, next value is at end of module */
25277 -       if (within(addr, mod->module_init, mod->init_size))
25278 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
25279 -       else 
25280 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
25281 +       if (within(addr, mod->module_init_rx, mod->init_size_rx))
25282 +               nextval = (unsigned long)mod->module_init_rw;
25283 +       else if (within(addr, mod->module_init_rw, mod->init_size_rw))
25284 +               nextval = (unsigned long)mod->module_core_rx;
25285 +       else if (within(addr, mod->module_core_rx, mod->core_size_rx))
25286 +               nextval = (unsigned long)mod->module_core_rw;
25287 +       else
25288 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
25289  
25290         /* Scan for closest preceeding symbol, and next symbol. (ELF
25291             starts real symbols at 1). */
25292 @@ -2010,8 +2144,10 @@ const char *module_address_lookup(unsign
25293         struct module *mod;
25294  
25295         list_for_each_entry(mod, &modules, list) {
25296 -               if (within(addr, mod->module_init, mod->init_size)
25297 -                   || within(addr, mod->module_core, mod->core_size)) {
25298 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
25299 +                   || within(addr, mod->module_init_rw, mod->init_size_rw)
25300 +                   || within(addr, mod->module_core_rx, mod->core_size_rx)
25301 +                   || within(addr, mod->module_core_rw, mod->core_size_rw)) {
25302                         *modname = mod->name;
25303                         return get_ksymbol(mod, addr, size, offset);
25304                 }
25305 @@ -2107,7 +2243,7 @@ static int m_show(struct seq_file *m, vo
25306  {
25307         struct module *mod = list_entry(p, struct module, list);
25308         seq_printf(m, "%s %lu",
25309 -                  mod->name, mod->init_size + mod->core_size);
25310 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
25311         print_unload_info(m, mod);
25312  
25313         /* Informative for users. */
25314 @@ -2116,7 +2252,7 @@ static int m_show(struct seq_file *m, vo
25315                    mod->state == MODULE_STATE_COMING ? "Loading":
25316                    "Live");
25317         /* Used by oprofile and other similar tools. */
25318 -       seq_printf(m, " 0x%p", mod->module_core);
25319 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
25320  
25321         seq_printf(m, "\n");
25322         return 0;
25323 @@ -2170,7 +2306,8 @@ int is_module_address(unsigned long addr
25324         spin_lock_irqsave(&modlist_lock, flags);
25325  
25326         list_for_each_entry(mod, &modules, list) {
25327 -               if (within(addr, mod->module_core, mod->core_size)) {
25328 +               if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
25329 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
25330                         spin_unlock_irqrestore(&modlist_lock, flags);
25331                         return 1;
25332                 }
25333 @@ -2188,8 +2325,8 @@ struct module *__module_text_address(uns
25334         struct module *mod;
25335  
25336         list_for_each_entry(mod, &modules, list)
25337 -               if (within(addr, mod->module_init, mod->init_text_size)
25338 -                   || within(addr, mod->module_core, mod->core_text_size))
25339 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
25340 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
25341                         return mod;
25342         return NULL;
25343  }
25344 diff -urNp linux-2.6.18/kernel/mutex.c linux-2.6.18/kernel/mutex.c
25345 --- linux-2.6.18/kernel/mutex.c 2006-09-19 23:42:06.000000000 -0400
25346 +++ linux-2.6.18/kernel/mutex.c 2006-09-22 20:45:04.000000000 -0400
25347 @@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
25348   *
25349   * This function is similar to (but not equivalent to) down().
25350   */
25351 -void inline fastcall __sched mutex_lock(struct mutex *lock)
25352 +inline void fastcall __sched mutex_lock(struct mutex *lock)
25353  {
25354         might_sleep();
25355         /*
25356 diff -urNp linux-2.6.18/kernel/pid.c linux-2.6.18/kernel/pid.c
25357 --- linux-2.6.18/kernel/pid.c   2006-09-19 23:42:06.000000000 -0400
25358 +++ linux-2.6.18/kernel/pid.c   2006-09-22 22:23:55.000000000 -0400
25359 @@ -26,6 +26,7 @@
25360  #include <linux/bootmem.h>
25361  #include <linux/hash.h>
25362  #include <linux/vs_pid.h>
25363 +#include <linux/grsecurity.h>
25364  
25365  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
25366  static struct hlist_head *pid_hash;
25367 @@ -90,7 +91,9 @@ static int alloc_pidmap(void)
25368         int i, offset, max_scan, pid, last = last_pid;
25369         pidmap_t *map;
25370  
25371 -       pid = last + 1;
25372 +       pid = gr_random_pid();
25373 +       if (!pid)
25374 +               pid = last_pid + 1;
25375         if (pid >= pid_max)
25376                 pid = RESERVED_PIDS;
25377         offset = pid & BITS_PER_PAGE_MASK;
25378 @@ -272,11 +274,18 @@ struct task_struct * fastcall pid_task(s
25379   */
25380  struct task_struct *find_task_by_pid_type(int type, int nr)
25381  {
25382 +       struct task_struct *task;
25383 +
25384         if (type == PIDTYPE_PID)
25385                 nr = vx_rmap_pid(nr);
25386         if (type == PIDTYPE_REALPID)
25387                 type = PIDTYPE_PID;
25388 -       return pid_task(find_pid(nr), type);
25389 +       task = pid_task(find_pid(nr), type);
25390 +
25391 +       if (gr_pid_is_chrooted(task))
25392 +               return NULL;
25393 +
25394 +       return task;
25395  }
25396  
25397  EXPORT_SYMBOL(find_task_by_pid_type);
25398 @@ -279,6 +289,8 @@ struct task_struct *fastcall get_pid_tas
25399         struct task_struct *result;
25400         rcu_read_lock();
25401         result = pid_task(pid, type);
25402 +       if (gr_pid_is_chrooted(result))
25403 +               result = NULL;
25404         if (result)
25405                 get_task_struct(result);
25406         rcu_read_unlock();
25407 diff -urNp linux-2.6.18/kernel/posix-cpu-timers.c linux-2.6.18/kernel/posix-cpu-timers.c
25408 --- linux-2.6.18/kernel/posix-cpu-timers.c      2006-09-19 23:42:06.000000000 -0400
25409 +++ linux-2.6.18/kernel/posix-cpu-timers.c      2006-09-22 20:04:35.000000000 -0400
25410 @@ -6,6 +6,7 @@
25411  #include <asm/uaccess.h>
25412  #include <linux/errno.h>
25413  #include <linux/vs_pid.h>
25414 +#include <linux/grsecurity.h>
25415  
25416  static int check_clock(const clockid_t which_clock)
25417  {
25418 @@ -1125,6 +1126,7 @@ static void check_process_timers(struct 
25419                         __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
25420                         return;
25421                 }
25422 +               gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
25423                 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
25424                         /*
25425                          * At the soft limit, send a SIGXCPU every second.
25426 diff -urNp linux-2.6.18/kernel/printk.c linux-2.6.18/kernel/printk.c
25427 --- linux-2.6.18/kernel/printk.c        2006-09-19 23:42:06.000000000 -0400
25428 +++ linux-2.6.18/kernel/printk.c        2006-09-22 20:04:35.000000000 -0400
25429 @@ -31,6 +31,7 @@
25430  #include <linux/syscalls.h>
25431  #include <linux/vs_context.h>
25432  #include <linux/vserver/cvirt.h>
25433 +#include <linux/grsecurity.h>
25434  
25435  #include <asm/uaccess.h>
25436  
25437 @@ -186,6 +187,11 @@ int do_syslog(int type, char __user *buf
25438         char c;
25439         int error = 0;
25440  
25441 +#ifdef CONFIG_GRKERNSEC_DMESG
25442 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
25443 +               return -EPERM;
25444 +#endif
25445 +
25446         error = security_syslog(type);
25447         if (error)
25448                 return error;
25449 diff -urNp linux-2.6.18/kernel/ptrace.c linux-2.6.18/kernel/ptrace.c
25450 --- linux-2.6.18/kernel/ptrace.c        2006-09-19 23:42:06.000000000 -0400
25451 +++ linux-2.6.18/kernel/ptrace.c        2006-09-22 20:19:31.000000000 -0400
25452 @@ -18,6 +18,7 @@
25453  #include <linux/security.h>
25454  #include <linux/signal.h>
25455  #include <linux/vs_pid.h>
25456 +#include <linux/grsecurity.h>
25457  
25458  #include <asm/pgtable.h>
25459  #include <asm/uaccess.h>
25460 @@ -137,12 +138,12 @@ static int may_attach(struct task_struct
25461              (current->uid != task->uid) ||
25462              (current->gid != task->egid) ||
25463              (current->gid != task->sgid) ||
25464 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
25465 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
25466                 return -EPERM;
25467         smp_rmb();
25468         if (task->mm)
25469                 dumpable = task->mm->dumpable;
25470 -       if (!dumpable && !capable(CAP_SYS_PTRACE))
25471 +       if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
25472                 return -EPERM;
25473  
25474         return security_ptrace(current, task);
25475 @@ -530,6 +531,11 @@ asmlinkage long sys_ptrace(long request,
25476         if (ret < 0)
25477                 goto out_put_task_struct;
25478  
25479 +       if (gr_handle_ptrace(child, request)) {
25480 +               ret = -EPERM;
25481 +               goto out_put_task_struct;
25482 +       }
25483 +
25484         ret = arch_ptrace(child, request, addr, data);
25485         if (ret < 0)
25486                 goto out_put_task_struct;
25487 diff -urNp linux-2.6.18/kernel/resource.c linux-2.6.18/kernel/resource.c
25488 --- linux-2.6.18/kernel/resource.c      2006-09-19 23:42:06.000000000 -0400
25489 +++ linux-2.6.18/kernel/resource.c      2006-09-22 20:04:35.000000000 -0400
25490 @@ -133,10 +133,27 @@ static int __init ioresources_init(void)
25491  {
25492         struct proc_dir_entry *entry;
25493  
25494 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
25495 +#ifdef CONFIG_GRKERNSEC_PROC_USER
25496 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
25497 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
25498 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
25499 +#endif
25500 +#else
25501         entry = create_proc_entry("ioports", 0, NULL);
25502 +#endif
25503         if (entry)
25504                 entry->proc_fops = &proc_ioports_operations;
25505 +
25506 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
25507 +#ifdef CONFIG_GRKERNSEC_PROC_USER
25508 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
25509 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
25510 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
25511 +#endif
25512 +#else
25513         entry = create_proc_entry("iomem", 0, NULL);
25514 +#endif
25515         if (entry)
25516                 entry->proc_fops = &proc_iomem_operations;
25517         return 0;
25518 diff -urNp linux-2.6.18/kernel/sched.c linux-2.6.18/kernel/sched.c
25519 --- linux-2.6.18/kernel/sched.c 2006-09-19 23:42:06.000000000 -0400
25520 +++ linux-2.6.18/kernel/sched.c 2006-09-22 20:18:35.000000000 -0400
25521 @@ -52,6 +52,7 @@
25522  #include <linux/acct.h>
25523  #include <linux/kprobes.h>
25524  #include <linux/delayacct.h>
25525 +#include <linux/grsecurity.h>
25526  #include <asm/tlb.h>
25527  
25528  #include <asm/unistd.h>
25529 @@ -3956,7 +3957,8 @@ asmlinkage long sys_nice(int increment)
25530         if (nice > 19)
25531                 nice = 19;
25532  
25533 -       if (increment < 0 && !can_nice(current, nice))
25534 +       if (increment < 0 && (!can_nice(current, nice) ||
25535 +                             gr_handle_chroot_nice()))
25536                 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
25537  
25538         retval = security_task_setnice(current, nice);
25539 diff -urNp linux-2.6.18/kernel/signal.c linux-2.6.18/kernel/signal.c
25540 --- linux-2.6.18/kernel/signal.c        2006-09-19 23:42:06.000000000 -0400
25541 +++ linux-2.6.18/kernel/signal.c        2006-09-22 20:25:59.000000000 -0400
25542 @@ -23,6 +23,7 @@
25543  #include <linux/signal.h>
25544  #include <linux/capability.h>
25545  #include <linux/vs_pid.h>
25546 +#include <linux/grsecurity.h>
25547  #include <asm/param.h>
25548  #include <asm/uaccess.h>
25549  #include <asm/unistd.h>
25550 @@ -582,11 +583,11 @@ static int check_kill_permission(int sig
25551                 (!is_si_special(info) && SI_FROMUSER(info)));
25552  
25553         error = -EPERM;
25554 -       if (user && ((sig != SIGCONT) ||
25555 +       if (user && ((((sig != SIGCONT) ||
25556                 (current->signal->session != t->signal->session))
25557             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
25558             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
25559 -           && !capable(CAP_KILL))
25560 +           && !capable(CAP_KILL)) || gr_handle_signal(t, sig)))
25561                 return error;
25562  
25563         error = -ESRCH;
25564 @@ -763,7 +766,7 @@ out_set:
25565         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
25566  
25567  
25568 -static int
25569 +int
25570  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
25571  {
25572         int ret = 0;
25573 @@ -817,6 +820,10 @@ force_sig_info(int sig, struct siginfo *
25574                 }
25575         }
25576         ret = specific_send_sig_info(sig, info, t);
25577 +
25578 +       gr_log_signal(sig, t);
25579 +       gr_handle_crash(t, sig);
25580 +
25581         spin_unlock_irqrestore(&t->sighand->siglock, flags);
25582  
25583         return ret;
25584 diff -urNp linux-2.6.18/kernel/sys.c linux-2.6.18/kernel/sys.c
25585 --- linux-2.6.18/kernel/sys.c   2006-09-19 23:42:06.000000000 -0400
25586 +++ linux-2.6.18/kernel/sys.c   2006-09-22 20:45:04.000000000 -0400
25587 @@ -28,6 +28,7 @@
25588  #include <linux/cn_proc.h>
25589  #include <linux/vs_cvirt.h>
25590  #include <linux/vs_pid.h>
25591 +#include <linux/grsecurity.h>
25592  
25593  #include <linux/compat.h>
25594  #include <linux/syscalls.h>
25595 @@ -447,6 +448,12 @@ static int set_one_prio(struct task_stru
25596                 error = -EACCES;
25597                 goto out;
25598         }
25599 +
25600 +       if (gr_handle_chroot_setpriority(p, niceval)) {
25601 +               error = -EACCES;
25602 +               goto out;
25603 +       }
25604 +
25605         no_nice = security_task_setnice(p, niceval);
25606         if (no_nice) {
25607                 error = no_nice;
25608 @@ -835,6 +842,9 @@ asmlinkage long sys_setregid(gid_t rgid,
25609         if (rgid != (gid_t) -1 ||
25610             (egid != (gid_t) -1 && egid != old_rgid))
25611                 current->sgid = new_egid;
25612 +
25613 +       gr_set_role_label(current, current->uid, new_rgid);
25614 +
25615         current->fsgid = new_egid;
25616         current->egid = new_egid;
25617         current->gid = new_rgid;
25618 @@ -864,6 +874,9 @@ asmlinkage long sys_setgid(gid_t gid)
25619                         current->mm->dumpable = suid_dumpable;
25620                         smp_wmb();
25621                 }
25622 +
25623 +               gr_set_role_label(current, current->uid, gid);
25624 +
25625                 current->gid = current->egid = current->sgid = current->fsgid = gid;
25626         }
25627         else if ((gid == current->gid) || (gid == current->sgid))
25628 @@ -905,6 +918,9 @@ static int set_user(uid_t new_ruid, int 
25629                 current->mm->dumpable = suid_dumpable;
25630                 smp_wmb();
25631         }
25632 +
25633 +       gr_set_role_label(current, new_ruid, current->gid);
25634 +
25635         current->uid = new_ruid;
25636         return 0;
25637  }
25638 @@ -1008,6 +1024,9 @@ asmlinkage long sys_setuid(uid_t uid)
25639         } else if ((uid != current->uid) && (uid != new_suid))
25640                 return -EPERM;
25641  
25642 +       if (gr_check_crash_uid(uid))
25643 +               return -EPERM;
25644 +
25645         if (old_euid != uid)
25646         {
25647                 current->mm->dumpable = suid_dumpable;
25648 @@ -1113,8 +1132,10 @@ asmlinkage long sys_setresgid(gid_t rgid
25649                 current->egid = egid;
25650         }
25651         current->fsgid = current->egid;
25652 -       if (rgid != (gid_t) -1)
25653 +       if (rgid != (gid_t) -1) {
25654 +               gr_set_role_label(current, current->uid, rgid);
25655                 current->gid = rgid;
25656 +       }
25657         if (sgid != (gid_t) -1)
25658                 current->sgid = sgid;
25659  
25660 @@ -1983,7 +2004,7 @@ asmlinkage long sys_prctl(int option, un
25661                         error = current->mm->dumpable;
25662                         break;
25663                 case PR_SET_DUMPABLE:
25664 -                       if (arg2 < 0 || arg2 > 1) {
25665 +                       if (arg2 > 1) {
25666                                 error = -EINVAL;
25667                                 break;
25668                         }
25669 diff -urNp linux-2.6.18/kernel/sysctl.c linux-2.6.18/kernel/sysctl.c
25670 --- linux-2.6.18/kernel/sysctl.c        2006-09-19 23:42:06.000000000 -0400
25671 +++ linux-2.6.18/kernel/sysctl.c        2006-09-23 00:26:32.000000000 -0400
25672 @@ -53,6 +53,14 @@ extern int proc_nr_files(ctl_table *tabl
25673                       void __user *buffer, size_t *lenp, loff_t *ppos);
25674  
25675  #if defined(CONFIG_SYSCTL)
25676 +#include <linux/grsecurity.h>
25677 +#include <linux/grinternal.h>
25678 +
25679 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
25680 +                             const void *newval);
25681 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
25682 +                               const int op);
25683 +extern int gr_handle_chroot_sysctl(const int op);
25684  
25685  /* External variables not in a header file. */
25686  extern int C_A_D;
25687 @@ -161,6 +169,22 @@ extern ctl_table inotify_table[];
25688  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
25689  int sysctl_legacy_va_layout;
25690  #endif
25691 +extern ctl_table grsecurity_table[];
25692 +
25693 +#ifdef CONFIG_PAX_SOFTMODE
25694 +static ctl_table pax_table[] = {
25695 +       {
25696 +               .ctl_name       = PAX_SOFTMODE,
25697 +               .procname       = "softmode",
25698 +               .data           = &pax_softmode,
25699 +               .maxlen         = sizeof(unsigned int),
25700 +               .mode           = 0600,
25701 +               .proc_handler   = &proc_dointvec,
25702 +       },
25703 +
25704 +       { .ctl_name = 0 }
25705 +};
25706 +#endif
25707  
25708  /* /proc declarations: */
25709  
25710 @@ -702,6 +726,24 @@ static ctl_table kern_table[] = {
25711         },
25712  #endif
25713  
25714 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
25715 +       {
25716 +               .ctl_name       = KERN_GRSECURITY,
25717 +               .procname       = "grsecurity",
25718 +               .mode           = 0500,
25719 +               .child          = grsecurity_table,
25720 +       },
25721 +#endif
25722 +
25723 +#ifdef CONFIG_PAX_SOFTMODE
25724 +       {
25725 +               .ctl_name       = KERN_PAX,
25726 +               .procname       = "pax",
25727 +               .mode           = 0500,
25728 +               .child          = pax_table,
25729 +       },
25730 +#endif
25731 +
25732         { .ctl_name = 0 }
25733  };
25734  
25735 @@ -1217,6 +1259,10 @@ static int test_perm(int mode, int op)
25736  static inline int ctl_perm(ctl_table *table, int op)
25737  {
25738         int error;
25739 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
25740 +               return -EACCES;
25741 +       if (gr_handle_chroot_sysctl(op))
25742 +               return -EACCES;
25743         error = security_sysctl(table, op);
25744         if (error)
25745                 return error;
25746 @@ -1253,6 +1299,10 @@ repeat:
25747                                 table = table->child;
25748                                 goto repeat;
25749                         }
25750 +
25751 +                       if (!gr_handle_sysctl(table, oldval, newval))
25752 +                               return -EPERM;
25753 +
25754                         error = do_sysctl_strategy(table, name, nlen,
25755                                                    oldval, oldlenp,
25756                                                    newval, newlen, context);
25757 diff -urNp linux-2.6.18/kernel/time.c linux-2.6.18/kernel/time.c
25758 --- linux-2.6.18/kernel/time.c  2006-09-19 23:42:06.000000000 -0400
25759 +++ linux-2.6.18/kernel/time.c  2006-09-22 20:04:35.000000000 -0400
25760 @@ -36,6 +36,7 @@
25761  #include <linux/security.h>
25762  #include <linux/fs.h>
25763  #include <linux/module.h>
25764 +#include <linux/grsecurity.h>
25765  
25766  #include <asm/uaccess.h>
25767  #include <asm/unistd.h>
25768 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user 
25769                 return err;
25770  
25771         vx_settimeofday(&tv);
25772 +
25773 +       gr_log_timechange();
25774 +
25775         return 0;
25776  }
25777  
25778 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct 
25779                         return -EFAULT;
25780         }
25781  
25782 +       gr_log_timechange();
25783 +
25784         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
25785  }
25786  
25787 diff -urNp linux-2.6.18/kernel/unwind.c linux-2.6.18/kernel/unwind.c
25788 --- linux-2.6.18/kernel/unwind.c        2006-09-19 23:42:06.000000000 -0400
25789 +++ linux-2.6.18/kernel/unwind.c        2006-09-22 20:45:04.000000000 -0400
25790 @@ -189,8 +189,8 @@ void *unwind_add_table(struct module *mo
25791                 return NULL;
25792  
25793         init_unwind_table(table, module->name,
25794 -                         module->module_core, module->core_size,
25795 -                         module->module_init, module->init_size,
25796 +                         module->module_core_rx, module->core_size_rx,
25797 +                         module->module_init_rx, module->init_size_rx,
25798                           table_start, table_size);
25799  
25800         if (last_table)
25801 diff -urNp linux-2.6.18/localversion-grsec linux-2.6.18/localversion-grsec
25802 --- linux-2.6.18/localversion-grsec     1969-12-31 19:00:00.000000000 -0500
25803 +++ linux-2.6.18/localversion-grsec     2006-09-22 20:04:35.000000000 -0400
25804 @@ -0,0 +1 @@
25805 +-grsec
25806 diff -urNp linux-2.6.18/Makefile linux-2.6.18/Makefile
25807 --- linux-2.6.18/Makefile       2006-09-19 23:42:06.000000000 -0400
25808 +++ linux-2.6.18/Makefile       2006-09-22 20:45:03.000000000 -0400
25809 @@ -307,7 +307,7 @@ LINUXINCLUDE    := -Iinclude \
25810  
25811  CPPFLAGS        := -D__KERNEL__ $(LINUXINCLUDE)
25812  
25813 -CFLAGS          := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
25814 +CFLAGS          := -Wall -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
25815                     -fno-strict-aliasing -fno-common
25816  AFLAGS          := -D__ASSEMBLY__
25817  
25818 @@ -552,7 +552,7 @@ export mod_strip_cmd
25819  
25820  
25821  ifeq ($(KBUILD_EXTMOD),)
25822 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
25823 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
25824  
25825  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
25826                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
25827 diff -urNp linux-2.6.18/mm/filemap.c linux-2.6.18/mm/filemap.c
25828 --- linux-2.6.18/mm/filemap.c   2006-09-19 23:42:06.000000000 -0400
25829 +++ linux-2.6.18/mm/filemap.c   2006-09-22 20:45:04.000000000 -0400
25830 @@ -30,6 +30,7 @@
25831  #include <linux/security.h>
25832  #include <linux/syscalls.h>
25833  #include <linux/cpuset.h>
25834 +#include <linux/grsecurity.h>
25835  #include "filemap.h"
25836  #include "internal.h"
25837  
25838 @@ -1737,7 +1738,13 @@ int generic_file_mmap(struct file * file
25839         struct address_space *mapping = file->f_mapping;
25840  
25841         if (!mapping->a_ops->readpage)
25842 -               return -ENOEXEC;
25843 +               return -ENODEV;
25844 +
25845 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
25846 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
25847 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
25848 +#endif
25849 +
25850         file_accessed(file);
25851         vma->vm_ops = &generic_file_vm_ops;
25852         return 0;
25853 @@ -1960,6 +1967,7 @@ inline int generic_write_checks(struct f
25854                          *pos = i_size_read(inode);
25855  
25856                 if (limit != RLIM_INFINITY) {
25857 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
25858                         if (*pos >= limit) {
25859                                 send_sig(SIGXFSZ, current, 0);
25860                                 return -EFBIG;
25861 diff -urNp linux-2.6.18/mm/madvise.c linux-2.6.18/mm/madvise.c
25862 --- linux-2.6.18/mm/madvise.c   2006-09-19 23:42:06.000000000 -0400
25863 +++ linux-2.6.18/mm/madvise.c   2006-09-22 20:45:04.000000000 -0400
25864 @@ -15,9 +15,46 @@
25865   * We can potentially split a vm area into separate
25866   * areas, each area with its own behavior.
25867   */
25868 +
25869 +#ifdef CONFIG_PAX_SEGMEXEC
25870 +static long __madvise_behavior(struct vm_area_struct * vma,
25871 +                    struct vm_area_struct **prev,
25872 +                    unsigned long start, unsigned long end, int behavior);
25873 +
25874 +static long madvise_behavior(struct vm_area_struct * vma,
25875 +                    struct vm_area_struct **prev,
25876 +                    unsigned long start, unsigned long end, int behavior)
25877 +{
25878 +       if (vma->vm_flags & VM_MIRROR) {
25879 +               struct vm_area_struct * vma_m, * prev_m;
25880 +               unsigned long start_m, end_m;
25881 +               int error;
25882 +
25883 +               start_m = vma->vm_start + vma->vm_mirror;
25884 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
25885 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
25886 +                       start_m = start + vma->vm_mirror;
25887 +                       end_m = end + vma->vm_mirror;
25888 +                       error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
25889 +                       if (error)
25890 +                               return error;
25891 +               } else {
25892 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
25893 +                       return -ENOMEM;
25894 +               }
25895 +       }
25896 +
25897 +       return __madvise_behavior(vma, prev, start, end, behavior);
25898 +}
25899 +
25900 +static long __madvise_behavior(struct vm_area_struct * vma,
25901 +                    struct vm_area_struct **prev,
25902 +                    unsigned long start, unsigned long end, int behavior)
25903 +#else
25904  static long madvise_behavior(struct vm_area_struct * vma,
25905                      struct vm_area_struct **prev,
25906                      unsigned long start, unsigned long end, int behavior)
25907 +#endif
25908  {
25909         struct mm_struct * mm = vma->vm_mm;
25910         int error = 0;
25911 diff -urNp linux-2.6.18/mm/memory.c linux-2.6.18/mm/memory.c
25912 --- linux-2.6.18/mm/memory.c    2006-09-19 23:42:06.000000000 -0400
25913 +++ linux-2.6.18/mm/memory.c    2006-09-22 20:45:04.000000000 -0400
25914 @@ -49,6 +49,7 @@
25915  #include <linux/module.h>
25916  #include <linux/delayacct.h>
25917  #include <linux/init.h>
25918 +#include <linux/grsecurity.h>
25919  
25920  #include <asm/pgalloc.h>
25921  #include <asm/uaccess.h>
25922 @@ -321,6 +322,11 @@ int __pte_alloc(struct mm_struct *mm, pm
25923  
25924  int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
25925  {
25926 +
25927 +#ifdef CONFIG_PAX_KERNEXEC
25928 +       unsigned long cr0;
25929 +#endif
25930 +
25931         pte_t *new = pte_alloc_one_kernel(&init_mm, address);
25932         if (!new)
25933                 return -ENOMEM;
25934 @@ -328,8 +334,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
25935         spin_lock(&init_mm.page_table_lock);
25936         if (pmd_present(*pmd))          /* Another has populated it */
25937                 pte_free_kernel(new);
25938 -       else
25939 +       else {
25940 +
25941 +#ifdef CONFIG_PAX_KERNEXEC
25942 +               pax_open_kernel(cr0);
25943 +#endif
25944 +
25945                 pmd_populate_kernel(&init_mm, pmd, new);
25946 +
25947 +#ifdef CONFIG_PAX_KERNEXEC
25948 +               pax_close_kernel(cr0);
25949 +#endif
25950 +
25951 +       }
25952         spin_unlock(&init_mm.page_table_lock);
25953         return 0;
25954  }
25955 @@ -1434,6 +1451,88 @@ static inline void cow_user_page(struct 
25956         copy_user_highpage(dst, src, va);
25957  }
25958  
25959 +#ifdef CONFIG_PAX_SEGMEXEC
25960 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
25961 + *
25962 + * the ptl of the lower mapped page is held on entry and is not released on exit
25963 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
25964 + */
25965 +static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
25966 +{
25967 +       struct mm_struct *mm = vma->vm_mm;
25968 +       unsigned long address_m, pfn_m;
25969 +       struct vm_area_struct * vma_m = NULL;
25970 +       pte_t * pte_m, entry_m;
25971 +       struct page * page_m = NULL;
25972 +
25973 +       address_m = vma->vm_start + vma->vm_mirror;
25974 +       vma_m = find_vma(mm, address_m);
25975 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
25976 +
25977 +       address_m = address + vma->vm_mirror;
25978 +       pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
25979 +
25980 +       if (pte_same(*pte, *pte_m)) {
25981 +               pte_unmap_nested(pte_m);
25982 +               return;
25983 +       }
25984 +
25985 +       pfn_m = pte_pfn(*pte);
25986 +       if (pte_present(*pte_m)) {
25987 +               page_m = vm_normal_page(vma_m, address_m, *pte_m);
25988 +               if (page_m) {
25989 +                       flush_cache_page(vma_m, address_m, pfn_m);
25990 +                       flush_icache_page(vma_m, page_m);
25991 +               }
25992 +       }
25993 +
25994 +       if (pte_present(*pte_m))
25995 +               entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
25996 +       else
25997 +               entry_m = ptep_get_and_clear(mm, address_m, pte_m);
25998 +
25999 +       if (pte_none(entry_m)) {
26000 +       } else if (pte_present(entry_m)) {
26001 +               if (page_m) {
26002 +                       page_remove_rmap(page_m);
26003 +                       if (PageAnon(page_m))
26004 +                               dec_mm_counter(mm, anon_rss);
26005 +                       else
26006 +                               dec_mm_counter(mm, file_rss);
26007 +                       page_cache_release(page_m);
26008 +               }
26009 +       } else if (!pte_file(entry_m)) {
26010 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
26011 +       } else {
26012 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
26013 +                               address, vma->vm_start, address_m, vma_m->vm_start);
26014 +       }
26015 +
26016 +       page_m = vm_normal_page(vma, address, *pte);
26017 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
26018 +       if (pte_write(*pte))
26019 +               entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
26020 +       if (page_m) {
26021 +               page_cache_get(page_m);
26022 +               /*
26023 +                * we can test PAGE_MAPPING_ANON without holding page_map_lock because
26024 +                * we hold the page table lock and have a reference to page_m
26025 +                */
26026 +               if (PageAnon(page_m)) {
26027 +                       page_add_anon_rmap(page_m, vma_m, address_m);
26028 +                       inc_mm_counter(mm, anon_rss);
26029 +               } else {
26030 +                       page_add_file_rmap(page_m);
26031 +                       inc_mm_counter(mm, file_rss);
26032 +               }
26033 +       }
26034 +       set_pte_at(mm, address_m, pte_m, entry_m);
26035 +       update_mmu_cache(vma_m, address_m, entry_m);
26036 +       lazy_mmu_prot_update(entry_m);
26037 +       pte_unmap_nested(pte_m);
26038 +}
26039 +#endif
26040 +
26041  /*
26042   * This routine handles present pages, when users try to write
26043   * to a shared page. It is done by copying the page to a new address
26044 @@ -1559,6 +1658,12 @@ gotten:
26045                 /* Free the old page.. */
26046                 new_page = old_page;
26047                 ret |= VM_FAULT_WRITE;
26048 +
26049 +#ifdef CONFIG_PAX_SEGMEXEC
26050 +               if (vma->vm_flags & VM_MIRROR)
26051 +                       pax_mirror_fault(vma, address, page_table);
26052 +#endif
26053 +
26054         }
26055         if (new_page)
26056                 page_cache_release(new_page);
26057 @@ -1813,6 +1918,7 @@ int vmtruncate(struct inode * inode, lof
26058  
26059  do_expand:
26060         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
26061 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
26062         if (limit != RLIM_INFINITY && offset > limit)
26063                 goto out_sig;
26064         if (offset > inode->i_sb->s_maxbytes)
26065 @@ -2002,6 +2108,12 @@ static int do_swap_page(struct mm_struct
26066         /* No need to invalidate - it was non-present before */
26067         update_mmu_cache(vma, address, pte);
26068         lazy_mmu_prot_update(pte);
26069 +
26070 +#ifdef CONFIG_PAX_SEGMEXEC
26071 +       if (vma->vm_flags & VM_MIRROR)
26072 +               pax_mirror_fault(vma, address, page_table);
26073 +#endif
26074 +
26075  unlock:
26076         pte_unmap_unlock(page_table, ptl);
26077  out:
26078 @@ -2064,6 +2176,12 @@ static int do_anonymous_page(struct mm_s
26079         /* No need to invalidate - it was non-present before */
26080         update_mmu_cache(vma, address, entry);
26081         lazy_mmu_prot_update(entry);
26082 +
26083 +#ifdef CONFIG_PAX_SEGMEXEC
26084 +       if (vma->vm_flags & VM_MIRROR)
26085 +               pax_mirror_fault(vma, address, page_table);
26086 +#endif
26087 +
26088  unlock:
26089         pte_unmap_unlock(page_table, ptl);
26090         return VM_FAULT_MINOR;
26091 @@ -2202,6 +2320,12 @@ retry:
26092         /* no need to invalidate: a not-present page shouldn't be cached */
26093         update_mmu_cache(vma, address, entry);
26094         lazy_mmu_prot_update(entry);
26095 +
26096 +#ifdef CONFIG_PAX_SEGMEXEC
26097 +       if (vma->vm_flags & VM_MIRROR)
26098 +               pax_mirror_fault(vma, address, page_table);
26099 +#endif
26100 +
26101  unlock:
26102         pte_unmap_unlock(page_table, ptl);
26103         return ret;
26104 @@ -2311,6 +2435,12 @@ static inline int handle_pte_fault(struc
26105                         flush_tlb_page(vma, address);
26106         }
26107  unlock:
26108 +
26109 +#ifdef CONFIG_PAX_SEGMEXEC
26110 +       if (vma->vm_flags & VM_MIRROR)
26111 +               pax_mirror_fault(vma, address, pte);
26112 +#endif
26113 +
26114         pte_unmap_unlock(pte, ptl);
26115         return VM_FAULT_MINOR;
26116  }
26117 @@ -2333,6 +2463,49 @@ int __handle_mm_fault(struct mm_struct *
26118         if (unlikely(is_vm_hugetlb_page(vma)))
26119                 return hugetlb_fault(mm, vma, address, write_access);
26120  
26121 +#ifdef CONFIG_PAX_SEGMEXEC
26122 +       if (vma->vm_flags & VM_MIRROR) {
26123 +               unsigned long address_m;
26124 +               struct vm_area_struct * vma_m;
26125 +               pgd_t *pgd_m;
26126 +               pud_t *pud_m;
26127 +               pmd_t *pmd_m;
26128 +
26129 +               address_m = vma->vm_start + vma->vm_mirror;
26130 +               vma_m = find_vma(mm, address_m);
26131 +
26132 +               /* PaX: sanity checks */
26133 +               if (!vma_m) {
26134 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
26135 +                              address, vma, address_m, vma_m);
26136 +                       return VM_FAULT_SIGBUS;
26137 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
26138 +                       vma_m->vm_start != address_m ||
26139 +                       vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
26140 +               {
26141 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
26142 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
26143 +                       return VM_FAULT_SIGBUS;
26144 +               }
26145 +
26146 +               if (address_m < address) {
26147 +                       address += vma->vm_mirror;
26148 +                       vma = vma_m;
26149 +               }
26150 +
26151 +               address_m = address + vma->vm_mirror;
26152 +               pgd_m = pgd_offset(mm, address_m);
26153 +               pud_m = pud_alloc(mm, pgd_m, address_m);
26154 +               if (!pud_m)
26155 +                       return VM_FAULT_OOM;
26156 +               pmd_m = pmd_alloc(mm, pud_m, address_m);
26157 +               if (!pmd_m)
26158 +                       return VM_FAULT_OOM;
26159 +               if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
26160 +                       return VM_FAULT_OOM;
26161 +       }
26162 +#endif
26163 +
26164         pgd = pgd_offset(mm, address);
26165         pud = pud_alloc(mm, pgd, address);
26166         if (!pud)
26167 diff -urNp linux-2.6.18/mm/mempolicy.c linux-2.6.18/mm/mempolicy.c
26168 --- linux-2.6.18/mm/mempolicy.c 2006-09-19 23:42:06.000000000 -0400
26169 +++ linux-2.6.18/mm/mempolicy.c 2006-09-22 20:45:04.000000000 -0400
26170 @@ -348,6 +348,12 @@ check_range(struct mm_struct *mm, unsign
26171                         if (prev && prev->vm_end < vma->vm_start)
26172                                 return ERR_PTR(-EFAULT);
26173                 }
26174 +
26175 +#ifdef CONFIG_PAX_SEGMEXEC
26176 +               if (vma->vm_flags & VM_MIRROR)
26177 +                       return ERR_PTR(-EFAULT);
26178 +#endif
26179 +
26180                 if (!is_vm_hugetlb_page(vma) &&
26181                     ((flags & MPOL_MF_STRICT) ||
26182                      ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
26183 diff -urNp linux-2.6.18/mm/mlock.c linux-2.6.18/mm/mlock.c
26184 --- linux-2.6.18/mm/mlock.c     2006-09-19 23:42:06.000000000 -0400
26185 +++ linux-2.6.18/mm/mlock.c     2006-09-22 20:45:04.000000000 -0400
26186 @@ -10,14 +10,85 @@
26187  #include <linux/mempolicy.h>
26188  #include <linux/syscalls.h>
26189  #include <linux/vs_memory.h>
26190 +#include <linux/grsecurity.h>
26191  
26192 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
26193 +       unsigned long start, unsigned long end, unsigned int newflags);
26194  
26195  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
26196         unsigned long start, unsigned long end, unsigned int newflags)
26197  {
26198         struct mm_struct * mm = vma->vm_mm;
26199 -       pgoff_t pgoff;
26200         int pages;
26201 +       int ret;
26202 +
26203 +#ifdef CONFIG_PAX_SEGMEXEC
26204 +       struct vm_area_struct * vma_m = NULL, *prev_m;
26205 +       unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
26206 +
26207 +       if (vma->vm_flags & VM_MIRROR) {
26208 +               start_m = vma->vm_start + vma->vm_mirror;
26209 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
26210 +               if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
26211 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
26212 +                       return -ENOMEM;
26213 +               }
26214 +
26215 +               start_m = start + vma->vm_mirror;
26216 +               end_m = end + vma->vm_mirror;
26217 +               if (newflags & VM_LOCKED)
26218 +                       newflags_m = vma_m->vm_flags | VM_LOCKED;
26219 +               else
26220 +                       newflags_m = vma_m->vm_flags & ~VM_LOCKED;
26221 +               ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
26222 +               if (ret)
26223 +                       return ret;
26224 +       }
26225 +#endif
26226 +
26227 +       ret = __mlock_fixup(vma, prev, start, end, newflags);
26228 +       if (ret)
26229 +               return ret;
26230 +
26231 +       /*
26232 +        * vm_flags is protected by the mmap_sem held in write mode.
26233 +        * It's okay if try_to_unmap_one unmaps a page just after we
26234 +        * set VM_LOCKED, make_pages_present below will bring it back.
26235 +        */
26236 +       vma->vm_flags = newflags;
26237 +
26238 +#ifdef CONFIG_PAX_SEGMEXEC
26239 +       if (vma->vm_flags & VM_MIRROR)
26240 +               vma_m->vm_flags = newflags_m;
26241 +#endif
26242 +
26243 +       /*
26244 +        * Keep track of amount of locked VM.
26245 +        */
26246 +       pages = (end - start) >> PAGE_SHIFT;
26247 +       if (newflags & VM_LOCKED) {
26248 +               pages = -pages;
26249 +               if (!(newflags & VM_IO))
26250 +                       ret = make_pages_present(start, end);
26251 +       }
26252 +
26253 +       mm->locked_vm -= pages;
26254 +
26255 +#ifdef CONFIG_PAX_SEGMEXEC
26256 +       if (vma->vm_flags & VM_MIRROR)
26257 +               mm->locked_vm -= pages;
26258 +#endif
26259 +
26260 +       if (ret == -ENOMEM)
26261 +               ret = -EAGAIN;
26262 +       return ret;
26263 +}
26264 +
26265 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
26266 +       unsigned long start, unsigned long end, unsigned int newflags)
26267 +{
26268 +       struct mm_struct * mm = vma->vm_mm;
26269 +       pgoff_t pgoff;
26270         int ret = 0;
26271  
26272         if (newflags == vma->vm_flags) {
26273 @@ -30,7 +101,7 @@ static int mlock_fixup(struct vm_area_st
26274                           vma->vm_file, pgoff, vma_policy(vma));
26275         if (*prev) {
26276                 vma = *prev;
26277 -               goto success;
26278 +               goto out;
26279         }
26280  
26281         *prev = vma;
26282 @@ -41,31 +112,9 @@ static int mlock_fixup(struct vm_area_st
26283                         goto out;
26284         }
26285  
26286 -       if (end != vma->vm_end) {
26287 +       if (end != vma->vm_end)
26288                 ret = split_vma(mm, vma, end, 0);
26289 -               if (ret)
26290 -                       goto out;
26291 -       }
26292  
26293 -success:
26294 -       /*
26295 -        * vm_flags is protected by the mmap_sem held in write mode.
26296 -        * It's okay if try_to_unmap_one unmaps a page just after we
26297 -        * set VM_LOCKED, make_pages_present below will bring it back.
26298 -        */
26299 -       vma->vm_flags = newflags;
26300 -
26301 -       /*
26302 -        * Keep track of amount of locked VM.
26303 -        */
26304 -       pages = (end - start) >> PAGE_SHIFT;
26305 -       if (newflags & VM_LOCKED) {
26306 -               pages = -pages;
26307 -               if (!(newflags & VM_IO))
26308 -                       ret = make_pages_present(start, end);
26309 -       }
26310 -
26311 -       vx_vmlocked_sub(vma->vm_mm, pages);
26312  out:
26313         if (ret == -ENOMEM)
26314                 ret = -EAGAIN;
26315 @@ -84,6 +133,17 @@ static int do_mlock(unsigned long start,
26316                 return -EINVAL;
26317         if (end == start)
26318                 return 0;
26319 +
26320 +#ifdef CONFIG_PAX_SEGMEXEC
26321 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
26322 +               if (end > SEGMEXEC_TASK_SIZE)
26323 +                       return -EINVAL;
26324 +       } else
26325 +#endif
26326 +
26327 +       if (end > TASK_SIZE)
26328 +               return -EINVAL;
26329 +
26330         vma = find_vma_prev(current->mm, start, &prev);
26331         if (!vma || vma->vm_start > start)
26332                 return -ENOMEM;
26333 @@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long 
26334         lock_limit >>= PAGE_SHIFT;
26335  
26336         /* check against resource limits */
26337 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
26338         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
26339                 error = do_mlock(start, len, 1);
26340  out:
26341 @@ -173,6 +234,16 @@ static int do_mlockall(int flags)
26342         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
26343                 unsigned int newflags;
26344  
26345 +#ifdef CONFIG_PAX_SEGMEXEC
26346 +               if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
26347 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
26348 +                               break;
26349 +               } else
26350 +#endif
26351 +
26352 +               if (vma->vm_end > TASK_SIZE)
26353 +                       break;
26354 +
26355                 newflags = vma->vm_flags | VM_LOCKED;
26356                 if (!(flags & MCL_CURRENT))
26357                         newflags &= ~VM_LOCKED;
26358 @@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
26359         lock_limit >>= PAGE_SHIFT;
26360  
26361         ret = -ENOMEM;
26362 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
26363         if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
26364                 goto out;
26365         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
26366 diff -urNp linux-2.6.18/mm/mmap.c linux-2.6.18/mm/mmap.c
26367 --- linux-2.6.18/mm/mmap.c      2006-09-19 23:42:06.000000000 -0400
26368 +++ linux-2.6.18/mm/mmap.c      2006-09-22 20:45:04.000000000 -0400
26369 @@ -25,6 +25,7 @@
26370  #include <linux/mount.h>
26371  #include <linux/mempolicy.h>
26372  #include <linux/rmap.h>
26373 +#include <linux/grsecurity.h>
26374  
26375  #include <asm/uaccess.h>
26376  #include <asm/cacheflush.h>
26377 @@ -244,6 +245,7 @@ asmlinkage unsigned long sys_brk(unsigne
26378          * not page aligned -Ram Gupta
26379          */
26380         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
26381 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
26382         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
26383                 goto out;
26384  
26385 @@ -632,11 +634,17 @@ again:                    remove_next = 1 + (end > next->
26386   * If the vma has a ->close operation then the driver probably needs to release
26387   * per-vma resources, so we don't attempt to merge those.
26388   */
26389 +#ifdef CONFIG_PAX_SEGMEXEC
26390 +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
26391 +#else
26392  #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
26393 +#endif
26394  
26395  static inline int is_mergeable_vma(struct vm_area_struct *vma,
26396                         struct file *file, unsigned long vm_flags)
26397  {
26398 +       if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
26399 +               return 0;
26400         if (vma->vm_flags != vm_flags)
26401                 return 0;
26402         if (vma->vm_file != file)
26403 @@ -861,14 +869,11 @@ none:
26404  void vm_stat_account(struct mm_struct *mm, unsigned long flags,
26405                                                 struct file *file, long pages)
26406  {
26407 -       const unsigned long stack_flags
26408 -               = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
26409 -
26410         if (file) {
26411                 mm->shared_vm += pages;
26412                 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
26413                         mm->exec_vm += pages;
26414 -       } else if (flags & stack_flags)
26415 +       } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
26416                 mm->stack_vm += pages;
26417         if (flags & (VM_RESERVED|VM_IO))
26418                 mm->reserved_vm += pages;
26419 @@ -879,9 +884,54 @@ void vm_stat_account(struct mm_struct *m
26420   * The caller must hold down_write(current->mm->mmap_sem).
26421   */
26422  
26423 +#ifdef CONFIG_PAX_SEGMEXEC
26424 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
26425 +                       unsigned long len, unsigned long prot,
26426 +                       unsigned long flags, unsigned long pgoff);
26427 +
26428 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
26429 +                       unsigned long len, unsigned long prot,
26430 +                       unsigned long flags, unsigned long pgoff)
26431 +{
26432 +       unsigned long ret = -EINVAL;
26433 +
26434 +       if (flags & MAP_MIRROR)
26435 +               return ret;
26436 +
26437 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
26438 +           (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
26439 +               return ret;
26440 +
26441 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
26442 +
26443 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
26444 +
26445 +#ifdef CONFIG_PAX_MPROTECT
26446 +           && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
26447 +#endif
26448 +
26449 +          )
26450 +       {
26451 +               unsigned long ret_m;
26452 +               prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
26453 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
26454 +               if (ret_m >= TASK_SIZE) {
26455 +                       do_munmap(current->mm, ret, len);
26456 +                       ret = ret_m;
26457 +               }
26458 +       }
26459 +
26460 +       return ret;
26461 +}
26462 +
26463 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
26464 +                       unsigned long len, unsigned long prot,
26465 +                       unsigned long flags, unsigned long pgoff)
26466 +#else
26467  unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
26468                         unsigned long len, unsigned long prot,
26469                         unsigned long flags, unsigned long pgoff)
26470 +#endif
26471  {
26472         struct mm_struct * mm = current->mm;
26473         struct vm_area_struct * vma, * prev;
26474 @@ -893,6 +943,28 @@ unsigned long do_mmap_pgoff(struct file 
26475         int accountable = 1;
26476         unsigned long charged = 0, reqprot = prot;
26477  
26478 +#ifdef CONFIG_PAX_SEGMEXEC
26479 +       struct vm_area_struct * vma_m = NULL;
26480 +
26481 +       if (flags & MAP_MIRROR) {
26482 +               /* PaX: sanity checks, to be removed when proved to be stable */
26483 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
26484 +                       return -EINVAL;
26485 +
26486 +               vma_m = find_vma(mm, pgoff);
26487 +
26488 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
26489 +                   vma_m->vm_start != pgoff ||
26490 +                   (vma_m->vm_flags & VM_SPECIAL) ||
26491 +                   (prot & PROT_WRITE))
26492 +                       return -EINVAL;
26493 +
26494 +               file = vma_m->vm_file;
26495 +               pgoff = vma_m->vm_pgoff;
26496 +               len = vma_m->vm_end - vma_m->vm_start;
26497 +       }
26498 +#endif
26499 +
26500         if (file) {
26501                 if (is_file_hugepages(file))
26502                         accountable = 0;
26503 @@ -910,7 +982,7 @@ unsigned long do_mmap_pgoff(struct file 
26504          * (the exception is when the underlying filesystem is noexec
26505          *  mounted, in which case we dont add PROT_EXEC.)
26506          */
26507 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
26508 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
26509                 if (!(file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)))
26510                         prot |= PROT_EXEC;
26511  
26512 @@ -937,7 +1009,7 @@ unsigned long do_mmap_pgoff(struct file 
26513         /* Obtain the address to map to. we verify (or select) it and ensure
26514          * that it represents a valid section of the address space.
26515          */
26516 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
26517 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
26518         if (addr & ~PAGE_MASK)
26519                 return addr;
26520  
26521 @@ -948,6 +1020,24 @@ unsigned long do_mmap_pgoff(struct file 
26522         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
26523                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
26524  
26525 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
26526 +               vm_flags &= ~VM_MAYEXEC;
26527 +
26528 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
26529 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
26530 +
26531 +#ifdef CONFIG_PAX_MPROTECT
26532 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
26533 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
26534 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
26535 +                       else
26536 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
26537 +               }
26538 +#endif
26539 +
26540 +       }
26541 +#endif
26542 +
26543         if (flags & MAP_LOCKED) {
26544                 if (!can_do_mlock())
26545                         return -EPERM;
26546 @@ -960,6 +1050,7 @@ unsigned long do_mmap_pgoff(struct file 
26547                 locked += mm->locked_vm;
26548                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
26549                 lock_limit >>= PAGE_SHIFT;
26550 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
26551                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
26552                         return -EAGAIN;
26553         }
26554 @@ -1007,6 +1098,11 @@ unsigned long do_mmap_pgoff(struct file 
26555                         /*
26556                          * Set pgoff according to addr for anon_vma.
26557                          */
26558 +
26559 +#ifdef CONFIG_PAX_SEGMEXEC
26560 +                       if (!(flags & MAP_MIRROR))
26561 +#endif
26562 +
26563                         pgoff = addr >> PAGE_SHIFT;
26564                         break;
26565                 default:
26566 @@ -1018,14 +1114,17 @@ unsigned long do_mmap_pgoff(struct file 
26567         if (error)
26568                 return error;
26569                 
26570 +       if (!gr_acl_handle_mmap(file, prot))
26571 +               return -EACCES;
26572 +
26573         /* Clear old maps */
26574         error = -ENOMEM;
26575 -munmap_back:
26576         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
26577         if (vma && vma->vm_start < addr + len) {
26578                 if (do_munmap(mm, addr, len))
26579                         return -ENOMEM;
26580 -               goto munmap_back;
26581 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
26582 +               BUG_ON(vma && vma->vm_start < addr + len);
26583         }
26584  
26585         /* Check against address space limit. */
26586 @@ -1073,6 +1172,13 @@ munmap_back:
26587         vma->vm_start = addr;
26588         vma->vm_end = addr + len;
26589         vma->vm_flags = vm_flags;
26590 +
26591 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26592 +       if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
26593 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
26594 +       else
26595 +#endif
26596 +
26597         vma->vm_page_prot = protection_map[vm_flags &
26598                                 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
26599         vma->vm_pgoff = pgoff;
26600 @@ -1100,9 +1206,25 @@ munmap_back:
26601  
26602         /* Don't make the VMA automatically writable if it's shared, but the
26603          * backer wishes to know when pages are first written to */
26604 -       if (vma->vm_ops && vma->vm_ops->page_mkwrite)
26605 +       if (vma->vm_ops && vma->vm_ops->page_mkwrite) {
26606 +
26607 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26608 +               if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
26609 +                       vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
26610 +               else
26611 +#endif
26612 +
26613                 vma->vm_page_prot =
26614                         protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
26615 +       }
26616 +
26617 +#ifdef CONFIG_PAX_SEGMEXEC
26618 +       if (flags & MAP_MIRROR) {
26619 +               vma_m->vm_flags |= VM_MIRROR;
26620 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
26621 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
26622 +       }
26623 +#endif
26624  
26625         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
26626          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
26627 @@ -1139,6 +1261,7 @@ munmap_back:
26628  out:   
26629         mm->total_vm += len >> PAGE_SHIFT;
26630         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
26631 +       track_exec_limit(mm, addr, addr + len, vm_flags);
26632         if (vm_flags & VM_LOCKED) {
26633                 mm->locked_vm += len >> PAGE_SHIFT;
26634                 make_pages_present(addr, addr + len);
26635 @@ -1193,6 +1316,10 @@ arch_get_unmapped_area(struct file *filp
26636         if (len > TASK_SIZE)
26637                 return -ENOMEM;
26638  
26639 +#ifdef CONFIG_PAX_RANDMMAP
26640 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
26641 +#endif
26642 +
26643         if (addr) {
26644                 addr = PAGE_ALIGN(addr);
26645                 vma = find_vma(mm, addr);
26646 @@ -1203,7 +1330,7 @@ arch_get_unmapped_area(struct file *filp
26647         if (len > mm->cached_hole_size) {
26648                 start_addr = addr = mm->free_area_cache;
26649         } else {
26650 -               start_addr = addr = TASK_UNMAPPED_BASE;
26651 +               start_addr = addr = mm->mmap_base;
26652                 mm->cached_hole_size = 0;
26653         }
26654  
26655 @@ -1215,9 +1342,8 @@ full_search:
26656                          * Start a new search - just in case we missed
26657                          * some holes.
26658                          */
26659 -                       if (start_addr != TASK_UNMAPPED_BASE) {
26660 -                               addr = TASK_UNMAPPED_BASE;
26661 -                               start_addr = addr;
26662 +                       if (start_addr != mm->mmap_base) {
26663 +                               start_addr = addr = mm->mmap_base;
26664                                 mm->cached_hole_size = 0;
26665                                 goto full_search;
26666                         }
26667 @@ -1242,7 +1368,7 @@ void arch_unmap_area(struct mm_struct *m
26668         /*
26669          * Is this a new hole at the lowest possible address?
26670          */
26671 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
26672 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
26673                 mm->free_area_cache = addr;
26674                 mm->cached_hole_size = ~0UL;
26675         }
26676 @@ -1260,12 +1386,16 @@ arch_get_unmapped_area_topdown(struct fi
26677  {
26678         struct vm_area_struct *vma;
26679         struct mm_struct *mm = current->mm;
26680 -       unsigned long addr = addr0;
26681 +       unsigned long base = mm->mmap_base, addr = addr0;
26682  
26683         /* requested length too big for entire address space */
26684         if (len > TASK_SIZE)
26685                 return -ENOMEM;
26686  
26687 +#ifdef CONFIG_PAX_RANDMMAP
26688 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
26689 +#endif
26690 +
26691         /* requesting a specific address */
26692         if (addr) {
26693                 addr = PAGE_ALIGN(addr);
26694 @@ -1323,13 +1453,21 @@ bottomup:
26695          * can happen with large stack limits and large mmap()
26696          * allocations.
26697          */
26698 +       mm->mmap_base = TASK_UNMAPPED_BASE;
26699 +
26700 +#ifdef CONFIG_PAX_RANDMMAP
26701 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
26702 +               mm->mmap_base += mm->delta_mmap;
26703 +#endif
26704 +
26705 +       mm->free_area_cache = mm->mmap_base;
26706         mm->cached_hole_size = ~0UL;
26707 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
26708         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
26709         /*
26710          * Restore the topdown base:
26711          */
26712 -       mm->free_area_cache = mm->mmap_base;
26713 +       mm->mmap_base = base;
26714 +       mm->free_area_cache = base;
26715         mm->cached_hole_size = ~0UL;
26716  
26717         return addr;
26718 @@ -1345,8 +1483,10 @@ void arch_unmap_area_topdown(struct mm_s
26719                 mm->free_area_cache = addr;
26720  
26721         /* dont allow allocations above current base */
26722 -       if (mm->free_area_cache > mm->mmap_base)
26723 +       if (mm->free_area_cache > mm->mmap_base) {
26724                 mm->free_area_cache = mm->mmap_base;
26725 +               mm->cached_hole_size = ~0UL;
26726 +       }
26727  }
26728  
26729  unsigned long
26730 @@ -1479,6 +1619,7 @@ static int acct_stack_growth(struct vm_a
26731                 return -ENOMEM;
26732  
26733         /* Stack limit test */
26734 +       gr_learn_resource(current, RLIMIT_STACK, size, 1);
26735         if (size > rlim[RLIMIT_STACK].rlim_cur)
26736                 return -ENOMEM;
26737  
26738 @@ -1488,6 +1629,7 @@ static int acct_stack_growth(struct vm_a
26739                 unsigned long limit;
26740                 locked = mm->locked_vm + grow;
26741                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
26742 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
26743                 if (locked > limit && !capable(CAP_IPC_LOCK))
26744                         return -ENOMEM;
26745         }
26746 @@ -1605,13 +1747,49 @@ int expand_stack(struct vm_area_struct *
26747         if (address < vma->vm_start) {
26748                 unsigned long size, grow;
26749  
26750 +#ifdef CONFIG_PAX_SEGMEXEC
26751 +               struct vm_area_struct *vma_m = NULL;
26752 +               unsigned long address_m = 0UL;
26753 +
26754 +               if (vma->vm_flags & VM_MIRROR) {
26755 +                       address_m = vma->vm_start + vma->vm_mirror;
26756 +                       vma_m = find_vma(vma->vm_mm, address_m);
26757 +                       if (!vma_m || vma_m->vm_start != address_m ||
26758 +                           !(vma_m->vm_flags & VM_MIRROR) ||
26759 +                           vma->vm_end - vma->vm_start !=
26760 +                           vma_m->vm_end - vma_m->vm_start ||
26761 +                           vma->anon_vma != vma_m->anon_vma) {
26762 +                               printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
26763 +                                      address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
26764 +                               anon_vma_unlock(vma);
26765 +                               return -EFAULT;
26766 +                       }
26767 +                       address_m = address + vma->vm_mirror;
26768 +               }
26769 +#endif
26770 +
26771                 size = vma->vm_end - address;
26772                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
26773  
26774 +#ifdef CONFIG_PAX_SEGMEXEC
26775 +               if (vma_m)
26776 +                       error = acct_stack_growth(vma, size, 2*grow);
26777 +               else
26778 +#endif
26779 +
26780                 error = acct_stack_growth(vma, size, grow);
26781                 if (!error) {
26782                         vma->vm_start = address;
26783                         vma->vm_pgoff -= grow;
26784 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
26785 +
26786 +#ifdef CONFIG_PAX_SEGMEXEC
26787 +                       if (vma_m) {
26788 +                               vma_m->vm_start = address_m;
26789 +                               vma_m->vm_pgoff -= grow;
26790 +                       }
26791 +#endif
26792 +
26793                 }
26794         }
26795         anon_vma_unlock(vma);
26796 @@ -1773,7 +1951,24 @@ int split_vma(struct mm_struct * mm, str
26797   * work.  This now handles partial unmappings.
26798   * Jeremy Fitzhardinge <jeremy@goop.org>
26799   */
26800 +#ifdef CONFIG_PAX_SEGMEXEC
26801 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
26802 +
26803 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
26804 +{
26805 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
26806 +               int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
26807 +               if (ret)
26808 +                       return ret;
26809 +       }
26810 +
26811 +       return __do_munmap(mm, start, len);
26812 +}
26813 +
26814 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
26815 +#else
26816  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
26817 +#endif
26818  {
26819         unsigned long end;
26820         struct vm_area_struct *vma, *prev, *last;
26821 @@ -1827,6 +2022,8 @@ int do_munmap(struct mm_struct *mm, unsi
26822         /* Fix up all other VM information */
26823         remove_vma_list(mm, vma);
26824  
26825 +       track_exec_limit(mm, start, end, 0UL);
26826 +
26827         return 0;
26828  }
26829  
26830 @@ -1839,6 +2036,12 @@ asmlinkage long sys_munmap(unsigned long
26831  
26832         profile_munmap(addr);
26833  
26834 +#ifdef CONFIG_PAX_SEGMEXEC
26835 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
26836 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
26837 +               return -EINVAL;
26838 +#endif
26839 +
26840         down_write(&mm->mmap_sem);
26841         ret = do_munmap(mm, addr, len);
26842         up_write(&mm->mmap_sem);
26843 @@ -1860,11 +2063,35 @@ static inline void verify_mm_writelocked
26844   *  anonymous maps.  eventually we may be able to do some
26845   *  brk-specific accounting here.
26846   */
26847 +#ifdef CONFIG_PAX_SEGMEXEC
26848 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
26849 +
26850 +unsigned long do_brk(unsigned long addr, unsigned long len)
26851 +{
26852 +       unsigned long ret;
26853 +
26854 +       ret = __do_brk(addr, len);
26855 +       if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
26856 +               unsigned long ret_m;
26857 +
26858 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
26859 +               if (ret_m > TASK_SIZE) {
26860 +                       do_munmap(current->mm, addr, len);
26861 +                       ret = ret_m;
26862 +               }
26863 +       }
26864 +
26865 +       return ret;
26866 +}
26867 +
26868 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
26869 +#else
26870  unsigned long do_brk(unsigned long addr, unsigned long len)
26871 +#endif
26872  {
26873         struct mm_struct * mm = current->mm;
26874         struct vm_area_struct * vma, * prev;
26875 -       unsigned long flags;
26876 +       unsigned long flags, task_size = TASK_SIZE;
26877         struct rb_node ** rb_link, * rb_parent;
26878         pgoff_t pgoff = addr >> PAGE_SHIFT;
26879         int error;
26880 @@ -1873,11 +2100,28 @@ unsigned long do_brk(unsigned long addr,
26881         if (!len)
26882                 return addr;
26883  
26884 -       if ((addr + len) > TASK_SIZE || (addr + len) < addr)
26885 +#ifdef CONFIG_PAX_SEGMEXEC
26886 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
26887 +               task_size = SEGMEXEC_TASK_SIZE;
26888 +#endif
26889 +
26890 +       if ((addr + len) > task_size || (addr + len) < addr)
26891                 return -EINVAL;
26892  
26893         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
26894  
26895 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
26896 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
26897 +               flags &= ~VM_EXEC;
26898 +
26899 +#ifdef CONFIG_PAX_MPROTECT
26900 +               if (mm->pax_flags & MF_PAX_MPROTECT)
26901 +                       flags &= ~VM_MAYEXEC;
26902 +#endif
26903 +
26904 +       }
26905 +#endif
26906 +
26907         error = arch_mmap_check(addr, len, flags);
26908         if (error)
26909                 return error;
26910 @@ -1891,6 +2135,7 @@ unsigned long do_brk(unsigned long addr,
26911                 locked += mm->locked_vm;
26912                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
26913                 lock_limit >>= PAGE_SHIFT;
26914 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
26915                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
26916                         return -EAGAIN;
26917         }
26918 @@ -1904,12 +2149,12 @@ unsigned long do_brk(unsigned long addr,
26919         /*
26920          * Clear old maps.  this also does some error checking for us
26921          */
26922 - munmap_back:
26923         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
26924         if (vma && vma->vm_start < addr + len) {
26925                 if (do_munmap(mm, addr, len))
26926                         return -ENOMEM;
26927 -               goto munmap_back;
26928 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
26929 +               BUG_ON(vma && vma->vm_start < addr + len);
26930         }
26931  
26932         /* Check against address space limits *after* clearing old maps... */
26933 @@ -1941,6 +2186,13 @@ unsigned long do_brk(unsigned long addr,
26934         vma->vm_end = addr + len;
26935         vma->vm_pgoff = pgoff;
26936         vma->vm_flags = flags;
26937 +
26938 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26939 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
26940 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
26941 +       else
26942 +#endif
26943 +
26944         vma->vm_page_prot = protection_map[flags &
26945                                 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
26946         vma_link(mm, vma, prev, rb_link, rb_parent);
26947 @@ -1950,6 +2202,7 @@ out:
26948                 mm->locked_vm += len >> PAGE_SHIFT;
26949                 make_pages_present(addr, addr + len);
26950         }
26951 +       track_exec_limit(mm, addr, addr + len, flags);
26952         return addr;
26953  }
26954  
26955 @@ -2082,7 +2335,7 @@ int may_expand_vm(struct mm_struct *mm, 
26956         unsigned long lim;
26957  
26958         lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
26959 -
26960 +       gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
26961         if (cur + npages > lim)
26962                 return 0;
26963         return 1;
26964 diff -urNp linux-2.6.18/mm/mprotect.c linux-2.6.18/mm/mprotect.c
26965 --- linux-2.6.18/mm/mprotect.c  2006-09-19 23:42:06.000000000 -0400
26966 +++ linux-2.6.18/mm/mprotect.c  2006-09-22 21:54:23.000000000 -0400
26967 @@ -21,10 +21,18 @@
26968  #include <linux/syscalls.h>
26969  #include <linux/swap.h>
26970  #include <linux/swapops.h>
26971 +#include <linux/grsecurity.h>
26972 +
26973 +#ifdef CONFIG_PAX_MPROTECT
26974 +#include <linux/elf.h>
26975 +#include <linux/fs.h>
26976 +#endif
26977 +
26978  #include <asm/uaccess.h>
26979  #include <asm/pgtable.h>
26980  #include <asm/cacheflush.h>
26981  #include <asm/tlbflush.h>
26982 +#include <asm/mmu_context.h>
26983  
26984  static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
26985                 unsigned long addr, unsigned long end, pgprot_t newprot)
26986 @@ -115,6 +123,95 @@ static void change_protection(struct vm_
26987         flush_tlb_range(vma, start, end);
26988  }
26989  
26990 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
26991 +/* called while holding the mmap semaphor for writing */
26992 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
26993 +{
26994 +       struct vm_area_struct *vma = find_vma(mm, start);
26995 +
26996 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
26997 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
26998 +
26999 +}
27000 +
27001 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
27002 +{
27003 +       unsigned long oldlimit, newlimit = 0UL;
27004 +
27005 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
27006 +               return;
27007 +
27008 +       spin_lock(&mm->page_table_lock);
27009 +       oldlimit = mm->context.user_cs_limit;
27010 +       if ((prot & VM_EXEC) && oldlimit < end)
27011 +               /* USER_CS limit moved up */
27012 +               newlimit = end;
27013 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
27014 +               /* USER_CS limit moved down */
27015 +               newlimit = start;
27016 +
27017 +       if (newlimit) {
27018 +               mm->context.user_cs_limit = newlimit;
27019 +
27020 +#ifdef CONFIG_SMP
27021 +               wmb();
27022 +               cpus_clear(mm->context.cpu_user_cs_mask);
27023 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
27024 +#endif
27025 +
27026 +               set_user_cs(mm, smp_processor_id());
27027 +       }
27028 +       spin_unlock(&mm->page_table_lock);
27029 +       if (newlimit == end)
27030 +               establish_user_cs_limit(mm, oldlimit, end);
27031 +}
27032 +#endif
27033 +
27034 +#ifdef CONFIG_PAX_SEGMEXEC
27035 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
27036 +       unsigned long start, unsigned long end, unsigned int newflags);
27037 +
27038 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
27039 +       unsigned long start, unsigned long end, unsigned int newflags)
27040 +{
27041 +       if (vma->vm_flags & VM_MIRROR) {
27042 +               struct vm_area_struct * vma_m, * prev_m;
27043 +               unsigned long start_m, end_m;
27044 +               int error;
27045 +
27046 +               start_m = vma->vm_start + vma->vm_mirror;
27047 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
27048 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
27049 +                       start_m = start + vma->vm_mirror;
27050 +                       end_m = end + vma->vm_mirror;
27051 +
27052 +                       if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
27053 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
27054 +                       else
27055 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
27056 +                       if (error)
27057 +                               return error;
27058 +               } else {
27059 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
27060 +                       return -ENOMEM;
27061 +               }
27062 +       }
27063 +
27064 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
27065 +}
27066 +
27067 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
27068 +       unsigned long start, unsigned long end, unsigned int newflags)
27069 +{
27070 +       struct mm_struct * mm = vma->vm_mm;
27071 +       unsigned long oldflags = vma->vm_flags;
27072 +       long nrpages = (end - start) >> PAGE_SHIFT;
27073 +       unsigned long charged = 0;
27074 +       unsigned int mask;
27075 +       pgprot_t newprot;
27076 +       pgoff_t pgoff;
27077 +       int error;
27078 +#else
27079  static int
27080  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
27081         unsigned long start, unsigned long end, unsigned long newflags)
27082 @@ -132,6 +229,7 @@ mprotect_fixup(struct vm_area_struct *vm
27083                 *pprev = vma;
27084                 return 0;
27085         }
27086 +#endif
27087  
27088         /*
27089          * If we make a private mapping writable we increase our commit;
27090 @@ -182,6 +280,12 @@ success:
27091         if (vma->vm_ops && vma->vm_ops->page_mkwrite)
27092                 mask &= ~VM_SHARED;
27093  
27094 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
27095 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
27096 +               newprot = protection_map[(newflags | VM_EXEC) & mask];
27097 +       else
27098 +#endif
27099 +
27100         newprot = protection_map[newflags & mask];
27101  
27102         /*
27103 @@ -203,6 +307,69 @@ fail:
27104         return error;
27105  }
27106  
27107 +#ifdef CONFIG_PAX_MPROTECT
27108 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
27109 + * therefore we'll grant them VM_MAYWRITE once during their life.
27110 + *
27111 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
27112 + * basis because we want to allow the common case and not the special ones.
27113 + */
27114 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
27115 +{
27116 +       struct elfhdr elf_h;
27117 +       struct elf_phdr elf_p, p_dyn;
27118 +       elf_dyn dyn;
27119 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
27120 +
27121 +#ifndef CONFIG_PAX_NOELFRELOCS
27122 +       if ((vma->vm_start != start) ||
27123 +           !vma->vm_file ||
27124 +           !(vma->vm_flags & VM_MAYEXEC) ||
27125 +           (vma->vm_flags & VM_MAYNOTWRITE))
27126 +#endif
27127 +
27128 +               return;
27129 +
27130 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
27131 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
27132 +
27133 +#ifdef CONFIG_PAX_ETEXECRELOCS
27134 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
27135 +#else
27136 +           elf_h.e_type != ET_DYN ||
27137 +#endif
27138 +
27139 +           !elf_check_arch(&elf_h) ||
27140 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
27141 +           elf_h.e_phnum > j)
27142 +               return;
27143 +
27144 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
27145 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
27146 +                       return;
27147 +               if (elf_p.p_type == PT_DYNAMIC) {
27148 +                       p_dyn = elf_p;
27149 +                       j = i;
27150 +               }
27151 +       }
27152 +       if (elf_h.e_phnum <= j)
27153 +               return;
27154 +
27155 +       i = 0UL;
27156 +       do {
27157 +               if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
27158 +                       return;
27159 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
27160 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
27161 +                       gr_log_textrel(vma);
27162 +                       return;
27163 +               }
27164 +               i++;
27165 +       } while (dyn.d_tag != DT_NULL);
27166 +       return;
27167 +}
27168 +#endif
27169 +
27170  asmlinkage long
27171  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
27172  {
27173 @@ -222,6 +389,17 @@ sys_mprotect(unsigned long start, size_t
27174         end = start + len;
27175         if (end <= start)
27176                 return -ENOMEM;
27177 +
27178 +#ifdef CONFIG_PAX_SEGMEXEC
27179 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
27180 +               if (end > SEGMEXEC_TASK_SIZE)
27181 +                       return -EINVAL;
27182 +       } else
27183 +#endif
27184 +
27185 +       if (end > TASK_SIZE)
27186 +               return -EINVAL;
27187 +
27188         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
27189                 return -EINVAL;
27190  
27191 @@ -229,7 +407,7 @@ sys_mprotect(unsigned long start, size_t
27192         /*
27193          * Does the application expect PROT_READ to imply PROT_EXEC:
27194          */
27195 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
27196 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
27197                 prot |= PROT_EXEC;
27198  
27199         vm_flags = calc_vm_prot_bits(prot);
27200 @@ -261,6 +439,16 @@ sys_mprotect(unsigned long start, size_t
27201         if (start > vma->vm_start)
27202                 prev = vma;
27203  
27204 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
27205 +               error = -EACCES;
27206 +               goto out;
27207 +       }
27208 +
27209 +#ifdef CONFIG_PAX_MPROTECT
27210 +       if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
27211 +               pax_handle_maywrite(vma, start);
27212 +#endif
27213 +
27214         for (nstart = start ; ; ) {
27215                 unsigned long newflags;
27216  
27217 @@ -274,6 +462,12 @@ sys_mprotect(unsigned long start, size_t
27218                         goto out;
27219                 }
27220  
27221 +#ifdef CONFIG_PAX_MPROTECT
27222 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
27223 +               if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
27224 +                       newflags &= ~VM_MAYWRITE;
27225 +#endif
27226 +
27227                 error = security_file_mprotect(vma, reqprot, prot);
27228                 if (error)
27229                         goto out;
27230 @@ -297,6 +491,9 @@ sys_mprotect(unsigned long start, size_t
27231                         goto out;
27232                 }
27233         }
27234 +
27235 +       track_exec_limit(current->mm, start, end, vm_flags);
27236 +
27237  out:
27238         up_write(&current->mm->mmap_sem);
27239         return error;
27240 diff -urNp linux-2.6.18/mm/mremap.c linux-2.6.18/mm/mremap.c
27241 --- linux-2.6.18/mm/mremap.c    2006-09-19 23:42:06.000000000 -0400
27242 +++ linux-2.6.18/mm/mremap.c    2006-09-22 20:45:04.000000000 -0400
27243 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
27244                 pte = ptep_clear_flush(vma, old_addr, old_pte);
27245                 /* ZERO_PAGE can be dependant on virtual addr */
27246                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
27247 +
27248 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
27249 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
27250 +                       pte_exprotect(pte);
27251 +#endif
27252 +
27253                 set_pte_at(mm, new_addr, new_pte, pte);
27254         }
27255  
27256 @@ -253,6 +259,7 @@ unsigned long do_mremap(unsigned long ad
27257         struct vm_area_struct *vma;
27258         unsigned long ret = -EINVAL;
27259         unsigned long charged = 0;
27260 +       unsigned long task_size = TASK_SIZE;
27261  
27262         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
27263                 goto out;
27264 @@ -271,6 +278,15 @@ unsigned long do_mremap(unsigned long ad
27265         if (!new_len)
27266                 goto out;
27267  
27268 +#ifdef CONFIG_PAX_SEGMEXEC
27269 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
27270 +               task_size = SEGMEXEC_TASK_SIZE;
27271 +#endif
27272 +
27273 +       if (new_len > task_size || addr > task_size-new_len ||
27274 +           old_len > task_size || addr > task_size-old_len)
27275 +               goto out;
27276 +
27277         /* new_addr is only valid if MREMAP_FIXED is specified */
27278         if (flags & MREMAP_FIXED) {
27279                 if (new_addr & ~PAGE_MASK)
27280 @@ -278,16 +294,13 @@ unsigned long do_mremap(unsigned long ad
27281                 if (!(flags & MREMAP_MAYMOVE))
27282                         goto out;
27283  
27284 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
27285 +               if (new_addr > task_size - new_len)
27286                         goto out;
27287  
27288                 /* Check if the location we're moving into overlaps the
27289                  * old location at all, and fail if it does.
27290                  */
27291 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
27292 -                       goto out;
27293 -
27294 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
27295 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
27296                         goto out;
27297  
27298                 ret = do_munmap(mm, new_addr, new_len);
27299 @@ -321,6 +334,14 @@ unsigned long do_mremap(unsigned long ad
27300                 ret = -EINVAL;
27301                 goto out;
27302         }
27303 +
27304 +#ifdef CONFIG_PAX_SEGMEXEC
27305 +       if (vma->vm_flags & VM_MIRROR) {
27306 +               ret = -EINVAL;
27307 +               goto out;
27308 +       }
27309 +#endif
27310 +
27311         /* We can't remap across vm area boundaries */
27312         if (old_len > vma->vm_end - addr)
27313                 goto out;
27314 @@ -354,7 +375,7 @@ unsigned long do_mremap(unsigned long ad
27315         if (old_len == vma->vm_end - addr &&
27316             !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
27317             (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
27318 -               unsigned long max_addr = TASK_SIZE;
27319 +               unsigned long max_addr = task_size;
27320                 if (vma->vm_next)
27321                         max_addr = vma->vm_next->vm_start;
27322                 /* can we just expand the current mapping? */
27323 @@ -372,6 +393,7 @@ unsigned long do_mremap(unsigned long ad
27324                                                    addr + new_len);
27325                         }
27326                         ret = addr;
27327 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
27328                         goto out;
27329                 }
27330         }
27331 @@ -382,8 +404,8 @@ unsigned long do_mremap(unsigned long ad
27332          */
27333         ret = -ENOMEM;
27334         if (flags & MREMAP_MAYMOVE) {
27335 +               unsigned long map_flags = 0;
27336                 if (!(flags & MREMAP_FIXED)) {
27337 -                       unsigned long map_flags = 0;
27338                         if (vma->vm_flags & VM_MAYSHARE)
27339                                 map_flags |= MAP_SHARED;
27340  
27341 @@ -393,7 +415,12 @@ unsigned long do_mremap(unsigned long ad
27342                         if (new_addr & ~PAGE_MASK)
27343                                 goto out;
27344                 }
27345 +               map_flags = vma->vm_flags;
27346                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
27347 +               if (!(ret & ~PAGE_MASK)) {
27348 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
27349 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
27350 +               }
27351         }
27352  out:
27353         if (ret & ~PAGE_MASK)
27354 diff -urNp linux-2.6.18/mm/page_alloc.c linux-2.6.18/mm/page_alloc.c
27355 --- linux-2.6.18/mm/page_alloc.c        2006-09-19 23:42:06.000000000 -0400
27356 +++ linux-2.6.18/mm/page_alloc.c        2006-09-22 20:45:04.000000000 -0400
27357 @@ -339,7 +339,7 @@ static inline int page_is_buddy(struct p
27358  static inline void __free_one_page(struct page *page,
27359                 struct zone *zone, unsigned int order)
27360  {
27361 -       unsigned long page_idx;
27362 +       unsigned long page_idx, index;
27363         int order_size = 1 << order;
27364  
27365         if (unlikely(PageCompound(page)))
27366 @@ -350,6 +350,11 @@ static inline void __free_one_page(struc
27367         BUG_ON(page_idx & (order_size - 1));
27368         BUG_ON(bad_range(zone, page));
27369  
27370 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
27371 +       for (index = order_size; index; --index)
27372 +               clear_highpage(page + index - 1);
27373 +#endif
27374 +
27375         zone->free_pages += order_size;
27376         while (order < MAX_ORDER-1) {
27377                 unsigned long combined_idx;
27378 diff -urNp linux-2.6.18/mm/rmap.c linux-2.6.18/mm/rmap.c
27379 --- linux-2.6.18/mm/rmap.c      2006-09-19 23:42:06.000000000 -0400
27380 +++ linux-2.6.18/mm/rmap.c      2006-09-22 20:45:04.000000000 -0400
27381 @@ -106,6 +106,19 @@ int anon_vma_prepare(struct vm_area_stru
27382                         list_add_tail(&vma->anon_vma_node, &anon_vma->head);
27383                         allocated = NULL;
27384                 }
27385 +
27386 +#ifdef CONFIG_PAX_SEGMEXEC
27387 +               if (vma->vm_flags & VM_MIRROR) {
27388 +                       struct vm_area_struct *vma_m;
27389 +
27390 +                       vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
27391 +                       BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
27392 +                       BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
27393 +                       vma_m->anon_vma = anon_vma;
27394 +                       __anon_vma_link(vma_m);
27395 +               }
27396 +#endif
27397 +
27398                 spin_unlock(&mm->page_table_lock);
27399  
27400                 if (locked)
27401 diff -urNp linux-2.6.18/mm/shmem.c linux-2.6.18/mm/shmem.c
27402 --- linux-2.6.18/mm/shmem.c     2006-09-19 23:42:06.000000000 -0400
27403 +++ linux-2.6.18/mm/shmem.c     2006-09-22 20:04:35.000000000 -0400
27404 @@ -2235,7 +2235,7 @@ static struct file_system_type tmpfs_fs_
27405         .get_sb         = shmem_get_sb,
27406         .kill_sb        = kill_litter_super,
27407  };
27408 -static struct vfsmount *shm_mnt;
27409 +struct vfsmount *shm_mnt;
27410  
27411  static int __init init_tmpfs(void)
27412  {
27413 diff -urNp linux-2.6.18/mm/slab.c linux-2.6.18/mm/slab.c
27414 --- linux-2.6.18/mm/slab.c      2006-09-19 23:42:06.000000000 -0400
27415 +++ linux-2.6.18/mm/slab.c      2006-09-22 20:45:04.000000000 -0400
27416 @@ -1613,6 +1613,11 @@ static void store_stackinfo(struct kmem_
27417  
27418                 while (!kstack_end(sptr)) {
27419                         svalue = *sptr++;
27420 +
27421 +#ifdef CONFIG_PAX_KERNEXEC
27422 +                       svalue += __KERNEL_TEXT_OFFSET;
27423 +#endif
27424 +
27425                         if (kernel_text_address(svalue)) {
27426                                 *addr++ = svalue;
27427                                 size -= sizeof(unsigned long);
27428 diff -urNp linux-2.6.18/mm/tiny-shmem.c linux-2.6.18/mm/tiny-shmem.c
27429 --- linux-2.6.18/mm/tiny-shmem.c        2006-09-19 23:42:06.000000000 -0400
27430 +++ linux-2.6.18/mm/tiny-shmem.c        2006-09-22 20:04:35.000000000 -0400
27431 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
27432         .kill_sb        = kill_litter_super,
27433  };
27434  
27435 -static struct vfsmount *shm_mnt;
27436 +struct vfsmount *shm_mnt;
27437  
27438  static int __init init_tmpfs(void)
27439  {
27440 diff -urNp linux-2.6.18/mm/vmalloc.c linux-2.6.18/mm/vmalloc.c
27441 --- linux-2.6.18/mm/vmalloc.c   2006-09-19 23:42:06.000000000 -0400
27442 +++ linux-2.6.18/mm/vmalloc.c   2006-09-22 20:45:04.000000000 -0400
27443 @@ -193,6 +193,8 @@ struct vm_struct *__get_vm_area_node(uns
27444  
27445         write_lock(&vmlist_lock);
27446         for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
27447 +               if (addr > end - size)
27448 +                       goto out;
27449                 if ((unsigned long)tmp->addr < addr) {
27450                         if((unsigned long)tmp->addr + tmp->size >= addr)
27451                                 addr = ALIGN(tmp->size + 
27452 @@ -204,8 +206,6 @@ struct vm_struct *__get_vm_area_node(uns
27453                 if (size + addr <= (unsigned long)tmp->addr)
27454                         goto found;
27455                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
27456 -               if (addr > end - size)
27457 -                       goto out;
27458         }
27459  
27460  found:
27461 diff -urNp linux-2.6.18/net/core/sock.c linux-2.6.18/net/core/sock.c
27462 --- linux-2.6.18/net/core/sock.c        2006-09-19 23:42:06.000000000 -0400
27463 +++ linux-2.6.18/net/core/sock.c        2006-09-22 20:45:04.000000000 -0400
27464 @@ -808,7 +808,7 @@ lenout:
27465   *
27466   * (We also register the sk_lock with the lock validator.)
27467   */
27468 -static void inline sock_lock_init(struct sock *sk)
27469 +static inline void sock_lock_init(struct sock *sk)
27470  {
27471         spin_lock_init(&sk->sk_lock.slock);
27472         sk->sk_lock.owner = NULL;
27473 diff -urNp linux-2.6.18/net/dccp/ccids/ccid3.c linux-2.6.18/net/dccp/ccids/ccid3.c
27474 --- linux-2.6.18/net/dccp/ccids/ccid3.c 2006-09-19 23:42:06.000000000 -0400
27475 +++ linux-2.6.18/net/dccp/ccids/ccid3.c 2006-09-22 20:45:04.000000000 -0400
27476 @@ -68,7 +68,7 @@ static int ccid3_debug;
27477                 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
27478         } while (0)
27479  #else
27480 -#define ccid3_pr_debug(format, a...)
27481 +#define ccid3_pr_debug(format, a...) do {} while (0)
27482  #endif
27483  
27484  static struct dccp_tx_hist *ccid3_tx_hist;
27485 diff -urNp linux-2.6.18/net/dccp/dccp.h linux-2.6.18/net/dccp/dccp.h
27486 --- linux-2.6.18/net/dccp/dccp.h        2006-09-19 23:42:06.000000000 -0400
27487 +++ linux-2.6.18/net/dccp/dccp.h        2006-09-22 20:45:04.000000000 -0400
27488 @@ -28,8 +28,8 @@ extern int dccp_debug;
27489  #define dccp_pr_debug_cat(format, a...) do { if (dccp_debug) \
27490                                              printk(format, ##a); } while (0)
27491  #else
27492 -#define dccp_pr_debug(format, a...)
27493 -#define dccp_pr_debug_cat(format, a...)
27494 +#define dccp_pr_debug(format, a...) do {} while (0)
27495 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
27496  #endif
27497  
27498  extern struct inet_hashinfo dccp_hashinfo;
27499 diff -urNp linux-2.6.18/net/ipv4/inet_connection_sock.c linux-2.6.18/net/ipv4/inet_connection_sock.c
27500 --- linux-2.6.18/net/ipv4/inet_connection_sock.c        2006-09-19 23:42:06.000000000 -0400
27501 +++ linux-2.6.18/net/ipv4/inet_connection_sock.c        2006-09-22 20:04:35.000000000 -0400
27502 @@ -15,6 +15,7 @@
27503  
27504  #include <linux/module.h>
27505  #include <linux/jhash.h>
27506 +#include <linux/grsecurity.h>
27507  
27508  #include <net/inet_connection_sock.h>
27509  #include <net/inet_hashtables.h>
27510 diff -urNp linux-2.6.18/net/ipv4/inet_hashtables.c linux-2.6.18/net/ipv4/inet_hashtables.c
27511 --- linux-2.6.18/net/ipv4/inet_hashtables.c     2006-09-19 23:42:06.000000000 -0400
27512 +++ linux-2.6.18/net/ipv4/inet_hashtables.c     2006-09-22 20:04:35.000000000 -0400
27513 @@ -18,11 +18,14 @@
27514  #include <linux/sched.h>
27515  #include <linux/slab.h>
27516  #include <linux/wait.h>
27517 +#include <linux/grsecurity.h>
27518  
27519  #include <net/inet_connection_sock.h>
27520  #include <net/inet_hashtables.h>
27521  #include <net/ip.h>
27522  
27523 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
27524 +
27525  /*
27526   * Allocate and initialize a new local port bind bucket.
27527   * The bindhash mutex for snum's hash chain must be held here.
27528 @@ -309,6 +312,8 @@ ok:
27529                 }
27530                 spin_unlock(&head->lock);
27531  
27532 +               gr_update_task_in_ip_table(current, inet_sk(sk));
27533 +
27534                 if (tw) {
27535                         inet_twsk_deschedule(tw, death_row);
27536                         inet_twsk_put(tw);
27537 diff -urNp linux-2.6.18/net/ipv4/netfilter/ipt_stealth.c linux-2.6.18/net/ipv4/netfilter/ipt_stealth.c
27538 --- linux-2.6.18/net/ipv4/netfilter/ipt_stealth.c       1969-12-31 19:00:00.000000000 -0500
27539 +++ linux-2.6.18/net/ipv4/netfilter/ipt_stealth.c       2006-09-22 20:04:35.000000000 -0400
27540 @@ -0,0 +1,116 @@
27541 +/* Kernel module to add stealth support.
27542 + *
27543 + * Copyright (C) 2002,2005 Brad Spengler  <spender@grsecurity.net>
27544 + *
27545 + */
27546 +
27547 +#include <linux/kernel.h>
27548 +#include <linux/module.h>
27549 +#include <linux/skbuff.h>
27550 +#include <linux/net.h>
27551 +#include <linux/sched.h>
27552 +#include <linux/inet.h>
27553 +#include <linux/stddef.h>
27554 +
27555 +#include <net/ip.h>
27556 +#include <net/sock.h>
27557 +#include <net/tcp.h>
27558 +#include <net/udp.h>
27559 +#include <net/route.h>
27560 +#include <net/inet_common.h>
27561 +
27562 +#include <linux/netfilter_ipv4/ip_tables.h>
27563 +
27564 +MODULE_LICENSE("GPL");
27565 +
27566 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
27567 +
27568 +static int
27569 +match(const struct sk_buff *skb,
27570 +      const struct net_device *in,
27571 +      const struct net_device *out,
27572 +      const struct xt_match *match,
27573 +      const void *matchinfo,
27574 +      int offset,
27575 +      unsigned int protoff,
27576 +      int *hotdrop)
27577 +{
27578 +       struct iphdr *ip = skb->nh.iph;
27579 +       struct tcphdr th;
27580 +       struct udphdr uh;
27581 +       struct sock *sk = NULL;
27582 +
27583 +       if (!ip || offset) return 0;
27584 +
27585 +       switch(ip->protocol) {
27586 +       case IPPROTO_TCP:
27587 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
27588 +                       *hotdrop = 1;
27589 +                       return 0;
27590 +               }
27591 +               if (!(th.syn && !th.ack)) return 0;
27592 +               sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);        
27593 +               break;
27594 +       case IPPROTO_UDP:
27595 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
27596 +                       *hotdrop = 1;
27597 +                       return 0;
27598 +               }
27599 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
27600 +               break;
27601 +       default:
27602 +               return 0;
27603 +       }
27604 +
27605 +       if(!sk) // port is being listened on, match this
27606 +               return 1;
27607 +       else {
27608 +               sock_put(sk);
27609 +               return 0;
27610 +       }
27611 +}
27612 +
27613 +/* Called when user tries to insert an entry of this type. */
27614 +static int
27615 +checkentry(const char *tablename,
27616 +           const void *nip,
27617 +          const struct xt_match *match,
27618 +           void *matchinfo,
27619 +           unsigned int matchsize,
27620 +           unsigned int hook_mask)
27621 +{
27622 +       const struct ipt_ip *ip = (const struct ipt_ip *)nip;
27623 +        if (matchsize != IPT_ALIGN(0))
27624 +                return 0;
27625 +
27626 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
27627 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
27628 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
27629 +                       return 1;
27630 +
27631 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
27632 +
27633 +        return 0;
27634 +}
27635 +
27636 +
27637 +static struct ipt_match stealth_match = {
27638 +       .name = "stealth",
27639 +       .match = match,
27640 +       .checkentry = checkentry,
27641 +       .destroy = NULL,
27642 +       .me = THIS_MODULE
27643 +};
27644 +
27645 +static int __init init(void)
27646 +{
27647 +       return ipt_register_match(&stealth_match);
27648 +}
27649 +
27650 +static void __exit fini(void)
27651 +{
27652 +       ipt_unregister_match(&stealth_match);
27653 +}
27654 +
27655 +module_init(init);
27656 +module_exit(fini);
27657 diff -urNp linux-2.6.18/net/ipv4/netfilter/Kconfig linux-2.6.18/net/ipv4/netfilter/Kconfig
27658 --- linux-2.6.18/net/ipv4/netfilter/Kconfig     2006-09-19 23:42:06.000000000 -0400
27659 +++ linux-2.6.18/net/ipv4/netfilter/Kconfig     2006-09-22 20:04:35.000000000 -0400
27660 @@ -340,6 +340,21 @@ config IP_NF_MATCH_HASHLIMIT
27661           destination IP' or `500pps from any given source IP'  with a single
27662           IPtables rule.
27663  
27664 +config IP_NF_MATCH_STEALTH
27665 +       tristate "stealth match support"
27666 +       depends on IP_NF_IPTABLES
27667 +       help
27668 +         Enabling this option will drop all syn packets coming to unserved tcp
27669 +         ports as well as all packets coming to unserved udp ports.  If you
27670 +         are using your system to route any type of packets (ie. via NAT)
27671 +         you should put this module at the end of your ruleset, since it will
27672 +         drop packets that aren't going to ports that are listening on your
27673 +         machine itself, it doesn't take into account that the packet might be
27674 +         destined for someone on your internal network if you're using NAT for
27675 +         instance.
27676 +
27677 +         To compile it as a module, choose M here.  If unsure, say N.
27678 +
27679  # `filter', generic and specific targets
27680  config IP_NF_FILTER
27681         tristate "Packet filtering"
27682 @@ -646,4 +661,3 @@ config IP_NF_ARP_MANGLE
27683           hardware and network addresses.
27684  
27685  endmenu
27686 -
27687 diff -urNp linux-2.6.18/net/ipv4/netfilter/Makefile linux-2.6.18/net/ipv4/netfilter/Makefile
27688 --- linux-2.6.18/net/ipv4/netfilter/Makefile    2006-09-19 23:42:06.000000000 -0400
27689 +++ linux-2.6.18/net/ipv4/netfilter/Makefile    2006-09-22 20:04:35.000000000 -0400
27690 @@ -63,6 +63,7 @@ obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_ds
27691  obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
27692  obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
27693  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
27694 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
27695  
27696  # targets
27697  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
27698 diff -urNp linux-2.6.18/net/ipv4/tcp_ipv4.c linux-2.6.18/net/ipv4/tcp_ipv4.c
27699 --- linux-2.6.18/net/ipv4/tcp_ipv4.c    2006-09-19 23:42:06.000000000 -0400
27700 +++ linux-2.6.18/net/ipv4/tcp_ipv4.c    2006-09-22 20:04:35.000000000 -0400
27701 @@ -61,6 +61,7 @@
27702  #include <linux/jhash.h>
27703  #include <linux/init.h>
27704  #include <linux/times.h>
27705 +#include <linux/grsecurity.h>
27706  
27707  #include <net/icmp.h>
27708  #include <net/inet_hashtables.h>
27709 diff -urNp linux-2.6.18/net/ipv4/tcp_lp.c linux-2.6.18/net/ipv4/tcp_lp.c
27710 --- linux-2.6.18/net/ipv4/tcp_lp.c      2006-09-19 23:42:06.000000000 -0400
27711 +++ linux-2.6.18/net/ipv4/tcp_lp.c      2006-09-22 20:45:04.000000000 -0400
27712 @@ -165,7 +165,7 @@ static u32 tcp_lp_remote_hz_estimator(st
27713  
27714   out:
27715         /* record time for successful remote HZ calc */
27716 -       if (rhz > 0)
27717 +       if (rhz > 63)
27718                 lp->flag |= LP_VALID_RHZ;
27719         else
27720                 lp->flag &= ~LP_VALID_RHZ;
27721 diff -urNp linux-2.6.18/net/ipv4/udp.c linux-2.6.18/net/ipv4/udp.c
27722 --- linux-2.6.18/net/ipv4/udp.c 2006-09-19 23:42:06.000000000 -0400
27723 +++ linux-2.6.18/net/ipv4/udp.c 2006-09-22 20:04:35.000000000 -0400
27724 @@ -101,6 +101,7 @@
27725  #include <linux/skbuff.h>
27726  #include <linux/proc_fs.h>
27727  #include <linux/seq_file.h>
27728 +#include <linux/grsecurity.h>
27729  #include <net/sock.h>
27730  #include <net/udp.h>
27731  #include <net/icmp.h>
27732 @@ -109,6 +110,12 @@
27733  #include <net/checksum.h>
27734  #include <net/xfrm.h>
27735  
27736 +extern int gr_search_udp_recvmsg(const struct sock *sk,
27737 +                                const struct sk_buff *skb);
27738 +extern int gr_search_udp_sendmsg(const struct sock *sk,
27739 +                                const struct sockaddr_in *addr);
27740 +
27741 +
27742  /*
27743   *     Snmp MIB for the UDP layer
27744   */
27745 @@ -265,8 +272,7 @@ static struct sock *udp_v4_lookup_longwa
27746         return result;
27747  }
27748  
27749 -static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
27750 -                                            u32 daddr, u16 dport, int dif)
27751 +struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
27752  {
27753         struct sock *sk;
27754  
27755 @@ -541,9 +547,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
27756                 dport = usin->sin_port;
27757                 if (dport == 0)
27758                         return -EINVAL;
27759 +
27760 +               if (!gr_search_udp_sendmsg(sk, usin))
27761 +                       return -EPERM;
27762         } else {
27763                 if (sk->sk_state != TCP_ESTABLISHED)
27764                         return -EDESTADDRREQ;
27765 +
27766 +               if (!gr_search_udp_sendmsg(sk, NULL))
27767 +                       return -EPERM;
27768 +
27769                 daddr = inet->daddr;
27770                 dport = inet->dport;
27771                 /* Open fast path for connected socket.
27772 @@ -797,6 +810,11 @@ try_again:
27773         if (!skb)
27774                 goto out;
27775    
27776 +       if (!gr_search_udp_recvmsg(sk, skb)) {
27777 +               err = -EPERM;
27778 +               goto out_free;
27779 +       }
27780 +
27781         copied = skb->len - sizeof(struct udphdr);
27782         if (copied > len) {
27783                 copied = len;
27784 diff -urNp linux-2.6.18/net/ipv6/addrconf.c linux-2.6.18/net/ipv6/addrconf.c
27785 --- linux-2.6.18/net/ipv6/addrconf.c    2006-09-19 23:42:06.000000000 -0400
27786 +++ linux-2.6.18/net/ipv6/addrconf.c    2006-09-22 20:45:04.000000000 -0400
27787 @@ -861,7 +861,7 @@ struct ipv6_saddr_score {
27788  #define IPV6_SADDR_SCORE_LABEL         0x0020
27789  #define IPV6_SADDR_SCORE_PRIVACY       0x0040
27790  
27791 -static int inline ipv6_saddr_preferred(int type)
27792 +static inline int ipv6_saddr_preferred(int type)
27793  {
27794         if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
27795                     IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
27796 @@ -870,7 +870,7 @@ static int inline ipv6_saddr_preferred(i
27797  }
27798  
27799  /* static matching label */
27800 -static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
27801 +static inline int ipv6_saddr_label(const struct in6_addr *addr, int type)
27802  {
27803   /*
27804    *    prefix (longest match)  label
27805 @@ -3297,7 +3297,7 @@ static void inet6_ifa_notify(int event, 
27806         netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFADDR, GFP_ATOMIC);
27807  }
27808  
27809 -static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
27810 +static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
27811                                 __s32 *array, int bytes)
27812  {
27813         memset(array, 0, bytes);
27814 diff -urNp linux-2.6.18/net/ipv6/raw.c linux-2.6.18/net/ipv6/raw.c
27815 --- linux-2.6.18/net/ipv6/raw.c 2006-09-19 23:42:06.000000000 -0400
27816 +++ linux-2.6.18/net/ipv6/raw.c 2006-09-22 20:45:04.000000000 -0400
27817 @@ -522,7 +522,7 @@ out:
27818         return err;
27819  }
27820  
27821 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
27822 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
27823                         struct flowi *fl, struct rt6_info *rt, 
27824                         unsigned int flags)
27825  {
27826 @@ -644,7 +644,7 @@ static int rawv6_sendmsg(struct kiocb *i
27827         /* Rough check on arithmetic overflow,
27828            better check is made in ip6_build_xmit
27829          */
27830 -       if (len < 0)
27831 +       if ((ssize_t)len < 0)
27832                 return -EMSGSIZE;
27833  
27834         /* Mirror BSD error message compatibility */
27835 diff -urNp linux-2.6.18/net/ipv6/route.c linux-2.6.18/net/ipv6/route.c
27836 --- linux-2.6.18/net/ipv6/route.c       2006-09-19 23:42:06.000000000 -0400
27837 +++ linux-2.6.18/net/ipv6/route.c       2006-09-22 20:45:04.000000000 -0400
27838 @@ -265,7 +265,7 @@ static inline void rt6_probe(struct rt6_
27839  /*
27840   * Default Router Selection (RFC 2461 6.3.6)
27841   */
27842 -static int inline rt6_check_dev(struct rt6_info *rt, int oif)
27843 +static inline int rt6_check_dev(struct rt6_info *rt, int oif)
27844  {
27845         struct net_device *dev = rt->rt6i_dev;
27846         if (!oif || dev->ifindex == oif)
27847 @@ -276,7 +276,7 @@ static int inline rt6_check_dev(struct r
27848         return 0;
27849  }
27850  
27851 -static int inline rt6_check_neigh(struct rt6_info *rt)
27852 +static inline int rt6_check_neigh(struct rt6_info *rt)
27853  {
27854         struct neighbour *neigh = rt->rt6i_nexthop;
27855         int m = 0;
27856 diff -urNp linux-2.6.18/net/ipv6/xfrm6_tunnel.c linux-2.6.18/net/ipv6/xfrm6_tunnel.c
27857 --- linux-2.6.18/net/ipv6/xfrm6_tunnel.c        2006-09-19 23:42:06.000000000 -0400
27858 +++ linux-2.6.18/net/ipv6/xfrm6_tunnel.c        2006-09-22 20:45:04.000000000 -0400
27859 @@ -58,7 +58,7 @@ static kmem_cache_t *xfrm6_tunnel_spi_km
27860  static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
27861  static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
27862  
27863 -static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
27864 +static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
27865  {
27866         unsigned h;
27867  
27868 @@ -70,7 +70,7 @@ static unsigned inline xfrm6_tunnel_spi_
27869         return h;
27870  }
27871  
27872 -static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi)
27873 +static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
27874  {
27875         return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
27876  }
27877 diff -urNp linux-2.6.18/net/sctp/sm_statetable.c linux-2.6.18/net/sctp/sm_statetable.c
27878 --- linux-2.6.18/net/sctp/sm_statetable.c       2006-09-19 23:42:06.000000000 -0400
27879 +++ linux-2.6.18/net/sctp/sm_statetable.c       2006-09-22 20:45:04.000000000 -0400
27880 @@ -986,7 +986,7 @@ static const sctp_sm_table_entry_t *sctp
27881         if (state > SCTP_STATE_MAX)
27882                 return &bug;
27883  
27884 -       if (cid >= 0 && cid <= SCTP_CID_BASE_MAX)
27885 +       if (cid <= SCTP_CID_BASE_MAX)
27886                 return &chunk_event_table[cid][state];
27887  
27888         if (sctp_prsctp_enable) {
27889 diff -urNp linux-2.6.18/net/socket.c linux-2.6.18/net/socket.c
27890 --- linux-2.6.18/net/socket.c   2006-09-19 23:42:06.000000000 -0400
27891 +++ linux-2.6.18/net/socket.c   2006-09-22 20:04:35.000000000 -0400
27892 @@ -85,6 +85,7 @@
27893  #include <linux/kmod.h>
27894  #include <linux/audit.h>
27895  #include <linux/wireless.h>
27896 +#include <linux/in.h>
27897  
27898  #include <asm/uaccess.h>
27899  #include <asm/unistd.h>
27900 @@ -94,6 +95,21 @@
27901  #include <net/sock.h>
27902  #include <linux/netfilter.h>
27903  
27904 +extern void gr_attach_curr_ip(const struct sock *sk);
27905 +extern int gr_handle_sock_all(const int family, const int type,
27906 +                             const int protocol);
27907 +extern int gr_handle_sock_server(const struct sockaddr *sck);
27908 +extern int gr_handle_sock_server_other(const struct socket *sck);
27909 +extern int gr_handle_sock_client(const struct sockaddr *sck);
27910 +extern int gr_search_connect(const struct socket * sock,
27911 +                            const struct sockaddr_in * addr);
27912 +extern int gr_search_bind(const struct socket * sock,
27913 +                          const struct sockaddr_in * addr);
27914 +extern int gr_search_listen(const struct socket * sock);
27915 +extern int gr_search_accept(const struct socket * sock);
27916 +extern int gr_search_socket(const int domain, const int type,
27917 +                           const int protocol);
27918 +
27919  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
27920  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
27921                          size_t size, loff_t pos);
27922 @@ -341,7 +357,7 @@ static int sockfs_get_sb(struct file_sys
27923                              mnt);
27924  }
27925  
27926 -static struct vfsmount *sock_mnt __read_mostly;
27927 +struct vfsmount *sock_mnt __read_mostly;
27928  
27929  static struct file_system_type sock_fs_type = {
27930         .name =         "sockfs",
27931 @@ -1241,6 +1257,16 @@ asmlinkage long sys_socket(int family, i
27932         int retval;
27933         struct socket *sock;
27934  
27935 +       if(!gr_search_socket(family, type, protocol)) {
27936 +               retval = -EACCES;
27937 +               goto out;
27938 +       }
27939 +
27940 +       if (gr_handle_sock_all(family, type, protocol)) {
27941 +               retval = -EACCES;
27942 +               goto out;
27943 +       }
27944 +
27945         retval = sock_create(family, type, protocol, &sock);
27946         if (retval < 0)
27947                 goto out;
27948 @@ -1336,16 +1362,25 @@ asmlinkage long sys_bind(int fd, struct 
27949  {
27950         struct socket *sock;
27951         char address[MAX_SOCK_ADDR];
27952 +       struct sockaddr *sck;
27953         int err, fput_needed;
27954  
27955         if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
27956         {
27957                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
27958 +                       sck = (struct sockaddr *)address;
27959 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck) ||
27960 +                           gr_handle_sock_server(sck)) {
27961 +                               err = -EACCES;
27962 +                               goto error;
27963 +                       }
27964 +
27965                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
27966                         if (!err)
27967                                 err = sock->ops->bind(sock,
27968                                         (struct sockaddr *)address, addrlen);
27969                 }
27970 +error:
27971                 fput_light(sock->file, fput_needed);
27972         }                       
27973         return err;
27974 @@ -1369,10 +1404,17 @@ asmlinkage long sys_listen(int fd, int b
27975                 if ((unsigned) backlog > sysctl_somaxconn)
27976                         backlog = sysctl_somaxconn;
27977  
27978 +               if (gr_handle_sock_server_other(sock) ||
27979 +                   !gr_search_listen(sock)) {
27980 +                       err = -EPERM;
27981 +                       goto error;
27982 +               }
27983 +
27984                 err = security_socket_listen(sock, backlog);
27985                 if (!err)
27986                         err = sock->ops->listen(sock, backlog);
27987  
27988 +error:
27989                 fput_light(sock->file, fput_needed);
27990         }
27991         return err;
27992 @@ -1409,6 +1451,13 @@ asmlinkage long sys_accept(int fd, struc
27993         newsock->type = sock->type;
27994         newsock->ops = sock->ops;
27995  
27996 +       if (gr_handle_sock_server_other(sock) ||
27997 +           !gr_search_accept(sock)) {
27998 +               err = -EPERM;
27999 +               sock_release(newsock);
28000 +               goto out_put;
28001 +       }
28002 +
28003         /*
28004          * We don't need try_module_get here, as the listening socket (sock)
28005          * has the protocol module (sock->ops->owner) held.
28006 @@ -1450,6 +1499,7 @@ asmlinkage long sys_accept(int fd, struc
28007         err = newfd;
28008  
28009         security_socket_post_accept(sock, newsock);
28010 +       gr_attach_curr_ip(newsock->sk);
28011  
28012  out_put:
28013         fput_light(sock->file, fput_needed);
28014 @@ -1478,6 +1528,7 @@ asmlinkage long sys_connect(int fd, stru
28015  {
28016         struct socket *sock;
28017         char address[MAX_SOCK_ADDR];
28018 +       struct sockaddr *sck;
28019         int err, fput_needed;
28020  
28021         sock = sockfd_lookup_light(fd, &err, &fput_needed);
28022 @@ -1487,6 +1538,13 @@ asmlinkage long sys_connect(int fd, stru
28023         if (err < 0)
28024                 goto out_put;
28025  
28026 +       sck = (struct sockaddr *)address;
28027 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
28028 +           gr_handle_sock_client(sck)) {
28029 +               err = -EACCES;
28030 +               goto out_put;
28031 +       }
28032 +
28033         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
28034         if (err)
28035                 goto out_put;
28036 @@ -1741,6 +1799,7 @@ asmlinkage long sys_shutdown(int fd, int
28037                         err = sock->ops->shutdown(sock, how);
28038                 fput_light(sock->file, fput_needed);
28039         }
28040 +
28041         return err;
28042  }
28043  
28044 diff -urNp linux-2.6.18/net/unix/af_unix.c linux-2.6.18/net/unix/af_unix.c
28045 --- linux-2.6.18/net/unix/af_unix.c     2006-09-19 23:42:06.000000000 -0400
28046 +++ linux-2.6.18/net/unix/af_unix.c     2006-09-22 20:04:35.000000000 -0400
28047 @@ -116,6 +116,7 @@
28048  #include <linux/vs_context.h>
28049  #include <linux/vs_network.h>
28050  #include <linux/vs_limit.h>
28051 +#include <linux/grsecurity.h>
28052  
28053  int sysctl_unix_max_dgram_qlen = 10;
28054  
28055 @@ -706,6 +707,11 @@ static struct sock *unix_find_other(stru
28056                 if (err)
28057                         goto put_fail;
28058  
28059 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
28060 +                       err = -EACCES;
28061 +                       goto put_fail;
28062 +               }
28063 +
28064                 err = -ECONNREFUSED;
28065                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
28066                         goto put_fail;
28067 @@ -729,6 +735,13 @@ static struct sock *unix_find_other(stru
28068                 if (u) {
28069                         struct dentry *dentry;
28070                         dentry = unix_sk(u)->dentry;
28071 +
28072 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
28073 +                               err = -EPERM;
28074 +                               sock_put(u);
28075 +                               goto fail;
28076 +                       }
28077 +
28078                         if (dentry)
28079                                 touch_atime(unix_sk(u)->mnt, dentry);
28080                 } else
28081 @@ -807,9 +820,18 @@ static int unix_bind(struct socket *sock
28082                  */
28083                 mode = S_IFSOCK |
28084                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
28085 +
28086 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
28087 +                       err = -EACCES;
28088 +                       goto out_mknod_dput;
28089 +               }
28090 +
28091                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
28092                 if (err)
28093                         goto out_mknod_dput;
28094 +
28095 +               gr_handle_create(dentry, nd.mnt);
28096 +
28097                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
28098                 dput(nd.dentry);
28099                 nd.dentry = dentry;
28100 @@ -827,6 +849,10 @@ static int unix_bind(struct socket *sock
28101                         goto out_unlock;
28102                 }
28103  
28104 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
28105 +               sk->sk_peercred.pid = current->pid;
28106 +#endif
28107 +
28108                 list = &unix_socket_table[addr->hash];
28109         } else {
28110                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
28111 diff -urNp linux-2.6.18/net/xfrm/xfrm_user.c linux-2.6.18/net/xfrm/xfrm_user.c
28112 --- linux-2.6.18/net/xfrm/xfrm_user.c   2006-09-19 23:42:06.000000000 -0400
28113 +++ linux-2.6.18/net/xfrm/xfrm_user.c   2006-09-22 20:45:04.000000000 -0400
28114 @@ -1584,7 +1584,7 @@ nlmsg_failure:
28115         return -1;
28116  }
28117  
28118 -static int inline xfrm_sa_len(struct xfrm_state *x)
28119 +static inline int xfrm_sa_len(struct xfrm_state *x)
28120  {
28121         int l = 0;
28122         if (x->aalg)
28123 diff -urNp linux-2.6.18/security/commoncap.c linux-2.6.18/security/commoncap.c
28124 --- linux-2.6.18/security/commoncap.c   2006-09-19 23:42:06.000000000 -0400
28125 +++ linux-2.6.18/security/commoncap.c   2006-09-22 20:04:35.000000000 -0400
28126 @@ -23,6 +23,7 @@
28127  #include <linux/ptrace.h>
28128  #include <linux/xattr.h>
28129  #include <linux/hugetlb.h>
28130 +#include <linux/grsecurity.h>
28131  
28132  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
28133  {
28134 @@ -44,7 +45,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
28135  int cap_capable (struct task_struct *tsk, int cap)
28136  {
28137         /* Derived from include/linux/sched.h:capable. */
28138 -       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
28139 +       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
28140 +               return 0;
28141 +       return -EPERM;
28142 +}
28143 +
28144 +int cap_capable_nolog (struct task_struct *tsk, int cap)
28145 +{
28146 +       /* Derived from include/linux/sched.h:capable. */
28147 +       if (cap_raised (tsk->cap_effective, cap))
28148                 return 0;
28149         return -EPERM;
28150  }
28151 @@ -163,8 +172,11 @@ void cap_bprm_apply_creds (struct linux_
28152                 }
28153         }
28154  
28155 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
28156 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
28157 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
28158 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
28159 +
28160 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
28161 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
28162  
28163         /* For init, we want to retain the capabilities set
28164          * in the init_task struct. Thus we skip the usual
28165 @@ -175,6 +187,8 @@ void cap_bprm_apply_creds (struct linux_
28166                     cap_intersect (new_permitted, bprm->cap_effective);
28167         }
28168  
28169 +       gr_handle_chroot_caps(current);
28170 +
28171         /* AUD: Audit candidate if current->cap_effective is set */
28172  
28173         current->keep_capabilities = 0;
28174 @@ -320,12 +334,13 @@ int cap_vm_enough_memory(long pages)
28175  {
28176         int cap_sys_admin = 0;
28177  
28178 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
28179 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
28180                 cap_sys_admin = 1;
28181         return __vm_enough_memory(pages, cap_sys_admin);
28182  }
28183  
28184  EXPORT_SYMBOL(cap_capable);
28185 +EXPORT_SYMBOL(cap_capable_nolog);
28186  EXPORT_SYMBOL(cap_settime);
28187  EXPORT_SYMBOL(cap_ptrace);
28188  EXPORT_SYMBOL(cap_capget);
28189 diff -urNp linux-2.6.18/security/dummy.c linux-2.6.18/security/dummy.c
28190 --- linux-2.6.18/security/dummy.c       2006-09-19 23:42:06.000000000 -0400
28191 +++ linux-2.6.18/security/dummy.c       2006-09-22 20:04:35.000000000 -0400
28192 @@ -28,6 +28,7 @@
28193  #include <linux/hugetlb.h>
28194  #include <linux/ptrace.h>
28195  #include <linux/file.h>
28196 +#include <linux/grsecurity.h>
28197  
28198  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
28199  {
28200 @@ -138,8 +139,11 @@ static void dummy_bprm_apply_creds (stru
28201                 }
28202         }
28203  
28204 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
28205 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
28206 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
28207 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
28208 +
28209 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
28210 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
28211  
28212         dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
28213  }
28214 diff -urNp linux-2.6.18/security/Kconfig linux-2.6.18/security/Kconfig
28215 --- linux-2.6.18/security/Kconfig       2006-09-19 23:42:06.000000000 -0400
28216 +++ linux-2.6.18/security/Kconfig       2006-09-22 20:49:25.000000000 -0400
28217 @@ -4,6 +4,432 @@
28218  
28219  menu "Security options"
28220  
28221 +menu "PaX"
28222 +
28223 +config PAX
28224 +       bool "Enable various PaX features"
28225 +       depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
28226 +       help
28227 +         This allows you to enable various PaX features.  PaX adds
28228 +         intrusion prevention mechanisms to the kernel that reduce
28229 +         the risks posed by exploitable memory corruption bugs.
28230 +
28231 +menu "PaX Control"
28232 +       depends on PAX
28233 +
28234 +config PAX_SOFTMODE
28235 +       bool 'Support soft mode'
28236 +       help
28237 +         Enabling this option will allow you to run PaX in soft mode, that
28238 +         is, PaX features will not be enforced by default, only on executables
28239 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
28240 +         is the only way to mark executables for soft mode use.
28241 +
28242 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
28243 +         line option on boot.  Furthermore you can control various PaX features
28244 +         at runtime via the entries in /proc/sys/kernel/pax.
28245 +
28246 +config PAX_EI_PAX
28247 +       bool 'Use legacy ELF header marking'
28248 +       help
28249 +         Enabling this option will allow you to control PaX features on
28250 +         a per executable basis via the 'chpax' utility available at
28251 +         http://pax.grsecurity.net/.  The control flags will be read from
28252 +         an otherwise reserved part of the ELF header.  This marking has
28253 +         numerous drawbacks (no support for soft-mode, toolchain does not
28254 +         know about the non-standard use of the ELF header) therefore it
28255 +         has been deprecated in favour of PT_PAX_FLAGS support.
28256 +
28257 +         If you have applications not marked by the PT_PAX_FLAGS ELF
28258 +         program header then you MUST enable this option otherwise they
28259 +         will not get any protection.
28260 +
28261 +         Note that if you enable PT_PAX_FLAGS marking support as well,
28262 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
28263 +
28264 +config PAX_PT_PAX_FLAGS
28265 +       bool 'Use ELF program header marking'
28266 +       help
28267 +         Enabling this option will allow you to control PaX features on
28268 +         a per executable basis via the 'paxctl' utility available at
28269 +         http://pax.grsecurity.net/.  The control flags will be read from
28270 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
28271 +         has the benefits of supporting both soft mode and being fully
28272 +         integrated into the toolchain (the binutils patch is available
28273 +         from http://pax.grsecurity.net).
28274 +
28275 +         If you have applications not marked by the PT_PAX_FLAGS ELF
28276 +         program header then you MUST enable the EI_PAX marking support
28277 +         otherwise they will not get any protection.
28278 +
28279 +         Note that if you enable the legacy EI_PAX marking support as well,
28280 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
28281 +
28282 +choice
28283 +       prompt 'MAC system integration'
28284 +       default PAX_NO_ACL_FLAGS
28285 +       help
28286 +         Mandatory Access Control systems have the option of controlling
28287 +         PaX flags on a per executable basis, choose the method supported
28288 +         by your particular system.
28289 +
28290 +         - "none": if your MAC system does not interact with PaX,
28291 +         - "direct": if your MAC system defines pax_set_flags() itself,
28292 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
28293 +
28294 +         NOTE: this option is for developers/integrators only.
28295 +
28296 +config PAX_NO_ACL_FLAGS
28297 +       bool 'none'
28298 +
28299 +config PAX_HAVE_ACL_FLAGS
28300 +       bool 'direct'
28301 +
28302 +config PAX_HOOK_ACL_FLAGS
28303 +       bool 'hook'
28304 +endchoice
28305 +
28306 +endmenu
28307 +
28308 +menu "Non-executable pages"
28309 +       depends on PAX
28310 +
28311 +config PAX_NOEXEC
28312 +       bool "Enforce non-executable pages"
28313 +       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)
28314 +       help
28315 +         By design some architectures do not allow for protecting memory
28316 +         pages against execution or even if they do, Linux does not make
28317 +         use of this feature.  In practice this means that if a page is
28318 +         readable (such as the stack or heap) it is also executable.
28319 +
28320 +         There is a well known exploit technique that makes use of this
28321 +         fact and a common programming mistake where an attacker can
28322 +         introduce code of his choice somewhere in the attacked program's
28323 +         memory (typically the stack or the heap) and then execute it.
28324 +
28325 +         If the attacked program was running with different (typically
28326 +         higher) privileges than that of the attacker, then he can elevate
28327 +         his own privilege level (e.g. get a root shell, write to files for
28328 +         which he does not have write access to, etc).
28329 +
28330 +         Enabling this option will let you choose from various features
28331 +         that prevent the injection and execution of 'foreign' code in
28332 +         a program.
28333 +
28334 +         This will also break programs that rely on the old behaviour and
28335 +         expect that dynamically allocated memory via the malloc() family
28336 +         of functions is executable (which it is not).  Notable examples
28337 +         are the XFree86 4.x server, the java runtime and wine.
28338 +
28339 +config PAX_PAGEEXEC
28340 +       bool "Paging based non-executable pages"
28341 +       depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
28342 +       help
28343 +         This implementation is based on the paging feature of the CPU.
28344 +         On i386 and ppc there is a variable but usually low performance
28345 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
28346 +         and x86_64 there is no performance impact.
28347 +
28348 +config PAX_SEGMEXEC
28349 +       bool "Segmentation based non-executable pages"
28350 +       depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
28351 +       help
28352 +         This implementation is based on the segmentation feature of the
28353 +         CPU and has little performance impact, however applications will
28354 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
28355 +
28356 +choice
28357 +       prompt "Default non-executable page method"
28358 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
28359 +       default PAX_DEFAULT_SEGMEXEC
28360 +       help
28361 +         Select the default non-executable page method applied to applications
28362 +         that do not select one themselves.
28363 +
28364 +config PAX_DEFAULT_PAGEEXEC
28365 +       bool "PAGEEXEC"
28366 +
28367 +config PAX_DEFAULT_SEGMEXEC
28368 +       bool "SEGMEXEC"
28369 +endchoice
28370 +
28371 +config PAX_EMUTRAMP
28372 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
28373 +       default y if PARISC || PPC32
28374 +       help
28375 +         There are some programs and libraries that for one reason or
28376 +         another attempt to execute special small code snippets from
28377 +         non-executable memory pages.  Most notable examples are the
28378 +         signal handler return code generated by the kernel itself and
28379 +         the GCC trampolines.
28380 +
28381 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
28382 +         such programs will no longer work under your kernel.
28383 +
28384 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
28385 +         utilities to enable trampoline emulation for the affected programs
28386 +         yet still have the protection provided by the non-executable pages.
28387 +
28388 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
28389 +         well, otherwise your system will not even boot.
28390 +
28391 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
28392 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
28393 +         for the affected files.
28394 +
28395 +         NOTE: enabling this feature *may* open up a loophole in the
28396 +         protection provided by non-executable pages that an attacker
28397 +         could abuse.  Therefore the best solution is to not have any
28398 +         files on your system that would require this option.  This can
28399 +         be achieved by not using libc5 (which relies on the kernel
28400 +         signal handler return code) and not using or rewriting programs
28401 +         that make use of the nested function implementation of GCC.
28402 +         Skilled users can just fix GCC itself so that it implements
28403 +         nested function calls in a way that does not interfere with PaX.
28404 +
28405 +config PAX_EMUSIGRT
28406 +       bool "Automatically emulate sigreturn trampolines"
28407 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
28408 +       default y
28409 +       help
28410 +         Enabling this option will have the kernel automatically detect
28411 +         and emulate signal return trampolines executing on the stack
28412 +         that would otherwise lead to task termination.
28413 +
28414 +         This solution is intended as a temporary one for users with
28415 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
28416 +         Modula-3 runtime, etc) or executables linked to such, basically
28417 +         everything that does not specify its own SA_RESTORER function in
28418 +         normal executable memory like glibc 2.1+ does.
28419 +
28420 +         On parisc and ppc you MUST enable this option, otherwise your
28421 +         system will not even boot.
28422 +
28423 +         NOTE: this feature cannot be disabled on a per executable basis
28424 +         and since it *does* open up a loophole in the protection provided
28425 +         by non-executable pages, the best solution is to not have any
28426 +         files on your system that would require this option.
28427 +
28428 +config PAX_MPROTECT
28429 +       bool "Restrict mprotect()"
28430 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
28431 +       help
28432 +         Enabling this option will prevent programs from
28433 +          - changing the executable status of memory pages that were
28434 +            not originally created as executable,
28435 +          - making read-only executable pages writable again,
28436 +          - creating executable pages from anonymous memory.
28437 +
28438 +         You should say Y here to complete the protection provided by
28439 +         the enforcement of non-executable pages.
28440 +
28441 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
28442 +         this feature on a per file basis.
28443 +
28444 +config PAX_NOELFRELOCS
28445 +       bool "Disallow ELF text relocations"
28446 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
28447 +       help
28448 +         Non-executable pages and mprotect() restrictions are effective
28449 +         in preventing the introduction of new executable code into an
28450 +         attacked task's address space.  There remain only two venues
28451 +         for this kind of attack: if the attacker can execute already
28452 +         existing code in the attacked task then he can either have it
28453 +         create and mmap() a file containing his code or have it mmap()
28454 +         an already existing ELF library that does not have position
28455 +         independent code in it and use mprotect() on it to make it
28456 +         writable and copy his code there.  While protecting against
28457 +         the former approach is beyond PaX, the latter can be prevented
28458 +         by having only PIC ELF libraries on one's system (which do not
28459 +         need to relocate their code).  If you are sure this is your case,
28460 +         then enable this option otherwise be careful as you may not even
28461 +         be able to boot or log on your system (for example, some PAM
28462 +         modules are erroneously compiled as non-PIC by default).
28463 +
28464 +         NOTE: if you are using dynamic ELF executables (as suggested
28465 +         when using ASLR) then you must have made sure that you linked
28466 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
28467 +         referenced there has already been updated to support this).
28468 +
28469 +config PAX_ETEXECRELOCS
28470 +       bool "Allow ELF ET_EXEC text relocations"
28471 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
28472 +       default y
28473 +       help
28474 +         On some architectures there are incorrectly created applications
28475 +         that require text relocations and would not work without enabling
28476 +         this option.  If you are an alpha, ia64 or parisc user, you should
28477 +         enable this option and disable it once you have made sure that
28478 +         none of your applications need it.
28479 +
28480 +config PAX_EMUPLT
28481 +       bool "Automatically emulate ELF PLT"
28482 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
28483 +       default y
28484 +       help
28485 +         Enabling this option will have the kernel automatically detect
28486 +         and emulate the Procedure Linkage Table entries in ELF files.
28487 +         On some architectures such entries are in writable memory, and
28488 +         become non-executable leading to task termination.  Therefore
28489 +         it is mandatory that you enable this option on alpha, parisc, ppc,
28490 +         sparc and sparc64, otherwise your system would not even boot.
28491 +
28492 +         NOTE: this feature *does* open up a loophole in the protection
28493 +         provided by the non-executable pages, therefore the proper
28494 +         solution is to modify the toolchain to produce a PLT that does
28495 +         not need to be writable.
28496 +
28497 +config PAX_DLRESOLVE
28498 +       bool
28499 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
28500 +       default y
28501 +
28502 +config PAX_SYSCALL
28503 +       bool
28504 +       depends on PAX_PAGEEXEC && PPC32
28505 +       default y
28506 +
28507 +config PAX_KERNEXEC
28508 +       bool "Enforce non-executable kernel pages"
28509 +       depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !DEBUG_RODATA && !COMPAT_VDSO
28510 +       help
28511 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
28512 +         that is, enabling this option will make it harder to inject
28513 +         and execute 'foreign' code in kernel memory itself.
28514 +
28515 +endmenu
28516 +
28517 +menu "Address Space Layout Randomization"
28518 +       depends on PAX
28519 +
28520 +config PAX_ASLR
28521 +       bool "Address Space Layout Randomization"
28522 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
28523 +       help
28524 +         Many if not most exploit techniques rely on the knowledge of
28525 +         certain addresses in the attacked program.  The following options
28526 +         will allow the kernel to apply a certain amount of randomization
28527 +         to specific parts of the program thereby forcing an attacker to
28528 +         guess them in most cases.  Any failed guess will most likely crash
28529 +         the attacked program which allows the kernel to detect such attempts
28530 +         and react on them.  PaX itself provides no reaction mechanisms,
28531 +         instead it is strongly encouraged that you make use of Nergal's
28532 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
28533 +         (http://www.grsecurity.net/) built-in crash detection features or
28534 +         develop one yourself.
28535 +
28536 +         By saying Y here you can choose to randomize the following areas:
28537 +          - top of the task's kernel stack
28538 +          - top of the task's userland stack
28539 +          - base address for mmap() requests that do not specify one
28540 +            (this includes all libraries)
28541 +          - base address of the main executable
28542 +
28543 +         It is strongly recommended to say Y here as address space layout
28544 +         randomization has negligible impact on performance yet it provides
28545 +         a very effective protection.
28546 +
28547 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
28548 +         this feature on a per file basis.
28549 +
28550 +config PAX_RANDKSTACK
28551 +       bool "Randomize kernel stack base"
28552 +       depends on PAX_ASLR && X86_TSC && X86_32
28553 +       help
28554 +         By saying Y here the kernel will randomize every task's kernel
28555 +         stack on every system call.  This will not only force an attacker
28556 +         to guess it but also prevent him from making use of possible
28557 +         leaked information about it.
28558 +
28559 +         Since the kernel stack is a rather scarce resource, randomization
28560 +         may cause unexpected stack overflows, therefore you should very
28561 +         carefully test your system.  Note that once enabled in the kernel
28562 +         configuration, this feature cannot be disabled on a per file basis.
28563 +
28564 +config PAX_RANDUSTACK
28565 +       bool "Randomize user stack base"
28566 +       depends on PAX_ASLR
28567 +       help
28568 +         By saying Y here the kernel will randomize every task's userland
28569 +         stack.  The randomization is done in two steps where the second
28570 +         one may apply a big amount of shift to the top of the stack and
28571 +         cause problems for programs that want to use lots of memory (more
28572 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
28573 +         For this reason the second step can be controlled by 'chpax' or
28574 +         'paxctl' on a per file basis.
28575 +
28576 +config PAX_RANDMMAP
28577 +       bool "Randomize mmap() base"
28578 +       depends on PAX_ASLR
28579 +       help
28580 +         By saying Y here the kernel will use a randomized base address for
28581 +         mmap() requests that do not specify one themselves.  As a result
28582 +         all dynamically loaded libraries will appear at random addresses
28583 +         and therefore be harder to exploit by a technique where an attacker
28584 +         attempts to execute library code for his purposes (e.g. spawn a
28585 +         shell from an exploited program that is running at an elevated
28586 +         privilege level).
28587 +
28588 +         Furthermore, if a program is relinked as a dynamic ELF file, its
28589 +         base address will be randomized as well, completing the full
28590 +         randomization of the address space layout.  Attacking such programs
28591 +         becomes a guess game.  You can find an example of doing this at
28592 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
28593 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
28594 +
28595 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
28596 +         feature on a per file basis.
28597 +
28598 +endmenu
28599 +
28600 +menu "Miscellaneous hardening features"
28601 +
28602 +config PAX_MEMORY_SANITIZE
28603 +       bool "Sanitize all freed memory"
28604 +       help
28605 +         By saying Y here the kernel will erase memory pages as soon as they
28606 +         are freed.  This in turn reduces the lifetime of data stored in the
28607 +         pages, making it less likely that sensitive information such as
28608 +         passwords, cryptographic secrets, etc stay in memory for too long.
28609 +
28610 +         This is especially useful for programs whose runtime is short, long
28611 +         lived processes and the kernel itself benefit from this as long as
28612 +         they operate on whole memory pages and ensure timely freeing of pages
28613 +         that may hold sensitive information.
28614 +
28615 +         The tradeoff is performance impact, on a single CPU system kernel
28616 +         compilation sees a 3% slowdown, other systems and workloads may vary
28617 +         and you are advised to test this feature on your expected workload
28618 +         before deploying it.
28619 +
28620 +         Note that this feature does not protect data stored in live pages,
28621 +         e.g., process memory swapped to disk may stay there for a long time.
28622 +
28623 +config PAX_MEMORY_UDEREF
28624 +       bool "Prevent invalid userland pointer dereference"
28625 +       depends on X86_32 && !COMPAT_VDSO
28626 +       help
28627 +         By saying Y here the kernel will be prevented from dereferencing
28628 +         userland pointers in contexts where the kernel expects only kernel
28629 +         pointers.  This is both a useful runtime debugging feature and a
28630 +         security measure that prevents exploiting a class of kernel bugs.
28631 +
28632 +         The tradeoff is that some virtualization solutions may experience
28633 +         a huge slowdown and therefore you should not enable this feature
28634 +         for kernels meant to run in such environments.  Whether a given VM
28635 +         solution is affected or not is best determined by simply trying it
28636 +         out, the performance impact will be obvious right on boot as this
28637 +         mechanism engages from very early on.  A good rule of thumb is that
28638 +         VMs running on CPUs without hardware virtualization support (i.e.,
28639 +         the majority of IA-32 CPUs) will likely experience the slowdown.
28640 +
28641 +endmenu
28642 +
28643 +endmenu
28644 +
28645 +source grsecurity/Kconfig
28646 +
28647  config KEYS
28648         bool "Enable access key retention support"
28649         help
28650 diff -urNp linux-2.6.18/sound/core/oss/pcm_oss.c linux-2.6.18/sound/core/oss/pcm_oss.c
28651 --- linux-2.6.18/sound/core/oss/pcm_oss.c       2006-09-19 23:42:06.000000000 -0400
28652 +++ linux-2.6.18/sound/core/oss/pcm_oss.c       2006-09-22 20:45:04.000000000 -0400
28653 @@ -2854,8 +2854,8 @@ static void snd_pcm_oss_proc_done(struct
28654         }
28655  }
28656  #else /* !CONFIG_SND_VERBOSE_PROCFS */
28657 -#define snd_pcm_oss_proc_init(pcm)
28658 -#define snd_pcm_oss_proc_done(pcm)
28659 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
28660 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
28661  #endif /* CONFIG_SND_VERBOSE_PROCFS */
28662  
28663  /*
This page took 2.233725 seconds and 3 git commands to generate.