]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.1.9-2.6.17.11.patch
- fix _alt_kernel logic, thnx glen
[packages/kernel.git] / grsecurity-2.1.9-2.6.17.11.patch
1 diff -urNp linux-2.6.17.11/arch/alpha/kernel/module.c linux-2.6.17.11/arch/alpha/kernel/module.c
2 --- linux-2.6.17.11/arch/alpha/kernel/module.c  2006-08-07 00:18:54.000000000 -0400
3 +++ linux-2.6.17.11/arch/alpha/kernel/module.c  2006-09-01 16:20:28.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.17.11/arch/alpha/kernel/osf_sys.c linux-2.6.17.11/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.17.11/arch/alpha/kernel/osf_sys.c 2006-08-07 00:18:54.000000000 -0400
15 +++ linux-2.6.17.11/arch/alpha/kernel/osf_sys.c 2006-09-01 16:20:28.000000000 -0400
16 @@ -1278,6 +1278,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 @@ -1285,8 +1289,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.17.11/arch/alpha/kernel/ptrace.c linux-2.6.17.11/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.17.11/arch/alpha/kernel/ptrace.c  2006-08-07 00:18:54.000000000 -0400
40 +++ linux-2.6.17.11/arch/alpha/kernel/ptrace.c  2006-09-01 16:20:28.000000000 -0400
41 @@ -16,6 +16,7 @@
42  #include <linux/security.h>
43  #include <linux/signal.h>
44  #include <linux/vs_pid.h>
45 +#include <linux/grsecurity.h>
46  
47  #include <asm/uaccess.h>
48  #include <asm/pgtable.h>
49 @@ -289,6 +290,9 @@ do_sys_ptrace(long request, long pid, lo
50                 goto out;
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.17.11/arch/alpha/mm/fault.c linux-2.6.17.11/arch/alpha/mm/fault.c
60 --- linux-2.6.17.11/arch/alpha/mm/fault.c       2006-08-07 00:18:54.000000000 -0400
61 +++ linux-2.6.17.11/arch/alpha/mm/fault.c       2006-09-01 16:20:28.000000000 -0400
62 @@ -25,6 +25,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 @@ -56,6 +57,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 @@ -133,8 +252,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.17.11/arch/arm/mm/mmap.c linux-2.6.17.11/arch/arm/mm/mmap.c
227 --- linux-2.6.17.11/arch/arm/mm/mmap.c  2006-08-07 00:18:54.000000000 -0400
228 +++ linux-2.6.17.11/arch/arm/mm/mmap.c  2006-09-01 16:20:28.000000000 -0400
229 @@ -62,6 +62,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 @@ -76,7 +80,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 @@ -93,8 +97,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.17.11/arch/i386/boot/compressed/head.S linux-2.6.17.11/arch/i386/boot/compressed/head.S
261 --- linux-2.6.17.11/arch/i386/boot/compressed/head.S    2006-08-07 00:18:54.000000000 -0400
262 +++ linux-2.6.17.11/arch/i386/boot/compressed/head.S    2006-09-01 16:20:28.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.17.11/arch/i386/Kconfig linux-2.6.17.11/arch/i386/Kconfig
278 --- linux-2.6.17.11/arch/i386/Kconfig   2006-08-07 00:18:54.000000000 -0400
279 +++ linux-2.6.17.11/arch/i386/Kconfig   2006-09-01 16:20:28.000000000 -0400
280 @@ -948,7 +948,7 @@ config PCI
281  choice
282         prompt "PCI access mode"
283         depends on PCI && !X86_VISWS
284 -       default PCI_GOANY
285 +       default PCI_GODIRECT
286         ---help---
287           On PCI systems, the BIOS can be used to detect the PCI devices and
288           determine their configuration. However, some old PCI motherboards
289 @@ -980,7 +980,7 @@ endchoice
290  
291  config PCI_BIOS
292         bool
293 -       depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
294 +       depends on !X86_VISWS && PCI && PCI_GOBIOS
295         default y
296  
297  config PCI_DIRECT
298 diff -urNp linux-2.6.17.11/arch/i386/Kconfig.cpu linux-2.6.17.11/arch/i386/Kconfig.cpu
299 --- linux-2.6.17.11/arch/i386/Kconfig.cpu       2006-08-07 00:18:54.000000000 -0400
300 +++ linux-2.6.17.11/arch/i386/Kconfig.cpu       2006-09-01 16:20:28.000000000 -0400
301 @@ -251,7 +251,7 @@ config X86_PPRO_FENCE
302  
303  config X86_F00F_BUG
304         bool
305 -       depends on M586MMX || M586TSC || M586 || M486 || M386
306 +       depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
307         default y
308  
309  config X86_WP_WORKS_OK
310 @@ -281,7 +281,7 @@ config X86_CMPXCHG64
311  
312  config X86_ALIGNMENT_16
313         bool
314 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
315 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
316         default y
317  
318  config X86_GOOD_APIC
319 diff -urNp linux-2.6.17.11/arch/i386/Kconfig.debug linux-2.6.17.11/arch/i386/Kconfig.debug
320 --- linux-2.6.17.11/arch/i386/Kconfig.debug     2006-08-07 00:18:54.000000000 -0400
321 +++ linux-2.6.17.11/arch/i386/Kconfig.debug     2006-09-01 16:20:28.000000000 -0400
322 @@ -53,7 +53,7 @@ config DEBUG_PAGEALLOC
323  
324  config DEBUG_RODATA
325         bool "Write protect kernel read-only data structures"
326 -       depends on DEBUG_KERNEL
327 +       depends on DEBUG_KERNEL && 0
328         help
329           Mark the kernel read-only data as write-protected in the pagetables,
330           in order to catch accidental (and incorrect) writes to such const
331 diff -urNp linux-2.6.17.11/arch/i386/kernel/acpi/sleep.c linux-2.6.17.11/arch/i386/kernel/acpi/sleep.c
332 --- linux-2.6.17.11/arch/i386/kernel/acpi/sleep.c       2006-08-07 00:18:54.000000000 -0400
333 +++ linux-2.6.17.11/arch/i386/kernel/acpi/sleep.c       2006-09-01 16:20:28.000000000 -0400
334 @@ -10,6 +10,7 @@
335  #include <linux/dmi.h>
336  #include <asm/smp.h>
337  #include <asm/tlbflush.h>
338 +#include <asm/desc.h>
339  
340  /* address in low memory of the wakeup routine. */
341  unsigned long acpi_wakeup_address = 0;
342 @@ -24,11 +25,22 @@ static void init_low_mapping(pgd_t * pgd
343  {
344         int pgd_ofs = 0;
345  
346 +#ifdef CONFIG_PAX_KERNEXEC
347 +       unsigned long cr0;
348 +
349 +       pax_open_kernel(cr0);
350 +#endif
351 +
352         while ((pgd_ofs < pgd_limit)
353                && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
354                 set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD));
355                 pgd_ofs++, pgd++;
356         }
357 +
358 +#ifdef CONFIG_PAX_KERNEXEC
359 +       pax_close_kernel(cr0);
360 +#endif
361 +
362         flush_tlb_all();
363  }
364  
365 @@ -55,7 +67,18 @@ int acpi_save_state_mem(void)
366   */
367  void acpi_restore_state_mem(void)
368  {
369 +#ifdef CONFIG_PAX_KERNEXEC
370 +       unsigned long cr0;
371 +
372 +       pax_open_kernel(cr0);
373 +#endif
374 +
375         zap_low_mappings();
376 +
377 +#ifdef CONFIG_PAX_KERNEXEC
378 +       pax_close_kernel(cr0);
379 +#endif
380 +
381  }
382  
383  /**
384 diff -urNp linux-2.6.17.11/arch/i386/kernel/alternative.c linux-2.6.17.11/arch/i386/kernel/alternative.c
385 --- linux-2.6.17.11/arch/i386/kernel/alternative.c      2006-08-07 00:18:54.000000000 -0400
386 +++ linux-2.6.17.11/arch/i386/kernel/alternative.c      2006-09-01 16:20:28.000000000 -0400
387 @@ -3,6 +3,7 @@
388  #include <linux/list.h>
389  #include <asm/alternative.h>
390  #include <asm/sections.h>
391 +#include <asm/desc.h>
392  
393  #define DEBUG 0
394  #if DEBUG
395 @@ -101,71 +102,128 @@ void apply_alternatives(struct alt_instr
396         struct alt_instr *a;
397         int diff, i, k;
398  
399 +#ifdef CONFIG_PAX_KERNEXEC
400 +       unsigned long cr0;
401 +
402 +       pax_open_kernel(cr0);
403 +#endif
404 +
405         DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
406         for (a = start; a < end; a++) {
407                 BUG_ON(a->replacementlen > a->instrlen);
408                 if (!boot_cpu_has(a->cpuid))
409                         continue;
410 -               memcpy(a->instr, a->replacement, a->replacementlen);
411 +               memcpy(a->instr + __KERNEL_TEXT_OFFSET, a->replacement, a->replacementlen);
412                 diff = a->instrlen - a->replacementlen;
413                 /* Pad the rest with nops */
414                 for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
415                         k = diff;
416                         if (k > ASM_NOP_MAX)
417                                 k = ASM_NOP_MAX;
418 -                       memcpy(a->instr + i, noptable[k], k);
419 +                       memcpy(a->instr + i + __KERNEL_TEXT_OFFSET, noptable[k], k);
420                 }
421         }
422 +
423 +#ifdef CONFIG_PAX_KERNEXEC
424 +       pax_close_kernel(cr0);
425 +#endif
426 +
427  }
428  
429  static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end)
430  {
431         struct alt_instr *a;
432  
433 +#ifdef CONFIG_PAX_KERNEXEC
434 +       unsigned long cr0;
435 +
436 +       pax_open_kernel(cr0);
437 +#endif
438 +
439         DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
440         for (a = start; a < end; a++) {
441                 memcpy(a->replacement + a->replacementlen,
442 -                      a->instr,
443 +                      a->instr + __KERNEL_TEXT_OFFSET,
444                        a->instrlen);
445         }
446 +
447 +#ifdef CONFIG_PAX_KERNEXEC
448 +       pax_close_kernel(cr0);
449 +#endif
450 +
451  }
452  
453  static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
454  {
455         struct alt_instr *a;
456  
457 +#ifdef CONFIG_PAX_KERNEXEC
458 +       unsigned long cr0;
459 +
460 +       pax_open_kernel(cr0);
461 +#endif
462 +
463         for (a = start; a < end; a++) {
464 -               memcpy(a->instr,
465 +               memcpy(a->instr + __KERNEL_TEXT_OFFSET,
466                        a->replacement + a->replacementlen,
467                        a->instrlen);
468         }
469 +
470 +#ifdef CONFIG_PAX_KERNEXEC
471 +       pax_close_kernel(cr0);
472 +#endif
473 +
474  }
475  
476  static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
477  {
478 -       u8 **ptr;
479 +       u8 *ptr;
480 +
481 +#ifdef CONFIG_PAX_KERNEXEC
482 +       unsigned long cr0;
483  
484 -       for (ptr = start; ptr < end; ptr++) {
485 -               if (*ptr < text)
486 +       pax_open_kernel(cr0);
487 +#endif
488 +
489 +       for (; start < end; start++) {
490 +               ptr = *start + __KERNEL_TEXT_OFFSET;
491 +               if (ptr < text)
492                         continue;
493 -               if (*ptr > text_end)
494 +               if (ptr > text_end)
495                         continue;
496 -               **ptr = 0xf0; /* lock prefix */
497 +               *ptr = 0xf0; /* lock prefix */
498         };
499 +
500 +#ifdef CONFIG_PAX_KERNEXEC
501 +       pax_close_kernel(cr0);
502 +#endif
503 +
504  }
505  
506  static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
507  {
508         unsigned char **noptable = find_nop_table();
509 -       u8 **ptr;
510 +       u8 *ptr;
511 +
512 +#ifdef CONFIG_PAX_KERNEXEC
513 +       unsigned long cr0;
514 +
515 +       pax_open_kernel(cr0);
516 +#endif
517  
518 -       for (ptr = start; ptr < end; ptr++) {
519 -               if (*ptr < text)
520 +       for (; start < end; start++) {
521 +               ptr = *start + __KERNEL_TEXT_OFFSET;
522 +               if (ptr < text)
523                         continue;
524 -               if (*ptr > text_end)
525 +               if (ptr > text_end)
526                         continue;
527 -               **ptr = noptable[1][0];
528 +               *ptr = noptable[1][0];
529         };
530 +
531 +#ifdef CONFIG_PAX_KERNEXEC
532 +       pax_close_kernel(cr0);
533 +#endif
534 +
535  }
536  
537  struct smp_alt_module {
538 diff -urNp linux-2.6.17.11/arch/i386/kernel/apic.c linux-2.6.17.11/arch/i386/kernel/apic.c
539 --- linux-2.6.17.11/arch/i386/kernel/apic.c     2006-08-07 00:18:54.000000000 -0400
540 +++ linux-2.6.17.11/arch/i386/kernel/apic.c     2006-09-01 16:20:28.000000000 -0400
541 @@ -1176,7 +1176,7 @@ inline void smp_local_timer_interrupt(st
542  {
543         profile_tick(CPU_PROFILING, regs);
544  #ifdef CONFIG_SMP
545 -       update_process_times(user_mode_vm(regs));
546 +       update_process_times(user_mode(regs));
547  #endif
548  
549         /*
550 diff -urNp linux-2.6.17.11/arch/i386/kernel/apm.c linux-2.6.17.11/arch/i386/kernel/apm.c
551 --- linux-2.6.17.11/arch/i386/kernel/apm.c      2006-08-07 00:18:54.000000000 -0400
552 +++ linux-2.6.17.11/arch/i386/kernel/apm.c      2006-09-01 16:20:28.000000000 -0400
553 @@ -235,7 +235,7 @@
554  #include "io_ports.h"
555  
556  extern unsigned long get_cmos_time(void);
557 -extern void machine_real_restart(unsigned char *, int);
558 +extern void machine_real_restart(const unsigned char *, unsigned int);
559  
560  #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
561  extern int (*console_blank_hook)(int);
562 @@ -589,9 +589,18 @@ static u8 apm_bios_call(u32 func, u32 eb
563         struct desc_struct      save_desc_40;
564         struct desc_struct      *gdt;
565  
566 +#ifdef CONFIG_PAX_KERNEXEC
567 +       unsigned long           cr0;
568 +#endif
569 +
570         cpus = apm_save_cpus();
571         
572         cpu = get_cpu();
573 +
574 +#ifdef CONFIG_PAX_KERNEXEC
575 +       pax_open_kernel(cr0);
576 +#endif
577 +
578         gdt = get_cpu_gdt_table(cpu);
579         save_desc_40 = gdt[0x40 / 8];
580         gdt[0x40 / 8] = bad_bios_desc;
581 @@ -603,6 +612,11 @@ static u8 apm_bios_call(u32 func, u32 eb
582         APM_DO_RESTORE_SEGS;
583         local_irq_restore(flags);
584         gdt[0x40 / 8] = save_desc_40;
585 +
586 +#ifdef CONFIG_PAX_KERNEXEC
587 +       pax_close_kernel(cr0);
588 +#endif
589 +
590         put_cpu();
591         apm_restore_cpus(cpus);
592         
593 @@ -633,9 +647,18 @@ static u8 apm_bios_call_simple(u32 func,
594         struct desc_struct      save_desc_40;
595         struct desc_struct      *gdt;
596  
597 +#ifdef CONFIG_PAX_KERNEXEC
598 +       unsigned long           cr0;
599 +#endif
600 +
601         cpus = apm_save_cpus();
602         
603         cpu = get_cpu();
604 +
605 +#ifdef CONFIG_PAX_KERNEXEC
606 +       pax_open_kernel(cr0);
607 +#endif
608 +
609         gdt = get_cpu_gdt_table(cpu);
610         save_desc_40 = gdt[0x40 / 8];
611         gdt[0x40 / 8] = bad_bios_desc;
612 @@ -647,6 +670,11 @@ static u8 apm_bios_call_simple(u32 func,
613         APM_DO_RESTORE_SEGS;
614         local_irq_restore(flags);
615         gdt[0x40 / 8] = save_desc_40;
616 +
617 +#ifdef CONFIG_PAX_KERNEXEC
618 +       pax_close_kernel(cr0);
619 +#endif
620 +
621         put_cpu();
622         apm_restore_cpus(cpus);
623         return error;
624 @@ -910,7 +938,7 @@ recalc:
625   
626  static void apm_power_off(void)
627  {
628 -       unsigned char   po_bios_call[] = {
629 +       const unsigned char     po_bios_call[] = {
630                 0xb8, 0x00, 0x10,       /* movw  $0x1000,ax  */
631                 0x8e, 0xd0,             /* movw  ax,ss       */
632                 0xbc, 0x00, 0xf0,       /* movw  $0xf000,sp  */
633 diff -urNp linux-2.6.17.11/arch/i386/kernel/asm-offsets.c linux-2.6.17.11/arch/i386/kernel/asm-offsets.c
634 --- linux-2.6.17.11/arch/i386/kernel/asm-offsets.c      2006-08-07 00:18:54.000000000 -0400
635 +++ linux-2.6.17.11/arch/i386/kernel/asm-offsets.c      2006-09-01 16:20:28.000000000 -0400
636 @@ -68,5 +68,6 @@ void foo(void)
637                  sizeof(struct tss_struct));
638  
639         DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
640 +       DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
641         DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
642  }
643 diff -urNp linux-2.6.17.11/arch/i386/kernel/cpu/common.c linux-2.6.17.11/arch/i386/kernel/cpu/common.c
644 --- linux-2.6.17.11/arch/i386/kernel/cpu/common.c       2006-08-07 00:18:54.000000000 -0400
645 +++ linux-2.6.17.11/arch/i386/kernel/cpu/common.c       2006-09-01 16:20:28.000000000 -0400
646 @@ -4,7 +4,6 @@
647  #include <linux/smp.h>
648  #include <linux/module.h>
649  #include <linux/percpu.h>
650 -#include <linux/bootmem.h>
651  #include <asm/semaphore.h>
652  #include <asm/processor.h>
653  #include <asm/i387.h>
654 @@ -19,16 +18,18 @@
655  
656  #include "cpu.h"
657  
658 -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
659 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
660 -
661  DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
662  EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
663  
664  static int cachesize_override __cpuinitdata = -1;
665  static int disable_x86_fxsr __cpuinitdata;
666  static int disable_x86_serial_nr __cpuinitdata = 1;
667 +
668 +#ifdef CONFIG_PAX_NOVSYSCALL
669 +static int disable_x86_sep __cpuinitdata = 1;
670 +#else
671  static int disable_x86_sep __cpuinitdata;
672 +#endif
673  
674  struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
675  
676 @@ -590,11 +591,10 @@ void __init early_cpu_init(void)
677  void __cpuinit cpu_init(void)
678  {
679         int cpu = smp_processor_id();
680 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
681 +       struct tss_struct * t = init_tss + cpu;
682         struct thread_struct *thread = &current->thread;
683 -       struct desc_struct *gdt;
684 +       struct desc_struct *gdt = get_cpu_gdt_table(cpu);
685         __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
686 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
687  
688         if (cpu_test_and_set(cpu, cpu_initialized)) {
689                 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
690 @@ -612,29 +612,11 @@ void __cpuinit cpu_init(void)
691         }
692  
693         /*
694 -        * This is a horrible hack to allocate the GDT.  The problem
695 -        * is that cpu_init() is called really early for the boot CPU
696 -        * (and hence needs bootmem) but much later for the secondary
697 -        * CPUs, when bootmem will have gone away
698 -        */
699 -       if (NODE_DATA(0)->bdata->node_bootmem_map) {
700 -               gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
701 -               /* alloc_bootmem_pages panics on failure, so no check */
702 -               memset(gdt, 0, PAGE_SIZE);
703 -       } else {
704 -               gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
705 -               if (unlikely(!gdt)) {
706 -                       printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
707 -                       for (;;)
708 -                               local_irq_enable();
709 -               }
710 -       }
711 -
712 -       /*
713          * Initialize the per-CPU GDT with the boot GDT,
714          * and set up the GDT descriptor:
715          */
716 -       memcpy(gdt, cpu_gdt_table, GDT_SIZE);
717 +       if (cpu)
718 +               memcpy(gdt, cpu_gdt_table, GDT_SIZE);
719  
720         /* Set up GDT entry for 16bit stack */
721         *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
722 @@ -642,10 +624,10 @@ void __cpuinit cpu_init(void)
723                 ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
724                 (CPU_16BIT_STACK_SIZE - 1);
725  
726 -       cpu_gdt_descr->size = GDT_SIZE - 1;
727 -       cpu_gdt_descr->address = (unsigned long)gdt;
728 +       cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
729 +       cpu_gdt_descr[cpu].address = (unsigned long)gdt;
730  
731 -       load_gdt(cpu_gdt_descr);
732 +       load_gdt(&cpu_gdt_descr[cpu]);
733         load_idt(&idt_descr);
734  
735         /*
736 @@ -660,7 +642,7 @@ void __cpuinit cpu_init(void)
737         load_esp0(t, thread);
738         set_tss_desc(cpu,t);
739         load_TR_desc();
740 -       load_LDT(&init_mm.context);
741 +       _load_LDT(&init_mm.context);
742  
743  #ifdef CONFIG_DOUBLEFAULT
744         /* Set up doublefault TSS pointer in the GDT */
745 @@ -668,7 +650,7 @@ void __cpuinit cpu_init(void)
746  #endif
747  
748         /* Clear %fs and %gs. */
749 -       asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
750 +       asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r"(0));
751  
752         /* Clear all 6 debug registers: */
753         set_debugreg(0, 0);
754 diff -urNp linux-2.6.17.11/arch/i386/kernel/crash.c linux-2.6.17.11/arch/i386/kernel/crash.c
755 --- linux-2.6.17.11/arch/i386/kernel/crash.c    2006-08-07 00:18:54.000000000 -0400
756 +++ linux-2.6.17.11/arch/i386/kernel/crash.c    2006-09-01 16:20:28.000000000 -0400
757 @@ -105,7 +105,7 @@ static int crash_nmi_callback(struct pt_
758                 return 1;
759         local_irq_disable();
760  
761 -       if (!user_mode_vm(regs)) {
762 +       if (!user_mode(regs)) {
763                 crash_fixup_ss_esp(&fixed_regs, regs);
764                 regs = &fixed_regs;
765         }
766 diff -urNp linux-2.6.17.11/arch/i386/kernel/doublefault.c linux-2.6.17.11/arch/i386/kernel/doublefault.c
767 --- linux-2.6.17.11/arch/i386/kernel/doublefault.c      2006-08-07 00:18:54.000000000 -0400
768 +++ linux-2.6.17.11/arch/i386/kernel/doublefault.c      2006-09-01 16:20:28.000000000 -0400
769 @@ -11,7 +11,7 @@
770  
771  #define DOUBLEFAULT_STACKSIZE (1024)
772  static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
773 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
774 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
775  
776  #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
777  
778 @@ -56,10 +56,10 @@ struct tss_struct doublefault_tss __cach
779         .eip            = (unsigned long) doublefault_fn,
780         .eflags         = X86_EFLAGS_SF | 0x2,  /* 0x2 bit is always set */
781         .esp            = STACK_START,
782 -       .es             = __USER_DS,
783 +       .es             = __KERNEL_DS,
784         .cs             = __KERNEL_CS,
785         .ss             = __KERNEL_DS,
786 -       .ds             = __USER_DS,
787 +       .ds             = __KERNEL_DS,
788  
789         .__cr3          = __pa(swapper_pg_dir)
790  };
791 diff -urNp linux-2.6.17.11/arch/i386/kernel/efi.c linux-2.6.17.11/arch/i386/kernel/efi.c
792 --- linux-2.6.17.11/arch/i386/kernel/efi.c      2006-08-07 00:18:54.000000000 -0400
793 +++ linux-2.6.17.11/arch/i386/kernel/efi.c      2006-09-01 16:20:28.000000000 -0400
794 @@ -64,82 +64,43 @@ extern void * boot_ioremap(unsigned long
795  
796  static unsigned long efi_rt_eflags;
797  static DEFINE_SPINLOCK(efi_rt_lock);
798 -static pgd_t efi_bak_pg_dir_pointer[2];
799 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
800  
801 -static void efi_call_phys_prelog(void)
802 +static void __init efi_call_phys_prelog(void)
803  {
804 -       unsigned long cr4;
805 -       unsigned long temp;
806 -       struct Xgt_desc_struct *cpu_gdt_descr;
807 -
808         spin_lock(&efi_rt_lock);
809         local_irq_save(efi_rt_eflags);
810  
811 -       cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
812 -
813 -       /*
814 -        * If I don't have PSE, I should just duplicate two entries in page
815 -        * directory. If I have PSE, I just need to duplicate one entry in
816 -        * page directory.
817 -        */
818 -       cr4 = read_cr4();
819 -
820 -       if (cr4 & X86_CR4_PSE) {
821 -               efi_bak_pg_dir_pointer[0].pgd =
822 -                   swapper_pg_dir[pgd_index(0)].pgd;
823 -               swapper_pg_dir[0].pgd =
824 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
825 -       } else {
826 -               efi_bak_pg_dir_pointer[0].pgd =
827 -                   swapper_pg_dir[pgd_index(0)].pgd;
828 -               efi_bak_pg_dir_pointer[1].pgd =
829 -                   swapper_pg_dir[pgd_index(0x400000)].pgd;
830 -               swapper_pg_dir[pgd_index(0)].pgd =
831 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
832 -               temp = PAGE_OFFSET + 0x400000;
833 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
834 -                   swapper_pg_dir[pgd_index(temp)].pgd;
835 -       }
836 +       clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
837 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
838 +                       USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
839  
840         /*
841          * After the lock is released, the original page table is restored.
842          */
843 -       local_flush_tlb();
844 +       __flush_tlb_all();
845  
846 -       cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
847 -       load_gdt(cpu_gdt_descr);
848 +       cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
849 +       load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
850  }
851  
852 -static void efi_call_phys_epilog(void)
853 +static void __init efi_call_phys_epilog(void)
854  {
855 -       unsigned long cr4;
856 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
857 -
858 -       cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address);
859 -       load_gdt(cpu_gdt_descr);
860 +       cpu_gdt_descr[0].address = (unsigned long) __va(cpu_gdt_descr[0].address);
861 +       load_gdt(&cpu_gdt_descr[0]);
862  
863 -       cr4 = read_cr4();
864 -
865 -       if (cr4 & X86_CR4_PSE) {
866 -               swapper_pg_dir[pgd_index(0)].pgd =
867 -                   efi_bak_pg_dir_pointer[0].pgd;
868 -       } else {
869 -               swapper_pg_dir[pgd_index(0)].pgd =
870 -                   efi_bak_pg_dir_pointer[0].pgd;
871 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
872 -                   efi_bak_pg_dir_pointer[1].pgd;
873 -       }
874 +       clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
875  
876         /*
877          * After the lock is released, the original page table is restored.
878          */
879 -       local_flush_tlb();
880 +       __flush_tlb_all();
881  
882         local_irq_restore(efi_rt_eflags);
883         spin_unlock(&efi_rt_lock);
884  }
885  
886 -static efi_status_t
887 +static efi_status_t __init
888  phys_efi_set_virtual_address_map(unsigned long memory_map_size,
889                                  unsigned long descriptor_size,
890                                  u32 descriptor_version,
891 @@ -155,7 +116,7 @@ phys_efi_set_virtual_address_map(unsigne
892         return status;
893  }
894  
895 -static efi_status_t
896 +static efi_status_t __init
897  phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
898  {
899         efi_status_t status;
900 diff -urNp linux-2.6.17.11/arch/i386/kernel/efi_stub.S linux-2.6.17.11/arch/i386/kernel/efi_stub.S
901 --- linux-2.6.17.11/arch/i386/kernel/efi_stub.S 2006-08-07 00:18:54.000000000 -0400
902 +++ linux-2.6.17.11/arch/i386/kernel/efi_stub.S 2006-09-01 16:20:28.000000000 -0400
903 @@ -7,6 +7,7 @@
904  
905  #include <linux/config.h>
906  #include <linux/linkage.h>
907 +#include <linux/init.h>
908  #include <asm/page.h>
909  #include <asm/pgtable.h>
910  
911 @@ -22,7 +23,7 @@
912   * service functions will comply with gcc calling convention, too.
913   */
914  
915 -.text
916 +__INIT
917  ENTRY(efi_call_phys)
918         /*
919          * 0. The function can only be called in Linux kernel. So CS has been
920 @@ -38,9 +39,7 @@ ENTRY(efi_call_phys)
921          * The mapping of lower virtual memory has been created in prelog and
922          * epilog.
923          */
924 -       movl    $1f, %edx
925 -       subl    $__PAGE_OFFSET, %edx
926 -       jmp     *%edx
927 +       jmp     1f-__PAGE_OFFSET
928  1:
929  
930         /*
931 @@ -49,14 +48,8 @@ ENTRY(efi_call_phys)
932          * parameter 2, ..., param n. To make things easy, we save the return
933          * address of efi_call_phys in a global variable.
934          */
935 -       popl    %edx
936 -       movl    %edx, saved_return_addr
937 -       /* get the function pointer into ECX*/
938 -       popl    %ecx
939 -       movl    %ecx, efi_rt_function_ptr
940 -       movl    $2f, %edx
941 -       subl    $__PAGE_OFFSET, %edx
942 -       pushl   %edx
943 +       popl    (saved_return_addr)
944 +       popl    (efi_rt_function_ptr)
945  
946         /*
947          * 3. Clear PG bit in %CR0.
948 @@ -75,9 +68,8 @@ ENTRY(efi_call_phys)
949         /*
950          * 5. Call the physical function.
951          */
952 -       jmp     *%ecx
953 +       call    *(efi_rt_function_ptr-__PAGE_OFFSET)
954  
955 -2:
956         /*
957          * 6. After EFI runtime service returns, control will return to
958          * following instruction. We'd better readjust stack pointer first.
959 @@ -87,37 +79,29 @@ ENTRY(efi_call_phys)
960         /*
961          * 7. Restore PG bit
962          */
963 -       movl    %cr0, %edx
964 -       orl     $0x80000000, %edx
965 -       movl    %edx, %cr0
966 -       jmp     1f
967 -1:
968         /*
969          * 8. Now restore the virtual mode from flat mode by
970          * adding EIP with PAGE_OFFSET.
971          */
972 -       movl    $1f, %edx
973 -       jmp     *%edx
974 +       movl    %cr0, %edx
975 +       orl     $0x80000000, %edx
976 +       movl    %edx, %cr0
977 +       jmp     1f+__PAGE_OFFSET
978  1:
979  
980         /*
981          * 9. Balance the stack. And because EAX contain the return value,
982          * we'd better not clobber it.
983          */
984 -       leal    efi_rt_function_ptr, %edx
985 -       movl    (%edx), %ecx
986 -       pushl   %ecx
987 +       pushl   (efi_rt_function_ptr)
988  
989         /*
990 -        * 10. Push the saved return address onto the stack and return.
991 +        * 10. Return to the saved return address.
992          */
993 -       leal    saved_return_addr, %edx
994 -       movl    (%edx), %ecx
995 -       pushl   %ecx
996 -       ret
997 +       jmpl    *(saved_return_addr)
998  .previous
999  
1000 -.data
1001 +__INITDATA
1002  saved_return_addr:
1003         .long 0
1004  efi_rt_function_ptr:
1005 diff -urNp linux-2.6.17.11/arch/i386/kernel/entry.S linux-2.6.17.11/arch/i386/kernel/entry.S
1006 --- linux-2.6.17.11/arch/i386/kernel/entry.S    2006-08-07 00:18:54.000000000 -0400
1007 +++ linux-2.6.17.11/arch/i386/kernel/entry.S    2006-09-01 16:20:28.000000000 -0400
1008 @@ -82,7 +82,7 @@ VM_MASK               = 0x00020000
1009  #define resume_kernel          restore_nocheck
1010  #endif
1011  
1012 -#define SAVE_ALL \
1013 +#define __SAVE_ALL(_DS) \
1014         cld; \
1015         pushl %es; \
1016         pushl %ds; \
1017 @@ -93,10 +93,24 @@ VM_MASK             = 0x00020000
1018         pushl %edx; \
1019         pushl %ecx; \
1020         pushl %ebx; \
1021 -       movl $(__USER_DS), %edx; \
1022 +       movl $(_DS), %edx; \
1023         movl %edx, %ds; \
1024         movl %edx, %es;
1025  
1026 +#ifdef CONFIG_PAX_KERNEXEC
1027 +#define SAVE_ALL \
1028 +       __SAVE_ALL(__KERNEL_DS) \
1029 +       movl %cr0, %edx; \
1030 +       movl %edx, %esi; \
1031 +       orl $0x10000, %edx; \
1032 +       xorl %edx, %esi; \
1033 +       movl %edx, %cr0;
1034 +#elif defined(CONFIG_PAX_NOVSYSCALL)
1035 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1036 +#else
1037 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
1038 +#endif
1039 +
1040  #define RESTORE_INT_REGS \
1041         popl %ebx;      \
1042         popl %ecx;      \
1043 @@ -146,7 +160,19 @@ ret_from_intr:
1044         movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
1045         movb CS(%esp), %al
1046         testl $(VM_MASK | 3), %eax
1047 +
1048 +#ifdef CONFIG_PAX_KERNEXEC
1049 +       jnz resume_userspace
1050 +
1051 +       movl %cr0, %edx
1052 +       xorl %esi, %edx
1053 +       movl %edx, %cr0
1054 +       jmp resume_kernel
1055 +#else
1056         jz resume_kernel
1057 +#endif
1058 +
1059 +
1060  ENTRY(resume_userspace)
1061         cli                             # make sure we don't miss an interrupt
1062                                         # setting need_resched or sigpending
1063 @@ -190,9 +216,17 @@ sysenter_past_esp:
1064   * Load the potential sixth argument from user stack.
1065   * Careful about security.
1066   */
1067 +
1068 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1069 +       pushl $(__USER_DS)
1070 +       pop %ds
1071 +1:     movl %ds:(%ebp),%ebp
1072 +#else
1073         cmpl $__PAGE_OFFSET-3,%ebp
1074         jae syscall_fault
1075  1:     movl (%ebp),%ebp
1076 +#endif
1077 +
1078  .section __ex_table,"a"
1079         .align 4
1080         .long 1b,syscall_fault
1081 @@ -213,13 +247,33 @@ sysenter_past_esp:
1082         movl TI_flags(%ebp), %ecx
1083         testw $_TIF_ALLWORK_MASK, %cx
1084         jne syscall_exit_work
1085 +
1086 +#ifdef CONFIG_PAX_RANDKSTACK
1087 +       pushl %eax
1088 +       call pax_randomize_kstack
1089 +       popl %eax
1090 +#endif
1091 +
1092  /* if something modifies registers it must also disable sysexit */
1093         movl EIP(%esp), %edx
1094         movl OLDESP(%esp), %ecx
1095 +1:     mov DS(%esp), %ds
1096 +2:     mov ES(%esp), %es
1097         xorl %ebp,%ebp
1098         sti
1099         sysexit
1100  
1101 +.section .fixup,"ax"
1102 +3:     movl $0,DS(%esp)
1103 +       jmp 1b
1104 +4:     movl $0,ES(%esp)
1105 +       jmp 2b
1106 +.previous
1107 +.section __ex_table,"a"
1108 +       .align 4
1109 +       .long 1b,3b
1110 +       .long 2b,4b
1111 +.previous
1112  
1113         # system call handler stub
1114  ENTRY(system_call)
1115 @@ -247,6 +301,10 @@ syscall_exit:
1116         testw $_TIF_ALLWORK_MASK, %cx   # current->work
1117         jne syscall_exit_work
1118  
1119 +#ifdef CONFIG_PAX_RANDKSTACK
1120 +       call pax_randomize_kstack
1121 +#endif
1122 +
1123  restore_all:
1124         movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
1125         # Warning: OLDSS(%esp) contains the wrong/random values if we
1126 @@ -402,7 +460,7 @@ syscall_badsys:
1127   * Build the entry stubs and pointer table with
1128   * some assembler magic.
1129   */
1130 -.data
1131 +.section .rodata,"a",@progbits
1132  ENTRY(interrupt)
1133  .text
1134  
1135 @@ -412,7 +470,7 @@ ENTRY(irq_entries_start)
1136         ALIGN
1137  1:     pushl $vector-256
1138         jmp common_interrupt
1139 -.data
1140 +.section .rodata,"a",@progbits
1141         .long 1b
1142  .text
1143  vector=vector+1
1144 @@ -459,10 +517,19 @@ error_code:
1145         movl ORIG_EAX(%esp), %edx       # get the error code
1146         movl %eax, ORIG_EAX(%esp)
1147         movl %ecx, ES(%esp)
1148 -       movl $(__USER_DS), %ecx
1149 +       movl $(__KERNEL_DS), %ecx
1150         movl %ecx, %ds
1151         movl %ecx, %es
1152         movl %esp,%eax                  # pt_regs pointer
1153 +
1154 +#ifdef CONFIG_PAX_KERNEXEC
1155 +       movl %cr0, %ecx
1156 +       movl %ecx, %esi
1157 +       orl $0x10000, %ecx
1158 +       xorl %ecx, %esi
1159 +       movl %ecx, %cr0
1160 +#endif
1161 +
1162         call *%edi
1163         jmp ret_from_exception
1164  
1165 @@ -558,6 +625,13 @@ nmi_stack_correct:
1166         xorl %edx,%edx          # zero error code
1167         movl %esp,%eax          # pt_regs pointer
1168         call do_nmi
1169 +
1170 +#ifdef CONFIG_PAX_KERNEXEC
1171 +       movl %cr0, %edx
1172 +       xorl %esi, %edx
1173 +       movl %edx, %cr0
1174 +#endif
1175 +
1176         jmp restore_all
1177  
1178  nmi_stack_fixup:
1179 @@ -588,6 +662,13 @@ nmi_16bit_stack:
1180         FIXUP_ESPFIX_STACK              # %eax == %esp
1181         xorl %edx,%edx                  # zero error code
1182         call do_nmi
1183 +
1184 +#ifdef CONFIG_PAX_KERNEXEC
1185 +       movl %cr0, %edx
1186 +       xorl %esi, %edx
1187 +       movl %edx, %cr0
1188 +#endif
1189 +
1190         RESTORE_REGS
1191         lss 12+4(%esp), %esp            # back to 16bit stack
1192  1:     iret
1193 @@ -663,7 +744,6 @@ ENTRY(spurious_interrupt_bug)
1194         pushl $do_spurious_interrupt_bug
1195         jmp error_code
1196  
1197 -.section .rodata,"a"
1198  #include "syscall_table.S"
1199  
1200  syscall_table_size=(.-sys_call_table)
1201 diff -urNp linux-2.6.17.11/arch/i386/kernel/head.S linux-2.6.17.11/arch/i386/kernel/head.S
1202 --- linux-2.6.17.11/arch/i386/kernel/head.S     2006-08-07 00:18:54.000000000 -0400
1203 +++ linux-2.6.17.11/arch/i386/kernel/head.S     2006-09-01 16:20:31.000000000 -0400
1204 @@ -46,6 +46,16 @@
1205   */
1206  #define INIT_MAP_BEYOND_END    (128*1024)
1207  
1208 +#ifdef CONFIG_PAX_KERNEXEC
1209 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1210 +.fill 4096,1,0xcc
1211 +#endif
1212 +
1213 +/*
1214 + * Real beginning of normal "text" segment
1215 + */
1216 +ENTRY(stext)
1217 +ENTRY(_stext)
1218  
1219  /*
1220   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
1221 @@ -67,6 +77,26 @@ ENTRY(startup_32)
1222         movl %eax,%fs
1223         movl %eax,%gs
1224  
1225 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1226 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1227 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1228 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0f300),%eax
1229 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_DEFAULT_USER_DS * 8 + 4)
1230 +#endif
1231 +
1232 +#ifdef CONFIG_PAX_KERNEXEC
1233 +       movl $ __KERNEL_TEXT_OFFSET,%eax
1234 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1235 +       rorl $16,%eax
1236 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1237 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1238 +
1239 +       movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
1240 +       movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
1241 +       rorl $16,%eax
1242 +       movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
1243 +#endif
1244 +
1245  /*
1246   * Clear BSS first so that there are no surprises...
1247   * No need to cld as DF is already clear from cld above...
1248 @@ -114,24 +144,42 @@ ENTRY(startup_32)
1249   * Warning: don't use %esi or the stack in this code.  However, %esp
1250   * can be used as a GPR if you really need it...
1251   */
1252 -page_pde_offset = (__PAGE_OFFSET >> 20);
1253 -
1254 +#ifdef CONFIG_X86_PAE
1255 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
1256 +#else
1257 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
1258 +#endif
1259         movl $(pg0 - __PAGE_OFFSET), %edi
1260 +#ifdef CONFIG_X86_PAE
1261 +       movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1262 +#else
1263         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1264 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
1265 +#endif
1266 +       movl $0x063, %eax                       /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1267  10:
1268 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
1269 +       leal 0x063(%edi),%ecx                   /* Create PDE entry */
1270         movl %ecx,(%edx)                        /* Store identity PDE entry */
1271         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
1272 +#ifdef CONFIG_X86_PAE
1273 +       movl $0,4(%edx)
1274 +       movl $0,page_pde_offset+4(%edx)
1275 +       addl $8,%edx
1276 +       movl $512, %ecx
1277 +#else
1278         addl $4,%edx
1279         movl $1024, %ecx
1280 +#endif
1281  11:
1282         stosl
1283 +#ifdef CONFIG_X86_PAE
1284 +       movl $0,(%edi)
1285 +       addl $4,%edi
1286 +#endif
1287         addl $0x1000,%eax
1288         loop 11b
1289         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1290 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1291 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1292 +       /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1293 +       leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1294         cmpl %ebp,%eax
1295         jb 10b
1296         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1297 @@ -154,6 +202,11 @@ ENTRY(startup_32_smp)
1298         movl %eax,%fs
1299         movl %eax,%gs
1300  
1301 +       /* This is a secondary processor (AP) */
1302 +       xorl %ebx,%ebx
1303 +       incl %ebx
1304 +#endif /* CONFIG_SMP */
1305 +
1306  /*
1307   *     New page tables may be in 4Mbyte page mode and may
1308   *     be using the global pages. 
1309 @@ -169,26 +222,27 @@ ENTRY(startup_32_smp)
1310   *     not yet offset PAGE_OFFSET..
1311   */
1312  #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1313 +3:
1314         movl cr4_bits,%edx
1315         andl %edx,%edx
1316 -       jz 6f
1317 +       jz 5f
1318         movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
1319         orl %edx,%eax
1320         movl %eax,%cr4
1321  
1322 -       btl $5, %eax            # check if PAE is enabled
1323 -       jnc 6f
1324 +#ifdef CONFIG_X86_PAE
1325 +       movl %ebx,%edi
1326  
1327         /* Check if extended functions are implemented */
1328         movl $0x80000000, %eax
1329         cpuid
1330         cmpl $0x80000000, %eax
1331 -       jbe 6f
1332 +       jbe 4f
1333         mov $0x80000001, %eax
1334         cpuid
1335         /* Execute Disable bit supported? */
1336         btl $20, %edx
1337 -       jnc 6f
1338 +       jnc 4f
1339  
1340         /* Setup EFER (Extended Feature Enable Register) */
1341         movl $0xc0000080, %ecx
1342 @@ -197,14 +251,12 @@ ENTRY(startup_32_smp)
1343         btsl $11, %eax
1344         /* Make changes effective */
1345         wrmsr
1346 +       btsl $63,__supported_pte_mask-__PAGE_OFFSET
1347  
1348 -6:
1349 -       /* This is a secondary processor (AP) */
1350 -       xorl %ebx,%ebx
1351 -       incl %ebx
1352 -
1353 -3:
1354 -#endif /* CONFIG_SMP */
1355 +4:
1356 +       movl %edi,%ebx
1357 +#endif
1358 +5:
1359  
1360  /*
1361   * Enable paging
1362 @@ -229,9 +281,7 @@ ENTRY(startup_32_smp)
1363  
1364  #ifdef CONFIG_SMP
1365         andl %ebx,%ebx
1366 -       jz  1f                          /* Initial CPU cleans BSS */
1367 -       jmp checkCPUtype
1368 -1:
1369 +       jnz checkCPUtype        /* Initial CPU cleans BSS */
1370  #endif /* CONFIG_SMP */
1371  
1372  /*
1373 @@ -308,8 +358,6 @@ is386:      movl $2,%ecx            # set MP
1374         ljmp $(__KERNEL_CS),$1f
1375  1:     movl $(__KERNEL_DS),%eax        # reload all the segment registers
1376         movl %eax,%ss                   # after changing gdt.
1377 -
1378 -       movl $(__USER_DS),%eax          # DS/ES contains default USER segment
1379         movl %eax,%ds
1380         movl %eax,%es
1381  
1382 @@ -383,63 +431,71 @@ rp_sidt:
1383  /* This is the default interrupt "handler" :-) */
1384         ALIGN
1385  ignore_int:
1386 -       cld
1387  #ifdef CONFIG_PRINTK
1388 -       pushl %eax
1389 -       pushl %ecx
1390 -       pushl %edx
1391 -       pushl %es
1392 -       pushl %ds
1393 +       cld
1394         movl $(__KERNEL_DS),%eax
1395         movl %eax,%ds
1396         movl %eax,%es
1397 -       pushl 16(%esp)
1398 -       pushl 24(%esp)
1399 -       pushl 32(%esp)
1400 -       pushl 40(%esp)
1401 +       pushl 12(%esp)
1402 +       pushl 12(%esp)
1403 +       pushl 12(%esp)
1404 +       pushl 12(%esp)
1405         pushl $int_msg
1406  #ifdef CONFIG_EARLY_PRINTK
1407         call early_printk
1408  #else
1409         call printk
1410  #endif
1411 -       addl $(5*4),%esp
1412 -       popl %ds
1413 -       popl %es
1414 -       popl %edx
1415 -       popl %ecx
1416 -       popl %eax
1417  #endif
1418 -       iret
1419 +1:     hlt
1420 +       jmp 1b
1421  
1422 -/*
1423 - * Real beginning of normal "text" segment
1424 - */
1425 -ENTRY(stext)
1426 -ENTRY(_stext)
1427 -
1428 -/*
1429 - * BSS section
1430 - */
1431 -.section ".bss.page_aligned","w"
1432 +.section .swapper_pg_dir,"a",@progbits
1433  ENTRY(swapper_pg_dir)
1434 +#ifdef CONFIG_X86_PAE
1435 +       .long swapper_pm_dir-__PAGE_OFFSET+1
1436 +       .long 0
1437 +       .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1438 +       .long 0
1439 +       .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1440 +       .long 0
1441 +       .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1442 +       .long 0
1443 +#else
1444         .fill 1024,4,0
1445 +#endif
1446 +
1447 +#ifdef CONFIG_X86_PAE
1448 +.section .swapper_pm_dir,"a",@progbits
1449 +ENTRY(swapper_pm_dir)
1450 +       .fill 512,8,0
1451 +       .fill 512,8,0
1452 +       .fill 512,8,0
1453 +       .fill 512,8,0
1454 +#endif
1455 +
1456 +.section .empty_zero_page,"a",@progbits
1457  ENTRY(empty_zero_page)
1458         .fill 4096,1,0
1459  
1460  /*
1461 - * This starts the data section.
1462 - */
1463 -.data
1464 + * The IDT has to be page-aligned to simplify the Pentium
1465 + * F0 0F bug workaround.. We have a special link segment
1466 + * for this.
1467 + */
1468 +.section .idt,"a",@progbits
1469 +ENTRY(idt_table)
1470 +       .fill 256,8,0
1471 +
1472 +.section .rodata,"a",@progbits
1473 +ready: .byte 0
1474  
1475  ENTRY(stack_start)
1476 -       .long init_thread_union+THREAD_SIZE
1477 +       .long init_thread_union+THREAD_SIZE-8
1478         .long __BOOT_DS
1479  
1480 -ready: .byte 0
1481 -
1482  int_msg:
1483 -       .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
1484 +       .asciz "Unknown interrupt, stack: %p %p %p %p\n"
1485  
1486  /*
1487   * The IDT and GDT 'descriptors' are a strange 48-bit object
1488 @@ -465,10 +521,12 @@ idt_descr:
1489  
1490  # boot GDT descriptor (later on used by CPU#0):
1491         .word 0                         # 32 bit align gdt_desc.address
1492 -cpu_gdt_descr:
1493 +ENTRY(cpu_gdt_descr)
1494         .word GDT_ENTRIES*8-1
1495         .long cpu_gdt_table
1496  
1497 +       .fill NR_CPUS*8-6,1,0           # space for the other GDT descriptors
1498 +
1499  /*
1500   * The boot_gdt_table must mirror the equivalent in setup.S and is
1501   * used only for booting.
1502 @@ -476,13 +534,13 @@ cpu_gdt_descr:
1503         .align L1_CACHE_BYTES
1504  ENTRY(boot_gdt_table)
1505         .fill GDT_ENTRY_BOOT_CS,8,0
1506 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
1507 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
1508 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
1509 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
1510  
1511  /*
1512   * The Global Descriptor Table contains 28 quadwords, per-CPU.
1513   */
1514 -       .align L1_CACHE_BYTES
1515 +       .align PAGE_SIZE_asm
1516  ENTRY(cpu_gdt_table)
1517         .quad 0x0000000000000000        /* NULL descriptor */
1518         .quad 0x0000000000000000        /* 0x0b reserved */
1519 @@ -497,10 +555,10 @@ ENTRY(cpu_gdt_table)
1520         .quad 0x0000000000000000        /* 0x53 reserved */
1521         .quad 0x0000000000000000        /* 0x5b reserved */
1522  
1523 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1524 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1525 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1526 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1527 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1528 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1529 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1530 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1531  
1532         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
1533         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
1534 @@ -510,24 +568,30 @@ ENTRY(cpu_gdt_table)
1535          * They code segments and data segments have fixed 64k limits,
1536          * the transfer segment sizes are set at run time.
1537          */
1538 -       .quad 0x00409a000000ffff        /* 0x90 32-bit code */
1539 -       .quad 0x00009a000000ffff        /* 0x98 16-bit code */
1540 -       .quad 0x000092000000ffff        /* 0xa0 16-bit data */
1541 -       .quad 0x0000920000000000        /* 0xa8 16-bit data */
1542 -       .quad 0x0000920000000000        /* 0xb0 16-bit data */
1543 +       .quad 0x00409b000000ffff        /* 0x90 32-bit code */
1544 +       .quad 0x00009b000000ffff        /* 0x98 16-bit code */
1545 +       .quad 0x000093000000ffff        /* 0xa0 16-bit data */
1546 +       .quad 0x0000930000000000        /* 0xa8 16-bit data */
1547 +       .quad 0x0000930000000000        /* 0xb0 16-bit data */
1548  
1549         /*
1550          * The APM segments have byte granularity and their bases
1551          * are set at run time.  All have 64k limits.
1552          */
1553 -       .quad 0x00409a000000ffff        /* 0xb8 APM CS    code */
1554 -       .quad 0x00009a000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1555 -       .quad 0x004092000000ffff        /* 0xc8 APM DS    data */
1556 +       .quad 0x00409b000000ffff        /* 0xb8 APM CS    code */
1557 +       .quad 0x00009b000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1558 +       .quad 0x004093000000ffff        /* 0xc8 APM DS    data */
1559  
1560 -       .quad 0x0000920000000000        /* 0xd0 - ESPFIX 16-bit SS */
1561 +       .quad 0x0000930000000000        /* 0xd0 - ESPFIX 16-bit SS */
1562         .quad 0x0000000000000000        /* 0xd8 - unused */
1563         .quad 0x0000000000000000        /* 0xe0 - unused */
1564         .quad 0x0000000000000000        /* 0xe8 - unused */
1565         .quad 0x0000000000000000        /* 0xf0 - unused */
1566         .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
1567  
1568 +       /* Be sure this is zeroed to avoid false validations in Xen */
1569 +       .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
1570 +
1571 +#ifdef CONFIG_SMP
1572 +       .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
1573 +#endif
1574 diff -urNp linux-2.6.17.11/arch/i386/kernel/i386_ksyms.c linux-2.6.17.11/arch/i386/kernel/i386_ksyms.c
1575 --- linux-2.6.17.11/arch/i386/kernel/i386_ksyms.c       2006-08-07 00:18:54.000000000 -0400
1576 +++ linux-2.6.17.11/arch/i386/kernel/i386_ksyms.c       2006-09-01 16:20:28.000000000 -0400
1577 @@ -3,12 +3,16 @@
1578  #include <asm/checksum.h>
1579  #include <asm/desc.h>
1580  
1581 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
1582 +
1583  EXPORT_SYMBOL(__down_failed);
1584  EXPORT_SYMBOL(__down_failed_interruptible);
1585  EXPORT_SYMBOL(__down_failed_trylock);
1586  EXPORT_SYMBOL(__up_wakeup);
1587  /* Networking helper routines. */
1588  EXPORT_SYMBOL(csum_partial_copy_generic);
1589 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
1590 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
1591  
1592  EXPORT_SYMBOL(__get_user_1);
1593  EXPORT_SYMBOL(__get_user_2);
1594 diff -urNp linux-2.6.17.11/arch/i386/kernel/init_task.c linux-2.6.17.11/arch/i386/kernel/init_task.c
1595 --- linux-2.6.17.11/arch/i386/kernel/init_task.c        2006-08-07 00:18:54.000000000 -0400
1596 +++ linux-2.6.17.11/arch/i386/kernel/init_task.c        2006-09-01 16:20:28.000000000 -0400
1597 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
1598   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
1599   * no more per-task TSS's.
1600   */ 
1601 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
1602 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
1603  
1604 diff -urNp linux-2.6.17.11/arch/i386/kernel/ioport.c linux-2.6.17.11/arch/i386/kernel/ioport.c
1605 --- linux-2.6.17.11/arch/i386/kernel/ioport.c   2006-08-07 00:18:54.000000000 -0400
1606 +++ linux-2.6.17.11/arch/i386/kernel/ioport.c   2006-09-01 16:20:28.000000000 -0400
1607 @@ -16,6 +16,7 @@
1608  #include <linux/stddef.h>
1609  #include <linux/slab.h>
1610  #include <linux/thread_info.h>
1611 +#include <linux/grsecurity.h>
1612  
1613  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
1614  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
1615 @@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
1616  
1617         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
1618                 return -EINVAL;
1619 +#ifdef CONFIG_GRKERNSEC_IO
1620 +       if (turn_on) {
1621 +               gr_handle_ioperm();
1622 +#else
1623         if (turn_on && !capable(CAP_SYS_RAWIO))
1624 +#endif
1625                 return -EPERM;
1626 -
1627 +#ifdef CONFIG_GRKERNSEC_IO
1628 +       }
1629 +#endif
1630         /*
1631          * If it's the first ioperm() call in this thread's lifetime, set the
1632          * IO bitmap up. ioperm() is much less timing critical than clone(),
1633 @@ -88,7 +96,7 @@ asmlinkage long sys_ioperm(unsigned long
1634          * because the ->io_bitmap_max value must match the bitmap
1635          * contents:
1636          */
1637 -       tss = &per_cpu(init_tss, get_cpu());
1638 +       tss = init_tss + get_cpu();
1639  
1640         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
1641  
1642 @@ -142,8 +150,13 @@ asmlinkage long sys_iopl(unsigned long u
1643                 return -EINVAL;
1644         /* Trying to gain more privileges? */
1645         if (level > old) {
1646 +#ifdef CONFIG_GRKERNSEC_IO
1647 +               gr_handle_iopl();
1648 +               return -EPERM;
1649 +#else
1650                 if (!capable(CAP_SYS_RAWIO))
1651                         return -EPERM;
1652 +#endif
1653         }
1654         t->iopl = level << 12;
1655         regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
1656 diff -urNp linux-2.6.17.11/arch/i386/kernel/irq.c linux-2.6.17.11/arch/i386/kernel/irq.c
1657 --- linux-2.6.17.11/arch/i386/kernel/irq.c      2006-08-07 00:18:54.000000000 -0400
1658 +++ linux-2.6.17.11/arch/i386/kernel/irq.c      2006-09-01 16:20:28.000000000 -0400
1659 @@ -91,7 +91,7 @@ fastcall unsigned int do_IRQ(struct pt_r
1660                 int arg1, arg2, ebx;
1661  
1662                 /* build the stack frame on the IRQ stack */
1663 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1664 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1665                 irqctx->tinfo.task = curctx->tinfo.task;
1666                 irqctx->tinfo.previous_esp = current_stack_pointer;
1667  
1668 @@ -119,10 +119,10 @@ fastcall unsigned int do_IRQ(struct pt_r
1669   * gcc's 3.0 and earlier don't handle that correctly.
1670   */
1671  static char softirq_stack[NR_CPUS * THREAD_SIZE]
1672 -               __attribute__((__aligned__(THREAD_SIZE)));
1673 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1674  
1675  static char hardirq_stack[NR_CPUS * THREAD_SIZE]
1676 -               __attribute__((__aligned__(THREAD_SIZE)));
1677 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1678  
1679  /*
1680   * allocate per-cpu stacks for hardirq and for softirq processing
1681 @@ -182,7 +182,7 @@ asmlinkage void do_softirq(void)
1682                 irqctx->tinfo.previous_esp = current_stack_pointer;
1683  
1684                 /* build the stack frame on the softirq stack */
1685 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1686 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1687  
1688                 asm volatile(
1689                         "       xchgl   %%ebx,%%esp     \n"
1690 diff -urNp linux-2.6.17.11/arch/i386/kernel/ldt.c linux-2.6.17.11/arch/i386/kernel/ldt.c
1691 --- linux-2.6.17.11/arch/i386/kernel/ldt.c      2006-08-07 00:18:54.000000000 -0400
1692 +++ linux-2.6.17.11/arch/i386/kernel/ldt.c      2006-09-01 16:20:28.000000000 -0400
1693 @@ -103,6 +103,19 @@ int init_new_context(struct task_struct 
1694                 retval = copy_ldt(&mm->context, &old_mm->context);
1695                 up(&old_mm->context.sem);
1696         }
1697 +
1698 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1699 +       if (!mm->context.user_cs_limit) {
1700 +               mm->context.user_cs_base = 0UL;
1701 +               mm->context.user_cs_limit = ~0UL;
1702 +
1703 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
1704 +               cpus_clear(mm->context.cpu_user_cs_mask);
1705 +#endif
1706 +
1707 +       }
1708 +#endif
1709 +
1710         return retval;
1711  }
1712  
1713 @@ -160,7 +173,7 @@ static int read_default_ldt(void __user 
1714  {
1715         int err;
1716         unsigned long size;
1717 -       void *address;
1718 +       const void *address;
1719  
1720         err = 0;
1721         address = &default_ldt[0];
1722 @@ -215,6 +228,13 @@ static int write_ldt(void __user * ptr, 
1723                 }
1724         }
1725  
1726 +#ifdef CONFIG_PAX_SEGMEXEC
1727 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
1728 +               error = -EINVAL;
1729 +               goto out_unlock;
1730 +       }
1731 +#endif
1732 +
1733         entry_1 = LDT_entry_a(&ldt_info);
1734         entry_2 = LDT_entry_b(&ldt_info);
1735         if (oldmode)
1736 diff -urNp linux-2.6.17.11/arch/i386/kernel/module.c linux-2.6.17.11/arch/i386/kernel/module.c
1737 --- linux-2.6.17.11/arch/i386/kernel/module.c   2006-08-07 00:18:54.000000000 -0400
1738 +++ linux-2.6.17.11/arch/i386/kernel/module.c   2006-09-01 16:20:28.000000000 -0400
1739 @@ -21,6 +21,7 @@
1740  #include <linux/fs.h>
1741  #include <linux/string.h>
1742  #include <linux/kernel.h>
1743 +#include <asm/desc.h>
1744  
1745  #if 0
1746  #define DEBUGP printk
1747 @@ -32,9 +33,30 @@ void *module_alloc(unsigned long size)
1748  {
1749         if (size == 0)
1750                 return NULL;
1751 +
1752 +#ifdef CONFIG_PAX_KERNEXEC
1753 +       return vmalloc(size);
1754 +#else
1755         return vmalloc_exec(size);
1756 +#endif
1757 +
1758  }
1759  
1760 +#ifdef CONFIG_PAX_KERNEXEC
1761 +void *module_alloc_exec(unsigned long size)
1762 +{
1763 +       struct vm_struct *area;
1764 +
1765 +       if (size == 0)
1766 +               return NULL;
1767 +
1768 +       area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
1769 +       if (area)
1770 +               return area->addr;
1771 +
1772 +       return NULL;
1773 +}
1774 +#endif
1775  
1776  /* Free memory returned from module_alloc */
1777  void module_free(struct module *mod, void *module_region)
1778 @@ -44,6 +66,45 @@ void module_free(struct module *mod, voi
1779             table entries. */
1780  }
1781  
1782 +#ifdef CONFIG_PAX_KERNEXEC
1783 +void module_free_exec(struct module *mod, void *module_region)
1784 +{
1785 +       struct vm_struct **p, *tmp;
1786 +
1787 +       if (!module_region)
1788 +               return;
1789 +
1790 +       if ((PAGE_SIZE-1) & (unsigned long)module_region) {
1791 +               printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
1792 +               WARN_ON(1);
1793 +               return;
1794 +       }
1795 +
1796 +       write_lock(&vmlist_lock);
1797 +       for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
1798 +                if (tmp->addr == module_region)
1799 +                       break;
1800 +
1801 +       if (tmp) {
1802 +               unsigned long cr0;
1803 +
1804 +               pax_open_kernel(cr0);
1805 +               memset(tmp->addr, 0xCC, tmp->size);
1806 +               pax_close_kernel(cr0);
1807 +
1808 +               *p = tmp->next;
1809 +               kfree(tmp);
1810 +       }
1811 +       write_unlock(&vmlist_lock);
1812 +
1813 +       if (!tmp) {
1814 +               printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
1815 +                               module_region);
1816 +               WARN_ON(1);
1817 +       }
1818 +}
1819 +#endif
1820 +
1821  /* We don't need anything special. */
1822  int module_frob_arch_sections(Elf_Ehdr *hdr,
1823                               Elf_Shdr *sechdrs,
1824 @@ -62,14 +123,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1825         unsigned int i;
1826         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
1827         Elf32_Sym *sym;
1828 -       uint32_t *location;
1829 +       uint32_t *plocation, location;
1830  
1831         DEBUGP("Applying relocate section %u to %u\n", relsec,
1832                sechdrs[relsec].sh_info);
1833         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
1834                 /* This is where to make the change */
1835 -               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
1836 -                       + rel[i].r_offset;
1837 +               plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
1838 +               location = (uint32_t)plocation;
1839 +               if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
1840 +                       plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
1841                 /* This is the symbol it is referring to.  Note that all
1842                    undefined symbols have been resolved.  */
1843                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
1844 @@ -78,11 +141,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1845                 switch (ELF32_R_TYPE(rel[i].r_info)) {
1846                 case R_386_32:
1847                         /* We add the value into the location given */
1848 -                       *location += sym->st_value;
1849 +                       *plocation += sym->st_value;
1850                         break;
1851                 case R_386_PC32:
1852                         /* Add the value, subtract its postition */
1853 -                       *location += sym->st_value - (uint32_t)location;
1854 +                       *plocation += sym->st_value - location;
1855                         break;
1856                 default:
1857                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
1858 diff -urNp linux-2.6.17.11/arch/i386/kernel/process.c linux-2.6.17.11/arch/i386/kernel/process.c
1859 --- linux-2.6.17.11/arch/i386/kernel/process.c  2006-08-07 00:18:54.000000000 -0400
1860 +++ linux-2.6.17.11/arch/i386/kernel/process.c  2006-09-01 16:20:28.000000000 -0400
1861 @@ -69,7 +69,7 @@ EXPORT_SYMBOL(boot_option_idle_override)
1862   */
1863  unsigned long thread_saved_pc(struct task_struct *tsk)
1864  {
1865 -       return ((unsigned long *)tsk->thread.esp)[3];
1866 +       return tsk->thread.eip;
1867  }
1868  
1869  /*
1870 @@ -296,7 +296,7 @@ void show_regs(struct pt_regs * regs)
1871                 0xffff & regs->xcs,regs->eip, smp_processor_id());
1872         print_symbol("EIP is at %s\n", regs->eip);
1873  
1874 -       if (user_mode_vm(regs))
1875 +       if (user_mode(regs))
1876                 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
1877         printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
1878                regs->eflags, print_tainted(), system_utsname.release,
1879 @@ -345,8 +345,8 @@ int kernel_thread(int (*fn)(void *), voi
1880         regs.ebx = (unsigned long) fn;
1881         regs.edx = (unsigned long) arg;
1882  
1883 -       regs.xds = __USER_DS;
1884 -       regs.xes = __USER_DS;
1885 +       regs.xds = __KERNEL_DS;
1886 +       regs.xes = __KERNEL_DS;
1887         regs.orig_eax = -1;
1888         regs.eip = (unsigned long) kernel_thread_helper;
1889         regs.xcs = __KERNEL_CS;
1890 @@ -369,7 +369,7 @@ void exit_thread(void)
1891         /* The process may have allocated an io port bitmap... nuke it. */
1892         if (unlikely(NULL != t->io_bitmap_ptr)) {
1893                 int cpu = get_cpu();
1894 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
1895 +               struct tss_struct *tss = init_tss + cpu;
1896  
1897                 kfree(t->io_bitmap_ptr);
1898                 t->io_bitmap_ptr = NULL;
1899 @@ -389,6 +389,9 @@ void flush_thread(void)
1900  {
1901         struct task_struct *tsk = current;
1902  
1903 +       __asm__("mov %0,%%fs\n"
1904 +               "mov %0,%%gs\n"
1905 +               : : "r" (0) : "memory");
1906         memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
1907         memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
1908         /*
1909 @@ -421,7 +424,7 @@ int copy_thread(int nr, unsigned long cl
1910         struct task_struct *tsk;
1911         int err;
1912  
1913 -       childregs = task_pt_regs(p);
1914 +       childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
1915         *childregs = *regs;
1916         childregs->eax = 0;
1917         childregs->esp = esp;
1918 @@ -464,6 +467,11 @@ int copy_thread(int nr, unsigned long cl
1919                 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1920                         goto out;
1921  
1922 +#ifdef CONFIG_PAX_SEGMEXEC
1923 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1924 +                       goto out;
1925 +#endif
1926 +
1927                 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
1928                 desc->a = LDT_entry_a(&info);
1929                 desc->b = LDT_entry_b(&info);
1930 @@ -628,7 +636,11 @@ struct task_struct fastcall * __switch_t
1931         struct thread_struct *prev = &prev_p->thread,
1932                                  *next = &next_p->thread;
1933         int cpu = smp_processor_id();
1934 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1935 +       struct tss_struct *tss = init_tss + cpu;
1936 +
1937 +#ifdef CONFIG_PAX_KERNEXEC
1938 +       unsigned long cr0;
1939 +#endif
1940  
1941         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
1942  
1943 @@ -651,11 +663,23 @@ struct task_struct fastcall * __switch_t
1944         savesegment(fs, prev->fs);
1945         savesegment(gs, prev->gs);
1946  
1947 +#ifdef CONFIG_PAX_KERNEXEC
1948 +       pax_open_kernel(cr0);
1949 +#endif
1950 +
1951 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1952 +       __set_fs(get_fs(), cpu);
1953 +#endif
1954 +
1955         /*
1956          * Load the per-thread Thread-Local Storage descriptor.
1957          */
1958         load_TLS(next, cpu);
1959  
1960 +#ifdef CONFIG_PAX_KERNEXEC
1961 +       pax_close_kernel(cr0);
1962 +#endif
1963 +
1964         /*
1965          * Restore %fs and %gs if needed.
1966          *
1967 @@ -809,8 +833,18 @@ asmlinkage int sys_set_thread_area(struc
1968         struct desc_struct *desc;
1969         int cpu, idx;
1970  
1971 +#ifdef CONFIG_PAX_KERNEXEC
1972 +       unsigned long cr0;
1973 +#endif
1974 +
1975         if (copy_from_user(&info, u_info, sizeof(info)))
1976                 return -EFAULT;
1977 +
1978 +#ifdef CONFIG_PAX_SEGMEXEC
1979 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1980 +               return -EINVAL;
1981 +#endif
1982 +
1983         idx = info.entry_number;
1984  
1985         /*
1986 @@ -842,8 +876,17 @@ asmlinkage int sys_set_thread_area(struc
1987                 desc->a = LDT_entry_a(&info);
1988                 desc->b = LDT_entry_b(&info);
1989         }
1990 +
1991 +#ifdef CONFIG_PAX_KERNEXEC
1992 +       pax_open_kernel(cr0);
1993 +#endif
1994 +
1995         load_TLS(t, cpu);
1996  
1997 +#ifdef CONFIG_PAX_KERNEXEC
1998 +       pax_close_kernel(cr0);
1999 +#endif
2000 +
2001         put_cpu();
2002  
2003         return 0;
2004 @@ -899,9 +942,27 @@ asmlinkage int sys_get_thread_area(struc
2005         return 0;
2006  }
2007  
2008 -unsigned long arch_align_stack(unsigned long sp)
2009 +#ifdef CONFIG_PAX_RANDKSTACK
2010 +asmlinkage void pax_randomize_kstack(void)
2011  {
2012 -       if (randomize_va_space)
2013 -               sp -= get_random_int() % 8192;
2014 -       return sp & ~0xf;
2015 +       struct tss_struct *tss = init_tss + smp_processor_id();
2016 +       unsigned long time;
2017 +
2018 +       if (!randomize_va_space)
2019 +               return;
2020 +
2021 +       rdtscl(time);
2022 +
2023 +       /* P4 seems to return a 0 LSB, ignore it */
2024 +#ifdef CONFIG_MPENTIUM4
2025 +       time &= 0x1EUL;
2026 +       time <<= 2;
2027 +#else
2028 +       time &= 0xFUL;
2029 +       time <<= 3;
2030 +#endif
2031 +
2032 +       tss->esp0 ^= time;
2033 +       current->thread.esp0 = tss->esp0;
2034  }
2035 +#endif
2036 diff -urNp linux-2.6.17.11/arch/i386/kernel/ptrace.c linux-2.6.17.11/arch/i386/kernel/ptrace.c
2037 --- linux-2.6.17.11/arch/i386/kernel/ptrace.c   2006-08-07 00:18:54.000000000 -0400
2038 +++ linux-2.6.17.11/arch/i386/kernel/ptrace.c   2006-09-01 16:20:28.000000000 -0400
2039 @@ -17,6 +17,7 @@
2040  #include <linux/audit.h>
2041  #include <linux/seccomp.h>
2042  #include <linux/signal.h>
2043 +#include <linux/grsecurity.h>
2044  
2045  #include <asm/uaccess.h>
2046  #include <asm/pgtable.h>
2047 @@ -342,6 +343,11 @@ ptrace_set_thread_area(struct task_struc
2048         if (copy_from_user(&info, user_desc, sizeof(info)))
2049                 return -EFAULT;
2050  
2051 +#ifdef CONFIG_PAX_SEGMEXEC
2052 +       if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2053 +               return -EINVAL;
2054 +#endif
2055 +
2056         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2057                 return -EINVAL;
2058  
2059 @@ -432,6 +438,17 @@ long arch_ptrace(struct task_struct *chi
2060                           if(addr == (long) &dummy->u_debugreg[5]) break;
2061                           if(addr < (long) &dummy->u_debugreg[4] &&
2062                              ((unsigned long) data) >= TASK_SIZE-3) break;
2063 +
2064 +#ifdef CONFIG_GRKERNSEC
2065 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
2066 +                            addr <= (long) &dummy->u_debugreg[3]){
2067 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
2068 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
2069 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
2070 +                               if((type & 1) && (data & align))
2071 +                                       break;
2072 +                         }
2073 +#endif
2074                           
2075                           /* Sanity-check data. Take one half-byte at once with
2076                            * check = (val >> (16 + 4*i)) & 0xf. It contains the
2077 @@ -645,7 +662,7 @@ void send_sigtrap(struct task_struct *ts
2078         info.si_code = TRAP_BRKPT;
2079  
2080         /* User-mode eip? */
2081 -       info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2082 +       info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2083  
2084         /* Send us the fakey SIGTRAP */
2085         force_sig_info(SIGTRAP, &info, tsk);
2086 diff -urNp linux-2.6.17.11/arch/i386/kernel/reboot.c linux-2.6.17.11/arch/i386/kernel/reboot.c
2087 --- linux-2.6.17.11/arch/i386/kernel/reboot.c   2006-08-07 00:18:54.000000000 -0400
2088 +++ linux-2.6.17.11/arch/i386/kernel/reboot.c   2006-09-01 16:20:28.000000000 -0400
2089 @@ -25,7 +25,7 @@
2090  void (*pm_power_off)(void);
2091  EXPORT_SYMBOL(pm_power_off);
2092  
2093 -static int reboot_mode;
2094 +static unsigned short reboot_mode;
2095  static int reboot_thru_bios;
2096  
2097  #ifdef CONFIG_SMP
2098 @@ -138,18 +138,18 @@ core_initcall(reboot_init);
2099     doesn't work with at least one type of 486 motherboard.  It is easy
2100     to stop this code working; hence the copious comments. */
2101  
2102 -static unsigned long long
2103 +static const unsigned long long
2104  real_mode_gdt_entries [3] =
2105  {
2106         0x0000000000000000ULL,  /* Null descriptor */
2107 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
2108 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
2109 +       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
2110 +       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
2111  };
2112  
2113  static struct
2114  {
2115         unsigned short       size __attribute__ ((packed));
2116 -       unsigned long long * base __attribute__ ((packed));
2117 +       const unsigned long long * base __attribute__ ((packed));
2118  }
2119  real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
2120  real_mode_idt = { 0x3ff, NULL },
2121 @@ -175,7 +175,7 @@ no_idt = { 0, NULL };
2122     More could be done here to set up the registers as if a CPU reset had
2123     occurred; hopefully real BIOSs don't assume much. */
2124  
2125 -static unsigned char real_mode_switch [] =
2126 +static const unsigned char real_mode_switch [] =
2127  {
2128         0x66, 0x0f, 0x20, 0xc0,                 /*    movl  %cr0,%eax        */
2129         0x66, 0x83, 0xe0, 0x11,                 /*    andl  $0x00000011,%eax */
2130 @@ -189,7 +189,7 @@ static unsigned char real_mode_switch []
2131         0x24, 0x10,                             /* f: andb  $0x10,al         */
2132         0x66, 0x0f, 0x22, 0xc0                  /*    movl  %eax,%cr0        */
2133  };
2134 -static unsigned char jump_to_bios [] =
2135 +static const unsigned char jump_to_bios [] =
2136  {
2137         0xea, 0x00, 0x00, 0xff, 0xff            /*    ljmp  $0xffff,$0x0000  */
2138  };
2139 @@ -199,10 +199,14 @@ static unsigned char jump_to_bios [] =
2140   * specified by the code and length parameters.
2141   * We assume that length will aways be less that 100!
2142   */
2143 -void machine_real_restart(unsigned char *code, int length)
2144 +void machine_real_restart(const unsigned char *code, unsigned int length)
2145  {
2146         unsigned long flags;
2147  
2148 +#ifdef CONFIG_PAX_KERNEXEC
2149 +       unsigned long cr0;
2150 +#endif
2151 +
2152         local_irq_disable();
2153  
2154         /* Write zero to CMOS register number 0x0f, which the BIOS POST
2155 @@ -223,8 +227,16 @@ void machine_real_restart(unsigned char 
2156            from the kernel segment.  This assumes the kernel segment starts at
2157            virtual address PAGE_OFFSET. */
2158  
2159 -       memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2160 -               sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2161 +#ifdef CONFIG_PAX_KERNEXEC
2162 +       pax_open_kernel(cr0);
2163 +#endif
2164 +
2165 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2166 +                       USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
2167 +
2168 +#ifdef CONFIG_PAX_KERNEXEC
2169 +       pax_close_kernel(cr0);
2170 +#endif
2171  
2172         /*
2173          * Use `swapper_pg_dir' as our page directory.
2174 @@ -237,7 +249,7 @@ void machine_real_restart(unsigned char 
2175            REBOOT.COM programs, and the previous reset routine did this
2176            too. */
2177  
2178 -       *((unsigned short *)0x472) = reboot_mode;
2179 +       __put_user(reboot_mode, (unsigned short __user *)0x472);
2180  
2181         /* For the switch to real mode, copy some code to low memory.  It has
2182            to be in the first 64k because it is running in 16-bit mode, and it
2183 @@ -245,9 +257,9 @@ void machine_real_restart(unsigned char 
2184            off paging.  Copy it near the end of the first page, out of the way
2185            of BIOS variables. */
2186  
2187 -       memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
2188 +       flags = __copy_to_user ((void __user *) (0x1000 - sizeof (real_mode_switch) - 100),
2189                 real_mode_switch, sizeof (real_mode_switch));
2190 -       memcpy ((void *) (0x1000 - 100), code, length);
2191 +       flags = __copy_to_user ((void __user *) (0x1000 - 100), code, length);
2192  
2193         /* Set up the IDT for real mode. */
2194  
2195 @@ -329,7 +341,7 @@ void machine_emergency_restart(void)
2196                         __asm__ __volatile__("int3");
2197                 }
2198                 /* rebooting needs to touch the page at absolute addr 0 */
2199 -               *((unsigned short *)__va(0x472)) = reboot_mode;
2200 +               __put_user(reboot_mode, (unsigned short __user *)0x472);
2201                 for (;;) {
2202                         mach_reboot_fixups(); /* for board specific fixups */
2203                         mach_reboot();
2204 diff -urNp linux-2.6.17.11/arch/i386/kernel/setup.c linux-2.6.17.11/arch/i386/kernel/setup.c
2205 --- linux-2.6.17.11/arch/i386/kernel/setup.c    2006-08-07 00:18:54.000000000 -0400
2206 +++ linux-2.6.17.11/arch/i386/kernel/setup.c    2006-09-01 16:20:28.000000000 -0400
2207 @@ -88,7 +88,11 @@ struct cpuinfo_x86 new_cpu_data __initda
2208  struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2209  EXPORT_SYMBOL(boot_cpu_data);
2210  
2211 +#ifdef CONFIG_X86_PAE
2212 +unsigned long mmu_cr4_features = X86_CR4_PAE;
2213 +#else
2214  unsigned long mmu_cr4_features;
2215 +#endif
2216  
2217  #ifdef CONFIG_ACPI
2218         int acpi_disabled = 0;
2219 @@ -1493,14 +1497,14 @@ void __init setup_arch(char **cmdline_p)
2220  
2221         if (!MOUNT_ROOT_RDONLY)
2222                 root_mountflags &= ~MS_RDONLY;
2223 -       init_mm.start_code = (unsigned long) _text;
2224 -       init_mm.end_code = (unsigned long) _etext;
2225 +       init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2226 +       init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2227         init_mm.end_data = (unsigned long) _edata;
2228         init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2229  
2230 -       code_resource.start = virt_to_phys(_text);
2231 -       code_resource.end = virt_to_phys(_etext)-1;
2232 -       data_resource.start = virt_to_phys(_etext);
2233 +       code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
2234 +       code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
2235 +       data_resource.start = virt_to_phys(_data);
2236         data_resource.end = virt_to_phys(_edata)-1;
2237  
2238         parse_cmdline_early(cmdline_p);
2239 diff -urNp linux-2.6.17.11/arch/i386/kernel/signal.c linux-2.6.17.11/arch/i386/kernel/signal.c
2240 --- linux-2.6.17.11/arch/i386/kernel/signal.c   2006-08-07 00:18:54.000000000 -0400
2241 +++ linux-2.6.17.11/arch/i386/kernel/signal.c   2006-09-01 16:20:28.000000000 -0400
2242 @@ -351,7 +351,17 @@ static int setup_frame(int sig, struct k
2243                         goto give_sigsegv;
2244         }
2245  
2246 +#ifdef CONFIG_PAX_NOVSYSCALL
2247 +       restorer = frame->retcode;
2248 +#else
2249         restorer = &__kernel_sigreturn;
2250 +
2251 +#ifdef CONFIG_PAX_SEGMEXEC
2252 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2253 +               restorer -= SEGMEXEC_TASK_SIZE;
2254 +#endif
2255 +#endif
2256 +
2257         if (ka->sa.sa_flags & SA_RESTORER)
2258                 restorer = ka->sa.sa_restorer;
2259  
2260 @@ -447,7 +457,18 @@ static int setup_rt_frame(int sig, struc
2261                 goto give_sigsegv;
2262  
2263         /* Set up to return from userspace.  */
2264 +
2265 +#ifdef CONFIG_PAX_NOVSYSCALL
2266 +       restorer = frame->retcode;
2267 +#else
2268         restorer = &__kernel_rt_sigreturn;
2269 +
2270 +#ifdef CONFIG_PAX_SEGMEXEC
2271 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2272 +               restorer -= SEGMEXEC_TASK_SIZE;
2273 +#endif
2274 +#endif
2275 +
2276         if (ka->sa.sa_flags & SA_RESTORER)
2277                 restorer = ka->sa.sa_restorer;
2278         err |= __put_user(restorer, &frame->pretcode);
2279 @@ -580,7 +601,7 @@ static void fastcall do_signal(struct pt
2280          * before reaching here, so testing against kernel
2281          * CS suffices.
2282          */
2283 -       if (!user_mode(regs))
2284 +       if (!user_mode_novm(regs))
2285                 return;
2286  
2287         if (test_thread_flag(TIF_RESTORE_SIGMASK))
2288 diff -urNp linux-2.6.17.11/arch/i386/kernel/smpboot.c linux-2.6.17.11/arch/i386/kernel/smpboot.c
2289 --- linux-2.6.17.11/arch/i386/kernel/smpboot.c  2006-08-07 00:18:54.000000000 -0400
2290 +++ linux-2.6.17.11/arch/i386/kernel/smpboot.c  2006-09-01 16:20:28.000000000 -0400
2291 @@ -1069,7 +1069,7 @@ static int __cpuinit __smp_prepare_cpu(i
2292  
2293         /* init low mem mapping */
2294         clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2295 -                       KERNEL_PGD_PTRS);
2296 +                       USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
2297         flush_tlb_all();
2298         schedule_work(&task);
2299         wait_for_completion(&done);
2300 diff -urNp linux-2.6.17.11/arch/i386/kernel/syscall_table.S linux-2.6.17.11/arch/i386/kernel/syscall_table.S
2301 --- linux-2.6.17.11/arch/i386/kernel/syscall_table.S    2006-08-07 00:18:54.000000000 -0400
2302 +++ linux-2.6.17.11/arch/i386/kernel/syscall_table.S    2006-09-01 16:20:28.000000000 -0400
2303 @@ -1,3 +1,4 @@
2304 +.section .rodata,"a",@progbits
2305  ENTRY(sys_call_table)
2306         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
2307         .long sys_exit
2308 diff -urNp linux-2.6.17.11/arch/i386/kernel/sysenter.c linux-2.6.17.11/arch/i386/kernel/sysenter.c
2309 --- linux-2.6.17.11/arch/i386/kernel/sysenter.c 2006-08-07 00:18:54.000000000 -0400
2310 +++ linux-2.6.17.11/arch/i386/kernel/sysenter.c 2006-09-01 16:20:28.000000000 -0400
2311 @@ -24,7 +24,7 @@ extern asmlinkage void sysenter_entry(vo
2312  void enable_sep_cpu(void)
2313  {
2314         int cpu = get_cpu();
2315 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2316 +       struct tss_struct *tss = init_tss + cpu;
2317  
2318         if (!boot_cpu_has(X86_FEATURE_SEP)) {
2319                 put_cpu();
2320 @@ -48,6 +48,7 @@ extern const char vsyscall_sysenter_star
2321  
2322  int __init sysenter_setup(void)
2323  {
2324 +#ifndef CONFIG_PAX_NOVSYSCALL
2325         void *page = (void *)get_zeroed_page(GFP_ATOMIC);
2326  
2327         __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
2328 @@ -62,6 +63,7 @@ int __init sysenter_setup(void)
2329         memcpy(page,
2330                &vsyscall_sysenter_start,
2331                &vsyscall_sysenter_end - &vsyscall_sysenter_start);
2332 +#endif
2333  
2334         return 0;
2335  }
2336 diff -urNp linux-2.6.17.11/arch/i386/kernel/sys_i386.c linux-2.6.17.11/arch/i386/kernel/sys_i386.c
2337 --- linux-2.6.17.11/arch/i386/kernel/sys_i386.c 2006-08-07 00:18:54.000000000 -0400
2338 +++ linux-2.6.17.11/arch/i386/kernel/sys_i386.c 2006-09-01 16:20:28.000000000 -0400
2339 @@ -100,6 +100,191 @@ out:
2340         return err;
2341  }
2342  
2343 +unsigned long
2344 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
2345 +               unsigned long len, unsigned long pgoff, unsigned long flags)
2346 +{
2347 +       struct mm_struct *mm = current->mm;
2348 +       struct vm_area_struct *vma;
2349 +       unsigned long start_addr, task_size = TASK_SIZE;
2350 +
2351 +#ifdef CONFIG_PAX_SEGMEXEC
2352 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
2353 +               task_size = SEGMEXEC_TASK_SIZE;
2354 +#endif
2355 +
2356 +       if (len > task_size)
2357 +               return -ENOMEM;
2358 +
2359 +#ifdef CONFIG_PAX_RANDMMAP
2360 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2361 +#endif
2362 +
2363 +       if (addr) {
2364 +               addr = PAGE_ALIGN(addr);
2365 +               vma = find_vma(mm, addr);
2366 +               if (task_size - len >= addr &&
2367 +                   (!vma || addr + len <= vma->vm_start))
2368 +                       return addr;
2369 +       }
2370 +       if (len > mm->cached_hole_size) {
2371 +               start_addr = addr = mm->free_area_cache;
2372 +       } else {
2373 +               start_addr = addr = mm->mmap_base;
2374 +               mm->cached_hole_size = 0;
2375 +       }
2376 +
2377 +#ifdef CONFIG_PAX_PAGEEXEC
2378 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
2379 +               start_addr = 0x00110000UL;
2380 +
2381 +#ifdef CONFIG_PAX_RANDMMAP
2382 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
2383 +                       start_addr += mm->delta_mmap & 0x03FFF000UL;
2384 +#endif
2385 +
2386 +               if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
2387 +                       start_addr = addr = mm->mmap_base;
2388 +               else
2389 +                       addr = start_addr;
2390 +       }
2391 +#endif
2392 +
2393 +full_search:
2394 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2395 +               /* At this point:  (!vma || addr < vma->vm_end). */
2396 +               if (task_size - len < addr) {
2397 +                       /*
2398 +                        * Start a new search - just in case we missed
2399 +                        * some holes.
2400 +                        */
2401 +                       if (start_addr != mm->mmap_base) {
2402 +                               start_addr = addr = mm->mmap_base;
2403 +                               mm->cached_hole_size = 0;
2404 +                               goto full_search;
2405 +                       }
2406 +                       return -ENOMEM;
2407 +               }
2408 +               if (!vma || addr + len <= vma->vm_start) {
2409 +                       /*
2410 +                        * Remember the place where we stopped the search:
2411 +                        */
2412 +                       mm->free_area_cache = addr + len;
2413 +                       return addr;
2414 +               }
2415 +               if (addr + mm->cached_hole_size < vma->vm_start)
2416 +                       mm->cached_hole_size = vma->vm_start - addr;
2417 +               addr = vma->vm_end;
2418 +               if (mm->start_brk <= addr && addr < mm->mmap_base) {
2419 +                       start_addr = addr = mm->mmap_base;
2420 +                       goto full_search;
2421 +               }
2422 +       }
2423 +}
2424 +
2425 +unsigned long
2426 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
2427 +                         const unsigned long len, const unsigned long pgoff,
2428 +                         const unsigned long flags)
2429 +{
2430 +       struct vm_area_struct *vma;
2431 +       struct mm_struct *mm = current->mm;
2432 +       unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
2433 +
2434 +#ifdef CONFIG_PAX_SEGMEXEC
2435 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
2436 +               task_size = SEGMEXEC_TASK_SIZE;
2437 +#endif
2438 +
2439 +       /* requested length too big for entire address space */
2440 +       if (len > task_size)
2441 +               return -ENOMEM;
2442 +
2443 +#ifdef CONFIG_PAX_PAGEEXEC
2444 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
2445 +               goto bottomup;
2446 +#endif
2447 +
2448 +#ifdef CONFIG_PAX_RANDMMAP
2449 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2450 +#endif
2451 +
2452 +       /* requesting a specific address */
2453 +       if (addr) {
2454 +               addr = PAGE_ALIGN(addr);
2455 +               vma = find_vma(mm, addr);
2456 +               if (task_size - len >= addr &&
2457 +                               (!vma || addr + len <= vma->vm_start))
2458 +                       return addr;
2459 +       }
2460 +
2461 +       /* check if free_area_cache is useful for us */
2462 +       if (len <= mm->cached_hole_size) {
2463 +               mm->cached_hole_size = 0;
2464 +               mm->free_area_cache = mm->mmap_base;
2465 +       }
2466 +
2467 +       /* either no address requested or can't fit in requested address hole */
2468 +       addr = mm->free_area_cache;
2469 +
2470 +       /* make sure it can fit in the remaining address space */
2471 +       if (addr > len) {
2472 +               vma = find_vma(mm, addr-len);
2473 +               if (!vma || addr <= vma->vm_start)
2474 +                       /* remember the address as a hint for next time */
2475 +                       return (mm->free_area_cache = addr-len);
2476 +       }
2477 +
2478 +       if (mm->mmap_base < len)
2479 +               goto bottomup;
2480 +
2481 +       addr = mm->mmap_base-len;
2482 +
2483 +       do {
2484 +               /*
2485 +                * Lookup failure means no vma is above this address,
2486 +                * else if new region fits below vma->vm_start,
2487 +                * return with success:
2488 +                */
2489 +               vma = find_vma(mm, addr);
2490 +               if (!vma || addr+len <= vma->vm_start)
2491 +                       /* remember the address as a hint for next time */
2492 +                       return (mm->free_area_cache = addr);
2493 +
2494 +               /* remember the largest hole we saw so far */
2495 +               if (addr + mm->cached_hole_size < vma->vm_start)
2496 +                       mm->cached_hole_size = vma->vm_start - addr;
2497 +
2498 +               /* try just below the current vma->vm_start */
2499 +               addr = vma->vm_start-len;
2500 +       } while (len < vma->vm_start);
2501 +
2502 +bottomup:
2503 +       /*
2504 +        * A failed mmap() very likely causes application failure,
2505 +        * so fall back to the bottom-up function here. This scenario
2506 +        * can happen with large stack limits and large mmap()
2507 +        * allocations.
2508 +        */
2509 +       mm->mmap_base = TASK_UNMAPPED_BASE;
2510 +
2511 +#ifdef CONFIG_PAX_RANDMMAP
2512 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
2513 +               mm->mmap_base += mm->delta_mmap;
2514 +#endif
2515 +
2516 +       mm->free_area_cache = mm->mmap_base;
2517 +       mm->cached_hole_size = ~0UL;
2518 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
2519 +       /*
2520 +        * Restore the topdown base:
2521 +        */
2522 +       mm->mmap_base = base;
2523 +       mm->free_area_cache = base;
2524 +       mm->cached_hole_size = ~0UL;
2525 +
2526 +       return addr;
2527 +}
2528  
2529  struct sel_arg_struct {
2530         unsigned long n;
2531 diff -urNp linux-2.6.17.11/arch/i386/kernel/traps.c linux-2.6.17.11/arch/i386/kernel/traps.c
2532 --- linux-2.6.17.11/arch/i386/kernel/traps.c    2006-08-07 00:18:54.000000000 -0400
2533 +++ linux-2.6.17.11/arch/i386/kernel/traps.c    2006-09-01 16:20:31.000000000 -0400
2534 @@ -28,6 +28,7 @@
2535  #include <linux/utsname.h>
2536  #include <linux/kprobes.h>
2537  #include <linux/kexec.h>
2538 +#include <linux/binfmts.h>
2539  
2540  #ifdef CONFIG_EISA
2541  #include <linux/ioport.h>
2542 @@ -58,18 +59,13 @@
2543  
2544  asmlinkage int system_call(void);
2545  
2546 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2547 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2548                 { 0, 0 }, { 0, 0 } };
2549  
2550  /* Do we ignore FPU interrupts ? */
2551  char ignore_fpu_irq = 0;
2552  
2553 -/*
2554 - * The IDT has to be page-aligned to simplify the Pentium
2555 - * F0 0F bug workaround.. We have a special link segment
2556 - * for this.
2557 - */
2558 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
2559 +extern struct desc_struct idt_table[256];
2560  
2561  asmlinkage void divide_error(void);
2562  asmlinkage void debug(void);
2563 @@ -144,18 +140,22 @@ static inline unsigned long print_contex
2564  {
2565         unsigned long addr;
2566         int printed = 0; /* nr of entries already printed on current line */
2567 +       int i = kstack_depth_to_print;
2568  
2569  #ifdef CONFIG_FRAME_POINTER
2570         while (valid_stack_ptr(tinfo, (void *)ebp)) {
2571                 addr = *(unsigned long *)(ebp + 4);
2572                 printed = print_addr_and_symbol(addr, log_lvl, printed);
2573                 ebp = *(unsigned long *)ebp;
2574 +               --i;
2575         }
2576  #else
2577         while (valid_stack_ptr(tinfo, stack)) {
2578                 addr = *stack++;
2579 -               if (__kernel_text_address(addr))
2580 +               if (__kernel_text_address(addr + __KERNEL_TEXT_OFFSET)) {
2581                         printed = print_addr_and_symbol(addr, log_lvl, printed);
2582 +                       --i;
2583 +               }
2584         }
2585  #endif
2586         if (printed)
2587 @@ -249,7 +249,7 @@ void show_registers(struct pt_regs *regs
2588  
2589         esp = (unsigned long) (&regs->esp);
2590         savesegment(ss, ss);
2591 -       if (user_mode_vm(regs)) {
2592 +       if (user_mode(regs)) {
2593                 in_kernel = 0;
2594                 esp = regs->esp;
2595                 ss = regs->xss & 0xffff;
2596 @@ -276,13 +276,15 @@ void show_registers(struct pt_regs *regs
2597          */
2598         if (in_kernel) {
2599                 u8 __user *eip;
2600 +               mm_segment_t old_fs = get_fs();
2601  
2602                 printk("\n" KERN_EMERG "Stack: ");
2603                 show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG);
2604  
2605                 printk(KERN_EMERG "Code: ");
2606  
2607 -               eip = (u8 __user *)regs->eip - 43;
2608 +               set_fs(KERNEL_DS);
2609 +               eip = (u8 __user *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
2610                 for (i = 0; i < 64; i++, eip++) {
2611                         unsigned char c;
2612  
2613 @@ -290,11 +292,12 @@ void show_registers(struct pt_regs *regs
2614                                 printk(" Bad EIP value.");
2615                                 break;
2616                         }
2617 -                       if (eip == (u8 __user *)regs->eip)
2618 +                       if (eip == (u8 __user *)regs->eip + __KERNEL_TEXT_OFFSET)
2619                                 printk("<%02x> ", c);
2620                         else
2621                                 printk("%02x ", c);
2622                 }
2623 +               set_fs(old_fs);
2624         }
2625         printk("\n");
2626  }      
2627 @@ -306,29 +309,34 @@ static void handle_BUG(struct pt_regs *r
2628         char *file;
2629         char c;
2630         unsigned long eip;
2631 +       mm_segment_t old_fs = get_fs();
2632  
2633 -       eip = regs->eip;
2634 +       eip = regs->eip + __KERNEL_TEXT_OFFSET;
2635  
2636 +       set_fs(KERNEL_DS);
2637         if (eip < PAGE_OFFSET)
2638                 goto no_bug;
2639         if (__get_user(ud2, (unsigned short __user *)eip))
2640                 goto no_bug;
2641         if (ud2 != 0x0b0f)
2642                 goto no_bug;
2643 -       if (__get_user(line, (unsigned short __user *)(eip + 2)))
2644 +       if (__get_user(line, (unsigned short __user *)(eip + 7)))
2645                 goto bug;
2646 -       if (__get_user(file, (char * __user *)(eip + 4)) ||
2647 -               (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
2648 +       if (__get_user(file, (char * __user *)(eip + 3)) || file < _text + __KERNEL_TEXT_OFFSET)
2649 +               goto bug;
2650 +       if (__get_user(c, file))
2651                 file = "<bad filename>";
2652  
2653         printk(KERN_EMERG "------------[ cut here ]------------\n");
2654         printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
2655  
2656  no_bug:
2657 +       set_fs(old_fs);
2658         return;
2659  
2660         /* Here we know it was a BUG but file-n-line is unavailable */
2661  bug:
2662 +       set_fs(old_fs);
2663         printk(KERN_EMERG "Kernel BUG\n");
2664  }
2665  
2666 @@ -430,7 +438,7 @@ void die(const char * str, struct pt_reg
2667  
2668  static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
2669  {
2670 -       if (!user_mode_vm(regs))
2671 +       if (!user_mode(regs))
2672                 die(str, regs, err);
2673  }
2674  
2675 @@ -448,7 +456,7 @@ static void __kprobes do_trap(int trapnr
2676                 goto trap_signal;
2677         }
2678  
2679 -       if (!user_mode(regs))
2680 +       if (!user_mode_novm(regs))
2681                 goto kernel_trap;
2682  
2683         trap_signal: {
2684 @@ -536,7 +544,7 @@ fastcall void __kprobes do_general_prote
2685                                               long error_code)
2686  {
2687         int cpu = get_cpu();
2688 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2689 +       struct tss_struct *tss = &init_tss[cpu];
2690         struct thread_struct *thread = &current->thread;
2691  
2692         /*
2693 @@ -572,9 +580,25 @@ fastcall void __kprobes do_general_prote
2694         if (regs->eflags & VM_MASK)
2695                 goto gp_in_vm86;
2696  
2697 -       if (!user_mode(regs))
2698 +       if (!user_mode_novm(regs))
2699                 goto gp_in_kernel;
2700  
2701 +#ifdef CONFIG_PAX_PAGEEXEC
2702 +       if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
2703 +               struct mm_struct *mm = current->mm;
2704 +               unsigned long limit;
2705 +
2706 +               down_write(&mm->mmap_sem);
2707 +               limit = mm->context.user_cs_limit;
2708 +               if (limit < TASK_SIZE) {
2709 +                       track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
2710 +                       up_write(&mm->mmap_sem);
2711 +                       return;
2712 +               }
2713 +               up_write(&mm->mmap_sem);
2714 +       }
2715 +#endif
2716 +
2717         current->thread.error_code = error_code;
2718         current->thread.trap_no = 13;
2719         force_sig(SIGSEGV, current);
2720 @@ -590,6 +614,13 @@ gp_in_kernel:
2721                 if (notify_die(DIE_GPF, "general protection fault", regs,
2722                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
2723                         return;
2724 +
2725 +#ifdef CONFIG_PAX_KERNEXEC
2726 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
2727 +                       die("PAX: suspicious general protection fault", regs, error_code);
2728 +               else
2729 +#endif
2730 +
2731                 die("general protection fault", regs, error_code);
2732         }
2733  }
2734 @@ -663,7 +694,7 @@ void die_nmi (struct pt_regs *regs, cons
2735         /* If we are in kernel we are probably nested up pretty bad
2736          * and might aswell get out now while we still can.
2737         */
2738 -       if (!user_mode_vm(regs)) {
2739 +       if (!user_mode(regs)) {
2740                 current->thread.trap_no = 2;
2741                 crash_kexec(regs);
2742         }
2743 @@ -816,7 +847,7 @@ fastcall void __kprobes do_debug(struct 
2744                  * check for kernel mode by just checking the CPL
2745                  * of CS.
2746                  */
2747 -               if (!user_mode(regs))
2748 +               if (!user_mode_novm(regs))
2749                         goto clear_TF_reenable;
2750         }
2751  
2752 @@ -1106,7 +1137,19 @@ do { \
2753   */
2754  void set_intr_gate(unsigned int n, void *addr)
2755  {
2756 +
2757 +#ifdef CONFIG_PAX_KERNEXEC
2758 +       unsigned long cr0;
2759 +
2760 +       pax_open_kernel(cr0);
2761 +#endif
2762 +
2763         _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
2764 +
2765 +#ifdef CONFIG_PAX_KERNEXEC
2766 +       pax_close_kernel(cr0);
2767 +#endif
2768 +
2769  }
2770  
2771  /*
2772 diff -urNp linux-2.6.17.11/arch/i386/kernel/vm86.c linux-2.6.17.11/arch/i386/kernel/vm86.c
2773 --- linux-2.6.17.11/arch/i386/kernel/vm86.c     2006-08-07 00:18:54.000000000 -0400
2774 +++ linux-2.6.17.11/arch/i386/kernel/vm86.c     2006-09-01 16:20:28.000000000 -0400
2775 @@ -123,7 +123,7 @@ struct pt_regs * fastcall save_v86_state
2776                 do_exit(SIGSEGV);
2777         }
2778  
2779 -       tss = &per_cpu(init_tss, get_cpu());
2780 +       tss = init_tss + get_cpu();
2781         current->thread.esp0 = current->thread.saved_esp0;
2782         current->thread.sysenter_cs = __KERNEL_CS;
2783         load_esp0(tss, &current->thread);
2784 @@ -297,7 +297,7 @@ static void do_sys_vm86(struct kernel_vm
2785         savesegment(fs, tsk->thread.saved_fs);
2786         savesegment(gs, tsk->thread.saved_gs);
2787  
2788 -       tss = &per_cpu(init_tss, get_cpu());
2789 +       tss = init_tss + get_cpu();
2790         tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
2791         if (cpu_has_sep)
2792                 tsk->thread.sysenter_cs = 0;
2793 diff -urNp linux-2.6.17.11/arch/i386/kernel/vmlinux.lds.S linux-2.6.17.11/arch/i386/kernel/vmlinux.lds.S
2794 --- linux-2.6.17.11/arch/i386/kernel/vmlinux.lds.S      2006-08-07 00:18:54.000000000 -0400
2795 +++ linux-2.6.17.11/arch/i386/kernel/vmlinux.lds.S      2006-09-01 16:20:28.000000000 -0400
2796 @@ -4,10 +4,19 @@
2797  
2798  #define LOAD_OFFSET __PAGE_OFFSET
2799  
2800 +#include <linux/config.h>
2801 +
2802  #include <asm-generic/vmlinux.lds.h>
2803  #include <asm/thread_info.h>
2804  #include <asm/page.h>
2805  #include <asm/cache.h>
2806 +#include <asm/segment.h>
2807 +
2808 +#ifdef CONFIG_X86_PAE
2809 +#define PMD_SHIFT 21
2810 +#else
2811 +#define PMD_SHIFT 22
2812 +#endif
2813  
2814  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2815  OUTPUT_ARCH(i386)
2816 @@ -16,59 +25,14 @@ jiffies = jiffies_64;
2817  SECTIONS
2818  {
2819    . = __KERNEL_START;
2820 -  phys_startup_32 = startup_32 - LOAD_OFFSET;
2821 -  /* read-only */
2822 -  _text = .;                   /* Text and read-only data */
2823 -  .text : AT(ADDR(.text) - LOAD_OFFSET) {
2824 -       *(.text)
2825 -       SCHED_TEXT
2826 -       LOCK_TEXT
2827 -       KPROBES_TEXT
2828 -       *(.fixup)
2829 -       *(.gnu.warning)
2830 -       } = 0x9090
2831 -
2832 -  _etext = .;                  /* End of text section */
2833 -
2834 -  . = ALIGN(16);               /* Exception table */
2835 -  __start___ex_table = .;
2836 -  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2837 -  __stop___ex_table = .;
2838 -
2839 -  RODATA
2840 +  phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
2841  
2842 -  /* writeable */
2843 -  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2844 -       *(.data)
2845 -       CONSTRUCTORS
2846 +  .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
2847 +       BYTE(0xEA) /* jmp far */
2848 +       LONG(phys_startup_32)
2849 +       SHORT(__BOOT_CS)
2850         }
2851  
2852 -  . = ALIGN(4096);
2853 -  __nosave_begin = .;
2854 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2855 -  . = ALIGN(4096);
2856 -  __nosave_end = .;
2857 -
2858 -  . = ALIGN(4096);
2859 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
2860 -       *(.data.idt)
2861 -  }
2862 -
2863 -  . = ALIGN(32);
2864 -  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2865 -       *(.data.cacheline_aligned)
2866 -  }
2867 -
2868 -  /* rarely changed data like cpu maps */
2869 -  . = ALIGN(32);
2870 -  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2871 -  _edata = .;                  /* End of data section */
2872 -
2873 -  . = ALIGN(THREAD_SIZE);      /* init_task */
2874 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2875 -       *(.data.init_task)
2876 -  }
2877 -
2878    /* might get freed after init */
2879    . = ALIGN(4096);
2880    __smp_alt_begin = .;
2881 @@ -92,11 +56,6 @@ SECTIONS
2882    /* will be freed after init */
2883    . = ALIGN(4096);             /* Init code and data */
2884    __init_begin = .;
2885 -  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
2886 -       _sinittext = .;
2887 -       *(.init.text)
2888 -       _einittext = .;
2889 -  }
2890    .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
2891    . = ALIGN(16);
2892    __setup_start = .;
2893 @@ -128,9 +87,7 @@ SECTIONS
2894    .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
2895         *(.altinstr_replacement)
2896    }
2897 -  /* .exit.text is discard at runtime, not link time, to deal with references
2898 -     from .altinstructions and .eh_frame */
2899 -  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
2900 +
2901    .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
2902    . = ALIGN(4096);
2903    __initramfs_start = .;
2904 @@ -140,10 +97,108 @@ SECTIONS
2905    __per_cpu_start = .;
2906    .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
2907    __per_cpu_end = .;
2908 +
2909 +  /* read-only */
2910 +
2911    . = ALIGN(4096);
2912 -  __init_end = .;
2913 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2914 +       _sinittext = .;
2915 +       *(.init.text)
2916 +       _einittext = .;
2917 +  }
2918 +
2919 +  /* .exit.text is discard at runtime, not link time, to deal with references
2920 +     from .altinstructions and .eh_frame */
2921 +  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
2922 +
2923 +#ifdef CONFIG_PAX_KERNEXEC
2924 +  .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2925 +       . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
2926 +       BYTE(0)
2927 +  }
2928 +#else
2929 +  . = ALIGN(4096);
2930 +#endif
2931 +
2932 +  __init_end = . + __KERNEL_TEXT_OFFSET;
2933    /* freed after init ends here */
2934 -       
2935 +
2936 +  _text = .;                   /* Text and read-only data */
2937 +  .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2938 +       *(.text)
2939 +       SCHED_TEXT
2940 +       LOCK_TEXT
2941 +       KPROBES_TEXT
2942 +       *(.fixup)
2943 +       *(.gnu.warning)
2944 +       } = 0x9090
2945 +
2946 +  _etext = .;                  /* End of text section */
2947 +  . += __KERNEL_TEXT_OFFSET;
2948 +  . = ALIGN(16);               /* Exception table */
2949 +  __start___ex_table = .;
2950 +  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2951 +  __stop___ex_table = .;
2952 +
2953 +  . = ALIGN(4096);
2954 +  .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
2955 +       *(.empty_zero_page)
2956 +
2957 +#ifdef CONFIG_X86_PAE
2958 +       *(.swapper_pm_dir)
2959 +#endif
2960 +
2961 +       *(.swapper_pg_dir)
2962 +       *(.idt)
2963 +       }
2964 +
2965 +  RODATA
2966 +
2967 +#ifdef CONFIG_PAX_KERNEXEC
2968 +  . = ALIGN(4096);
2969 +  MODULES_VADDR = .;
2970 +
2971 +  .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
2972 +       . += (4 * 1024 * 1024);
2973 +       . = ALIGN(1 << PMD_SHIFT) - 1;
2974 +       BYTE(0)
2975 +  }
2976 +
2977 +  MODULES_END = .;
2978 +#else
2979 +  . = ALIGN(32);
2980 +#endif
2981 +
2982 +  /* writeable */
2983 +  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2984 +       _data = .;
2985 +       *(.data)
2986 +       CONSTRUCTORS
2987 +       }
2988 +
2989 +  . = ALIGN(4096);
2990 +  __nosave_begin = .;
2991 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2992 +  . = ALIGN(4096);
2993 +  __nosave_end = .;
2994 +
2995 +  . = ALIGN(32);
2996 +  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2997 +       *(.data.cacheline_aligned)
2998 +  }
2999 +
3000 +  /* rarely changed data like cpu maps */
3001 +  . = ALIGN(32);
3002 +  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
3003 +
3004 +  . = ALIGN(THREAD_SIZE);      /* init_task */
3005 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
3006 +       *(.data.init_task)
3007 +  }
3008 +
3009 +  _edata = .;                  /* End of data section */
3010 +
3011 +  . = ALIGN(4096);
3012    __bss_start = .;             /* BSS */
3013    .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
3014         *(.bss.page_aligned)
3015 diff -urNp linux-2.6.17.11/arch/i386/lib/checksum.S linux-2.6.17.11/arch/i386/lib/checksum.S
3016 --- linux-2.6.17.11/arch/i386/lib/checksum.S    2006-08-07 00:18:54.000000000 -0400
3017 +++ linux-2.6.17.11/arch/i386/lib/checksum.S    2006-09-01 16:20:28.000000000 -0400
3018 @@ -27,7 +27,8 @@
3019  
3020  #include <linux/config.h>
3021  #include <asm/errno.h>
3022 -                               
3023 +#include <asm/segment.h>
3024 +
3025  /*
3026   * computes a partial checksum, e.g. for TCP/UDP fragments
3027   */
3028 @@ -281,12 +282,23 @@ unsigned int csum_partial_copy_generic (
3029  
3030  .align 4
3031  .globl csum_partial_copy_generic
3032 -                               
3033 +.globl csum_partial_copy_generic_to_user
3034 +.globl csum_partial_copy_generic_from_user
3035 +
3036  #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
3037  
3038  #define ARGBASE 16             
3039  #define FP             12
3040 -               
3041 +
3042 +csum_partial_copy_generic_to_user:
3043 +       pushl $(__USER_DS)
3044 +       popl %es
3045 +       jmp csum_partial_copy_generic
3046 +
3047 +csum_partial_copy_generic_from_user:
3048 +       pushl $(__USER_DS)
3049 +       popl %ds
3050 +
3051  csum_partial_copy_generic:
3052         subl  $4,%esp   
3053         pushl %edi
3054 @@ -305,7 +317,7 @@ csum_partial_copy_generic:
3055         jmp 4f
3056  SRC(1: movw (%esi), %bx        )
3057         addl $2, %esi
3058 -DST(   movw %bx, (%edi)        )
3059 +DST(   movw %bx, %es:(%edi)    )
3060         addl $2, %edi
3061         addw %bx, %ax   
3062         adcl $0, %eax
3063 @@ -317,30 +329,30 @@ DST(      movw %bx, (%edi)        )
3064  SRC(1: movl (%esi), %ebx       )
3065  SRC(   movl 4(%esi), %edx      )
3066         adcl %ebx, %eax
3067 -DST(   movl %ebx, (%edi)       )
3068 +DST(   movl %ebx, %es:(%edi)   )
3069         adcl %edx, %eax
3070 -DST(   movl %edx, 4(%edi)      )
3071 +DST(   movl %edx, %es:4(%edi)  )
3072  
3073  SRC(   movl 8(%esi), %ebx      )
3074  SRC(   movl 12(%esi), %edx     )
3075         adcl %ebx, %eax
3076 -DST(   movl %ebx, 8(%edi)      )
3077 +DST(   movl %ebx, %es:8(%edi)  )
3078         adcl %edx, %eax
3079 -DST(   movl %edx, 12(%edi)     )
3080 +DST(   movl %edx, %es:12(%edi) )
3081  
3082  SRC(   movl 16(%esi), %ebx     )
3083  SRC(   movl 20(%esi), %edx     )
3084         adcl %ebx, %eax
3085 -DST(   movl %ebx, 16(%edi)     )
3086 +DST(   movl %ebx, %es:16(%edi) )
3087         adcl %edx, %eax
3088 -DST(   movl %edx, 20(%edi)     )
3089 +DST(   movl %edx, %es:20(%edi) )
3090  
3091  SRC(   movl 24(%esi), %ebx     )
3092  SRC(   movl 28(%esi), %edx     )
3093         adcl %ebx, %eax
3094 -DST(   movl %ebx, 24(%edi)     )
3095 +DST(   movl %ebx, %es:24(%edi) )
3096         adcl %edx, %eax
3097 -DST(   movl %edx, 28(%edi)     )
3098 +DST(   movl %edx, %es:28(%edi) )
3099  
3100         lea 32(%esi), %esi
3101         lea 32(%edi), %edi
3102 @@ -354,7 +366,7 @@ DST(        movl %edx, 28(%edi)     )
3103         shrl $2, %edx                   # This clears CF
3104  SRC(3: movl (%esi), %ebx       )
3105         adcl %ebx, %eax
3106 -DST(   movl %ebx, (%edi)       )
3107 +DST(   movl %ebx, %es:(%edi)   )
3108         lea 4(%esi), %esi
3109         lea 4(%edi), %edi
3110         dec %edx
3111 @@ -366,12 +378,12 @@ DST(      movl %ebx, (%edi)       )
3112         jb 5f
3113  SRC(   movw (%esi), %cx        )
3114         leal 2(%esi), %esi
3115 -DST(   movw %cx, (%edi)        )
3116 +DST(   movw %cx, %es:(%edi)    )
3117         leal 2(%edi), %edi
3118         je 6f
3119         shll $16,%ecx
3120  SRC(5: movb (%esi), %cl        )
3121 -DST(   movb %cl, (%edi)        )
3122 +DST(   movb %cl, %es:(%edi)    )
3123  6:     addl %ecx, %eax
3124         adcl $0, %eax
3125  7:
3126 @@ -382,7 +394,7 @@ DST(        movb %cl, (%edi)        )
3127  
3128  6001:
3129         movl ARGBASE+20(%esp), %ebx     # src_err_ptr
3130 -       movl $-EFAULT, (%ebx)
3131 +       movl $-EFAULT, %ss:(%ebx)
3132  
3133         # zero the complete destination - computing the rest
3134         # is too much work 
3135 @@ -395,11 +407,15 @@ DST(      movb %cl, (%edi)        )
3136  
3137  6002:
3138         movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
3139 -       movl $-EFAULT,(%ebx)
3140 +       movl $-EFAULT,%ss:(%ebx)
3141         jmp 5000b
3142  
3143  .previous
3144  
3145 +       pushl %ss
3146 +       popl %ds
3147 +       pushl %ss
3148 +       popl %es
3149         popl %ebx
3150         popl %esi
3151         popl %edi
3152 @@ -411,17 +427,28 @@ DST(      movb %cl, (%edi)        )
3153  /* Version for PentiumII/PPro */
3154  
3155  #define ROUND1(x) \
3156 +       nop; nop; nop;                          \
3157         SRC(movl x(%esi), %ebx  )       ;       \
3158         addl %ebx, %eax                 ;       \
3159 -       DST(movl %ebx, x(%edi)  )       ; 
3160 +       DST(movl %ebx, %es:x(%edi));
3161  
3162  #define ROUND(x) \
3163 +       nop; nop; nop;                          \
3164         SRC(movl x(%esi), %ebx  )       ;       \
3165         adcl %ebx, %eax                 ;       \
3166 -       DST(movl %ebx, x(%edi)  )       ;
3167 +       DST(movl %ebx, %es:x(%edi));
3168  
3169  #define ARGBASE 12
3170 -               
3171 +
3172 +csum_partial_copy_generic_to_user:
3173 +       pushl $(__USER_DS)
3174 +       popl %es
3175 +       jmp csum_partial_copy_generic
3176 +
3177 +csum_partial_copy_generic_from_user:
3178 +       pushl $(__USER_DS)
3179 +       popl %ds
3180 +
3181  csum_partial_copy_generic:
3182         pushl %ebx
3183         pushl %edi
3184 @@ -440,7 +467,7 @@ csum_partial_copy_generic:
3185         subl %ebx, %edi  
3186         lea  -1(%esi),%edx
3187         andl $-32,%edx
3188 -       lea 3f(%ebx,%ebx), %ebx
3189 +       lea 3f(%ebx,%ebx,2), %ebx
3190         testl %esi, %esi 
3191         jmp *%ebx
3192  1:     addl $64,%esi
3193 @@ -461,19 +488,19 @@ csum_partial_copy_generic:
3194         jb 5f
3195  SRC(   movw (%esi), %dx         )
3196         leal 2(%esi), %esi
3197 -DST(   movw %dx, (%edi)         )
3198 +DST(   movw %dx, %es:(%edi)     )
3199         leal 2(%edi), %edi
3200         je 6f
3201         shll $16,%edx
3202  5:
3203  SRC(   movb (%esi), %dl         )
3204 -DST(   movb %dl, (%edi)         )
3205 +DST(   movb %dl, %es:(%edi)     )
3206  6:     addl %edx, %eax
3207         adcl $0, %eax
3208  7:
3209  .section .fixup, "ax"
3210  6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
3211 -       movl $-EFAULT, (%ebx)
3212 +       movl $-EFAULT, %ss:(%ebx)
3213         # zero the complete destination (computing the rest is too much work)
3214         movl ARGBASE+8(%esp),%edi       # dst
3215         movl ARGBASE+12(%esp),%ecx      # len
3216 @@ -481,10 +508,14 @@ DST(      movb %dl, (%edi)         )
3217         rep; stosb
3218         jmp 7b
3219  6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
3220 -       movl $-EFAULT, (%ebx)
3221 +       movl $-EFAULT, %ss:(%ebx)
3222         jmp  7b                 
3223  .previous                              
3224  
3225 +       pushl %ss
3226 +       popl %ds
3227 +       pushl %ss
3228 +       popl %es
3229         popl %esi
3230         popl %edi
3231         popl %ebx
3232 diff -urNp linux-2.6.17.11/arch/i386/lib/getuser.S linux-2.6.17.11/arch/i386/lib/getuser.S
3233 --- linux-2.6.17.11/arch/i386/lib/getuser.S     2006-08-07 00:18:54.000000000 -0400
3234 +++ linux-2.6.17.11/arch/i386/lib/getuser.S     2006-09-01 16:20:28.000000000 -0400
3235 @@ -9,6 +9,7 @@
3236   * return value.
3237   */
3238  #include <asm/thread_info.h>
3239 +#include <asm/segment.h>
3240  
3241  
3242  /*
3243 @@ -30,8 +31,12 @@ __get_user_1:
3244         GET_THREAD_INFO(%edx)
3245         cmpl TI_addr_limit(%edx),%eax
3246         jae bad_get_user
3247 +       pushl $(__USER_DS)
3248 +       popl %ds
3249  1:     movzbl (%eax),%edx
3250         xorl %eax,%eax
3251 +       pushl %ss
3252 +       pop %ds
3253         ret
3254  
3255  .align 4
3256 @@ -42,7 +47,11 @@ __get_user_2:
3257         GET_THREAD_INFO(%edx)
3258         cmpl TI_addr_limit(%edx),%eax
3259         jae bad_get_user
3260 +       pushl $(__USER_DS)
3261 +       popl %ds
3262  2:     movzwl -1(%eax),%edx
3263 +       pushl %ss
3264 +       pop %ds
3265         xorl %eax,%eax
3266         ret
3267  
3268 @@ -54,11 +63,17 @@ __get_user_4:
3269         GET_THREAD_INFO(%edx)
3270         cmpl TI_addr_limit(%edx),%eax
3271         jae bad_get_user
3272 +       pushl $(__USER_DS)
3273 +       popl %ds
3274  3:     movl -3(%eax),%edx
3275 +       pushl %ss
3276 +       pop %ds
3277         xorl %eax,%eax
3278         ret
3279  
3280  bad_get_user:
3281 +       pushl %ss
3282 +       pop %ds
3283         xorl %edx,%edx
3284         movl $-14,%eax
3285         ret
3286 diff -urNp linux-2.6.17.11/arch/i386/lib/mmx.c linux-2.6.17.11/arch/i386/lib/mmx.c
3287 --- linux-2.6.17.11/arch/i386/lib/mmx.c 2006-08-07 00:18:54.000000000 -0400
3288 +++ linux-2.6.17.11/arch/i386/lib/mmx.c 2006-09-01 16:20:28.000000000 -0400
3289 @@ -48,14 +48,30 @@ void *_mmx_memcpy(void *to, const void *
3290                 "   prefetch 256(%0)\n"
3291                 "2:  \n"
3292                 ".section .fixup, \"ax\"\n"
3293 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3294 +               "3:  \n"
3295 +
3296 +#ifdef CONFIG_PAX_KERNEXEC
3297 +               "   cli\n"
3298 +               "   movl %%cr0, %%eax\n"
3299 +               "   andl $0xFFFEFFFF, %%eax\n"
3300 +               "   movl %%eax, %%cr0\n"
3301 +#endif
3302 +
3303 +               " movw $0x1AEB, 1b\n"   /* jmp on 26 bytes */
3304 +
3305 +#ifdef CONFIG_PAX_KERNEXEC
3306 +               "   orl $0x00010000, %%eax\n"
3307 +               "   movl %%eax, %%cr0\n"
3308 +               "   sti\n"
3309 +#endif
3310 +
3311                 "   jmp 2b\n"
3312                 ".previous\n"
3313                 ".section __ex_table,\"a\"\n"
3314                 "       .align 4\n"
3315                 "       .long 1b, 3b\n"
3316                 ".previous"
3317 -               : : "r" (from) );
3318 +               : : "r" (from) : "ax");
3319                 
3320         
3321         for(; i>5; i--)
3322 @@ -79,14 +95,30 @@ void *_mmx_memcpy(void *to, const void *
3323                 "  movq %%mm2, 48(%1)\n"
3324                 "  movq %%mm3, 56(%1)\n"
3325                 ".section .fixup, \"ax\"\n"
3326 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3327 +               "3:\n"
3328 +
3329 +#ifdef CONFIG_PAX_KERNEXEC
3330 +               "  cli\n"
3331 +               "  movl %%cr0, %%eax\n"
3332 +               "  andl $0xFFFEFFFF, %%eax\n"
3333 +               "  movl %%eax, %%cr0\n"
3334 +#endif
3335 +
3336 +               "  movw $0x05EB, 1b\n"  /* jmp on 5 bytes */
3337 +
3338 +#ifdef CONFIG_PAX_KERNEXEC
3339 +               "  orl $0x00010000, %%eax\n"
3340 +               "  movl %%eax, %%cr0\n"
3341 +               "  sti\n"
3342 +#endif
3343 +
3344                 "   jmp 2b\n"
3345                 ".previous\n"
3346                 ".section __ex_table,\"a\"\n"
3347                 "       .align 4\n"
3348                 "       .long 1b, 3b\n"
3349                 ".previous"
3350 -               : : "r" (from), "r" (to) : "memory");
3351 +               : : "r" (from), "r" (to) : "memory", "ax");
3352                 from+=64;
3353                 to+=64;
3354         }
3355 @@ -179,14 +211,30 @@ static void fast_copy_page(void *to, voi
3356                 "   prefetch 256(%0)\n"
3357                 "2:  \n"
3358                 ".section .fixup, \"ax\"\n"
3359 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3360 +               "3:  \n"
3361 +
3362 +#ifdef CONFIG_PAX_KERNEXEC
3363 +               "   cli\n"
3364 +               "   movl %%cr0, %%eax\n"
3365 +               "   andl $0xFFFEFFFF, %%eax\n"
3366 +               "   movl %%eax, %%cr0\n"
3367 +#endif
3368 +
3369 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3370 +
3371 +#ifdef CONFIG_PAX_KERNEXEC
3372 +               "   orl $0x00010000, %%eax\n"
3373 +               "   movl %%eax, %%cr0\n"
3374 +               "   sti\n"
3375 +#endif
3376 +
3377                 "   jmp 2b\n"
3378                 ".previous\n"
3379                 ".section __ex_table,\"a\"\n"
3380                 "       .align 4\n"
3381                 "       .long 1b, 3b\n"
3382                 ".previous"
3383 -               : : "r" (from) );
3384 +               : : "r" (from) : "ax");
3385  
3386         for(i=0; i<(4096-320)/64; i++)
3387         {
3388 @@ -209,14 +257,30 @@ static void fast_copy_page(void *to, voi
3389                 "   movq 56(%0), %%mm7\n"
3390                 "   movntq %%mm7, 56(%1)\n"
3391                 ".section .fixup, \"ax\"\n"
3392 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3393 +               "3:\n"
3394 +
3395 +#ifdef CONFIG_PAX_KERNEXEC
3396 +               "   cli\n"
3397 +               "   movl %%cr0, %%eax\n"
3398 +               "   andl $0xFFFEFFFF, %%eax\n"
3399 +               "   movl %%eax, %%cr0\n"
3400 +#endif
3401 +
3402 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3403 +
3404 +#ifdef CONFIG_PAX_KERNEXEC
3405 +               "   orl $0x00010000, %%eax\n"
3406 +               "   movl %%eax, %%cr0\n"
3407 +               "   sti\n"
3408 +#endif
3409 +
3410                 "   jmp 2b\n"
3411                 ".previous\n"
3412                 ".section __ex_table,\"a\"\n"
3413                 "       .align 4\n"
3414                 "       .long 1b, 3b\n"
3415                 ".previous"
3416 -               : : "r" (from), "r" (to) : "memory");
3417 +               : : "r" (from), "r" (to) : "memory", "ax");
3418                 from+=64;
3419                 to+=64;
3420         }
3421 @@ -309,14 +373,30 @@ static void fast_copy_page(void *to, voi
3422                 "   prefetch 256(%0)\n"
3423                 "2:  \n"
3424                 ".section .fixup, \"ax\"\n"
3425 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3426 +               "3:  \n"
3427 +
3428 +#ifdef CONFIG_PAX_KERNEXEC
3429 +               "   cli\n"
3430 +               "   movl %%cr0, %%eax\n"
3431 +               "   andl $0xFFFEFFFF, %%eax\n"
3432 +               "   movl %%eax, %%cr0\n"
3433 +#endif
3434 +
3435 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3436 +
3437 +#ifdef CONFIG_PAX_KERNEXEC
3438 +               "   orl $0x00010000, %%eax\n"
3439 +               "   movl %%eax, %%cr0\n"
3440 +               "   sti\n"
3441 +#endif
3442 +
3443                 "   jmp 2b\n"
3444                 ".previous\n"
3445                 ".section __ex_table,\"a\"\n"
3446                 "       .align 4\n"
3447                 "       .long 1b, 3b\n"
3448                 ".previous"
3449 -               : : "r" (from) );
3450 +               : : "r" (from) : "ax");
3451  
3452         for(i=0; i<4096/64; i++)
3453         {
3454 @@ -339,14 +419,30 @@ static void fast_copy_page(void *to, voi
3455                 "   movq %%mm2, 48(%1)\n"
3456                 "   movq %%mm3, 56(%1)\n"
3457                 ".section .fixup, \"ax\"\n"
3458 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3459 +               "3:\n"
3460 +
3461 +#ifdef CONFIG_PAX_KERNEXEC
3462 +               "   cli\n"
3463 +               "   movl %%cr0, %%eax\n"
3464 +               "   andl $0xFFFEFFFF, %%eax\n"
3465 +               "   movl %%eax, %%cr0\n"
3466 +#endif
3467 +
3468 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3469 +
3470 +#ifdef CONFIG_PAX_KERNEXEC
3471 +               "   orl $0x00010000, %%eax\n"
3472 +               "   movl %%eax, %%cr0\n"
3473 +               "   sti\n"
3474 +#endif
3475 +
3476                 "   jmp 2b\n"
3477                 ".previous\n"
3478                 ".section __ex_table,\"a\"\n"
3479                 "       .align 4\n"
3480                 "       .long 1b, 3b\n"
3481                 ".previous"
3482 -               : : "r" (from), "r" (to) : "memory");
3483 +               : : "r" (from), "r" (to) : "memory", "ax");
3484                 from+=64;
3485                 to+=64;
3486         }
3487 diff -urNp linux-2.6.17.11/arch/i386/lib/putuser.S linux-2.6.17.11/arch/i386/lib/putuser.S
3488 --- linux-2.6.17.11/arch/i386/lib/putuser.S     2006-08-07 00:18:54.000000000 -0400
3489 +++ linux-2.6.17.11/arch/i386/lib/putuser.S     2006-09-01 16:20:28.000000000 -0400
3490 @@ -9,6 +9,7 @@
3491   * return value.
3492   */
3493  #include <asm/thread_info.h>
3494 +#include <asm/segment.h>
3495  
3496  
3497  /*
3498 @@ -33,7 +34,11 @@ __put_user_1:
3499         ENTER
3500         cmpl TI_addr_limit(%ebx),%ecx
3501         jae bad_put_user
3502 +       pushl $(__USER_DS)
3503 +       popl %ds
3504  1:     movb %al,(%ecx)
3505 +       pushl %ss
3506 +       popl %ds
3507         xorl %eax,%eax
3508         EXIT
3509  
3510 @@ -45,7 +50,11 @@ __put_user_2:
3511         subl $1,%ebx
3512         cmpl %ebx,%ecx
3513         jae bad_put_user
3514 +       pushl $(__USER_DS)
3515 +       popl %ds
3516  2:     movw %ax,(%ecx)
3517 +       pushl %ss
3518 +       popl %ds
3519         xorl %eax,%eax
3520         EXIT
3521  
3522 @@ -57,7 +66,11 @@ __put_user_4:
3523         subl $3,%ebx
3524         cmpl %ebx,%ecx
3525         jae bad_put_user
3526 +       pushl $(__USER_DS)
3527 +       popl %ds
3528  3:     movl %eax,(%ecx)
3529 +       pushl %ss
3530 +       popl %ds
3531         xorl %eax,%eax
3532         EXIT
3533  
3534 @@ -69,12 +82,18 @@ __put_user_8:
3535         subl $7,%ebx
3536         cmpl %ebx,%ecx
3537         jae bad_put_user
3538 +       pushl $(__USER_DS)
3539 +       popl %ds
3540  4:     movl %eax,(%ecx)
3541  5:     movl %edx,4(%ecx)
3542 +       pushl %ss
3543 +       popl %ds
3544         xorl %eax,%eax
3545         EXIT
3546  
3547  bad_put_user:
3548 +       pushl %ss
3549 +       popl %ds
3550         movl $-14,%eax
3551         EXIT
3552  
3553 diff -urNp linux-2.6.17.11/arch/i386/lib/usercopy.c linux-2.6.17.11/arch/i386/lib/usercopy.c
3554 --- linux-2.6.17.11/arch/i386/lib/usercopy.c    2006-08-07 00:18:54.000000000 -0400
3555 +++ linux-2.6.17.11/arch/i386/lib/usercopy.c    2006-09-01 16:20:28.000000000 -0400
3556 @@ -33,6 +33,7 @@ do {                                                                     \
3557         int __d0, __d1, __d2;                                              \
3558         might_sleep();                                                     \
3559         __asm__ __volatile__(                                              \
3560 +               "       movw %w10,%%ds\n"                                  \
3561                 "       testl %1,%1\n"                                     \
3562                 "       jz 2f\n"                                           \
3563                 "0:     lodsb\n"                                           \
3564 @@ -43,6 +44,8 @@ do {                                                                     \
3565                 "       jnz 0b\n"                                          \
3566                 "1:     subl %1,%0\n"                                      \
3567                 "2:\n"                                                     \
3568 +               "       pushl %%ss\n"                                      \
3569 +               "       popl %%ds\n"                                       \
3570                 ".section .fixup,\"ax\"\n"                                 \
3571                 "3:     movl %5,%0\n"                                      \
3572                 "       jmp 2b\n"                                          \
3573 @@ -53,7 +56,8 @@ do {                                                                     \
3574                 ".previous"                                                \
3575                 : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
3576                   "=&D" (__d2)                                             \
3577 -               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
3578 +               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),\
3579 +                 "r"(__USER_DS)                                           \
3580                 : "memory");                                               \
3581  } while (0)
3582  
3583 @@ -123,10 +127,13 @@ do {                                                                      \
3584         int __d0;                                                       \
3585         might_sleep();                                                  \
3586         __asm__ __volatile__(                                           \
3587 +               "       movw %w6,%%es\n"                                \
3588                 "0:     rep; stosl\n"                                   \
3589                 "       movl %2,%0\n"                                   \
3590                 "1:     rep; stosb\n"                                   \
3591                 "2:\n"                                                  \
3592 +               "       pushl %%ss\n"                                   \
3593 +               "       popl %%es\n"                                    \
3594                 ".section .fixup,\"ax\"\n"                              \
3595                 "3:     lea 0(%2,%0,4),%0\n"                            \
3596                 "       jmp 2b\n"                                       \
3597 @@ -137,7 +144,8 @@ do {                                                                        \
3598                 "       .long 1b,2b\n"                                  \
3599                 ".previous"                                             \
3600                 : "=&c"(size), "=&D" (__d0)                             \
3601 -               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
3602 +               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),      \
3603 +                 "r"(__USER_DS));                                      \
3604  } while (0)
3605  
3606  /**
3607 @@ -198,14 +206,17 @@ long strnlen_user(const char __user *s, 
3608         might_sleep();
3609  
3610         __asm__ __volatile__(
3611 +               "       movw %w8,%%es\n"
3612                 "       testl %0, %0\n"
3613                 "       jz 3f\n"
3614 -               "       andl %0,%%ecx\n"
3615 +               "       movl %0,%%ecx\n"
3616                 "0:     repne; scasb\n"
3617                 "       setne %%al\n"
3618                 "       subl %%ecx,%0\n"
3619                 "       addl %0,%%eax\n"
3620                 "1:\n"
3621 +               "       pushl %%ss\n"
3622 +               "       popl %%es\n"
3623                 ".section .fixup,\"ax\"\n"
3624                 "2:     xorl %%eax,%%eax\n"
3625                 "       jmp 1b\n"
3626 @@ -217,7 +228,7 @@ long strnlen_user(const char __user *s, 
3627                 "       .long 0b,2b\n"
3628                 ".previous"
3629                 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
3630 -               :"0" (n), "1" (s), "2" (0), "3" (mask)
3631 +               :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
3632                 :"cc");
3633         return res & mask;
3634  }
3635 @@ -229,6 +240,7 @@ __copy_user_intel(void __user *to, const
3636  {
3637         int d0, d1;
3638         __asm__ __volatile__(
3639 +                      "       movw %w6, %%es\n"
3640                        "       .align 2,0x90\n"
3641                        "1:     movl 32(%4), %%eax\n"
3642                        "       cmpl $67, %0\n"
3643 @@ -237,36 +249,36 @@ __copy_user_intel(void __user *to, const
3644                        "       .align 2,0x90\n"
3645                        "3:     movl 0(%4), %%eax\n"
3646                        "4:     movl 4(%4), %%edx\n"
3647 -                      "5:     movl %%eax, 0(%3)\n"
3648 -                      "6:     movl %%edx, 4(%3)\n"
3649 +                      "5:     movl %%eax, %%es:0(%3)\n"
3650 +                      "6:     movl %%edx, %%es:4(%3)\n"
3651                        "7:     movl 8(%4), %%eax\n"
3652                        "8:     movl 12(%4),%%edx\n"
3653 -                      "9:     movl %%eax, 8(%3)\n"
3654 -                      "10:    movl %%edx, 12(%3)\n"
3655 +                      "9:     movl %%eax, %%es:8(%3)\n"
3656 +                      "10:    movl %%edx, %%es:12(%3)\n"
3657                        "11:    movl 16(%4), %%eax\n"
3658                        "12:    movl 20(%4), %%edx\n"
3659 -                      "13:    movl %%eax, 16(%3)\n"
3660 -                      "14:    movl %%edx, 20(%3)\n"
3661 +                      "13:    movl %%eax, %%es:16(%3)\n"
3662 +                      "14:    movl %%edx, %%es:20(%3)\n"
3663                        "15:    movl 24(%4), %%eax\n"
3664                        "16:    movl 28(%4), %%edx\n"
3665 -                      "17:    movl %%eax, 24(%3)\n"
3666 -                      "18:    movl %%edx, 28(%3)\n"
3667 +                      "17:    movl %%eax, %%es:24(%3)\n"
3668 +                      "18:    movl %%edx, %%es:28(%3)\n"
3669                        "19:    movl 32(%4), %%eax\n"
3670                        "20:    movl 36(%4), %%edx\n"
3671 -                      "21:    movl %%eax, 32(%3)\n"
3672 -                      "22:    movl %%edx, 36(%3)\n"
3673 +                      "21:    movl %%eax, %%es:32(%3)\n"
3674 +                      "22:    movl %%edx, %%es:36(%3)\n"
3675                        "23:    movl 40(%4), %%eax\n"
3676                        "24:    movl 44(%4), %%edx\n"
3677 -                      "25:    movl %%eax, 40(%3)\n"
3678 -                      "26:    movl %%edx, 44(%3)\n"
3679 +                      "25:    movl %%eax, %%es:40(%3)\n"
3680 +                      "26:    movl %%edx, %%es:44(%3)\n"
3681                        "27:    movl 48(%4), %%eax\n"
3682                        "28:    movl 52(%4), %%edx\n"
3683 -                      "29:    movl %%eax, 48(%3)\n"
3684 -                      "30:    movl %%edx, 52(%3)\n"
3685 +                      "29:    movl %%eax, %%es:48(%3)\n"
3686 +                      "30:    movl %%edx, %%es:52(%3)\n"
3687                        "31:    movl 56(%4), %%eax\n"
3688                        "32:    movl 60(%4), %%edx\n"
3689 -                      "33:    movl %%eax, 56(%3)\n"
3690 -                      "34:    movl %%edx, 60(%3)\n"
3691 +                      "33:    movl %%eax, %%es:56(%3)\n"
3692 +                      "34:    movl %%edx, %%es:60(%3)\n"
3693                        "       addl $-64, %0\n"
3694                        "       addl $64, %4\n"
3695                        "       addl $64, %3\n"
3696 @@ -280,6 +292,8 @@ __copy_user_intel(void __user *to, const
3697                        "36:    movl %%eax, %0\n"
3698                        "37:    rep; movsb\n"
3699                        "100:\n"
3700 +                      "       pushl %%ss\n"
3701 +                      "       popl %%es\n"
3702                        ".section .fixup,\"ax\"\n"
3703                        "101:   lea 0(%%eax,%0,4),%0\n"
3704                        "       jmp 100b\n"
3705 @@ -326,7 +340,7 @@ __copy_user_intel(void __user *to, const
3706                        "       .long 99b,101b\n"
3707                        ".previous"
3708                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
3709 -                      :  "1"(to), "2"(from), "0"(size)
3710 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3711                        : "eax", "edx", "memory");
3712         return size;
3713  }
3714 @@ -336,6 +350,7 @@ __copy_user_zeroing_intel(void *to, cons
3715  {
3716         int d0, d1;
3717         __asm__ __volatile__(
3718 +                      "        movw %w6, %%ds\n"
3719                        "        .align 2,0x90\n"
3720                        "0:      movl 32(%4), %%eax\n"
3721                        "        cmpl $67, %0\n"      
3722 @@ -344,36 +359,36 @@ __copy_user_zeroing_intel(void *to, cons
3723                        "        .align 2,0x90\n"     
3724                        "2:      movl 0(%4), %%eax\n" 
3725                        "21:     movl 4(%4), %%edx\n" 
3726 -                      "        movl %%eax, 0(%3)\n" 
3727 -                      "        movl %%edx, 4(%3)\n" 
3728 +                      "        movl %%eax, %%es:0(%3)\n" 
3729 +                      "        movl %%edx, %%es:4(%3)\n" 
3730                        "3:      movl 8(%4), %%eax\n" 
3731                        "31:     movl 12(%4),%%edx\n" 
3732 -                      "        movl %%eax, 8(%3)\n" 
3733 -                      "        movl %%edx, 12(%3)\n"
3734 +                      "        movl %%eax, %%es:8(%3)\n" 
3735 +                      "        movl %%edx, %%es:12(%3)\n"
3736                        "4:      movl 16(%4), %%eax\n"
3737                        "41:     movl 20(%4), %%edx\n"
3738 -                      "        movl %%eax, 16(%3)\n"
3739 -                      "        movl %%edx, 20(%3)\n"
3740 +                      "        movl %%eax, %%es:16(%3)\n"
3741 +                      "        movl %%edx, %%es:20(%3)\n"
3742                        "10:     movl 24(%4), %%eax\n"
3743                        "51:     movl 28(%4), %%edx\n"
3744 -                      "        movl %%eax, 24(%3)\n"
3745 -                      "        movl %%edx, 28(%3)\n"
3746 +                      "        movl %%eax, %%es:24(%3)\n"
3747 +                      "        movl %%edx, %%es:28(%3)\n"
3748                        "11:     movl 32(%4), %%eax\n"
3749                        "61:     movl 36(%4), %%edx\n"
3750 -                      "        movl %%eax, 32(%3)\n"
3751 -                      "        movl %%edx, 36(%3)\n"
3752 +                      "        movl %%eax, %%es:32(%3)\n"
3753 +                      "        movl %%edx, %%es:36(%3)\n"
3754                        "12:     movl 40(%4), %%eax\n"
3755                        "71:     movl 44(%4), %%edx\n"
3756 -                      "        movl %%eax, 40(%3)\n"
3757 -                      "        movl %%edx, 44(%3)\n"
3758 +                      "        movl %%eax, %%es:40(%3)\n"
3759 +                      "        movl %%edx, %%es:44(%3)\n"
3760                        "13:     movl 48(%4), %%eax\n"
3761                        "81:     movl 52(%4), %%edx\n"
3762 -                      "        movl %%eax, 48(%3)\n"
3763 -                      "        movl %%edx, 52(%3)\n"
3764 +                      "        movl %%eax, %%es:48(%3)\n"
3765 +                      "        movl %%edx, %%es:52(%3)\n"
3766                        "14:     movl 56(%4), %%eax\n"
3767                        "91:     movl 60(%4), %%edx\n"
3768 -                      "        movl %%eax, 56(%3)\n"
3769 -                      "        movl %%edx, 60(%3)\n"
3770 +                      "        movl %%eax, %%es:56(%3)\n"
3771 +                      "        movl %%edx, %%es:60(%3)\n"
3772                        "        addl $-64, %0\n"     
3773                        "        addl $64, %4\n"      
3774                        "        addl $64, %3\n"      
3775 @@ -387,6 +402,8 @@ __copy_user_zeroing_intel(void *to, cons
3776                        "        movl %%eax,%0\n"
3777                        "7:      rep; movsb\n"   
3778                        "8:\n"                   
3779 +                      "        pushl %%ss\n"
3780 +                      "        popl %%ds\n"
3781                        ".section .fixup,\"ax\"\n"
3782                        "9:      lea 0(%%eax,%0,4),%0\n" 
3783                        "16:     pushl %0\n"     
3784 @@ -421,7 +438,7 @@ __copy_user_zeroing_intel(void *to, cons
3785                        "        .long 7b,16b\n" 
3786                        ".previous"              
3787                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
3788 -                      :  "1"(to), "2"(from), "0"(size)
3789 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3790                        : "eax", "edx", "memory");
3791         return size;
3792  }
3793 @@ -441,6 +458,7 @@ __copy_user_intel(void __user *to, const
3794  do {                                                                   \
3795         int __d0, __d1, __d2;                                           \
3796         __asm__ __volatile__(                                           \
3797 +               "       movw %w8,%%es\n"                                \
3798                 "       cmp  $7,%0\n"                                   \
3799                 "       jbe  1f\n"                                      \
3800                 "       movl %1,%0\n"                                   \
3801 @@ -456,6 +474,8 @@ do {                                                                        \
3802                 "       movl %3,%0\n"                                   \
3803                 "1:     rep; movsb\n"                                   \
3804                 "2:\n"                                                  \
3805 +               "       pushl %%ss\n"                                   \
3806 +               "       popl %%es\n"                                    \
3807                 ".section .fixup,\"ax\"\n"                              \
3808                 "5:     addl %3,%0\n"                                   \
3809                 "       jmp 2b\n"                                       \
3810 @@ -469,7 +489,7 @@ do {                                                                        \
3811                 "       .long 1b,2b\n"                                  \
3812                 ".previous"                                             \
3813                 : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
3814 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
3815 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)\
3816                 : "memory");                                            \
3817  } while (0)
3818  
3819 @@ -477,6 +497,7 @@ do {                                                                        \
3820  do {                                                                   \
3821         int __d0, __d1, __d2;                                           \
3822         __asm__ __volatile__(                                           \
3823 +               "       movw %w8,%%ds\n"                                \
3824                 "       cmp  $7,%0\n"                                   \
3825                 "       jbe  1f\n"                                      \
3826                 "       movl %1,%0\n"                                   \
3827 @@ -492,6 +513,8 @@ do {                                                                        \
3828                 "       movl %3,%0\n"                                   \
3829                 "1:     rep; movsb\n"                                   \
3830                 "2:\n"                                                  \
3831 +               "       pushl %%ss\n"                                   \
3832 +               "       popl %%ds\n"                                    \
3833                 ".section .fixup,\"ax\"\n"                              \
3834                 "5:     addl %3,%0\n"                                   \
3835                 "       jmp 6f\n"                                       \
3836 @@ -511,7 +534,7 @@ do {                                                                        \
3837                 "       .long 1b,6b\n"                                  \
3838                 ".previous"                                             \
3839                 : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
3840 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
3841 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)\
3842                 : "memory");                                            \
3843  } while (0)
3844  
3845 @@ -640,3 +663,45 @@ copy_from_user(void *to, const void __us
3846         return n;
3847  }
3848  EXPORT_SYMBOL(copy_from_user);
3849 +
3850 +#ifdef CONFIG_PAX_MEMORY_UDEREF
3851 +void __set_fs(mm_segment_t x, int cpu)
3852 +{
3853 +       unsigned long limit = x.seg;
3854 +
3855 +       current_thread_info()->addr_limit = x;
3856 +       if (likely(limit)) {
3857 +               limit -= 1UL;
3858 +               limit >>= 12;
3859 +       }
3860 +
3861 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].a = (limit & 0xFFFFUL);
3862 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].b = (limit & 0xF0000UL) | 0xC0F300UL;
3863 +}
3864 +
3865 +void set_fs(mm_segment_t x)
3866 +{
3867 +       int cpu = get_cpu();
3868 +
3869 +#ifdef CONFIG_PAX_KERNEXEC
3870 +       unsigned long cr0;
3871 +
3872 +       pax_open_kernel(cr0);
3873 +#endif
3874 +
3875 +       __set_fs(x, cpu);
3876 +
3877 +#ifdef CONFIG_PAX_KERNEXEC
3878 +       pax_close_kernel(cr0);
3879 +#endif
3880 +
3881 +       put_cpu_no_resched();
3882 +}
3883 +#else
3884 +void set_fs(mm_segment_t x)
3885 +{
3886 +       current_thread_info()->addr_limit = x;
3887 +}
3888 +#endif
3889 +
3890 +EXPORT_SYMBOL(set_fs);
3891 diff -urNp linux-2.6.17.11/arch/i386/mach-voyager/voyager_smp.c linux-2.6.17.11/arch/i386/mach-voyager/voyager_smp.c
3892 --- linux-2.6.17.11/arch/i386/mach-voyager/voyager_smp.c        2006-08-07 00:18:54.000000000 -0400
3893 +++ linux-2.6.17.11/arch/i386/mach-voyager/voyager_smp.c        2006-09-01 16:20:28.000000000 -0400
3894 @@ -1295,7 +1295,7 @@ smp_local_timer_interrupt(struct pt_regs
3895                                                 per_cpu(prof_counter, cpu);
3896                 }
3897  
3898 -               update_process_times(user_mode_vm(regs));
3899 +               update_process_times(user_mode(regs));
3900         }
3901  
3902         if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
3903 diff -urNp linux-2.6.17.11/arch/i386/mm/boot_ioremap.c linux-2.6.17.11/arch/i386/mm/boot_ioremap.c
3904 --- linux-2.6.17.11/arch/i386/mm/boot_ioremap.c 2006-08-07 00:18:54.000000000 -0400
3905 +++ linux-2.6.17.11/arch/i386/mm/boot_ioremap.c 2006-09-01 16:20:28.000000000 -0400
3906 @@ -8,53 +8,37 @@
3907   */
3908  
3909  
3910 -/*
3911 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
3912 - * keeps that from happenning.  If anyone has a better way, I'm listening.
3913 - *
3914 - * boot_pte_t is defined only if this all works correctly
3915 - */
3916 -
3917  #include <linux/config.h>
3918 -#undef CONFIG_X86_PAE
3919  #include <asm/page.h>
3920  #include <asm/pgtable.h>
3921  #include <asm/tlbflush.h>
3922  #include <linux/init.h>
3923  #include <linux/stddef.h>
3924  
3925 -/* 
3926 - * I'm cheating here.  It is known that the two boot PTE pages are 
3927 - * allocated next to each other.  I'm pretending that they're just
3928 - * one big array. 
3929 - */
3930 -
3931 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
3932 -#define boot_pte_index(address) \
3933 -            (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
3934 -
3935 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
3936 -{
3937 -       boot_pte_t* boot_pg = (boot_pte_t*)pg0;
3938 -       return &boot_pg[boot_pte_index((unsigned long)address)];
3939 -}
3940  
3941  /*
3942   * This is only for a caller who is clever enough to page-align
3943   * phys_addr and virtual_source, and who also has a preference
3944   * about which virtual address from which to steal ptes
3945   */
3946 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
3947 -                   void* virtual_source)
3948 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned int nrpages,
3949 +                   char* virtual_source)
3950  {
3951 -       boot_pte_t* pte;
3952 -       int i;
3953 -       char *vaddr = virtual_source;
3954 +       pgd_t *pgd;
3955 +       pud_t *pud;
3956 +       pmd_t *pmd;
3957 +       pte_t* pte;
3958 +       unsigned int i;
3959 +       unsigned long vaddr = (unsigned long)virtual_source;
3960 +
3961 +       pgd = pgd_offset_k(vaddr);
3962 +       pud = pud_offset(pgd, vaddr);
3963 +       pmd = pmd_offset(pud, vaddr);
3964 +       pte = pte_offset_kernel(pmd, vaddr);
3965  
3966 -       pte = boot_vaddr_to_pte(virtual_source);
3967         for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
3968                 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
3969 -               __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
3970 +               __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
3971         }
3972  }
3973  
3974 diff -urNp linux-2.6.17.11/arch/i386/mm/extable.c linux-2.6.17.11/arch/i386/mm/extable.c
3975 --- linux-2.6.17.11/arch/i386/mm/extable.c      2006-08-07 00:18:54.000000000 -0400
3976 +++ linux-2.6.17.11/arch/i386/mm/extable.c      2006-09-01 16:20:28.000000000 -0400
3977 @@ -12,7 +12,7 @@ int fixup_exception(struct pt_regs *regs
3978         const struct exception_table_entry *fixup;
3979  
3980  #ifdef CONFIG_PNPBIOS
3981 -       if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
3982 +       if (unlikely(!(regs->eflags & VM_MASK) && ((regs->xcs & 0xFFFCU) == PNP_CS32 || (regs->xcs & 0xFFFCU) == PNP_CS16)))
3983         {
3984                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
3985                 extern u32 pnp_bios_is_utter_crap;
3986 diff -urNp linux-2.6.17.11/arch/i386/mm/fault.c linux-2.6.17.11/arch/i386/mm/fault.c
3987 --- linux-2.6.17.11/arch/i386/mm/fault.c        2006-08-07 00:18:54.000000000 -0400
3988 +++ linux-2.6.17.11/arch/i386/mm/fault.c        2006-09-01 16:20:28.000000000 -0400
3989 @@ -22,6 +22,9 @@
3990  #include <linux/highmem.h>
3991  #include <linux/module.h>
3992  #include <linux/kprobes.h>
3993 +#include <linux/unistd.h>
3994 +#include <linux/compiler.h>
3995 +#include <linux/binfmts.h>
3996  
3997  #include <asm/system.h>
3998  #include <asm/uaccess.h>
3999 @@ -82,11 +85,13 @@ static inline unsigned long get_segment_
4000  
4001         /* Unlikely, but must come before segment checks. */
4002         if (unlikely((regs->eflags & VM_MASK) != 0))
4003 -               return eip + (seg << 4);
4004 +               return (eip & 0xFFFF) + (seg << 4);
4005         
4006         /* By far the most common cases. */
4007 -       if (likely(seg == __USER_CS || seg == __KERNEL_CS))
4008 +       if (likely(seg == __USER_CS))
4009                 return eip;
4010 +       if (likely(seg == __KERNEL_CS))
4011 +               return eip + __KERNEL_TEXT_OFFSET;
4012  
4013         /* Check the segment exists, is within the current LDT/GDT size,
4014            that kernel/user (ring 0..3) has the appropriate privilege,
4015 @@ -214,6 +219,30 @@ static noinline void force_sig_info_faul
4016  
4017  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
4018  
4019 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4020 +static int pax_handle_fetch_fault(struct pt_regs *regs);
4021 +#endif
4022 +
4023 +#ifdef CONFIG_PAX_PAGEEXEC
4024 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
4025 +{
4026 +       pgd_t *pgd;
4027 +       pud_t *pud;
4028 +       pmd_t *pmd;
4029 +
4030 +       pgd = pgd_offset(mm, address);
4031 +       if (!pgd_present(*pgd))
4032 +               return NULL;
4033 +       pud = pud_offset(pgd, address);
4034 +       if (!pud_present(*pud))
4035 +               return NULL;
4036 +       pmd = pmd_offset(pud, address);
4037 +       if (!pmd_present(*pmd))
4038 +               return NULL;
4039 +       return pmd;
4040 +}
4041 +#endif
4042 +
4043  static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
4044  {
4045         unsigned index = pgd_index(address);
4046 @@ -295,13 +324,20 @@ fastcall void __kprobes do_page_fault(st
4047         struct mm_struct *mm;
4048         struct vm_area_struct * vma;
4049         unsigned long address;
4050 -       unsigned long page;
4051         int write, si_code;
4052  
4053 +#ifdef CONFIG_PAX_PAGEEXEC
4054 +       pmd_t *pmd;
4055 +       pte_t *pte;
4056 +       spinlock_t *ptl;
4057 +       unsigned char pte_mask;
4058 +#endif
4059 +
4060         /* get the address */
4061          address = read_cr2();
4062  
4063         tsk = current;
4064 +       mm = tsk->mm;
4065  
4066         si_code = SEGV_MAPERR;
4067  
4068 @@ -340,14 +376,12 @@ fastcall void __kprobes do_page_fault(st
4069         if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
4070                 local_irq_enable();
4071  
4072 -       mm = tsk->mm;
4073 -
4074         /*
4075          * If we're in an interrupt, have no user context or are running in an
4076          * atomic region then we must not take the fault..
4077          */
4078         if (in_atomic() || !mm)
4079 -               goto bad_area_nosemaphore;
4080 +               goto bad_area_nopax;
4081  
4082         /* When running in the kernel we expect faults to occur only to
4083          * addresses in user space.  All other faults represent errors in the
4084 @@ -367,10 +401,101 @@ fastcall void __kprobes do_page_fault(st
4085         if (!down_read_trylock(&mm->mmap_sem)) {
4086                 if ((error_code & 4) == 0 &&
4087                     !search_exception_tables(regs->eip))
4088 -                       goto bad_area_nosemaphore;
4089 +                       goto bad_area_nopax;
4090                 down_read(&mm->mmap_sem);
4091         }
4092  
4093 +#ifdef CONFIG_PAX_PAGEEXEC
4094 +       if (unlikely((error_code & 5) != 5 ||
4095 +                    (regs->eflags & X86_EFLAGS_VM) ||
4096 +                    !(mm->pax_flags & MF_PAX_PAGEEXEC)))
4097 +               goto not_pax_fault;
4098 +
4099 +       /* PaX: it's our fault, let's handle it if we can */
4100 +
4101 +       /* PaX: take a look at read faults before acquiring any locks */
4102 +       if (unlikely(!(error_code & 2) && (regs->eip == address))) {
4103 +               /* instruction fetch attempt from a protected page in user mode */
4104 +               up_read(&mm->mmap_sem);
4105 +               switch (pax_handle_fetch_fault(regs)) {
4106 +
4107 +#ifdef CONFIG_PAX_EMUTRAMP
4108 +               case 2:
4109 +                       return;
4110 +#endif
4111 +
4112 +               }
4113 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4114 +               do_exit(SIGKILL);
4115 +       }
4116 +
4117 +       pmd = pax_get_pmd(mm, address);
4118 +       if (unlikely(!pmd))
4119 +               goto not_pax_fault;
4120 +
4121 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
4122 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
4123 +               pte_unmap_unlock(pte, ptl);
4124 +               goto not_pax_fault;
4125 +       }
4126 +
4127 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
4128 +               /* write attempt to a protected page in user mode */
4129 +               pte_unmap_unlock(pte, ptl);
4130 +               goto not_pax_fault;
4131 +       }
4132 +
4133 +#ifdef CONFIG_SMP
4134 +       if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
4135 +#else
4136 +       if (likely(address > get_limit(regs->xcs)))
4137 +#endif
4138 +       {
4139 +               set_pte(pte, pte_mkread(*pte));
4140 +               __flush_tlb_one(address);
4141 +               pte_unmap_unlock(pte, ptl);
4142 +               up_read(&mm->mmap_sem);
4143 +               return;
4144 +       }
4145 +
4146 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
4147 +
4148 +       /*
4149 +        * PaX: fill DTLB with user rights and retry
4150 +        */
4151 +       __asm__ __volatile__ (
4152 +               "movw %w4,%%ds\n"
4153 +               "orb %2,%%ss:(%1)\n"
4154 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
4155 +/*
4156 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
4157 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
4158 + * page fault when examined during a TLB load attempt. this is true not only
4159 + * for PTEs holding a non-present entry but also present entries that will
4160 + * raise a page fault (such as those set up by PaX, or the copy-on-write
4161 + * mechanism). in effect it means that we do *not* need to flush the TLBs
4162 + * for our target pages since their PTEs are simply not in the TLBs at all.
4163 +
4164 + * the best thing in omitting it is that we gain around 15-20% speed in the
4165 + * fast path of the page fault handler and can get rid of tracing since we
4166 + * can no longer flush unintended entries.
4167 + */
4168 +               "invlpg (%0)\n"
4169 +#endif
4170 +               "testb $0,(%0)\n"
4171 +               "xorb %3,%%ss:(%1)\n"
4172 +               "pushl %%ss\n"
4173 +               "popl %%ds\n"
4174 +               :
4175 +               : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
4176 +               : "memory", "cc");
4177 +       pte_unmap_unlock(pte, ptl);
4178 +       up_read(&mm->mmap_sem);
4179 +       return;
4180 +
4181 +not_pax_fault:
4182 +#endif
4183 +
4184         vma = find_vma(mm, address);
4185         if (!vma)
4186                 goto bad_area;
4187 @@ -456,6 +581,37 @@ bad_area:
4188         up_read(&mm->mmap_sem);
4189  
4190  bad_area_nosemaphore:
4191 +
4192 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4193 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
4194 +
4195 +#ifdef CONFIG_PAX_PAGEEXEC
4196 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
4197 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4198 +                       do_exit(SIGKILL);
4199 +               }
4200 +#endif
4201 +
4202 +#ifdef CONFIG_PAX_SEGMEXEC
4203 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
4204 +
4205 +                       switch (pax_handle_fetch_fault(regs)) {
4206 +
4207 +#ifdef CONFIG_PAX_EMUTRAMP
4208 +                       case 2:
4209 +                               return;
4210 +#endif
4211 +
4212 +                       }
4213 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4214 +                       do_exit(SIGKILL);
4215 +               }
4216 +#endif
4217 +
4218 +       }
4219 +#endif
4220 +
4221 +bad_area_nopax:
4222         /* User mode accesses just cause a SIGSEGV */
4223         if (error_code & 4) {
4224                 /* 
4225 @@ -523,6 +679,21 @@ no_context:
4226                 if (address < PAGE_SIZE)
4227                         printk(KERN_ALERT "BUG: unable to handle kernel NULL "
4228                                         "pointer dereference");
4229 +
4230 +#ifdef CONFIG_PAX_KERNEXEC
4231 +#ifdef CONFIG_MODULES
4232 +               else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
4233 +#else
4234 +               else if (init_mm.start_code <= address && address < init_mm.end_code)
4235 +#endif
4236 +                       if (tsk->signal->curr_ip)
4237 +                               printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
4238 +                                        NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
4239 +                       else
4240 +                               printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
4241 +                                        tsk->comm, tsk->pid, tsk->uid, tsk->euid);
4242 +#endif
4243 +
4244                 else
4245                         printk(KERN_ALERT "BUG: unable to handle kernel paging"
4246                                         " request");
4247 @@ -530,24 +701,34 @@ no_context:
4248                 printk(KERN_ALERT " printing eip:\n");
4249                 printk("%08lx\n", regs->eip);
4250         }
4251 -       page = read_cr3();
4252 -       page = ((unsigned long *) __va(page))[address >> 22];
4253 -       if (oops_may_print())
4254 -               printk(KERN_ALERT "*pde = %08lx\n", page);
4255 -       /*
4256 -        * We must not directly access the pte in the highpte
4257 -        * case, the page table might be allocated in highmem.
4258 -        * And lets rather not kmap-atomic the pte, just in case
4259 -        * it's allocated already.
4260 -        */
4261 +
4262 +       if (oops_may_print()) {
4263 +               unsigned long index = pgd_index(address);
4264 +               pgd_t *pgd;
4265 +               pud_t *pud;
4266 +               pmd_t *pmd;
4267 +               pte_t *pte;
4268 +
4269 +               pgd = index + (pgd_t *)__va(read_cr3());
4270 +               printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
4271 +               if (pgd_present(*pgd)) {
4272 +                       pud = pud_offset(pgd, address);
4273 +                       pmd = pmd_offset(pud, address);
4274 +                       printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
4275 +                       /*
4276 +                        * We must not directly access the pte in the highpte
4277 +                        * case, the page table might be allocated in highmem.
4278 +                        * And lets rather not kmap-atomic the pte, just in case
4279 +                        * it's allocated already.
4280 +                        */
4281  #ifndef CONFIG_HIGHPTE
4282 -       if ((page & 1) && oops_may_print()) {
4283 -               page &= PAGE_MASK;
4284 -               address &= 0x003ff000;
4285 -               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
4286 -               printk(KERN_ALERT "*pte = %08lx\n", page);
4287 -       }
4288 +                       if (pmd_present(*pmd) && !pmd_large(*pmd)) {
4289 +                               pte = pte_offset_kernel(pmd, address);
4290 +                               printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
4291 +                       }
4292  #endif
4293 +               }
4294 +       }
4295         tsk->thread.cr2 = address;
4296         tsk->thread.trap_no = 14;
4297         tsk->thread.error_code = error_code;
4298 @@ -624,3 +805,105 @@ void vmalloc_sync_all(void)
4299         }
4300  }
4301  #endif
4302 +
4303 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4304 +/*
4305 + * PaX: decide what to do with offenders (regs->eip = fault address)
4306 + *
4307 + * returns 1 when task should be killed
4308 + *         2 when gcc trampoline was detected
4309 + */
4310 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4311 +{
4312 +
4313 +#ifdef CONFIG_PAX_EMUTRAMP
4314 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
4315 +       int err;
4316 +#endif
4317 +
4318 +       if (regs->eflags & X86_EFLAGS_VM)
4319 +               return 1;
4320 +
4321 +#ifdef CONFIG_PAX_EMUTRAMP
4322 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
4323 +               return 1;
4324 +
4325 +       do { /* PaX: gcc trampoline emulation #1 */
4326 +               unsigned char mov1, mov2;
4327 +               unsigned short jmp;
4328 +               unsigned long addr1, addr2;
4329 +
4330 +               err = get_user(mov1, (unsigned char __user *)regs->eip);
4331 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
4332 +               err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
4333 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
4334 +               err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
4335 +
4336 +               if (err)
4337 +                       break;
4338 +
4339 +               if ((mov1 & 0xF8) == 0xB8 &&
4340 +                   (mov2 & 0xF8) == 0xB8 &&
4341 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
4342 +                   (jmp & 0xF8FF) == 0xE0FF &&
4343 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07))
4344 +               {
4345 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
4346 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
4347 +                       regs->eip = addr2;
4348 +                       return 2;
4349 +               }
4350 +       } while (0);
4351 +
4352 +       do { /* PaX: gcc trampoline emulation #2 */
4353 +               unsigned char mov, jmp;
4354 +               unsigned long addr1, addr2;
4355 +
4356 +               err = get_user(mov, (unsigned char __user *)regs->eip);
4357 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
4358 +               err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
4359 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
4360 +
4361 +               if (err)
4362 +                       break;
4363 +
4364 +               if ((mov & 0xF8) == 0xB8 &&
4365 +                   jmp == 0xE9)
4366 +               {
4367 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
4368 +                       regs->eip += addr2 + 10;
4369 +                       return 2;
4370 +               }
4371 +       } while (0);
4372 +#endif
4373 +
4374 +       return 1; /* PaX in action */
4375 +}
4376 +#endif
4377 +
4378 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4379 +void pax_report_insns(void *pc, void *sp)
4380 +{
4381 +       long i;
4382 +
4383 +       printk(KERN_ERR "PAX: bytes at PC: ");
4384 +       for (i = 0; i < 20; i++) {
4385 +               unsigned char c;
4386 +               if (get_user(c, (unsigned char __user *)pc+i))
4387 +                       printk("?? ");
4388 +               else
4389 +                       printk("%02x ", c);
4390 +       }
4391 +       printk("\n");
4392 +
4393 +       printk(KERN_ERR "PAX: bytes at SP-4: ");
4394 +       for (i = -1; i < 20; i++) {
4395 +               unsigned long c;
4396 +               if (get_user(c, (unsigned long __user *)sp+i))
4397 +                       printk("???????? ");
4398 +               else
4399 +                       printk("%08lx ", c);
4400 +       }
4401 +       printk("\n");
4402 +}
4403 +#endif
4404 diff -urNp linux-2.6.17.11/arch/i386/mm/hugetlbpage.c linux-2.6.17.11/arch/i386/mm/hugetlbpage.c
4405 --- linux-2.6.17.11/arch/i386/mm/hugetlbpage.c  2006-08-07 00:18:54.000000000 -0400
4406 +++ linux-2.6.17.11/arch/i386/mm/hugetlbpage.c  2006-09-01 16:20:28.000000000 -0400
4407 @@ -121,7 +121,12 @@ static unsigned long hugetlb_get_unmappe
4408  {
4409         struct mm_struct *mm = current->mm;
4410         struct vm_area_struct *vma;
4411 -       unsigned long start_addr;
4412 +       unsigned long start_addr, task_size = TASK_SIZE;
4413 +
4414 +#ifdef CONFIG_PAX_SEGMEXEC
4415 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
4416 +               task_size = SEGMEXEC_TASK_SIZE;
4417 +#endif
4418  
4419         if (len > mm->cached_hole_size) {
4420                 start_addr = mm->free_area_cache;
4421 @@ -135,7 +140,7 @@ full_search:
4422  
4423         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
4424                 /* At this point:  (!vma || addr < vma->vm_end). */
4425 -               if (TASK_SIZE - len < addr) {
4426 +               if (task_size - len < addr) {
4427                         /*
4428                          * Start a new search - just in case we missed
4429                          * some holes.
4430 @@ -163,9 +168,8 @@ static unsigned long hugetlb_get_unmappe
4431  {
4432         struct mm_struct *mm = current->mm;
4433         struct vm_area_struct *vma, *prev_vma;
4434 -       unsigned long base = mm->mmap_base, addr = addr0;
4435 +       unsigned long base = mm->mmap_base, addr;
4436         unsigned long largest_hole = mm->cached_hole_size;
4437 -       int first_time = 1;
4438  
4439         /* don't allow allocations above current base */
4440         if (mm->free_area_cache > base)
4441 @@ -175,7 +179,7 @@ static unsigned long hugetlb_get_unmappe
4442                 largest_hole = 0;
4443                 mm->free_area_cache  = base;
4444         }
4445 -try_again:
4446 +
4447         /* make sure it can fit in the remaining address space */
4448         if (mm->free_area_cache < len)
4449                 goto fail;
4450 @@ -217,16 +221,6 @@ try_again:
4451  
4452  fail:
4453         /*
4454 -        * if hint left us with no space for the requested
4455 -        * mapping then try again:
4456 -        */
4457 -       if (first_time) {
4458 -               mm->free_area_cache = base;
4459 -               largest_hole = 0;
4460 -               first_time = 0;
4461 -               goto try_again;
4462 -       }
4463 -       /*
4464          * A failed mmap() very likely causes application failure,
4465          * so fall back to the bottom-up function here. This scenario
4466          * can happen with large stack limits and large mmap()
4467 @@ -252,16 +246,23 @@ hugetlb_get_unmapped_area(struct file *f
4468  {
4469         struct mm_struct *mm = current->mm;
4470         struct vm_area_struct *vma;
4471 +       unsigned long task_size = TASK_SIZE;
4472  
4473         if (len & ~HPAGE_MASK)
4474                 return -EINVAL;
4475 -       if (len > TASK_SIZE)
4476 +
4477 +#ifdef CONFIG_PAX_SEGMEXEC
4478 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
4479 +               task_size = SEGMEXEC_TASK_SIZE;
4480 +#endif
4481 +
4482 +       if (len > task_size || addr > task_size - len)
4483                 return -ENOMEM;
4484  
4485         if (addr) {
4486                 addr = ALIGN(addr, HPAGE_SIZE);
4487                 vma = find_vma(mm, addr);
4488 -               if (TASK_SIZE - len >= addr &&
4489 +               if (task_size - len >= addr &&
4490                     (!vma || addr + len <= vma->vm_start))
4491                         return addr;
4492         }
4493 diff -urNp linux-2.6.17.11/arch/i386/mm/init.c linux-2.6.17.11/arch/i386/mm/init.c
4494 --- linux-2.6.17.11/arch/i386/mm/init.c 2006-08-07 00:18:54.000000000 -0400
4495 +++ linux-2.6.17.11/arch/i386/mm/init.c 2006-09-01 16:20:28.000000000 -0400
4496 @@ -41,6 +41,7 @@
4497  #include <asm/tlb.h>
4498  #include <asm/tlbflush.h>
4499  #include <asm/sections.h>
4500 +#include <asm/desc.h>
4501  
4502  unsigned int __VMALLOC_RESERVE = 128 << 20;
4503  
4504 @@ -50,30 +51,6 @@ unsigned long highstart_pfn, highend_pfn
4505  static int noinline do_test_wp_bit(void);
4506  
4507  /*
4508 - * Creates a middle page table and puts a pointer to it in the
4509 - * given global directory entry. This only returns the gd entry
4510 - * in non-PAE compilation mode, since the middle layer is folded.
4511 - */
4512 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
4513 -{
4514 -       pud_t *pud;
4515 -       pmd_t *pmd_table;
4516 -               
4517 -#ifdef CONFIG_X86_PAE
4518 -       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
4519 -       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
4520 -       pud = pud_offset(pgd, 0);
4521 -       if (pmd_table != pmd_offset(pud, 0)) 
4522 -               BUG();
4523 -#else
4524 -       pud = pud_offset(pgd, 0);
4525 -       pmd_table = pmd_offset(pud, 0);
4526 -#endif
4527 -
4528 -       return pmd_table;
4529 -}
4530 -
4531 -/*
4532   * Create a page table and place a pointer to it in a middle page
4533   * directory entry.
4534   */
4535 @@ -81,7 +58,11 @@ static pte_t * __init one_page_table_ini
4536  {
4537         if (pmd_none(*pmd)) {
4538                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
4539 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4540 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
4541 +#else
4542                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
4543 +#endif
4544                 if (page_table != pte_offset_kernel(pmd, 0))
4545                         BUG();  
4546  
4547 @@ -116,8 +97,6 @@ static void __init page_table_range_init
4548         pgd = pgd_base + pgd_idx;
4549  
4550         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
4551 -               if (pgd_none(*pgd)) 
4552 -                       one_md_table_init(pgd);
4553                 pud = pud_offset(pgd, vaddr);
4554                 pmd = pmd_offset(pud, vaddr);
4555                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
4556 @@ -130,11 +109,22 @@ static void __init page_table_range_init
4557         }
4558  }
4559  
4560 -static inline int is_kernel_text(unsigned long addr)
4561 +static inline int is_kernel_text(unsigned long start, unsigned long end)
4562  {
4563 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
4564 -               return 1;
4565 -       return 0;
4566 +       unsigned long etext;
4567 +
4568 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
4569 +       etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
4570 +#else
4571 +       etext = (unsigned long)&_etext;
4572 +#endif
4573 +
4574 +       if ((start > etext + __KERNEL_TEXT_OFFSET ||
4575 +            end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
4576 +           (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
4577 +            end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
4578 +               return 0;
4579 +       return 1;
4580  }
4581  
4582  /*
4583 @@ -146,26 +136,24 @@ static void __init kernel_physical_mappi
4584  {
4585         unsigned long pfn;
4586         pgd_t *pgd;
4587 +       pud_t *pud;
4588         pmd_t *pmd;
4589         pte_t *pte;
4590 -       int pgd_idx, pmd_idx, pte_ofs;
4591 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
4592  
4593         pgd_idx = pgd_index(PAGE_OFFSET);
4594         pgd = pgd_base + pgd_idx;
4595         pfn = 0;
4596  
4597 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
4598 -               pmd = one_md_table_init(pgd);
4599 -               if (pfn >= max_low_pfn)
4600 -                       continue;
4601 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
4602 +               pud = pud_offset(pgd, 0);
4603 +               pmd = pmd_offset(pud, 0);
4604                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
4605 -                       unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
4606 +                       unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
4607  
4608                         /* Map with big pages if possible, otherwise create normal page tables. */
4609                         if (cpu_has_pse) {
4610 -                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
4611 -
4612 -                               if (is_kernel_text(address) || is_kernel_text(address2))
4613 +                               if (is_kernel_text(address, address + PMD_SIZE))
4614                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
4615                                 else
4616                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
4617 @@ -174,7 +162,7 @@ static void __init kernel_physical_mappi
4618                                 pte = one_page_table_init(pmd);
4619  
4620                                 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
4621 -                                               if (is_kernel_text(address))
4622 +                                               if (is_kernel_text(address, address + PAGE_SIZE))
4623                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
4624                                                 else
4625                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
4626 @@ -341,13 +329,6 @@ static void __init pagetable_init (void)
4627         unsigned long vaddr;
4628         pgd_t *pgd_base = swapper_pg_dir;
4629  
4630 -#ifdef CONFIG_X86_PAE
4631 -       int i;
4632 -       /* Init entries of the first-level page table to the zero page */
4633 -       for (i = 0; i < PTRS_PER_PGD; i++)
4634 -               set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
4635 -#endif
4636 -
4637         /* Enable PSE if available */
4638         if (cpu_has_pse) {
4639                 set_in_cr4(X86_CR4_PSE);
4640 @@ -371,17 +352,6 @@ static void __init pagetable_init (void)
4641         page_table_range_init(vaddr, 0, pgd_base);
4642  
4643         permanent_kmaps_init(pgd_base);
4644 -
4645 -#ifdef CONFIG_X86_PAE
4646 -       /*
4647 -        * Add low memory identity-mappings - SMP needs it when
4648 -        * starting up on an AP from real-mode. In the non-PAE
4649 -        * case we already have these mappings through head.S.
4650 -        * All user-space mappings are explicitly cleared after
4651 -        * SMP startup.
4652 -        */
4653 -       set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
4654 -#endif
4655  }
4656  
4657  #ifdef CONFIG_SUSPEND_SHARED
4658 @@ -423,7 +393,6 @@ void zap_low_mappings (void)
4659         flush_tlb_all();
4660  }
4661  
4662 -static int disable_nx __initdata = 0;
4663  u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
4664  
4665  /*
4666 @@ -437,11 +406,9 @@ u64 __supported_pte_mask __read_mostly =
4667  void __init noexec_setup(const char *str)
4668  {
4669         if (!strncmp(str, "on",2) && cpu_has_nx) {
4670 -               __supported_pte_mask |= _PAGE_NX;
4671 -               disable_nx = 0;
4672 +               nx_enabled = 1;
4673         } else if (!strncmp(str,"off",3)) {
4674 -               disable_nx = 1;
4675 -               __supported_pte_mask &= ~_PAGE_NX;
4676 +               nx_enabled = 0;
4677         }
4678  }
4679  
4680 @@ -450,17 +417,13 @@ int nx_enabled = 0;
4681  
4682  static void __init set_nx(void)
4683  {
4684 -       unsigned int v[4], l, h;
4685 +       if (!nx_enabled && cpu_has_nx) {
4686 +               unsigned l, h;
4687  
4688 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
4689 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
4690 -               if ((v[3] & (1 << 20)) && !disable_nx) {
4691 -                       rdmsr(MSR_EFER, l, h);
4692 -                       l |= EFER_NX;
4693 -                       wrmsr(MSR_EFER, l, h);
4694 -                       nx_enabled = 1;
4695 -                       __supported_pte_mask |= _PAGE_NX;
4696 -               }
4697 +               __supported_pte_mask &= ~_PAGE_NX;
4698 +               rdmsr(MSR_EFER, l, h);
4699 +               l &= ~EFER_NX;
4700 +               wrmsr(MSR_EFER, l, h);
4701         }
4702  }
4703  
4704 @@ -512,14 +475,6 @@ void __init paging_init(void)
4705  
4706         load_cr3(swapper_pg_dir);
4707  
4708 -#ifdef CONFIG_X86_PAE
4709 -       /*
4710 -        * We will bail out later - printk doesn't work right now so
4711 -        * the user would just see a hanging kernel.
4712 -        */
4713 -       if (cpu_has_pae)
4714 -               set_in_cr4(X86_CR4_PAE);
4715 -#endif
4716         __flush_tlb_all();
4717  
4718         kmap_init();
4719 @@ -611,7 +566,7 @@ void __init mem_init(void)
4720         set_highmem_pages_init(bad_ppro);
4721  
4722         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
4723 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
4724 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
4725         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
4726  
4727         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
4728 @@ -628,10 +583,6 @@ void __init mem_init(void)
4729                 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
4730                );
4731  
4732 -#ifdef CONFIG_X86_PAE
4733 -       if (!cpu_has_pae)
4734 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
4735 -#endif
4736         if (boot_cpu_data.wp_works_ok < 0)
4737                 test_wp_bit();
4738  
4739 @@ -761,6 +712,37 @@ void free_init_pages(char *what, unsigne
4740  
4741  void free_initmem(void)
4742  {
4743 +
4744 +#ifdef CONFIG_PAX_KERNEXEC
4745 +       /* PaX: limit KERNEL_CS to actual size */
4746 +       unsigned long addr, limit;
4747 +       int cpu;
4748 +       pgd_t *pgd;
4749 +       pud_t *pud;
4750 +       pmd_t *pmd;
4751 +
4752 +#ifdef CONFIG_MODULES
4753 +       limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
4754 +#else
4755 +       limit = (unsigned long)&_etext;
4756 +#endif
4757 +       limit = (limit - 1UL) >> PAGE_SHIFT;
4758 +
4759 +       for (cpu = 0; cpu < NR_CPUS; cpu++) {
4760 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
4761 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
4762 +       }
4763 +
4764 +       /* PaX: make KERNEL_CS read-only */
4765 +       for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
4766 +               pgd = pgd_offset_k(addr);
4767 +               pud = pud_offset(pgd, addr);
4768 +               pmd = pmd_offset(pud, addr);
4769 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
4770 +       }
4771 +       flush_tlb_all();
4772 +#endif
4773 +
4774         free_init_pages("unused kernel memory",
4775                         (unsigned long)(&__init_begin),
4776                         (unsigned long)(&__init_end));
4777 diff -urNp linux-2.6.17.11/arch/i386/mm/mmap.c linux-2.6.17.11/arch/i386/mm/mmap.c
4778 --- linux-2.6.17.11/arch/i386/mm/mmap.c 2006-08-07 00:18:54.000000000 -0400
4779 +++ linux-2.6.17.11/arch/i386/mm/mmap.c 2006-09-01 16:20:28.000000000 -0400
4780 @@ -34,12 +34,18 @@
4781   * Leave an at least ~128 MB hole.
4782   */
4783  #define MIN_GAP (128*1024*1024)
4784 -#define MAX_GAP (TASK_SIZE/6*5)
4785 +#define MAX_GAP (task_size/6*5)
4786  
4787  static inline unsigned long mmap_base(struct mm_struct *mm)
4788  {
4789         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
4790         unsigned long random_factor = 0;
4791 +       unsigned long task_size = TASK_SIZE;
4792 +
4793 +#ifdef CONFIG_PAX_SEGMEXEC
4794 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
4795 +               task_size = SEGMEXEC_TASK_SIZE;
4796 +#endif
4797  
4798         if (current->flags & PF_RANDOMIZE)
4799                 random_factor = get_random_int() % (1024*1024);
4800 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
4801         else if (gap > MAX_GAP)
4802                 gap = MAX_GAP;
4803  
4804 -       return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
4805 +       return PAGE_ALIGN(task_size - gap - random_factor);
4806  }
4807  
4808  /*
4809 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
4810                         (current->personality & ADDR_COMPAT_LAYOUT) ||
4811                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
4812                 mm->mmap_base = TASK_UNMAPPED_BASE;
4813 +
4814 +#ifdef CONFIG_PAX_RANDMMAP
4815 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
4816 +                       mm->mmap_base += mm->delta_mmap;
4817 +#endif
4818 +
4819                 mm->get_unmapped_area = arch_get_unmapped_area;
4820                 mm->unmap_area = arch_unmap_area;
4821         } else {
4822                 mm->mmap_base = mmap_base(mm);
4823 +
4824 +#ifdef CONFIG_PAX_RANDMMAP
4825 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
4826 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
4827 +#endif
4828 +
4829                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4830                 mm->unmap_area = arch_unmap_area_topdown;
4831         }
4832 diff -urNp linux-2.6.17.11/arch/i386/mm/pageattr.c linux-2.6.17.11/arch/i386/mm/pageattr.c
4833 --- linux-2.6.17.11/arch/i386/mm/pageattr.c     2006-08-07 00:18:54.000000000 -0400
4834 +++ linux-2.6.17.11/arch/i386/mm/pageattr.c     2006-09-01 16:20:28.000000000 -0400
4835 @@ -14,6 +14,7 @@
4836  #include <asm/tlbflush.h>
4837  #include <asm/pgalloc.h>
4838  #include <asm/sections.h>
4839 +#include <asm/desc.h>
4840  
4841  static DEFINE_SPINLOCK(cpa_lock);
4842  static struct list_head df_list = LIST_HEAD_INIT(df_list);
4843 @@ -84,7 +85,18 @@ static void set_pmd_pte(pte_t *kpte, uns
4844         struct page *page;
4845         unsigned long flags;
4846  
4847 +#ifdef CONFIG_PAX_KERNEXEC
4848 +       unsigned long cr0;
4849 +
4850 +       pax_open_kernel(cr0);
4851 +#endif
4852 +
4853         set_pte_atomic(kpte, pte);      /* change init_mm */
4854 +
4855 +#ifdef CONFIG_PAX_KERNEXEC
4856 +       pax_close_kernel(cr0);
4857 +#endif
4858 +
4859         if (PTRS_PER_PMD > 1)
4860                 return;
4861  
4862 @@ -111,7 +123,7 @@ static inline void revert_page(struct pa
4863         pte_t *linear;
4864  
4865         ref_prot =
4866 -       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
4867 +       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
4868                 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
4869  
4870         linear = (pte_t *)
4871 @@ -143,7 +155,7 @@ __change_page_attr(struct page *page, pg
4872                         struct page *split;
4873  
4874                         ref_prot =
4875 -                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
4876 +                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
4877                                 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
4878                         split = split_large_page(address, prot, ref_prot);
4879                         if (!split)
4880 diff -urNp linux-2.6.17.11/arch/i386/oprofile/backtrace.c linux-2.6.17.11/arch/i386/oprofile/backtrace.c
4881 --- linux-2.6.17.11/arch/i386/oprofile/backtrace.c      2006-08-07 00:18:54.000000000 -0400
4882 +++ linux-2.6.17.11/arch/i386/oprofile/backtrace.c      2006-09-01 16:20:28.000000000 -0400
4883 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
4884         head = (struct frame_head *)regs->ebp;
4885  #endif
4886  
4887 -       if (!user_mode_vm(regs)) {
4888 +       if (!user_mode(regs)) {
4889                 while (depth-- && valid_kernel_stack(head, regs))
4890                         head = dump_kernel_backtrace(head);
4891                 return;
4892 diff -urNp linux-2.6.17.11/arch/i386/power/cpu.c linux-2.6.17.11/arch/i386/power/cpu.c
4893 --- linux-2.6.17.11/arch/i386/power/cpu.c       2006-08-07 00:18:54.000000000 -0400
4894 +++ linux-2.6.17.11/arch/i386/power/cpu.c       2006-09-01 16:20:28.000000000 -0400
4895 @@ -62,7 +62,7 @@ static void do_fpu_end(void)
4896  static void fix_processor_context(void)
4897  {
4898         int cpu = smp_processor_id();
4899 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
4900 +       struct tss_struct * t = init_tss + cpu;
4901  
4902         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. */
4903  
4904 diff -urNp linux-2.6.17.11/arch/ia64/ia32/binfmt_elf32.c linux-2.6.17.11/arch/ia64/ia32/binfmt_elf32.c
4905 --- linux-2.6.17.11/arch/ia64/ia32/binfmt_elf32.c       2006-08-07 00:18:54.000000000 -0400
4906 +++ linux-2.6.17.11/arch/ia64/ia32/binfmt_elf32.c       2006-09-01 16:20:28.000000000 -0400
4907 @@ -46,6 +46,17 @@ randomize_stack_top(unsigned long stack_
4908  
4909  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
4910  
4911 +#ifdef CONFIG_PAX_ASLR
4912 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
4913 +
4914 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
4915 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4916 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
4917 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4918 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
4919 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4920 +#endif
4921 +
4922  /* Ugly but avoids duplication */
4923  #include "../../../fs/binfmt_elf.c"
4924  
4925 diff -urNp linux-2.6.17.11/arch/ia64/ia32/ia32priv.h linux-2.6.17.11/arch/ia64/ia32/ia32priv.h
4926 --- linux-2.6.17.11/arch/ia64/ia32/ia32priv.h   2006-08-07 00:18:54.000000000 -0400
4927 +++ linux-2.6.17.11/arch/ia64/ia32/ia32priv.h   2006-09-01 16:20:28.000000000 -0400
4928 @@ -305,7 +305,14 @@ struct old_linux32_dirent {
4929  #define ELF_DATA       ELFDATA2LSB
4930  #define ELF_ARCH       EM_386
4931  
4932 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
4933 +#ifdef CONFIG_PAX_RANDUSTACK
4934 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
4935 +#else
4936 +#define __IA32_DELTA_STACK     0UL
4937 +#endif
4938 +
4939 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
4940 +
4941  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
4942  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
4943  
4944 diff -urNp linux-2.6.17.11/arch/ia64/kernel/module.c linux-2.6.17.11/arch/ia64/kernel/module.c
4945 --- linux-2.6.17.11/arch/ia64/kernel/module.c   2006-08-07 00:18:54.000000000 -0400
4946 +++ linux-2.6.17.11/arch/ia64/kernel/module.c   2006-09-01 16:20:28.000000000 -0400
4947 @@ -322,7 +322,7 @@ module_alloc (unsigned long size)
4948  void
4949  module_free (struct module *mod, void *module_region)
4950  {
4951 -       if (mod->arch.init_unw_table && module_region == mod->module_init) {
4952 +       if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
4953                 unw_remove_unwind_table(mod->arch.init_unw_table);
4954                 mod->arch.init_unw_table = NULL;
4955         }
4956 @@ -500,15 +500,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
4957  }
4958  
4959  static inline int
4960 +in_init_rx (const struct module *mod, uint64_t addr)
4961 +{
4962 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
4963 +}
4964 +
4965 +static inline int
4966 +in_init_rw (const struct module *mod, uint64_t addr)
4967 +{
4968 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
4969 +}
4970 +
4971 +static inline int
4972  in_init (const struct module *mod, uint64_t addr)
4973  {
4974 -       return addr - (uint64_t) mod->module_init < mod->init_size;
4975 +       return in_init_rx(mod, value) || in_init_rw(mod, value);
4976 +}
4977 +
4978 +static inline int
4979 +in_core_rx (const struct module *mod, uint64_t addr)
4980 +{
4981 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
4982 +}
4983 +
4984 +static inline int
4985 +in_core_rw (const struct module *mod, uint64_t addr)
4986 +{
4987 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
4988  }
4989  
4990  static inline int
4991  in_core (const struct module *mod, uint64_t addr)
4992  {
4993 -       return addr - (uint64_t) mod->module_core < mod->core_size;
4994 +       return in_core_rx(mod, value) || in_core_rw(mod, value);
4995  }
4996  
4997  static inline int
4998 @@ -692,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_
4999                 break;
5000  
5001               case RV_BDREL:
5002 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
5003 +               if (in_init_rx(mod, val))
5004 +                       val -= (uint64_t) mod->module_init_rx;
5005 +               else if (in_init_rw(mod, val))
5006 +                       val -= (uint64_t) mod->module_init_rw;
5007 +               else if (in_core_rx(mod, val))
5008 +                       val -= (uint64_t) mod->module_core_rx;
5009 +               else if (in_core_rw(mod, val))
5010 +                       val -= (uint64_t) mod->module_core_rw;
5011                 break;
5012  
5013               case RV_LTV:
5014 @@ -826,15 +857,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
5015                  *     addresses have been selected...
5016                  */
5017                 uint64_t gp;
5018 -               if (mod->core_size > MAX_LTOFF)
5019 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
5020                         /*
5021                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
5022                          * at the end of the module.
5023                          */
5024 -                       gp = mod->core_size - MAX_LTOFF / 2;
5025 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
5026                 else
5027 -                       gp = mod->core_size / 2;
5028 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
5029 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
5030 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
5031                 mod->arch.gp = gp;
5032                 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
5033         }
5034 diff -urNp linux-2.6.17.11/arch/ia64/kernel/ptrace.c linux-2.6.17.11/arch/ia64/kernel/ptrace.c
5035 --- linux-2.6.17.11/arch/ia64/kernel/ptrace.c   2006-08-07 00:18:54.000000000 -0400
5036 +++ linux-2.6.17.11/arch/ia64/kernel/ptrace.c   2006-09-01 16:20:28.000000000 -0400
5037 @@ -19,6 +19,7 @@
5038  #include <linux/audit.h>
5039  #include <linux/signal.h>
5040  #include <linux/vs_pid.h>
5041 +#include <linux/grsecurity.h>
5042  
5043  #include <asm/pgtable.h>
5044  #include <asm/processor.h>
5045 @@ -1451,6 +1452,9 @@ sys_ptrace (long request, pid_t pid, uns
5046         if (pid == 1)           /* no messing around with init! */
5047                 goto out_tsk;
5048  
5049 +       if (gr_handle_ptrace(child, request))
5050 +               goto out_tsk;
5051 +
5052         if (request == PTRACE_ATTACH) {
5053                 ret = ptrace_attach(child);
5054                 goto out_tsk;
5055 diff -urNp linux-2.6.17.11/arch/ia64/kernel/sys_ia64.c linux-2.6.17.11/arch/ia64/kernel/sys_ia64.c
5056 --- linux-2.6.17.11/arch/ia64/kernel/sys_ia64.c 2006-08-23 19:30:00.000000000 -0400
5057 +++ linux-2.6.17.11/arch/ia64/kernel/sys_ia64.c 2006-09-01 16:20:28.000000000 -0400
5058 @@ -38,6 +38,13 @@ arch_get_unmapped_area (struct file *fil
5059         if (REGION_NUMBER(addr) == RGN_HPAGE)
5060                 addr = 0;
5061  #endif
5062 +
5063 +#ifdef CONFIG_PAX_RANDMMAP
5064 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
5065 +               addr = mm->free_area_cache;
5066 +       else
5067 +#endif
5068 +
5069         if (!addr)
5070                 addr = mm->free_area_cache;
5071  
5072 @@ -56,9 +63,9 @@ arch_get_unmapped_area (struct file *fil
5073         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
5074                 /* At this point:  (!vma || addr < vma->vm_end). */
5075                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
5076 -                       if (start_addr != TASK_UNMAPPED_BASE) {
5077 +                       if (start_addr != mm->mmap_base) {
5078                                 /* Start a new search --- just in case we missed some holes.  */
5079 -                               addr = TASK_UNMAPPED_BASE;
5080 +                               addr = mm->mmap_base;
5081                                 goto full_search;
5082                         }
5083                         return -ENOMEM;
5084 diff -urNp linux-2.6.17.11/arch/ia64/mm/fault.c linux-2.6.17.11/arch/ia64/mm/fault.c
5085 --- linux-2.6.17.11/arch/ia64/mm/fault.c        2006-08-07 00:18:54.000000000 -0400
5086 +++ linux-2.6.17.11/arch/ia64/mm/fault.c        2006-09-01 16:20:28.000000000 -0400
5087 @@ -11,6 +11,7 @@
5088  #include <linux/interrupt.h>
5089  #include <linux/kprobes.h>
5090  #include <linux/vs_memory.h>
5091 +#include <linux/binfmts.h>
5092  
5093  #include <asm/pgtable.h>
5094  #include <asm/processor.h>
5095 @@ -52,6 +53,23 @@ mapped_kernel_page_is_present (unsigned 
5096         return pte_present(pte);
5097  }
5098  
5099 +#ifdef CONFIG_PAX_PAGEEXEC
5100 +void pax_report_insns(void *pc, void *sp)
5101 +{
5102 +       unsigned long i;
5103 +
5104 +       printk(KERN_ERR "PAX: bytes at PC: ");
5105 +       for (i = 0; i < 8; i++) {
5106 +               unsigned int c;
5107 +               if (get_user(c, (unsigned int*)pc+i))
5108 +                       printk("???????? ");
5109 +               else
5110 +                       printk("%08x ", c);
5111 +       }
5112 +       printk("\n");
5113 +}
5114 +#endif
5115 +
5116  void __kprobes
5117  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
5118  {
5119 @@ -117,9 +135,23 @@ ia64_do_page_fault (unsigned long addres
5120                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
5121                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
5122  
5123 -       if ((vma->vm_flags & mask) != mask)
5124 +       if ((vma->vm_flags & mask) != mask) {
5125 +
5126 +#ifdef CONFIG_PAX_PAGEEXEC
5127 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
5128 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
5129 +                               goto bad_area;
5130 +
5131 +                       up_read(&mm->mmap_sem);
5132 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
5133 +                       do_exit(SIGKILL);
5134 +               }
5135 +#endif
5136 +
5137                 goto bad_area;
5138  
5139 +       }
5140 +
5141    survive:
5142         /*
5143          * If for any reason at all we couldn't handle the fault, make
5144 diff -urNp linux-2.6.17.11/arch/ia64/mm/init.c linux-2.6.17.11/arch/ia64/mm/init.c
5145 --- linux-2.6.17.11/arch/ia64/mm/init.c 2006-08-07 00:18:54.000000000 -0400
5146 +++ linux-2.6.17.11/arch/ia64/mm/init.c 2006-09-01 16:20:28.000000000 -0400
5147 @@ -20,8 +20,8 @@
5148  #include <linux/swap.h>
5149  #include <linux/proc_fs.h>
5150  #include <linux/bitops.h>
5151 +#include <linux/a.out.h>
5152  
5153 -#include <asm/a.out.h>
5154  #include <asm/dma.h>
5155  #include <asm/ia32.h>
5156  #include <asm/io.h>
5157 diff -urNp linux-2.6.17.11/arch/mips/kernel/binfmt_elfn32.c linux-2.6.17.11/arch/mips/kernel/binfmt_elfn32.c
5158 --- linux-2.6.17.11/arch/mips/kernel/binfmt_elfn32.c    2006-08-07 00:18:54.000000000 -0400
5159 +++ linux-2.6.17.11/arch/mips/kernel/binfmt_elfn32.c    2006-09-01 16:20:28.000000000 -0400
5160 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
5161  #undef ELF_ET_DYN_BASE
5162  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
5163  
5164 +#ifdef CONFIG_PAX_ASLR
5165 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5166 +
5167 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5168 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5169 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5170 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5171 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5172 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5173 +#endif
5174 +
5175  #include <asm/processor.h>
5176  #include <linux/module.h>
5177  #include <linux/elfcore.h>
5178 diff -urNp linux-2.6.17.11/arch/mips/kernel/binfmt_elfo32.c linux-2.6.17.11/arch/mips/kernel/binfmt_elfo32.c
5179 --- linux-2.6.17.11/arch/mips/kernel/binfmt_elfo32.c    2006-08-07 00:18:54.000000000 -0400
5180 +++ linux-2.6.17.11/arch/mips/kernel/binfmt_elfo32.c    2006-09-01 16:20:28.000000000 -0400
5181 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
5182  #undef ELF_ET_DYN_BASE
5183  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
5184  
5185 +#ifdef CONFIG_PAX_ASLR
5186 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5187 +
5188 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5189 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5190 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5191 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5192 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5193 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5194 +#endif
5195 +
5196  #include <asm/processor.h>
5197  #include <linux/module.h>
5198  #include <linux/elfcore.h>
5199 diff -urNp linux-2.6.17.11/arch/mips/kernel/syscall.c linux-2.6.17.11/arch/mips/kernel/syscall.c
5200 --- linux-2.6.17.11/arch/mips/kernel/syscall.c  2006-08-07 00:18:54.000000000 -0400
5201 +++ linux-2.6.17.11/arch/mips/kernel/syscall.c  2006-09-01 16:20:28.000000000 -0400
5202 @@ -90,6 +90,11 @@ unsigned long arch_get_unmapped_area(str
5203         do_color_align = 0;
5204         if (filp || (flags & MAP_SHARED))
5205                 do_color_align = 1;
5206 +
5207 +#ifdef CONFIG_PAX_RANDMMAP
5208 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5209 +#endif
5210 +
5211         if (addr) {
5212                 if (do_color_align)
5213                         addr = COLOUR_ALIGN(addr, pgoff);
5214 @@ -100,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
5215                     (!vmm || addr + len <= vmm->vm_start))
5216                         return addr;
5217         }
5218 -       addr = TASK_UNMAPPED_BASE;
5219 +       addr = current->mm->mmap_base;
5220         if (do_color_align)
5221                 addr = COLOUR_ALIGN(addr, pgoff);
5222         else
5223 diff -urNp linux-2.6.17.11/arch/mips/mm/fault.c linux-2.6.17.11/arch/mips/mm/fault.c
5224 --- linux-2.6.17.11/arch/mips/mm/fault.c        2006-08-07 00:18:54.000000000 -0400
5225 +++ linux-2.6.17.11/arch/mips/mm/fault.c        2006-09-01 16:20:28.000000000 -0400
5226 @@ -27,6 +27,23 @@
5227  #include <asm/ptrace.h>
5228  #include <asm/highmem.h>               /* For VMALLOC_END */
5229  
5230 +#ifdef CONFIG_PAX_PAGEEXEC
5231 +void pax_report_insns(void *pc)
5232 +{
5233 +       unsigned long i;
5234 +
5235 +       printk(KERN_ERR "PAX: bytes at PC: ");
5236 +       for (i = 0; i < 5; i++) {
5237 +               unsigned int c;
5238 +               if (get_user(c, (unsigned int*)pc+i))
5239 +                       printk("???????? ");
5240 +               else
5241 +                       printk("%08x ", c);
5242 +       }
5243 +       printk("\n");
5244 +}
5245 +#endif
5246 +
5247  /*
5248   * This routine handles page faults.  It determines the address,
5249   * and the problem, and then passes it off to one of the appropriate
5250 diff -urNp linux-2.6.17.11/arch/parisc/kernel/module.c linux-2.6.17.11/arch/parisc/kernel/module.c
5251 --- linux-2.6.17.11/arch/parisc/kernel/module.c 2006-08-07 00:18:54.000000000 -0400
5252 +++ linux-2.6.17.11/arch/parisc/kernel/module.c 2006-09-01 16:20:28.000000000 -0400
5253 @@ -72,16 +72,38 @@
5254  
5255  /* three functions to determine where in the module core
5256   * or init pieces the location is */
5257 +static inline int is_init_rx(struct module *me, void *loc)
5258 +{
5259 +       return (loc >= me->module_init_rx &&
5260 +               loc < (me->module_init_rx + me->init_size_rx));
5261 +}
5262 +
5263 +static inline int is_init_rw(struct module *me, void *loc)
5264 +{
5265 +       return (loc >= me->module_init_rw &&
5266 +               loc < (me->module_init_rw + me->init_size_rw));
5267 +}
5268 +
5269  static inline int is_init(struct module *me, void *loc)
5270  {
5271 -       return (loc >= me->module_init &&
5272 -               loc <= (me->module_init + me->init_size));
5273 +       return is_init_rx(me, loc) || is_init_rw(me, loc);
5274 +}
5275 +
5276 +static inline int is_core_rx(struct module *me, void *loc)
5277 +{
5278 +       return (loc >= me->module_core_rx &&
5279 +               loc < (me->module_core_rx + me->core_size_rx));
5280 +}
5281 +
5282 +static inline int is_core_rw(struct module *me, void *loc)
5283 +{
5284 +       return (loc >= me->module_core_rw &&
5285 +               loc < (me->module_core_rw + me->core_size_rw));
5286  }
5287  
5288  static inline int is_core(struct module *me, void *loc)
5289  {
5290 -       return (loc >= me->module_core &&
5291 -               loc <= (me->module_core + me->core_size));
5292 +       return is_core_rx(me, loc) || is_core_rw(me, loc);
5293  }
5294  
5295  static inline int is_local(struct module *me, void *loc)
5296 @@ -289,21 +311,21 @@ int module_frob_arch_sections(CONST Elf_
5297         }
5298  
5299         /* align things a bit */
5300 -       me->core_size = ALIGN(me->core_size, 16);
5301 -       me->arch.got_offset = me->core_size;
5302 -       me->core_size += gots * sizeof(struct got_entry);
5303 -
5304 -       me->core_size = ALIGN(me->core_size, 16);
5305 -       me->arch.fdesc_offset = me->core_size;
5306 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
5307 -
5308 -       me->core_size = ALIGN(me->core_size, 16);
5309 -       me->arch.stub_offset = me->core_size;
5310 -       me->core_size += stubs * sizeof(struct stub_entry);
5311 -
5312 -       me->init_size = ALIGN(me->init_size, 16);
5313 -       me->arch.init_stub_offset = me->init_size;
5314 -       me->init_size += init_stubs * sizeof(struct stub_entry);
5315 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
5316 +       me->arch.got_offset = me->core_size_rw;
5317 +       me->core_size_rw += gots * sizeof(struct got_entry);
5318 +
5319 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
5320 +       me->arch.fdesc_offset = me->core_size_rw;
5321 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
5322 +
5323 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
5324 +       me->arch.stub_offset = me->core_size_rx;
5325 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
5326 +
5327 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
5328 +       me->arch.init_stub_offset = me->init_size_rx;
5329 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
5330  
5331         me->arch.got_max = gots;
5332         me->arch.fdesc_max = fdescs;
5333 @@ -323,7 +345,7 @@ static Elf64_Word get_got(struct module 
5334  
5335         BUG_ON(value == 0);
5336  
5337 -       got = me->module_core + me->arch.got_offset;
5338 +       got = me->module_core_rw + me->arch.got_offset;
5339         for (i = 0; got[i].addr; i++)
5340                 if (got[i].addr == value)
5341                         goto out;
5342 @@ -341,7 +363,7 @@ static Elf64_Word get_got(struct module 
5343  #ifdef __LP64__
5344  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
5345  {
5346 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
5347 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
5348  
5349         if (!value) {
5350                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
5351 @@ -359,7 +381,7 @@ static Elf_Addr get_fdesc(struct module 
5352  
5353         /* Create new one */
5354         fdesc->addr = value;
5355 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
5356 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
5357         return (Elf_Addr)fdesc;
5358  }
5359  #endif /* __LP64__ */
5360 @@ -373,12 +395,12 @@ static Elf_Addr get_stub(struct module *
5361         if(init_section) {
5362                 i = me->arch.init_stub_count++;
5363                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
5364 -               stub = me->module_init + me->arch.init_stub_offset + 
5365 +               stub = me->module_init_rx + me->arch.init_stub_offset + 
5366                         i * sizeof(struct stub_entry);
5367         } else {
5368                 i = me->arch.stub_count++;
5369                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
5370 -               stub = me->module_core + me->arch.stub_offset + 
5371 +               stub = me->module_core_rx + me->arch.stub_offset + 
5372                         i * sizeof(struct stub_entry);
5373         }
5374  
5375 @@ -721,7 +743,7 @@ register_unwind_table(struct module *me,
5376  
5377         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
5378         end = table + sechdrs[me->arch.unwind_section].sh_size;
5379 -       gp = (Elf_Addr)me->module_core + me->arch.got_offset;
5380 +       gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
5381  
5382         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
5383                me->arch.unwind_section, table, end, gp);
5384 diff -urNp linux-2.6.17.11/arch/parisc/kernel/ptrace.c linux-2.6.17.11/arch/parisc/kernel/ptrace.c
5385 --- linux-2.6.17.11/arch/parisc/kernel/ptrace.c 2006-08-07 00:18:54.000000000 -0400
5386 +++ linux-2.6.17.11/arch/parisc/kernel/ptrace.c 2006-09-01 16:20:28.000000000 -0400
5387 @@ -18,6 +18,7 @@
5388  #include <linux/security.h>
5389  #include <linux/compat.h>
5390  #include <linux/signal.h>
5391 +#include <linux/grsecurity.h>
5392  
5393  #include <asm/uaccess.h>
5394  #include <asm/pgtable.h>
5395 diff -urNp linux-2.6.17.11/arch/parisc/kernel/sys_parisc.c linux-2.6.17.11/arch/parisc/kernel/sys_parisc.c
5396 --- linux-2.6.17.11/arch/parisc/kernel/sys_parisc.c     2006-08-07 00:18:54.000000000 -0400
5397 +++ linux-2.6.17.11/arch/parisc/kernel/sys_parisc.c     2006-09-01 16:20:28.000000000 -0400
5398 @@ -105,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
5399         if (len > TASK_SIZE)
5400                 return -ENOMEM;
5401         if (!addr)
5402 -               addr = TASK_UNMAPPED_BASE;
5403 +               addr = current->mm->mmap_base;
5404  
5405         if (filp) {
5406                 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
5407 diff -urNp linux-2.6.17.11/arch/parisc/kernel/traps.c linux-2.6.17.11/arch/parisc/kernel/traps.c
5408 --- linux-2.6.17.11/arch/parisc/kernel/traps.c  2006-08-07 00:18:54.000000000 -0400
5409 +++ linux-2.6.17.11/arch/parisc/kernel/traps.c  2006-09-01 16:20:28.000000000 -0400
5410 @@ -712,9 +712,7 @@ void handle_interruption(int code, struc
5411  
5412                         down_read(&current->mm->mmap_sem);
5413                         vma = find_vma(current->mm,regs->iaoq[0]);
5414 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
5415 -                               && (vma->vm_flags & VM_EXEC)) {
5416 -
5417 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
5418                                 fault_address = regs->iaoq[0];
5419                                 fault_space = regs->iasq[0];
5420  
5421 diff -urNp linux-2.6.17.11/arch/parisc/mm/fault.c linux-2.6.17.11/arch/parisc/mm/fault.c
5422 --- linux-2.6.17.11/arch/parisc/mm/fault.c      2006-08-07 00:18:54.000000000 -0400
5423 +++ linux-2.6.17.11/arch/parisc/mm/fault.c      2006-09-01 16:20:28.000000000 -0400
5424 @@ -16,6 +16,8 @@
5425  #include <linux/sched.h>
5426  #include <linux/interrupt.h>
5427  #include <linux/module.h>
5428 +#include <linux/unistd.h>
5429 +#include <linux/binfmts.h>
5430  
5431  #include <asm/uaccess.h>
5432  #include <asm/traps.h>
5433 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
5434  static unsigned long
5435  parisc_acctyp(unsigned long code, unsigned int inst)
5436  {
5437 -       if (code == 6 || code == 16)
5438 +       if (code == 6 || code == 7 || code == 16)
5439             return VM_EXEC;
5440  
5441         switch (inst & 0xf0000000) {
5442 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
5443                         }
5444  #endif
5445  
5446 +#ifdef CONFIG_PAX_PAGEEXEC
5447 +/*
5448 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
5449 + *
5450 + * returns 1 when task should be killed
5451 + *         2 when rt_sigreturn trampoline was detected
5452 + *         3 when unpatched PLT trampoline was detected
5453 + */
5454 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5455 +{
5456 +
5457 +#ifdef CONFIG_PAX_EMUPLT
5458 +       int err;
5459 +
5460 +       do { /* PaX: unpatched PLT emulation */
5461 +               unsigned int bl, depwi;
5462 +
5463 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
5464 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
5465 +
5466 +               if (err)
5467 +                       break;
5468 +
5469 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
5470 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
5471 +
5472 +                       err = get_user(ldw, (unsigned int*)addr);
5473 +                       err |= get_user(bv, (unsigned int*)(addr+4));
5474 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
5475 +
5476 +                       if (err)
5477 +                               break;
5478 +
5479 +                       if (ldw == 0x0E801096U &&
5480 +                           bv == 0xEAC0C000U &&
5481 +                           ldw2 == 0x0E881095U)
5482 +                       {
5483 +                               unsigned int resolver, map;
5484 +
5485 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
5486 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
5487 +                               if (err)
5488 +                                       break;
5489 +
5490 +                               regs->gr[20] = instruction_pointer(regs)+8;
5491 +                               regs->gr[21] = map;
5492 +                               regs->gr[22] = resolver;
5493 +                               regs->iaoq[0] = resolver | 3UL;
5494 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
5495 +                               return 3;
5496 +                       }
5497 +               }
5498 +       } while (0);
5499 +#endif
5500 +
5501 +#ifdef CONFIG_PAX_EMUTRAMP
5502 +
5503 +#ifndef CONFIG_PAX_EMUSIGRT
5504 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
5505 +               return 1;
5506 +#endif
5507 +
5508 +       do { /* PaX: rt_sigreturn emulation */
5509 +               unsigned int ldi1, ldi2, bel, nop;
5510 +
5511 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
5512 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
5513 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
5514 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
5515 +
5516 +               if (err)
5517 +                       break;
5518 +
5519 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
5520 +                   ldi2 == 0x3414015AU &&
5521 +                   bel == 0xE4008200U &&
5522 +                   nop == 0x08000240U)
5523 +               {
5524 +                       regs->gr[25] = (ldi1 & 2) >> 1;
5525 +                       regs->gr[20] = __NR_rt_sigreturn;
5526 +                       regs->gr[31] = regs->iaoq[1] + 16;
5527 +                       regs->sr[0] = regs->iasq[1];
5528 +                       regs->iaoq[0] = 0x100UL;
5529 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
5530 +                       regs->iasq[0] = regs->sr[2];
5531 +                       regs->iasq[1] = regs->sr[2];
5532 +                       return 2;
5533 +               }
5534 +       } while (0);
5535 +#endif
5536 +
5537 +       return 1;
5538 +}
5539 +
5540 +void pax_report_insns(void *pc, void *sp)
5541 +{
5542 +       unsigned long i;
5543 +
5544 +       printk(KERN_ERR "PAX: bytes at PC: ");
5545 +       for (i = 0; i < 5; i++) {
5546 +               unsigned int c;
5547 +               if (get_user(c, (unsigned int*)pc+i))
5548 +                       printk("???????? ");
5549 +               else
5550 +                       printk("%08x ", c);
5551 +       }
5552 +       printk("\n");
5553 +}
5554 +#endif
5555 +
5556  void do_page_fault(struct pt_regs *regs, unsigned long code,
5557                               unsigned long address)
5558  {
5559 @@ -168,8 +280,33 @@ good_area:
5560  
5561         acc_type = parisc_acctyp(code,regs->iir);
5562  
5563 -       if ((vma->vm_flags & acc_type) != acc_type)
5564 +       if ((vma->vm_flags & acc_type) != acc_type) {
5565 +
5566 +#ifdef CONFIG_PAX_PAGEEXEC
5567 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
5568 +                   (address & ~3UL) == instruction_pointer(regs))
5569 +               {
5570 +                       up_read(&mm->mmap_sem);
5571 +                       switch(pax_handle_fetch_fault(regs)) {
5572 +
5573 +#ifdef CONFIG_PAX_EMUPLT
5574 +                       case 3:
5575 +                               return;
5576 +#endif
5577 +
5578 +#ifdef CONFIG_PAX_EMUTRAMP
5579 +                       case 2:
5580 +                               return;
5581 +#endif
5582 +
5583 +                       }
5584 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
5585 +                       do_exit(SIGKILL);
5586 +               }
5587 +#endif
5588 +
5589                 goto bad_area;
5590 +       }
5591  
5592         /*
5593          * If for any reason at all we couldn't handle the fault, make
5594 diff -urNp linux-2.6.17.11/arch/powerpc/kernel/module_32.c linux-2.6.17.11/arch/powerpc/kernel/module_32.c
5595 --- linux-2.6.17.11/arch/powerpc/kernel/module_32.c     2006-08-07 00:18:54.000000000 -0400
5596 +++ linux-2.6.17.11/arch/powerpc/kernel/module_32.c     2006-09-01 16:20:28.000000000 -0400
5597 @@ -123,7 +123,7 @@ int module_frob_arch_sections(Elf32_Ehdr
5598                         me->arch.core_plt_section = i;
5599         }
5600         if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
5601 -               printk("Module doesn't contain .plt or .init.plt sections.\n");
5602 +               printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
5603                 return -ENOEXEC;
5604         }
5605  
5606 @@ -164,11 +164,16 @@ static uint32_t do_plt_call(void *locati
5607  
5608         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
5609         /* Init, or core PLT? */
5610 -       if (location >= mod->module_core
5611 -           && location < mod->module_core + mod->core_size)
5612 +       if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
5613 +           (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
5614                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
5615 -       else
5616 +       else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
5617 +                (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
5618                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
5619 +       else {
5620 +               printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
5621 +               return ~0UL;
5622 +       }
5623  
5624         /* Find this entry, or if that fails, the next avail. entry */
5625         while (entry->jump[0]) {
5626 diff -urNp linux-2.6.17.11/arch/powerpc/mm/fault.c linux-2.6.17.11/arch/powerpc/mm/fault.c
5627 --- linux-2.6.17.11/arch/powerpc/mm/fault.c     2006-08-07 00:18:54.000000000 -0400
5628 +++ linux-2.6.17.11/arch/powerpc/mm/fault.c     2006-09-01 16:20:28.000000000 -0400
5629 @@ -29,6 +29,7 @@
5630  #include <linux/highmem.h>
5631  #include <linux/module.h>
5632  #include <linux/kprobes.h>
5633 +#include <linux/binfmts.h>
5634  
5635  #include <asm/page.h>
5636  #include <asm/pgtable.h>
5637 @@ -103,6 +104,38 @@ static void do_dabr(struct pt_regs *regs
5638  }
5639  #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
5640  
5641 +#ifdef CONFIG_PAX_PAGEEXEC
5642 +/*
5643 + * PaX: decide what to do with offenders (regs->nip = fault address)
5644 + *
5645 + * returns 1 when task should be killed
5646 + */
5647 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5648 +{
5649 +
5650 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
5651 +       int err;
5652 +#endif
5653 +
5654 +       return 1;
5655 +}
5656 +
5657 +void pax_report_insns(void *pc, void *sp)
5658 +{
5659 +       unsigned long i;
5660 +
5661 +       printk(KERN_ERR "PAX: bytes at PC: ");
5662 +       for (i = 0; i < 5; i++) {
5663 +               unsigned int c;
5664 +               if (get_user(c, (unsigned int*)pc+i))
5665 +                       printk("???????? ");
5666 +               else
5667 +                       printk("%08x ", c);
5668 +       }
5669 +       printk("\n");
5670 +}
5671 +#endif
5672 +
5673  /*
5674   * For 600- and 800-family processors, the error_code parameter is DSISR
5675   * for a data fault, SRR1 for an instruction fault. For 400-family processors
5676 @@ -335,6 +368,19 @@ bad_area:
5677  bad_area_nosemaphore:
5678         /* User mode accesses cause a SIGSEGV */
5679         if (user_mode(regs)) {
5680 +
5681 +#ifdef CONFIG_PAX_PAGEEXEC
5682 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
5683 +                       if (is_exec && (error_code & DSISR_PROTFAULT)) {
5684 +                               switch (pax_handle_fetch_fault(regs)) {
5685 +                               }
5686 +
5687 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
5688 +                               do_exit(SIGKILL);
5689 +                       }
5690 +               }
5691 +#endif
5692 +
5693                 _exception(SIGSEGV, regs, code, address);
5694                 return 0;
5695         }
5696 diff -urNp linux-2.6.17.11/arch/powerpc/mm/mmap.c linux-2.6.17.11/arch/powerpc/mm/mmap.c
5697 --- linux-2.6.17.11/arch/powerpc/mm/mmap.c      2006-08-07 00:18:54.000000000 -0400
5698 +++ linux-2.6.17.11/arch/powerpc/mm/mmap.c      2006-09-01 16:20:28.000000000 -0400
5699 @@ -74,10 +74,22 @@ void arch_pick_mmap_layout(struct mm_str
5700          */
5701         if (mmap_is_legacy()) {
5702                 mm->mmap_base = TASK_UNMAPPED_BASE;
5703 +
5704 +#ifdef CONFIG_PAX_RANDMMAP
5705 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5706 +                       mm->mmap_base += mm->delta_mmap;
5707 +#endif
5708 +
5709                 mm->get_unmapped_area = arch_get_unmapped_area;
5710                 mm->unmap_area = arch_unmap_area;
5711         } else {
5712                 mm->mmap_base = mmap_base();
5713 +
5714 +#ifdef CONFIG_PAX_RANDMMAP
5715 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5716 +                       mm->mmap_base -= mm->delta_mmap;
5717 +#endif
5718 +
5719                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
5720                 mm->unmap_area = arch_unmap_area_topdown;
5721         }
5722 diff -urNp linux-2.6.17.11/arch/ppc/mm/fault.c linux-2.6.17.11/arch/ppc/mm/fault.c
5723 --- linux-2.6.17.11/arch/ppc/mm/fault.c 2006-08-07 00:18:54.000000000 -0400
5724 +++ linux-2.6.17.11/arch/ppc/mm/fault.c 2006-09-01 16:20:28.000000000 -0400
5725 @@ -26,6 +26,11 @@
5726  #include <linux/interrupt.h>
5727  #include <linux/highmem.h>
5728  #include <linux/module.h>
5729 +#include <linux/slab.h>
5730 +#include <linux/pagemap.h>
5731 +#include <linux/compiler.h>
5732 +#include <linux/binfmts.h>
5733 +#include <linux/unistd.h>
5734  
5735  #include <asm/page.h>
5736  #include <asm/pgtable.h>
5737 @@ -49,6 +54,364 @@ unsigned long pte_misses;   /* updated by 
5738  unsigned long pte_errors;      /* updated by do_page_fault() */
5739  unsigned int probingmem;
5740  
5741 +#ifdef CONFIG_PAX_EMUSIGRT
5742 +void pax_syscall_close(struct vm_area_struct * vma)
5743 +{
5744 +       vma->vm_mm->call_syscall = 0UL;
5745 +}
5746 +
5747 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
5748 +{
5749 +       struct page* page;
5750 +       unsigned int *kaddr;
5751 +
5752 +       page = alloc_page(GFP_HIGHUSER);
5753 +       if (!page)
5754 +               return NOPAGE_OOM;
5755 +
5756 +       kaddr = kmap(page);
5757 +       memset(kaddr, 0, PAGE_SIZE);
5758 +       kaddr[0] = 0x44000002U; /* sc */
5759 +       __flush_dcache_icache(kaddr);
5760 +       kunmap(page);
5761 +       if (type)
5762 +               *type = VM_FAULT_MAJOR;
5763 +       return page;
5764 +}
5765 +
5766 +static struct vm_operations_struct pax_vm_ops = {
5767 +       .close = pax_syscall_close,
5768 +       .nopage = pax_syscall_nopage,
5769 +};
5770 +
5771 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
5772 +{
5773 +       int ret;
5774 +
5775 +       memset(vma, 0, sizeof(*vma));
5776 +       vma->vm_mm = current->mm;
5777 +       vma->vm_start = addr;
5778 +       vma->vm_end = addr + PAGE_SIZE;
5779 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
5780 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
5781 +       vma->vm_ops = &pax_vm_ops;
5782 +
5783 +       ret = insert_vm_struct(current->mm, vma);
5784 +       if (ret)
5785 +               return ret;
5786 +
5787 +       ++current->mm->total_vm;
5788 +       return 0;
5789 +}
5790 +#endif
5791 +
5792 +#ifdef CONFIG_PAX_PAGEEXEC
5793 +/*
5794 + * PaX: decide what to do with offenders (regs->nip = fault address)
5795 + *
5796 + * returns 1 when task should be killed
5797 + *         2 when patched GOT trampoline was detected
5798 + *         3 when patched PLT trampoline was detected
5799 + *         4 when unpatched PLT trampoline was detected
5800 + *         5 when sigreturn trampoline was detected
5801 + *         7 when rt_sigreturn trampoline was detected
5802 + */
5803 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5804 +{
5805 +
5806 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
5807 +       int err;
5808 +#endif
5809 +
5810 +#ifdef CONFIG_PAX_EMUPLT
5811 +       do { /* PaX: patched GOT emulation */
5812 +               unsigned int blrl;
5813 +
5814 +               err = get_user(blrl, (unsigned int*)regs->nip);
5815 +
5816 +               if (!err && blrl == 0x4E800021U) {
5817 +                       unsigned long temp = regs->nip;
5818 +
5819 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
5820 +                       regs->link = temp + 4UL;
5821 +                       return 2;
5822 +               }
5823 +       } while (0);
5824 +
5825 +       do { /* PaX: patched PLT emulation #1 */
5826 +               unsigned int b;
5827 +
5828 +               err = get_user(b, (unsigned int *)regs->nip);
5829 +
5830 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
5831 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
5832 +                       return 3;
5833 +               }
5834 +       } while (0);
5835 +
5836 +       do { /* PaX: unpatched PLT emulation #1 */
5837 +               unsigned int li, b;
5838 +
5839 +               err = get_user(li, (unsigned int *)regs->nip);
5840 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
5841 +
5842 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
5843 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
5844 +                       unsigned long addr = b | 0xFC000000UL;
5845 +
5846 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5847 +                       err = get_user(rlwinm, (unsigned int*)addr);
5848 +                       err |= get_user(add, (unsigned int*)(addr+4));
5849 +                       err |= get_user(li2, (unsigned int*)(addr+8));
5850 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
5851 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
5852 +                       err |= get_user(li3, (unsigned int*)(addr+20));
5853 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
5854 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
5855 +
5856 +                       if (err)
5857 +                               break;
5858 +
5859 +                       if (rlwinm == 0x556C083CU &&
5860 +                           add == 0x7D6C5A14U &&
5861 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
5862 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
5863 +                           mtctr == 0x7D8903A6U &&
5864 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
5865 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
5866 +                           bctr == 0x4E800420U)
5867 +                       {
5868 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5869 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5870 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
5871 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5872 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
5873 +                               regs->nip = regs->ctr;
5874 +                               return 4;
5875 +                       }
5876 +               }
5877 +       } while (0);
5878 +
5879 +#if 0
5880 +       do { /* PaX: unpatched PLT emulation #2 */
5881 +               unsigned int lis, lwzu, b, bctr;
5882 +
5883 +               err = get_user(lis, (unsigned int *)regs->nip);
5884 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
5885 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
5886 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
5887 +
5888 +               if (err)
5889 +                       break;
5890 +
5891 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
5892 +                   (lwzu & 0xU) == 0xU &&
5893 +                   (b & 0xFC000003U) == 0x48000000U &&
5894 +                   bctr == 0x4E800420U)
5895 +               {
5896 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
5897 +                       unsigned long addr = b | 0xFC000000UL;
5898 +
5899 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5900 +                       err = get_user(addis, (unsigned int*)addr);
5901 +                       err |= get_user(addi, (unsigned int*)(addr+4));
5902 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
5903 +                       err |= get_user(add, (unsigned int*)(addr+12));
5904 +                       err |= get_user(li2, (unsigned int*)(addr+16));
5905 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
5906 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
5907 +                       err |= get_user(li3, (unsigned int*)(addr+28));
5908 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
5909 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
5910 +
5911 +                       if (err)
5912 +                               break;
5913 +
5914 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
5915 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
5916 +                           rlwinm == 0x556C083CU &&
5917 +                           add == 0x7D6C5A14U &&
5918 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
5919 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
5920 +                           mtctr == 0x7D8903A6U &&
5921 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
5922 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
5923 +                           bctr == 0x4E800420U)
5924 +                       {
5925 +                               regs->gpr[PT_R11] = 
5926 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5927 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5928 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
5929 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5930 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
5931 +                               regs->nip = regs->ctr;
5932 +                               return 4;
5933 +                       }
5934 +               }
5935 +       } while (0);
5936 +#endif
5937 +
5938 +       do { /* PaX: unpatched PLT emulation #3 */
5939 +               unsigned int li, b;
5940 +
5941 +               err = get_user(li, (unsigned int *)regs->nip);
5942 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
5943 +
5944 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
5945 +                       unsigned int addis, lwz, mtctr, bctr;
5946 +                       unsigned long addr = b | 0xFC000000UL;
5947 +
5948 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5949 +                       err = get_user(addis, (unsigned int*)addr);
5950 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
5951 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
5952 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
5953 +
5954 +                       if (err)
5955 +                               break;
5956 +
5957 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
5958 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
5959 +                           mtctr == 0x7D6903A6U &&
5960 +                           bctr == 0x4E800420U)
5961 +                       {
5962 +                               unsigned int r11;
5963 +
5964 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5965 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5966 +
5967 +                               err = get_user(r11, (unsigned int*)addr);
5968 +                               if (err)
5969 +                                       break;
5970 +
5971 +                               regs->gpr[PT_R11] = r11;
5972 +                               regs->ctr = r11;
5973 +                               regs->nip = r11;
5974 +                               return 4;
5975 +                       }
5976 +               }
5977 +       } while (0);
5978 +#endif
5979 +
5980 +#ifdef CONFIG_PAX_EMUSIGRT
5981 +       do { /* PaX: sigreturn emulation */
5982 +               unsigned int li, sc;
5983 +
5984 +               err = get_user(li, (unsigned int *)regs->nip);
5985 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
5986 +
5987 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
5988 +                       struct vm_area_struct *vma;
5989 +                       unsigned long call_syscall;
5990 +
5991 +                       down_read(&current->mm->mmap_sem);
5992 +                       call_syscall = current->mm->call_syscall;
5993 +                       up_read(&current->mm->mmap_sem);
5994 +                       if (likely(call_syscall))
5995 +                               goto emulate;
5996 +
5997 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5998 +
5999 +                       down_write(&current->mm->mmap_sem);
6000 +                       if (current->mm->call_syscall) {
6001 +                               call_syscall = current->mm->call_syscall;
6002 +                               up_write(&current->mm->mmap_sem);
6003 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6004 +                               goto emulate;
6005 +                       }
6006 +
6007 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6008 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
6009 +                               up_write(&current->mm->mmap_sem);
6010 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6011 +                               return 1;
6012 +                       }
6013 +
6014 +                       if (pax_insert_vma(vma, call_syscall)) {
6015 +                               up_write(&current->mm->mmap_sem);
6016 +                               kmem_cache_free(vm_area_cachep, vma);
6017 +                               return 1;
6018 +                       }
6019 +
6020 +                       current->mm->call_syscall = call_syscall;
6021 +                       up_write(&current->mm->mmap_sem);
6022 +
6023 +emulate:
6024 +                       regs->gpr[PT_R0] = __NR_sigreturn;
6025 +                       regs->nip = call_syscall;
6026 +                       return 5;
6027 +               }
6028 +       } while (0);
6029 +
6030 +       do { /* PaX: rt_sigreturn emulation */
6031 +               unsigned int li, sc;
6032 +
6033 +               err = get_user(li, (unsigned int *)regs->nip);
6034 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
6035 +
6036 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
6037 +                       struct vm_area_struct *vma;
6038 +                       unsigned int call_syscall;
6039 +
6040 +                       down_read(&current->mm->mmap_sem);
6041 +                       call_syscall = current->mm->call_syscall;
6042 +                       up_read(&current->mm->mmap_sem);
6043 +                       if (likely(call_syscall))
6044 +                               goto rt_emulate;
6045 +
6046 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6047 +
6048 +                       down_write(&current->mm->mmap_sem);
6049 +                       if (current->mm->call_syscall) {
6050 +                               call_syscall = current->mm->call_syscall;
6051 +                               up_write(&current->mm->mmap_sem);
6052 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6053 +                               goto rt_emulate;
6054 +                       }
6055 +
6056 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6057 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
6058 +                               up_write(&current->mm->mmap_sem);
6059 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
6060 +                               return 1;
6061 +                       }
6062 +
6063 +                       if (pax_insert_vma(vma, call_syscall)) {
6064 +                               up_write(&current->mm->mmap_sem);
6065 +                               kmem_cache_free(vm_area_cachep, vma);
6066 +                               return 1;
6067 +                       }
6068 +
6069 +                       current->mm->call_syscall = call_syscall;
6070 +                       up_write(&current->mm->mmap_sem);
6071 +
6072 +rt_emulate:
6073 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
6074 +                       regs->nip = call_syscall;
6075 +                       return 6;
6076 +               }
6077 +       } while (0);
6078 +#endif
6079 +
6080 +       return 1;
6081 +}
6082 +
6083 +void pax_report_insns(void *pc, void *sp)
6084 +{
6085 +       unsigned long i;
6086 +
6087 +       printk(KERN_ERR "PAX: bytes at PC: ");
6088 +       for (i = 0; i < 5; i++) {
6089 +               unsigned int c;
6090 +               if (get_user(c, (unsigned int*)pc+i))
6091 +                       printk("???????? ");
6092 +               else
6093 +                       printk("%08x ", c);
6094 +       }
6095 +       printk("\n");
6096 +}
6097 +#endif
6098 +
6099  /*
6100   * Check whether the instruction at regs->nip is a store using
6101   * an update addressing form which will update r1.
6102 @@ -109,7 +472,7 @@ int do_page_fault(struct pt_regs *regs, 
6103          * indicate errors in DSISR but can validly be set in SRR1.
6104          */
6105         if (TRAP(regs) == 0x400)
6106 -               error_code &= 0x48200000;
6107 +               error_code &= 0x58200000;
6108         else
6109                 is_write = error_code & 0x02000000;
6110  #endif /* CONFIG_4xx || CONFIG_BOOKE */
6111 @@ -204,15 +567,14 @@ good_area:
6112                 pte_t *ptep;
6113                 pmd_t *pmdp;
6114  
6115 -#if 0
6116 +#if 1
6117                 /* It would be nice to actually enforce the VM execute
6118                    permission on CPUs which can do so, but far too
6119                    much stuff in userspace doesn't get the permissions
6120                    right, so we let any page be executed for now. */
6121                 if (! (vma->vm_flags & VM_EXEC))
6122                         goto bad_area;
6123 -#endif
6124 -
6125 +#else
6126                 /* Since 4xx/Book-E supports per-page execute permission,
6127                  * we lazily flush dcache to icache. */
6128                 ptep = NULL;
6129 @@ -235,6 +597,7 @@ good_area:
6130                         pte_unmap_unlock(ptep, ptl);
6131                 }
6132  #endif
6133 +#endif
6134         /* a read */
6135         } else {
6136                 /* protection fault */
6137 @@ -280,6 +643,33 @@ bad_area:
6138  
6139         /* User mode accesses cause a SIGSEGV */
6140         if (user_mode(regs)) {
6141 +
6142 +#ifdef CONFIG_PAX_PAGEEXEC
6143 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
6144 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
6145 +                               switch (pax_handle_fetch_fault(regs)) {
6146 +
6147 +#ifdef CONFIG_PAX_EMUPLT
6148 +                               case 2:
6149 +                               case 3:
6150 +                               case 4:
6151 +                                       return 0;
6152 +#endif
6153 +
6154 +#ifdef CONFIG_PAX_EMUSIGRT
6155 +                               case 5:
6156 +                               case 6:
6157 +                                       return 0;
6158 +#endif
6159 +
6160 +                               }
6161 +
6162 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
6163 +                               do_exit(SIGKILL);
6164 +                       }
6165 +               }
6166 +#endif
6167 +
6168                 _exception(SIGSEGV, regs, code, address);
6169                 return 0;
6170         }
6171 diff -urNp linux-2.6.17.11/arch/s390/kernel/module.c linux-2.6.17.11/arch/s390/kernel/module.c
6172 --- linux-2.6.17.11/arch/s390/kernel/module.c   2006-08-07 00:18:54.000000000 -0400
6173 +++ linux-2.6.17.11/arch/s390/kernel/module.c   2006-09-01 16:20:28.000000000 -0400
6174 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
6175  
6176         /* Increase core size by size of got & plt and set start
6177            offsets for got and plt. */
6178 -       me->core_size = ALIGN(me->core_size, 4);
6179 -       me->arch.got_offset = me->core_size;
6180 -       me->core_size += me->arch.got_size;
6181 -       me->arch.plt_offset = me->core_size;
6182 -       me->core_size += me->arch.plt_size;
6183 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
6184 +       me->arch.got_offset = me->core_size_rw;
6185 +       me->core_size_rw += me->arch.got_size;
6186 +       me->arch.plt_offset = me->core_size_rx;
6187 +       me->core_size_rx += me->arch.plt_size;
6188         return 0;
6189  }
6190  
6191 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6192                 if (info->got_initialized == 0) {
6193                         Elf_Addr *gotent;
6194  
6195 -                       gotent = me->module_core + me->arch.got_offset +
6196 +                       gotent = me->module_core_rw + me->arch.got_offset +
6197                                 info->got_offset;
6198                         *gotent = val;
6199                         info->got_initialized = 1;
6200 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6201                 else if (r_type == R_390_GOTENT ||
6202                          r_type == R_390_GOTPLTENT)
6203                         *(unsigned int *) loc =
6204 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
6205 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
6206                 else if (r_type == R_390_GOT64 ||
6207                          r_type == R_390_GOTPLT64)
6208                         *(unsigned long *) loc = val;
6209 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6210         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
6211                 if (info->plt_initialized == 0) {
6212                         unsigned int *ip;
6213 -                       ip = me->module_core + me->arch.plt_offset +
6214 +                       ip = me->module_core_rx + me->arch.plt_offset +
6215                                 info->plt_offset;
6216  #ifndef CONFIG_64BIT
6217                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
6218 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6219                         val = me->arch.plt_offset - me->arch.got_offset +
6220                                 info->plt_offset + rela->r_addend;
6221                 else
6222 -                       val =  (Elf_Addr) me->module_core +
6223 +                       val =  (Elf_Addr) me->module_core_rx +
6224                                 me->arch.plt_offset + info->plt_offset + 
6225                                 rela->r_addend - loc;
6226                 if (r_type == R_390_PLT16DBL)
6227 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6228         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
6229         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
6230                 val = val + rela->r_addend -
6231 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
6232 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
6233                 if (r_type == R_390_GOTOFF16)
6234                         *(unsigned short *) loc = val;
6235                 else if (r_type == R_390_GOTOFF32)
6236 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6237                 break;
6238         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
6239         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
6240 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
6241 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
6242                         rela->r_addend - loc;
6243                 if (r_type == R_390_GOTPC)
6244                         *(unsigned int *) loc = val;
6245 diff -urNp linux-2.6.17.11/arch/sparc/kernel/ptrace.c linux-2.6.17.11/arch/sparc/kernel/ptrace.c
6246 --- linux-2.6.17.11/arch/sparc/kernel/ptrace.c  2006-08-07 00:18:54.000000000 -0400
6247 +++ linux-2.6.17.11/arch/sparc/kernel/ptrace.c  2006-09-01 16:20:28.000000000 -0400
6248 @@ -20,6 +20,7 @@
6249  #include <linux/security.h>
6250  #include <linux/signal.h>
6251  #include <linux/vs_pid.h>
6252 +#include <linux/grsecurity.h>
6253  
6254  #include <asm/pgtable.h>
6255  #include <asm/system.h>
6256 @@ -305,6 +306,11 @@ asmlinkage void do_ptrace(struct pt_regs
6257                 goto out_tsk;
6258         }
6259  
6260 +       if (gr_handle_ptrace(child, request)) {
6261 +               pt_error_return(regs, EPERM);
6262 +               goto out_tsk;
6263 +       }
6264 +
6265         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
6266             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
6267                 if (ptrace_attach(child)) {
6268 diff -urNp linux-2.6.17.11/arch/sparc/kernel/sys_sparc.c linux-2.6.17.11/arch/sparc/kernel/sys_sparc.c
6269 --- linux-2.6.17.11/arch/sparc/kernel/sys_sparc.c       2006-08-23 19:30:00.000000000 -0400
6270 +++ linux-2.6.17.11/arch/sparc/kernel/sys_sparc.c       2006-09-01 16:20:28.000000000 -0400
6271 @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
6272         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
6273                 return -ENOMEM;
6274         if (!addr)
6275 -               addr = TASK_UNMAPPED_BASE;
6276 +               addr = current->mm->mmap_base;
6277  
6278         if (flags & MAP_SHARED)
6279                 addr = COLOUR_ALIGN(addr);
6280 diff -urNp linux-2.6.17.11/arch/sparc/Makefile linux-2.6.17.11/arch/sparc/Makefile
6281 --- linux-2.6.17.11/arch/sparc/Makefile 2006-08-07 00:18:54.000000000 -0400
6282 +++ linux-2.6.17.11/arch/sparc/Makefile 2006-09-01 16:20:28.000000000 -0400
6283 @@ -34,7 +34,7 @@ libs-y += arch/sparc/prom/ arch/sparc/li
6284  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
6285  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
6286  CORE_Y         := $(core-y)
6287 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
6288 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
6289  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
6290  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
6291  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
6292 diff -urNp linux-2.6.17.11/arch/sparc/mm/fault.c linux-2.6.17.11/arch/sparc/mm/fault.c
6293 --- linux-2.6.17.11/arch/sparc/mm/fault.c       2006-08-07 00:18:54.000000000 -0400
6294 +++ linux-2.6.17.11/arch/sparc/mm/fault.c       2006-09-01 16:20:28.000000000 -0400
6295 @@ -21,6 +21,10 @@
6296  #include <linux/smp_lock.h>
6297  #include <linux/interrupt.h>
6298  #include <linux/module.h>
6299 +#include <linux/slab.h>
6300 +#include <linux/pagemap.h>
6301 +#include <linux/compiler.h>
6302 +#include <linux/binfmts.h>
6303  
6304  #include <asm/system.h>
6305  #include <asm/page.h>
6306 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
6307         return safe_compute_effective_address(regs, insn);
6308  }
6309  
6310 +#ifdef CONFIG_PAX_PAGEEXEC
6311 +void pax_emuplt_close(struct vm_area_struct * vma)
6312 +{
6313 +       vma->vm_mm->call_dl_resolve = 0UL;
6314 +}
6315 +
6316 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6317 +{
6318 +       struct page* page;
6319 +       unsigned int *kaddr;
6320 +
6321 +       page = alloc_page(GFP_HIGHUSER);
6322 +       if (!page)
6323 +               return NOPAGE_OOM;
6324 +
6325 +       kaddr = kmap(page);
6326 +       memset(kaddr, 0, PAGE_SIZE);
6327 +       kaddr[0] = 0x9DE3BFA8U; /* save */
6328 +       flush_dcache_page(page);
6329 +       kunmap(page);
6330 +       if (type)
6331 +               *type = VM_FAULT_MAJOR;
6332 +
6333 +       return page;
6334 +}
6335 +
6336 +static struct vm_operations_struct pax_vm_ops = {
6337 +       .close = pax_emuplt_close,
6338 +       .nopage = pax_emuplt_nopage,
6339 +};
6340 +
6341 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6342 +{
6343 +       int ret;
6344 +
6345 +       memset(vma, 0, sizeof(*vma));
6346 +       vma->vm_mm = current->mm;
6347 +       vma->vm_start = addr;
6348 +       vma->vm_end = addr + PAGE_SIZE;
6349 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6350 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6351 +       vma->vm_ops = &pax_vm_ops;
6352 +
6353 +       ret = insert_vm_struct(current->mm, vma);
6354 +       if (ret)
6355 +               return ret;
6356 +
6357 +       ++current->mm->total_vm;
6358 +       return 0;
6359 +}
6360 +
6361 +/*
6362 + * PaX: decide what to do with offenders (regs->pc = fault address)
6363 + *
6364 + * returns 1 when task should be killed
6365 + *         2 when patched PLT trampoline was detected
6366 + *         3 when unpatched PLT trampoline was detected
6367 + */
6368 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6369 +{
6370 +
6371 +#ifdef CONFIG_PAX_EMUPLT
6372 +       int err;
6373 +
6374 +       do { /* PaX: patched PLT emulation #1 */
6375 +               unsigned int sethi1, sethi2, jmpl;
6376 +
6377 +               err = get_user(sethi1, (unsigned int*)regs->pc);
6378 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
6379 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
6380 +
6381 +               if (err)
6382 +                       break;
6383 +
6384 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6385 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
6386 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
6387 +               {
6388 +                       unsigned int addr;
6389 +
6390 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
6391 +                       addr = regs->u_regs[UREG_G1];
6392 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
6393 +                       regs->pc = addr;
6394 +                       regs->npc = addr+4;
6395 +                       return 2;
6396 +               }
6397 +       } while (0);
6398 +
6399 +       { /* PaX: patched PLT emulation #2 */
6400 +               unsigned int ba;
6401 +
6402 +               err = get_user(ba, (unsigned int*)regs->pc);
6403 +
6404 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
6405 +                       unsigned int addr;
6406 +
6407 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
6408 +                       regs->pc = addr;
6409 +                       regs->npc = addr+4;
6410 +                       return 2;
6411 +               }
6412 +       }
6413 +
6414 +       do { /* PaX: patched PLT emulation #3 */
6415 +               unsigned int sethi, jmpl, nop;
6416 +
6417 +               err = get_user(sethi, (unsigned int*)regs->pc);
6418 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
6419 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
6420 +
6421 +               if (err)
6422 +                       break;
6423 +
6424 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6425 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
6426 +                   nop == 0x01000000U)
6427 +               {
6428 +                       unsigned int addr;
6429 +
6430 +                       addr = (sethi & 0x003FFFFFU) << 10;
6431 +                       regs->u_regs[UREG_G1] = addr;
6432 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
6433 +                       regs->pc = addr;
6434 +                       regs->npc = addr+4;
6435 +                       return 2;
6436 +               }
6437 +       } while (0);
6438 +
6439 +       do { /* PaX: unpatched PLT emulation step 1 */
6440 +               unsigned int sethi, ba, nop;
6441 +
6442 +               err = get_user(sethi, (unsigned int*)regs->pc);
6443 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
6444 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
6445 +
6446 +               if (err)
6447 +                       break;
6448 +
6449 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6450 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
6451 +                   nop == 0x01000000U)
6452 +               {
6453 +                       unsigned int addr, save, call;
6454 +
6455 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
6456 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
6457 +                       else
6458 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
6459 +
6460 +                       err = get_user(save, (unsigned int*)addr);
6461 +                       err |= get_user(call, (unsigned int*)(addr+4));
6462 +                       err |= get_user(nop, (unsigned int*)(addr+8));
6463 +                       if (err)
6464 +                               break;
6465 +
6466 +                       if (save == 0x9DE3BFA8U &&
6467 +                           (call & 0xC0000000U) == 0x40000000U &&
6468 +                           nop == 0x01000000U)
6469 +                       {
6470 +                               struct vm_area_struct *vma;
6471 +                               unsigned long call_dl_resolve;
6472 +
6473 +                               down_read(&current->mm->mmap_sem);
6474 +                               call_dl_resolve = current->mm->call_dl_resolve;
6475 +                               up_read(&current->mm->mmap_sem);
6476 +                               if (likely(call_dl_resolve))
6477 +                                       goto emulate;
6478 +
6479 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6480 +
6481 +                               down_write(&current->mm->mmap_sem);
6482 +                               if (current->mm->call_dl_resolve) {
6483 +                                       call_dl_resolve = current->mm->call_dl_resolve;
6484 +                                       up_write(&current->mm->mmap_sem);
6485 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
6486 +                                       goto emulate;
6487 +                               }
6488 +
6489 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6490 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
6491 +                                       up_write(&current->mm->mmap_sem);
6492 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
6493 +                                       return 1;
6494 +                               }
6495 +
6496 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
6497 +                                       up_write(&current->mm->mmap_sem);
6498 +                                       kmem_cache_free(vm_area_cachep, vma);
6499 +                                       return 1;
6500 +                               }
6501 +
6502 +                               current->mm->call_dl_resolve = call_dl_resolve;
6503 +                               up_write(&current->mm->mmap_sem);
6504 +
6505 +emulate:
6506 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
6507 +                               regs->pc = call_dl_resolve;
6508 +                               regs->npc = addr+4;
6509 +                               return 3;
6510 +                       }
6511 +               }
6512 +       } while (0);
6513 +
6514 +       do { /* PaX: unpatched PLT emulation step 2 */
6515 +               unsigned int save, call, nop;
6516 +
6517 +               err = get_user(save, (unsigned int*)(regs->pc-4));
6518 +               err |= get_user(call, (unsigned int*)regs->pc);
6519 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
6520 +               if (err)
6521 +                       break;
6522 +
6523 +               if (save == 0x9DE3BFA8U &&
6524 +                   (call & 0xC0000000U) == 0x40000000U &&
6525 +                   nop == 0x01000000U)
6526 +               {
6527 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
6528 +
6529 +                       regs->u_regs[UREG_RETPC] = regs->pc;
6530 +                       regs->pc = dl_resolve;
6531 +                       regs->npc = dl_resolve+4;
6532 +                       return 3;
6533 +               }
6534 +       } while (0);
6535 +#endif
6536 +
6537 +       return 1;
6538 +}
6539 +
6540 +void pax_report_insns(void *pc, void *sp)
6541 +{
6542 +       unsigned long i;
6543 +
6544 +       printk(KERN_ERR "PAX: bytes at PC: ");
6545 +       for (i = 0; i < 5; i++) {
6546 +               unsigned int c;
6547 +               if (get_user(c, (unsigned int*)pc+i))
6548 +                       printk("???????? ");
6549 +               else
6550 +                       printk("%08x ", c);
6551 +       }
6552 +       printk("\n");
6553 +}
6554 +#endif
6555 +
6556  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
6557                                unsigned long address)
6558  {
6559 @@ -280,6 +530,24 @@ good_area:
6560                 if(!(vma->vm_flags & VM_WRITE))
6561                         goto bad_area;
6562         } else {
6563 +
6564 +#ifdef CONFIG_PAX_PAGEEXEC
6565 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
6566 +                       up_read(&mm->mmap_sem);
6567 +                       switch (pax_handle_fetch_fault(regs)) {
6568 +
6569 +#ifdef CONFIG_PAX_EMUPLT
6570 +                       case 2:
6571 +                       case 3:
6572 +                               return;
6573 +#endif
6574 +
6575 +                       }
6576 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
6577 +                       do_exit(SIGKILL);
6578 +               }
6579 +#endif
6580 +
6581                 /* Allow reads even for write-only mappings */
6582                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
6583                         goto bad_area;
6584 diff -urNp linux-2.6.17.11/arch/sparc/mm/init.c linux-2.6.17.11/arch/sparc/mm/init.c
6585 --- linux-2.6.17.11/arch/sparc/mm/init.c        2006-08-07 00:18:54.000000000 -0400
6586 +++ linux-2.6.17.11/arch/sparc/mm/init.c        2006-09-01 16:20:28.000000000 -0400
6587 @@ -333,17 +333,17 @@ void __init paging_init(void)
6588  
6589         /* Initialize the protection map with non-constant, MMU dependent values. */
6590         protection_map[0] = PAGE_NONE;
6591 -       protection_map[1] = PAGE_READONLY;
6592 -       protection_map[2] = PAGE_COPY;
6593 -       protection_map[3] = PAGE_COPY;
6594 +       protection_map[1] = PAGE_READONLY_NOEXEC;
6595 +       protection_map[2] = PAGE_COPY_NOEXEC;
6596 +       protection_map[3] = PAGE_COPY_NOEXEC;
6597         protection_map[4] = PAGE_READONLY;
6598         protection_map[5] = PAGE_READONLY;
6599         protection_map[6] = PAGE_COPY;
6600         protection_map[7] = PAGE_COPY;
6601         protection_map[8] = PAGE_NONE;
6602 -       protection_map[9] = PAGE_READONLY;
6603 -       protection_map[10] = PAGE_SHARED;
6604 -       protection_map[11] = PAGE_SHARED;
6605 +       protection_map[9] = PAGE_READONLY_NOEXEC;
6606 +       protection_map[10] = PAGE_SHARED_NOEXEC;
6607 +       protection_map[11] = PAGE_SHARED_NOEXEC;
6608         protection_map[12] = PAGE_READONLY;
6609         protection_map[13] = PAGE_READONLY;
6610         protection_map[14] = PAGE_SHARED;
6611 diff -urNp linux-2.6.17.11/arch/sparc/mm/srmmu.c linux-2.6.17.11/arch/sparc/mm/srmmu.c
6612 --- linux-2.6.17.11/arch/sparc/mm/srmmu.c       2006-08-07 00:18:54.000000000 -0400
6613 +++ linux-2.6.17.11/arch/sparc/mm/srmmu.c       2006-09-01 16:20:28.000000000 -0400
6614 @@ -2161,6 +2161,13 @@ void __init ld_mmu_srmmu(void)
6615         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
6616         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
6617         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
6618 +
6619 +#ifdef CONFIG_PAX_PAGEEXEC
6620 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
6621 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
6622 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
6623 +#endif
6624 +
6625         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
6626         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
6627  
6628 diff -urNp linux-2.6.17.11/arch/sparc64/kernel/ptrace.c linux-2.6.17.11/arch/sparc64/kernel/ptrace.c
6629 --- linux-2.6.17.11/arch/sparc64/kernel/ptrace.c        2006-08-07 00:18:54.000000000 -0400
6630 +++ linux-2.6.17.11/arch/sparc64/kernel/ptrace.c        2006-09-01 16:20:28.000000000 -0400
6631 @@ -23,6 +23,7 @@
6632  #include <linux/audit.h>
6633  #include <linux/signal.h>
6634  #include <linux/vs_pid.h>
6635 +#include <linux/grsecurity.h>
6636  
6637  #include <asm/asi.h>
6638  #include <asm/pgtable.h>
6639 @@ -218,6 +219,11 @@ asmlinkage void do_ptrace(struct pt_regs
6640                 goto out_tsk;
6641         }
6642  
6643 +       if (gr_handle_ptrace(child, (long)request)) {
6644 +               pt_error_return(regs, EPERM);
6645 +               goto out_tsk;
6646 +       }
6647 +
6648         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
6649             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
6650                 if (ptrace_attach(child)) {
6651 diff -urNp linux-2.6.17.11/arch/sparc64/kernel/sys_sparc.c linux-2.6.17.11/arch/sparc64/kernel/sys_sparc.c
6652 --- linux-2.6.17.11/arch/sparc64/kernel/sys_sparc.c     2006-08-23 19:30:00.000000000 -0400
6653 +++ linux-2.6.17.11/arch/sparc64/kernel/sys_sparc.c     2006-09-01 16:20:28.000000000 -0400
6654 @@ -141,6 +141,10 @@ unsigned long arch_get_unmapped_area(str
6655         if (filp || (flags & MAP_SHARED))
6656                 do_color_align = 1;
6657  
6658 +#ifdef CONFIG_PAX_RANDMMAP
6659 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6660 +#endif
6661 +
6662         if (addr) {
6663                 if (do_color_align)
6664                         addr = COLOUR_ALIGN(addr, pgoff);
6665 @@ -154,9 +158,9 @@ unsigned long arch_get_unmapped_area(str
6666         }
6667  
6668         if (len > mm->cached_hole_size) {
6669 -               start_addr = addr = mm->free_area_cache;
6670 +               start_addr = addr = mm->free_area_cache;
6671         } else {
6672 -               start_addr = addr = TASK_UNMAPPED_BASE;
6673 +               start_addr = addr = mm->mmap_base;
6674                 mm->cached_hole_size = 0;
6675         }
6676  
6677 @@ -176,8 +180,8 @@ full_search:
6678                         vma = find_vma(mm, VA_EXCLUDE_END);
6679                 }
6680                 if (unlikely(task_size < addr)) {
6681 -                       if (start_addr != TASK_UNMAPPED_BASE) {
6682 -                               start_addr = addr = TASK_UNMAPPED_BASE;
6683 +                       if (start_addr != mm->mmap_base) {
6684 +                               start_addr = addr = mm->mmap_base;
6685                                 mm->cached_hole_size = 0;
6686                                 goto full_search;
6687                         }
6688 @@ -380,6 +384,12 @@ void arch_pick_mmap_layout(struct mm_str
6689             current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
6690             sysctl_legacy_va_layout) {
6691                 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
6692 +
6693 +#ifdef CONFIG_PAX_RANDMMAP
6694 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6695 +                       mm->mmap_base += mm->delta_mmap;
6696 +#endif
6697 +
6698                 mm->get_unmapped_area = arch_get_unmapped_area;
6699                 mm->unmap_area = arch_unmap_area;
6700         } else {
6701 @@ -394,6 +404,12 @@ void arch_pick_mmap_layout(struct mm_str
6702                         gap = (task_size / 6 * 5);
6703  
6704                 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
6705 +
6706 +#ifdef CONFIG_PAX_RANDMMAP
6707 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6708 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
6709 +#endif
6710 +
6711                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
6712                 mm->unmap_area = arch_unmap_area_topdown;
6713         }
6714 diff -urNp linux-2.6.17.11/arch/sparc64/mm/fault.c linux-2.6.17.11/arch/sparc64/mm/fault.c
6715 --- linux-2.6.17.11/arch/sparc64/mm/fault.c     2006-08-07 00:18:54.000000000 -0400
6716 +++ linux-2.6.17.11/arch/sparc64/mm/fault.c     2006-09-01 16:20:28.000000000 -0400
6717 @@ -19,6 +19,10 @@
6718  #include <linux/init.h>
6719  #include <linux/interrupt.h>
6720  #include <linux/kprobes.h>
6721 +#include <linux/slab.h>
6722 +#include <linux/pagemap.h>
6723 +#include <linux/compiler.h>
6724 +#include <linux/binfmts.h>
6725  
6726  #include <asm/page.h>
6727  #include <asm/pgtable.h>
6728 @@ -253,6 +257,369 @@ cannot_handle:
6729         unhandled_fault (address, current, regs);
6730  }
6731  
6732 +#ifdef CONFIG_PAX_PAGEEXEC
6733 +#ifdef CONFIG_PAX_EMUPLT
6734 +static void pax_emuplt_close(struct vm_area_struct * vma)
6735 +{
6736 +       vma->vm_mm->call_dl_resolve = 0UL;
6737 +}
6738 +
6739 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6740 +{
6741 +       struct page* page;
6742 +       unsigned int *kaddr;
6743 +
6744 +       page = alloc_page(GFP_HIGHUSER);
6745 +       if (!page)
6746 +               return NOPAGE_OOM;
6747 +
6748 +       kaddr = kmap(page);
6749 +       memset(kaddr, 0, PAGE_SIZE);
6750 +       kaddr[0] = 0x9DE3BFA8U; /* save */
6751 +       flush_dcache_page(page);
6752 +       kunmap(page);
6753 +       if (type)
6754 +               *type = VM_FAULT_MAJOR;
6755 +       return page;
6756 +}
6757 +
6758 +static struct vm_operations_struct pax_vm_ops = {
6759 +       .close = pax_emuplt_close,
6760 +       .nopage = pax_emuplt_nopage,
6761 +};
6762 +
6763 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6764 +{
6765 +       int ret;
6766 +
6767 +       memset(vma, 0, sizeof(*vma));
6768 +       vma->vm_mm = current->mm;
6769 +       vma->vm_start = addr;
6770 +       vma->vm_end = addr + PAGE_SIZE;
6771 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6772 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6773 +       vma->vm_ops = &pax_vm_ops;
6774 +
6775 +       ret = insert_vm_struct(current->mm, vma);
6776 +       if (ret)
6777 +               return ret;
6778 +
6779 +       ++current->mm->total_vm;
6780 +       return 0;
6781 +}
6782 +#endif
6783 +
6784 +/*
6785 + * PaX: decide what to do with offenders (regs->tpc = fault address)
6786 + *
6787 + * returns 1 when task should be killed
6788 + *         2 when patched PLT trampoline was detected
6789 + *         3 when unpatched PLT trampoline was detected
6790 + */
6791 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6792 +{
6793 +
6794 +#ifdef CONFIG_PAX_EMUPLT
6795 +       int err;
6796 +
6797 +       do { /* PaX: patched PLT emulation #1 */
6798 +               unsigned int sethi1, sethi2, jmpl;
6799 +
6800 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
6801 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6802 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
6803 +
6804 +               if (err)
6805 +                       break;
6806 +
6807 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6808 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
6809 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
6810 +               {
6811 +                       unsigned long addr;
6812 +
6813 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
6814 +                       addr = regs->u_regs[UREG_G1];
6815 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
6816 +                       regs->tpc = addr;
6817 +                       regs->tnpc = addr+4;
6818 +                       return 2;
6819 +               }
6820 +       } while (0);
6821 +
6822 +       { /* PaX: patched PLT emulation #2 */
6823 +               unsigned int ba;
6824 +
6825 +               err = get_user(ba, (unsigned int*)regs->tpc);
6826 +
6827 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
6828 +                       unsigned long addr;
6829 +
6830 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
6831 +                       regs->tpc = addr;
6832 +                       regs->tnpc = addr+4;
6833 +                       return 2;
6834 +               }
6835 +       }
6836 +
6837 +       do { /* PaX: patched PLT emulation #3 */
6838 +               unsigned int sethi, jmpl, nop;
6839 +
6840 +               err = get_user(sethi, (unsigned int*)regs->tpc);
6841 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
6842 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6843 +
6844 +               if (err)
6845 +                       break;
6846 +
6847 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6848 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
6849 +                   nop == 0x01000000U)
6850 +               {
6851 +                       unsigned long addr;
6852 +
6853 +                       addr = (sethi & 0x003FFFFFU) << 10;
6854 +                       regs->u_regs[UREG_G1] = addr;
6855 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
6856 +                       regs->tpc = addr;
6857 +                       regs->tnpc = addr+4;
6858 +                       return 2;
6859 +               }
6860 +       } while (0);
6861 +
6862 +       do { /* PaX: patched PLT emulation #4 */
6863 +               unsigned int mov1, call, mov2;
6864 +
6865 +               err = get_user(mov1, (unsigned int*)regs->tpc);
6866 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
6867 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
6868 +
6869 +               if (err)
6870 +                       break;
6871 +
6872 +               if (mov1 == 0x8210000FU &&
6873 +                   (call & 0xC0000000U) == 0x40000000U &&
6874 +                   mov2 == 0x9E100001U)
6875 +               {
6876 +                       unsigned long addr;
6877 +
6878 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
6879 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
6880 +                       regs->tpc = addr;
6881 +                       regs->tnpc = addr+4;
6882 +                       return 2;
6883 +               }
6884 +       } while (0);
6885 +
6886 +       do { /* PaX: patched PLT emulation #5 */
6887 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
6888 +
6889 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
6890 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6891 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
6892 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
6893 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
6894 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
6895 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
6896 +
6897 +               if (err)
6898 +                       break;
6899 +
6900 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6901 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
6902 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
6903 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
6904 +                   sllx == 0x83287020 &&
6905 +                   jmpl == 0x81C04005U &&
6906 +                   nop == 0x01000000U)
6907 +               {
6908 +                       unsigned long addr;
6909 +
6910 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
6911 +                       regs->u_regs[UREG_G1] <<= 32;
6912 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
6913 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
6914 +                       regs->tpc = addr;
6915 +                       regs->tnpc = addr+4;
6916 +                       return 2;
6917 +               }
6918 +       } while (0);
6919 +
6920 +       do { /* PaX: patched PLT emulation #6 */
6921 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
6922 +
6923 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
6924 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6925 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
6926 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
6927 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
6928 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
6929 +
6930 +               if (err)
6931 +                       break;
6932 +
6933 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6934 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
6935 +                   sllx == 0x83287020 &&
6936 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
6937 +                   jmpl == 0x81C04005U &&
6938 +                   nop == 0x01000000U)
6939 +               {
6940 +                       unsigned long addr;
6941 +
6942 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
6943 +                       regs->u_regs[UREG_G1] <<= 32;
6944 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
6945 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
6946 +                       regs->tpc = addr;
6947 +                       regs->tnpc = addr+4;
6948 +                       return 2;
6949 +               }
6950 +       } while (0);
6951 +
6952 +       do { /* PaX: patched PLT emulation #7 */
6953 +               unsigned int sethi, ba, nop;
6954 +
6955 +               err = get_user(sethi, (unsigned int*)regs->tpc);
6956 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
6957 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6958 +
6959 +               if (err)
6960 +                       break;
6961 +
6962 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6963 +                   (ba & 0xFFF00000U) == 0x30600000U &&
6964 +                   nop == 0x01000000U)
6965 +               {
6966 +                       unsigned long addr;
6967 +
6968 +                       addr = (sethi & 0x003FFFFFU) << 10;
6969 +                       regs->u_regs[UREG_G1] = addr;
6970 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
6971 +                       regs->tpc = addr;
6972 +                       regs->tnpc = addr+4;
6973 +                       return 2;
6974 +               }
6975 +       } while (0);
6976 +
6977 +       do { /* PaX: unpatched PLT emulation step 1 */
6978 +               unsigned int sethi, ba, nop;
6979 +
6980 +               err = get_user(sethi, (unsigned int*)regs->tpc);
6981 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
6982 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6983 +
6984 +               if (err)
6985 +                       break;
6986 +
6987 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6988 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
6989 +                   nop == 0x01000000U)
6990 +               {
6991 +                       unsigned long addr;
6992 +                       unsigned int save, call;
6993 +
6994 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
6995 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
6996 +                       else
6997 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
6998 +
6999 +                       err = get_user(save, (unsigned int*)addr);
7000 +                       err |= get_user(call, (unsigned int*)(addr+4));
7001 +                       err |= get_user(nop, (unsigned int*)(addr+8));
7002 +                       if (err)
7003 +                               break;
7004 +
7005 +                       if (save == 0x9DE3BFA8U &&
7006 +                           (call & 0xC0000000U) == 0x40000000U &&
7007 +                           nop == 0x01000000U)
7008 +                       {
7009 +                               struct vm_area_struct *vma;
7010 +                               unsigned long call_dl_resolve;
7011 +
7012 +                               down_read(&current->mm->mmap_sem);
7013 +                               call_dl_resolve = current->mm->call_dl_resolve;
7014 +                               up_read(&current->mm->mmap_sem);
7015 +                               if (likely(call_dl_resolve))
7016 +                                       goto emulate;
7017 +
7018 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7019 +
7020 +                               down_write(&current->mm->mmap_sem);
7021 +                               if (current->mm->call_dl_resolve) {
7022 +                                       call_dl_resolve = current->mm->call_dl_resolve;
7023 +                                       up_write(&current->mm->mmap_sem);
7024 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
7025 +                                       goto emulate;
7026 +                               }
7027 +
7028 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7029 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
7030 +                                       up_write(&current->mm->mmap_sem);
7031 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
7032 +                                       return 1;
7033 +                               }
7034 +
7035 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
7036 +                                       up_write(&current->mm->mmap_sem);
7037 +                                       kmem_cache_free(vm_area_cachep, vma);
7038 +                                       return 1;
7039 +                               }
7040 +
7041 +                               current->mm->call_dl_resolve = call_dl_resolve;
7042 +                               up_write(&current->mm->mmap_sem);
7043 +
7044 +emulate:
7045 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
7046 +                               regs->tpc = call_dl_resolve;
7047 +                               regs->tnpc = addr+4;
7048 +                               return 3;
7049 +                       }
7050 +               }
7051 +       } while (0);
7052 +
7053 +       do { /* PaX: unpatched PLT emulation step 2 */
7054 +               unsigned int save, call, nop;
7055 +
7056 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
7057 +               err |= get_user(call, (unsigned int*)regs->tpc);
7058 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
7059 +               if (err)
7060 +                       break;
7061 +
7062 +               if (save == 0x9DE3BFA8U &&
7063 +                   (call & 0xC0000000U) == 0x40000000U &&
7064 +                   nop == 0x01000000U)
7065 +               {
7066 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
7067 +
7068 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
7069 +                       regs->tpc = dl_resolve;
7070 +                       regs->tnpc = dl_resolve+4;
7071 +                       return 3;
7072 +               }
7073 +       } while (0);
7074 +#endif
7075 +
7076 +       return 1;
7077 +}
7078 +
7079 +void pax_report_insns(void *pc, void *sp)
7080 +{
7081 +       unsigned long i;
7082 +
7083 +       printk(KERN_ERR "PAX: bytes at PC: ");
7084 +       for (i = 0; i < 5; i++) {
7085 +               unsigned int c;
7086 +               if (get_user(c, (unsigned int*)pc+i))
7087 +                       printk("???????? ");
7088 +               else
7089 +                       printk("%08x ", c);
7090 +       }
7091 +       printk("\n");
7092 +}
7093 +#endif
7094 +
7095  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
7096  {
7097         struct mm_struct *mm = current->mm;
7098 @@ -295,8 +662,10 @@ asmlinkage void __kprobes do_sparc64_fau
7099                 goto intr_or_no_mm;
7100  
7101         if (test_thread_flag(TIF_32BIT)) {
7102 -               if (!(regs->tstate & TSTATE_PRIV))
7103 +               if (!(regs->tstate & TSTATE_PRIV)) {
7104                         regs->tpc &= 0xffffffff;
7105 +                       regs->tnpc &= 0xffffffff;
7106 +               }
7107                 address &= 0xffffffff;
7108         }
7109  
7110 @@ -313,6 +682,29 @@ asmlinkage void __kprobes do_sparc64_fau
7111         if (!vma)
7112                 goto bad_area;
7113  
7114 +#ifdef CONFIG_PAX_PAGEEXEC
7115 +       /* PaX: detect ITLB misses on non-exec pages */
7116 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
7117 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
7118 +       {
7119 +               if (address != regs->tpc)
7120 +                       goto good_area;
7121 +
7122 +               up_read(&mm->mmap_sem);
7123 +               switch (pax_handle_fetch_fault(regs)) {
7124 +
7125 +#ifdef CONFIG_PAX_EMUPLT
7126 +               case 2:
7127 +               case 3:
7128 +                       return;
7129 +#endif
7130 +
7131 +               }
7132 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
7133 +               do_exit(SIGKILL);
7134 +       }
7135 +#endif
7136 +
7137         /* Pure DTLB misses do not tell us whether the fault causing
7138          * load/store/atomic was a write or not, it only says that there
7139          * was no match.  So in such a case we (carefully) read the
7140 diff -urNp linux-2.6.17.11/arch/v850/kernel/module.c linux-2.6.17.11/arch/v850/kernel/module.c
7141 --- linux-2.6.17.11/arch/v850/kernel/module.c   2006-08-07 00:18:54.000000000 -0400
7142 +++ linux-2.6.17.11/arch/v850/kernel/module.c   2006-09-01 16:20:28.000000000 -0400
7143 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
7144         tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
7145  
7146         /* Init, or core PLT? */
7147 -       if (location >= mod->module_core
7148 -           && location < mod->module_core + mod->core_size)
7149 +       if (location >= mod->module_core_rx
7150 +           && location < mod->module_core_rx + mod->core_size_rx)
7151                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
7152         else
7153                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
7154 diff -urNp linux-2.6.17.11/arch/x86_64/boot/compressed/head.S linux-2.6.17.11/arch/x86_64/boot/compressed/head.S
7155 --- linux-2.6.17.11/arch/x86_64/boot/compressed/head.S  2006-08-07 00:18:54.000000000 -0400
7156 +++ linux-2.6.17.11/arch/x86_64/boot/compressed/head.S  2006-09-01 16:20:28.000000000 -0400
7157 @@ -41,11 +41,13 @@ startup_32:
7158         movl %eax,%gs
7159  
7160         lss stack_start,%esp
7161 +       movl 0x000000,%ecx
7162         xorl %eax,%eax
7163  1:     incl %eax               # check that A20 really IS enabled
7164         movl %eax,0x000000      # loop forever if it isn't
7165         cmpl %eax,0x100000
7166         je 1b
7167 +       movl %ecx,0x000000
7168  
7169  /*
7170   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
7171 diff -urNp linux-2.6.17.11/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.17.11/arch/x86_64/ia32/ia32_binfmt.c
7172 --- linux-2.6.17.11/arch/x86_64/ia32/ia32_binfmt.c      2006-08-07 00:18:54.000000000 -0400
7173 +++ linux-2.6.17.11/arch/x86_64/ia32/ia32_binfmt.c      2006-09-01 16:20:28.000000000 -0400
7174 @@ -186,6 +186,17 @@ struct elf_prpsinfo
7175  //#include <asm/ia32.h>
7176  #include <linux/elf.h>
7177  
7178 +#ifdef CONFIG_PAX_ASLR
7179 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
7180 +
7181 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
7182 +#define PAX_DELTA_MMAP_LEN(tsk)                16
7183 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
7184 +#define PAX_DELTA_EXEC_LEN(tsk)                16
7185 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
7186 +#define PAX_DELTA_STACK_LEN(tsk)       16
7187 +#endif
7188 +
7189  typedef struct user_i387_ia32_struct elf_fpregset_t;
7190  typedef struct user32_fxsr_struct elf_fpxregset_t;
7191  
7192 diff -urNp linux-2.6.17.11/arch/x86_64/ia32/mmap32.c linux-2.6.17.11/arch/x86_64/ia32/mmap32.c
7193 --- linux-2.6.17.11/arch/x86_64/ia32/mmap32.c   2006-08-07 00:18:54.000000000 -0400
7194 +++ linux-2.6.17.11/arch/x86_64/ia32/mmap32.c   2006-09-01 16:20:28.000000000 -0400
7195 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
7196                         (current->personality & ADDR_COMPAT_LAYOUT) ||
7197                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
7198                 mm->mmap_base = TASK_UNMAPPED_BASE;
7199 +
7200 +#ifdef CONFIG_PAX_RANDMMAP
7201 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7202 +                       mm->mmap_base += mm->delta_mmap;
7203 +#endif
7204 +
7205                 mm->get_unmapped_area = arch_get_unmapped_area;
7206                 mm->unmap_area = arch_unmap_area;
7207         } else {
7208                 mm->mmap_base = mmap_base(mm);
7209 +
7210 +#ifdef CONFIG_PAX_RANDMMAP
7211 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7212 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7213 +#endif
7214 +
7215                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7216                 mm->unmap_area = arch_unmap_area_topdown;
7217         }
7218 diff -urNp linux-2.6.17.11/arch/x86_64/kernel/process.c linux-2.6.17.11/arch/x86_64/kernel/process.c
7219 --- linux-2.6.17.11/arch/x86_64/kernel/process.c        2006-08-07 00:18:54.000000000 -0400
7220 +++ linux-2.6.17.11/arch/x86_64/kernel/process.c        2006-09-01 16:20:28.000000000 -0400
7221 @@ -831,9 +831,3 @@ int dump_task_regs(struct task_struct *t
7222         return 1;
7223  }
7224  
7225 -unsigned long arch_align_stack(unsigned long sp)
7226 -{
7227 -       if (randomize_va_space)
7228 -               sp -= get_random_int() % 8192;
7229 -       return sp & ~0xf;
7230 -}
7231 diff -urNp linux-2.6.17.11/arch/x86_64/kernel/ptrace.c linux-2.6.17.11/arch/x86_64/kernel/ptrace.c
7232 --- linux-2.6.17.11/arch/x86_64/kernel/ptrace.c 2006-08-07 00:18:54.000000000 -0400
7233 +++ linux-2.6.17.11/arch/x86_64/kernel/ptrace.c 2006-09-01 16:20:28.000000000 -0400
7234 @@ -19,6 +19,7 @@
7235  #include <linux/audit.h>
7236  #include <linux/seccomp.h>
7237  #include <linux/signal.h>
7238 +#include <linux/grsecurity.h>
7239  
7240  #include <asm/uaccess.h>
7241  #include <asm/pgtable.h>
7242 diff -urNp linux-2.6.17.11/arch/x86_64/kernel/setup64.c linux-2.6.17.11/arch/x86_64/kernel/setup64.c
7243 --- linux-2.6.17.11/arch/x86_64/kernel/setup64.c        2006-08-07 00:18:54.000000000 -0400
7244 +++ linux-2.6.17.11/arch/x86_64/kernel/setup64.c        2006-09-01 16:20:28.000000000 -0400
7245 @@ -38,7 +38,6 @@ struct desc_ptr idt_descr = { 256 * 16 -
7246  char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
7247  
7248  unsigned long __supported_pte_mask __read_mostly = ~0UL;
7249 -static int do_not_nx __cpuinitdata = 0;
7250  
7251  /* noexec=on|off
7252  Control non executable mappings for 64bit processes.
7253 @@ -50,16 +49,14 @@ int __init nonx_setup(char *str)
7254  {
7255         if (!strncmp(str, "on", 2)) {
7256                  __supported_pte_mask |= _PAGE_NX; 
7257 -               do_not_nx = 0; 
7258         } else if (!strncmp(str, "off", 3)) {
7259 -               do_not_nx = 1;
7260                 __supported_pte_mask &= ~_PAGE_NX;
7261          }
7262         return 1;
7263  } 
7264  __setup("noexec=", nonx_setup);        /* parsed early actually */
7265  
7266 -int force_personality32 = 0; 
7267 +int force_personality32;
7268  
7269  /* noexec32=on|off
7270  Control non executable heap for 32bit processes.
7271 @@ -173,7 +170,7 @@ void __cpuinit check_efer(void)
7272         unsigned long efer;
7273  
7274         rdmsrl(MSR_EFER, efer); 
7275 -        if (!(efer & EFER_NX) || do_not_nx) { 
7276 +        if (!(efer & EFER_NX)) { 
7277                  __supported_pte_mask &= ~_PAGE_NX; 
7278          }       
7279  }
7280 diff -urNp linux-2.6.17.11/arch/x86_64/kernel/sys_x86_64.c linux-2.6.17.11/arch/x86_64/kernel/sys_x86_64.c
7281 --- linux-2.6.17.11/arch/x86_64/kernel/sys_x86_64.c     2006-08-07 00:18:54.000000000 -0400
7282 +++ linux-2.6.17.11/arch/x86_64/kernel/sys_x86_64.c     2006-09-01 16:20:28.000000000 -0400
7283 @@ -66,8 +66,8 @@ out:
7284         return error;
7285  }
7286  
7287 -static void find_start_end(unsigned long flags, unsigned long *begin,
7288 -                          unsigned long *end)
7289 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
7290 +                          unsigned long *begin, unsigned long *end)
7291  {
7292         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
7293                 /* This is usually used needed to map code in small
7294 @@ -80,7 +80,7 @@ static void find_start_end(unsigned long
7295                 *begin = 0x40000000; 
7296                 *end = 0x80000000;              
7297         } else {
7298 -               *begin = TASK_UNMAPPED_BASE;
7299 +               *begin = mm->mmap_base;
7300                 *end = TASK_SIZE; 
7301         }
7302  } 
7303 @@ -94,11 +94,15 @@ arch_get_unmapped_area(struct file *filp
7304         unsigned long start_addr;
7305         unsigned long begin, end;
7306         
7307 -       find_start_end(flags, &begin, &end); 
7308 +       find_start_end(mm, flags, &begin, &end); 
7309  
7310         if (len > end)
7311                 return -ENOMEM;
7312  
7313 +#ifdef CONFIG_PAX_RANDMMAP
7314 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7315 +#endif
7316 +
7317         if (addr) {
7318                 addr = PAGE_ALIGN(addr);
7319                 vma = find_vma(mm, addr);
7320 diff -urNp linux-2.6.17.11/arch/x86_64/mm/fault.c linux-2.6.17.11/arch/x86_64/mm/fault.c
7321 --- linux-2.6.17.11/arch/x86_64/mm/fault.c      2006-08-07 00:18:54.000000000 -0400
7322 +++ linux-2.6.17.11/arch/x86_64/mm/fault.c      2006-09-01 16:20:28.000000000 -0400
7323 @@ -24,6 +24,7 @@
7324  #include <linux/compiler.h>
7325  #include <linux/module.h>
7326  #include <linux/kprobes.h>
7327 +#include <linux/binfmts.h>
7328  
7329  #include <asm/system.h>
7330  #include <asm/uaccess.h>
7331 @@ -294,6 +295,33 @@ static int vmalloc_fault(unsigned long a
7332         return 0;
7333  }
7334  
7335 +#ifdef CONFIG_PAX_PAGEEXEC
7336 +void pax_report_insns(void *pc, void *sp)
7337 +{
7338 +       long i;
7339 +
7340 +       printk(KERN_ERR "PAX: bytes at PC: ");
7341 +       for (i = 0; i < 20; i++) {
7342 +               unsigned char c;
7343 +               if (get_user(c, (unsigned char __user *)pc+i))
7344 +                       printk("?? ");
7345 +               else
7346 +                       printk("%02x ", c);
7347 +       }
7348 +       printk("\n");
7349 +
7350 +       printk(KERN_ERR "PAX: bytes at SP-8: ");
7351 +       for (i = -1; i < 10; i++) {
7352 +               unsigned long c;
7353 +               if (get_user(c, (unsigned long __user *)sp+i))
7354 +                       printk("???????????????? ");
7355 +               else
7356 +                       printk("%016lx ", c);
7357 +       }
7358 +       printk("\n");
7359 +}
7360 +#endif
7361 +
7362  int page_fault_trace = 0;
7363  int exception_trace = 1;
7364  
7365 @@ -423,6 +451,8 @@ asmlinkage void __kprobes do_page_fault(
7366  good_area:
7367         info.si_code = SEGV_ACCERR;
7368         write = 0;
7369 +       if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
7370 +               goto bad_area;
7371         switch (error_code & (PF_PROT|PF_WRITE)) {
7372                 default:        /* 3: write, present */
7373                         /* fall through */
7374 @@ -489,7 +519,14 @@ bad_area_nosemaphore:
7375                                         tsk->comm, tsk->pid, address, regs->rip,
7376                                         regs->rsp, error_code);
7377                 }
7378 -       
7379 +
7380 +#ifdef CONFIG_PAX_PAGEEXEC
7381 +               if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
7382 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
7383 +                       do_exit(SIGKILL);
7384 +               }
7385 +#endif
7386 +
7387                 tsk->thread.cr2 = address;
7388                 /* Kernel addresses are always protection faults */
7389                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
7390 diff -urNp linux-2.6.17.11/arch/x86_64/mm/mmap.c linux-2.6.17.11/arch/x86_64/mm/mmap.c
7391 --- linux-2.6.17.11/arch/x86_64/mm/mmap.c       2006-08-07 00:18:54.000000000 -0400
7392 +++ linux-2.6.17.11/arch/x86_64/mm/mmap.c       2006-09-01 16:20:28.000000000 -0400
7393 @@ -24,6 +24,12 @@ void arch_pick_mmap_layout(struct mm_str
7394                 unsigned rnd = get_random_int() & 0xfffffff;
7395                 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
7396         }
7397 +
7398 +#ifdef CONFIG_PAX_RANDMMAP
7399 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
7400 +               mm->mmap_base += mm->delta_mmap;
7401 +#endif
7402 +
7403         mm->get_unmapped_area = arch_get_unmapped_area;
7404         mm->unmap_area = arch_unmap_area;
7405  }
7406 diff -urNp linux-2.6.17.11/Documentation/dontdiff linux-2.6.17.11/Documentation/dontdiff
7407 --- linux-2.6.17.11/Documentation/dontdiff      2006-08-07 00:18:54.000000000 -0400
7408 +++ linux-2.6.17.11/Documentation/dontdiff      2006-09-01 16:20:28.000000000 -0400
7409 @@ -55,7 +55,7 @@ aic7*seq.h*
7410  aicasm
7411  aicdb.h*
7412  asm
7413 -asm-offsets.*
7414 +asm-offsets.h
7415  asm_offsets.*
7416  autoconf.h*
7417  bbootsect
7418 diff -urNp linux-2.6.17.11/drivers/char/agp/frontend.c linux-2.6.17.11/drivers/char/agp/frontend.c
7419 --- linux-2.6.17.11/drivers/char/agp/frontend.c 2006-08-07 00:18:54.000000000 -0400
7420 +++ linux-2.6.17.11/drivers/char/agp/frontend.c 2006-09-01 16:20:28.000000000 -0400
7421 @@ -841,7 +841,7 @@ static int agpioc_reserve_wrap(struct ag
7422         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
7423                 return -EFAULT;
7424  
7425 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
7426 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
7427                 return -EFAULT;
7428  
7429         client = agp_find_client_by_pid(reserve.pid);
7430 diff -urNp linux-2.6.17.11/drivers/char/keyboard.c linux-2.6.17.11/drivers/char/keyboard.c
7431 --- linux-2.6.17.11/drivers/char/keyboard.c     2006-08-07 00:18:54.000000000 -0400
7432 +++ linux-2.6.17.11/drivers/char/keyboard.c     2006-09-01 16:20:28.000000000 -0400
7433 @@ -618,6 +618,16 @@ static void k_spec(struct vc_data *vc, u
7434              kbd->kbdmode == VC_MEDIUMRAW) &&
7435              value != KVAL(K_SAK))
7436                 return;         /* SAK is allowed even in raw mode */
7437 +
7438 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
7439 +       {
7440 +               void *func = fn_handler[value];
7441 +               if (func == fn_show_state || func == fn_show_ptregs ||
7442 +                   func == fn_show_mem)
7443 +                       return;
7444 +       }
7445 +#endif
7446 +
7447         fn_handler[value](vc, regs);
7448  }
7449  
7450 diff -urNp linux-2.6.17.11/drivers/char/mem.c linux-2.6.17.11/drivers/char/mem.c
7451 --- linux-2.6.17.11/drivers/char/mem.c  2006-08-07 00:18:54.000000000 -0400
7452 +++ linux-2.6.17.11/drivers/char/mem.c  2006-09-01 16:20:28.000000000 -0400
7453 @@ -28,6 +28,7 @@
7454  #include <linux/backing-dev.h>
7455  #include <linux/bootmem.h>
7456  #include <linux/pipe_fs_i.h>
7457 +#include <linux/grsecurity.h>
7458  
7459  #include <asm/uaccess.h>
7460  #include <asm/io.h>
7461 @@ -36,6 +37,10 @@
7462  # include <linux/efi.h>
7463  #endif
7464  
7465 +#ifdef CONFIG_GRKERNSEC
7466 +extern struct file_operations grsec_fops;
7467 +#endif
7468 +
7469  /*
7470   * Architectures vary in how they handle caching for addresses
7471   * outside of main memory.
7472 @@ -175,6 +180,11 @@ static ssize_t write_mem(struct file * f
7473         if (!valid_phys_addr_range(p, count))
7474                 return -EFAULT;
7475  
7476 +#ifdef CONFIG_GRKERNSEC_KMEM
7477 +       gr_handle_mem_write();
7478 +       return -EPERM;
7479 +#endif
7480 +
7481         written = 0;
7482  
7483  #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
7484 @@ -251,6 +261,11 @@ static int mmap_mem(struct file * file, 
7485                                                  size,
7486                                                  vma->vm_page_prot);
7487  
7488 +#ifdef CONFIG_GRKERNSEC_KMEM
7489 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
7490 +               return -EPERM;
7491 +#endif
7492 +
7493         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
7494         if (remap_pfn_range(vma,
7495                             vma->vm_start,
7496 @@ -478,6 +493,11 @@ static ssize_t write_kmem(struct file * 
7497         ssize_t written;
7498         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
7499  
7500 +#ifdef CONFIG_GRKERNSEC_KMEM
7501 +       gr_handle_kmem_write();
7502 +       return -EPERM;
7503 +#endif
7504 +
7505         if (p < (unsigned long) high_memory) {
7506  
7507                 wrote = count;
7508 @@ -618,7 +638,23 @@ static inline size_t read_zero_pagealign
7509                         count = size;
7510  
7511                 zap_page_range(vma, addr, count, NULL);
7512 -               zeromap_page_range(vma, addr, count, PAGE_COPY);
7513 +               zeromap_page_range(vma, addr, count, vma->vm_page_prot);
7514 +
7515 +#ifdef CONFIG_PAX_SEGMEXEC
7516 +               if (vma->vm_flags & VM_MIRROR) {
7517 +                       unsigned long addr_m;
7518 +                       struct vm_area_struct * vma_m;
7519 +
7520 +                       addr_m = vma->vm_start + vma->vm_mirror;
7521 +                       vma_m = find_vma(mm, addr_m);
7522 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
7523 +                               addr_m = addr + vma->vm_mirror;
7524 +                               zap_page_range(vma_m, addr_m, count, NULL);
7525 +                       } else
7526 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
7527 +                                      addr, vma->vm_start);
7528 +               }
7529 +#endif
7530  
7531                 size -= count;
7532                 buf += count;
7533 @@ -767,6 +803,16 @@ static loff_t memory_lseek(struct file *
7534  
7535  static int open_port(struct inode * inode, struct file * filp)
7536  {
7537 +#ifdef CONFIG_GRKERNSEC_KMEM
7538 +       gr_handle_open_port();
7539 +       return -EPERM;
7540 +#endif
7541 +
7542 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
7543 +}
7544 +
7545 +static int open_mem(struct inode * inode, struct file * filp)
7546 +{
7547         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
7548  }
7549  
7550 @@ -774,7 +820,6 @@ static int open_port(struct inode * inod
7551  #define full_lseek      null_lseek
7552  #define write_zero     write_null
7553  #define read_full       read_zero
7554 -#define open_mem       open_port
7555  #define open_kmem      open_mem
7556  #define open_oldmem    open_mem
7557  
7558 @@ -897,6 +942,11 @@ static int memory_open(struct inode * in
7559                         filp->f_op = &oldmem_fops;
7560                         break;
7561  #endif
7562 +#ifdef CONFIG_GRKERNSEC
7563 +               case 13:
7564 +                       filp->f_op = &grsec_fops;
7565 +                       break;
7566 +#endif
7567                 default:
7568                         return -ENXIO;
7569         }
7570 @@ -929,6 +979,9 @@ static const struct {
7571  #ifdef CONFIG_CRASH_DUMP
7572         {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
7573  #endif
7574 +#ifdef CONFIG_GRKERNSEC
7575 +       {13,"grsec",    S_IRUSR | S_IWUGO,          &grsec_fops},
7576 +#endif
7577  };
7578  
7579  static struct class *mem_class;
7580 diff -urNp linux-2.6.17.11/drivers/char/random.c linux-2.6.17.11/drivers/char/random.c
7581 --- linux-2.6.17.11/drivers/char/random.c       2006-08-07 00:18:54.000000000 -0400
7582 +++ linux-2.6.17.11/drivers/char/random.c       2006-09-01 16:20:28.000000000 -0400
7583 @@ -249,8 +249,13 @@
7584  /*
7585   * Configuration information
7586   */
7587 +#ifdef CONFIG_GRKERNSEC_RANDNET
7588 +#define INPUT_POOL_WORDS 512
7589 +#define OUTPUT_POOL_WORDS 128
7590 +#else
7591  #define INPUT_POOL_WORDS 128
7592  #define OUTPUT_POOL_WORDS 32
7593 +#endif
7594  #define SEC_XFER_SIZE 512
7595  
7596  /*
7597 @@ -287,10 +292,17 @@ static struct poolinfo {
7598         int poolwords;
7599         int tap1, tap2, tap3, tap4, tap5;
7600  } poolinfo_table[] = {
7601 +#ifdef CONFIG_GRKERNSEC_RANDNET
7602 +       /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
7603 +       { 512,  411,    308,    208,    104,    1 },
7604 +       /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
7605 +       { 128,  103,    76,     51,     25,     1 },
7606 +#else
7607         /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
7608         { 128,  103,    76,     51,     25,     1 },
7609         /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
7610         { 32,   26,     20,     14,     7,      1 },
7611 +#endif
7612  #if 0
7613         /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
7614         { 2048, 1638,   1231,   819,    411,    1 },
7615 @@ -1658,3 +1670,25 @@ randomize_range(unsigned long start, uns
7616                 return 0;
7617         return PAGE_ALIGN(get_random_int() % range + start);
7618  }
7619 +
7620 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
7621 +unsigned long pax_get_random_long(void)
7622 +{
7623 +       static time_t   rekey_time;
7624 +       static __u32    secret[12];
7625 +       time_t          t;
7626 +
7627 +       /*
7628 +        * Pick a random secret every REKEY_INTERVAL seconds.
7629 +        */
7630 +       t = get_seconds();
7631 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
7632 +               rekey_time = t;
7633 +               get_random_bytes(secret, sizeof(secret));
7634 +       }
7635 +
7636 +       secret[1] = half_md4_transform(secret+8, secret);
7637 +       secret[0] = half_md4_transform(secret+8, secret);
7638 +       return *(unsigned long *)secret;
7639 +}
7640 +#endif
7641 diff -urNp linux-2.6.17.11/drivers/char/vt_ioctl.c linux-2.6.17.11/drivers/char/vt_ioctl.c
7642 --- linux-2.6.17.11/drivers/char/vt_ioctl.c     2006-08-07 00:18:54.000000000 -0400
7643 +++ linux-2.6.17.11/drivers/char/vt_ioctl.c     2006-09-01 16:20:28.000000000 -0400
7644 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
7645         case KDSKBENT:
7646                 if (!perm)
7647                         return -EPERM;
7648 +
7649 +#ifdef CONFIG_GRKERNSEC
7650 +               if (!capable(CAP_SYS_TTY_CONFIG))
7651 +                       return -EPERM;
7652 +#endif
7653 +
7654                 if (!i && v == K_NOSUCHMAP) {
7655                         /* disallocate map */
7656                         key_map = key_maps[s];
7657 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
7658                         goto reterr;
7659                 }
7660  
7661 +#ifdef CONFIG_GRKERNSEC
7662 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
7663 +                       ret = -EPERM;
7664 +                       goto reterr;
7665 +               }
7666 +#endif
7667 +
7668                 q = func_table[i];
7669                 first_free = funcbufptr + (funcbufsize - funcbufleft);
7670                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
7671 diff -urNp linux-2.6.17.11/drivers/ieee1394/hosts.c linux-2.6.17.11/drivers/ieee1394/hosts.c
7672 --- linux-2.6.17.11/drivers/ieee1394/hosts.c    2006-08-07 00:18:54.000000000 -0400
7673 +++ linux-2.6.17.11/drivers/ieee1394/hosts.c    2006-09-01 16:20:28.000000000 -0400
7674 @@ -75,6 +75,7 @@ static int dummy_isoctl(struct hpsb_iso 
7675  }
7676  
7677  static struct hpsb_host_driver dummy_driver = {
7678 +       .name =            "dummy",
7679         .transmit_packet = dummy_transmit_packet,
7680         .devctl =          dummy_devctl,
7681         .isoctl =          dummy_isoctl
7682 diff -urNp linux-2.6.17.11/drivers/ieee1394/ohci1394.c linux-2.6.17.11/drivers/ieee1394/ohci1394.c
7683 --- linux-2.6.17.11/drivers/ieee1394/ohci1394.c 2006-08-23 19:30:00.000000000 -0400
7684 +++ linux-2.6.17.11/drivers/ieee1394/ohci1394.c 2006-09-01 16:20:28.000000000 -0400
7685 @@ -162,9 +162,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
7686  printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
7687  
7688  /* Module Parameters */
7689 -static int phys_dma = 1;
7690 +static int phys_dma = 0;
7691  module_param(phys_dma, int, 0644);
7692 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
7693 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
7694  
7695  static void dma_trm_tasklet(unsigned long data);
7696  static void dma_trm_reset(struct dma_trm_ctx *d);
7697 diff -urNp linux-2.6.17.11/drivers/mtd/devices/doc2001.c linux-2.6.17.11/drivers/mtd/devices/doc2001.c
7698 --- linux-2.6.17.11/drivers/mtd/devices/doc2001.c       2006-08-07 00:18:54.000000000 -0400
7699 +++ linux-2.6.17.11/drivers/mtd/devices/doc2001.c       2006-09-01 16:20:28.000000000 -0400
7700 @@ -423,6 +423,8 @@ static int doc_read_ecc (struct mtd_info
7701         /* Don't allow read past end of device */
7702         if (from >= this->totlen)
7703                 return -EINVAL;
7704 +       if (!len)
7705 +               return -EINVAL;
7706  
7707         /* Don't allow a single read to cross a 512-byte block boundary */
7708         if (from + len > ((from | 0x1ff) + 1))
7709 diff -urNp linux-2.6.17.11/drivers/net/pcnet32.c linux-2.6.17.11/drivers/net/pcnet32.c
7710 --- linux-2.6.17.11/drivers/net/pcnet32.c       2006-08-07 00:18:54.000000000 -0400
7711 +++ linux-2.6.17.11/drivers/net/pcnet32.c       2006-09-01 16:20:28.000000000 -0400
7712 @@ -81,7 +81,7 @@ static int cards_found;
7713  /*
7714   * VLB I/O addresses
7715   */
7716 -static unsigned int pcnet32_portlist[] __initdata =
7717 +static unsigned int pcnet32_portlist[] __devinitdata =
7718      { 0x300, 0x320, 0x340, 0x360, 0 };
7719  
7720  static int pcnet32_debug = 0;
7721 diff -urNp linux-2.6.17.11/drivers/pci/proc.c linux-2.6.17.11/drivers/pci/proc.c
7722 --- linux-2.6.17.11/drivers/pci/proc.c  2006-08-07 00:18:54.000000000 -0400
7723 +++ linux-2.6.17.11/drivers/pci/proc.c  2006-09-01 16:20:28.000000000 -0400
7724 @@ -473,7 +473,15 @@ static int __init pci_proc_init(void)
7725  {
7726         struct proc_dir_entry *entry;
7727         struct pci_dev *dev = NULL;
7728 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7729 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7730 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
7731 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7732 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
7733 +#endif
7734 +#else
7735         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
7736 +#endif
7737         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
7738         if (entry)
7739                 entry->proc_fops = &proc_bus_pci_dev_operations;
7740 diff -urNp linux-2.6.17.11/drivers/pnp/pnpbios/bioscalls.c linux-2.6.17.11/drivers/pnp/pnpbios/bioscalls.c
7741 --- linux-2.6.17.11/drivers/pnp/pnpbios/bioscalls.c     2006-08-07 00:18:54.000000000 -0400
7742 +++ linux-2.6.17.11/drivers/pnp/pnpbios/bioscalls.c     2006-09-01 16:20:28.000000000 -0400
7743 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
7744  set_limit(gdt[(selname) >> 3], size); \
7745  } while(0)
7746  
7747 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
7748 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
7749  
7750  /*
7751   * At some point we want to use this stack frame pointer to unwind
7752 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
7753         struct desc_struct save_desc_40;
7754         int cpu;
7755  
7756 +#ifdef CONFIG_PAX_KERNEXEC
7757 +       unsigned long cr0;
7758 +#endif
7759 +
7760         /*
7761          * PnP BIOSes are generally not terribly re-entrant.
7762          * Also, don't rely on them to save everything correctly.
7763 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
7764         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
7765         spin_lock_irqsave(&pnp_bios_lock, flags);
7766  
7767 +#ifdef CONFIG_PAX_KERNEXEC
7768 +       pax_open_kernel(cr0);
7769 +#endif
7770 +
7771         /* The lock prevents us bouncing CPU here */
7772         if (ts1_size)
7773                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
7774 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
7775                   "i" (0)
7776                 : "memory"
7777         );
7778 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
7779  
7780         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
7781 +
7782 +#ifdef CONFIG_PAX_KERNEXEC
7783 +       pax_close_kernel(cr0);
7784 +#endif
7785 +
7786 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
7787         put_cpu();
7788  
7789         /* If we get here and this is set then the PnP BIOS faulted on us. */
7790 diff -urNp linux-2.6.17.11/drivers/video/i810/i810_main.c linux-2.6.17.11/drivers/video/i810/i810_main.c
7791 --- linux-2.6.17.11/drivers/video/i810/i810_main.c      2006-08-07 00:18:54.000000000 -0400
7792 +++ linux-2.6.17.11/drivers/video/i810/i810_main.c      2006-09-01 16:20:28.000000000 -0400
7793 @@ -1508,7 +1508,7 @@ static int i810fb_cursor(struct fb_info 
7794                 int size = ((cursor->image.width + 7) >> 3) *
7795                         cursor->image.height;
7796                 int i;
7797 -               u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
7798 +               u8 *data = kmalloc(64 * 8, GFP_KERNEL);
7799  
7800                 if (data == NULL)
7801                         return -ENOMEM;
7802 diff -urNp linux-2.6.17.11/drivers/video/vesafb.c linux-2.6.17.11/drivers/video/vesafb.c
7803 --- linux-2.6.17.11/drivers/video/vesafb.c      2006-08-07 00:18:54.000000000 -0400
7804 +++ linux-2.6.17.11/drivers/video/vesafb.c      2006-09-01 16:20:28.000000000 -0400
7805 @@ -267,7 +267,7 @@ static int __init vesafb_probe(struct pl
7806                 size_remap = size_total;
7807         vesafb_fix.smem_len = size_remap;
7808  
7809 -#ifndef __i386__
7810 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
7811         screen_info.vesapm_seg = 0;
7812  #endif
7813  
7814 diff -urNp linux-2.6.17.11/fs/binfmt_aout.c linux-2.6.17.11/fs/binfmt_aout.c
7815 --- linux-2.6.17.11/fs/binfmt_aout.c    2006-08-07 00:18:54.000000000 -0400
7816 +++ linux-2.6.17.11/fs/binfmt_aout.c    2006-09-01 16:20:28.000000000 -0400
7817 @@ -25,6 +25,7 @@
7818  #include <linux/personality.h>
7819  #include <linux/init.h>
7820  #include <linux/vs_memory.h>
7821 +#include <linux/grsecurity.h>
7822  
7823  #include <asm/system.h>
7824  #include <asm/uaccess.h>
7825 @@ -124,10 +125,12 @@ static int aout_core_dump(long signr, st
7826  /* If the size of the dump file exceeds the rlimit, then see what would happen
7827     if we wrote the stack, but not the data area.  */
7828  #ifdef __sparc__
7829 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
7830         if ((dump.u_dsize+dump.u_ssize) >
7831             current->signal->rlim[RLIMIT_CORE].rlim_cur)
7832                 dump.u_dsize = 0;
7833  #else
7834 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
7835         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
7836             current->signal->rlim[RLIMIT_CORE].rlim_cur)
7837                 dump.u_dsize = 0;
7838 @@ -135,10 +138,12 @@ static int aout_core_dump(long signr, st
7839  
7840  /* Make sure we have enough room to write the stack and data areas. */
7841  #ifdef __sparc__
7842 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
7843         if ((dump.u_ssize) >
7844             current->signal->rlim[RLIMIT_CORE].rlim_cur)
7845                 dump.u_ssize = 0;
7846  #else
7847 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
7848         if ((dump.u_ssize+1) * PAGE_SIZE >
7849             current->signal->rlim[RLIMIT_CORE].rlim_cur)
7850                 dump.u_ssize = 0;
7851 @@ -288,6 +293,8 @@ static int load_aout_binary(struct linux
7852         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
7853         if (rlim >= RLIM_INFINITY)
7854                 rlim = ~0;
7855 +
7856 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
7857         if (ex.a_data + ex.a_bss > rlim)
7858                 return -ENOMEM;
7859  
7860 @@ -320,6 +327,28 @@ static int load_aout_binary(struct linux
7861         current->mm->mmap = NULL;
7862         compute_creds(bprm);
7863         current->flags &= ~PF_FORKNOEXEC;
7864 +
7865 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
7866 +       current->mm->pax_flags = 0UL;
7867 +#endif
7868 +
7869 +#ifdef CONFIG_PAX_PAGEEXEC
7870 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
7871 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
7872 +
7873 +#ifdef CONFIG_PAX_EMUTRAMP
7874 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
7875 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
7876 +#endif
7877 +
7878 +#ifdef CONFIG_PAX_MPROTECT
7879 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
7880 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
7881 +#endif
7882 +
7883 +       }
7884 +#endif
7885 +
7886  #ifdef __sparc__
7887         if (N_MAGIC(ex) == NMAGIC) {
7888                 loff_t pos = fd_offset;
7889 @@ -415,7 +444,7 @@ static int load_aout_binary(struct linux
7890  
7891                 down_write(&current->mm->mmap_sem);
7892                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
7893 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
7894 +                               PROT_READ | PROT_WRITE,
7895                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
7896                                 fd_offset + ex.a_text);
7897                 up_write(&current->mm->mmap_sem);
7898 diff -urNp linux-2.6.17.11/fs/binfmt_elf.c linux-2.6.17.11/fs/binfmt_elf.c
7899 --- linux-2.6.17.11/fs/binfmt_elf.c     2006-08-07 00:18:54.000000000 -0400
7900 +++ linux-2.6.17.11/fs/binfmt_elf.c     2006-09-01 16:20:28.000000000 -0400
7901 @@ -40,11 +40,16 @@
7902  #include <linux/random.h>
7903  #include <linux/vs_memory.h>
7904  #include <linux/vs_cvirt.h>
7905 +#include <linux/grsecurity.h>
7906  
7907  #include <asm/uaccess.h>
7908  #include <asm/param.h>
7909  #include <asm/page.h>
7910  
7911 +#ifdef CONFIG_PAX_SEGMEXEC
7912 +#include <asm/desc.h>
7913 +#endif
7914 +
7915  #include <linux/elf.h>
7916  
7917  static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
7918 @@ -92,6 +97,8 @@ static struct linux_binfmt elf_format = 
7919  
7920  static int set_brk(unsigned long start, unsigned long end)
7921  {
7922 +       unsigned long e = end;
7923 +
7924         start = ELF_PAGEALIGN(start);
7925         end = ELF_PAGEALIGN(end);
7926         if (end > start) {
7927 @@ -102,7 +109,7 @@ static int set_brk(unsigned long start, 
7928                 if (BAD_ADDR(addr))
7929                         return addr;
7930         }
7931 -       current->mm->start_brk = current->mm->brk = end;
7932 +       current->mm->start_brk = current->mm->brk = e;
7933         return 0;
7934  }
7935  
7936 @@ -318,10 +325,9 @@ static unsigned long load_elf_interp(str
7937  {
7938         struct elf_phdr *elf_phdata;
7939         struct elf_phdr *eppnt;
7940 -       unsigned long load_addr = 0;
7941 -       int load_addr_set = 0;
7942 +       unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
7943         unsigned long last_bss = 0, elf_bss = 0;
7944 -       unsigned long error = ~0UL;
7945 +       unsigned long error = -EINVAL;
7946         int retval, i, size;
7947  
7948         /* First of all, some simple consistency checks */
7949 @@ -360,42 +366,64 @@
7950                 goto out_close;
7951         }
7952  
7953 +#ifdef CONFIG_PAX_SEGMEXEC
7954 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
7955 +               task_size = SEGMEXEC_TASK_SIZE;
7956 +#endif
7957 +
7958         eppnt = elf_phdata;
7959 +       min_addr = task_size;
7960 +       max_addr = 0;
7961 +       error = -ENOMEM;
7962 +
7963         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
7964 -         if (eppnt->p_type == PT_LOAD) {
7965 -           int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
7966 -           int elf_prot = 0;
7967 -           unsigned long vaddr = 0;
7968 -           unsigned long k, map_addr;
7969 -
7970 -           if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
7971 -           if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
7972 -           if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
7973 -           vaddr = eppnt->p_vaddr;
7974 -           if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
7975 -               elf_type |= MAP_FIXED;
7976 -
7977 -           map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
7978 -           error = map_addr;
7979 -           if (BAD_ADDR(map_addr))
7980 -               goto out_close;
7981 -
7982 -           if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
7983 -               load_addr = map_addr - ELF_PAGESTART(vaddr);
7984 -               load_addr_set = 1;
7985 -           }
7986 +           if (eppnt->p_type != PT_LOAD)
7987 +               continue;
7988  
7989             /*
7990              * Check to see if the section's size will overflow the
7991              * allowed task size. Note that p_filesz must always be
7992              * <= p_memsize so it is only necessary to check p_memsz.
7993              */
7994 -           k = load_addr + eppnt->p_vaddr;
7995 -           if (BAD_ADDR(k) || eppnt->p_filesz > eppnt->p_memsz ||
7996 -               eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
7997 -               error = -ENOMEM;
7998 +           if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
7999 +               goto out_close;
8000 +
8001 +           if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
8002 +               min_addr = ELF_PAGESTART(eppnt->p_vaddr);
8003 +           if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
8004 +               max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
8005 +       }
8006 +       if (min_addr >= max_addr)
8007                 goto out_close;
8008 -           }
8009 +       
8010 +       eppnt = elf_phdata;
8011 +       for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
8012 +               int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
8013 +               int elf_prot = 0;
8014 +               unsigned long vaddr;
8015 +               unsigned long k, map_addr;
8016 +
8017 +               if (eppnt->p_type != PT_LOAD)
8018 +                       continue;
8019 +
8020 +               if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
8021 +               if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
8022 +               if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
8023 +               vaddr = eppnt->p_vaddr;
8024 +
8025 +               if (!load_addr && interp_elf_ex->e_type == ET_DYN) {
8026 +                       load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
8027 +
8028 +                       if (load_addr > task_size)
8029 +                               goto out_close;
8030 +
8031 +                       load_addr -= min_addr;
8032 +               }
8033 +
8034 +               map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
8035 +               error = map_addr;
8036 +               if (BAD_ADDR(map_addr))
8037 +                       goto out_close;
8038  
8039             /*
8040              * Find the end of the file mapping for this phdr, and keep
8041 @@ -412,7 +440,6 @@
8042             k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
8043             if (k > last_bss)
8044                 last_bss = k;
8045 -         }
8046         }
8047  
8048         /*
8049 @@ -449,7 +476,7 @@ out:
8050  static unsigned long load_aout_interp(struct exec * interp_ex,
8051                              struct file * interpreter)
8052  {
8053 -       unsigned long text_data, elf_entry = ~0UL;
8054 +       unsigned long text_data, elf_entry = -EINVAL;
8055         char __user * addr;
8056         loff_t offset;
8057  
8058 @@ -493,6 +520,180 @@ out:
8059         return elf_entry;
8060  }
8061  
8062 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
8063 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
8064 +{
8065 +       unsigned long pax_flags = 0UL;
8066 +
8067 +#ifdef CONFIG_PAX_PAGEEXEC
8068 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
8069 +               pax_flags |= MF_PAX_PAGEEXEC;
8070 +#endif
8071 +
8072 +#ifdef CONFIG_PAX_SEGMEXEC
8073 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
8074 +               pax_flags |= MF_PAX_SEGMEXEC;
8075 +#endif
8076 +
8077 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
8078 +       if (pax_flags & MF_PAX_PAGEEXEC)
8079 +               pax_flags &= ~MF_PAX_SEGMEXEC;
8080 +#endif
8081 +
8082 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
8083 +       if (pax_flags & MF_PAX_SEGMEXEC)
8084 +               pax_flags &= ~MF_PAX_PAGEEXEC;
8085 +#endif
8086 +
8087 +#ifdef CONFIG_PAX_EMUTRAMP
8088 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
8089 +               pax_flags |= MF_PAX_EMUTRAMP;
8090 +#endif
8091 +
8092 +#ifdef CONFIG_PAX_MPROTECT
8093 +       if (elf_phdata->p_flags & PF_MPROTECT)
8094 +               pax_flags |= MF_PAX_MPROTECT;
8095 +#endif
8096 +
8097 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
8098 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
8099 +               pax_flags |= MF_PAX_RANDMMAP;
8100 +#endif
8101 +
8102 +       return pax_flags;
8103 +}
8104 +#endif
8105 +
8106 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
8107 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
8108 +{
8109 +       unsigned long pax_flags = 0UL;
8110 +
8111 +#ifdef CONFIG_PAX_PAGEEXEC
8112 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
8113 +               pax_flags |= MF_PAX_PAGEEXEC;
8114 +#endif
8115 +
8116 +#ifdef CONFIG_PAX_SEGMEXEC
8117 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
8118 +               pax_flags |= MF_PAX_SEGMEXEC;
8119 +#endif
8120 +
8121 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
8122 +       if (pax_flags & MF_PAX_PAGEEXEC)
8123 +               pax_flags &= ~MF_PAX_SEGMEXEC;
8124 +#endif
8125 +
8126 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
8127 +       if (pax_flags & MF_PAX_SEGMEXEC)
8128 +               pax_flags &= ~MF_PAX_PAGEEXEC;
8129 +#endif
8130 +
8131 +#ifdef CONFIG_PAX_EMUTRAMP
8132 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
8133 +               pax_flags |= MF_PAX_EMUTRAMP;
8134 +#endif
8135 +
8136 +#ifdef CONFIG_PAX_MPROTECT
8137 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
8138 +               pax_flags |= MF_PAX_MPROTECT;
8139 +#endif
8140 +
8141 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
8142 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
8143 +               pax_flags |= MF_PAX_RANDMMAP;
8144 +#endif
8145 +
8146 +       return pax_flags;
8147 +}
8148 +#endif
8149 +
8150 +#ifdef CONFIG_PAX_EI_PAX
8151 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
8152 +{
8153 +       unsigned long pax_flags = 0UL;
8154 +
8155 +#ifdef CONFIG_PAX_PAGEEXEC
8156 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
8157 +               pax_flags |= MF_PAX_PAGEEXEC;
8158 +#endif
8159 +
8160 +#ifdef CONFIG_PAX_SEGMEXEC
8161 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
8162 +               pax_flags |= MF_PAX_SEGMEXEC;
8163 +#endif
8164 +
8165 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
8166 +       if (pax_flags & MF_PAX_PAGEEXEC)
8167 +               pax_flags &= ~MF_PAX_SEGMEXEC;
8168 +#endif
8169 +
8170 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
8171 +       if (pax_flags & MF_PAX_SEGMEXEC)
8172 +               pax_flags &= ~MF_PAX_PAGEEXEC;
8173 +#endif
8174 +
8175 +#ifdef CONFIG_PAX_EMUTRAMP
8176 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
8177 +               pax_flags |= MF_PAX_EMUTRAMP;
8178 +#endif
8179 +
8180 +#ifdef CONFIG_PAX_MPROTECT
8181 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
8182 +               pax_flags |= MF_PAX_MPROTECT;
8183 +#endif
8184 +
8185 +#ifdef CONFIG_PAX_ASLR
8186 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
8187 +               pax_flags |= MF_PAX_RANDMMAP;
8188 +#endif
8189 +
8190 +       return pax_flags;
8191 +}
8192 +#endif
8193 +
8194 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
8195 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
8196 +{
8197 +       unsigned long pax_flags = 0UL;
8198 +
8199 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
8200 +       unsigned long i;
8201 +#endif
8202 +
8203 +#ifdef CONFIG_PAX_EI_PAX
8204 +       pax_flags = pax_parse_ei_pax(elf_ex);
8205 +#endif
8206 +
8207 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
8208 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
8209 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
8210 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
8211 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
8212 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
8213 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
8214 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
8215 +                               return -EINVAL;
8216 +
8217 +#ifdef CONFIG_PAX_SOFTMODE
8218 +                       if (pax_softmode)
8219 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
8220 +                       else
8221 +#endif
8222 +
8223 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
8224 +                       break;
8225 +               }
8226 +#endif
8227 +
8228 +       if (0 > pax_check_flags(&pax_flags))
8229 +               return -EINVAL;
8230 +
8231 +       current->mm->pax_flags = pax_flags;
8232 +       return 0;
8233 +}
8234 +#endif
8235 +
8236  /*
8237   * These are the functions used to load ELF style executables and shared
8238   * libraries.  There is no binary dependent code anywhere else.
8239 @@ -529,7 +730,7 @@ static int load_elf_binary(struct linux_
8240         char * elf_interpreter = NULL;
8241         unsigned int interpreter_type = INTERPRETER_NONE;
8242         unsigned char ibcs2_interpreter = 0;
8243 -       unsigned long error;
8244 +       unsigned long error = 0;
8245         struct elf_phdr * elf_ppnt, *elf_phdata;
8246         unsigned long elf_bss, elf_brk;
8247         int elf_exec_fileno;
8248 @@ -547,6 +748,7 @@ static int load_elf_binary(struct linux_
8249                 struct elfhdr interp_elf_ex;
8250                 struct exec interp_ex;
8251         } *loc;
8252 +       unsigned long task_size = TASK_SIZE;
8253  
8254         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
8255         if (!loc) {
8256 @@ -772,14 +974,88 @@ static int load_elf_binary(struct linux_
8257         current->mm->end_code = 0;
8258         current->mm->mmap = NULL;
8259         current->flags &= ~PF_FORKNOEXEC;
8260 +
8261 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
8262 +       current->mm->pax_flags = 0UL;
8263 +#endif
8264 +
8265 +#ifdef CONFIG_PAX_DLRESOLVE
8266 +       current->mm->call_dl_resolve = 0UL;
8267 +#endif
8268 +
8269 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
8270 +       current->mm->call_syscall = 0UL;
8271 +#endif
8272 +
8273 +#ifdef CONFIG_PAX_ASLR
8274 +       current->mm->delta_mmap = 0UL;
8275 +       current->mm->delta_exec = 0UL;
8276 +       current->mm->delta_stack = 0UL;
8277 +#endif
8278 +
8279         current->mm->def_flags = def_flags;
8280  
8281 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
8282 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
8283 +               send_sig(SIGKILL, current, 0);
8284 +               goto out_free_dentry;
8285 +       }
8286 +#endif
8287 +
8288 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
8289 +       pax_set_initial_flags(bprm);
8290 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
8291 +       if (pax_set_initial_flags_func)
8292 +               (pax_set_initial_flags_func)(bprm);
8293 +#endif
8294 +
8295 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8296 +       if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
8297 +               current->mm->context.user_cs_limit = PAGE_SIZE;
8298 +#endif
8299 +
8300 +#ifdef CONFIG_PAX_SEGMEXEC
8301 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
8302 +               int cpu = get_cpu();
8303 +
8304 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
8305 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
8306 +               set_user_cs(current->mm, cpu);
8307 +               put_cpu();
8308 +               task_size = SEGMEXEC_TASK_SIZE;
8309 +       }
8310 +#endif
8311 +
8312 +#ifdef CONFIG_PAX_ASLR
8313 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
8314 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
8315 +
8316 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
8317 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
8318 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
8319 +       }
8320 +#endif
8321 +
8322 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8323 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8324 +               executable_stack = EXSTACK_DEFAULT;
8325 +#endif
8326 +
8327         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
8328            may depend on the personality.  */
8329         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
8330 +
8331 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8332 +       if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
8333 +#endif
8334 +
8335         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
8336                 current->personality |= READ_IMPLIES_EXEC;
8337  
8338 +#ifdef CONFIG_PAX_ASLR
8339 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
8340 +#endif
8341 +
8342         if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8343                 current->flags |= PF_RANDOMIZE;
8344         arch_pick_mmap_layout(current->mm);
8345 @@ -851,6 +1127,15 @@ static int load_elf_binary(struct linux_
8346                            base, as well as whatever program they might try to exec.  This
8347                            is because the brk will follow the loader, and is not movable.  */
8348                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
8349 +
8350 +#ifdef CONFIG_PAX_RANDMMAP
8351 +                       /* PaX: randomize base address at the default exe base if requested */
8352 +                       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
8353 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
8354 +                               elf_flags |= MAP_FIXED;
8355 +                       }
8356 +#endif
8357 +
8358                 }
8359  
8360                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
8361 @@ -878,8 +1163,8 @@ static int load_elf_binary(struct linux_
8362                  * <= p_memsz so it is only necessary to check p_memsz.
8363                  */
8364                 if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
8365 -                   elf_ppnt->p_memsz > TASK_SIZE ||
8366 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
8367 +                   elf_ppnt->p_memsz > task_size ||
8368 +                   task_size - elf_ppnt->p_memsz < k) {
8369                         /* set_brk can never work.  Avoid overflows.  */
8370                         send_sig(SIGKILL, current, 0);
8371                         goto out_free_dentry;
8372 @@ -907,6 +1192,12 @@ static int load_elf_binary(struct linux_
8373         start_data += load_bias;
8374         end_data += load_bias;
8375  
8376 +#ifdef CONFIG_PAX_RANDMMAP
8377 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP)
8378 +               elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
8379 +#undef pax_delta_mask
8380 +#endif
8381 +
8382         /* Calling set_brk effectively mmaps the pages that we need
8383          * for the bss and break sections.  We must do this before
8384          * mapping in the interpreter, to make sure it doesn't wind
8385 @@ -1159,7 +1450,7 @@ static int dump_seek(struct file *file, 
8386   *
8387   * I think we should skip something. But I am not sure how. H.J.
8388   */
8389 -static int maydump(struct vm_area_struct *vma)
8390 +static int maydump(struct vm_area_struct *vma, long signr)
8391  {
8392         /* Do not dump I/O mapped devices or special mappings */
8393         if (vma->vm_flags & (VM_IO | VM_RESERVED))
8394 @@ -1170,7 +1461,7 @@ static int maydump(struct vm_area_struct
8395                 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
8396  
8397         /* If it hasn't been written to, don't write it out */
8398 -       if (!vma->anon_vma)
8399 +       if (signr != SIGKILL && !vma->anon_vma)
8400                 return 0;
8401  
8402         return 1;
8403 @@ -1224,8 +1515,11 @@ static int writenote(struct memelfnote *
8404  #undef DUMP_SEEK
8405  
8406  #define DUMP_WRITE(addr, nr)   \
8407 +       do { \
8408 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
8409         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
8410 -               goto end_coredump;
8411 +               goto end_coredump; \
8412 +       } while (0);
8413  #define DUMP_SEEK(off) \
8414         if (!dump_seek(file, (off))) \
8415                 goto end_coredump;
8416 @@ -1575,7 +1869,7 @@ static int elf_core_dump(long signr, str
8417                 phdr.p_offset = offset;
8418                 phdr.p_vaddr = vma->vm_start;
8419                 phdr.p_paddr = 0;
8420 -               phdr.p_filesz = maydump(vma) ? sz : 0;
8421 +               phdr.p_filesz = maydump(vma, signr) ? sz : 0;
8422                 phdr.p_memsz = sz;
8423                 offset += phdr.p_filesz;
8424                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
8425 @@ -1608,7 +1902,7 @@ static int elf_core_dump(long signr, str
8426         for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
8427                 unsigned long addr;
8428  
8429 -               if (!maydump(vma))
8430 +               if (!maydump(vma, signr))
8431                         continue;
8432  
8433                 for (addr = vma->vm_start;
8434 @@ -1627,6 +1921,7 @@ static int elf_core_dump(long signr, str
8435                                         void *kaddr;
8436                                         flush_cache_page(vma, addr, page_to_pfn(page));
8437                                         kaddr = kmap(page);
8438 +                                       gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
8439                                         if ((size += PAGE_SIZE) > limit ||
8440                                             !dump_write(file, kaddr,
8441                                             PAGE_SIZE)) {
8442 diff -urNp linux-2.6.17.11/fs/binfmt_flat.c linux-2.6.17.11/fs/binfmt_flat.c
8443 --- linux-2.6.17.11/fs/binfmt_flat.c    2006-08-07 00:18:54.000000000 -0400
8444 +++ linux-2.6.17.11/fs/binfmt_flat.c    2006-09-01 16:20:28.000000000 -0400
8445 @@ -553,7 +553,9 @@ static int load_flat_file(struct linux_b
8446                                 realdatastart = (unsigned long) -ENOMEM;
8447                         printk("Unable to allocate RAM for process data, errno %d\n",
8448                                         (int)-datapos);
8449 +                       down_write(&current->mm->mmap_sem);
8450                         do_munmap(current->mm, textpos, text_len);
8451 +                       up_write(&current->mm->mmap_sem);
8452                         ret = realdatastart;
8453                         goto err;
8454                 }
8455 @@ -575,8 +577,10 @@ static int load_flat_file(struct linux_b
8456                 }
8457                 if (result >= (unsigned long)-4096) {
8458                         printk("Unable to read data+bss, errno %d\n", (int)-result);
8459 +                       down_write(&current->mm->mmap_sem);
8460                         do_munmap(current->mm, textpos, text_len);
8461                         do_munmap(current->mm, realdatastart, data_len + extra);
8462 +                       up_write(&current->mm->mmap_sem);
8463                         ret = result;
8464                         goto err;
8465                 }
8466 @@ -640,8 +644,10 @@ static int load_flat_file(struct linux_b
8467                 }
8468                 if (result >= (unsigned long)-4096) {
8469                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
8470 +                       down_write(&current->mm->mmap_sem);
8471                         do_munmap(current->mm, textpos, text_len + data_len + extra +
8472                                 MAX_SHARED_LIBS * sizeof(unsigned long));
8473 +                       up_write(&current->mm->mmap_sem);
8474                         ret = result;
8475                         goto err;
8476                 }
8477 diff -urNp linux-2.6.17.11/fs/binfmt_misc.c linux-2.6.17.11/fs/binfmt_misc.c
8478 --- linux-2.6.17.11/fs/binfmt_misc.c    2006-08-07 00:18:54.000000000 -0400
8479 +++ linux-2.6.17.11/fs/binfmt_misc.c    2006-09-01 16:20:28.000000000 -0400
8480 @@ -112,9 +112,11 @@ static int load_misc_binary(struct linux
8481         struct files_struct *files = NULL;
8482  
8483         retval = -ENOEXEC;
8484 -       if (!enabled)
8485 +       if (!enabled || bprm->misc)
8486                 goto _ret;
8487  
8488 +       bprm->misc++;
8489 +
8490         /* to keep locking time low, we copy the interpreter string */
8491         read_lock(&entries_lock);
8492         fmt = check_file(bprm);
8493 diff -urNp linux-2.6.17.11/fs/buffer.c linux-2.6.17.11/fs/buffer.c
8494 --- linux-2.6.17.11/fs/buffer.c 2006-08-07 00:18:54.000000000 -0400
8495 +++ linux-2.6.17.11/fs/buffer.c 2006-09-01 16:20:28.000000000 -0400
8496 @@ -42,6 +42,7 @@
8497  #include <linux/bitops.h>
8498  #include <linux/mpage.h>
8499  #include <linux/bit_spinlock.h>
8500 +#include <linux/grsecurity.h>
8501  
8502  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
8503  static void invalidate_bh_lrus(void);
8504 @@ -2167,6 +2168,7 @@ static int __generic_cont_expand(struct 
8505  
8506         err = -EFBIG;
8507          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
8508 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
8509         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
8510                 send_sig(SIGXFSZ, current, 0);
8511                 goto out;
8512 diff -urNp linux-2.6.17.11/fs/compat.c linux-2.6.17.11/fs/compat.c
8513 --- linux-2.6.17.11/fs/compat.c 2006-08-07 00:18:54.000000000 -0400
8514 +++ linux-2.6.17.11/fs/compat.c 2006-09-01 16:20:28.000000000 -0400
8515 @@ -46,6 +46,7 @@
8516  #include <linux/rwsem.h>
8517  #include <linux/acct.h>
8518  #include <linux/mm.h>
8519 +#include <linux/grsecurity.h>
8520  
8521  #include <net/sock.h>          /* siocdevprivate_ioctl */
8522  
8523 @@ -1498,6 +1499,11 @@ int compat_do_execve(char * filename,
8524         struct file *file;
8525         int retval;
8526         int i;
8527 +#ifdef CONFIG_GRKERNSEC
8528 +       struct file *old_exec_file;
8529 +       struct acl_subject_label *old_acl;
8530 +       struct rlimit old_rlim[RLIM_NLIMITS];
8531 +#endif
8532  
8533         retval = -ENOMEM;
8534         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
8535 @@ -1515,6 +1521,15 @@ int compat_do_execve(char * filename,
8536         bprm->file = file;
8537         bprm->filename = filename;
8538         bprm->interp = filename;
8539 +
8540 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
8541 +       retval = -EAGAIN;
8542 +       if (gr_handle_nproc())
8543 +               goto out_file;
8544 +       retval = -EACCES;
8545 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
8546 +               goto out_file;
8547 +
8548         bprm->mm = mm_alloc();
8549         retval = -ENOMEM;
8550         if (!bprm->mm)
8551 @@ -1553,10 +1568,39 @@ int compat_do_execve(char * filename,
8552         if (retval < 0)
8553                 goto out;
8554  
8555 +       if (!gr_tpe_allow(file)) {
8556 +               retval = -EACCES;
8557 +               goto out;
8558 +       }
8559 +
8560 +       if (gr_check_crash_exec(file)) {
8561 +               retval = -EACCES;
8562 +               goto out;
8563 +       }
8564 +
8565 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
8566 +
8567 +       gr_handle_exec_args(bprm, (char __user * __user *)argv);
8568 +
8569 +#ifdef CONFIG_GRKERNSEC
8570 +       old_acl = current->acl;
8571 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
8572 +       old_exec_file = current->exec_file;
8573 +       get_file(file);
8574 +       current->exec_file = file;
8575 +#endif
8576 +
8577 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
8578 +
8579         retval = search_binary_handler(bprm, regs);
8580         if (retval >= 0) {
8581                 free_arg_pages(bprm);
8582  
8583 +#ifdef CONFIG_GRKERNSEC
8584 +               if (old_exec_file)
8585 +                       fput(old_exec_file);
8586 +#endif
8587 +
8588                 /* execve success */
8589                 security_bprm_free(bprm);
8590                 acct_update_integrals(current);
8591 @@ -1564,6 +1608,13 @@ int compat_do_execve(char * filename,
8592                 return retval;
8593         }
8594  
8595 +#ifdef CONFIG_GRKERNSEC
8596 +       current->acl = old_acl;
8597 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
8598 +       fput(current->exec_file);
8599 +       current->exec_file = old_exec_file;
8600 +#endif
8601 +
8602  out:
8603         /* Something went wrong, return the inode and free the argument pages*/
8604         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8605 diff -urNp linux-2.6.17.11/fs/dcache.c linux-2.6.17.11/fs/dcache.c
8606 --- linux-2.6.17.11/fs/dcache.c 2006-08-07 00:18:54.000000000 -0400
8607 +++ linux-2.6.17.11/fs/dcache.c 2006-09-01 16:20:28.000000000 -0400
8608 @@ -1399,7 +1399,7 @@ already_unhashed:
8609   *
8610   * "buflen" should be positive. Caller holds the dcache_lock.
8611   */
8612 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
8613 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
8614                         struct dentry *root, struct vfsmount *rootmnt,
8615                         char *buffer, int buflen)
8616  {
8617 diff -urNp linux-2.6.17.11/fs/exec.c linux-2.6.17.11/fs/exec.c
8618 --- linux-2.6.17.11/fs/exec.c   2006-08-07 00:18:54.000000000 -0400
8619 +++ linux-2.6.17.11/fs/exec.c   2006-09-01 16:20:28.000000000 -0400
8620 @@ -51,6 +51,8 @@
8621  #include <linux/cn_proc.h>
8622  #include <linux/vs_cvirt.h>
8623  #include <linux/vs_memory.h>
8624 +#include <linux/random.h>
8625 +#include <linux/grsecurity.h>
8626  
8627  #include <asm/uaccess.h>
8628  #include <asm/mmu_context.h>
8629 @@ -69,6 +71,15 @@ EXPORT_SYMBOL(suid_dumpable);
8630  static struct linux_binfmt *formats;
8631  static DEFINE_RWLOCK(binfmt_lock);
8632  
8633 +#ifdef CONFIG_PAX_SOFTMODE
8634 +unsigned int pax_softmode;
8635 +#endif
8636 +
8637 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
8638 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
8639 +EXPORT_SYMBOL(pax_set_initial_flags_func);
8640 +#endif
8641 +
8642  int register_binfmt(struct linux_binfmt * fmt)
8643  {
8644         struct linux_binfmt ** tmp = &formats;
8645 @@ -314,6 +325,10 @@ void install_arg_page(struct vm_area_str
8646         if (unlikely(anon_vma_prepare(vma)))
8647                 goto out;
8648  
8649 +#ifdef CONFIG_PAX_SEGMEXEC
8650 +       if (page_count(page) == 1)
8651 +#endif
8652 +
8653         flush_dcache_page(page);
8654         pte = get_locked_pte(mm, address, &ptl);
8655         if (!pte)
8656 @@ -323,9 +338,21 @@ void install_arg_page(struct vm_area_str
8657                 goto out;
8658         }
8659         inc_mm_counter(mm, anon_rss);
8660 +
8661 +#ifdef CONFIG_PAX_SEGMEXEC
8662 +       if (page_count(page) == 1)
8663 +#endif
8664 +
8665         lru_cache_add_active(page);
8666         set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
8667                                         page, vma->vm_page_prot))));
8668 +
8669 +#ifdef CONFIG_PAX_SEGMEXEC
8670 +       if (page_count(page) != 1)
8671 +               page_add_anon_rmap(page, vma, address);
8672 +       else
8673 +#endif
8674 +
8675         page_add_new_anon_rmap(page, vma, address);
8676         pte_unmap_unlock(pte, ptl);
8677  
8678 @@ -348,6 +375,10 @@ int setup_arg_pages(struct linux_binprm 
8679         int i, ret;
8680         long arg_size;
8681  
8682 +#ifdef CONFIG_PAX_SEGMEXEC
8683 +       struct vm_area_struct *mpnt_m = NULL;
8684 +#endif
8685 +
8686  #ifdef CONFIG_STACK_GROWSUP
8687         /* Move the argument and environment strings to the bottom of the
8688          * stack space.
8689 @@ -406,11 +437,19 @@ int setup_arg_pages(struct linux_binprm 
8690                 bprm->loader += stack_base;
8691         bprm->exec += stack_base;
8692  
8693 -       mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8694 +       mpnt = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
8695         if (!mpnt)
8696                 return -ENOMEM;
8697  
8698 -       memset(mpnt, 0, sizeof(*mpnt));
8699 +#ifdef CONFIG_PAX_SEGMEXEC
8700 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
8701 +               mpnt_m = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
8702 +               if (!mpnt_m) {
8703 +                       kmem_cache_free(vm_area_cachep, mpnt);
8704 +                       return -ENOMEM;
8705 +               }
8706 +       }
8707 +#endif
8708  
8709         down_write(&mm->mmap_sem);
8710         {
8711 @@ -432,14 +471,51 @@ int setup_arg_pages(struct linux_binprm 
8712                 else
8713                         mpnt->vm_flags = VM_STACK_FLAGS;
8714                 mpnt->vm_flags |= mm->def_flags;
8715 -               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
8716 +
8717 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
8718 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
8719 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
8720 +               else
8721 +#endif
8722 +
8723 +               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
8724                 if ((ret = insert_vm_struct(mm, mpnt))) {
8725                         up_write(&mm->mmap_sem);
8726                         kmem_cache_free(vm_area_cachep, mpnt);
8727 +
8728 +#ifdef CONFIG_PAX_SEGMEXEC
8729 +                       if (mpnt_m)
8730 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
8731 +#endif
8732 +
8733                         return ret;
8734                 }
8735                 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
8736                 mm->stack_vm = mm->total_vm;
8737 +
8738 +#ifdef CONFIG_PAX_SEGMEXEC
8739 +               if (mpnt_m) {
8740 +                       *mpnt_m = *mpnt;
8741 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
8742 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
8743 +                               mpnt_m->vm_page_prot = PAGE_NONE;
8744 +                       }
8745 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
8746 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
8747 +                       if ((ret = insert_vm_struct(mm, mpnt_m))) {
8748 +                               up_write(&mm->mmap_sem);
8749 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
8750 +                               return ret;
8751 +                       }
8752 +                       mpnt_m->vm_flags |= VM_MIRROR;
8753 +                       mpnt->vm_flags |= VM_MIRROR;
8754 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
8755 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
8756 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
8757 +                       mm->total_vm += vma_pages(mpnt_m);
8758 +               }
8759 +#endif
8760 +
8761         }
8762  
8763         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8764 @@ -447,6 +523,14 @@ int setup_arg_pages(struct linux_binprm 
8765                 if (page) {
8766                         bprm->page[i] = NULL;
8767                         install_arg_page(mpnt, page, stack_base);
8768 +
8769 +#ifdef CONFIG_PAX_SEGMEXEC
8770 +                       if (mpnt_m) {
8771 +                               page_cache_get(page);
8772 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
8773 +                       }
8774 +#endif
8775 +
8776                 }
8777                 stack_base += PAGE_SIZE;
8778         }
8779 @@ -1150,6 +1234,11 @@ int do_execve(char * filename,
8780         struct file *file;
8781         int retval;
8782         int i;
8783 +#ifdef CONFIG_GRKERNSEC
8784 +       struct file *old_exec_file;
8785 +       struct acl_subject_label *old_acl;
8786 +       struct rlimit old_rlim[RLIM_NLIMITS];
8787 +#endif
8788  
8789         retval = -ENOMEM;
8790         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
8791 @@ -1161,10 +1250,29 @@ int do_execve(char * filename,
8792         if (IS_ERR(file))
8793                 goto out_kfree;
8794  
8795 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
8796 +
8797 +       if (gr_handle_nproc()) {
8798 +               allow_write_access(file);
8799 +               fput(file);
8800 +               return -EAGAIN;
8801 +       }
8802 +
8803 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
8804 +               allow_write_access(file);
8805 +               fput(file);
8806 +               return -EACCES;
8807 +       }
8808 +
8809         sched_exec();
8810  
8811         bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
8812  
8813 +#ifdef CONFIG_PAX_RANDUSTACK
8814 +       if (randomize_va_space)
8815 +               bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
8816 +#endif
8817 +
8818         bprm->file = file;
8819         bprm->filename = filename;
8820         bprm->interp = filename;
8821 @@ -1206,8 +1314,38 @@ int do_execve(char * filename,
8822         if (retval < 0)
8823                 goto out;
8824  
8825 +       if (!gr_tpe_allow(file)) {
8826 +               retval = -EACCES;
8827 +               goto out;
8828 +       }
8829 +
8830 +       if (gr_check_crash_exec(file)) {
8831 +               retval = -EACCES;
8832 +               goto out;
8833 +       }
8834 +
8835 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
8836 +
8837 +       gr_handle_exec_args(bprm, argv);
8838 +
8839 +#ifdef CONFIG_GRKERNSEC
8840 +       old_acl = current->acl;
8841 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
8842 +       old_exec_file = current->exec_file;
8843 +       get_file(file);
8844 +       current->exec_file = file;
8845 +#endif
8846 +
8847 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
8848 +       if (retval < 0)
8849 +               goto out_fail;
8850 +
8851         retval = search_binary_handler(bprm,regs);
8852         if (retval >= 0) {
8853 +#ifdef CONFIG_GRKERNSEC
8854 +               if (old_exec_file)
8855 +                       fput(old_exec_file);
8856 +#endif
8857                 free_arg_pages(bprm);
8858  
8859                 /* execve success */
8860 @@ -1217,6 +1355,14 @@ int do_execve(char * filename,
8861                 return retval;
8862         }
8863  
8864 +out_fail:
8865 +#ifdef CONFIG_GRKERNSEC
8866 +       current->acl = old_acl;
8867 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
8868 +       fput(current->exec_file);
8869 +       current->exec_file = old_exec_file;
8870 +#endif
8871 +
8872  out:
8873         /* Something went wrong, return the inode and free the argument pages*/
8874         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8875 @@ -1377,6 +1523,114 @@ static void format_corename(char *corena
8876         *out_ptr = 0;
8877  }
8878  
8879 +int pax_check_flags(unsigned long * flags)
8880 +{
8881 +       int retval = 0;
8882 +
8883 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
8884 +       if (*flags & MF_PAX_SEGMEXEC)
8885 +       {
8886 +               *flags &= ~MF_PAX_SEGMEXEC;
8887 +               retval = -EINVAL;
8888 +       }
8889 +#endif
8890 +
8891 +       if ((*flags & MF_PAX_PAGEEXEC)
8892 +
8893 +#ifdef CONFIG_PAX_PAGEEXEC
8894 +           &&  (*flags & MF_PAX_SEGMEXEC)
8895 +#endif
8896 +
8897 +          )
8898 +       {
8899 +               *flags &= ~MF_PAX_PAGEEXEC;
8900 +               retval = -EINVAL;
8901 +       }
8902 +
8903 +       if ((*flags & MF_PAX_MPROTECT)
8904 +
8905 +#ifdef CONFIG_PAX_MPROTECT
8906 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8907 +#endif
8908 +
8909 +          )
8910 +       {
8911 +               *flags &= ~MF_PAX_MPROTECT;
8912 +               retval = -EINVAL;
8913 +       }
8914 +
8915 +       if ((*flags & MF_PAX_EMUTRAMP)
8916 +
8917 +#ifdef CONFIG_PAX_EMUTRAMP
8918 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8919 +#endif
8920 +
8921 +          )
8922 +       {
8923 +               *flags &= ~MF_PAX_EMUTRAMP;
8924 +               retval = -EINVAL;
8925 +       }
8926 +
8927 +       return retval;
8928 +}
8929 +
8930 +EXPORT_SYMBOL(pax_check_flags);
8931 +
8932 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8933 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
8934 +{
8935 +       struct task_struct *tsk = current;
8936 +       struct mm_struct *mm = current->mm;
8937 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
8938 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
8939 +       char* path_exec=NULL;
8940 +       char* path_fault=NULL;
8941 +       unsigned long start=0UL, end=0UL, offset=0UL;
8942 +
8943 +       if (buffer_exec && buffer_fault) {
8944 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
8945 +
8946 +               down_read(&mm->mmap_sem);
8947 +               vma = mm->mmap;
8948 +               while (vma && (!vma_exec || !vma_fault)) {
8949 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
8950 +                               vma_exec = vma;
8951 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
8952 +                               vma_fault = vma;
8953 +                       vma = vma->vm_next;
8954 +               }
8955 +               if (vma_exec) {
8956 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
8957 +                       if (IS_ERR(path_exec))
8958 +                               path_exec = "<path too long>";
8959 +               }
8960 +               if (vma_fault) {
8961 +                       start = vma_fault->vm_start;
8962 +                       end = vma_fault->vm_end;
8963 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
8964 +                       if (vma_fault->vm_file) {
8965 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
8966 +                               if (IS_ERR(path_fault))
8967 +                                       path_fault = "<path too long>";
8968 +                       } else
8969 +                               path_fault = "<anonymous mapping>";
8970 +               }
8971 +               up_read(&mm->mmap_sem);
8972 +       }
8973 +       if (tsk->signal->curr_ip)
8974 +               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);
8975 +       else
8976 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
8977 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
8978 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
8979 +                       tsk->uid, tsk->euid, pc, sp);
8980 +       free_page((unsigned long)buffer_exec);
8981 +       free_page((unsigned long)buffer_fault);
8982 +       pax_report_insns(pc, sp);
8983 +       do_coredump(SIGKILL, SIGKILL, regs);
8984 +}
8985 +#endif
8986 +
8987  static void zap_threads (struct mm_struct *mm)
8988  {
8989         struct task_struct *g, *p;
8990 @@ -1494,6 +1748,10 @@ int do_coredump(long signr, int exit_cod
8991          */
8992         clear_thread_flag(TIF_SIGPENDING);
8993  
8994 +       if (signr == SIGKILL || signr == SIGILL)
8995 +               gr_handle_brute_attach(current);
8996 +
8997 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
8998         if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
8999                 goto fail_unlock;
9000  
9001 diff -urNp linux-2.6.17.11/fs/fcntl.c linux-2.6.17.11/fs/fcntl.c
9002 --- linux-2.6.17.11/fs/fcntl.c  2006-08-07 00:18:54.000000000 -0400
9003 +++ linux-2.6.17.11/fs/fcntl.c  2006-09-01 16:20:28.000000000 -0400
9004 @@ -19,6 +19,7 @@
9005  #include <linux/signal.h>
9006  #include <linux/rcupdate.h>
9007  #include <linux/vs_limit.h>
9008 +#include <linux/grsecurity.h>
9009  
9010  #include <asm/poll.h>
9011  #include <asm/siginfo.h>
9012 @@ -64,6 +65,7 @@ static int locate_fd(struct files_struct
9013         struct fdtable *fdt;
9014  
9015         error = -EINVAL;
9016 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
9017         if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
9018                 goto out;
9019  
9020 @@ -84,6 +86,7 @@ repeat:
9021         }
9022         
9023         error = -EMFILE;
9024 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
9025         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
9026                 goto out;
9027         if (!vx_files_avail(1))
9028 @@ -145,6 +148,8 @@ asmlinkage long sys_dup2(unsigned int ol
9029         struct files_struct * files = current->files;
9030         struct fdtable *fdt;
9031  
9032 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
9033 +
9034         spin_lock(&files->file_lock);
9035         if (!(file = fcheck(oldfd)))
9036                 goto out_unlock;
9037 @@ -434,7 +439,8 @@ static inline int sigio_perm(struct task
9038         return (((fown->euid == 0) ||
9039                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
9040                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
9041 -               !security_file_send_sigiotask(p, fown, sig));
9042 +               !security_file_send_sigiotask(p, fown, sig) &&
9043 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
9044  }
9045  
9046  static void send_sigio_to_task(struct task_struct *p,
9047 diff -urNp linux-2.6.17.11/fs/Kconfig linux-2.6.17.11/fs/Kconfig
9048 --- linux-2.6.17.11/fs/Kconfig  2006-08-07 00:18:54.000000000 -0400
9049 +++ linux-2.6.17.11/fs/Kconfig  2006-09-01 16:20:28.000000000 -0400
9050 @@ -796,7 +796,7 @@ config PROC_FS
9051  
9052  config PROC_KCORE
9053         bool "/proc/kcore support" if !ARM
9054 -       depends on PROC_FS && MMU
9055 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
9056  
9057  config PROC_VMCORE
9058          bool "/proc/vmcore support (EXPERIMENTAL)"
9059 diff -urNp linux-2.6.17.11/fs/namei.c linux-2.6.17.11/fs/namei.c
9060 --- linux-2.6.17.11/fs/namei.c  2006-08-07 00:18:54.000000000 -0400
9061 +++ linux-2.6.17.11/fs/namei.c  2006-09-01 16:20:28.000000000 -0400
9062 @@ -36,6 +36,7 @@
9063  #include <linux/vserver/inode.h>
9064  #include <linux/vs_tag.h>
9065  #include <linux/vserver/debug.h>
9066 +#include <linux/grsecurity.h>
9067  #include <asm/namei.h>
9068  #include <asm/uaccess.h>
9069  
9070 @@ -635,6 +636,13 @@ static inline int do_follow_link(struct 
9071         err = security_inode_follow_link(path->dentry, nd);
9072         if (err)
9073                 goto loop;
9074 +
9075 +       if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
9076 +                                 path->dentry->d_inode, path->dentry, nd->mnt)) {
9077 +               err = -EACCES;
9078 +               goto loop;
9079 +       }
9080 +
9081         current->link_count++;
9082         current->total_link_count++;
9083         nd->depth++;
9084 @@ -997,11 +1005,18 @@ return_reval:
9085                                 break;
9086                 }
9087  return_base:
9088 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
9089 +                       path_release(nd);
9090 +                       return -ENOENT;
9091 +               }
9092                 return 0;
9093  out_dput:
9094                 dput_path(&next, nd);
9095                 break;
9096         }
9097 +       if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
9098 +               err = -ENOENT;
9099 +
9100         path_release(nd);
9101  return_err:
9102         return err;
9103 @@ -1661,6 +1676,17 @@ int open_namei(int dfd, const char *path
9104                                          nd, flag);
9105                 if (error)
9106                         return error;
9107 +
9108 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
9109 +                       error = -EPERM;
9110 +                       goto exit;
9111 +               }
9112 +
9113 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
9114 +                       error = -EACCES;
9115 +                       goto exit;
9116 +               }
9117 +
9118                 goto ok;
9119         }
9120  
9121 @@ -1701,9 +1727,16 @@ do_last:
9122  
9123         /* Negative dentry, just create the file */
9124         if (!path.dentry->d_inode) {
9125 +               if (!gr_acl_handle_creat(path.dentry, nd->dentry, nd->mnt, flag, mode)) {
9126 +                       error = -EACCES;
9127 +                       mutex_unlock(&dir->d_inode->i_mutex);
9128 +                       goto exit_dput;
9129 +               }
9130                 if (!IS_POSIXACL(dir->d_inode))
9131                         mode &= ~current->fs->umask;
9132                 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
9133 +               if (!error)
9134 +                       gr_handle_create(path.dentry, nd->mnt);
9135                 mutex_unlock(&dir->d_inode->i_mutex);
9136                 dput(nd->dentry);
9137                 nd->dentry = path.dentry;
9138 @@ -1718,6 +1751,23 @@ do_last:
9139         /*
9140          * It already exists.
9141          */
9142 +
9143 +       if (gr_handle_rawio(path.dentry->d_inode)) {
9144 +               mutex_unlock(&dir->d_inode->i_mutex);
9145 +               error = -EPERM;
9146 +               goto exit_dput;
9147 +       }
9148 +       if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
9149 +               mutex_unlock(&dir->d_inode->i_mutex);
9150 +               error = -EACCES;
9151 +               goto exit_dput;
9152 +       }
9153 +       if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
9154 +               mutex_unlock(&dir->d_inode->i_mutex);
9155 +               error = -EACCES;
9156 +               goto exit_dput;
9157 +       }
9158 +
9159         mutex_unlock(&dir->d_inode->i_mutex);
9160  
9161         error = -EEXIST;
9162 @@ -1784,6 +1834,13 @@ do_link:
9163         error = security_inode_follow_link(path.dentry, nd);
9164         if (error)
9165                 goto exit_dput;
9166 +
9167 +       if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
9168 +                                 path.dentry, nd->mnt)) {
9169 +               error = -EACCES;
9170 +               goto exit_dput;
9171 +       }
9172 +
9173         error = __do_follow_link(&path, nd);
9174         if (error) {
9175                 /* Does someone understand code flow here? Or it is only
9176 @@ -1911,6 +1968,22 @@ asmlinkage long sys_mknodat(int dfd, con
9177         if (!IS_POSIXACL(nd.dentry->d_inode))
9178                 mode &= ~current->fs->umask;
9179         if (!IS_ERR(dentry)) {
9180 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
9181 +                       error = -EPERM;
9182 +                       dput(dentry);
9183 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
9184 +                       path_release(&nd);
9185 +                       goto out;
9186 +               }
9187 +
9188 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
9189 +                       error = -EACCES;
9190 +                       dput(dentry);
9191 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
9192 +                       path_release(&nd);
9193 +                       goto out;
9194 +               }
9195 +
9196                 switch (mode & S_IFMT) {
9197                 case 0: case S_IFREG:
9198                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
9199 @@ -1929,6 +2002,10 @@ asmlinkage long sys_mknodat(int dfd, con
9200                 default:
9201                         error = -EINVAL;
9202                 }
9203 +
9204 +               if (!error)
9205 +                       gr_handle_create(dentry, nd.mnt);
9206 +
9207                 dput(dentry);
9208         }
9209         mutex_unlock(&nd.dentry->d_inode->i_mutex);
9210 @@ -1984,10 +2061,19 @@ asmlinkage long sys_mkdirat(int dfd, con
9211                 dentry = lookup_create(&nd, 1);
9212                 error = PTR_ERR(dentry);
9213                 if (!IS_ERR(dentry)) {
9214 +                       error = 0;
9215                         if (!IS_POSIXACL(nd.dentry->d_inode))
9216                                 mode &= ~current->fs->umask;
9217 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
9218 -                               mode, &nd);
9219 +
9220 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
9221 +                               error = -EACCES;
9222 +
9223 +                       if (!error)
9224 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry,
9225 +                                       mode, &nd);
9226 +                       if (!error)
9227 +                               gr_handle_create(dentry, nd.mnt);
9228 +
9229                         dput(dentry);
9230                 }
9231                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9232 @@ -2072,6 +2158,8 @@ static long do_rmdir(int dfd, const char
9233         char * name;
9234         struct dentry *dentry;
9235         struct nameidata nd;
9236 +       ino_t saved_ino = 0;
9237 +       dev_t saved_dev = 0;
9238  
9239         name = getname(pathname);
9240         if(IS_ERR(name))
9241 @@ -2096,7 +2184,21 @@ static long do_rmdir(int dfd, const char
9242         dentry = lookup_hash(&nd);
9243         error = PTR_ERR(dentry);
9244         if (!IS_ERR(dentry)) {
9245 -               error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
9246 +               error = 0;
9247 +               if (dentry->d_inode) {
9248 +                       if (dentry->d_inode->i_nlink <= 1) {
9249 +                               saved_ino = dentry->d_inode->i_ino;
9250 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
9251 +                       }
9252 +
9253 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
9254 +                               error = -EACCES;
9255 +               }
9256 +
9257 +               if (!error)
9258 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
9259 +               if (!error && (saved_dev || saved_ino))
9260 +                       gr_handle_delete(saved_ino, saved_dev);
9261                 dput(dentry);
9262         }
9263         mutex_unlock(&nd.dentry->d_inode->i_mutex);
9264 @@ -2156,6 +2258,8 @@ static long do_unlinkat(int dfd, const c
9265         struct dentry *dentry;
9266         struct nameidata nd;
9267         struct inode *inode = NULL;
9268 +       ino_t saved_ino = 0;
9269 +       dev_t saved_dev = 0;
9270  
9271         name = getname(pathname);
9272         if(IS_ERR(name))
9273 @@ -2171,13 +2275,26 @@ static long do_unlinkat(int dfd, const c
9274         dentry = lookup_hash(&nd);
9275         error = PTR_ERR(dentry);
9276         if (!IS_ERR(dentry)) {
9277 +               error = 0;
9278                 /* Why not before? Because we want correct error value */
9279                 if (nd.last.name[nd.last.len])
9280                         goto slashes;
9281                 inode = dentry->d_inode;
9282 -               if (inode)
9283 +               if (inode) {
9284 +                       if (inode->i_nlink <= 1) {
9285 +                               saved_ino = inode->i_ino;
9286 +                               saved_dev = inode->i_sb->s_dev;
9287 +                       }
9288 +
9289 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
9290 +                               error = -EACCES;
9291 +
9292                         atomic_inc(&inode->i_count);
9293 -               error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
9294 +               }
9295 +               if (!error)
9296 +                       error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
9297 +               if (!error && (saved_ino || saved_dev))
9298 +                       gr_handle_delete(saved_ino, saved_dev);
9299         exit2:
9300                 dput(dentry);
9301         }
9302 @@ -2256,8 +2373,15 @@ asmlinkage long sys_symlinkat(const char
9303                 dentry = lookup_create(&nd, 0);
9304                 error = PTR_ERR(dentry);
9305                 if (!IS_ERR(dentry)) {
9306 -                       error = vfs_symlink(nd.dentry->d_inode, dentry,
9307 -                               from, S_IALLUGO, &nd);
9308 +                       error = 0;
9309 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
9310 +                               error = -EACCES;
9311 +
9312 +                       if (!error)
9313 +                               error = vfs_symlink(nd.dentry->d_inode, dentry,
9314 +                                       from, S_IALLUGO, &nd);
9315 +                       if (!error)
9316 +                               gr_handle_create(dentry, nd.mnt);
9317                         dput(dentry);
9318                 }
9319                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9320 @@ -2350,8 +2474,20 @@ asmlinkage long sys_linkat(int olddfd, c
9321         new_dentry = lookup_create(&nd, 0);
9322         error = PTR_ERR(new_dentry);
9323         if (!IS_ERR(new_dentry)) {
9324 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode,
9325 -                       new_dentry, &nd);
9326 +               error = 0;
9327 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
9328 +                                      old_nd.dentry->d_inode,
9329 +                                      old_nd.dentry->d_inode->i_mode, to))
9330 +                       error = -EPERM;
9331 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
9332 +                                       old_nd.dentry, old_nd.mnt, to))
9333 +                       error = -EACCES;
9334 +               if (!error)
9335 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry,
9336 +                               &nd);
9337 +               if (!error)
9338 +                       gr_handle_create(new_dentry, nd.mnt);
9339 +
9340                 dput(new_dentry);
9341         }
9342         mutex_unlock(&nd.dentry->d_inode->i_mutex);
9343 @@ -2580,8 +2716,16 @@ static int do_rename(int olddfd, const c
9344         if (new_dentry == trap)
9345                 goto exit5;
9346  
9347 -       error = vfs_rename(old_dir->d_inode, old_dentry,
9348 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
9349 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
9350 +                                    newname);
9351 +
9352 +       if (!error)
9353 +               error = vfs_rename(old_dir->d_inode, old_dentry,
9354                                    new_dir->d_inode, new_dentry);
9355 +       if (!error)
9356 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
9357 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
9358  exit5:
9359         dput(new_dentry);
9360  exit4:
9361 diff -urNp linux-2.6.17.11/fs/namespace.c linux-2.6.17.11/fs/namespace.c
9362 --- linux-2.6.17.11/fs/namespace.c      2006-08-07 00:18:54.000000000 -0400
9363 +++ linux-2.6.17.11/fs/namespace.c      2006-09-01 16:20:28.000000000 -0400
9364 @@ -25,6 +25,8 @@
9365  #include <linux/mount.h>
9366  #include <linux/vserver/namespace.h>
9367  #include <linux/vserver/tag.h>
9368 +#include <linux/sched.h>
9369 +#include <linux/grsecurity.h>
9370  #include <asm/uaccess.h>
9371  #include <asm/unistd.h>
9372  #include "pnode.h"
9373 @@ -655,6 +657,8 @@ static int do_umount(struct vfsmount *mn
9374                         DQUOT_OFF(sb->s_dqh);
9375                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
9376                         unlock_kernel();
9377 +
9378 +                       gr_log_remount(mnt->mnt_devname, retval);
9379                 }
9380                 up_write(&sb->s_umount);
9381                 return retval;
9382 @@ -675,6 +679,9 @@ static int do_umount(struct vfsmount *mn
9383                 security_sb_umount_busy(mnt);
9384         up_write(&namespace_sem);
9385         release_mounts(&umount_list);
9386 +
9387 +       gr_log_unmount(mnt->mnt_devname, retval);
9388 +
9389         return retval;
9390  }
9391  
9392 @@ -1425,6 +1432,11 @@ long do_mount(char *dev_name, char *dir_
9393         if (retval)
9394                 goto dput_out;
9395  
9396 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
9397 +               retval = -EPERM;
9398 +               goto dput_out;
9399 +       }
9400 +
9401         if (flags & MS_REMOUNT)
9402                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
9403                                     data_page, tag);
9404 @@ -1439,6 +1451,9 @@ long do_mount(char *dev_name, char *dir_
9405                                       dev_name, data_page);
9406  dput_out:
9407         path_release(&nd);
9408 +
9409 +       gr_log_mount(dev_name, dir_name, retval);
9410 +
9411         return retval;
9412  }
9413  
9414 @@ -1691,6 +1706,9 @@ asmlinkage long sys_pivot_root(const cha
9415         if (!capable(CAP_SYS_ADMIN))
9416                 return -EPERM;
9417  
9418 +       if (gr_handle_chroot_pivot())
9419 +               return -EPERM;
9420 +
9421         lock_kernel();
9422  
9423         error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
9424 diff -urNp linux-2.6.17.11/fs/open.c linux-2.6.17.11/fs/open.c
9425 --- linux-2.6.17.11/fs/open.c   2006-08-07 00:18:54.000000000 -0400
9426 +++ linux-2.6.17.11/fs/open.c   2006-09-01 16:20:28.000000000 -0400
9427 @@ -31,6 +31,7 @@
9428  #include <linux/vs_limit.h>
9429  #include <linux/vs_dlimit.h>
9430  #include <linux/vserver/tag.h>
9431 +#include <linux/grsecurity.h>
9432  
9433  #include <asm/unistd.h>
9434  
9435 @@ -212,6 +213,9 @@ int do_truncate(struct dentry *dentry, l
9436         if (length < 0)
9437                 return -EINVAL;
9438  
9439 +       if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
9440 +               return -EACCES;
9441 +
9442         newattrs.ia_size = length;
9443         newattrs.ia_valid = ATTR_SIZE | time_attrs;
9444         if (filp) {
9445 @@ -412,6 +416,12 @@ asmlinkage long sys_utime(char __user * 
9446                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
9447                         goto dput_and_out;
9448         }
9449 +
9450 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
9451 +               error = -EACCES;
9452 +               goto dput_and_out;
9453 +       }
9454 +
9455         mutex_lock(&inode->i_mutex);
9456         error = notify_change(nd.dentry, &newattrs);
9457         mutex_unlock(&inode->i_mutex);
9458 @@ -465,6 +475,12 @@ long do_utimes(int dfd, char __user *fil
9459                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
9460                         goto dput_and_out;
9461         }
9462 +
9463 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
9464 +               error = -EACCES;
9465 +               goto dput_and_out;
9466 +       }
9467 +
9468         mutex_lock(&inode->i_mutex);
9469         error = notify_change(nd.dentry, &newattrs);
9470         mutex_unlock(&inode->i_mutex);
9471 @@ -532,6 +548,10 @@ asmlinkage long sys_faccessat(int dfd, c
9472                    && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
9473                    && !special_file(nd.dentry->d_inode->i_mode))
9474                         res = -EROFS;
9475 +
9476 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
9477 +                       res = -EACCES;
9478 +
9479                 path_release(&nd);
9480         }
9481  
9482 @@ -560,6 +580,8 @@ asmlinkage long sys_chdir(const char __u
9483         if (error)
9484                 goto dput_and_out;
9485  
9486 +       gr_log_chdir(nd.dentry, nd.mnt);
9487 +
9488         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
9489  
9490  dput_and_out:
9491 @@ -590,6 +612,13 @@ asmlinkage long sys_fchdir(unsigned int 
9492                 goto out_putf;
9493  
9494         error = file_permission(file, MAY_EXEC);
9495 +
9496 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
9497 +               error = -EPERM;
9498 +
9499 +       if (!error)
9500 +               gr_log_chdir(dentry, mnt);
9501 +
9502         if (!error)
9503                 set_fs_pwd(current->fs, mnt, dentry);
9504  out_putf:
9505 @@ -615,8 +644,16 @@ asmlinkage long sys_chroot(const char __
9506         if (!capable(CAP_SYS_CHROOT))
9507                 goto dput_and_out;
9508  
9509 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
9510 +               goto dput_and_out;
9511 +
9512         set_fs_root(current->fs, nd.mnt, nd.dentry);
9513         set_fs_altroot();
9514 +
9515 +       gr_handle_chroot_caps(current);
9516 +
9517 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
9518 +
9519         error = 0;
9520  dput_and_out:
9521         path_release(&nd);
9522 @@ -647,9 +684,22 @@ asmlinkage long sys_fchmod(unsigned int 
9523         err = -EPERM;
9524         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9525                 goto out_putf;
9526 +
9527 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
9528 +               err = -EACCES;
9529 +               goto out_putf;
9530 +       }
9531 +
9532         mutex_lock(&inode->i_mutex);
9533         if (mode == (mode_t) -1)
9534                 mode = inode->i_mode;
9535 +
9536 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
9537 +               err = -EPERM;
9538 +               mutex_unlock(&inode->i_mutex);
9539 +               goto out_putf;
9540 +       }
9541 +
9542         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
9543         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
9544         err = notify_change(dentry, &newattrs);
9545 @@ -682,9 +732,21 @@ asmlinkage long sys_fchmodat(int dfd, co
9546         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9547                 goto dput_and_out;
9548  
9549 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
9550 +               error = -EACCES;
9551 +               goto dput_and_out;
9552 +       };
9553 +
9554         mutex_lock(&inode->i_mutex);
9555         if (mode == (mode_t) -1)
9556                 mode = inode->i_mode;
9557 +
9558 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
9559 +               error = -EACCES;
9560 +               mutex_unlock(&inode->i_mutex);
9561 +               goto dput_and_out;
9562 +       }
9563 +
9564         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
9565         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
9566         error = notify_change(nd.dentry, &newattrs);
9567 @@ -719,6 +781,12 @@ static int chown_common(struct dentry * 
9568         error = -EPERM;
9569         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9570                 goto out;
9571 +
9572 +       if (!gr_acl_handle_chown(dentry, mnt)) {
9573 +               error = -EACCES;
9574 +               goto out;
9575 +       }
9576 +
9577         newattrs.ia_valid =  ATTR_CTIME;
9578         if (user != (uid_t) -1) {
9579                 newattrs.ia_valid |= ATTR_UID;
9580 @@ -1002,6 +1070,7 @@ repeat:
9581          * N.B. For clone tasks sharing a files structure, this test
9582          * will limit the total number of files that can be opened.
9583          */
9584 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
9585         if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
9586                 goto out;
9587  
9588 diff -urNp linux-2.6.17.11/fs/pipe.c linux-2.6.17.11/fs/pipe.c
9589 --- linux-2.6.17.11/fs/pipe.c   2006-08-07 00:18:54.000000000 -0400
9590 +++ linux-2.6.17.11/fs/pipe.c   2006-09-01 16:20:28.000000000 -0400
9591 @@ -842,7 +842,7 @@ void free_pipe_info(struct inode *inode)
9592         inode->i_pipe = NULL;
9593  }
9594  
9595 -static struct vfsmount *pipe_mnt __read_mostly;
9596 +struct vfsmount *pipe_mnt __read_mostly;
9597  static int pipefs_delete_dentry(struct dentry *dentry)
9598  {
9599         return 1;
9600 diff -urNp linux-2.6.17.11/fs/proc/array.c linux-2.6.17.11/fs/proc/array.c
9601 --- linux-2.6.17.11/fs/proc/array.c     2006-08-07 00:18:54.000000000 -0400
9602 +++ linux-2.6.17.11/fs/proc/array.c     2006-09-01 16:20:28.000000000 -0400
9603 @@ -306,6 +306,21 @@ static inline char *task_cap(struct task
9604                 (unsigned)vx_info_mbcap(vxi, p->cap_effective));
9605  }
9606  
9607 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9608 +static inline char *task_pax(struct task_struct *p, char *buffer)
9609 +{
9610 +       if (p->mm)
9611 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
9612 +                               p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
9613 +                               p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
9614 +                               p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
9615 +                               p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
9616 +                               p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
9617 +       else
9618 +               return buffer + sprintf(buffer, "PaX:\t-----\n");
9619 +}
9620 +#endif
9621 +
9622  int proc_pid_status(struct task_struct *task, char * buffer)
9623  {
9624         char * orig = buffer;
9625 @@ -370,9 +385,20 @@ int proc_pid_status(struct task_struct *
9626  #if defined(CONFIG_S390)
9627         buffer = task_show_regs(task, buffer);
9628  #endif
9629 +
9630 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9631 +       buffer = task_pax(task, buffer);
9632 +#endif
9633 +
9634         return buffer - orig;
9635  }
9636  
9637 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9638 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
9639 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
9640 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
9641 +#endif
9642 +
9643  static int do_task_stat(struct task_struct *task, char * buffer, int whole)
9644  {
9645         unsigned long vsize, eip, esp, wchan = ~0UL;
9646 @@ -461,6 +487,19 @@ static int do_task_stat(struct task_stru
9647                 stime = task->stime;
9648         }
9649  
9650 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9651 +       if (PAX_RAND_FLAGS(mm)) {
9652 +               eip = 0;
9653 +               esp = 0;
9654 +               wchan = 0;
9655 +       }
9656 +#endif
9657 +#ifdef CONFIG_GRKERNSEC_HIDESYM
9658 +       wchan = 0;
9659 +       eip =0;
9660 +       esp =0;
9661 +#endif
9662 +
9663         /* scale priority and nice values from timeslices to -20..20 */
9664         /* to make it look like a "normal" Unix priority/nice value  */
9665         priority = task_prio(task);
9666 @@ -511,9 +550,15 @@ static int do_task_stat(struct task_stru
9667                 vsize,
9668                 mm ? get_mm_rss(mm) : 0,
9669                 rsslim,
9670 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9671 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
9672 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
9673 +               PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
9674 +#else
9675                 mm ? mm->start_code : 0,
9676                 mm ? mm->end_code : 0,
9677                 mm ? mm->start_stack : 0,
9678 +#endif
9679                 esp,
9680                 eip,
9681                 /* The signal information here is obsolete.
9682 @@ -559,3 +604,14 @@ int proc_pid_statm(struct task_struct *t
9683         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
9684                        size, resident, shared, text, lib, data, 0);
9685  }
9686 +
9687 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9688 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
9689 +{
9690 +       int len;
9691 +
9692 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
9693 +       return len;
9694 +}
9695 +#endif
9696 +
9697 diff -urNp linux-2.6.17.11/fs/proc/base.c linux-2.6.17.11/fs/proc/base.c
9698 --- linux-2.6.17.11/fs/proc/base.c      2006-08-07 00:18:54.000000000 -0400
9699 +++ linux-2.6.17.11/fs/proc/base.c      2006-09-01 16:20:28.000000000 -0400
9700 @@ -75,6 +75,7 @@
9701  #include <linux/vs_context.h>
9702  #include <linux/vs_network.h>
9703  #include <linux/vs_pid.h>
9704 +#include <linux/grsecurity.h>
9705  #include "internal.h"
9706  
9707  /*
9708 @@ -130,6 +131,9 @@ enum pid_directory_inos {
9709  #ifdef CONFIG_AUDITSYSCALL
9710         PROC_TGID_LOGINUID,
9711  #endif
9712 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9713 +       PROC_TGID_IPADDR,
9714 +#endif
9715         PROC_TGID_OOM_SCORE,
9716         PROC_TGID_OOM_ADJUST,
9717         PROC_TID_INO,
9718 @@ -211,6 +215,9 @@ static struct pid_entry tgid_base_stuff[
9719         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
9720         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
9721         E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
9722 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9723 +       E(PROC_TGID_IPADDR,     "ipaddr", S_IFREG|S_IRUSR),
9724 +#endif
9725  #ifdef CONFIG_MMU
9726         E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
9727  #endif
9728 @@ -421,7 +428,7 @@ static int proc_task_root_link(struct in
9729         (task->parent == current && \
9730         (task->ptrace & PT_PTRACED) && \
9731          (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
9732 -        security_ptrace(current,task) == 0))
9733 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
9734  
9735  static int proc_pid_environ(struct task_struct *task, char * buffer)
9736  {
9737 @@ -607,9 +614,25 @@ static int proc_check_root(struct inode 
9738  
9739  static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
9740  {
9741 +       int ret = -EACCES;
9742 +       struct task_struct *task;
9743 +
9744         if (generic_permission(inode, mask, NULL) != 0)
9745 -               return -EACCES;
9746 -       return proc_check_root(inode);
9747 +               goto out;
9748 +
9749 +       ret = proc_check_root(inode);
9750 +       if (ret)
9751 +               goto out;
9752 +
9753 +       task = proc_task(inode);
9754 +
9755 +       if (!task)
9756 +               goto out;
9757 +
9758 +       ret = gr_acl_handle_procpidmem(task);
9759 +
9760 +out:
9761 +       return ret;
9762  }
9763  
9764  static int proc_setattr(struct dentry *dentry, struct iattr *attr)
9765 @@ -1423,6 +1446,9 @@ static struct inode *proc_pid_make_inode
9766         }
9767         /* procfs is xid tagged */
9768         inode->i_tag = (tag_t)vx_task_xid(task);
9769 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9770 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9771 +#endif
9772         security_task_to_inode(task, inode);
9773  
9774  out:
9775 @@ -1455,7 +1481,9 @@ static int pid_revalidate(struct dentry 
9776  
9777                 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
9778                         inode->i_uid = task->euid;
9779 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
9780                         inode->i_gid = task->egid;
9781 +#endif
9782                 } else {
9783                         inode->i_uid = 0;
9784                         inode->i_gid = 0;
9785 @@ -1791,6 +1819,12 @@ static struct dentry *proc_pident_lookup
9786                         inode->i_fop = &proc_info_file_operations;
9787                         ei->op.proc_read = proc_pid_status;
9788                         break;
9789 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9790 +               case PROC_TGID_IPADDR:
9791 +                       inode->i_fop = &proc_info_file_operations;
9792 +                       ei->op.proc_read = proc_pid_ipaddr;
9793 +                       break;
9794 +#endif
9795                 case PROC_TID_STAT:
9796                         inode->i_fop = &proc_info_file_operations;
9797                         ei->op.proc_read = proc_tid_stat;
9798 @@ -2140,11 +2174,34 @@ struct dentry *proc_pid_lookup(struct in
9799         if (!proc_pid_visible(task, tgid))
9800                 goto out_drop_task;
9801  
9802 +       if (gr_check_hidden_task(task)) {
9803 +               put_task_struct(task);
9804 +               goto out;
9805 +       }
9806 +
9807 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9808 +       if (current->uid && (task->uid != current->uid)
9809 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9810 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
9811 +#endif
9812 +       ) {
9813 +               put_task_struct(task);
9814 +               goto out;
9815 +       }
9816 +#endif
9817 +
9818         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
9819         if (!inode)
9820                 goto out_drop_task;
9821  
9822 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9823 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
9824 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9825 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
9826 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9827 +#else
9828         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
9829 +#endif
9830         inode->i_op = &proc_tgid_base_inode_operations;
9831         inode->i_fop = &proc_tgid_base_operations;
9832         inode->i_flags|=S_IMMUTABLE;
9833 @@ -2243,6 +2300,9 @@ out:
9834  static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
9835  {
9836         struct task_struct *p;
9837 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9838 +       struct task_struct *tmp = current;
9839 +#endif
9840         int nr_tgids = 0;
9841  
9842         index--;
9843 @@ -2267,6 +2327,18 @@ static int get_tgid_list(int index, unsi
9844                 /* check for context visibility */
9845                 if (!proc_pid_visible(p, tgid))
9846                         continue;
9847 +               if (gr_pid_is_chrooted(p))
9848 +                       continue;
9849 +               if (gr_check_hidden_task(p))
9850 +                       continue;
9851 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9852 +               if (tmp->uid && (p->uid != tmp->uid)
9853 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9854 +                   && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
9855 +#endif
9856 +               )
9857 +                       continue;
9858 +#endif
9859                 if (--index >= 0)
9860                         continue;
9861                 tgids[nr_tgids] = vx_map_tgid(tgid);
9862 diff -urNp linux-2.6.17.11/fs/proc/inode.c linux-2.6.17.11/fs/proc/inode.c
9863 --- linux-2.6.17.11/fs/proc/inode.c     2006-08-07 00:18:54.000000000 -0400
9864 +++ linux-2.6.17.11/fs/proc/inode.c     2006-09-01 16:20:28.000000000 -0400
9865 @@ -169,7 +169,11 @@ struct inode *proc_get_inode(struct supe
9866                 if (de->mode) {
9867                         inode->i_mode = de->mode;
9868                         inode->i_uid = de->uid;
9869 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9870 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9871 +#else
9872                         inode->i_gid = de->gid;
9873 +#endif
9874                 }
9875                 if (de->vx_flags)
9876                         PROC_I(inode)->vx_flags = de->vx_flags;
9877 diff -urNp linux-2.6.17.11/fs/proc/internal.h linux-2.6.17.11/fs/proc/internal.h
9878 --- linux-2.6.17.11/fs/proc/internal.h  2006-08-07 00:18:54.000000000 -0400
9879 +++ linux-2.6.17.11/fs/proc/internal.h  2006-09-01 16:20:28.000000000 -0400
9880 @@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
9881  extern int proc_tgid_stat(struct task_struct *, char *);
9882  extern int proc_pid_status(struct task_struct *, char *);
9883  extern int proc_pid_statm(struct task_struct *, char *);
9884 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9885 +extern int proc_pid_ipaddr(struct task_struct*,char*);
9886 +#endif
9887  
9888  void free_proc_entry(struct proc_dir_entry *de);
9889  
9890 diff -urNp linux-2.6.17.11/fs/proc/proc_misc.c linux-2.6.17.11/fs/proc/proc_misc.c
9891 --- linux-2.6.17.11/fs/proc/proc_misc.c 2006-08-07 00:18:54.000000000 -0400
9892 +++ linux-2.6.17.11/fs/proc/proc_misc.c 2006-09-01 16:20:28.000000000 -0400
9893 @@ -651,6 +651,8 @@ void create_seq_entry(char *name, mode_t
9894  void __init proc_misc_init(void)
9895  {
9896         struct proc_dir_entry *entry;
9897 +       int gr_mode = 0;
9898 +
9899         static struct {
9900                 char *name;
9901                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
9902 @@ -666,7 +668,9 @@ void __init proc_misc_init(void)
9903                 {"stram",       stram_read_proc},
9904  #endif
9905                 {"filesystems", filesystems_read_proc},
9906 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
9907                 {"cmdline",     cmdline_read_proc},
9908 +#endif
9909                 {"locks",       locks_read_proc},
9910                 {"execdomains", execdomains_read_proc},
9911                 {NULL,}
9912 @@ -674,19 +678,36 @@ void __init proc_misc_init(void)
9913         for (p = simple_ones; p->name; p++)
9914                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
9915  
9916 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9917 +       gr_mode = S_IRUSR;
9918 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9919 +       gr_mode = S_IRUSR | S_IRGRP;
9920 +#endif
9921 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9922 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
9923 +#endif
9924 +
9925         proc_symlink("mounts", NULL, "self/mounts");
9926  
9927         /* And now for trickier ones */
9928         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
9929         if (entry)
9930                 entry->proc_fops = &proc_kmsg_operations;
9931 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9932 +       create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
9933 +#else
9934         create_seq_entry("devices", 0, &proc_devinfo_operations);
9935 +#endif
9936         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
9937         create_seq_entry("partitions", 0, &proc_partitions_operations);
9938         create_seq_entry("stat", 0, &proc_stat_operations);
9939         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
9940  #ifdef CONFIG_SLAB
9941 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9942 +       create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
9943 +#else
9944         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
9945 +#endif
9946  #ifdef CONFIG_DEBUG_SLAB_LEAK
9947         create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
9948  #endif
9949 @@ -701,7 +722,7 @@ void __init proc_misc_init(void)
9950  #ifdef CONFIG_SCHEDSTATS
9951         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
9952  #endif
9953 -#ifdef CONFIG_PROC_KCORE
9954 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
9955         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
9956         if (proc_root_kcore) {
9957                 proc_root_kcore->proc_fops = &proc_kcore_operations;
9958 diff -urNp linux-2.6.17.11/fs/proc/root.c linux-2.6.17.11/fs/proc/root.c
9959 --- linux-2.6.17.11/fs/proc/root.c      2006-08-07 00:18:54.000000000 -0400
9960 +++ linux-2.6.17.11/fs/proc/root.c      2006-09-01 16:20:28.000000000 -0400
9961 @@ -53,7 +53,13 @@ void __init proc_root_init(void)
9962                 return;
9963         }
9964         proc_misc_init();
9965 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9966 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
9967 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9968 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
9969 +#else
9970         proc_net = proc_mkdir("net", NULL);
9971 +#endif
9972         proc_net_stat = proc_mkdir("net/stat", NULL);
9973  
9974  #ifdef CONFIG_SYSVIPC
9975 @@ -77,7 +83,15 @@ void __init proc_root_init(void)
9976  #ifdef CONFIG_PROC_DEVICETREE
9977         proc_device_tree_init();
9978  #endif
9979 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9980 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9981 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
9982 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9983 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
9984 +#endif
9985 +#else
9986         proc_bus = proc_mkdir("bus", NULL);
9987 +#endif
9988         proc_vx_init();
9989  }
9990  
9991 diff -urNp linux-2.6.17.11/fs/proc/task_mmu.c linux-2.6.17.11/fs/proc/task_mmu.c
9992 --- linux-2.6.17.11/fs/proc/task_mmu.c  2006-08-07 00:18:54.000000000 -0400
9993 +++ linux-2.6.17.11/fs/proc/task_mmu.c  2006-09-01 16:20:28.000000000 -0400
9994 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
9995                 "VmStk:\t%8lu kB\n"
9996                 "VmExe:\t%8lu kB\n"
9997                 "VmLib:\t%8lu kB\n"
9998 -               "VmPTE:\t%8lu kB\n",
9999 -               hiwater_vm << (PAGE_SHIFT-10),
10000 +               "VmPTE:\t%8lu kB\n"
10001 +
10002 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
10003 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
10004 +#endif
10005 +
10006 +               ,hiwater_vm << (PAGE_SHIFT-10),
10007                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
10008                 mm->locked_vm << (PAGE_SHIFT-10),
10009                 hiwater_rss << (PAGE_SHIFT-10),
10010                 total_rss << (PAGE_SHIFT-10),
10011                 data << (PAGE_SHIFT-10),
10012                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
10013 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
10014 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
10015 +
10016 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
10017 +               , mm->context.user_cs_base, mm->context.user_cs_limit
10018 +#endif
10019 +
10020 +       );
10021 +
10022         return buffer;
10023  }
10024  
10025 @@ -118,6 +130,12 @@ struct mem_size_stats
10026         unsigned long private_dirty;
10027  };
10028  
10029 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
10030 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
10031 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
10032 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
10033 +#endif
10034 +
10035  static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
10036  {
10037         struct task_struct *task = m->private;
10038 @@ -136,13 +154,30 @@ static int show_map_internal(struct seq_
10039         }
10040  
10041         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
10042 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
10043 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
10044 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
10045 +#else
10046                         vma->vm_start,
10047                         vma->vm_end,
10048 +#endif
10049 +
10050 +#if 0
10051 +                       flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
10052 +                       flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
10053 +                       flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
10054 +#else
10055                         flags & VM_READ ? 'r' : '-',
10056                         flags & VM_WRITE ? 'w' : '-',
10057                         flags & VM_EXEC ? 'x' : '-',
10058 +#endif
10059 +
10060                         flags & VM_MAYSHARE ? 's' : 'p',
10061 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
10062 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
10063 +#else
10064                         vma->vm_pgoff << PAGE_SHIFT,
10065 +#endif
10066                         MAJOR(dev), MINOR(dev), ino, &len);
10067  
10068         /*
10069 @@ -154,13 +189,13 @@ static int show_map_internal(struct seq_
10070                 seq_path(m, file->f_vfsmnt, file->f_dentry, "\n");
10071         } else {
10072                 if (mm) {
10073 -                       if (vma->vm_start <= mm->start_brk &&
10074 -                                               vma->vm_end >= mm->brk) {
10075 +                       if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
10076                                 pad_len_spaces(m, len);
10077                                 seq_puts(m, "[heap]");
10078                         } else {
10079 -                               if (vma->vm_start <= mm->start_stack &&
10080 -                                       vma->vm_end >= mm->start_stack) {
10081 +                               if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
10082 +                                   (vma->vm_start <= mm->start_stack &&
10083 +                                       vma->vm_end >= mm->start_stack)) {
10084  
10085                                         pad_len_spaces(m, len);
10086                                         seq_puts(m, "[stack]");
10087 @@ -173,7 +208,25 @@ static int show_map_internal(struct seq_
10088         }
10089         seq_putc(m, '\n');
10090  
10091 -       if (mss)
10092 +       
10093 +       if (mss) {
10094 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
10095 +           if (PAX_RAND_FLAGS(mm))
10096 +               seq_printf(m,
10097 +                          "Size:          %8lu kB\n"
10098 +                          "Rss:           %8lu kB\n"
10099 +                          "Shared_Clean:  %8lu kB\n"
10100 +                          "Shared_Dirty:  %8lu kB\n"
10101 +                          "Private_Clean: %8lu kB\n"
10102 +                          "Private_Dirty: %8lu kB\n",
10103 +                          0UL,
10104 +                          0UL,
10105 +                          0UL,
10106 +                          0UL,
10107 +                          0UL,
10108 +                          0UL);
10109 +           else
10110 +#endif
10111                 seq_printf(m,
10112                            "Size:          %8lu kB\n"
10113                            "Rss:           %8lu kB\n"
10114 @@ -187,6 +240,7 @@ static int show_map_internal(struct seq_
10115                            mss->shared_dirty  >> 10,
10116                            mss->private_clean >> 10,
10117                            mss->private_dirty >> 10);
10118 +       }
10119  
10120         if (m->count < m->size)  /* vma is copied successfully */
10121                 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
10122 diff -urNp linux-2.6.17.11/fs/readdir.c linux-2.6.17.11/fs/readdir.c
10123 --- linux-2.6.17.11/fs/readdir.c        2006-08-07 00:18:54.000000000 -0400
10124 +++ linux-2.6.17.11/fs/readdir.c        2006-09-01 16:20:28.000000000 -0400
10125 @@ -16,6 +16,8 @@
10126  #include <linux/security.h>
10127  #include <linux/syscalls.h>
10128  #include <linux/unistd.h>
10129 +#include <linux/namei.h>
10130 +#include <linux/grsecurity.h>
10131  
10132  #include <asm/uaccess.h>
10133  
10134 @@ -65,6 +67,7 @@ struct old_linux_dirent {
10135  
10136  struct readdir_callback {
10137         struct old_linux_dirent __user * dirent;
10138 +       struct file * file;
10139         int result;
10140  };
10141  
10142 @@ -76,6 +79,10 @@ static int fillonedir(void * __buf, cons
10143  
10144         if (buf->result)
10145                 return -EINVAL;
10146 +
10147 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
10148 +               return 0;
10149 +
10150         buf->result++;
10151         dirent = buf->dirent;
10152         if (!access_ok(VERIFY_WRITE, dirent,
10153 @@ -107,6 +114,7 @@ asmlinkage long old_readdir(unsigned int
10154  
10155         buf.result = 0;
10156         buf.dirent = dirent;
10157 +       buf.file = file;
10158  
10159         error = vfs_readdir(file, fillonedir, &buf);
10160         if (error >= 0)
10161 @@ -133,6 +141,7 @@ struct linux_dirent {
10162  struct getdents_callback {
10163         struct linux_dirent __user * current_dir;
10164         struct linux_dirent __user * previous;
10165 +       struct file * file;
10166         int count;
10167         int error;
10168  };
10169 @@ -147,6 +156,10 @@ static int filldir(void * __buf, const c
10170         buf->error = -EINVAL;   /* only used if we fail.. */
10171         if (reclen > buf->count)
10172                 return -EINVAL;
10173 +
10174 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
10175 +               return 0;
10176 +
10177         dirent = buf->previous;
10178         if (dirent) {
10179                 if (__put_user(offset, &dirent->d_off))
10180 @@ -191,6 +204,7 @@ asmlinkage long sys_getdents(unsigned in
10181  
10182         buf.current_dir = dirent;
10183         buf.previous = NULL;
10184 +       buf.file = file;
10185         buf.count = count;
10186         buf.error = 0;
10187  
10188 @@ -217,6 +231,7 @@ out:
10189  struct getdents_callback64 {
10190         struct linux_dirent64 __user * current_dir;
10191         struct linux_dirent64 __user * previous;
10192 +       struct file * file;
10193         int count;
10194         int error;
10195  };
10196 @@ -231,6 +246,10 @@ static int filldir64(void * __buf, const
10197         buf->error = -EINVAL;   /* only used if we fail.. */
10198         if (reclen > buf->count)
10199                 return -EINVAL;
10200 +
10201 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
10202 +               return 0;
10203 +
10204         dirent = buf->previous;
10205         if (dirent) {
10206                 if (__put_user(offset, &dirent->d_off))
10207 @@ -277,6 +296,7 @@ asmlinkage long sys_getdents64(unsigned 
10208  
10209         buf.current_dir = dirent;
10210         buf.previous = NULL;
10211 +       buf.file = file;
10212         buf.count = count;
10213         buf.error = 0;
10214  
10215 diff -urNp linux-2.6.17.11/fs/xfs/linux-2.6/xfs_file.c linux-2.6.17.11/fs/xfs/linux-2.6/xfs_file.c
10216 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_file.c 2006-08-07 00:18:54.000000000 -0400
10217 +++ linux-2.6.17.11/fs/xfs/linux-2.6/xfs_file.c 2006-09-01 16:20:28.000000000 -0400
10218 @@ -461,6 +461,11 @@ xfs_file_mmap(
10219         vattr_t         vattr;
10220         int             error;
10221  
10222 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
10223 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
10224 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
10225 +#endif
10226 +
10227         vma->vm_ops = &xfs_file_vm_ops;
10228  
10229  #ifdef CONFIG_XFS_DMAPI
10230 diff -urNp linux-2.6.17.11/grsecurity/gracl_alloc.c linux-2.6.17.11/grsecurity/gracl_alloc.c
10231 --- linux-2.6.17.11/grsecurity/gracl_alloc.c    1969-12-31 19:00:00.000000000 -0500
10232 +++ linux-2.6.17.11/grsecurity/gracl_alloc.c    2006-09-01 16:20:28.000000000 -0400
10233 @@ -0,0 +1,91 @@
10234 +#include <linux/kernel.h>
10235 +#include <linux/mm.h>
10236 +#include <linux/slab.h>
10237 +#include <linux/vmalloc.h>
10238 +#include <linux/gracl.h>
10239 +#include <linux/grsecurity.h>
10240 +
10241 +static unsigned long alloc_stack_next = 1;
10242 +static unsigned long alloc_stack_size = 1;
10243 +static void **alloc_stack;
10244 +
10245 +static __inline__ int
10246 +alloc_pop(void)
10247 +{
10248 +       if (alloc_stack_next == 1)
10249 +               return 0;
10250 +
10251 +       kfree(alloc_stack[alloc_stack_next - 2]);
10252 +
10253 +       alloc_stack_next--;
10254 +
10255 +       return 1;
10256 +}
10257 +
10258 +static __inline__ void
10259 +alloc_push(void *buf)
10260 +{
10261 +       if (alloc_stack_next >= alloc_stack_size)
10262 +               BUG();
10263 +
10264 +       alloc_stack[alloc_stack_next - 1] = buf;
10265 +
10266 +       alloc_stack_next++;
10267 +
10268 +       return;
10269 +}
10270 +
10271 +void *
10272 +acl_alloc(unsigned long len)
10273 +{
10274 +       void *ret;
10275 +
10276 +       if (len > PAGE_SIZE)
10277 +               BUG();
10278 +
10279 +       ret = kmalloc(len, GFP_KERNEL);
10280 +
10281 +       if (ret)
10282 +               alloc_push(ret);
10283 +
10284 +       return ret;
10285 +}
10286 +
10287 +void
10288 +acl_free_all(void)
10289 +{
10290 +       if (gr_acl_is_enabled() || !alloc_stack)
10291 +               return;
10292 +
10293 +       while (alloc_pop()) ;
10294 +
10295 +       if (alloc_stack) {
10296 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
10297 +                       kfree(alloc_stack);
10298 +               else
10299 +                       vfree(alloc_stack);
10300 +       }
10301 +
10302 +       alloc_stack = NULL;
10303 +       alloc_stack_size = 1;
10304 +       alloc_stack_next = 1;
10305 +
10306 +       return;
10307 +}
10308 +
10309 +int
10310 +acl_alloc_stack_init(unsigned long size)
10311 +{
10312 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
10313 +               alloc_stack =
10314 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
10315 +       else
10316 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
10317 +
10318 +       alloc_stack_size = size;
10319 +
10320 +       if (!alloc_stack)
10321 +               return 0;
10322 +       else
10323 +               return 1;
10324 +}
10325 diff -urNp linux-2.6.17.11/grsecurity/gracl.c linux-2.6.17.11/grsecurity/gracl.c
10326 --- linux-2.6.17.11/grsecurity/gracl.c  1969-12-31 19:00:00.000000000 -0500
10327 +++ linux-2.6.17.11/grsecurity/gracl.c  2006-09-01 16:20:28.000000000 -0400
10328 @@ -0,0 +1,3547 @@
10329 +#include <linux/kernel.h>
10330 +#include <linux/module.h>
10331 +#include <linux/sched.h>
10332 +#include <linux/mm.h>
10333 +#include <linux/file.h>
10334 +#include <linux/fs.h>
10335 +#include <linux/namei.h>
10336 +#include <linux/mount.h>
10337 +#include <linux/tty.h>
10338 +#include <linux/proc_fs.h>
10339 +#include <linux/smp_lock.h>
10340 +#include <linux/slab.h>
10341 +#include <linux/vmalloc.h>
10342 +#include <linux/types.h>
10343 +#include <linux/capability.h>
10344 +#include <linux/sysctl.h>
10345 +#include <linux/netdevice.h>
10346 +#include <linux/ptrace.h>
10347 +#include <linux/gracl.h>
10348 +#include <linux/gralloc.h>
10349 +#include <linux/grsecurity.h>
10350 +#include <linux/grinternal.h>
10351 +#include <linux/percpu.h>
10352 +
10353 +#include <asm/uaccess.h>
10354 +#include <asm/errno.h>
10355 +#include <asm/mman.h>
10356 +
10357 +static struct acl_role_db acl_role_set;
10358 +static struct name_db name_set;
10359 +static struct inodev_db inodev_set;
10360 +
10361 +/* for keeping track of userspace pointers used for subjects, so we
10362 +   can share references in the kernel as well
10363 +*/
10364 +
10365 +static struct dentry *real_root;
10366 +static struct vfsmount *real_root_mnt;
10367 +
10368 +static struct acl_subj_map_db subj_map_set;
10369 +
10370 +static struct acl_role_label *default_role;
10371 +
10372 +static u16 acl_sp_role_value;
10373 +
10374 +extern char *gr_shared_page[4];
10375 +static DECLARE_MUTEX(gr_dev_sem);
10376 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
10377 +
10378 +struct gr_arg *gr_usermode;
10379 +
10380 +static unsigned int gr_status = GR_STATUS_INIT;
10381 +
10382 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
10383 +extern void gr_clear_learn_entries(void);
10384 +
10385 +#ifdef CONFIG_GRKERNSEC_RESLOG
10386 +extern void gr_log_resource(const struct task_struct *task,
10387 +                           const int res, const unsigned long wanted, const int gt);
10388 +#endif
10389 +
10390 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
10391 +                        struct dentry *root, struct vfsmount *rootmnt,
10392 +                        char *buffer, int buflen);
10393 +
10394 +unsigned char *gr_system_salt;
10395 +unsigned char *gr_system_sum;
10396 +
10397 +static struct sprole_pw **acl_special_roles = NULL;
10398 +static __u16 num_sprole_pws = 0;
10399 +
10400 +static struct acl_role_label *kernel_role = NULL;
10401 +
10402 +static unsigned int gr_auth_attempts = 0;
10403 +static unsigned long gr_auth_expires = 0UL;
10404 +
10405 +extern struct vfsmount *sock_mnt;
10406 +extern struct vfsmount *pipe_mnt;
10407 +extern struct vfsmount *shm_mnt;
10408 +static struct acl_object_label *fakefs_obj;
10409 +
10410 +extern int gr_init_uidset(void);
10411 +extern void gr_free_uidset(void);
10412 +extern void gr_remove_uid(uid_t uid);
10413 +extern int gr_find_uid(uid_t uid);
10414 +
10415 +__inline__ int
10416 +gr_acl_is_enabled(void)
10417 +{
10418 +       return (gr_status & GR_READY);
10419 +}
10420 +
10421 +char gr_roletype_to_char(void)
10422 +{
10423 +       switch (current->role->roletype &
10424 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
10425 +                GR_ROLE_SPECIAL)) {
10426 +       case GR_ROLE_DEFAULT:
10427 +               return 'D';
10428 +       case GR_ROLE_USER:
10429 +               return 'U';
10430 +       case GR_ROLE_GROUP:
10431 +               return 'G';
10432 +       case GR_ROLE_SPECIAL:
10433 +               return 'S';
10434 +       }
10435 +
10436 +       return 'X';
10437 +}
10438 +
10439 +__inline__ int
10440 +gr_acl_tpe_check(void)
10441 +{
10442 +       if (unlikely(!(gr_status & GR_READY)))
10443 +               return 0;
10444 +       if (current->role->roletype & GR_ROLE_TPE)
10445 +               return 1;
10446 +       else
10447 +               return 0;
10448 +}
10449 +
10450 +int
10451 +gr_handle_rawio(const struct inode *inode)
10452 +{
10453 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
10454 +       if (inode && S_ISBLK(inode->i_mode) &&
10455 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
10456 +           !capable(CAP_SYS_RAWIO))
10457 +               return 1;
10458 +#endif
10459 +       return 0;
10460 +}
10461 +
10462 +static int
10463 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
10464 +{
10465 +       int i;
10466 +       unsigned long *l1;
10467 +       unsigned long *l2;
10468 +       unsigned char *c1;
10469 +       unsigned char *c2;
10470 +       int num_longs;
10471 +
10472 +       if (likely(lena != lenb))
10473 +               return 0;
10474 +
10475 +       l1 = (unsigned long *)a;
10476 +       l2 = (unsigned long *)b;
10477 +
10478 +       num_longs = lena / sizeof(unsigned long);
10479 +
10480 +       for (i = num_longs; i--; l1++, l2++) {
10481 +               if (unlikely(*l1 != *l2))
10482 +                       return 0;
10483 +       }
10484 +
10485 +       c1 = (unsigned char *) l1;
10486 +       c2 = (unsigned char *) l2;
10487 +
10488 +       i = lena - (num_longs * sizeof(unsigned long)); 
10489 +
10490 +       for (; i--; c1++, c2++) {
10491 +               if (unlikely(*c1 != *c2))
10492 +                       return 0;
10493 +       }
10494 +
10495 +       return 1;
10496 +}
10497 +               
10498 +static char *
10499 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
10500 +              struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
10501 +{
10502 +       char *end = buf + buflen;
10503 +       char *retval;
10504 +       int namelen = 0;
10505 +
10506 +       *--end = '\0';
10507 +
10508 +       retval = end - 1;
10509 +       *retval = '/';
10510 +
10511 +       if (dentry == root && vfsmnt == rootmnt)
10512 +               return retval;
10513 +       if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
10514 +               namelen = strlen(dentry->d_name.name);
10515 +               buflen -= namelen;
10516 +               if (buflen < 2)
10517 +                       goto err;
10518 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
10519 +                       buflen--;
10520 +       }
10521 +
10522 +       retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
10523 +       if (unlikely(IS_ERR(retval)))
10524 +err:
10525 +               retval = strcpy(buf, "<path too long>");
10526 +       else if (namelen != 0) {
10527 +               end = buf + buflen - 1; // accounts for null termination
10528 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
10529 +                       *end++ = '/'; // accounted for above with buflen--
10530 +               memcpy(end, dentry->d_name.name, namelen);
10531 +       }
10532 +
10533 +       return retval;
10534 +}
10535 +
10536 +static char *
10537 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
10538 +               char *buf, int buflen)
10539 +{
10540 +       char *res;
10541 +
10542 +       /* we can use real_root, real_root_mnt, because this is only called
10543 +          by the RBAC system */
10544 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
10545 +
10546 +       return res;
10547 +}
10548 +
10549 +static char *
10550 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
10551 +           char *buf, int buflen)
10552 +{
10553 +       char *res;
10554 +       struct dentry *root;
10555 +       struct vfsmount *rootmnt;
10556 +
10557 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
10558 +       read_lock(&child_reaper->fs->lock);
10559 +       root = dget(child_reaper->fs->root);
10560 +       rootmnt = mntget(child_reaper->fs->rootmnt);
10561 +       read_unlock(&child_reaper->fs->lock);
10562 +
10563 +       spin_lock(&dcache_lock);
10564 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
10565 +       spin_unlock(&dcache_lock);
10566 +
10567 +       dput(root);
10568 +       mntput(rootmnt);
10569 +       return res;
10570 +}
10571 +
10572 +static char *
10573 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
10574 +{
10575 +       char *ret;
10576 +       spin_lock(&dcache_lock);
10577 +       ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
10578 +                            PAGE_SIZE);
10579 +       spin_unlock(&dcache_lock);
10580 +       return ret;
10581 +}
10582 +
10583 +char *
10584 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
10585 +{
10586 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
10587 +                            PAGE_SIZE);
10588 +}
10589 +
10590 +char *
10591 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
10592 +{
10593 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
10594 +                          PAGE_SIZE);
10595 +}
10596 +
10597 +char *
10598 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
10599 +{
10600 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
10601 +                          PAGE_SIZE);
10602 +}
10603 +
10604 +char *
10605 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
10606 +{
10607 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
10608 +                          PAGE_SIZE);
10609 +}
10610 +
10611 +char *
10612 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
10613 +{
10614 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
10615 +                          PAGE_SIZE);
10616 +}
10617 +
10618 +__inline__ __u32
10619 +to_gr_audit(const __u32 reqmode)
10620 +{
10621 +       /* masks off auditable permission flags, then shifts them to create
10622 +          auditing flags, and adds the special case of append auditing if
10623 +          we're requesting write */
10624 +       return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
10625 +}
10626 +
10627 +struct acl_subject_label *
10628 +lookup_subject_map(const struct acl_subject_label *userp)
10629 +{
10630 +       unsigned int index = shash(userp, subj_map_set.s_size);
10631 +       struct subject_map *match;
10632 +
10633 +       match = subj_map_set.s_hash[index];
10634 +
10635 +       while (match && match->user != userp)
10636 +               match = match->next;
10637 +
10638 +       if (match != NULL)
10639 +               return match->kernel;
10640 +       else
10641 +               return NULL;
10642 +}
10643 +
10644 +static void
10645 +insert_subj_map_entry(struct subject_map *subjmap)
10646 +{
10647 +       unsigned int index = shash(subjmap->user, subj_map_set.s_size);
10648 +       struct subject_map **curr;
10649 +
10650 +       subjmap->prev = NULL;
10651 +
10652 +       curr = &subj_map_set.s_hash[index];
10653 +       if (*curr != NULL)
10654 +               (*curr)->prev = subjmap;
10655 +
10656 +       subjmap->next = *curr;
10657 +       *curr = subjmap;
10658 +
10659 +       return;
10660 +}
10661 +
10662 +static struct acl_role_label *
10663 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
10664 +                     const gid_t gid)
10665 +{
10666 +       unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
10667 +       struct acl_role_label *match;
10668 +       struct role_allowed_ip *ipp;
10669 +       unsigned int x;
10670 +
10671 +       match = acl_role_set.r_hash[index];
10672 +
10673 +       while (match) {
10674 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
10675 +                       for (x = 0; x < match->domain_child_num; x++) {
10676 +                               if (match->domain_children[x] == uid)
10677 +                                       goto found;
10678 +                       }
10679 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
10680 +                       break;
10681 +               match = match->next;
10682 +       }
10683 +found:
10684 +       if (match == NULL) {
10685 +             try_group:
10686 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
10687 +               match = acl_role_set.r_hash[index];
10688 +
10689 +               while (match) {
10690 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
10691 +                               for (x = 0; x < match->domain_child_num; x++) {
10692 +                                       if (match->domain_children[x] == gid)
10693 +                                               goto found2;
10694 +                               }
10695 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
10696 +                               break;
10697 +                       match = match->next;
10698 +               }
10699 +found2:
10700 +               if (match == NULL)
10701 +                       match = default_role;
10702 +               if (match->allowed_ips == NULL)
10703 +                       return match;
10704 +               else {
10705 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
10706 +                               if (likely
10707 +                                   ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
10708 +                                    (ntohl(ipp->addr) & ipp->netmask)))
10709 +                                       return match;
10710 +                       }
10711 +                       match = default_role;
10712 +               }
10713 +       } else if (match->allowed_ips == NULL) {
10714 +               return match;
10715 +       } else {
10716 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
10717 +                       if (likely
10718 +                           ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
10719 +                            (ntohl(ipp->addr) & ipp->netmask)))
10720 +                               return match;
10721 +               }
10722 +               goto try_group;
10723 +       }
10724 +
10725 +       return match;
10726 +}
10727 +
10728 +struct acl_subject_label *
10729 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
10730 +                     const struct acl_role_label *role)
10731 +{
10732 +       unsigned int index = fhash(ino, dev, role->subj_hash_size);
10733 +       struct acl_subject_label *match;
10734 +
10735 +       match = role->subj_hash[index];
10736 +
10737 +       while (match && (match->inode != ino || match->device != dev ||
10738 +              (match->mode & GR_DELETED))) {
10739 +               match = match->next;
10740 +       }
10741 +
10742 +       if (match && !(match->mode & GR_DELETED))
10743 +               return match;
10744 +       else
10745 +               return NULL;
10746 +}
10747 +
10748 +static struct acl_object_label *
10749 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
10750 +                    const struct acl_subject_label *subj)
10751 +{
10752 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
10753 +       struct acl_object_label *match;
10754 +
10755 +       match = subj->obj_hash[index];
10756 +
10757 +       while (match && (match->inode != ino || match->device != dev ||
10758 +              (match->mode & GR_DELETED))) {
10759 +               match = match->next;
10760 +       }
10761 +
10762 +       if (match && !(match->mode & GR_DELETED))
10763 +               return match;
10764 +       else
10765 +               return NULL;
10766 +}
10767 +
10768 +static struct acl_object_label *
10769 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
10770 +                    const struct acl_subject_label *subj)
10771 +{
10772 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
10773 +       struct acl_object_label *match;
10774 +
10775 +       match = subj->obj_hash[index];
10776 +
10777 +       while (match && (match->inode != ino || match->device != dev ||
10778 +              !(match->mode & GR_DELETED))) {
10779 +               match = match->next;
10780 +       }
10781 +
10782 +       if (match && (match->mode & GR_DELETED))
10783 +               return match;
10784 +
10785 +       match = subj->obj_hash[index];
10786 +
10787 +       while (match && (match->inode != ino || match->device != dev ||
10788 +              (match->mode & GR_DELETED))) {
10789 +               match = match->next;
10790 +       }
10791 +
10792 +       if (match && !(match->mode & GR_DELETED))
10793 +               return match;
10794 +       else
10795 +               return NULL;
10796 +}
10797 +
10798 +static struct name_entry *
10799 +lookup_name_entry(const char *name)
10800 +{
10801 +       unsigned int len = strlen(name);
10802 +       unsigned int key = full_name_hash(name, len);
10803 +       unsigned int index = key % name_set.n_size;
10804 +       struct name_entry *match;
10805 +
10806 +       match = name_set.n_hash[index];
10807 +
10808 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
10809 +               match = match->next;
10810 +
10811 +       return match;
10812 +}
10813 +
10814 +static struct inodev_entry *
10815 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
10816 +{
10817 +       unsigned int index = fhash(ino, dev, inodev_set.i_size);
10818 +       struct inodev_entry *match;
10819 +
10820 +       match = inodev_set.i_hash[index];
10821 +
10822 +       while (match && (match->nentry->inode != ino || match->nentry->device != dev))
10823 +               match = match->next;
10824 +
10825 +       return match;
10826 +}
10827 +
10828 +static void
10829 +insert_inodev_entry(struct inodev_entry *entry)
10830 +{
10831 +       unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
10832 +                                   inodev_set.i_size);
10833 +       struct inodev_entry **curr;
10834 +
10835 +       entry->prev = NULL;
10836 +
10837 +       curr = &inodev_set.i_hash[index];
10838 +       if (*curr != NULL)
10839 +               (*curr)->prev = entry;
10840 +       
10841 +       entry->next = *curr;
10842 +       *curr = entry;
10843 +
10844 +       return;
10845 +}
10846 +
10847 +static void
10848 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
10849 +{
10850 +       unsigned int index =
10851 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
10852 +       struct acl_role_label **curr;
10853 +
10854 +       role->prev = NULL;
10855 +
10856 +       curr = &acl_role_set.r_hash[index];
10857 +       if (*curr != NULL)
10858 +               (*curr)->prev = role;
10859 +
10860 +       role->next = *curr;
10861 +       *curr = role;
10862 +
10863 +       return;
10864 +}
10865 +
10866 +static void
10867 +insert_acl_role_label(struct acl_role_label *role)
10868 +{
10869 +       int i;
10870 +
10871 +       if (role->roletype & GR_ROLE_DOMAIN) {
10872 +               for (i = 0; i < role->domain_child_num; i++)
10873 +                       __insert_acl_role_label(role, role->domain_children[i]);
10874 +       } else
10875 +               __insert_acl_role_label(role, role->uidgid);
10876 +}
10877 +                                       
10878 +static int
10879 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
10880 +{
10881 +       struct name_entry **curr, *nentry;
10882 +       struct inodev_entry *ientry;
10883 +       unsigned int len = strlen(name);
10884 +       unsigned int key = full_name_hash(name, len);
10885 +       unsigned int index = key % name_set.n_size;
10886 +
10887 +       curr = &name_set.n_hash[index];
10888 +
10889 +       while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
10890 +               curr = &((*curr)->next);
10891 +
10892 +       if (*curr != NULL)
10893 +               return 1;
10894 +
10895 +       nentry = acl_alloc(sizeof (struct name_entry));
10896 +       if (nentry == NULL)
10897 +               return 0;
10898 +       ientry = acl_alloc(sizeof (struct inodev_entry));
10899 +       if (ientry == NULL)
10900 +               return 0;
10901 +       ientry->nentry = nentry;
10902 +
10903 +       nentry->key = key;
10904 +       nentry->name = name;
10905 +       nentry->inode = inode;
10906 +       nentry->device = device;
10907 +       nentry->len = len;
10908 +
10909 +       nentry->prev = NULL;
10910 +       curr = &name_set.n_hash[index];
10911 +       if (*curr != NULL)
10912 +               (*curr)->prev = nentry;
10913 +       nentry->next = *curr;
10914 +       *curr = nentry;
10915 +
10916 +       /* insert us into the table searchable by inode/dev */
10917 +       insert_inodev_entry(ientry);
10918 +
10919 +       return 1;
10920 +}
10921 +
10922 +static void
10923 +insert_acl_obj_label(struct acl_object_label *obj,
10924 +                    struct acl_subject_label *subj)
10925 +{
10926 +       unsigned int index =
10927 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
10928 +       struct acl_object_label **curr;
10929 +
10930 +       
10931 +       obj->prev = NULL;
10932 +
10933 +       curr = &subj->obj_hash[index];
10934 +       if (*curr != NULL)
10935 +               (*curr)->prev = obj;
10936 +
10937 +       obj->next = *curr;
10938 +       *curr = obj;
10939 +
10940 +       return;
10941 +}
10942 +
10943 +static void
10944 +insert_acl_subj_label(struct acl_subject_label *obj,
10945 +                     struct acl_role_label *role)
10946 +{
10947 +       unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
10948 +       struct acl_subject_label **curr;
10949 +
10950 +       obj->prev = NULL;
10951 +
10952 +       curr = &role->subj_hash[index];
10953 +       if (*curr != NULL)
10954 +               (*curr)->prev = obj;
10955 +
10956 +       obj->next = *curr;
10957 +       *curr = obj;
10958 +
10959 +       return;
10960 +}
10961 +
10962 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
10963 +
10964 +static void *
10965 +create_table(__u32 * len, int elementsize)
10966 +{
10967 +       unsigned int table_sizes[] = {
10968 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
10969 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
10970 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
10971 +               268435399, 536870909, 1073741789, 2147483647
10972 +       };
10973 +       void *newtable = NULL;
10974 +       unsigned int pwr = 0;
10975 +
10976 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
10977 +              table_sizes[pwr] <= *len)
10978 +               pwr++;
10979 +
10980 +       if (table_sizes[pwr] <= *len)
10981 +               return newtable;
10982 +
10983 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
10984 +               newtable =
10985 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
10986 +       else
10987 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
10988 +
10989 +       *len = table_sizes[pwr];
10990 +
10991 +       return newtable;
10992 +}
10993 +
10994 +static int
10995 +init_variables(const struct gr_arg *arg)
10996 +{
10997 +       unsigned int stacksize;
10998 +
10999 +       subj_map_set.s_size = arg->role_db.num_subjects;
11000 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
11001 +       name_set.n_size = arg->role_db.num_objects;
11002 +       inodev_set.i_size = arg->role_db.num_objects;
11003 +
11004 +       if (!subj_map_set.s_size || !acl_role_set.r_size ||
11005 +           !name_set.n_size || !inodev_set.i_size)
11006 +               return 1;
11007 +
11008 +       if (!gr_init_uidset())
11009 +               return 1;
11010 +
11011 +       /* set up the stack that holds allocation info */
11012 +
11013 +       stacksize = arg->role_db.num_pointers + 5;
11014 +
11015 +       if (!acl_alloc_stack_init(stacksize))
11016 +               return 1;
11017 +
11018 +       /* grab reference for the real root dentry and vfsmount */
11019 +       read_lock(&child_reaper->fs->lock);
11020 +       real_root_mnt = mntget(child_reaper->fs->rootmnt);
11021 +       real_root = dget(child_reaper->fs->root);
11022 +       read_unlock(&child_reaper->fs->lock);
11023 +       
11024 +       fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
11025 +       if (fakefs_obj == NULL)
11026 +               return 1;
11027 +       fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
11028 +
11029 +       subj_map_set.s_hash =
11030 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
11031 +       acl_role_set.r_hash =
11032 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
11033 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
11034 +       inodev_set.i_hash =
11035 +           (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
11036 +
11037 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
11038 +           !name_set.n_hash || !inodev_set.i_hash)
11039 +               return 1;
11040 +
11041 +       memset(subj_map_set.s_hash, 0,
11042 +              sizeof(struct subject_map *) * subj_map_set.s_size);
11043 +       memset(acl_role_set.r_hash, 0,
11044 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
11045 +       memset(name_set.n_hash, 0,
11046 +              sizeof (struct name_entry *) * name_set.n_size);
11047 +       memset(inodev_set.i_hash, 0,
11048 +              sizeof (struct inodev_entry *) * inodev_set.i_size);
11049 +
11050 +       return 0;
11051 +}
11052 +
11053 +/* free information not needed after startup
11054 +   currently contains user->kernel pointer mappings for subjects
11055 +*/
11056 +
11057 +static void
11058 +free_init_variables(void)
11059 +{
11060 +       __u32 i;
11061 +
11062 +       if (subj_map_set.s_hash) {
11063 +               for (i = 0; i < subj_map_set.s_size; i++) {
11064 +                       if (subj_map_set.s_hash[i]) {
11065 +                               kfree(subj_map_set.s_hash[i]);
11066 +                               subj_map_set.s_hash[i] = NULL;
11067 +                       }
11068 +               }
11069 +
11070 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
11071 +                   PAGE_SIZE)
11072 +                       kfree(subj_map_set.s_hash);
11073 +               else
11074 +                       vfree(subj_map_set.s_hash);
11075 +       }
11076 +
11077 +       return;
11078 +}
11079 +
11080 +static void
11081 +free_variables(void)
11082 +{
11083 +       struct acl_subject_label *s;
11084 +       struct acl_role_label *r;
11085 +       struct task_struct *task, *task2;
11086 +       unsigned int i, x;
11087 +
11088 +       gr_clear_learn_entries();
11089 +
11090 +       read_lock(&tasklist_lock);
11091 +       do_each_thread(task2, task) {
11092 +               task->acl_sp_role = 0;
11093 +               task->acl_role_id = 0;
11094 +               task->acl = NULL;
11095 +               task->role = NULL;
11096 +       } while_each_thread(task2, task);
11097 +       read_unlock(&tasklist_lock);
11098 +
11099 +       /* release the reference to the real root dentry and vfsmount */
11100 +       if (real_root)
11101 +               dput(real_root);
11102 +       real_root = NULL;
11103 +       if (real_root_mnt)
11104 +               mntput(real_root_mnt);
11105 +       real_root_mnt = NULL;
11106 +
11107 +       /* free all object hash tables */
11108 +
11109 +       FOR_EACH_ROLE_START(r, i)
11110 +               if (r->subj_hash == NULL)
11111 +                       break;
11112 +               FOR_EACH_SUBJECT_START(r, s, x)
11113 +                       if (s->obj_hash == NULL)
11114 +                               break;
11115 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
11116 +                               kfree(s->obj_hash);
11117 +                       else
11118 +                               vfree(s->obj_hash);
11119 +               FOR_EACH_SUBJECT_END(s, x)
11120 +               FOR_EACH_NESTED_SUBJECT_START(r, s)
11121 +                       if (s->obj_hash == NULL)
11122 +                               break;
11123 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
11124 +                               kfree(s->obj_hash);
11125 +                       else
11126 +                               vfree(s->obj_hash);
11127 +               FOR_EACH_NESTED_SUBJECT_END(s)
11128 +               if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
11129 +                       kfree(r->subj_hash);
11130 +               else
11131 +                       vfree(r->subj_hash);
11132 +               r->subj_hash = NULL;
11133 +       FOR_EACH_ROLE_END(r,i)
11134 +
11135 +       acl_free_all();
11136 +
11137 +       if (acl_role_set.r_hash) {
11138 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
11139 +                   PAGE_SIZE)
11140 +                       kfree(acl_role_set.r_hash);
11141 +               else
11142 +                       vfree(acl_role_set.r_hash);
11143 +       }
11144 +       if (name_set.n_hash) {
11145 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
11146 +                   PAGE_SIZE)
11147 +                       kfree(name_set.n_hash);
11148 +               else
11149 +                       vfree(name_set.n_hash);
11150 +       }
11151 +
11152 +       if (inodev_set.i_hash) {
11153 +               if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
11154 +                   PAGE_SIZE)
11155 +                       kfree(inodev_set.i_hash);
11156 +               else
11157 +                       vfree(inodev_set.i_hash);
11158 +       }
11159 +
11160 +       gr_free_uidset();
11161 +
11162 +       memset(&name_set, 0, sizeof (struct name_db));
11163 +       memset(&inodev_set, 0, sizeof (struct inodev_db));
11164 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
11165 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
11166 +
11167 +       default_role = NULL;
11168 +
11169 +       return;
11170 +}
11171 +
11172 +static __u32
11173 +count_user_objs(struct acl_object_label *userp)
11174 +{
11175 +       struct acl_object_label o_tmp;
11176 +       __u32 num = 0;
11177 +
11178 +       while (userp) {
11179 +               if (copy_from_user(&o_tmp, userp,
11180 +                                  sizeof (struct acl_object_label)))
11181 +                       break;
11182 +
11183 +               userp = o_tmp.prev;
11184 +               num++;
11185 +       }
11186 +
11187 +       return num;
11188 +}
11189 +
11190 +static struct acl_subject_label *
11191 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
11192 +
11193 +static int
11194 +copy_user_glob(struct acl_object_label *obj)
11195 +{
11196 +       struct acl_object_label *g_tmp, **guser;
11197 +       unsigned int len;
11198 +       char *tmp;
11199 +
11200 +       if (obj->globbed == NULL)
11201 +               return 0;
11202 +
11203 +       guser = &obj->globbed;
11204 +       while (*guser) {
11205 +               g_tmp = (struct acl_object_label *)
11206 +                       acl_alloc(sizeof (struct acl_object_label));
11207 +               if (g_tmp == NULL)
11208 +                       return -ENOMEM;
11209 +
11210 +               if (copy_from_user(g_tmp, *guser,
11211 +                                  sizeof (struct acl_object_label)))
11212 +                       return -EFAULT;
11213 +
11214 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
11215 +
11216 +               if (!len || len >= PATH_MAX)
11217 +                       return -EINVAL;
11218 +
11219 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
11220 +                       return -ENOMEM;
11221 +
11222 +               if (copy_from_user(tmp, g_tmp->filename, len))
11223 +                       return -EFAULT;
11224 +
11225 +               g_tmp->filename = tmp;
11226 +
11227 +               *guser = g_tmp;
11228 +               guser = &(g_tmp->next);
11229 +       }
11230 +
11231 +       return 0;
11232 +}
11233 +
11234 +static int
11235 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
11236 +              struct acl_role_label *role)
11237 +{
11238 +       struct acl_object_label *o_tmp;
11239 +       unsigned int len;
11240 +       int ret;
11241 +       char *tmp;
11242 +
11243 +       while (userp) {
11244 +               if ((o_tmp = (struct acl_object_label *)
11245 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
11246 +                       return -ENOMEM;
11247 +
11248 +               if (copy_from_user(o_tmp, userp,
11249 +                                  sizeof (struct acl_object_label)))
11250 +                       return -EFAULT;
11251 +
11252 +               userp = o_tmp->prev;
11253 +
11254 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
11255 +
11256 +               if (!len || len >= PATH_MAX)
11257 +                       return -EINVAL;
11258 +
11259 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
11260 +                       return -ENOMEM;
11261 +
11262 +               if (copy_from_user(tmp, o_tmp->filename, len))
11263 +                       return -EFAULT;
11264 +
11265 +               o_tmp->filename = tmp;
11266 +
11267 +               insert_acl_obj_label(o_tmp, subj);
11268 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
11269 +                                      o_tmp->device))
11270 +                       return -ENOMEM;
11271 +
11272 +               ret = copy_user_glob(o_tmp);
11273 +               if (ret)
11274 +                       return ret;
11275 +
11276 +               if (o_tmp->nested) {
11277 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
11278 +                       if (IS_ERR(o_tmp->nested))
11279 +                               return PTR_ERR(o_tmp->nested);
11280 +
11281 +                       /* insert into nested subject list */
11282 +                       o_tmp->nested->next = role->hash->first;
11283 +                       role->hash->first = o_tmp->nested;
11284 +               }
11285 +       }
11286 +
11287 +       return 0;
11288 +}
11289 +
11290 +static __u32
11291 +count_user_subjs(struct acl_subject_label *userp)
11292 +{
11293 +       struct acl_subject_label s_tmp;
11294 +       __u32 num = 0;
11295 +
11296 +       while (userp) {
11297 +               if (copy_from_user(&s_tmp, userp,
11298 +                                  sizeof (struct acl_subject_label)))
11299 +                       break;
11300 +
11301 +               userp = s_tmp.prev;
11302 +               /* do not count nested subjects against this count, since
11303 +                  they are not included in the hash table, but are
11304 +                  attached to objects.  We have already counted
11305 +                  the subjects in userspace for the allocation 
11306 +                  stack
11307 +               */
11308 +               if (!(s_tmp.mode & GR_NESTED))
11309 +                       num++;
11310 +       }
11311 +
11312 +       return num;
11313 +}
11314 +
11315 +static int
11316 +copy_user_allowedips(struct acl_role_label *rolep)
11317 +{
11318 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
11319 +
11320 +       ruserip = rolep->allowed_ips;
11321 +
11322 +       while (ruserip) {
11323 +               rlast = rtmp;
11324 +
11325 +               if ((rtmp = (struct role_allowed_ip *)
11326 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
11327 +                       return -ENOMEM;
11328 +
11329 +               if (copy_from_user(rtmp, ruserip,
11330 +                                  sizeof (struct role_allowed_ip)))
11331 +                       return -EFAULT;
11332 +
11333 +               ruserip = rtmp->prev;
11334 +
11335 +               if (!rlast) {
11336 +                       rtmp->prev = NULL;
11337 +                       rolep->allowed_ips = rtmp;
11338 +               } else {
11339 +                       rlast->next = rtmp;
11340 +                       rtmp->prev = rlast;
11341 +               }
11342 +
11343 +               if (!ruserip)
11344 +                       rtmp->next = NULL;
11345 +       }
11346 +
11347 +       return 0;
11348 +}
11349 +
11350 +static int
11351 +copy_user_transitions(struct acl_role_label *rolep)
11352 +{
11353 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
11354 +       
11355 +       unsigned int len;
11356 +       char *tmp;
11357 +
11358 +       rusertp = rolep->transitions;
11359 +
11360 +       while (rusertp) {
11361 +               rlast = rtmp;
11362 +
11363 +               if ((rtmp = (struct role_transition *)
11364 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
11365 +                       return -ENOMEM;
11366 +
11367 +               if (copy_from_user(rtmp, rusertp,
11368 +                                  sizeof (struct role_transition)))
11369 +                       return -EFAULT;
11370 +
11371 +               rusertp = rtmp->prev;
11372 +
11373 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
11374 +
11375 +               if (!len || len >= GR_SPROLE_LEN)
11376 +                       return -EINVAL;
11377 +
11378 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
11379 +                       return -ENOMEM;
11380 +
11381 +               if (copy_from_user(tmp, rtmp->rolename, len))
11382 +                       return -EFAULT;
11383 +
11384 +               rtmp->rolename = tmp;
11385 +
11386 +               if (!rlast) {
11387 +                       rtmp->prev = NULL;
11388 +                       rolep->transitions = rtmp;
11389 +               } else {
11390 +                       rlast->next = rtmp;
11391 +                       rtmp->prev = rlast;
11392 +               }
11393 +
11394 +               if (!rusertp)
11395 +                       rtmp->next = NULL;
11396 +       }
11397 +
11398 +       return 0;
11399 +}
11400 +
11401 +static struct acl_subject_label *
11402 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
11403 +{
11404 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
11405 +       unsigned int len;
11406 +       char *tmp;
11407 +       __u32 num_objs;
11408 +       struct acl_ip_label **i_tmp, *i_utmp2;
11409 +       struct gr_hash_struct ghash;
11410 +       struct subject_map *subjmap;
11411 +       unsigned int i_num;
11412 +       int err;
11413 +
11414 +       s_tmp = lookup_subject_map(userp);
11415 +
11416 +       /* we've already copied this subject into the kernel, just return
11417 +          the reference to it, and don't copy it over again
11418 +       */
11419 +       if (s_tmp)
11420 +               return(s_tmp);
11421 +
11422 +       if ((s_tmp = (struct acl_subject_label *)
11423 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
11424 +               return ERR_PTR(-ENOMEM);
11425 +
11426 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
11427 +       if (subjmap == NULL)
11428 +               return ERR_PTR(-ENOMEM);
11429 +
11430 +       subjmap->user = userp;
11431 +       subjmap->kernel = s_tmp;
11432 +       insert_subj_map_entry(subjmap);
11433 +
11434 +       if (copy_from_user(s_tmp, userp,
11435 +                          sizeof (struct acl_subject_label)))
11436 +               return ERR_PTR(-EFAULT);
11437 +
11438 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
11439 +
11440 +       if (!len || len >= PATH_MAX)
11441 +               return ERR_PTR(-EINVAL);
11442 +
11443 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
11444 +               return ERR_PTR(-ENOMEM);
11445 +
11446 +       if (copy_from_user(tmp, s_tmp->filename, len))
11447 +               return ERR_PTR(-EFAULT);
11448 +
11449 +       s_tmp->filename = tmp;
11450 +
11451 +       if (!strcmp(s_tmp->filename, "/"))
11452 +               role->root_label = s_tmp;
11453 +
11454 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
11455 +               return ERR_PTR(-EFAULT);
11456 +
11457 +       /* copy user and group transition tables */
11458 +
11459 +       if (s_tmp->user_trans_num) {
11460 +               uid_t *uidlist;
11461 +
11462 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
11463 +               if (uidlist == NULL)
11464 +                       return ERR_PTR(-ENOMEM);
11465 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
11466 +                       return ERR_PTR(-EFAULT);
11467 +
11468 +               s_tmp->user_transitions = uidlist;
11469 +       }
11470 +
11471 +       if (s_tmp->group_trans_num) {
11472 +               gid_t *gidlist;
11473 +
11474 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
11475 +               if (gidlist == NULL)
11476 +                       return ERR_PTR(-ENOMEM);
11477 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
11478 +                       return ERR_PTR(-EFAULT);
11479 +
11480 +               s_tmp->group_transitions = gidlist;
11481 +       }
11482 +
11483 +       /* set up object hash table */
11484 +       num_objs = count_user_objs(ghash.first);
11485 +
11486 +       s_tmp->obj_hash_size = num_objs;
11487 +       s_tmp->obj_hash =
11488 +           (struct acl_object_label **)
11489 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
11490 +
11491 +       if (!s_tmp->obj_hash)
11492 +               return ERR_PTR(-ENOMEM);
11493 +
11494 +       memset(s_tmp->obj_hash, 0,
11495 +              s_tmp->obj_hash_size *
11496 +              sizeof (struct acl_object_label *));
11497 +
11498 +       /* add in objects */
11499 +       err = copy_user_objs(ghash.first, s_tmp, role);
11500 +
11501 +       if (err)
11502 +               return ERR_PTR(err);
11503 +
11504 +       /* set pointer for parent subject */
11505 +       if (s_tmp->parent_subject) {
11506 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
11507 +
11508 +               if (IS_ERR(s_tmp2))
11509 +                       return s_tmp2;
11510 +
11511 +               s_tmp->parent_subject = s_tmp2;
11512 +       }
11513 +
11514 +       /* add in ip acls */
11515 +
11516 +       if (!s_tmp->ip_num) {
11517 +               s_tmp->ips = NULL;
11518 +               goto insert;
11519 +       }
11520 +
11521 +       i_tmp =
11522 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
11523 +                                              sizeof (struct
11524 +                                                      acl_ip_label *));
11525 +
11526 +       if (!i_tmp)
11527 +               return ERR_PTR(-ENOMEM);
11528 +
11529 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
11530 +               *(i_tmp + i_num) =
11531 +                   (struct acl_ip_label *)
11532 +                   acl_alloc(sizeof (struct acl_ip_label));
11533 +               if (!*(i_tmp + i_num))
11534 +                       return ERR_PTR(-ENOMEM);
11535 +
11536 +               if (copy_from_user
11537 +                   (&i_utmp2, s_tmp->ips + i_num,
11538 +                    sizeof (struct acl_ip_label *)))
11539 +                       return ERR_PTR(-EFAULT);
11540 +
11541 +               if (copy_from_user
11542 +                   (*(i_tmp + i_num), i_utmp2,
11543 +                    sizeof (struct acl_ip_label)))
11544 +                       return ERR_PTR(-EFAULT);
11545 +               
11546 +               if ((*(i_tmp + i_num))->iface == NULL)
11547 +                       continue;
11548 +
11549 +               len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
11550 +               if (!len || len >= IFNAMSIZ)
11551 +                       return ERR_PTR(-EINVAL);
11552 +               tmp = acl_alloc(len);
11553 +               if (tmp == NULL)
11554 +                       return ERR_PTR(-ENOMEM);
11555 +               if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
11556 +                       return ERR_PTR(-EFAULT);
11557 +               (*(i_tmp + i_num))->iface = tmp;
11558 +       }
11559 +
11560 +       s_tmp->ips = i_tmp;
11561 +
11562 +insert:
11563 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
11564 +                              s_tmp->device))
11565 +               return ERR_PTR(-ENOMEM);
11566 +
11567 +       return s_tmp;
11568 +}
11569 +
11570 +static int
11571 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
11572 +{
11573 +       struct acl_subject_label s_pre;
11574 +       struct acl_subject_label * ret;
11575 +       int err;
11576 +
11577 +       while (userp) {
11578 +               if (copy_from_user(&s_pre, userp,
11579 +                                  sizeof (struct acl_subject_label)))
11580 +                       return -EFAULT;
11581 +               
11582 +               /* do not add nested subjects here, add
11583 +                  while parsing objects
11584 +               */
11585 +
11586 +               if (s_pre.mode & GR_NESTED) {
11587 +                       userp = s_pre.prev;
11588 +                       continue;
11589 +               }
11590 +
11591 +               ret = do_copy_user_subj(userp, role);
11592 +
11593 +               err = PTR_ERR(ret);
11594 +               if (IS_ERR(ret))
11595 +                       return err;
11596 +
11597 +               insert_acl_subj_label(ret, role);
11598 +
11599 +               userp = s_pre.prev;
11600 +       }
11601 +
11602 +       return 0;
11603 +}
11604 +
11605 +static int
11606 +copy_user_acl(struct gr_arg *arg)
11607 +{
11608 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
11609 +       struct sprole_pw *sptmp;
11610 +       struct gr_hash_struct *ghash;
11611 +       uid_t *domainlist;
11612 +       unsigned int r_num;
11613 +       unsigned int len;
11614 +       char *tmp;
11615 +       int err = 0;
11616 +       __u16 i;
11617 +       __u32 num_subjs;
11618 +
11619 +       /* we need a default and kernel role */
11620 +       if (arg->role_db.num_roles < 2)
11621 +               return -EINVAL;
11622 +
11623 +       /* copy special role authentication info from userspace */
11624 +
11625 +       num_sprole_pws = arg->num_sprole_pws;
11626 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
11627 +
11628 +       if (!acl_special_roles) {
11629 +               err = -ENOMEM;
11630 +               goto cleanup;
11631 +       }
11632 +
11633 +       for (i = 0; i < num_sprole_pws; i++) {
11634 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
11635 +               if (!sptmp) {
11636 +                       err = -ENOMEM;
11637 +                       goto cleanup;
11638 +               }
11639 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
11640 +                                  sizeof (struct sprole_pw))) {
11641 +                       err = -EFAULT;
11642 +                       goto cleanup;
11643 +               }
11644 +
11645 +               len =
11646 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
11647 +
11648 +               if (!len || len >= GR_SPROLE_LEN) {
11649 +                       err = -EINVAL;
11650 +                       goto cleanup;
11651 +               }
11652 +
11653 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
11654 +                       err = -ENOMEM;
11655 +                       goto cleanup;
11656 +               }
11657 +
11658 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
11659 +                       err = -EFAULT;
11660 +                       goto cleanup;
11661 +               }
11662 +
11663 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11664 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
11665 +#endif
11666 +               sptmp->rolename = tmp;
11667 +               acl_special_roles[i] = sptmp;
11668 +       }
11669 +
11670 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
11671 +
11672 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
11673 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
11674 +
11675 +               if (!r_tmp) {
11676 +                       err = -ENOMEM;
11677 +                       goto cleanup;
11678 +               }
11679 +
11680 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
11681 +                                  sizeof (struct acl_role_label *))) {
11682 +                       err = -EFAULT;
11683 +                       goto cleanup;
11684 +               }
11685 +
11686 +               if (copy_from_user(r_tmp, r_utmp2,
11687 +                                  sizeof (struct acl_role_label))) {
11688 +                       err = -EFAULT;
11689 +                       goto cleanup;
11690 +               }
11691 +
11692 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
11693 +
11694 +               if (!len || len >= PATH_MAX) {
11695 +                       err = -EINVAL;
11696 +                       goto cleanup;
11697 +               }
11698 +
11699 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
11700 +                       err = -ENOMEM;
11701 +                       goto cleanup;
11702 +               }
11703 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
11704 +                       err = -EFAULT;
11705 +                       goto cleanup;
11706 +               }
11707 +               r_tmp->rolename = tmp;
11708 +
11709 +               if (!strcmp(r_tmp->rolename, "default")
11710 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
11711 +                       default_role = r_tmp;
11712 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
11713 +                       kernel_role = r_tmp;
11714 +               }
11715 +
11716 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
11717 +                       err = -ENOMEM;
11718 +                       goto cleanup;
11719 +               }
11720 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
11721 +                       err = -EFAULT;
11722 +                       goto cleanup;
11723 +               }
11724 +
11725 +               r_tmp->hash = ghash;
11726 +
11727 +               num_subjs = count_user_subjs(r_tmp->hash->first);
11728 +
11729 +               r_tmp->subj_hash_size = num_subjs;
11730 +               r_tmp->subj_hash =
11731 +                   (struct acl_subject_label **)
11732 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
11733 +
11734 +               if (!r_tmp->subj_hash) {
11735 +                       err = -ENOMEM;
11736 +                       goto cleanup;
11737 +               }
11738 +
11739 +               err = copy_user_allowedips(r_tmp);
11740 +               if (err)
11741 +                       goto cleanup;
11742 +
11743 +               /* copy domain info */
11744 +               if (r_tmp->domain_children != NULL) {
11745 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
11746 +                       if (domainlist == NULL) {
11747 +                               err = -ENOMEM;
11748 +                               goto cleanup;
11749 +                       }
11750 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
11751 +                               err = -EFAULT;
11752 +                               goto cleanup;
11753 +                       }
11754 +                       r_tmp->domain_children = domainlist;
11755 +               }
11756 +
11757 +               err = copy_user_transitions(r_tmp);
11758 +               if (err)
11759 +                       goto cleanup;
11760 +
11761 +               memset(r_tmp->subj_hash, 0,
11762 +                      r_tmp->subj_hash_size *
11763 +                      sizeof (struct acl_subject_label *));
11764 +
11765 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
11766 +
11767 +               if (err)
11768 +                       goto cleanup;
11769 +
11770 +               /* set nested subject list to null */
11771 +               r_tmp->hash->first = NULL;
11772 +
11773 +               insert_acl_role_label(r_tmp);
11774 +       }
11775 +
11776 +       goto return_err;
11777 +      cleanup:
11778 +       free_variables();
11779 +      return_err:
11780 +       return err;
11781 +
11782 +}
11783 +
11784 +static int
11785 +gracl_init(struct gr_arg *args)
11786 +{
11787 +       int error = 0;
11788 +
11789 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
11790 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
11791 +
11792 +       if (init_variables(args)) {
11793 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
11794 +               error = -ENOMEM;
11795 +               free_variables();
11796 +               goto out;
11797 +       }
11798 +
11799 +       error = copy_user_acl(args);
11800 +       free_init_variables();
11801 +       if (error) {
11802 +               free_variables();
11803 +               goto out;
11804 +       }
11805 +
11806 +       if ((error = gr_set_acls(0))) {
11807 +               free_variables();
11808 +               goto out;
11809 +       }
11810 +
11811 +       gr_status |= GR_READY;
11812 +      out:
11813 +       return error;
11814 +}
11815 +
11816 +/* derived from glibc fnmatch() 0: match, 1: no match*/
11817 +
11818 +static int
11819 +glob_match(const char *p, const char *n)
11820 +{
11821 +       char c;
11822 +
11823 +       while ((c = *p++) != '\0') {
11824 +       switch (c) {
11825 +               case '?':
11826 +                       if (*n == '\0')
11827 +                               return 1;
11828 +                       else if (*n == '/')
11829 +                               return 1;
11830 +                       break;
11831 +               case '\\':
11832 +                       if (*n != c)
11833 +                               return 1;
11834 +                       break;
11835 +               case '*':
11836 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
11837 +                               if (*n == '/')
11838 +                                       return 1;
11839 +                               else if (c == '?') {
11840 +                                       if (*n == '\0')
11841 +                                               return 1;
11842 +                                       else
11843 +                                               ++n;
11844 +                               }
11845 +                       }
11846 +                       if (c == '\0') {
11847 +                               return 0;
11848 +                       } else {
11849 +                               const char *endp;
11850 +
11851 +                               if ((endp = strchr(n, '/')) == NULL)
11852 +                                       endp = n + strlen(n);
11853 +
11854 +                               if (c == '[') {
11855 +                                       for (--p; n < endp; ++n)
11856 +                                               if (!glob_match(p, n))
11857 +                                                       return 0;
11858 +                               } else if (c == '/') {
11859 +                                       while (*n != '\0' && *n != '/')
11860 +                                               ++n;
11861 +                                       if (*n == '/' && !glob_match(p, n + 1))
11862 +                                               return 0;
11863 +                               } else {
11864 +                                       for (--p; n < endp; ++n)
11865 +                                               if (*n == c && !glob_match(p, n))
11866 +                                                       return 0;
11867 +                               }
11868 +
11869 +                               return 1;
11870 +                       }
11871 +               case '[':
11872 +                       {
11873 +                       int not;
11874 +                       char cold;
11875 +
11876 +                       if (*n == '\0' || *n == '/')
11877 +                               return 1;
11878 +
11879 +                       not = (*p == '!' || *p == '^');
11880 +                       if (not)
11881 +                               ++p;
11882 +
11883 +                       c = *p++;
11884 +                       for (;;) {
11885 +                               unsigned char fn = (unsigned char)*n;
11886 +
11887 +                               if (c == '\0')
11888 +                                       return 1;
11889 +                               else {
11890 +                                       if (c == fn)
11891 +                                               goto matched;
11892 +                                       cold = c;
11893 +                                       c = *p++;
11894 +
11895 +                                       if (c == '-' && *p != ']') {
11896 +                                               unsigned char cend = *p++;
11897 +
11898 +                                               if (cend == '\0')
11899 +                                                       return 1;
11900 +
11901 +                                               if (cold <= fn && fn <= cend)
11902 +                                                       goto matched;
11903 +
11904 +                                               c = *p++;
11905 +                                       }
11906 +                               }
11907 +
11908 +                               if (c == ']')
11909 +                                       break;
11910 +                       }
11911 +                       if (!not)
11912 +                               return 1;
11913 +                       break;
11914 +               matched:
11915 +                       while (c != ']') {
11916 +                               if (c == '\0')
11917 +                                       return 1;
11918 +
11919 +                               c = *p++;
11920 +                       }
11921 +                       if (not)
11922 +                               return 1;
11923 +               }
11924 +               break;
11925 +       default:
11926 +               if (c != *n)
11927 +                       return 1;
11928 +       }
11929 +
11930 +       ++n;
11931 +       }
11932 +
11933 +       if (*n == '\0')
11934 +               return 0;
11935 +
11936 +       if (*n == '/')
11937 +               return 0;
11938 +
11939 +       return 1;
11940 +}
11941 +
11942 +static struct acl_object_label *
11943 +chk_glob_label(struct acl_object_label *globbed,
11944 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
11945 +{
11946 +       struct acl_object_label *tmp;
11947 +
11948 +       if (*path == NULL)
11949 +               *path = gr_to_filename_nolock(dentry, mnt);
11950 +
11951 +       tmp = globbed;
11952 +
11953 +       while (tmp) {
11954 +               if (!glob_match(tmp->filename, *path))
11955 +                       return tmp;
11956 +               tmp = tmp->next;
11957 +       }
11958 +
11959 +       return NULL;
11960 +}
11961 +
11962 +static struct acl_object_label *
11963 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
11964 +           const ino_t curr_ino, const dev_t curr_dev,
11965 +           const struct acl_subject_label *subj, char **path)
11966 +{
11967 +       struct acl_subject_label *tmpsubj;
11968 +       struct acl_object_label *retval;
11969 +       struct acl_object_label *retval2;
11970 +
11971 +       tmpsubj = (struct acl_subject_label *) subj;
11972 +       read_lock(&gr_inode_lock);
11973 +       do {
11974 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
11975 +               if (retval) {
11976 +                       if (retval->globbed) {
11977 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
11978 +                                               (struct vfsmount *)orig_mnt, path);
11979 +                               if (retval2)
11980 +                                       retval = retval2;
11981 +                       }
11982 +                       break;
11983 +               }
11984 +       } while ((tmpsubj = tmpsubj->parent_subject));
11985 +       read_unlock(&gr_inode_lock);
11986 +
11987 +       return retval;
11988 +}
11989 +
11990 +static __inline__ struct acl_object_label *
11991 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
11992 +           const struct dentry *curr_dentry,
11993 +           const struct acl_subject_label *subj, char **path)
11994 +{
11995 +       return __full_lookup(orig_dentry, orig_mnt,
11996 +                            curr_dentry->d_inode->i_ino, 
11997 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
11998 +}
11999 +
12000 +static struct acl_object_label *
12001 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12002 +             const struct acl_subject_label *subj, char *path)
12003 +{
12004 +       struct dentry *dentry = (struct dentry *) l_dentry;
12005 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
12006 +       struct acl_object_label *retval;
12007 +
12008 +       spin_lock(&dcache_lock);
12009 +
12010 +       if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt)) {
12011 +               retval = fakefs_obj;
12012 +               goto out;
12013 +       }
12014 +
12015 +       for (;;) {
12016 +               if (dentry == real_root && mnt == real_root_mnt)
12017 +                       break;
12018 +
12019 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
12020 +                       if (mnt->mnt_parent == mnt)
12021 +                               break;
12022 +
12023 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12024 +                       if (retval != NULL)
12025 +                               goto out;
12026 +
12027 +                       dentry = mnt->mnt_mountpoint;
12028 +                       mnt = mnt->mnt_parent;
12029 +                       continue;
12030 +               }
12031 +
12032 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12033 +               if (retval != NULL)
12034 +                       goto out;
12035 +
12036 +               dentry = dentry->d_parent;
12037 +       }
12038 +
12039 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12040 +
12041 +       if (retval == NULL)
12042 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
12043 +out:
12044 +       spin_unlock(&dcache_lock);
12045 +       return retval;
12046 +}
12047 +
12048 +static __inline__ struct acl_object_label *
12049 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12050 +             const struct acl_subject_label *subj)
12051 +{
12052 +       char *path = NULL;
12053 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
12054 +}
12055 +
12056 +static __inline__ struct acl_object_label *
12057 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12058 +                    const struct acl_subject_label *subj, char *path)
12059 +{
12060 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
12061 +}
12062 +
12063 +static struct acl_subject_label *
12064 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12065 +              const struct acl_role_label *role)
12066 +{
12067 +       struct dentry *dentry = (struct dentry *) l_dentry;
12068 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
12069 +       struct acl_subject_label *retval;
12070 +
12071 +       spin_lock(&dcache_lock);
12072 +
12073 +       for (;;) {
12074 +               if (dentry == real_root && mnt == real_root_mnt)
12075 +                       break;
12076 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
12077 +                       if (mnt->mnt_parent == mnt)
12078 +                               break;
12079 +
12080 +                       read_lock(&gr_inode_lock);
12081 +                       retval =
12082 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
12083 +                                               dentry->d_inode->i_sb->s_dev, role);
12084 +                       read_unlock(&gr_inode_lock);
12085 +                       if (retval != NULL)
12086 +                               goto out;
12087 +
12088 +                       dentry = mnt->mnt_mountpoint;
12089 +                       mnt = mnt->mnt_parent;
12090 +                       continue;
12091 +               }
12092 +
12093 +               read_lock(&gr_inode_lock);
12094 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
12095 +                                         dentry->d_inode->i_sb->s_dev, role);
12096 +               read_unlock(&gr_inode_lock);
12097 +               if (retval != NULL)
12098 +                       goto out;
12099 +
12100 +               dentry = dentry->d_parent;
12101 +       }
12102 +
12103 +       read_lock(&gr_inode_lock);
12104 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
12105 +                                 dentry->d_inode->i_sb->s_dev, role);
12106 +       read_unlock(&gr_inode_lock);
12107 +
12108 +       if (unlikely(retval == NULL)) {
12109 +               read_lock(&gr_inode_lock);
12110 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
12111 +                                         real_root->d_inode->i_sb->s_dev, role);
12112 +               read_unlock(&gr_inode_lock);
12113 +       }
12114 +out:
12115 +       spin_unlock(&dcache_lock);
12116 +
12117 +       return retval;
12118 +}
12119 +
12120 +static void
12121 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
12122 +{
12123 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
12124 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
12125 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
12126 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
12127 +
12128 +       return;
12129 +}
12130 +
12131 +static void
12132 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
12133 +                      const unsigned int effective, const unsigned int fs)
12134 +{
12135 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
12136 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
12137 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
12138 +                      type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
12139 +
12140 +       return;
12141 +}
12142 +
12143 +__u32
12144 +gr_check_link(const struct dentry * new_dentry,
12145 +             const struct dentry * parent_dentry,
12146 +             const struct vfsmount * parent_mnt,
12147 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
12148 +{
12149 +       struct acl_object_label *obj;
12150 +       __u32 oldmode, newmode;
12151 +       __u32 needmode;
12152 +
12153 +       if (unlikely(!(gr_status & GR_READY)))
12154 +               return (GR_CREATE | GR_LINK);
12155 +
12156 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
12157 +       oldmode = obj->mode;
12158 +
12159 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
12160 +               oldmode |= (GR_CREATE | GR_LINK);
12161 +
12162 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
12163 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
12164 +               needmode |= GR_SETID | GR_AUDIT_SETID;
12165 +
12166 +       newmode =
12167 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
12168 +                           oldmode | needmode);
12169 +
12170 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
12171 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
12172 +                             GR_INHERIT | GR_AUDIT_INHERIT);
12173 +
12174 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
12175 +               goto bad;
12176 +
12177 +       if ((oldmode & needmode) != needmode)
12178 +               goto bad;
12179 +
12180 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
12181 +       if ((newmode & needmode) != needmode)
12182 +               goto bad;
12183 +
12184 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
12185 +               return newmode;
12186 +bad:
12187 +       needmode = oldmode;
12188 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
12189 +               needmode |= GR_SETID;
12190 +       
12191 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
12192 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
12193 +               return (GR_CREATE | GR_LINK);
12194 +       } else if (newmode & GR_SUPPRESS)
12195 +               return GR_SUPPRESS;
12196 +       else
12197 +               return 0;
12198 +}
12199 +
12200 +__u32
12201 +gr_search_file(const struct dentry * dentry, const __u32 mode,
12202 +              const struct vfsmount * mnt)
12203 +{
12204 +       __u32 retval = mode;
12205 +       struct acl_subject_label *curracl;
12206 +       struct acl_object_label *currobj;
12207 +
12208 +       if (unlikely(!(gr_status & GR_READY)))
12209 +               return (mode & ~GR_AUDITS);
12210 +
12211 +       curracl = current->acl;
12212 +
12213 +       currobj = chk_obj_label(dentry, mnt, curracl);
12214 +       retval = currobj->mode & mode;
12215 +
12216 +       if (unlikely
12217 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
12218 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
12219 +               __u32 new_mode = mode;
12220 +
12221 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12222 +
12223 +               retval = new_mode;
12224 +
12225 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
12226 +                       new_mode |= GR_INHERIT;
12227 +
12228 +               if (!(mode & GR_NOLEARN))
12229 +                       gr_log_learn(current, dentry, mnt, new_mode);
12230 +       }
12231 +
12232 +       return retval;
12233 +}
12234 +
12235 +__u32
12236 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
12237 +               const struct vfsmount * mnt, const __u32 mode)
12238 +{
12239 +       struct name_entry *match;
12240 +       struct acl_object_label *matchpo;
12241 +       struct acl_subject_label *curracl;
12242 +       char *path;
12243 +       __u32 retval;
12244 +
12245 +       if (unlikely(!(gr_status & GR_READY)))
12246 +               return (mode & ~GR_AUDITS);
12247 +
12248 +       preempt_disable();
12249 +       path = gr_to_filename_rbac(new_dentry, mnt);
12250 +       match = lookup_name_entry(path);
12251 +
12252 +       if (!match)
12253 +               goto check_parent;
12254 +
12255 +       curracl = current->acl;
12256 +
12257 +       read_lock(&gr_inode_lock);
12258 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
12259 +       read_unlock(&gr_inode_lock);
12260 +
12261 +       if (matchpo) {
12262 +               if ((matchpo->mode & mode) !=
12263 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
12264 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
12265 +                       __u32 new_mode = mode;
12266 +
12267 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12268 +
12269 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
12270 +
12271 +                       preempt_enable();
12272 +                       return new_mode;
12273 +               }
12274 +               preempt_enable();
12275 +               return (matchpo->mode & mode);
12276 +       }
12277 +
12278 +      check_parent:
12279 +       curracl = current->acl;
12280 +
12281 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
12282 +       retval = matchpo->mode & mode;
12283 +
12284 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
12285 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
12286 +               __u32 new_mode = mode;
12287 +
12288 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12289 +
12290 +               gr_log_learn(current, new_dentry, mnt, new_mode);
12291 +               preempt_enable();
12292 +               return new_mode;
12293 +       }
12294 +
12295 +       preempt_enable();
12296 +       return retval;
12297 +}
12298 +
12299 +int
12300 +gr_check_hidden_task(const struct task_struct *task)
12301 +{
12302 +       if (unlikely(!(gr_status & GR_READY)))
12303 +               return 0;
12304 +
12305 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
12306 +               return 1;
12307 +
12308 +       return 0;
12309 +}
12310 +
12311 +int
12312 +gr_check_protected_task(const struct task_struct *task)
12313 +{
12314 +       if (unlikely(!(gr_status & GR_READY) || !task))
12315 +               return 0;
12316 +
12317 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
12318 +           task->acl != current->acl)
12319 +               return 1;
12320 +
12321 +       return 0;
12322 +}
12323 +
12324 +void
12325 +gr_copy_label(struct task_struct *tsk)
12326 +{
12327 +       tsk->signal->used_accept = 0;
12328 +       tsk->acl_sp_role = 0;
12329 +       tsk->acl_role_id = current->acl_role_id;
12330 +       tsk->acl = current->acl;
12331 +       tsk->role = current->role;
12332 +       tsk->signal->curr_ip = current->signal->curr_ip;
12333 +       if (current->exec_file)
12334 +               get_file(current->exec_file);
12335 +       tsk->exec_file = current->exec_file;
12336 +       tsk->is_writable = current->is_writable;
12337 +       if (unlikely(current->signal->used_accept))
12338 +               current->signal->curr_ip = 0;
12339 +
12340 +       return;
12341 +}
12342 +
12343 +static void
12344 +gr_set_proc_res(struct task_struct *task)
12345 +{
12346 +       struct acl_subject_label *proc;
12347 +       unsigned short i;
12348 +
12349 +       proc = task->acl;
12350 +
12351 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
12352 +               return;
12353 +
12354 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
12355 +               if (!(proc->resmask & (1 << i)))
12356 +                       continue;
12357 +
12358 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
12359 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
12360 +       }
12361 +
12362 +       return;
12363 +}
12364 +
12365 +int
12366 +gr_check_user_change(int real, int effective, int fs)
12367 +{
12368 +       unsigned int i;
12369 +       __u16 num;
12370 +       uid_t *uidlist;
12371 +       int curuid;
12372 +       int realok = 0;
12373 +       int effectiveok = 0;
12374 +       int fsok = 0;
12375 +
12376 +       if (unlikely(!(gr_status & GR_READY)))
12377 +               return 0;
12378 +
12379 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
12380 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
12381 +
12382 +       num = current->acl->user_trans_num;
12383 +       uidlist = current->acl->user_transitions;
12384 +
12385 +       if (uidlist == NULL)
12386 +               return 0;
12387 +
12388 +       if (real == -1)
12389 +               realok = 1;
12390 +       if (effective == -1)
12391 +               effectiveok = 1;
12392 +       if (fs == -1)
12393 +               fsok = 1;
12394 +
12395 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
12396 +               for (i = 0; i < num; i++) {
12397 +                       curuid = (int)uidlist[i];
12398 +                       if (real == curuid)
12399 +                               realok = 1;
12400 +                       if (effective == curuid)
12401 +                               effectiveok = 1;
12402 +                       if (fs == curuid)
12403 +                               fsok = 1;
12404 +               }
12405 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
12406 +               for (i = 0; i < num; i++) {
12407 +                       curuid = (int)uidlist[i];
12408 +                       if (real == curuid)
12409 +                               break;
12410 +                       if (effective == curuid)
12411 +                               break;
12412 +                       if (fs == curuid)
12413 +                               break;
12414 +               }
12415 +               /* not in deny list */
12416 +               if (i == num) {
12417 +                       realok = 1;
12418 +                       effectiveok = 1;
12419 +                       fsok = 1;
12420 +               }
12421 +       }
12422 +
12423 +       if (realok && effectiveok && fsok)
12424 +               return 0;
12425 +       else {
12426 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
12427 +               return 1;
12428 +       }
12429 +}
12430 +
12431 +int
12432 +gr_check_group_change(int real, int effective, int fs)
12433 +{
12434 +       unsigned int i;
12435 +       __u16 num;
12436 +       gid_t *gidlist;
12437 +       int curgid;
12438 +       int realok = 0;
12439 +       int effectiveok = 0;
12440 +       int fsok = 0;
12441 +
12442 +       if (unlikely(!(gr_status & GR_READY)))
12443 +               return 0;
12444 +
12445 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
12446 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
12447 +
12448 +       num = current->acl->group_trans_num;
12449 +       gidlist = current->acl->group_transitions;
12450 +
12451 +       if (gidlist == NULL)
12452 +               return 0;
12453 +
12454 +       if (real == -1)
12455 +               realok = 1;
12456 +       if (effective == -1)
12457 +               effectiveok = 1;
12458 +       if (fs == -1)
12459 +               fsok = 1;
12460 +
12461 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
12462 +               for (i = 0; i < num; i++) {
12463 +                       curgid = (int)gidlist[i];
12464 +                       if (real == curgid)
12465 +                               realok = 1;
12466 +                       if (effective == curgid)
12467 +                               effectiveok = 1;
12468 +                       if (fs == curgid)
12469 +                               fsok = 1;
12470 +               }
12471 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
12472 +               for (i = 0; i < num; i++) {
12473 +                       curgid = (int)gidlist[i];
12474 +                       if (real == curgid)
12475 +                               break;
12476 +                       if (effective == curgid)
12477 +                               break;
12478 +                       if (fs == curgid)
12479 +                               break;
12480 +               }
12481 +               /* not in deny list */
12482 +               if (i == num) {
12483 +                       realok = 1;
12484 +                       effectiveok = 1;
12485 +                       fsok = 1;
12486 +               }
12487 +       }
12488 +
12489 +       if (realok && effectiveok && fsok)
12490 +               return 0;
12491 +       else {
12492 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
12493 +               return 1;
12494 +       }
12495 +}
12496 +
12497 +void
12498 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
12499 +{
12500 +       struct acl_role_label *role = task->role;
12501 +       struct acl_subject_label *subj = NULL;
12502 +       struct acl_object_label *obj;
12503 +       struct file *filp;
12504 +
12505 +       if (unlikely(!(gr_status & GR_READY)))
12506 +               return;
12507 +
12508 +       filp = task->exec_file;
12509 +
12510 +       /* kernel process, we'll give them the kernel role */
12511 +       if (unlikely(!filp)) {
12512 +               task->role = kernel_role;
12513 +               task->acl = kernel_role->root_label;
12514 +               return;
12515 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
12516 +               role = lookup_acl_role_label(task, uid, gid);
12517 +
12518 +       /* perform subject lookup in possibly new role
12519 +          we can use this result below in the case where role == task->role
12520 +       */
12521 +       subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
12522 +
12523 +       /* if we changed uid/gid, but result in the same role
12524 +          and are using inheritance, don't lose the inherited subject
12525 +          if current subject is other than what normal lookup
12526 +          would result in, we arrived via inheritance, don't
12527 +          lose subject
12528 +       */
12529 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
12530 +                                  (subj == task->acl)))
12531 +               task->acl = subj;
12532 +
12533 +       task->role = role;
12534 +
12535 +       task->is_writable = 0;
12536 +
12537 +       /* ignore additional mmap checks for processes that are writable 
12538 +          by the default ACL */
12539 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
12540 +       if (unlikely(obj->mode & GR_WRITE))
12541 +               task->is_writable = 1;
12542 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
12543 +       if (unlikely(obj->mode & GR_WRITE))
12544 +               task->is_writable = 1;
12545 +
12546 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
12547 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
12548 +#endif
12549 +
12550 +       gr_set_proc_res(task);
12551 +
12552 +       return;
12553 +}
12554 +
12555 +int
12556 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
12557 +{
12558 +       struct task_struct *task = current;
12559 +       struct acl_subject_label *newacl;
12560 +       struct acl_object_label *obj;
12561 +       __u32 retmode;
12562 +
12563 +       if (unlikely(!(gr_status & GR_READY)))
12564 +               return 0;
12565 +
12566 +       newacl = chk_subj_label(dentry, mnt, task->role);
12567 +
12568 +       task_lock(task);
12569 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
12570 +            GR_POVERRIDE) && (task->acl != newacl) &&
12571 +            !(task->role->roletype & GR_ROLE_GOD) &&
12572 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
12573 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
12574 +           (atomic_read(&task->fs->count) > 1 ||
12575 +            atomic_read(&task->files->count) > 1 ||
12576 +            atomic_read(&task->sighand->count) > 1)) {
12577 +                task_unlock(task);
12578 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
12579 +               return -EACCES;
12580 +       }
12581 +       task_unlock(task);
12582 +
12583 +       obj = chk_obj_label(dentry, mnt, task->acl);
12584 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
12585 +
12586 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
12587 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
12588 +               if (obj->nested)
12589 +                       task->acl = obj->nested;
12590 +               else
12591 +                       task->acl = newacl;
12592 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
12593 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
12594 +
12595 +       task->is_writable = 0;
12596 +
12597 +       /* ignore additional mmap checks for processes that are writable 
12598 +          by the default ACL */
12599 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
12600 +       if (unlikely(obj->mode & GR_WRITE))
12601 +               task->is_writable = 1;
12602 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
12603 +       if (unlikely(obj->mode & GR_WRITE))
12604 +               task->is_writable = 1;
12605 +
12606 +       gr_set_proc_res(task);
12607 +
12608 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
12609 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
12610 +#endif
12611 +       return 0;
12612 +}
12613 +
12614 +static void
12615 +do_handle_delete(const ino_t ino, const dev_t dev)
12616 +{
12617 +       struct acl_object_label *matchpo;
12618 +       struct acl_subject_label *matchps;
12619 +       struct acl_subject_label *subj;
12620 +       struct acl_role_label *role;
12621 +       unsigned int i, x;
12622 +
12623 +       FOR_EACH_ROLE_START(role, i)
12624 +               FOR_EACH_SUBJECT_START(role, subj, x)
12625 +                       if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
12626 +                               matchpo->mode |= GR_DELETED;
12627 +               FOR_EACH_SUBJECT_END(subj,x)
12628 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
12629 +                       if (subj->inode == ino && subj->device == dev)
12630 +                               subj->mode |= GR_DELETED;
12631 +               FOR_EACH_NESTED_SUBJECT_END(subj)
12632 +               if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
12633 +                       matchps->mode |= GR_DELETED;
12634 +       FOR_EACH_ROLE_END(role,i)
12635 +
12636 +       return;
12637 +}
12638 +
12639 +void
12640 +gr_handle_delete(const ino_t ino, const dev_t dev)
12641 +{
12642 +       if (unlikely(!(gr_status & GR_READY)))
12643 +               return;
12644 +
12645 +       write_lock(&gr_inode_lock);
12646 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
12647 +               do_handle_delete(ino, dev);
12648 +       write_unlock(&gr_inode_lock);
12649 +
12650 +       return;
12651 +}
12652 +
12653 +static void
12654 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
12655 +                    const ino_t newinode, const dev_t newdevice,
12656 +                    struct acl_subject_label *subj)
12657 +{
12658 +       unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
12659 +       struct acl_object_label *match;
12660 +
12661 +       match = subj->obj_hash[index];
12662 +
12663 +       while (match && (match->inode != oldinode ||
12664 +              match->device != olddevice ||
12665 +              !(match->mode & GR_DELETED)))
12666 +               match = match->next;
12667 +
12668 +       if (match && (match->inode == oldinode)
12669 +           && (match->device == olddevice)
12670 +           && (match->mode & GR_DELETED)) {
12671 +               if (match->prev == NULL) {
12672 +                       subj->obj_hash[index] = match->next;
12673 +                       if (match->next != NULL)
12674 +                               match->next->prev = NULL;
12675 +               } else {
12676 +                       match->prev->next = match->next;
12677 +                       if (match->next != NULL)
12678 +                               match->next->prev = match->prev;
12679 +               }
12680 +               match->prev = NULL;
12681 +               match->next = NULL;
12682 +               match->inode = newinode;
12683 +               match->device = newdevice;
12684 +               match->mode &= ~GR_DELETED;
12685 +
12686 +               insert_acl_obj_label(match, subj);
12687 +       }
12688 +
12689 +       return;
12690 +}
12691 +
12692 +static void
12693 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
12694 +                     const ino_t newinode, const dev_t newdevice,
12695 +                     struct acl_role_label *role)
12696 +{
12697 +       unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
12698 +       struct acl_subject_label *match;
12699 +
12700 +       match = role->subj_hash[index];
12701 +
12702 +       while (match && (match->inode != oldinode ||
12703 +              match->device != olddevice ||
12704 +              !(match->mode & GR_DELETED)))
12705 +               match = match->next;
12706 +
12707 +       if (match && (match->inode == oldinode)
12708 +           && (match->device == olddevice)
12709 +           && (match->mode & GR_DELETED)) {
12710 +               if (match->prev == NULL) {
12711 +                       role->subj_hash[index] = match->next;
12712 +                       if (match->next != NULL)
12713 +                               match->next->prev = NULL;
12714 +               } else {
12715 +                       match->prev->next = match->next;
12716 +                       if (match->next != NULL)
12717 +                               match->next->prev = match->prev;
12718 +               }
12719 +               match->prev = NULL;
12720 +               match->next = NULL;
12721 +               match->inode = newinode;
12722 +               match->device = newdevice;
12723 +               match->mode &= ~GR_DELETED;
12724 +
12725 +               insert_acl_subj_label(match, role);
12726 +       }
12727 +
12728 +       return;
12729 +}
12730 +
12731 +static void
12732 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
12733 +                   const ino_t newinode, const dev_t newdevice)
12734 +{
12735 +       unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
12736 +       struct inodev_entry *match;
12737 +
12738 +       match = inodev_set.i_hash[index];
12739 +
12740 +       while (match && (match->nentry->inode != oldinode ||
12741 +              match->nentry->device != olddevice))
12742 +               match = match->next;
12743 +
12744 +       if (match && (match->nentry->inode == oldinode)
12745 +           && (match->nentry->device == olddevice)) {
12746 +               if (match->prev == NULL) {
12747 +                       inodev_set.i_hash[index] = match->next;
12748 +                       if (match->next != NULL)
12749 +                               match->next->prev = NULL;
12750 +               } else {
12751 +                       match->prev->next = match->next;
12752 +                       if (match->next != NULL)
12753 +                               match->next->prev = match->prev;
12754 +               }
12755 +               match->prev = NULL;
12756 +               match->next = NULL;
12757 +               match->nentry->inode = newinode;
12758 +               match->nentry->device = newdevice;
12759 +
12760 +               insert_inodev_entry(match);
12761 +       }
12762 +
12763 +       return;
12764 +}
12765 +
12766 +static void
12767 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
12768 +                const struct vfsmount *mnt)
12769 +{
12770 +       struct acl_subject_label *subj;
12771 +       struct acl_role_label *role;
12772 +       unsigned int i, x;
12773 +
12774 +       FOR_EACH_ROLE_START(role, i)
12775 +               update_acl_subj_label(matchn->inode, matchn->device,
12776 +                                     dentry->d_inode->i_ino,
12777 +                                     dentry->d_inode->i_sb->s_dev, role);
12778 +
12779 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
12780 +                       if ((subj->inode == dentry->d_inode->i_ino) &&
12781 +                           (subj->device == dentry->d_inode->i_sb->s_dev)) {
12782 +                               subj->inode = dentry->d_inode->i_ino;
12783 +                               subj->device = dentry->d_inode->i_sb->s_dev;
12784 +                       }
12785 +               FOR_EACH_NESTED_SUBJECT_END(subj)
12786 +               FOR_EACH_SUBJECT_START(role, subj, x)
12787 +                       update_acl_obj_label(matchn->inode, matchn->device,
12788 +                                            dentry->d_inode->i_ino,
12789 +                                            dentry->d_inode->i_sb->s_dev, subj);
12790 +               FOR_EACH_SUBJECT_END(subj,x)
12791 +       FOR_EACH_ROLE_END(role,i)
12792 +
12793 +       update_inodev_entry(matchn->inode, matchn->device,
12794 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
12795 +
12796 +       return;
12797 +}
12798 +
12799 +void
12800 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
12801 +{
12802 +       struct name_entry *matchn;
12803 +
12804 +       if (unlikely(!(gr_status & GR_READY)))
12805 +               return;
12806 +
12807 +       preempt_disable();
12808 +       matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
12809 +
12810 +       if (unlikely((unsigned long)matchn)) {
12811 +               write_lock(&gr_inode_lock);
12812 +               do_handle_create(matchn, dentry, mnt);
12813 +               write_unlock(&gr_inode_lock);
12814 +       }
12815 +       preempt_enable();
12816 +
12817 +       return;
12818 +}
12819 +
12820 +void
12821 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
12822 +                struct dentry *old_dentry,
12823 +                struct dentry *new_dentry,
12824 +                struct vfsmount *mnt, const __u8 replace)
12825 +{
12826 +       struct name_entry *matchn;
12827 +
12828 +       if (unlikely(!(gr_status & GR_READY)))
12829 +               return;
12830 +
12831 +       preempt_disable();
12832 +       matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
12833 +
12834 +       /* we wouldn't have to check d_inode if it weren't for
12835 +          NFS silly-renaming
12836 +        */
12837 +
12838 +       write_lock(&gr_inode_lock);
12839 +       if (unlikely(replace && new_dentry->d_inode)) {
12840 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
12841 +                                       new_dentry->d_inode->i_sb->s_dev) &&
12842 +                   (old_dentry->d_inode->i_nlink <= 1)))
12843 +                       do_handle_delete(new_dentry->d_inode->i_ino,
12844 +                                        new_dentry->d_inode->i_sb->s_dev);
12845 +       }
12846 +
12847 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
12848 +                               old_dentry->d_inode->i_sb->s_dev) &&
12849 +           (old_dentry->d_inode->i_nlink <= 1)))
12850 +               do_handle_delete(old_dentry->d_inode->i_ino,
12851 +                                old_dentry->d_inode->i_sb->s_dev);
12852 +
12853 +       if (unlikely((unsigned long)matchn))
12854 +               do_handle_create(matchn, old_dentry, mnt);
12855 +
12856 +       write_unlock(&gr_inode_lock);
12857 +       preempt_enable();
12858 +
12859 +       return;
12860 +}
12861 +
12862 +static int
12863 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
12864 +                        unsigned char **sum)
12865 +{
12866 +       struct acl_role_label *r;
12867 +       struct role_allowed_ip *ipp;
12868 +       struct role_transition *trans;
12869 +       unsigned int i;
12870 +       int found = 0;
12871 +
12872 +       /* check transition table */
12873 +
12874 +       for (trans = current->role->transitions; trans; trans = trans->next) {
12875 +               if (!strcmp(rolename, trans->rolename)) {
12876 +                       found = 1;
12877 +                       break;
12878 +               }
12879 +       }
12880 +
12881 +       if (!found)
12882 +               return 0;
12883 +
12884 +       /* handle special roles that do not require authentication
12885 +          and check ip */
12886 +
12887 +       FOR_EACH_ROLE_START(r, i)
12888 +               if (!strcmp(rolename, r->rolename) &&
12889 +                   (r->roletype & GR_ROLE_SPECIAL)) {
12890 +                       found = 0;
12891 +                       if (r->allowed_ips != NULL) {
12892 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
12893 +                                       if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
12894 +                                            (ntohl(ipp->addr) & ipp->netmask))
12895 +                                               found = 1;
12896 +                               }
12897 +                       } else
12898 +                               found = 2;
12899 +                       if (!found)
12900 +                               return 0;
12901 +
12902 +                       if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
12903 +                           ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
12904 +                               *salt = NULL;
12905 +                               *sum = NULL;
12906 +                               return 1;
12907 +                       }
12908 +               }
12909 +       FOR_EACH_ROLE_END(r,i)
12910 +
12911 +       for (i = 0; i < num_sprole_pws; i++) {
12912 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
12913 +                       *salt = acl_special_roles[i]->salt;
12914 +                       *sum = acl_special_roles[i]->sum;
12915 +                       return 1;
12916 +               }
12917 +       }
12918 +
12919 +       return 0;
12920 +}
12921 +
12922 +static void
12923 +assign_special_role(char *rolename)
12924 +{
12925 +       struct acl_object_label *obj;
12926 +       struct acl_role_label *r;
12927 +       struct acl_role_label *assigned = NULL;
12928 +       struct task_struct *tsk;
12929 +       struct file *filp;
12930 +       unsigned int i;
12931 +
12932 +       FOR_EACH_ROLE_START(r, i)
12933 +               if (!strcmp(rolename, r->rolename) &&
12934 +                   (r->roletype & GR_ROLE_SPECIAL))
12935 +                       assigned = r;
12936 +       FOR_EACH_ROLE_END(r,i)
12937 +
12938 +       if (!assigned)
12939 +               return;
12940 +
12941 +       read_lock(&tasklist_lock);
12942 +       read_lock(&grsec_exec_file_lock);
12943 +
12944 +       tsk = current->parent;
12945 +       if (tsk == NULL)
12946 +               goto out_unlock;
12947 +
12948 +       filp = tsk->exec_file;
12949 +       if (filp == NULL)
12950 +               goto out_unlock;
12951 +
12952 +       tsk->is_writable = 0;
12953 +
12954 +       tsk->acl_sp_role = 1;
12955 +       tsk->acl_role_id = ++acl_sp_role_value;
12956 +       tsk->role = assigned;
12957 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
12958 +
12959 +       /* ignore additional mmap checks for processes that are writable 
12960 +          by the default ACL */
12961 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
12962 +       if (unlikely(obj->mode & GR_WRITE))
12963 +               tsk->is_writable = 1;
12964 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
12965 +       if (unlikely(obj->mode & GR_WRITE))
12966 +               tsk->is_writable = 1;
12967 +
12968 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
12969 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
12970 +#endif
12971 +
12972 +out_unlock:
12973 +       read_unlock(&grsec_exec_file_lock);
12974 +       read_unlock(&tasklist_lock);
12975 +       return;
12976 +}
12977 +
12978 +int gr_check_secure_terminal(struct task_struct *task)
12979 +{
12980 +       struct task_struct *p, *p2, *p3;
12981 +       struct files_struct *files;
12982 +       struct fdtable *fdt;
12983 +       struct file *our_file = NULL, *file;
12984 +       int i;
12985 +
12986 +       if (task->signal->tty == NULL)
12987 +               return 1;
12988 +
12989 +       files = get_files_struct(task);
12990 +       if (files != NULL) {
12991 +               rcu_read_lock();
12992 +               fdt = files_fdtable(files);
12993 +               for (i=0; i < fdt->max_fds; i++) {
12994 +                       file = fcheck_files(files, i);
12995 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
12996 +                               get_file(file);
12997 +                               our_file = file;
12998 +                       }
12999 +               }
13000 +               rcu_read_unlock();
13001 +               put_files_struct(files);
13002 +       }
13003 +
13004 +       if (our_file == NULL)
13005 +               return 1;
13006 +
13007 +       read_lock(&tasklist_lock);
13008 +       do_each_thread(p2, p) {
13009 +               files = get_files_struct(p);
13010 +               if (files == NULL ||
13011 +                   (p->signal && p->signal->tty == task->signal->tty)) {
13012 +                       if (files != NULL)
13013 +                               put_files_struct(files);
13014 +                       continue;
13015 +               }
13016 +               rcu_read_lock();
13017 +               fdt = files_fdtable(files);
13018 +               for (i=0; i < fdt->max_fds; i++) {
13019 +                       file = fcheck_files(files, i);
13020 +                       if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
13021 +                           file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
13022 +                               p3 = task;
13023 +                               while (p3->pid > 0) {
13024 +                                       if (p3 == p)
13025 +                                               break;
13026 +                                       p3 = p3->parent;
13027 +                               }
13028 +                               if (p3 == p)
13029 +                                       break;
13030 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
13031 +                               gr_handle_alertkill(p);
13032 +                               rcu_read_unlock();
13033 +                               put_files_struct(files);
13034 +                               read_unlock(&tasklist_lock);
13035 +                               fput(our_file);
13036 +                               return 0;
13037 +                       }
13038 +               }
13039 +               rcu_read_unlock();
13040 +               put_files_struct(files);
13041 +       } while_each_thread(p2, p);
13042 +       read_unlock(&tasklist_lock);
13043 +
13044 +       fput(our_file);
13045 +       return 1;
13046 +}
13047 +
13048 +ssize_t
13049 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
13050 +{
13051 +       struct gr_arg_wrapper uwrap;
13052 +       unsigned char *sprole_salt;
13053 +       unsigned char *sprole_sum;
13054 +       int error = sizeof (struct gr_arg_wrapper);
13055 +       int error2 = 0;
13056 +
13057 +       down(&gr_dev_sem);
13058 +
13059 +       if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
13060 +               error = -EPERM;
13061 +               goto out;
13062 +       }
13063 +
13064 +       if (count != sizeof (struct gr_arg_wrapper)) {
13065 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
13066 +               error = -EINVAL;
13067 +               goto out;
13068 +       }
13069 +
13070 +       
13071 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
13072 +               gr_auth_expires = 0;
13073 +               gr_auth_attempts = 0;
13074 +       }
13075 +
13076 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
13077 +               error = -EFAULT;
13078 +               goto out;
13079 +       }
13080 +
13081 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
13082 +               error = -EINVAL;
13083 +               goto out;
13084 +       }
13085 +
13086 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
13087 +               error = -EFAULT;
13088 +               goto out;
13089 +       }
13090 +
13091 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
13092 +           gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
13093 +           time_after(gr_auth_expires, get_seconds())) {
13094 +               error = -EBUSY;
13095 +               goto out;
13096 +       }
13097 +
13098 +       /* if non-root trying to do anything other than use a special role,
13099 +          do not attempt authentication, do not count towards authentication
13100 +          locking
13101 +        */
13102 +
13103 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
13104 +           gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
13105 +           current->uid) {
13106 +               error = -EPERM;
13107 +               goto out;
13108 +       }
13109 +
13110 +       /* ensure pw and special role name are null terminated */
13111 +
13112 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
13113 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
13114 +
13115 +       /* Okay. 
13116 +        * We have our enough of the argument structure..(we have yet
13117 +        * to copy_from_user the tables themselves) . Copy the tables
13118 +        * only if we need them, i.e. for loading operations. */
13119 +
13120 +       switch (gr_usermode->mode) {
13121 +       case STATUS:
13122 +                       if (gr_status & GR_READY) {
13123 +                               error = 1;
13124 +                               if (!gr_check_secure_terminal(current))
13125 +                                       error = 3;
13126 +                       } else
13127 +                               error = 2;
13128 +                       goto out;
13129 +       case SHUTDOWN:
13130 +               if ((gr_status & GR_READY)
13131 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13132 +                       gr_status &= ~GR_READY;
13133 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
13134 +                       free_variables();
13135 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
13136 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
13137 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
13138 +               } else if (gr_status & GR_READY) {
13139 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
13140 +                       error = -EPERM;
13141 +               } else {
13142 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
13143 +                       error = -EAGAIN;
13144 +               }
13145 +               break;
13146 +       case ENABLE:
13147 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
13148 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
13149 +               else {
13150 +                       if (gr_status & GR_READY)
13151 +                               error = -EAGAIN;
13152 +                       else
13153 +                               error = error2;
13154 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
13155 +               }
13156 +               break;
13157 +       case RELOAD:
13158 +               if (!(gr_status & GR_READY)) {
13159 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
13160 +                       error = -EAGAIN;
13161 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13162 +                       lock_kernel();
13163 +                       gr_status &= ~GR_READY;
13164 +                       free_variables();
13165 +                       if (!(error2 = gracl_init(gr_usermode))) {
13166 +                               unlock_kernel();
13167 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
13168 +                       } else {
13169 +                               unlock_kernel();
13170 +                               error = error2;
13171 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
13172 +                       }
13173 +               } else {
13174 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
13175 +                       error = -EPERM;
13176 +               }
13177 +               break;
13178 +       case SEGVMOD:
13179 +               if (unlikely(!(gr_status & GR_READY))) {
13180 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
13181 +                       error = -EAGAIN;
13182 +                       break;
13183 +               }
13184 +
13185 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13186 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
13187 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
13188 +                               struct acl_subject_label *segvacl;
13189 +                               segvacl =
13190 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
13191 +                                                         gr_usermode->segv_device,
13192 +                                                         current->role);
13193 +                               if (segvacl) {
13194 +                                       segvacl->crashes = 0;
13195 +                                       segvacl->expires = 0;
13196 +                               }
13197 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
13198 +                               gr_remove_uid(gr_usermode->segv_uid);
13199 +                       }
13200 +               } else {
13201 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
13202 +                       error = -EPERM;
13203 +               }
13204 +               break;
13205 +       case SPROLE:
13206 +       case SPROLEPAM:
13207 +               if (unlikely(!(gr_status & GR_READY))) {
13208 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
13209 +                       error = -EAGAIN;
13210 +                       break;
13211 +               }
13212 +
13213 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
13214 +                       current->role->expires = 0;
13215 +                       current->role->auth_attempts = 0;
13216 +               }
13217 +
13218 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
13219 +                   time_after(current->role->expires, get_seconds())) {
13220 +                       error = -EBUSY;
13221 +                       goto out;
13222 +               }
13223 +
13224 +               if (lookup_special_role_auth
13225 +                   (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
13226 +                   && ((!sprole_salt && !sprole_sum)
13227 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
13228 +                       char *p = "";
13229 +                       assign_special_role(gr_usermode->sp_role);
13230 +                       read_lock(&tasklist_lock);
13231 +                       if (current->parent)
13232 +                               p = current->parent->role->rolename;
13233 +                       read_unlock(&tasklist_lock);
13234 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
13235 +                                       p, acl_sp_role_value);
13236 +               } else {
13237 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
13238 +                       error = -EPERM;
13239 +                       if(!(current->role->auth_attempts++))
13240 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
13241 +
13242 +                       goto out;
13243 +               }
13244 +               break;
13245 +       case UNSPROLE:
13246 +               if (unlikely(!(gr_status & GR_READY))) {
13247 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
13248 +                       error = -EAGAIN;
13249 +                       break;
13250 +               }
13251 +
13252 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
13253 +                       char *p = "";
13254 +                       int i = 0;
13255 +
13256 +                       read_lock(&tasklist_lock);
13257 +                       if (current->parent) {
13258 +                               p = current->parent->role->rolename;
13259 +                               i = current->parent->acl_role_id;
13260 +                       }
13261 +                       read_unlock(&tasklist_lock);
13262 +
13263 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
13264 +                       gr_set_acls(1);
13265 +               } else {
13266 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
13267 +                       error = -EPERM;
13268 +                       goto out;
13269 +               }
13270 +               break;
13271 +       default:
13272 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
13273 +               error = -EINVAL;
13274 +               break;
13275 +       }
13276 +
13277 +       if (error != -EPERM)
13278 +               goto out;
13279 +
13280 +       if(!(gr_auth_attempts++))
13281 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
13282 +
13283 +      out:
13284 +       up(&gr_dev_sem);
13285 +       return error;
13286 +}
13287 +
13288 +int
13289 +gr_set_acls(const int type)
13290 +{
13291 +       struct acl_object_label *obj;
13292 +       struct task_struct *task, *task2;
13293 +       struct file *filp;
13294 +       struct acl_role_label *role = current->role;
13295 +       __u16 acl_role_id = current->acl_role_id;
13296 +
13297 +       read_lock(&tasklist_lock);
13298 +       read_lock(&grsec_exec_file_lock);
13299 +       do_each_thread(task2, task) {
13300 +               /* check to see if we're called from the exit handler,
13301 +                  if so, only replace ACLs that have inherited the admin
13302 +                  ACL */
13303 +
13304 +               if (type && (task->role != role ||
13305 +                            task->acl_role_id != acl_role_id))
13306 +                       continue;
13307 +
13308 +               task->acl_role_id = 0;
13309 +               task->acl_sp_role = 0;
13310 +
13311 +               if ((filp = task->exec_file)) {
13312 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
13313 +
13314 +                       task->acl =
13315 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
13316 +                                          task->role);
13317 +                       if (task->acl) {
13318 +                               struct acl_subject_label *curr;
13319 +                               curr = task->acl;
13320 +
13321 +                               task->is_writable = 0;
13322 +                               /* ignore additional mmap checks for processes that are writable 
13323 +                                  by the default ACL */
13324 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13325 +                               if (unlikely(obj->mode & GR_WRITE))
13326 +                                       task->is_writable = 1;
13327 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
13328 +                               if (unlikely(obj->mode & GR_WRITE))
13329 +                                       task->is_writable = 1;
13330 +
13331 +                               gr_set_proc_res(task);
13332 +
13333 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13334 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13335 +#endif
13336 +                       } else {
13337 +                               read_unlock(&grsec_exec_file_lock);
13338 +                               read_unlock(&tasklist_lock);
13339 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
13340 +                               return 1;
13341 +                       }
13342 +               } else {
13343 +                       // it's a kernel process
13344 +                       task->role = kernel_role;
13345 +                       task->acl = kernel_role->root_label;
13346 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
13347 +                       task->acl->mode &= ~GR_PROCFIND;
13348 +#endif
13349 +               }
13350 +       } while_each_thread(task2, task);
13351 +       read_unlock(&grsec_exec_file_lock);
13352 +       read_unlock(&tasklist_lock);
13353 +       return 0;
13354 +}
13355 +
13356 +void
13357 +gr_learn_resource(const struct task_struct *task,
13358 +                 const int res, const unsigned long wanted, const int gt)
13359 +{
13360 +       struct acl_subject_label *acl;
13361 +
13362 +       if (unlikely((gr_status & GR_READY) &&
13363 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
13364 +               goto skip_reslog;
13365 +
13366 +#ifdef CONFIG_GRKERNSEC_RESLOG
13367 +       gr_log_resource(task, res, wanted, gt);
13368 +#endif
13369 +      skip_reslog:
13370 +
13371 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
13372 +               return;
13373 +
13374 +       acl = task->acl;
13375 +
13376 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
13377 +                  !(acl->resmask & (1 << (unsigned short) res))))
13378 +               return;
13379 +
13380 +       if (wanted >= acl->res[res].rlim_cur) {
13381 +               unsigned long res_add;
13382 +
13383 +               res_add = wanted;
13384 +               switch (res) {
13385 +               case RLIMIT_CPU:
13386 +                       res_add += GR_RLIM_CPU_BUMP;
13387 +                       break;
13388 +               case RLIMIT_FSIZE:
13389 +                       res_add += GR_RLIM_FSIZE_BUMP;
13390 +                       break;
13391 +               case RLIMIT_DATA:
13392 +                       res_add += GR_RLIM_DATA_BUMP;
13393 +                       break;
13394 +               case RLIMIT_STACK:
13395 +                       res_add += GR_RLIM_STACK_BUMP;
13396 +                       break;
13397 +               case RLIMIT_CORE:
13398 +                       res_add += GR_RLIM_CORE_BUMP;
13399 +                       break;
13400 +               case RLIMIT_RSS:
13401 +                       res_add += GR_RLIM_RSS_BUMP;
13402 +                       break;
13403 +               case RLIMIT_NPROC:
13404 +                       res_add += GR_RLIM_NPROC_BUMP;
13405 +                       break;
13406 +               case RLIMIT_NOFILE:
13407 +                       res_add += GR_RLIM_NOFILE_BUMP;
13408 +                       break;
13409 +               case RLIMIT_MEMLOCK:
13410 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
13411 +                       break;
13412 +               case RLIMIT_AS:
13413 +                       res_add += GR_RLIM_AS_BUMP;
13414 +                       break;
13415 +               case RLIMIT_LOCKS:
13416 +                       res_add += GR_RLIM_LOCKS_BUMP;
13417 +                       break;
13418 +               }
13419 +
13420 +               acl->res[res].rlim_cur = res_add;
13421 +
13422 +               if (wanted > acl->res[res].rlim_max)
13423 +                       acl->res[res].rlim_max = res_add;
13424 +
13425 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
13426 +                              task->role->roletype, acl->filename,
13427 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
13428 +                              "", (unsigned long) res);
13429 +       }
13430 +
13431 +       return;
13432 +}
13433 +
13434 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
13435 +void
13436 +pax_set_initial_flags(struct linux_binprm *bprm)
13437 +{
13438 +       struct task_struct *task = current;
13439 +        struct acl_subject_label *proc;
13440 +       unsigned long flags;
13441 +
13442 +        if (unlikely(!(gr_status & GR_READY)))
13443 +                return;
13444 +
13445 +       flags = pax_get_flags(task);
13446 +
13447 +        proc = task->acl;
13448 +
13449 +       if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
13450 +               flags &= ~MF_PAX_PAGEEXEC;
13451 +       if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
13452 +               flags &= ~MF_PAX_SEGMEXEC;
13453 +       if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
13454 +               flags &= ~MF_PAX_RANDMMAP;
13455 +       if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
13456 +               flags &= ~MF_PAX_EMUTRAMP;
13457 +       if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
13458 +               flags &= ~MF_PAX_MPROTECT;
13459 +
13460 +       if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
13461 +               flags |= MF_PAX_PAGEEXEC;
13462 +       if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
13463 +               flags |= MF_PAX_SEGMEXEC;
13464 +       if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
13465 +               flags |= MF_PAX_RANDMMAP;
13466 +       if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
13467 +               flags |= MF_PAX_EMUTRAMP;
13468 +       if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
13469 +               flags |= MF_PAX_MPROTECT;
13470 +
13471 +       pax_set_flags(task, flags);
13472 +
13473 +        return;
13474 +}
13475 +#endif
13476 +
13477 +#ifdef CONFIG_SYSCTL
13478 +extern struct proc_dir_entry *proc_sys_root;
13479 +
13480 +/* the following function is called under the BKL */
13481 +
13482 +__u32
13483 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
13484 +                const void *newval)
13485 +{
13486 +       struct proc_dir_entry *tmp;
13487 +       struct nameidata nd;
13488 +       const char *proc_sys = "/proc/sys";
13489 +       char *path;
13490 +       struct acl_object_label *obj;
13491 +       unsigned short len = 0, pos = 0, depth = 0, i;
13492 +       __u32 err = 0;
13493 +       __u32 mode = 0;
13494 +
13495 +       if (unlikely(!(gr_status & GR_READY)))
13496 +               return 1;
13497 +
13498 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
13499 +
13500 +       if (oldval)
13501 +               mode |= GR_READ;
13502 +       if (newval)
13503 +               mode |= GR_WRITE;
13504 +
13505 +       /* convert the requested sysctl entry into a pathname */
13506 +
13507 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
13508 +               len += strlen(tmp->name);
13509 +               len++;
13510 +               depth++;
13511 +       }
13512 +
13513 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
13514 +               return 0;       /* deny */
13515 +
13516 +       memset(path, 0, PAGE_SIZE);
13517 +
13518 +       memcpy(path, proc_sys, strlen(proc_sys));
13519 +
13520 +       pos += strlen(proc_sys);
13521 +
13522 +       for (; depth > 0; depth--) {
13523 +               path[pos] = '/';
13524 +               pos++;
13525 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
13526 +                    tmp = tmp->parent) {
13527 +                       if (depth == i) {
13528 +                               memcpy(path + pos, tmp->name,
13529 +                                      strlen(tmp->name));
13530 +                               pos += strlen(tmp->name);
13531 +                       }
13532 +                       i++;
13533 +               }
13534 +       }
13535 +
13536 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
13537 +
13538 +       if (err)
13539 +               goto out;
13540 +
13541 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
13542 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
13543 +
13544 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
13545 +                    ((err & mode) != mode))) {
13546 +               __u32 new_mode = mode;
13547 +
13548 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
13549 +
13550 +               err = new_mode;
13551 +               gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
13552 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
13553 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
13554 +                              path, (mode & GR_READ) ? " reading" : "",
13555 +                              (mode & GR_WRITE) ? " writing" : "");
13556 +               err = 0;
13557 +       } else if ((err & mode) != mode) {
13558 +               err = 0;
13559 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
13560 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
13561 +                              path, (mode & GR_READ) ? " reading" : "",
13562 +                              (mode & GR_WRITE) ? " writing" : "");
13563 +       }
13564 +
13565 +       path_release(&nd);
13566 +
13567 +      out:
13568 +       return err;
13569 +}
13570 +#endif
13571 +
13572 +int
13573 +gr_handle_proc_ptrace(struct task_struct *task)
13574 +{
13575 +       struct file *filp;
13576 +       struct task_struct *tmp = task;
13577 +       struct task_struct *curtemp = current;
13578 +       __u32 retmode;
13579 +
13580 +       if (unlikely(!(gr_status & GR_READY)))
13581 +               return 0;
13582 +
13583 +       read_lock(&tasklist_lock);
13584 +       read_lock(&grsec_exec_file_lock);
13585 +       filp = task->exec_file;
13586 +
13587 +       while (tmp->pid > 0) {
13588 +               if (tmp == curtemp)
13589 +                       break;
13590 +               tmp = tmp->parent;
13591 +       }
13592 +
13593 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
13594 +               read_unlock(&grsec_exec_file_lock);
13595 +               read_unlock(&tasklist_lock);
13596 +               return 1;
13597 +       }
13598 +
13599 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
13600 +       read_unlock(&grsec_exec_file_lock);
13601 +       read_unlock(&tasklist_lock);
13602 +
13603 +       if (retmode & GR_NOPTRACE)
13604 +               return 1;
13605 +
13606 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
13607 +           && (current->acl != task->acl || (current->acl != current->role->root_label
13608 +           && current->pid != task->pid)))
13609 +               return 1;
13610 +
13611 +       return 0;
13612 +}
13613 +
13614 +int
13615 +gr_handle_ptrace(struct task_struct *task, const long request)
13616 +{
13617 +       struct task_struct *tmp = task;
13618 +       struct task_struct *curtemp = current;
13619 +       __u32 retmode;
13620 +
13621 +       if (unlikely(!(gr_status & GR_READY)))
13622 +               return 0;
13623 +
13624 +       read_lock(&tasklist_lock);
13625 +       while (tmp->pid > 0) {
13626 +               if (tmp == curtemp)
13627 +                       break;
13628 +               tmp = tmp->parent;
13629 +       }
13630 +
13631 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
13632 +               read_unlock(&tasklist_lock);
13633 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
13634 +               return 1;
13635 +       }
13636 +       read_unlock(&tasklist_lock);
13637 +
13638 +       read_lock(&grsec_exec_file_lock);
13639 +       if (unlikely(!task->exec_file)) {
13640 +               read_unlock(&grsec_exec_file_lock);
13641 +               return 0;
13642 +       }
13643 +
13644 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
13645 +       read_unlock(&grsec_exec_file_lock);
13646 +
13647 +       if (retmode & GR_NOPTRACE) {
13648 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
13649 +               return 1;
13650 +       }
13651 +               
13652 +       if (retmode & GR_PTRACERD) {
13653 +               switch (request) {
13654 +               case PTRACE_POKETEXT:
13655 +               case PTRACE_POKEDATA:
13656 +               case PTRACE_POKEUSR:
13657 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
13658 +               case PTRACE_SETREGS:
13659 +               case PTRACE_SETFPREGS:
13660 +#endif
13661 +#ifdef CONFIG_X86
13662 +               case PTRACE_SETFPXREGS:
13663 +#endif
13664 +#ifdef CONFIG_ALTIVEC
13665 +               case PTRACE_SETVRREGS:
13666 +#endif
13667 +                       return 1;
13668 +               default:
13669 +                       return 0;
13670 +               }
13671 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
13672 +                  !(current->role->roletype & GR_ROLE_GOD) &&
13673 +                  (current->acl != task->acl)) {
13674 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
13675 +               return 1;
13676 +       }
13677 +
13678 +       return 0;
13679 +}
13680 +
13681 +static int is_writable_mmap(const struct file *filp)
13682 +{
13683 +       struct task_struct *task = current;
13684 +       struct acl_object_label *obj, *obj2;
13685 +
13686 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
13687 +           !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
13688 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13689 +               obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
13690 +                                    task->role->root_label);
13691 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
13692 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
13693 +                       return 1;
13694 +               }
13695 +       }
13696 +       return 0;
13697 +}
13698 +
13699 +int
13700 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
13701 +{
13702 +       __u32 mode;
13703 +
13704 +       if (unlikely(!file || !(prot & PROT_EXEC)))
13705 +               return 1;
13706 +
13707 +       if (is_writable_mmap(file))
13708 +               return 0;
13709 +
13710 +       mode =
13711 +           gr_search_file(file->f_dentry,
13712 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
13713 +                          file->f_vfsmnt);
13714 +
13715 +       if (!gr_tpe_allow(file))
13716 +               return 0;
13717 +
13718 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
13719 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
13720 +               return 0;
13721 +       } else if (unlikely(!(mode & GR_EXEC))) {
13722 +               return 0;
13723 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
13724 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
13725 +               return 1;
13726 +       }
13727 +
13728 +       return 1;
13729 +}
13730 +
13731 +int
13732 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
13733 +{
13734 +       __u32 mode;
13735 +
13736 +       if (unlikely(!file || !(prot & PROT_EXEC)))
13737 +               return 1;
13738 +
13739 +       if (is_writable_mmap(file))
13740 +               return 0;
13741 +
13742 +       mode =
13743 +           gr_search_file(file->f_dentry,
13744 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
13745 +                          file->f_vfsmnt);
13746 +
13747 +       if (!gr_tpe_allow(file))
13748 +               return 0;
13749 +
13750 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
13751 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
13752 +               return 0;
13753 +       } else if (unlikely(!(mode & GR_EXEC))) {
13754 +               return 0;
13755 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
13756 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
13757 +               return 1;
13758 +       }
13759 +
13760 +       return 1;
13761 +}
13762 +
13763 +void
13764 +gr_acl_handle_psacct(struct task_struct *task, const long code)
13765 +{
13766 +       unsigned long runtime;
13767 +       unsigned long cputime;
13768 +       unsigned int wday, cday;
13769 +       __u8 whr, chr;
13770 +       __u8 wmin, cmin;
13771 +       __u8 wsec, csec;
13772 +
13773 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
13774 +                    !(task->acl->mode & GR_PROCACCT)))
13775 +               return;
13776 +
13777 +       runtime = xtime.tv_sec - task->start_time.tv_sec;
13778 +       wday = runtime / (3600 * 24);
13779 +       runtime -= wday * (3600 * 24);
13780 +       whr = runtime / 3600;
13781 +       runtime -= whr * 3600;
13782 +       wmin = runtime / 60;
13783 +       runtime -= wmin * 60;
13784 +       wsec = runtime;
13785 +
13786 +       cputime = (task->utime + task->stime) / HZ;
13787 +       cday = cputime / (3600 * 24);
13788 +       cputime -= cday * (3600 * 24);
13789 +       chr = cputime / 3600;
13790 +       cputime -= chr * 3600;
13791 +       cmin = cputime / 60;
13792 +       cputime -= cmin * 60;
13793 +       csec = cputime;
13794 +
13795 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
13796 +
13797 +       return;
13798 +}
13799 +
13800 +void gr_set_kernel_label(struct task_struct *task)
13801 +{
13802 +       if (gr_status & GR_READY) {
13803 +               task->role = kernel_role;
13804 +               task->acl = kernel_role->root_label;
13805 +       }
13806 +       return;
13807 +}
13808 +
13809 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
13810 +{
13811 +       struct task_struct *task = current;
13812 +       struct dentry *dentry = file->f_dentry;
13813 +       struct vfsmount *mnt = file->f_vfsmnt;
13814 +       struct acl_object_label *obj, *tmp;
13815 +       struct acl_subject_label *subj;
13816 +       unsigned int bufsize;
13817 +       int is_not_root;
13818 +       char *path;
13819 +
13820 +       if (unlikely(!(gr_status & GR_READY)))
13821 +               return 1;
13822 +
13823 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
13824 +               return 1;
13825 +
13826 +       subj = task->acl;
13827 +       do {
13828 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
13829 +               if (obj != NULL)
13830 +                       return (obj->mode & GR_FIND) ? 1 : 0;
13831 +       } while ((subj = subj->parent_subject));
13832 +       
13833 +       obj = chk_obj_label(dentry, mnt, task->acl);
13834 +       if (obj->globbed == NULL)
13835 +               return (obj->mode & GR_FIND) ? 1 : 0;
13836 +
13837 +       is_not_root = ((obj->filename[0] == '/') &&
13838 +                  (obj->filename[1] == '\0')) ? 0 : 1;
13839 +       bufsize = PAGE_SIZE - namelen - is_not_root;
13840 +
13841 +       /* check bufsize > PAGE_SIZE || bufsize == 0 */
13842 +       if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
13843 +               return 1;
13844 +
13845 +       preempt_disable();
13846 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
13847 +                          bufsize);
13848 +
13849 +       bufsize = strlen(path);
13850 +
13851 +       /* if base is "/", don't append an additional slash */
13852 +       if (is_not_root)
13853 +               *(path + bufsize) = '/';
13854 +       memcpy(path + bufsize + is_not_root, name, namelen);
13855 +       *(path + bufsize + namelen + is_not_root) = '\0';
13856 +
13857 +       tmp = obj->globbed;
13858 +       while (tmp) {
13859 +               if (!glob_match(tmp->filename, path)) {
13860 +                       preempt_enable();
13861 +                       return (tmp->mode & GR_FIND) ? 1 : 0;
13862 +               }
13863 +               tmp = tmp->next;
13864 +       }
13865 +       preempt_enable();
13866 +       return (obj->mode & GR_FIND) ? 1 : 0;
13867 +}
13868 +
13869 +EXPORT_SYMBOL(gr_learn_resource);
13870 +EXPORT_SYMBOL(gr_set_kernel_label);
13871 +#ifdef CONFIG_SECURITY
13872 +EXPORT_SYMBOL(gr_check_user_change);
13873 +EXPORT_SYMBOL(gr_check_group_change);
13874 +#endif
13875 +
13876 diff -urNp linux-2.6.17.11/grsecurity/gracl_cap.c linux-2.6.17.11/grsecurity/gracl_cap.c
13877 --- linux-2.6.17.11/grsecurity/gracl_cap.c      1969-12-31 19:00:00.000000000 -0500
13878 +++ linux-2.6.17.11/grsecurity/gracl_cap.c      2006-09-01 16:20:28.000000000 -0400
13879 @@ -0,0 +1,110 @@
13880 +#include <linux/kernel.h>
13881 +#include <linux/module.h>
13882 +#include <linux/sched.h>
13883 +#include <linux/capability.h>
13884 +#include <linux/gracl.h>
13885 +#include <linux/grsecurity.h>
13886 +#include <linux/grinternal.h>
13887 +
13888 +static const char *captab_log[] = {
13889 +       "CAP_CHOWN",
13890 +       "CAP_DAC_OVERRIDE",
13891 +       "CAP_DAC_READ_SEARCH",
13892 +       "CAP_FOWNER",
13893 +       "CAP_FSETID",
13894 +       "CAP_KILL",
13895 +       "CAP_SETGID",
13896 +       "CAP_SETUID",
13897 +       "CAP_SETPCAP",
13898 +       "CAP_LINUX_IMMUTABLE",
13899 +       "CAP_NET_BIND_SERVICE",
13900 +       "CAP_NET_BROADCAST",
13901 +       "CAP_NET_ADMIN",
13902 +       "CAP_NET_RAW",
13903 +       "CAP_IPC_LOCK",
13904 +       "CAP_IPC_OWNER",
13905 +       "CAP_SYS_MODULE",
13906 +       "CAP_SYS_RAWIO",
13907 +       "CAP_SYS_CHROOT",
13908 +       "CAP_SYS_PTRACE",
13909 +       "CAP_SYS_PACCT",
13910 +       "CAP_SYS_ADMIN",
13911 +       "CAP_SYS_BOOT",
13912 +       "CAP_SYS_NICE",
13913 +       "CAP_SYS_RESOURCE",
13914 +       "CAP_SYS_TIME",
13915 +       "CAP_SYS_TTY_CONFIG",
13916 +       "CAP_MKNOD",
13917 +       "CAP_LEASE"
13918 +};
13919 +
13920 +EXPORT_SYMBOL(gr_task_is_capable);
13921 +
13922 +int
13923 +gr_task_is_capable(struct task_struct *task, const int cap)
13924 +{
13925 +       struct acl_subject_label *curracl;
13926 +       __u32 cap_drop = 0, cap_mask = 0;
13927 +
13928 +       if (!gr_acl_is_enabled())
13929 +               return 1;
13930 +
13931 +       curracl = task->acl;
13932 +
13933 +       cap_drop = curracl->cap_lower;
13934 +       cap_mask = curracl->cap_mask;
13935 +
13936 +       while ((curracl = curracl->parent_subject)) {
13937 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
13938 +                       cap_drop |= curracl->cap_lower & (1 << cap);
13939 +               cap_mask |= curracl->cap_mask;
13940 +       }
13941 +
13942 +       if (!cap_raised(cap_drop, cap))
13943 +               return 1;
13944 +
13945 +       curracl = task->acl;
13946 +
13947 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
13948 +           && cap_raised(task->cap_effective, cap)) {
13949 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
13950 +                              task->role->roletype, task->uid,
13951 +                              task->gid, task->exec_file ?
13952 +                              gr_to_filename(task->exec_file->f_dentry,
13953 +                              task->exec_file->f_vfsmnt) : curracl->filename,
13954 +                              curracl->filename, 0UL,
13955 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
13956 +               return 1;
13957 +       }
13958 +
13959 +       if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
13960 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
13961 +
13962 +       return 0;
13963 +}
13964 +
13965 +int
13966 +gr_is_capable_nolog(const int cap)
13967 +{
13968 +       struct acl_subject_label *curracl;
13969 +       __u32 cap_drop = 0, cap_mask = 0;
13970 +
13971 +       if (!gr_acl_is_enabled())
13972 +               return 1;
13973 +
13974 +       curracl = current->acl;
13975 +
13976 +       cap_drop = curracl->cap_lower;
13977 +       cap_mask = curracl->cap_mask;
13978 +
13979 +       while ((curracl = curracl->parent_subject)) {
13980 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
13981 +               cap_mask |= curracl->cap_mask;
13982 +       }
13983 +
13984 +       if (!cap_raised(cap_drop, cap))
13985 +               return 1;
13986 +
13987 +       return 0;
13988 +}
13989 +
13990 diff -urNp linux-2.6.17.11/grsecurity/gracl_fs.c linux-2.6.17.11/grsecurity/gracl_fs.c
13991 --- linux-2.6.17.11/grsecurity/gracl_fs.c       1969-12-31 19:00:00.000000000 -0500
13992 +++ linux-2.6.17.11/grsecurity/gracl_fs.c       2006-09-01 16:20:28.000000000 -0400
13993 @@ -0,0 +1,423 @@
13994 +#include <linux/kernel.h>
13995 +#include <linux/sched.h>
13996 +#include <linux/types.h>
13997 +#include <linux/fs.h>
13998 +#include <linux/file.h>
13999 +#include <linux/stat.h>
14000 +#include <linux/grsecurity.h>
14001 +#include <linux/grinternal.h>
14002 +#include <linux/gracl.h>
14003 +
14004 +__u32
14005 +gr_acl_handle_hidden_file(const struct dentry * dentry,
14006 +                         const struct vfsmount * mnt)
14007 +{
14008 +       __u32 mode;
14009 +
14010 +       if (unlikely(!dentry->d_inode))
14011 +               return GR_FIND;
14012 +
14013 +       mode =
14014 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
14015 +
14016 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
14017 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
14018 +               return mode;
14019 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
14020 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
14021 +               return 0;
14022 +       } else if (unlikely(!(mode & GR_FIND)))
14023 +               return 0;
14024 +
14025 +       return GR_FIND;
14026 +}
14027 +
14028 +__u32
14029 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
14030 +                  const int fmode)
14031 +{
14032 +       __u32 reqmode = GR_FIND;
14033 +       __u32 mode;
14034 +
14035 +       if (unlikely(!dentry->d_inode))
14036 +               return reqmode;
14037 +
14038 +       if (unlikely(fmode & O_APPEND))
14039 +               reqmode |= GR_APPEND;
14040 +       else if (unlikely(fmode & FMODE_WRITE))
14041 +               reqmode |= GR_WRITE;
14042 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
14043 +               reqmode |= GR_READ;
14044 +
14045 +       mode =
14046 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
14047 +                          mnt);
14048 +
14049 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14050 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
14051 +                              reqmode & GR_READ ? " reading" : "",
14052 +                              reqmode & GR_WRITE ? " writing" : reqmode &
14053 +                              GR_APPEND ? " appending" : "");
14054 +               return reqmode;
14055 +       } else
14056 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14057 +       {
14058 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
14059 +                              reqmode & GR_READ ? " reading" : "",
14060 +                              reqmode & GR_WRITE ? " writing" : reqmode &
14061 +                              GR_APPEND ? " appending" : "");
14062 +               return 0;
14063 +       } else if (unlikely((mode & reqmode) != reqmode))
14064 +               return 0;
14065 +
14066 +       return reqmode;
14067 +}
14068 +
14069 +__u32
14070 +gr_acl_handle_creat(const struct dentry * dentry,
14071 +                   const struct dentry * p_dentry,
14072 +                   const struct vfsmount * p_mnt, const int fmode,
14073 +                   const int imode)
14074 +{
14075 +       __u32 reqmode = GR_WRITE | GR_CREATE;
14076 +       __u32 mode;
14077 +
14078 +       if (unlikely(fmode & O_APPEND))
14079 +               reqmode |= GR_APPEND;
14080 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
14081 +               reqmode |= GR_READ;
14082 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
14083 +               reqmode |= GR_SETID;
14084 +
14085 +       mode =
14086 +           gr_check_create(dentry, p_dentry, p_mnt,
14087 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
14088 +
14089 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14090 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
14091 +                              reqmode & GR_READ ? " reading" : "",
14092 +                              reqmode & GR_WRITE ? " writing" : reqmode &
14093 +                              GR_APPEND ? " appending" : "");
14094 +               return reqmode;
14095 +       } else
14096 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14097 +       {
14098 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
14099 +                              reqmode & GR_READ ? " reading" : "",
14100 +                              reqmode & GR_WRITE ? " writing" : reqmode &
14101 +                              GR_APPEND ? " appending" : "");
14102 +               return 0;
14103 +       } else if (unlikely((mode & reqmode) != reqmode))
14104 +               return 0;
14105 +
14106 +       return reqmode;
14107 +}
14108 +
14109 +__u32
14110 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
14111 +                    const int fmode)
14112 +{
14113 +       __u32 mode, reqmode = GR_FIND;
14114 +
14115 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
14116 +               reqmode |= GR_EXEC;
14117 +       if (fmode & S_IWOTH)
14118 +               reqmode |= GR_WRITE;
14119 +       if (fmode & S_IROTH)
14120 +               reqmode |= GR_READ;
14121 +
14122 +       mode =
14123 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
14124 +                          mnt);
14125 +
14126 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14127 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
14128 +                              reqmode & GR_READ ? " reading" : "",
14129 +                              reqmode & GR_WRITE ? " writing" : "",
14130 +                              reqmode & GR_EXEC ? " executing" : "");
14131 +               return reqmode;
14132 +       } else
14133 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14134 +       {
14135 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
14136 +                              reqmode & GR_READ ? " reading" : "",
14137 +                              reqmode & GR_WRITE ? " writing" : "",
14138 +                              reqmode & GR_EXEC ? " executing" : "");
14139 +               return 0;
14140 +       } else if (unlikely((mode & reqmode) != reqmode))
14141 +               return 0;
14142 +
14143 +       return reqmode;
14144 +}
14145 +
14146 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
14147 +{
14148 +       __u32 mode;
14149 +
14150 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
14151 +
14152 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
14153 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
14154 +               return mode;
14155 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
14156 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
14157 +               return 0;
14158 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
14159 +               return 0;
14160 +
14161 +       return (reqmode);
14162 +}
14163 +
14164 +__u32
14165 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
14166 +{
14167 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
14168 +}
14169 +
14170 +__u32
14171 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
14172 +{
14173 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
14174 +}
14175 +
14176 +__u32
14177 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
14178 +{
14179 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
14180 +}
14181 +
14182 +__u32
14183 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
14184 +{
14185 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
14186 +}
14187 +
14188 +__u32
14189 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
14190 +                    mode_t mode)
14191 +{
14192 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
14193 +               return 1;
14194 +
14195 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
14196 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
14197 +                                  GR_FCHMOD_ACL_MSG);
14198 +       } else {
14199 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
14200 +       }
14201 +}
14202 +
14203 +__u32
14204 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
14205 +                   mode_t mode)
14206 +{
14207 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
14208 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
14209 +                                  GR_CHMOD_ACL_MSG);
14210 +       } else {
14211 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
14212 +       }
14213 +}
14214 +
14215 +__u32
14216 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
14217 +{
14218 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
14219 +}
14220 +
14221 +__u32
14222 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
14223 +{
14224 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
14225 +}
14226 +
14227 +__u32
14228 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
14229 +{
14230 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
14231 +                          GR_UNIXCONNECT_ACL_MSG);
14232 +}
14233 +
14234 +/* hardlinks require at minimum create permission,
14235 +   any additional privilege required is based on the
14236 +   privilege of the file being linked to
14237 +*/
14238 +__u32
14239 +gr_acl_handle_link(const struct dentry * new_dentry,
14240 +                  const struct dentry * parent_dentry,
14241 +                  const struct vfsmount * parent_mnt,
14242 +                  const struct dentry * old_dentry,
14243 +                  const struct vfsmount * old_mnt, const char *to)
14244 +{
14245 +       __u32 mode;
14246 +       __u32 needmode = GR_CREATE | GR_LINK;
14247 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
14248 +
14249 +       mode =
14250 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
14251 +                         old_mnt);
14252 +
14253 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
14254 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
14255 +               return mode;
14256 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
14257 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
14258 +               return 0;
14259 +       } else if (unlikely((mode & needmode) != needmode))
14260 +               return 0;
14261 +
14262 +       return 1;
14263 +}
14264 +
14265 +__u32
14266 +gr_acl_handle_symlink(const struct dentry * new_dentry,
14267 +                     const struct dentry * parent_dentry,
14268 +                     const struct vfsmount * parent_mnt, const char *from)
14269 +{
14270 +       __u32 needmode = GR_WRITE | GR_CREATE;
14271 +       __u32 mode;
14272 +
14273 +       mode =
14274 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
14275 +                           GR_CREATE | GR_AUDIT_CREATE |
14276 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
14277 +
14278 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
14279 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
14280 +               return mode;
14281 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
14282 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
14283 +               return 0;
14284 +       } else if (unlikely((mode & needmode) != needmode))
14285 +               return 0;
14286 +
14287 +       return (GR_WRITE | GR_CREATE);
14288 +}
14289 +
14290 +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)
14291 +{
14292 +       __u32 mode;
14293 +
14294 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
14295 +
14296 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
14297 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
14298 +               return mode;
14299 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
14300 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
14301 +               return 0;
14302 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
14303 +               return 0;
14304 +
14305 +       return (reqmode);
14306 +}
14307 +
14308 +__u32
14309 +gr_acl_handle_mknod(const struct dentry * new_dentry,
14310 +                   const struct dentry * parent_dentry,
14311 +                   const struct vfsmount * parent_mnt,
14312 +                   const int mode)
14313 +{
14314 +       __u32 reqmode = GR_WRITE | GR_CREATE;
14315 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
14316 +               reqmode |= GR_SETID;
14317 +
14318 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
14319 +                                 reqmode, GR_MKNOD_ACL_MSG);
14320 +}
14321 +
14322 +__u32
14323 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
14324 +                   const struct dentry *parent_dentry,
14325 +                   const struct vfsmount *parent_mnt)
14326 +{
14327 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
14328 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
14329 +}
14330 +
14331 +#define RENAME_CHECK_SUCCESS(old, new) \
14332 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
14333 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
14334 +
14335 +int
14336 +gr_acl_handle_rename(struct dentry *new_dentry,
14337 +                    struct dentry *parent_dentry,
14338 +                    const struct vfsmount *parent_mnt,
14339 +                    struct dentry *old_dentry,
14340 +                    struct inode *old_parent_inode,
14341 +                    struct vfsmount *old_mnt, const char *newname)
14342 +{
14343 +       __u32 comp1, comp2;
14344 +       int error = 0;
14345 +
14346 +       if (unlikely(!gr_acl_is_enabled()))
14347 +               return 0;
14348 +
14349 +       if (!new_dentry->d_inode) {
14350 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
14351 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
14352 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
14353 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
14354 +                                      GR_DELETE | GR_AUDIT_DELETE |
14355 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
14356 +                                      GR_SUPPRESS, old_mnt);
14357 +       } else {
14358 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
14359 +                                      GR_CREATE | GR_DELETE |
14360 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
14361 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
14362 +                                      GR_SUPPRESS, parent_mnt);
14363 +               comp2 =
14364 +                   gr_search_file(old_dentry,
14365 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
14366 +                                  GR_DELETE | GR_AUDIT_DELETE |
14367 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
14368 +       }
14369 +
14370 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
14371 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
14372 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
14373 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
14374 +                && !(comp2 & GR_SUPPRESS)) {
14375 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
14376 +               error = -EACCES;
14377 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
14378 +               error = -EACCES;
14379 +
14380 +       return error;
14381 +}
14382 +
14383 +void
14384 +gr_acl_handle_exit(void)
14385 +{
14386 +       u16 id;
14387 +       char *rolename;
14388 +       struct file *exec_file;
14389 +
14390 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
14391 +               id = current->acl_role_id;
14392 +               rolename = current->role->rolename;
14393 +               gr_set_acls(1);
14394 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
14395 +       }
14396 +
14397 +       write_lock(&grsec_exec_file_lock);
14398 +       exec_file = current->exec_file;
14399 +       current->exec_file = NULL;
14400 +       write_unlock(&grsec_exec_file_lock);
14401 +
14402 +       if (exec_file)
14403 +               fput(exec_file);
14404 +}
14405 +
14406 +int
14407 +gr_acl_handle_procpidmem(const struct task_struct *task)
14408 +{
14409 +       if (unlikely(!gr_acl_is_enabled()))
14410 +               return 0;
14411 +
14412 +       if (task->acl->mode & GR_PROTPROCFD)
14413 +               return -EACCES;
14414 +
14415 +       return 0;
14416 +}
14417 diff -urNp linux-2.6.17.11/grsecurity/gracl_ip.c linux-2.6.17.11/grsecurity/gracl_ip.c
14418 --- linux-2.6.17.11/grsecurity/gracl_ip.c       1969-12-31 19:00:00.000000000 -0500
14419 +++ linux-2.6.17.11/grsecurity/gracl_ip.c       2006-09-01 16:20:28.000000000 -0400
14420 @@ -0,0 +1,313 @@
14421 +#include <linux/kernel.h>
14422 +#include <asm/uaccess.h>
14423 +#include <asm/errno.h>
14424 +#include <net/sock.h>
14425 +#include <linux/file.h>
14426 +#include <linux/fs.h>
14427 +#include <linux/net.h>
14428 +#include <linux/in.h>
14429 +#include <linux/skbuff.h>
14430 +#include <linux/ip.h>
14431 +#include <linux/udp.h>
14432 +#include <linux/smp_lock.h>
14433 +#include <linux/types.h>
14434 +#include <linux/sched.h>
14435 +#include <linux/netdevice.h>
14436 +#include <linux/inetdevice.h>
14437 +#include <linux/gracl.h>
14438 +#include <linux/grsecurity.h>
14439 +#include <linux/grinternal.h>
14440 +
14441 +#define GR_BIND        0x01
14442 +#define GR_CONNECT     0x02
14443 +#define GR_INVERT      0x04
14444 +
14445 +static const char * gr_protocols[256] = {
14446 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
14447 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
14448 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
14449 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
14450 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
14451 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
14452 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
14453 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
14454 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
14455 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
14456 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
14457 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
14458 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
14459 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
14460 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
14461 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
14462 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
14463 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
14464 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
14465 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
14466 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
14467 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
14468 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
14469 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
14470 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
14471 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
14472 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
14473 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
14474 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
14475 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
14476 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
14477 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
14478 +       };
14479 +
14480 +static const char * gr_socktypes[11] = {
14481 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
14482 +       "unknown:7", "unknown:8", "unknown:9", "packet"
14483 +       };
14484 +
14485 +const char *
14486 +gr_proto_to_name(unsigned char proto)
14487 +{
14488 +       return gr_protocols[proto];
14489 +}
14490 +
14491 +const char *
14492 +gr_socktype_to_name(unsigned char type)
14493 +{
14494 +       return gr_socktypes[type];
14495 +}
14496 +
14497 +int
14498 +gr_search_socket(const int domain, const int type, const int protocol)
14499 +{
14500 +       struct acl_subject_label *curr;
14501 +
14502 +       if (unlikely(!gr_acl_is_enabled()))
14503 +               goto exit;
14504 +
14505 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
14506 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
14507 +               goto exit;      // let the kernel handle it
14508 +
14509 +       curr = current->acl;
14510 +
14511 +       if (!curr->ips)
14512 +               goto exit;
14513 +
14514 +       if ((curr->ip_type & (1 << type)) &&
14515 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
14516 +               goto exit;
14517 +
14518 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
14519 +               /* we don't place acls on raw sockets , and sometimes
14520 +                  dgram/ip sockets are opened for ioctl and not
14521 +                  bind/connect, so we'll fake a bind learn log */
14522 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
14523 +                       __u32 fakeip = 0;
14524 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
14525 +                                      current->role->roletype, current->uid,
14526 +                                      current->gid, current->exec_file ?
14527 +                                      gr_to_filename(current->exec_file->f_dentry,
14528 +                                      current->exec_file->f_vfsmnt) :
14529 +                                      curr->filename, curr->filename,
14530 +                                      NIPQUAD(fakeip), 0, type,
14531 +                                      protocol, GR_CONNECT, 
14532 +NIPQUAD(current->signal->curr_ip));
14533 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
14534 +                       __u32 fakeip = 0;
14535 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
14536 +                                      current->role->roletype, current->uid,
14537 +                                      current->gid, current->exec_file ?
14538 +                                      gr_to_filename(current->exec_file->f_dentry,
14539 +                                      current->exec_file->f_vfsmnt) :
14540 +                                      curr->filename, curr->filename,
14541 +                                      NIPQUAD(fakeip), 0, type,
14542 +                                      protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
14543 +               }
14544 +               /* we'll log when they use connect or bind */
14545 +               goto exit;
14546 +       }
14547 +
14548 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
14549 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
14550 +
14551 +       return 0;
14552 +      exit:
14553 +       return 1;
14554 +}
14555 +
14556 +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)
14557 +{
14558 +       if ((ip->mode & mode) &&
14559 +           (ip_port >= ip->low) &&
14560 +           (ip_port <= ip->high) &&
14561 +           ((ntohl(ip_addr) & our_netmask) ==
14562 +            (ntohl(our_addr) & our_netmask))
14563 +           && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
14564 +           && (ip->type & (1 << type))) {
14565 +               if (ip->mode & GR_INVERT)
14566 +                       return 2; // specifically denied
14567 +               else
14568 +                       return 1; // allowed
14569 +       }
14570 +
14571 +       return 0; // not specifically allowed, may continue parsing
14572 +}
14573 +
14574 +static int
14575 +gr_search_connectbind(const int mode, const struct sock *sk,
14576 +                     const struct sockaddr_in *addr, const int type)
14577 +{
14578 +       char iface[IFNAMSIZ] = {0};
14579 +       struct acl_subject_label *curr;
14580 +       struct acl_ip_label *ip;
14581 +       struct net_device *dev;
14582 +       struct in_device *idev;
14583 +       unsigned long i;
14584 +       int ret;
14585 +       __u32 ip_addr = 0;
14586 +       __u32 our_addr;
14587 +       __u32 our_netmask;
14588 +       char *p;
14589 +       __u16 ip_port = 0;
14590 +
14591 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
14592 +               return 1;
14593 +
14594 +       curr = current->acl;
14595 +
14596 +       if (!curr->ips)
14597 +               return 1;
14598 +
14599 +       ip_addr = addr->sin_addr.s_addr;
14600 +       ip_port = ntohs(addr->sin_port);
14601 +
14602 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
14603 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
14604 +                              current->role->roletype, current->uid,
14605 +                              current->gid, current->exec_file ?
14606 +                              gr_to_filename(current->exec_file->f_dentry,
14607 +                              current->exec_file->f_vfsmnt) :
14608 +                              curr->filename, curr->filename,
14609 +                              NIPQUAD(ip_addr), ip_port, type,
14610 +                              sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
14611 +               return 1;
14612 +       }
14613 +
14614 +       for (i = 0; i < curr->ip_num; i++) {
14615 +               ip = *(curr->ips + i);
14616 +               if (ip->iface != NULL) {
14617 +                       strncpy(iface, ip->iface, IFNAMSIZ - 1);
14618 +                       p = strchr(iface, ':');
14619 +                       if (p != NULL)
14620 +                               *p = '\0';
14621 +                       dev = dev_get_by_name(iface);
14622 +                       if (dev == NULL)
14623 +                               continue;
14624 +                       idev = in_dev_get(dev);
14625 +                       if (idev == NULL) {
14626 +                               dev_put(dev);
14627 +                               continue;
14628 +                       }
14629 +                       rcu_read_lock();
14630 +                       for_ifa(idev) {
14631 +                               if (!strcmp(ip->iface, ifa->ifa_label)) {
14632 +                                       our_addr = ifa->ifa_address;
14633 +                                       our_netmask = 0xffffffff;
14634 +                                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
14635 +                                       if (ret == 1) {
14636 +                                               rcu_read_unlock();
14637 +                                               in_dev_put(idev);
14638 +                                               dev_put(dev);
14639 +                                               return 1;
14640 +                                       } else if (ret == 2) {
14641 +                                               rcu_read_unlock();
14642 +                                               in_dev_put(idev);
14643 +                                               dev_put(dev);
14644 +                                               goto denied;
14645 +                                       }
14646 +                               }
14647 +                       } endfor_ifa(idev);
14648 +                       rcu_read_unlock();
14649 +                       in_dev_put(idev);
14650 +                       dev_put(dev);
14651 +               } else {
14652 +                       our_addr = ip->addr;
14653 +                       our_netmask = ip->netmask;
14654 +                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
14655 +                       if (ret == 1)
14656 +                               return 1;
14657 +                       else if (ret == 2)
14658 +                               goto denied;
14659 +               }
14660 +       }
14661 +
14662 +denied:
14663 +       if (mode == GR_BIND)
14664 +               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));
14665 +       else if (mode == GR_CONNECT)
14666 +               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));
14667 +
14668 +       return 0;
14669 +}
14670 +
14671 +int
14672 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
14673 +{
14674 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
14675 +}
14676 +
14677 +int
14678 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
14679 +{
14680 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
14681 +}
14682 +
14683 +int gr_search_listen(const struct socket *sock)
14684 +{
14685 +       struct sock *sk = sock->sk;
14686 +       struct sockaddr_in addr;
14687 +
14688 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
14689 +       addr.sin_port = inet_sk(sk)->sport;
14690 +
14691 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
14692 +}
14693 +
14694 +int gr_search_accept(const struct socket *sock)
14695 +{
14696 +       struct sock *sk = sock->sk;
14697 +       struct sockaddr_in addr;
14698 +
14699 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
14700 +       addr.sin_port = inet_sk(sk)->sport;
14701 +
14702 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
14703 +}
14704 +
14705 +int
14706 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
14707 +{
14708 +       if (addr)
14709 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
14710 +       else {
14711 +               struct sockaddr_in sin;
14712 +               const struct inet_sock *inet = inet_sk(sk);
14713 +
14714 +               sin.sin_addr.s_addr = inet->daddr;
14715 +               sin.sin_port = inet->dport;
14716 +
14717 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
14718 +       }
14719 +}
14720 +
14721 +int
14722 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
14723 +{
14724 +       struct sockaddr_in sin;
14725 +
14726 +       if (unlikely(skb->len < sizeof (struct udphdr)))
14727 +               return 1;       // skip this packet
14728 +
14729 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
14730 +       sin.sin_port = skb->h.uh->source;
14731 +
14732 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
14733 +}
14734 diff -urNp linux-2.6.17.11/grsecurity/gracl_learn.c linux-2.6.17.11/grsecurity/gracl_learn.c
14735 --- linux-2.6.17.11/grsecurity/gracl_learn.c    1969-12-31 19:00:00.000000000 -0500
14736 +++ linux-2.6.17.11/grsecurity/gracl_learn.c    2006-09-01 16:20:28.000000000 -0400
14737 @@ -0,0 +1,204 @@
14738 +#include <linux/kernel.h>
14739 +#include <linux/mm.h>
14740 +#include <linux/sched.h>
14741 +#include <linux/poll.h>
14742 +#include <linux/smp_lock.h>
14743 +#include <linux/string.h>
14744 +#include <linux/file.h>
14745 +#include <linux/types.h>
14746 +#include <linux/vmalloc.h>
14747 +#include <linux/grinternal.h>
14748 +
14749 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
14750 +                                  size_t count, loff_t *ppos);
14751 +extern int gr_acl_is_enabled(void);
14752 +
14753 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
14754 +static int gr_learn_attached;
14755 +
14756 +/* use a 512k buffer */
14757 +#define LEARN_BUFFER_SIZE (512 * 1024)
14758 +
14759 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
14760 +static DECLARE_MUTEX(gr_learn_user_sem);
14761 +
14762 +/* we need to maintain two buffers, so that the kernel context of grlearn
14763 +   uses a semaphore around the userspace copying, and the other kernel contexts
14764 +   use a spinlock when copying into the buffer, since they cannot sleep
14765 +*/
14766 +static char *learn_buffer;
14767 +static char *learn_buffer_user;
14768 +static int learn_buffer_len;
14769 +static int learn_buffer_user_len;
14770 +
14771 +static ssize_t
14772 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
14773 +{
14774 +       DECLARE_WAITQUEUE(wait, current);
14775 +       ssize_t retval = 0;
14776 +
14777 +       add_wait_queue(&learn_wait, &wait);
14778 +       set_current_state(TASK_INTERRUPTIBLE);
14779 +       do {
14780 +               down(&gr_learn_user_sem);
14781 +               spin_lock(&gr_learn_lock);
14782 +               if (learn_buffer_len)
14783 +                       break;
14784 +               spin_unlock(&gr_learn_lock);
14785 +               up(&gr_learn_user_sem);
14786 +               if (file->f_flags & O_NONBLOCK) {
14787 +                       retval = -EAGAIN;
14788 +                       goto out;
14789 +               }
14790 +               if (signal_pending(current)) {
14791 +                       retval = -ERESTARTSYS;
14792 +                       goto out;
14793 +               }
14794 +
14795 +               schedule();
14796 +       } while (1);
14797 +
14798 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
14799 +       learn_buffer_user_len = learn_buffer_len;
14800 +       retval = learn_buffer_len;
14801 +       learn_buffer_len = 0;
14802 +
14803 +       spin_unlock(&gr_learn_lock);
14804 +
14805 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
14806 +               retval = -EFAULT;
14807 +
14808 +       up(&gr_learn_user_sem);
14809 +out:
14810 +       set_current_state(TASK_RUNNING);
14811 +       remove_wait_queue(&learn_wait, &wait);
14812 +       return retval;
14813 +}
14814 +
14815 +static unsigned int
14816 +poll_learn(struct file * file, poll_table * wait)
14817 +{
14818 +       poll_wait(file, &learn_wait, wait);
14819 +
14820 +       if (learn_buffer_len)
14821 +               return (POLLIN | POLLRDNORM);
14822 +
14823 +       return 0;
14824 +}
14825 +
14826 +void
14827 +gr_clear_learn_entries(void)
14828 +{
14829 +       char *tmp;
14830 +
14831 +       down(&gr_learn_user_sem);
14832 +       if (learn_buffer != NULL) {
14833 +               spin_lock(&gr_learn_lock);
14834 +               tmp = learn_buffer;
14835 +               learn_buffer = NULL;
14836 +               spin_unlock(&gr_learn_lock);
14837 +               vfree(learn_buffer);
14838 +       }
14839 +       if (learn_buffer_user != NULL) {
14840 +               vfree(learn_buffer_user);
14841 +               learn_buffer_user = NULL;
14842 +       }
14843 +       learn_buffer_len = 0;
14844 +       up(&gr_learn_user_sem);
14845 +
14846 +       return;
14847 +}
14848 +
14849 +void
14850 +gr_add_learn_entry(const char *fmt, ...)
14851 +{
14852 +       va_list args;
14853 +       unsigned int len;
14854 +
14855 +       if (!gr_learn_attached)
14856 +               return;
14857 +
14858 +       spin_lock(&gr_learn_lock);
14859 +
14860 +       /* leave a gap at the end so we know when it's "full" but don't have to
14861 +          compute the exact length of the string we're trying to append
14862 +       */
14863 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
14864 +               spin_unlock(&gr_learn_lock);
14865 +               wake_up_interruptible(&learn_wait);
14866 +               return;
14867 +       }
14868 +       if (learn_buffer == NULL) {
14869 +               spin_unlock(&gr_learn_lock);
14870 +               return;
14871 +       }
14872 +
14873 +       va_start(args, fmt);
14874 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
14875 +       va_end(args);
14876 +
14877 +       learn_buffer_len += len + 1;
14878 +
14879 +       spin_unlock(&gr_learn_lock);
14880 +       wake_up_interruptible(&learn_wait);
14881 +
14882 +       return;
14883 +}
14884 +
14885 +static int
14886 +open_learn(struct inode *inode, struct file *file)
14887 +{
14888 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
14889 +               return -EBUSY;
14890 +       if (file->f_mode & FMODE_READ) {
14891 +               down(&gr_learn_user_sem);
14892 +               if (learn_buffer == NULL)
14893 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
14894 +               if (learn_buffer_user == NULL)
14895 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
14896 +               if (learn_buffer == NULL)
14897 +                       return -ENOMEM;
14898 +               if (learn_buffer_user == NULL)
14899 +                       return -ENOMEM;
14900 +               learn_buffer_len = 0;
14901 +               learn_buffer_user_len = 0;
14902 +               gr_learn_attached = 1;
14903 +               up(&gr_learn_user_sem);
14904 +       }
14905 +       return 0;
14906 +}
14907 +
14908 +static int
14909 +close_learn(struct inode *inode, struct file *file)
14910 +{
14911 +       char *tmp;
14912 +
14913 +       if (file->f_mode & FMODE_READ) {
14914 +               down(&gr_learn_user_sem);
14915 +               if (learn_buffer != NULL) {
14916 +                       spin_lock(&gr_learn_lock);
14917 +                       tmp = learn_buffer;
14918 +                       learn_buffer = NULL;
14919 +                       spin_unlock(&gr_learn_lock);
14920 +                       vfree(tmp);
14921 +               }
14922 +               if (learn_buffer_user != NULL) {
14923 +                       vfree(learn_buffer_user);
14924 +                       learn_buffer_user = NULL;
14925 +               }
14926 +               learn_buffer_len = 0;
14927 +               learn_buffer_user_len = 0;
14928 +               gr_learn_attached = 0;
14929 +               up(&gr_learn_user_sem);
14930 +       }
14931 +
14932 +       return 0;
14933 +}
14934 +               
14935 +struct file_operations grsec_fops = {
14936 +       .read           = read_learn,
14937 +       .write          = write_grsec_handler,
14938 +       .open           = open_learn,
14939 +       .release        = close_learn,
14940 +       .poll           = poll_learn,
14941 +};
14942 diff -urNp linux-2.6.17.11/grsecurity/gracl_res.c linux-2.6.17.11/grsecurity/gracl_res.c
14943 --- linux-2.6.17.11/grsecurity/gracl_res.c      1969-12-31 19:00:00.000000000 -0500
14944 +++ linux-2.6.17.11/grsecurity/gracl_res.c      2006-09-01 16:20:28.000000000 -0400
14945 @@ -0,0 +1,45 @@
14946 +#include <linux/kernel.h>
14947 +#include <linux/sched.h>
14948 +#include <linux/gracl.h>
14949 +#include <linux/grinternal.h>
14950 +
14951 +static const char *restab_log[] = {
14952 +       [RLIMIT_CPU] = "RLIMIT_CPU",
14953 +       [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
14954 +       [RLIMIT_DATA] = "RLIMIT_DATA",
14955 +       [RLIMIT_STACK] = "RLIMIT_STACK",
14956 +       [RLIMIT_CORE] = "RLIMIT_CORE",
14957 +       [RLIMIT_RSS] = "RLIMIT_RSS",
14958 +       [RLIMIT_NPROC] = "RLIMIT_NPROC",
14959 +       [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
14960 +       [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
14961 +       [RLIMIT_AS] = "RLIMIT_AS",
14962 +       [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
14963 +       [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
14964 +};
14965 +
14966 +void
14967 +gr_log_resource(const struct task_struct *task,
14968 +               const int res, const unsigned long wanted, const int gt)
14969 +{
14970 +       if (res == RLIMIT_NPROC && 
14971 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
14972 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
14973 +               return;
14974 +       else if (res == RLIMIT_MEMLOCK &&
14975 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
14976 +               return;
14977 +
14978 +       if (!gr_acl_is_enabled() && !grsec_resource_logging)
14979 +               return;
14980 +
14981 +       preempt_disable();
14982 +
14983 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
14984 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
14985 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
14986 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
14987 +       preempt_enable_no_resched();
14988 +
14989 +       return;
14990 +}
14991 diff -urNp linux-2.6.17.11/grsecurity/gracl_segv.c linux-2.6.17.11/grsecurity/gracl_segv.c
14992 --- linux-2.6.17.11/grsecurity/gracl_segv.c     1969-12-31 19:00:00.000000000 -0500
14993 +++ linux-2.6.17.11/grsecurity/gracl_segv.c     2006-09-01 16:20:28.000000000 -0400
14994 @@ -0,0 +1,295 @@
14995 +#include <linux/kernel.h>
14996 +#include <linux/mm.h>
14997 +#include <asm/uaccess.h>
14998 +#include <asm/errno.h>
14999 +#include <asm/mman.h>
15000 +#include <net/sock.h>
15001 +#include <linux/file.h>
15002 +#include <linux/fs.h>
15003 +#include <linux/net.h>
15004 +#include <linux/in.h>
15005 +#include <linux/smp_lock.h>
15006 +#include <linux/slab.h>
15007 +#include <linux/types.h>
15008 +#include <linux/sched.h>
15009 +#include <linux/timer.h>
15010 +#include <linux/gracl.h>
15011 +#include <linux/grsecurity.h>
15012 +#include <linux/grinternal.h>
15013 +
15014 +static struct crash_uid *uid_set;
15015 +static unsigned short uid_used;
15016 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
15017 +extern rwlock_t gr_inode_lock;
15018 +extern struct acl_subject_label *
15019 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
15020 +                             struct acl_role_label *role);
15021 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
15022 +
15023 +int
15024 +gr_init_uidset(void)
15025 +{
15026 +       uid_set =
15027 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
15028 +       uid_used = 0;
15029 +
15030 +       return uid_set ? 1 : 0;
15031 +}
15032 +
15033 +void
15034 +gr_free_uidset(void)
15035 +{
15036 +       if (uid_set)
15037 +               kfree(uid_set);
15038 +
15039 +       return;
15040 +}
15041 +
15042 +int
15043 +gr_find_uid(const uid_t uid)
15044 +{
15045 +       struct crash_uid *tmp = uid_set;
15046 +       uid_t buid;
15047 +       int low = 0, high = uid_used - 1, mid;
15048 +
15049 +       while (high >= low) {
15050 +               mid = (low + high) >> 1;
15051 +               buid = tmp[mid].uid;
15052 +               if (buid == uid)
15053 +                       return mid;
15054 +               if (buid > uid)
15055 +                       high = mid - 1;
15056 +               if (buid < uid)
15057 +                       low = mid + 1;
15058 +       }
15059 +
15060 +       return -1;
15061 +}
15062 +
15063 +static __inline__ void
15064 +gr_insertsort(void)
15065 +{
15066 +       unsigned short i, j;
15067 +       struct crash_uid index;
15068 +
15069 +       for (i = 1; i < uid_used; i++) {
15070 +               index = uid_set[i];
15071 +               j = i;
15072 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
15073 +                       uid_set[j] = uid_set[j - 1];
15074 +                       j--;
15075 +               }
15076 +               uid_set[j] = index;
15077 +       }
15078 +
15079 +       return;
15080 +}
15081 +
15082 +static __inline__ void
15083 +gr_insert_uid(const uid_t uid, const unsigned long expires)
15084 +{
15085 +       int loc;
15086 +
15087 +       if (uid_used == GR_UIDTABLE_MAX)
15088 +               return;
15089 +
15090 +       loc = gr_find_uid(uid);
15091 +
15092 +       if (loc >= 0) {
15093 +               uid_set[loc].expires = expires;
15094 +               return;
15095 +       }
15096 +
15097 +       uid_set[uid_used].uid = uid;
15098 +       uid_set[uid_used].expires = expires;
15099 +       uid_used++;
15100 +
15101 +       gr_insertsort();
15102 +
15103 +       return;
15104 +}
15105 +
15106 +void
15107 +gr_remove_uid(const unsigned short loc)
15108 +{
15109 +       unsigned short i;
15110 +
15111 +       for (i = loc + 1; i < uid_used; i++)
15112 +               uid_set[i - 1] = uid_set[i];
15113 +
15114 +       uid_used--;
15115 +
15116 +       return;
15117 +}
15118 +
15119 +int
15120 +gr_check_crash_uid(const uid_t uid)
15121 +{
15122 +       int loc;
15123 +       int ret = 0;
15124 +
15125 +       if (unlikely(!gr_acl_is_enabled()))
15126 +               return 0;
15127 +
15128 +       spin_lock(&gr_uid_lock);
15129 +       loc = gr_find_uid(uid);
15130 +
15131 +       if (loc < 0)
15132 +               goto out_unlock;
15133 +
15134 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
15135 +               gr_remove_uid(loc);
15136 +       else
15137 +               ret = 1;
15138 +
15139 +out_unlock:
15140 +       spin_unlock(&gr_uid_lock);
15141 +       return ret;
15142 +}
15143 +
15144 +static __inline__ int
15145 +proc_is_setxid(const struct task_struct *task)
15146 +{
15147 +       if (task->uid != task->euid || task->uid != task->suid ||
15148 +           task->uid != task->fsuid)
15149 +               return 1;
15150 +       if (task->gid != task->egid || task->gid != task->sgid ||
15151 +           task->gid != task->fsgid)
15152 +               return 1;
15153 +
15154 +       return 0;
15155 +}
15156 +static __inline__ int
15157 +gr_fake_force_sig(int sig, struct task_struct *t)
15158 +{
15159 +       unsigned long int flags;
15160 +       int ret;
15161 +
15162 +       spin_lock_irqsave(&t->sighand->siglock, flags);
15163 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
15164 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
15165 +               sigdelset(&t->blocked, sig);
15166 +               recalc_sigpending_tsk(t);
15167 +       }
15168 +       ret = specific_send_sig_info(sig, (void*)1L, t);
15169 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
15170 +
15171 +       return ret;
15172 +}
15173 +
15174 +void
15175 +gr_handle_crash(struct task_struct *task, const int sig)
15176 +{
15177 +       struct acl_subject_label *curr;
15178 +       struct acl_subject_label *curr2;
15179 +       struct task_struct *tsk, *tsk2;
15180 +
15181 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
15182 +               return;
15183 +
15184 +       if (unlikely(!gr_acl_is_enabled()))
15185 +               return;
15186 +
15187 +       curr = task->acl;
15188 +
15189 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
15190 +               return;
15191 +
15192 +       if (time_before_eq(curr->expires, get_seconds())) {
15193 +               curr->expires = 0;
15194 +               curr->crashes = 0;
15195 +       }
15196 +
15197 +       curr->crashes++;
15198 +
15199 +       if (!curr->expires)
15200 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
15201 +
15202 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
15203 +           time_after(curr->expires, get_seconds())) {
15204 +               if (task->uid && proc_is_setxid(task)) {
15205 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
15206 +                       spin_lock(&gr_uid_lock);
15207 +                       gr_insert_uid(task->uid, curr->expires);
15208 +                       spin_unlock(&gr_uid_lock);
15209 +                       curr->expires = 0;
15210 +                       curr->crashes = 0;
15211 +                       read_lock(&tasklist_lock);
15212 +                       do_each_thread(tsk2, tsk) {
15213 +                               if (tsk != task && tsk->uid == task->uid)
15214 +                                       gr_fake_force_sig(SIGKILL, tsk);
15215 +                       } while_each_thread(tsk2, tsk);
15216 +                       read_unlock(&tasklist_lock);
15217 +               } else {
15218 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
15219 +                       read_lock(&tasklist_lock);
15220 +                       do_each_thread(tsk2, tsk) {
15221 +                               if (likely(tsk != task)) {
15222 +                                       curr2 = tsk->acl;
15223 +
15224 +                                       if (curr2->device == curr->device &&
15225 +                                           curr2->inode == curr->inode)
15226 +                                               gr_fake_force_sig(SIGKILL, tsk);
15227 +                               }
15228 +                       } while_each_thread(tsk2, tsk);
15229 +                       read_unlock(&tasklist_lock);
15230 +               }
15231 +       }
15232 +
15233 +       return;
15234 +}
15235 +
15236 +int
15237 +gr_check_crash_exec(const struct file *filp)
15238 +{
15239 +       struct acl_subject_label *curr;
15240 +
15241 +       if (unlikely(!gr_acl_is_enabled()))
15242 +               return 0;
15243 +
15244 +       read_lock(&gr_inode_lock);
15245 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
15246 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
15247 +                                    current->role);
15248 +       read_unlock(&gr_inode_lock);
15249 +
15250 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
15251 +           (!curr->crashes && !curr->expires))
15252 +               return 0;
15253 +
15254 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
15255 +           time_after(curr->expires, get_seconds()))
15256 +               return 1;
15257 +       else if (time_before_eq(curr->expires, get_seconds())) {
15258 +               curr->crashes = 0;
15259 +               curr->expires = 0;
15260 +       }
15261 +
15262 +       return 0;
15263 +}
15264 +
15265 +void
15266 +gr_handle_alertkill(struct task_struct *task)
15267 +{
15268 +       struct acl_subject_label *curracl;
15269 +       __u32 curr_ip;
15270 +       struct task_struct *p, *p2;
15271 +
15272 +       if (unlikely(!gr_acl_is_enabled()))
15273 +               return;
15274 +
15275 +       curracl = task->acl;
15276 +       curr_ip = task->signal->curr_ip;
15277 +
15278 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
15279 +               read_lock(&tasklist_lock);
15280 +               do_each_thread(p2, p) {
15281 +                       if (p->signal->curr_ip == curr_ip)
15282 +                               gr_fake_force_sig(SIGKILL, p);
15283 +               } while_each_thread(p2, p);
15284 +               read_unlock(&tasklist_lock);
15285 +       } else if (curracl->mode & GR_KILLPROC)
15286 +               gr_fake_force_sig(SIGKILL, task);
15287 +
15288 +       return;
15289 +}
15290 diff -urNp linux-2.6.17.11/grsecurity/gracl_shm.c linux-2.6.17.11/grsecurity/gracl_shm.c
15291 --- linux-2.6.17.11/grsecurity/gracl_shm.c      1969-12-31 19:00:00.000000000 -0500
15292 +++ linux-2.6.17.11/grsecurity/gracl_shm.c      2006-09-01 16:20:28.000000000 -0400
15293 @@ -0,0 +1,34 @@
15294 +#include <linux/kernel.h>
15295 +#include <linux/mm.h>
15296 +#include <linux/sched.h>
15297 +#include <linux/file.h>
15298 +#include <linux/ipc.h>
15299 +#include <linux/gracl.h>
15300 +#include <linux/grsecurity.h>
15301 +#include <linux/grinternal.h>
15302 +#include <linux/vs_pid.h>
15303 +
15304 +int
15305 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
15306 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
15307 +{
15308 +       struct task_struct *task;
15309 +
15310 +       if (!gr_acl_is_enabled())
15311 +               return 1;
15312 +
15313 +       task = find_task_by_pid(shm_cprid);
15314 +
15315 +       if (unlikely(!task))
15316 +               task = find_task_by_pid(shm_lapid);
15317 +
15318 +       if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
15319 +                             (task->pid == shm_lapid)) &&
15320 +                    (task->acl->mode & GR_PROTSHM) &&
15321 +                    (task->acl != current->acl))) {
15322 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
15323 +               return 0;
15324 +       }
15325 +
15326 +       return 1;
15327 +}
15328 diff -urNp linux-2.6.17.11/grsecurity/grsec_chdir.c linux-2.6.17.11/grsecurity/grsec_chdir.c
15329 --- linux-2.6.17.11/grsecurity/grsec_chdir.c    1969-12-31 19:00:00.000000000 -0500
15330 +++ linux-2.6.17.11/grsecurity/grsec_chdir.c    2006-09-01 16:20:28.000000000 -0400
15331 @@ -0,0 +1,19 @@
15332 +#include <linux/kernel.h>
15333 +#include <linux/sched.h>
15334 +#include <linux/fs.h>
15335 +#include <linux/file.h>
15336 +#include <linux/grsecurity.h>
15337 +#include <linux/grinternal.h>
15338 +
15339 +void
15340 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
15341 +{
15342 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
15343 +       if ((grsec_enable_chdir && grsec_enable_group &&
15344 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
15345 +                                             !grsec_enable_group)) {
15346 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
15347 +       }
15348 +#endif
15349 +       return;
15350 +}
15351 diff -urNp linux-2.6.17.11/grsecurity/grsec_chroot.c linux-2.6.17.11/grsecurity/grsec_chroot.c
15352 --- linux-2.6.17.11/grsecurity/grsec_chroot.c   1969-12-31 19:00:00.000000000 -0500
15353 +++ linux-2.6.17.11/grsecurity/grsec_chroot.c   2006-09-01 16:20:28.000000000 -0400
15354 @@ -0,0 +1,332 @@
15355 +#include <linux/kernel.h>
15356 +#include <linux/module.h>
15357 +#include <linux/sched.h>
15358 +#include <linux/file.h>
15359 +#include <linux/fs.h>
15360 +#include <linux/mount.h>
15361 +#include <linux/types.h>
15362 +#include <linux/grinternal.h>
15363 +
15364 +int
15365 +gr_handle_chroot_unix(const pid_t pid)
15366 +{
15367 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
15368 +       struct pid *spid = NULL;
15369 +
15370 +       if (unlikely(!grsec_enable_chroot_unix))
15371 +               return 1;
15372 +
15373 +       if (likely(!proc_is_chrooted(current)))
15374 +               return 1;
15375 +
15376 +       read_lock(&tasklist_lock);
15377 +
15378 +       spid = find_pid(pid);
15379 +       if (spid) {
15380 +               struct task_struct *p;
15381 +               p = pid_task(spid, PIDTYPE_PID);
15382 +               task_lock(p);
15383 +               if (unlikely(!have_same_root(current, p))) {
15384 +                       task_unlock(p);
15385 +                       read_unlock(&tasklist_lock);
15386 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
15387 +                       return 0;
15388 +               }
15389 +               task_unlock(p);
15390 +       }
15391 +       read_unlock(&tasklist_lock);
15392 +#endif
15393 +       return 1;
15394 +}
15395 +
15396 +int
15397 +gr_handle_chroot_nice(void)
15398 +{
15399 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
15400 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
15401 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
15402 +               return -EPERM;
15403 +       }
15404 +#endif
15405 +       return 0;
15406 +}
15407 +
15408 +int
15409 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
15410 +{
15411 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
15412 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
15413 +                       && proc_is_chrooted(current)) {
15414 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
15415 +               return -EACCES;
15416 +       }
15417 +#endif
15418 +       return 0;
15419 +}
15420 +
15421 +int
15422 +gr_handle_chroot_rawio(const struct inode *inode)
15423 +{
15424 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
15425 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
15426 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
15427 +               return 1;
15428 +#endif
15429 +       return 0;
15430 +}
15431 +
15432 +int
15433 +gr_pid_is_chrooted(struct task_struct *p)
15434 +{
15435 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
15436 +       if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !p)
15437 +               return 0;
15438 +
15439 +       task_lock(p);
15440 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
15441 +           !have_same_root(current, p)) {
15442 +               task_unlock(p);
15443 +               return 1;
15444 +       }
15445 +       task_unlock(p);
15446 +#endif
15447 +       return 0;
15448 +}
15449 +
15450 +EXPORT_SYMBOL(gr_pid_is_chrooted);
15451 +
15452 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
15453 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
15454 +{
15455 +       struct dentry *dentry = (struct dentry *)u_dentry;
15456 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
15457 +       struct dentry *realroot;
15458 +       struct vfsmount *realrootmnt;
15459 +       struct dentry *currentroot;
15460 +       struct vfsmount *currentmnt;
15461 +       int ret = 1;
15462 +
15463 +       read_lock(&child_reaper->fs->lock);
15464 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
15465 +       realroot = dget(child_reaper->fs->root);
15466 +       read_unlock(&child_reaper->fs->lock);
15467 +
15468 +       read_lock(&current->fs->lock);
15469 +       currentmnt = mntget(current->fs->rootmnt);
15470 +       currentroot = dget(current->fs->root);
15471 +       read_unlock(&current->fs->lock);
15472 +
15473 +       spin_lock(&dcache_lock);
15474 +       for (;;) {
15475 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
15476 +                    || (dentry == currentroot && mnt == currentmnt)))
15477 +                       break;
15478 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
15479 +                       if (mnt->mnt_parent == mnt)
15480 +                               break;
15481 +                       dentry = mnt->mnt_mountpoint;
15482 +                       mnt = mnt->mnt_parent;
15483 +                       continue;
15484 +               }
15485 +               dentry = dentry->d_parent;
15486 +       }
15487 +       spin_unlock(&dcache_lock);
15488 +
15489 +       dput(currentroot);
15490 +       mntput(currentmnt);
15491 +
15492 +       /* access is outside of chroot */
15493 +       if (dentry == realroot && mnt == realrootmnt)
15494 +               ret = 0;
15495 +
15496 +       dput(realroot);
15497 +       mntput(realrootmnt);
15498 +       return ret;
15499 +}
15500 +#endif
15501 +
15502 +int
15503 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
15504 +{
15505 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
15506 +       if (!grsec_enable_chroot_fchdir)
15507 +               return 1;
15508 +
15509 +       if (!proc_is_chrooted(current))
15510 +               return 1;
15511 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
15512 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
15513 +               return 0;
15514 +       }
15515 +#endif
15516 +       return 1;
15517 +}
15518 +
15519 +int
15520 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
15521 +               const time_t shm_createtime)
15522 +{
15523 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
15524 +       struct pid *pid = NULL;
15525 +       time_t starttime;
15526 +
15527 +       if (unlikely(!grsec_enable_chroot_shmat))
15528 +               return 1;
15529 +
15530 +       if (likely(!proc_is_chrooted(current)))
15531 +               return 1;
15532 +
15533 +       read_lock(&tasklist_lock);
15534 +
15535 +       pid = find_pid(shm_cprid);
15536 +       if (pid) {
15537 +               struct task_struct *p;
15538 +               p = pid_task(pid, PIDTYPE_PID);
15539 +               task_lock(p);
15540 +               starttime = p->start_time.tv_sec;
15541 +               if (unlikely(!have_same_root(current, p) &&
15542 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
15543 +                       task_unlock(p);
15544 +                       read_unlock(&tasklist_lock);
15545 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
15546 +                       return 0;
15547 +               }
15548 +               task_unlock(p);
15549 +       } else {
15550 +               pid = find_pid(shm_lapid);
15551 +               if (pid) {
15552 +                       struct task_struct *p;
15553 +                       p = pid_task(pid, PIDTYPE_PID);
15554 +                       task_lock(p);
15555 +                       if (unlikely(!have_same_root(current, p))) {
15556 +                               task_unlock(p);
15557 +                               read_unlock(&tasklist_lock);
15558 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
15559 +                               return 0;
15560 +                       }
15561 +                       task_unlock(p);
15562 +               }
15563 +       }
15564 +
15565 +       read_unlock(&tasklist_lock);
15566 +#endif
15567 +       return 1;
15568 +}
15569 +
15570 +void
15571 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
15572 +{
15573 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
15574 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
15575 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
15576 +#endif
15577 +       return;
15578 +}
15579 +
15580 +int
15581 +gr_handle_chroot_mknod(const struct dentry *dentry,
15582 +                      const struct vfsmount *mnt, const int mode)
15583 +{
15584 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
15585 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
15586 +           proc_is_chrooted(current)) {
15587 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
15588 +               return -EPERM;
15589 +       }
15590 +#endif
15591 +       return 0;
15592 +}
15593 +
15594 +int
15595 +gr_handle_chroot_mount(const struct dentry *dentry,
15596 +                      const struct vfsmount *mnt, const char *dev_name)
15597 +{
15598 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
15599 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
15600 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
15601 +               return -EPERM;
15602 +       }
15603 +#endif
15604 +       return 0;
15605 +}
15606 +
15607 +int
15608 +gr_handle_chroot_pivot(void)
15609 +{
15610 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
15611 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
15612 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
15613 +               return -EPERM;
15614 +       }
15615 +#endif
15616 +       return 0;
15617 +}
15618 +
15619 +int
15620 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
15621 +{
15622 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
15623 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
15624 +           !gr_is_outside_chroot(dentry, mnt)) {
15625 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
15626 +               return -EPERM;
15627 +       }
15628 +#endif
15629 +       return 0;
15630 +}
15631 +
15632 +void
15633 +gr_handle_chroot_caps(struct task_struct *task)
15634 +{
15635 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
15636 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
15637 +               task->cap_permitted =
15638 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
15639 +               task->cap_inheritable =
15640 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
15641 +               task->cap_effective =
15642 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
15643 +       }
15644 +#endif
15645 +       return;
15646 +}
15647 +
15648 +int
15649 +gr_handle_chroot_sysctl(const int op)
15650 +{
15651 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
15652 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
15653 +           && (op & 002))
15654 +               return -EACCES;
15655 +#endif
15656 +       return 0;
15657 +}
15658 +
15659 +void
15660 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
15661 +{
15662 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
15663 +       if (grsec_enable_chroot_chdir)
15664 +               set_fs_pwd(current->fs, mnt, dentry);
15665 +#endif
15666 +       return;
15667 +}
15668 +
15669 +int
15670 +gr_handle_chroot_chmod(const struct dentry *dentry,
15671 +                      const struct vfsmount *mnt, const int mode)
15672 +{
15673 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
15674 +       if (grsec_enable_chroot_chmod &&
15675 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
15676 +           proc_is_chrooted(current)) {
15677 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
15678 +               return -EPERM;
15679 +       }
15680 +#endif
15681 +       return 0;
15682 +}
15683 +
15684 +#ifdef CONFIG_SECURITY
15685 +EXPORT_SYMBOL(gr_handle_chroot_caps);
15686 +#endif
15687 diff -urNp linux-2.6.17.11/grsecurity/grsec_disabled.c linux-2.6.17.11/grsecurity/grsec_disabled.c
15688 --- linux-2.6.17.11/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
15689 +++ linux-2.6.17.11/grsecurity/grsec_disabled.c 2006-09-01 16:20:28.000000000 -0400
15690 @@ -0,0 +1,418 @@
15691 +#include <linux/kernel.h>
15692 +#include <linux/module.h>
15693 +#include <linux/config.h>
15694 +#include <linux/sched.h>
15695 +#include <linux/file.h>
15696 +#include <linux/fs.h>
15697 +#include <linux/kdev_t.h>
15698 +#include <linux/net.h>
15699 +#include <linux/in.h>
15700 +#include <linux/ip.h>
15701 +#include <linux/skbuff.h>
15702 +#include <linux/sysctl.h>
15703 +
15704 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
15705 +void
15706 +pax_set_initial_flags(struct linux_binprm *bprm)
15707 +{
15708 +       return;
15709 +}
15710 +#endif
15711 +
15712 +#ifdef CONFIG_SYSCTL
15713 +__u32
15714 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
15715 +{
15716 +       return mode;
15717 +}
15718 +#endif
15719 +
15720 +int
15721 +gr_acl_is_enabled(void)
15722 +{
15723 +       return 0;
15724 +}
15725 +
15726 +int
15727 +gr_handle_rawio(const struct inode *inode)
15728 +{
15729 +       return 0;
15730 +}
15731 +
15732 +void
15733 +gr_acl_handle_psacct(struct task_struct *task, const long code)
15734 +{
15735 +       return;
15736 +}
15737 +
15738 +int
15739 +gr_handle_ptrace(struct task_struct *task, const long request)
15740 +{
15741 +       return 0;
15742 +}
15743 +
15744 +int
15745 +gr_handle_proc_ptrace(struct task_struct *task)
15746 +{
15747 +       return 0;
15748 +}
15749 +
15750 +void
15751 +gr_learn_resource(const struct task_struct *task,
15752 +                 const int res, const unsigned long wanted, const int gt)
15753 +{
15754 +       return;
15755 +}
15756 +
15757 +int
15758 +gr_set_acls(const int type)
15759 +{
15760 +       return 0;
15761 +}
15762 +
15763 +int
15764 +gr_check_hidden_task(const struct task_struct *tsk)
15765 +{
15766 +       return 0;
15767 +}
15768 +
15769 +int
15770 +gr_check_protected_task(const struct task_struct *task)
15771 +{
15772 +       return 0;
15773 +}
15774 +
15775 +void
15776 +gr_copy_label(struct task_struct *tsk)
15777 +{
15778 +       return;
15779 +}
15780 +
15781 +void
15782 +gr_set_pax_flags(struct task_struct *task)
15783 +{
15784 +       return;
15785 +}
15786 +
15787 +int
15788 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
15789 +{
15790 +       return 0;
15791 +}
15792 +
15793 +void
15794 +gr_handle_delete(const ino_t ino, const dev_t dev)
15795 +{
15796 +       return;
15797 +}
15798 +
15799 +void
15800 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
15801 +{
15802 +       return;
15803 +}
15804 +
15805 +void
15806 +gr_handle_crash(struct task_struct *task, const int sig)
15807 +{
15808 +       return;
15809 +}
15810 +
15811 +int
15812 +gr_check_crash_exec(const struct file *filp)
15813 +{
15814 +       return 0;
15815 +}
15816 +
15817 +int
15818 +gr_check_crash_uid(const uid_t uid)
15819 +{
15820 +       return 0;
15821 +}
15822 +
15823 +void
15824 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
15825 +                struct dentry *old_dentry,
15826 +                struct dentry *new_dentry,
15827 +                struct vfsmount *mnt, const __u8 replace)
15828 +{
15829 +       return;
15830 +}
15831 +
15832 +int
15833 +gr_search_socket(const int family, const int type, const int protocol)
15834 +{
15835 +       return 1;
15836 +}
15837 +
15838 +int
15839 +gr_search_connectbind(const int mode, const struct socket *sock,
15840 +                     const struct sockaddr_in *addr)
15841 +{
15842 +       return 1;
15843 +}
15844 +
15845 +int
15846 +gr_task_is_capable(struct task_struct *task, const int cap)
15847 +{
15848 +       return 1;
15849 +}
15850 +
15851 +int
15852 +gr_is_capable_nolog(const int cap)
15853 +{
15854 +       return 1;
15855 +}
15856 +
15857 +void
15858 +gr_handle_alertkill(struct task_struct *task)
15859 +{
15860 +       return;
15861 +}
15862 +
15863 +__u32
15864 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
15865 +{
15866 +       return 1;
15867 +}
15868 +
15869 +__u32
15870 +gr_acl_handle_hidden_file(const struct dentry * dentry,
15871 +                         const struct vfsmount * mnt)
15872 +{
15873 +       return 1;
15874 +}
15875 +
15876 +__u32
15877 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
15878 +                  const int fmode)
15879 +{
15880 +       return 1;
15881 +}
15882 +
15883 +__u32
15884 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
15885 +{
15886 +       return 1;
15887 +}
15888 +
15889 +__u32
15890 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
15891 +{
15892 +       return 1;
15893 +}
15894 +
15895 +int
15896 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
15897 +                  unsigned int *vm_flags)
15898 +{
15899 +       return 1;
15900 +}
15901 +
15902 +__u32
15903 +gr_acl_handle_truncate(const struct dentry * dentry,
15904 +                      const struct vfsmount * mnt)
15905 +{
15906 +       return 1;
15907 +}
15908 +
15909 +__u32
15910 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
15911 +{
15912 +       return 1;
15913 +}
15914 +
15915 +__u32
15916 +gr_acl_handle_access(const struct dentry * dentry,
15917 +                    const struct vfsmount * mnt, const int fmode)
15918 +{
15919 +       return 1;
15920 +}
15921 +
15922 +__u32
15923 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
15924 +                    mode_t mode)
15925 +{
15926 +       return 1;
15927 +}
15928 +
15929 +__u32
15930 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
15931 +                   mode_t mode)
15932 +{
15933 +       return 1;
15934 +}
15935 +
15936 +__u32
15937 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
15938 +{
15939 +       return 1;
15940 +}
15941 +
15942 +void
15943 +grsecurity_init(void)
15944 +{
15945 +       return;
15946 +}
15947 +
15948 +__u32
15949 +gr_acl_handle_mknod(const struct dentry * new_dentry,
15950 +                   const struct dentry * parent_dentry,
15951 +                   const struct vfsmount * parent_mnt,
15952 +                   const int mode)
15953 +{
15954 +       return 1;
15955 +}
15956 +
15957 +__u32
15958 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
15959 +                   const struct dentry * parent_dentry,
15960 +                   const struct vfsmount * parent_mnt)
15961 +{
15962 +       return 1;
15963 +}
15964 +
15965 +__u32
15966 +gr_acl_handle_symlink(const struct dentry * new_dentry,
15967 +                     const struct dentry * parent_dentry,
15968 +                     const struct vfsmount * parent_mnt, const char *from)
15969 +{
15970 +       return 1;
15971 +}
15972 +
15973 +__u32
15974 +gr_acl_handle_link(const struct dentry * new_dentry,
15975 +                  const struct dentry * parent_dentry,
15976 +                  const struct vfsmount * parent_mnt,
15977 +                  const struct dentry * old_dentry,
15978 +                  const struct vfsmount * old_mnt, const char *to)
15979 +{
15980 +       return 1;
15981 +}
15982 +
15983 +int
15984 +gr_acl_handle_rename(const struct dentry *new_dentry,
15985 +                    const struct dentry *parent_dentry,
15986 +                    const struct vfsmount *parent_mnt,
15987 +                    const struct dentry *old_dentry,
15988 +                    const struct inode *old_parent_inode,
15989 +                    const struct vfsmount *old_mnt, const char *newname)
15990 +{
15991 +       return 0;
15992 +}
15993 +
15994 +int
15995 +gr_acl_handle_filldir(const struct file *file, const char *name,
15996 +                     const int namelen, const ino_t ino)
15997 +{
15998 +       return 1;
15999 +}
16000 +
16001 +int
16002 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16003 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
16004 +{
16005 +       return 1;
16006 +}
16007 +
16008 +int
16009 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
16010 +{
16011 +       return 1;
16012 +}
16013 +
16014 +int
16015 +gr_search_accept(const struct socket *sock)
16016 +{
16017 +       return 1;
16018 +}
16019 +
16020 +int
16021 +gr_search_listen(const struct socket *sock)
16022 +{
16023 +       return 1;
16024 +}
16025 +
16026 +int
16027 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
16028 +{
16029 +       return 1;
16030 +}
16031 +
16032 +__u32
16033 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
16034 +{
16035 +       return 1;
16036 +}
16037 +
16038 +__u32
16039 +gr_acl_handle_creat(const struct dentry * dentry,
16040 +                   const struct dentry * p_dentry,
16041 +                   const struct vfsmount * p_mnt, const int fmode,
16042 +                   const int imode)
16043 +{
16044 +       return 1;
16045 +}
16046 +
16047 +void
16048 +gr_acl_handle_exit(void)
16049 +{
16050 +       return;
16051 +}
16052 +
16053 +int
16054 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
16055 +{
16056 +       return 1;
16057 +}
16058 +
16059 +void
16060 +gr_set_role_label(const uid_t uid, const gid_t gid)
16061 +{
16062 +       return;
16063 +}
16064 +
16065 +int
16066 +gr_acl_handle_procpidmem(const struct task_struct *task)
16067 +{
16068 +       return 0;
16069 +}
16070 +
16071 +int
16072 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
16073 +{
16074 +       return 1;
16075 +}
16076 +
16077 +int
16078 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
16079 +{
16080 +       return 1;
16081 +}
16082 +
16083 +void
16084 +gr_set_kernel_label(struct task_struct *task)
16085 +{
16086 +       return;
16087 +}
16088 +
16089 +int
16090 +gr_check_user_change(int real, int effective, int fs)
16091 +{
16092 +       return 0;
16093 +}
16094 +
16095 +int
16096 +gr_check_group_change(int real, int effective, int fs)
16097 +{
16098 +       return 0;
16099 +}
16100 +
16101 +
16102 +EXPORT_SYMBOL(gr_task_is_capable);
16103 +EXPORT_SYMBOL(gr_learn_resource);
16104 +EXPORT_SYMBOL(gr_set_kernel_label);
16105 +#ifdef CONFIG_SECURITY
16106 +EXPORT_SYMBOL(gr_check_user_change);
16107 +EXPORT_SYMBOL(gr_check_group_change);
16108 +#endif
16109 diff -urNp linux-2.6.17.11/grsecurity/grsec_exec.c linux-2.6.17.11/grsecurity/grsec_exec.c
16110 --- linux-2.6.17.11/grsecurity/grsec_exec.c     1969-12-31 19:00:00.000000000 -0500
16111 +++ linux-2.6.17.11/grsecurity/grsec_exec.c     2006-09-01 16:20:28.000000000 -0400
16112 @@ -0,0 +1,88 @@
16113 +#include <linux/kernel.h>
16114 +#include <linux/sched.h>
16115 +#include <linux/file.h>
16116 +#include <linux/binfmts.h>
16117 +#include <linux/smp_lock.h>
16118 +#include <linux/fs.h>
16119 +#include <linux/types.h>
16120 +#include <linux/grdefs.h>
16121 +#include <linux/grinternal.h>
16122 +#include <linux/capability.h>
16123 +
16124 +#include <asm/uaccess.h>
16125 +
16126 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16127 +static char gr_exec_arg_buf[132];
16128 +static DECLARE_MUTEX(gr_exec_arg_sem);
16129 +#endif
16130 +
16131 +int
16132 +gr_handle_nproc(void)
16133 +{
16134 +#ifdef CONFIG_GRKERNSEC_EXECVE
16135 +       if (grsec_enable_execve && current->user &&
16136 +           (atomic_read(&current->user->processes) >
16137 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
16138 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
16139 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
16140 +               return -EAGAIN;
16141 +       }
16142 +#endif
16143 +       return 0;
16144 +}
16145 +
16146 +void
16147 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
16148 +{
16149 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16150 +       char *grarg = gr_exec_arg_buf;
16151 +       unsigned int i, x, execlen = 0;
16152 +       char c;
16153 +
16154 +       if (!((grsec_enable_execlog && grsec_enable_group &&
16155 +              in_group_p(grsec_audit_gid))
16156 +             || (grsec_enable_execlog && !grsec_enable_group)))
16157 +               return;
16158 +
16159 +       down(&gr_exec_arg_sem);
16160 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
16161 +
16162 +       if (unlikely(argv == NULL))
16163 +               goto log;
16164 +
16165 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
16166 +               const char __user *p;
16167 +               unsigned int len;
16168 +
16169 +               if (copy_from_user(&p, argv + i, sizeof(p)))
16170 +                       goto log;
16171 +               if (!p)
16172 +                       goto log;
16173 +               len = strnlen_user(p, 128 - execlen);
16174 +               if (len > 128 - execlen)
16175 +                       len = 128 - execlen;
16176 +               else if (len > 0)
16177 +                       len--;
16178 +               if (copy_from_user(grarg + execlen, p, len))
16179 +                       goto log;
16180 +
16181 +               /* rewrite unprintable characters */
16182 +               for (x = 0; x < len; x++) {
16183 +                       c = *(grarg + execlen + x);
16184 +                       if (c < 32 || c > 126)
16185 +                               *(grarg + execlen + x) = ' ';
16186 +               }
16187 +
16188 +               execlen += len;
16189 +               *(grarg + execlen) = ' ';
16190 +               *(grarg + execlen + 1) = '\0';
16191 +               execlen++;
16192 +       }
16193 +
16194 +      log:
16195 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
16196 +                       bprm->file->f_vfsmnt, grarg);
16197 +       up(&gr_exec_arg_sem);
16198 +#endif
16199 +       return;
16200 +}
16201 diff -urNp linux-2.6.17.11/grsecurity/grsec_fifo.c linux-2.6.17.11/grsecurity/grsec_fifo.c
16202 --- linux-2.6.17.11/grsecurity/grsec_fifo.c     1969-12-31 19:00:00.000000000 -0500
16203 +++ linux-2.6.17.11/grsecurity/grsec_fifo.c     2006-09-01 16:20:28.000000000 -0400
16204 @@ -0,0 +1,22 @@
16205 +#include <linux/kernel.h>
16206 +#include <linux/sched.h>
16207 +#include <linux/fs.h>
16208 +#include <linux/file.h>
16209 +#include <linux/grinternal.h>
16210 +
16211 +int
16212 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
16213 +              const struct dentry *dir, const int flag, const int acc_mode)
16214 +{
16215 +#ifdef CONFIG_GRKERNSEC_FIFO
16216 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
16217 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
16218 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
16219 +           (current->fsuid != dentry->d_inode->i_uid)) {
16220 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
16221 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
16222 +               return -EACCES;
16223 +       }
16224 +#endif
16225 +       return 0;
16226 +}
16227 diff -urNp linux-2.6.17.11/grsecurity/grsec_fork.c linux-2.6.17.11/grsecurity/grsec_fork.c
16228 --- linux-2.6.17.11/grsecurity/grsec_fork.c     1969-12-31 19:00:00.000000000 -0500
16229 +++ linux-2.6.17.11/grsecurity/grsec_fork.c     2006-09-01 16:20:28.000000000 -0400
16230 @@ -0,0 +1,15 @@
16231 +#include <linux/kernel.h>
16232 +#include <linux/sched.h>
16233 +#include <linux/grsecurity.h>
16234 +#include <linux/grinternal.h>
16235 +#include <linux/errno.h>
16236 +
16237 +void
16238 +gr_log_forkfail(const int retval)
16239 +{
16240 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
16241 +       if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
16242 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
16243 +#endif
16244 +       return;
16245 +}
16246 diff -urNp linux-2.6.17.11/grsecurity/grsec_init.c linux-2.6.17.11/grsecurity/grsec_init.c
16247 --- linux-2.6.17.11/grsecurity/grsec_init.c     1969-12-31 19:00:00.000000000 -0500
16248 +++ linux-2.6.17.11/grsecurity/grsec_init.c     2006-09-01 16:20:28.000000000 -0400
16249 @@ -0,0 +1,236 @@
16250 +#include <linux/kernel.h>
16251 +#include <linux/sched.h>
16252 +#include <linux/mm.h>
16253 +#include <linux/smp_lock.h>
16254 +#include <linux/gracl.h>
16255 +#include <linux/slab.h>
16256 +#include <linux/vmalloc.h>
16257 +#include <linux/percpu.h>
16258 +
16259 +int grsec_enable_shm;
16260 +int grsec_enable_link;
16261 +int grsec_enable_dmesg;
16262 +int grsec_enable_fifo;
16263 +int grsec_enable_execve;
16264 +int grsec_enable_execlog;
16265 +int grsec_enable_signal;
16266 +int grsec_enable_forkfail;
16267 +int grsec_enable_time;
16268 +int grsec_enable_audit_textrel;
16269 +int grsec_enable_group;
16270 +int grsec_audit_gid;
16271 +int grsec_enable_chdir;
16272 +int grsec_enable_audit_ipc;
16273 +int grsec_enable_mount;
16274 +int grsec_enable_chroot_findtask;
16275 +int grsec_enable_chroot_mount;
16276 +int grsec_enable_chroot_shmat;
16277 +int grsec_enable_chroot_fchdir;
16278 +int grsec_enable_chroot_double;
16279 +int grsec_enable_chroot_pivot;
16280 +int grsec_enable_chroot_chdir;
16281 +int grsec_enable_chroot_chmod;
16282 +int grsec_enable_chroot_mknod;
16283 +int grsec_enable_chroot_nice;
16284 +int grsec_enable_chroot_execlog;
16285 +int grsec_enable_chroot_caps;
16286 +int grsec_enable_chroot_sysctl;
16287 +int grsec_enable_chroot_unix;
16288 +int grsec_enable_tpe;
16289 +int grsec_tpe_gid;
16290 +int grsec_enable_tpe_all;
16291 +int grsec_enable_randpid;
16292 +int grsec_enable_socket_all;
16293 +int grsec_socket_all_gid;
16294 +int grsec_enable_socket_client;
16295 +int grsec_socket_client_gid;
16296 +int grsec_enable_socket_server;
16297 +int grsec_socket_server_gid;
16298 +int grsec_resource_logging;
16299 +int grsec_lock;
16300 +
16301 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
16302 +unsigned long grsec_alert_wtime = 0;
16303 +unsigned long grsec_alert_fyet = 0;
16304 +
16305 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
16306 +
16307 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
16308 +
16309 +char *gr_shared_page[4];
16310 +
16311 +char *gr_alert_log_fmt;
16312 +char *gr_audit_log_fmt;
16313 +char *gr_alert_log_buf;
16314 +char *gr_audit_log_buf;
16315 +
16316 +extern struct gr_arg *gr_usermode;
16317 +extern unsigned char *gr_system_salt;
16318 +extern unsigned char *gr_system_sum;
16319 +
16320 +void
16321 +grsecurity_init(void)
16322 +{
16323 +       int j;
16324 +       /* create the per-cpu shared pages */
16325 +
16326 +       preempt_disable();
16327 +       for (j = 0; j < 4; j++) {
16328 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
16329 +               if (gr_shared_page[j] == NULL) {
16330 +                       panic("Unable to allocate grsecurity shared page");
16331 +                       return;
16332 +               }
16333 +       }
16334 +       preempt_enable();
16335 +
16336 +       /* allocate log buffers */
16337 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
16338 +       if (!gr_alert_log_fmt) {
16339 +               panic("Unable to allocate grsecurity alert log format buffer");
16340 +               return;
16341 +       }
16342 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
16343 +       if (!gr_audit_log_fmt) {
16344 +               panic("Unable to allocate grsecurity audit log format buffer");
16345 +               return;
16346 +       }
16347 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
16348 +       if (!gr_alert_log_buf) {
16349 +               panic("Unable to allocate grsecurity alert log buffer");
16350 +               return;
16351 +       }
16352 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
16353 +       if (!gr_audit_log_buf) {
16354 +               panic("Unable to allocate grsecurity audit log buffer");
16355 +               return;
16356 +       }
16357 +
16358 +       /* allocate memory for authentication structure */
16359 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
16360 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
16361 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
16362 +
16363 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
16364 +               panic("Unable to allocate grsecurity authentication structure");
16365 +               return;
16366 +       }
16367 +
16368 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
16369 +#ifndef CONFIG_GRKERNSEC_SYSCTL
16370 +       grsec_lock = 1;
16371 +#endif
16372 +#ifdef CONFIG_GRKERNSEC_SHM
16373 +       grsec_enable_shm = 1;
16374 +#endif
16375 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
16376 +       grsec_enable_audit_textrel = 1;
16377 +#endif
16378 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
16379 +       grsec_enable_group = 1;
16380 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
16381 +#endif
16382 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16383 +       grsec_enable_chdir = 1;
16384 +#endif
16385 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16386 +       grsec_enable_audit_ipc = 1;
16387 +#endif
16388 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16389 +       grsec_enable_mount = 1;
16390 +#endif
16391 +#ifdef CONFIG_GRKERNSEC_LINK
16392 +       grsec_enable_link = 1;
16393 +#endif
16394 +#ifdef CONFIG_GRKERNSEC_DMESG
16395 +       grsec_enable_dmesg = 1;
16396 +#endif
16397 +#ifdef CONFIG_GRKERNSEC_FIFO
16398 +       grsec_enable_fifo = 1;
16399 +#endif
16400 +#ifdef CONFIG_GRKERNSEC_EXECVE
16401 +       grsec_enable_execve = 1;
16402 +#endif
16403 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16404 +       grsec_enable_execlog = 1;
16405 +#endif
16406 +#ifdef CONFIG_GRKERNSEC_SIGNAL
16407 +       grsec_enable_signal = 1;
16408 +#endif
16409 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
16410 +       grsec_enable_forkfail = 1;
16411 +#endif
16412 +#ifdef CONFIG_GRKERNSEC_TIME
16413 +       grsec_enable_time = 1;
16414 +#endif
16415 +#ifdef CONFIG_GRKERNSEC_RESLOG
16416 +       grsec_resource_logging = 1;
16417 +#endif
16418 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16419 +       grsec_enable_chroot_findtask = 1;
16420 +#endif
16421 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16422 +       grsec_enable_chroot_unix = 1;
16423 +#endif
16424 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16425 +       grsec_enable_chroot_mount = 1;
16426 +#endif
16427 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16428 +       grsec_enable_chroot_fchdir = 1;
16429 +#endif
16430 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16431 +       grsec_enable_chroot_shmat = 1;
16432 +#endif
16433 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
16434 +       grsec_enable_chroot_double = 1;
16435 +#endif
16436 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16437 +       grsec_enable_chroot_pivot = 1;
16438 +#endif
16439 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
16440 +       grsec_enable_chroot_chdir = 1;
16441 +#endif
16442 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
16443 +       grsec_enable_chroot_chmod = 1;
16444 +#endif
16445 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16446 +       grsec_enable_chroot_mknod = 1;
16447 +#endif
16448 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16449 +       grsec_enable_chroot_nice = 1;
16450 +#endif
16451 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16452 +       grsec_enable_chroot_execlog = 1;
16453 +#endif
16454 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16455 +       grsec_enable_chroot_caps = 1;
16456 +#endif
16457 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
16458 +       grsec_enable_chroot_sysctl = 1;
16459 +#endif
16460 +#ifdef CONFIG_GRKERNSEC_TPE
16461 +       grsec_enable_tpe = 1;
16462 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
16463 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
16464 +       grsec_enable_tpe_all = 1;
16465 +#endif
16466 +#endif
16467 +#ifdef CONFIG_GRKERNSEC_RANDPID
16468 +       grsec_enable_randpid = 1;
16469 +#endif
16470 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
16471 +       grsec_enable_socket_all = 1;
16472 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
16473 +#endif
16474 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
16475 +       grsec_enable_socket_client = 1;
16476 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
16477 +#endif
16478 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
16479 +       grsec_enable_socket_server = 1;
16480 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
16481 +#endif
16482 +#endif
16483 +
16484 +       return;
16485 +}
16486 diff -urNp linux-2.6.17.11/grsecurity/grsec_ipc.c linux-2.6.17.11/grsecurity/grsec_ipc.c
16487 --- linux-2.6.17.11/grsecurity/grsec_ipc.c      1969-12-31 19:00:00.000000000 -0500
16488 +++ linux-2.6.17.11/grsecurity/grsec_ipc.c      2006-09-01 16:20:28.000000000 -0400
16489 @@ -0,0 +1,81 @@
16490 +#include <linux/kernel.h>
16491 +#include <linux/sched.h>
16492 +#include <linux/types.h>
16493 +#include <linux/ipc.h>
16494 +#include <linux/grsecurity.h>
16495 +#include <linux/grinternal.h>
16496 +
16497 +void
16498 +gr_log_msgget(const int ret, const int msgflg)
16499 +{
16500 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16501 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
16502 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
16503 +                                         !grsec_enable_group)) && (ret >= 0)
16504 +           && (msgflg & IPC_CREAT))
16505 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
16506 +#endif
16507 +       return;
16508 +}
16509 +
16510 +void
16511 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
16512 +{
16513 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16514 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
16515 +            grsec_enable_audit_ipc) ||
16516 +           (grsec_enable_audit_ipc && !grsec_enable_group))
16517 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
16518 +#endif
16519 +       return;
16520 +}
16521 +
16522 +void
16523 +gr_log_semget(const int err, const int semflg)
16524 +{
16525 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16526 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
16527 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
16528 +                                         !grsec_enable_group)) && (err >= 0)
16529 +           && (semflg & IPC_CREAT))
16530 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
16531 +#endif
16532 +       return;
16533 +}
16534 +
16535 +void
16536 +gr_log_semrm(const uid_t uid, const uid_t cuid)
16537 +{
16538 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16539 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
16540 +            grsec_enable_audit_ipc) ||
16541 +           (grsec_enable_audit_ipc && !grsec_enable_group))
16542 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
16543 +#endif
16544 +       return;
16545 +}
16546 +
16547 +void
16548 +gr_log_shmget(const int err, const int shmflg, const size_t size)
16549 +{
16550 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16551 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
16552 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
16553 +                                         !grsec_enable_group)) && (err >= 0)
16554 +           && (shmflg & IPC_CREAT))
16555 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
16556 +#endif
16557 +       return;
16558 +}
16559 +
16560 +void
16561 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
16562 +{
16563 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16564 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
16565 +            grsec_enable_audit_ipc) ||
16566 +           (grsec_enable_audit_ipc && !grsec_enable_group))
16567 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
16568 +#endif
16569 +       return;
16570 +}
16571 diff -urNp linux-2.6.17.11/grsecurity/grsec_link.c linux-2.6.17.11/grsecurity/grsec_link.c
16572 --- linux-2.6.17.11/grsecurity/grsec_link.c     1969-12-31 19:00:00.000000000 -0500
16573 +++ linux-2.6.17.11/grsecurity/grsec_link.c     2006-09-01 16:20:28.000000000 -0400
16574 @@ -0,0 +1,39 @@
16575 +#include <linux/kernel.h>
16576 +#include <linux/sched.h>
16577 +#include <linux/fs.h>
16578 +#include <linux/file.h>
16579 +#include <linux/grinternal.h>
16580 +
16581 +int
16582 +gr_handle_follow_link(const struct inode *parent,
16583 +                     const struct inode *inode,
16584 +                     const struct dentry *dentry, const struct vfsmount *mnt)
16585 +{
16586 +#ifdef CONFIG_GRKERNSEC_LINK
16587 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
16588 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
16589 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
16590 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
16591 +               return -EACCES;
16592 +       }
16593 +#endif
16594 +       return 0;
16595 +}
16596 +
16597 +int
16598 +gr_handle_hardlink(const struct dentry *dentry,
16599 +                  const struct vfsmount *mnt,
16600 +                  struct inode *inode, const int mode, const char *to)
16601 +{
16602 +#ifdef CONFIG_GRKERNSEC_LINK
16603 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
16604 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
16605 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
16606 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
16607 +           !capable(CAP_FOWNER) && current->uid) {
16608 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
16609 +               return -EPERM;
16610 +       }
16611 +#endif
16612 +       return 0;
16613 +}
16614 diff -urNp linux-2.6.17.11/grsecurity/grsec_log.c linux-2.6.17.11/grsecurity/grsec_log.c
16615 --- linux-2.6.17.11/grsecurity/grsec_log.c      1969-12-31 19:00:00.000000000 -0500
16616 +++ linux-2.6.17.11/grsecurity/grsec_log.c      2006-09-01 16:20:28.000000000 -0400
16617 @@ -0,0 +1,265 @@
16618 +#include <linux/kernel.h>
16619 +#include <linux/sched.h>
16620 +#include <linux/file.h>
16621 +#include <linux/tty.h>
16622 +#include <linux/fs.h>
16623 +#include <linux/grinternal.h>
16624 +
16625 +#define BEGIN_LOCKS(x) \
16626 +       read_lock(&tasklist_lock); \
16627 +       read_lock(&grsec_exec_file_lock); \
16628 +       if (x != GR_DO_AUDIT) \
16629 +               spin_lock(&grsec_alert_lock); \
16630 +       else \
16631 +               spin_lock(&grsec_audit_lock)
16632 +
16633 +#define END_LOCKS(x) \
16634 +       if (x != GR_DO_AUDIT) \
16635 +               spin_unlock(&grsec_alert_lock); \
16636 +       else \
16637 +               spin_unlock(&grsec_audit_lock); \
16638 +       read_unlock(&grsec_exec_file_lock); \
16639 +       read_unlock(&tasklist_lock); \
16640 +       if (x == GR_DONT_AUDIT) \
16641 +               gr_handle_alertkill(current)
16642 +
16643 +enum {
16644 +       FLOODING,
16645 +       NO_FLOODING
16646 +};
16647 +
16648 +extern char *gr_alert_log_fmt;
16649 +extern char *gr_audit_log_fmt;
16650 +extern char *gr_alert_log_buf;
16651 +extern char *gr_audit_log_buf;
16652 +
16653 +static int gr_log_start(int audit)
16654 +{
16655 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
16656 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
16657 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
16658 +
16659 +       if (audit == GR_DO_AUDIT)
16660 +               goto set_fmt;
16661 +
16662 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
16663 +               grsec_alert_wtime = jiffies;
16664 +               grsec_alert_fyet = 0;
16665 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
16666 +               grsec_alert_fyet++;
16667 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
16668 +               grsec_alert_wtime = jiffies;
16669 +               grsec_alert_fyet++;
16670 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
16671 +               return FLOODING;
16672 +       } else return FLOODING;
16673 +
16674 +set_fmt:
16675 +       memset(buf, 0, PAGE_SIZE);
16676 +       if (current->signal->curr_ip && gr_acl_is_enabled()) {
16677 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
16678 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
16679 +       } else if (current->signal->curr_ip) {
16680 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
16681 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
16682 +       } else if (gr_acl_is_enabled()) {
16683 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
16684 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
16685 +       } else {
16686 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
16687 +               strcpy(buf, fmt);
16688 +       }
16689 +
16690 +       return NO_FLOODING;
16691 +}
16692 +
16693 +static void gr_log_middle(int audit, const char *msg, va_list ap)
16694 +{
16695 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
16696 +       unsigned int len = strlen(buf);
16697 +
16698 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
16699 +
16700 +       return;
16701 +}
16702 +
16703 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
16704 +{
16705 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
16706 +       unsigned int len = strlen(buf);
16707 +       va_list ap;
16708 +
16709 +       va_start(ap, msg);
16710 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
16711 +       va_end(ap);
16712 +
16713 +       return;
16714 +}
16715 +
16716 +static void gr_log_end(int audit)
16717 +{
16718 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
16719 +       unsigned int len = strlen(buf);
16720 +
16721 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
16722 +       printk("%s\n", buf);
16723 +
16724 +       return;
16725 +}
16726 +
16727 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
16728 +{
16729 +       int logtype;
16730 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
16731 +       char *str1, *str2, *str3;
16732 +       int num1, num2;
16733 +       unsigned long ulong1, ulong2;
16734 +       struct dentry *dentry;
16735 +       struct vfsmount *mnt;
16736 +       struct file *file;
16737 +       struct task_struct *task;
16738 +       va_list ap;
16739 +
16740 +       BEGIN_LOCKS(audit);
16741 +       logtype = gr_log_start(audit);
16742 +       if (logtype == FLOODING) {
16743 +               END_LOCKS(audit);
16744 +               return;
16745 +       }
16746 +       va_start(ap, argtypes);
16747 +       switch (argtypes) {
16748 +       case GR_TTYSNIFF:
16749 +               task = va_arg(ap, struct task_struct *);
16750 +               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);
16751 +               break;
16752 +       case GR_RBAC:
16753 +               dentry = va_arg(ap, struct dentry *);
16754 +               mnt = va_arg(ap, struct vfsmount *);
16755 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
16756 +               break;
16757 +       case GR_RBAC_STR:
16758 +               dentry = va_arg(ap, struct dentry *);
16759 +               mnt = va_arg(ap, struct vfsmount *);
16760 +               str1 = va_arg(ap, char *);
16761 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
16762 +               break;
16763 +       case GR_STR_RBAC:
16764 +               str1 = va_arg(ap, char *);
16765 +               dentry = va_arg(ap, struct dentry *);
16766 +               mnt = va_arg(ap, struct vfsmount *);
16767 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
16768 +               break;
16769 +       case GR_RBAC_MODE2:
16770 +               dentry = va_arg(ap, struct dentry *);
16771 +               mnt = va_arg(ap, struct vfsmount *);
16772 +               str1 = va_arg(ap, char *);
16773 +               str2 = va_arg(ap, char *);
16774 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
16775 +               break;
16776 +       case GR_RBAC_MODE3:
16777 +               dentry = va_arg(ap, struct dentry *);
16778 +               mnt = va_arg(ap, struct vfsmount *);
16779 +               str1 = va_arg(ap, char *);
16780 +               str2 = va_arg(ap, char *);
16781 +               str3 = va_arg(ap, char *);
16782 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
16783 +               break;
16784 +       case GR_FILENAME:
16785 +               dentry = va_arg(ap, struct dentry *);
16786 +               mnt = va_arg(ap, struct vfsmount *);
16787 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
16788 +               break;
16789 +       case GR_STR_FILENAME:
16790 +               str1 = va_arg(ap, char *);
16791 +               dentry = va_arg(ap, struct dentry *);
16792 +               mnt = va_arg(ap, struct vfsmount *);
16793 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
16794 +               break;
16795 +       case GR_FILENAME_STR:
16796 +               dentry = va_arg(ap, struct dentry *);
16797 +               mnt = va_arg(ap, struct vfsmount *);
16798 +               str1 = va_arg(ap, char *);
16799 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
16800 +               break;
16801 +       case GR_FILENAME_TWO_INT:
16802 +               dentry = va_arg(ap, struct dentry *);
16803 +               mnt = va_arg(ap, struct vfsmount *);
16804 +               num1 = va_arg(ap, int);
16805 +               num2 = va_arg(ap, int);
16806 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
16807 +               break;
16808 +       case GR_FILENAME_TWO_INT_STR:
16809 +               dentry = va_arg(ap, struct dentry *);
16810 +               mnt = va_arg(ap, struct vfsmount *);
16811 +               num1 = va_arg(ap, int);
16812 +               num2 = va_arg(ap, int);
16813 +               str1 = va_arg(ap, char *);
16814 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
16815 +               break;
16816 +       case GR_TEXTREL:
16817 +               file = va_arg(ap, struct file *);
16818 +               ulong1 = va_arg(ap, unsigned long);
16819 +               ulong2 = va_arg(ap, unsigned long);
16820 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
16821 +               break;
16822 +       case GR_PTRACE:
16823 +               task = va_arg(ap, struct task_struct *);
16824 +               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);
16825 +               break;
16826 +       case GR_RESOURCE:
16827 +               task = va_arg(ap, struct task_struct *);
16828 +               ulong1 = va_arg(ap, unsigned long);
16829 +               str1 = va_arg(ap, char *);
16830 +               ulong2 = va_arg(ap, unsigned long);
16831 +               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);
16832 +               break;
16833 +       case GR_CAP:
16834 +               task = va_arg(ap, struct task_struct *);
16835 +               str1 = va_arg(ap, char *);
16836 +               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);
16837 +               break;
16838 +       case GR_SIG:
16839 +               task = va_arg(ap, struct task_struct *);
16840 +               num1 = va_arg(ap, int);
16841 +               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);
16842 +               break;
16843 +       case GR_CRASH1:
16844 +               task = va_arg(ap, struct task_struct *);
16845 +               ulong1 = va_arg(ap, unsigned long);
16846 +               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);
16847 +               break;
16848 +       case GR_CRASH2:
16849 +               task = va_arg(ap, struct task_struct *);
16850 +               ulong1 = va_arg(ap, unsigned long);
16851 +               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);
16852 +               break;
16853 +       case GR_PSACCT:
16854 +               {
16855 +                       unsigned int wday, cday;
16856 +                       __u8 whr, chr;
16857 +                       __u8 wmin, cmin;
16858 +                       __u8 wsec, csec;
16859 +                       char cur_tty[64] = { 0 };
16860 +                       char parent_tty[64] = { 0 };
16861 +
16862 +                       task = va_arg(ap, struct task_struct *);
16863 +                       wday = va_arg(ap, unsigned int);
16864 +                       cday = va_arg(ap, unsigned int);
16865 +                       whr = va_arg(ap, int);
16866 +                       chr = va_arg(ap, int);
16867 +                       wmin = va_arg(ap, int);
16868 +                       cmin = va_arg(ap, int);
16869 +                       wsec = va_arg(ap, int);
16870 +                       csec = va_arg(ap, int);
16871 +                       ulong1 = va_arg(ap, unsigned long);
16872 +
16873 +                       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);
16874 +               }
16875 +               break;
16876 +       default:
16877 +               gr_log_middle(audit, msg, ap);
16878 +       }
16879 +       va_end(ap);
16880 +       gr_log_end(audit);
16881 +       END_LOCKS(audit);
16882 +}
16883 diff -urNp linux-2.6.17.11/grsecurity/grsec_mem.c linux-2.6.17.11/grsecurity/grsec_mem.c
16884 --- linux-2.6.17.11/grsecurity/grsec_mem.c      1969-12-31 19:00:00.000000000 -0500
16885 +++ linux-2.6.17.11/grsecurity/grsec_mem.c      2006-09-01 16:20:28.000000000 -0400
16886 @@ -0,0 +1,71 @@
16887 +#include <linux/kernel.h>
16888 +#include <linux/sched.h>
16889 +#include <linux/mm.h>
16890 +#include <linux/mman.h>
16891 +#include <linux/grinternal.h>
16892 +
16893 +void
16894 +gr_handle_ioperm(void)
16895 +{
16896 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
16897 +       return;
16898 +}
16899 +
16900 +void
16901 +gr_handle_iopl(void)
16902 +{
16903 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
16904 +       return;
16905 +}
16906 +
16907 +void
16908 +gr_handle_mem_write(void)
16909 +{
16910 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
16911 +       return;
16912 +}
16913 +
16914 +void
16915 +gr_handle_kmem_write(void)
16916 +{
16917 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
16918 +       return;
16919 +}
16920 +
16921 +void
16922 +gr_handle_open_port(void)
16923 +{
16924 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
16925 +       return;
16926 +}
16927 +
16928 +int
16929 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
16930 +{
16931 +       unsigned long start, end;
16932 +
16933 +       start = offset;
16934 +       end = start + vma->vm_end - vma->vm_start;
16935 +
16936 +       if (start > end) {
16937 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
16938 +               return -EPERM;
16939 +       }
16940 +
16941 +       /* allowed ranges : ISA I/O BIOS */
16942 +       if ((start >= __pa(high_memory))
16943 +#ifdef CONFIG_X86
16944 +           || (start >= 0x000a0000 && end <= 0x00100000)
16945 +           || (start >= 0x00000000 && end <= 0x00001000)
16946 +#endif
16947 +       )
16948 +               return 0;
16949 +
16950 +       if (vma->vm_flags & VM_WRITE) {
16951 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
16952 +               return -EPERM;
16953 +       } else
16954 +               vma->vm_flags &= ~VM_MAYWRITE;
16955 +
16956 +       return 0;
16957 +}
16958 diff -urNp linux-2.6.17.11/grsecurity/grsec_mount.c linux-2.6.17.11/grsecurity/grsec_mount.c
16959 --- linux-2.6.17.11/grsecurity/grsec_mount.c    1969-12-31 19:00:00.000000000 -0500
16960 +++ linux-2.6.17.11/grsecurity/grsec_mount.c    2006-09-01 16:20:28.000000000 -0400
16961 @@ -0,0 +1,34 @@
16962 +#include <linux/kernel.h>
16963 +#include <linux/sched.h>
16964 +#include <linux/grsecurity.h>
16965 +#include <linux/grinternal.h>
16966 +
16967 +void
16968 +gr_log_remount(const char *devname, const int retval)
16969 +{
16970 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16971 +       if (grsec_enable_mount && (retval >= 0))
16972 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
16973 +#endif
16974 +       return;
16975 +}
16976 +
16977 +void
16978 +gr_log_unmount(const char *devname, const int retval)
16979 +{
16980 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16981 +       if (grsec_enable_mount && (retval >= 0))
16982 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
16983 +#endif
16984 +       return;
16985 +}
16986 +
16987 +void
16988 +gr_log_mount(const char *from, const char *to, const int retval)
16989 +{
16990 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16991 +       if (grsec_enable_mount && (retval >= 0))
16992 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
16993 +#endif
16994 +       return;
16995 +}
16996 diff -urNp linux-2.6.17.11/grsecurity/grsec_rand.c linux-2.6.17.11/grsecurity/grsec_rand.c
16997 --- linux-2.6.17.11/grsecurity/grsec_rand.c     1969-12-31 19:00:00.000000000 -0500
16998 +++ linux-2.6.17.11/grsecurity/grsec_rand.c     2006-09-01 16:20:28.000000000 -0400
16999 @@ -0,0 +1,26 @@
17000 +#include <linux/kernel.h>
17001 +#include <linux/sched.h>
17002 +#include <linux/smp_lock.h>
17003 +#include <linux/grsecurity.h>
17004 +#include <linux/grinternal.h>
17005 +
17006 +extern int pid_max;
17007 +
17008 +int
17009 +gr_random_pid(void)
17010 +{
17011 +#ifdef CONFIG_GRKERNSEC_RANDPID
17012 +       int pid;
17013 +
17014 +       if (grsec_enable_randpid && current->fs->root) {
17015 +               /* return a pid in the range 1 ... pid_max - 1
17016 +                  optimize this so we don't have to do a real division
17017 +               */
17018 +               pid = 1 + (get_random_long() % pid_max);
17019 +               if (pid == pid_max)
17020 +                       pid = pid_max - 1;
17021 +               return pid;
17022 +       }
17023 +#endif
17024 +       return 0;
17025 +}
17026 diff -urNp linux-2.6.17.11/grsecurity/grsec_sig.c linux-2.6.17.11/grsecurity/grsec_sig.c
17027 --- linux-2.6.17.11/grsecurity/grsec_sig.c      1969-12-31 19:00:00.000000000 -0500
17028 +++ linux-2.6.17.11/grsecurity/grsec_sig.c      2006-09-01 16:20:28.000000000 -0400
17029 @@ -0,0 +1,59 @@
17030 +#include <linux/kernel.h>
17031 +#include <linux/sched.h>
17032 +#include <linux/grsecurity.h>
17033 +#include <linux/grinternal.h>
17034 +
17035 +void
17036 +gr_log_signal(const int sig, const struct task_struct *t)
17037 +{
17038 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17039 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
17040 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
17041 +               if (t->pid == current->pid) {
17042 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
17043 +               } else {
17044 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
17045 +               }
17046 +       }
17047 +#endif
17048 +       return;
17049 +}
17050 +
17051 +int
17052 +gr_handle_signal(const struct task_struct *p, const int sig)
17053 +{
17054 +#ifdef CONFIG_GRKERNSEC
17055 +       if (current->pid > 1 && gr_check_protected_task(p)) {
17056 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
17057 +               return -EPERM;
17058 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
17059 +               return -EPERM;
17060 +       }
17061 +#endif
17062 +       return 0;
17063 +}
17064 +
17065 +void gr_handle_brute_attach(struct task_struct *p)
17066 +{
17067 +#ifdef CONFIG_GRKERNSEC_BRUTE
17068 +       read_lock(&tasklist_lock);
17069 +       read_lock(&grsec_exec_file_lock);
17070 +       if (p->parent && p->parent->exec_file == p->exec_file)
17071 +               p->parent->brute = 1;
17072 +       read_unlock(&grsec_exec_file_lock);
17073 +       read_unlock(&tasklist_lock);
17074 +#endif
17075 +       return;
17076 +}
17077 +
17078 +void gr_handle_brute_check(void)
17079 +{
17080 +#ifdef CONFIG_GRKERNSEC_BRUTE
17081 +       if (current->brute) {
17082 +               set_current_state(TASK_UNINTERRUPTIBLE);
17083 +               schedule_timeout(30 * HZ);
17084 +       }
17085 +#endif
17086 +       return;
17087 +}
17088 +
17089 diff -urNp linux-2.6.17.11/grsecurity/grsec_sock.c linux-2.6.17.11/grsecurity/grsec_sock.c
17090 --- linux-2.6.17.11/grsecurity/grsec_sock.c     1969-12-31 19:00:00.000000000 -0500
17091 +++ linux-2.6.17.11/grsecurity/grsec_sock.c     2006-09-01 16:20:28.000000000 -0400
17092 @@ -0,0 +1,263 @@
17093 +#include <linux/kernel.h>
17094 +#include <linux/module.h>
17095 +#include <linux/sched.h>
17096 +#include <linux/file.h>
17097 +#include <linux/net.h>
17098 +#include <linux/in.h>
17099 +#include <linux/ip.h>
17100 +#include <net/sock.h>
17101 +#include <net/inet_sock.h>
17102 +#include <linux/grsecurity.h>
17103 +#include <linux/grinternal.h>
17104 +#include <linux/gracl.h>
17105 +
17106 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
17107 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
17108 +EXPORT_SYMBOL(udp_v4_lookup);
17109 +#endif
17110 +
17111 +EXPORT_SYMBOL(gr_cap_rtnetlink);
17112 +
17113 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
17114 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
17115 +
17116 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
17117 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
17118 +
17119 +#ifdef CONFIG_UNIX_MODULE
17120 +EXPORT_SYMBOL(gr_acl_handle_unix);
17121 +EXPORT_SYMBOL(gr_acl_handle_mknod);
17122 +EXPORT_SYMBOL(gr_handle_chroot_unix);
17123 +EXPORT_SYMBOL(gr_handle_create);
17124 +#endif
17125 +
17126 +#ifdef CONFIG_GRKERNSEC
17127 +#define gr_conn_table_size 32749
17128 +struct conn_table_entry {
17129 +       struct conn_table_entry *next;
17130 +       struct signal_struct *sig;
17131 +};
17132 +
17133 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
17134 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
17135 +
17136 +extern const char * gr_socktype_to_name(unsigned char type);
17137 +extern const char * gr_proto_to_name(unsigned char proto);
17138 +
17139 +static __inline__ int 
17140 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
17141 +{
17142 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
17143 +}
17144 +
17145 +static __inline__ int
17146 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, 
17147 +          __u16 sport, __u16 dport)
17148 +{
17149 +       if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
17150 +                    sig->gr_sport == sport && sig->gr_dport == dport))
17151 +               return 1;
17152 +       else
17153 +               return 0;
17154 +}
17155 +
17156 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
17157 +{
17158 +       struct conn_table_entry **match;
17159 +       unsigned int index;
17160 +
17161 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
17162 +                         sig->gr_sport, sig->gr_dport, 
17163 +                         gr_conn_table_size);
17164 +
17165 +       newent->sig = sig;
17166 +       
17167 +       match = &gr_conn_table[index];
17168 +       newent->next = *match;
17169 +       *match = newent;
17170 +
17171 +       return;
17172 +}
17173 +
17174 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
17175 +{
17176 +       struct conn_table_entry *match, *last = NULL;
17177 +       unsigned int index;
17178 +
17179 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
17180 +                         sig->gr_sport, sig->gr_dport, 
17181 +                         gr_conn_table_size);
17182 +
17183 +       match = gr_conn_table[index];
17184 +       while (match && !conn_match(match->sig, 
17185 +               sig->gr_saddr, sig->gr_daddr, sig->gr_sport, 
17186 +               sig->gr_dport)) {
17187 +               last = match;
17188 +               match = match->next;
17189 +       }
17190 +
17191 +       if (match) {
17192 +               if (last)
17193 +                       last->next = match->next;
17194 +               else
17195 +                       gr_conn_table[index] = NULL;
17196 +               kfree(match);
17197 +       }
17198 +
17199 +       return;
17200 +}
17201 +
17202 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
17203 +                                            __u16 sport, __u16 dport)
17204 +{
17205 +       struct conn_table_entry *match;
17206 +       unsigned int index;
17207 +
17208 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
17209 +
17210 +       match = gr_conn_table[index];
17211 +       while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
17212 +               match = match->next;
17213 +
17214 +       if (match)
17215 +               return match->sig;
17216 +       else
17217 +               return NULL;
17218 +}
17219 +
17220 +#endif
17221 +
17222 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
17223 +{
17224 +#ifdef CONFIG_GRKERNSEC
17225 +       struct signal_struct *sig = task->signal;
17226 +       struct conn_table_entry *newent;
17227 +
17228 +       newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
17229 +       if (newent == NULL)
17230 +               return;
17231 +       /* no bh lock needed since we are called with bh disabled */
17232 +       spin_lock(&gr_conn_table_lock);
17233 +       gr_del_task_from_ip_table_nolock(sig);
17234 +       sig->gr_saddr = inet->rcv_saddr;
17235 +       sig->gr_daddr = inet->daddr;
17236 +       sig->gr_sport = inet->sport;
17237 +       sig->gr_dport = inet->dport;
17238 +       gr_add_to_task_ip_table_nolock(sig, newent);
17239 +       spin_unlock(&gr_conn_table_lock);
17240 +#endif
17241 +       return;
17242 +}
17243 +
17244 +void gr_del_task_from_ip_table(struct task_struct *task)
17245 +{
17246 +#ifdef CONFIG_GRKERNSEC
17247 +       spin_lock(&gr_conn_table_lock);
17248 +       gr_del_task_from_ip_table_nolock(task->signal);
17249 +       spin_unlock(&gr_conn_table_lock);
17250 +#endif
17251 +       return;
17252 +}
17253 +
17254 +void
17255 +gr_attach_curr_ip(const struct sock *sk)
17256 +{
17257 +#ifdef CONFIG_GRKERNSEC
17258 +       struct signal_struct *p, *set;
17259 +       const struct inet_sock *inet = inet_sk(sk);     
17260 +
17261 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
17262 +               return;
17263 +
17264 +       set = current->signal;
17265 +
17266 +       spin_lock_bh(&gr_conn_table_lock);
17267 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
17268 +                                   inet->dport, inet->sport);
17269 +       if (unlikely(p != NULL)) {
17270 +               set->curr_ip = p->curr_ip;
17271 +               set->used_accept = 1;
17272 +               gr_del_task_from_ip_table_nolock(p);
17273 +               spin_unlock_bh(&gr_conn_table_lock);
17274 +               return;
17275 +       }
17276 +       spin_unlock_bh(&gr_conn_table_lock);
17277 +
17278 +       set->curr_ip = inet->daddr;
17279 +       set->used_accept = 1;
17280 +#endif
17281 +       return;
17282 +}
17283 +
17284 +int
17285 +gr_handle_sock_all(const int family, const int type, const int protocol)
17286 +{
17287 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
17288 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
17289 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
17290 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
17291 +               return -EACCES;
17292 +       }
17293 +#endif
17294 +       return 0;
17295 +}
17296 +
17297 +int
17298 +gr_handle_sock_server(const struct sockaddr *sck)
17299 +{
17300 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
17301 +       if (grsec_enable_socket_server &&
17302 +           in_group_p(grsec_socket_server_gid) &&
17303 +           sck && (sck->sa_family != AF_UNIX) &&
17304 +           (sck->sa_family != AF_LOCAL)) {
17305 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
17306 +               return -EACCES;
17307 +       }
17308 +#endif
17309 +       return 0;
17310 +}
17311 +
17312 +int
17313 +gr_handle_sock_server_other(const struct sock *sck)
17314 +{
17315 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
17316 +       if (grsec_enable_socket_server &&
17317 +           in_group_p(grsec_socket_server_gid) &&
17318 +           sck && (sck->sk_family != AF_UNIX) &&
17319 +           (sck->sk_family != AF_LOCAL)) {
17320 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
17321 +               return -EACCES;
17322 +       }
17323 +#endif
17324 +       return 0;
17325 +}
17326 +
17327 +int
17328 +gr_handle_sock_client(const struct sockaddr *sck)
17329 +{
17330 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
17331 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
17332 +           sck && (sck->sa_family != AF_UNIX) &&
17333 +           (sck->sa_family != AF_LOCAL)) {
17334 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
17335 +               return -EACCES;
17336 +       }
17337 +#endif
17338 +       return 0;
17339 +}
17340 +
17341 +__u32
17342 +gr_cap_rtnetlink(void)
17343 +{
17344 +#ifdef CONFIG_GRKERNSEC
17345 +       if (!gr_acl_is_enabled())
17346 +               return current->cap_effective;
17347 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
17348 +                gr_task_is_capable(current, CAP_NET_ADMIN))
17349 +               return current->cap_effective;
17350 +       else
17351 +               return 0;
17352 +#else
17353 +       return current->cap_effective;
17354 +#endif
17355 +}
17356 diff -urNp linux-2.6.17.11/grsecurity/grsec_sysctl.c linux-2.6.17.11/grsecurity/grsec_sysctl.c
17357 --- linux-2.6.17.11/grsecurity/grsec_sysctl.c   1969-12-31 19:00:00.000000000 -0500
17358 +++ linux-2.6.17.11/grsecurity/grsec_sysctl.c   2006-09-01 16:20:28.000000000 -0400
17359 @@ -0,0 +1,466 @@
17360 +#include <linux/kernel.h>
17361 +#include <linux/sched.h>
17362 +#include <linux/sysctl.h>
17363 +#include <linux/grsecurity.h>
17364 +#include <linux/grinternal.h>
17365 +
17366 +#ifdef CONFIG_GRKERNSEC_MODSTOP
17367 +int grsec_modstop;
17368 +#endif
17369 +
17370 +int
17371 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
17372 +{
17373 +#ifdef CONFIG_GRKERNSEC_SYSCTL
17374 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
17375 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
17376 +               return -EACCES;
17377 +       }
17378 +#endif
17379 +#ifdef CONFIG_GRKERNSEC_MODSTOP
17380 +       if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
17381 +           grsec_modstop && (op & 002)) {
17382 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
17383 +               return -EACCES;
17384 +       }
17385 +#endif
17386 +       return 0;
17387 +}
17388 +
17389 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
17390 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
17391 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
17392 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
17393 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
17394 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
17395 +GS_RANDPID, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
17396 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, 
17397 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
17398 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
17399 +
17400 +
17401 +ctl_table grsecurity_table[] = {
17402 +#ifdef CONFIG_GRKERNSEC_SYSCTL
17403 +#ifdef CONFIG_GRKERNSEC_LINK
17404 +       {
17405 +               .ctl_name       = GS_LINK,
17406 +               .procname       = "linking_restrictions",
17407 +               .data           = &grsec_enable_link,
17408 +               .maxlen         = sizeof(int),
17409 +               .mode           = 0600,
17410 +               .proc_handler   = &proc_dointvec,
17411 +       },
17412 +#endif
17413 +#ifdef CONFIG_GRKERNSEC_FIFO
17414 +       {
17415 +               .ctl_name       = GS_FIFO,
17416 +               .procname       = "fifo_restrictions",
17417 +               .data           = &grsec_enable_fifo,
17418 +               .maxlen         = sizeof(int),
17419 +               .mode           = 0600,
17420 +               .proc_handler   = &proc_dointvec,
17421 +       },
17422 +#endif
17423 +#ifdef CONFIG_GRKERNSEC_EXECVE
17424 +       {
17425 +               .ctl_name       = GS_EXECVE,
17426 +               .procname       = "execve_limiting",
17427 +               .data           = &grsec_enable_execve,
17428 +               .maxlen         = sizeof(int),
17429 +               .mode           = 0600,
17430 +               .proc_handler   = &proc_dointvec,
17431 +       },
17432 +#endif
17433 +#ifdef CONFIG_GRKERNSEC_EXECLOG
17434 +       {
17435 +               .ctl_name       = GS_EXECLOG,
17436 +               .procname       = "exec_logging",
17437 +               .data           = &grsec_enable_execlog,
17438 +               .maxlen         = sizeof(int),
17439 +               .mode           = 0600,
17440 +               .proc_handler   = &proc_dointvec,
17441 +       },
17442 +#endif
17443 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17444 +       {
17445 +               .ctl_name       = GS_SIGNAL,
17446 +               .procname       = "signal_logging",
17447 +               .data           = &grsec_enable_signal,
17448 +               .maxlen         = sizeof(int),
17449 +               .mode           = 0600,
17450 +               .proc_handler   = &proc_dointvec,
17451 +       },
17452 +#endif
17453 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
17454 +       {
17455 +               .ctl_name       = GS_FORKFAIL,
17456 +               .procname       = "forkfail_logging",
17457 +               .data           = &grsec_enable_forkfail,
17458 +               .maxlen         = sizeof(int),
17459 +               .mode           = 0600,
17460 +               .proc_handler   = &proc_dointvec,
17461 +       },
17462 +#endif
17463 +#ifdef CONFIG_GRKERNSEC_TIME
17464 +       {
17465 +               .ctl_name       = GS_TIME,
17466 +               .procname       = "timechange_logging",
17467 +               .data           = &grsec_enable_time,
17468 +               .maxlen         = sizeof(int),
17469 +               .mode           = 0600,
17470 +               .proc_handler   = &proc_dointvec,
17471 +       },
17472 +#endif
17473 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
17474 +       {
17475 +               .ctl_name       = GS_CHROOT_SHMAT,
17476 +               .procname       = "chroot_deny_shmat",
17477 +               .data           = &grsec_enable_chroot_shmat,
17478 +               .maxlen         = sizeof(int),
17479 +               .mode           = 0600,
17480 +               .proc_handler   = &proc_dointvec,
17481 +       },
17482 +#endif
17483 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
17484 +       {
17485 +               .ctl_name       = GS_CHROOT_UNIX,
17486 +               .procname       = "chroot_deny_unix",
17487 +               .data           = &grsec_enable_chroot_unix,
17488 +               .maxlen         = sizeof(int),
17489 +               .mode           = 0600,
17490 +               .proc_handler   = &proc_dointvec,
17491 +       },
17492 +#endif
17493 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
17494 +       {
17495 +               .ctl_name       = GS_CHROOT_MNT,
17496 +               .procname       = "chroot_deny_mount",
17497 +               .data           = &grsec_enable_chroot_mount,
17498 +               .maxlen         = sizeof(int),
17499 +               .mode           = 0600,
17500 +               .proc_handler   = &proc_dointvec,
17501 +       },
17502 +#endif
17503 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
17504 +       {
17505 +               .ctl_name       = GS_CHROOT_FCHDIR,
17506 +               .procname       = "chroot_deny_fchdir",
17507 +               .data           = &grsec_enable_chroot_fchdir,
17508 +               .maxlen         = sizeof(int),
17509 +               .mode           = 0600,
17510 +               .proc_handler   = &proc_dointvec,
17511 +       },
17512 +#endif
17513 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17514 +       {
17515 +               .ctl_name       = GS_CHROOT_DBL,
17516 +               .procname       = "chroot_deny_chroot",
17517 +               .data           = &grsec_enable_chroot_double,
17518 +               .maxlen         = sizeof(int),
17519 +               .mode           = 0600,
17520 +               .proc_handler   = &proc_dointvec,
17521 +       },
17522 +#endif
17523 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
17524 +       {
17525 +               .ctl_name       = GS_CHROOT_PVT,
17526 +               .procname       = "chroot_deny_pivot",
17527 +               .data           = &grsec_enable_chroot_pivot,
17528 +               .maxlen         = sizeof(int),
17529 +               .mode           = 0600,
17530 +               .proc_handler   = &proc_dointvec,
17531 +       },
17532 +#endif
17533 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17534 +       {
17535 +               .ctl_name       = GS_CHROOT_CD,
17536 +               .procname       = "chroot_enforce_chdir",
17537 +               .data           = &grsec_enable_chroot_chdir,
17538 +               .maxlen         = sizeof(int),
17539 +               .mode           = 0600,
17540 +               .proc_handler   = &proc_dointvec,
17541 +       },
17542 +#endif
17543 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17544 +       {
17545 +               .ctl_name       = GS_CHROOT_CM,
17546 +               .procname       = "chroot_deny_chmod",
17547 +               .data           = &grsec_enable_chroot_chmod,
17548 +               .maxlen         = sizeof(int),
17549 +               .mode           = 0600,
17550 +               .proc_handler   = &proc_dointvec,
17551 +       },
17552 +#endif
17553 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
17554 +       {
17555 +               .ctl_name       = GS_CHROOT_MK,
17556 +               .procname       = "chroot_deny_mknod",
17557 +               .data           = &grsec_enable_chroot_mknod,
17558 +               .maxlen         = sizeof(int),
17559 +               .mode           = 0600,
17560 +               .proc_handler   = &proc_dointvec,
17561 +       },
17562 +#endif
17563 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17564 +       {
17565 +               .ctl_name       = GS_CHROOT_NI,
17566 +               .procname       = "chroot_restrict_nice",
17567 +               .data           = &grsec_enable_chroot_nice,
17568 +               .maxlen         = sizeof(int),
17569 +               .mode           = 0600,
17570 +               .proc_handler   = &proc_dointvec,
17571 +       },
17572 +#endif
17573 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
17574 +       {
17575 +               .ctl_name       = GS_CHROOT_EXECLOG,
17576 +               .procname       = "chroot_execlog",
17577 +               .data           = &grsec_enable_chroot_execlog,
17578 +               .maxlen         = sizeof(int),
17579 +               .mode           = 0600,
17580 +               .proc_handler   = &proc_dointvec,
17581 +       },
17582 +#endif
17583 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17584 +       {
17585 +               .ctl_name       = GS_CHROOT_CAPS,
17586 +               .procname       = "chroot_caps",
17587 +               .data           = &grsec_enable_chroot_caps,
17588 +               .maxlen         = sizeof(int),
17589 +               .mode           = 0600,
17590 +               .proc_handler   = &proc_dointvec,
17591 +       },
17592 +#endif
17593 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17594 +       {
17595 +               .ctl_name       = GS_CHROOT_SYSCTL,
17596 +               .procname       = "chroot_deny_sysctl",
17597 +               .data           = &grsec_enable_chroot_sysctl,
17598 +               .maxlen         = sizeof(int),
17599 +               .mode           = 0600,
17600 +               .proc_handler   = &proc_dointvec,
17601 +       },
17602 +#endif
17603 +#ifdef CONFIG_GRKERNSEC_TPE
17604 +       {
17605 +               .ctl_name       = GS_TPE,
17606 +               .procname       = "tpe",
17607 +               .data           = &grsec_enable_tpe,
17608 +               .maxlen         = sizeof(int),
17609 +               .mode           = 0600,
17610 +               .proc_handler   = &proc_dointvec,
17611 +       },
17612 +       {
17613 +               .ctl_name       = GS_TPE_GID,
17614 +               .procname       = "tpe_gid",
17615 +               .data           = &grsec_tpe_gid,
17616 +               .maxlen         = sizeof(int),
17617 +               .mode           = 0600,
17618 +               .proc_handler   = &proc_dointvec,
17619 +       },
17620 +#endif
17621 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
17622 +       {
17623 +               .ctl_name       = GS_TPE_ALL,
17624 +               .procname       = "tpe_restrict_all",
17625 +               .data           = &grsec_enable_tpe_all,
17626 +               .maxlen         = sizeof(int),
17627 +               .mode           = 0600,
17628 +               .proc_handler   = &proc_dointvec,
17629 +       },
17630 +#endif
17631 +#ifdef CONFIG_GRKERNSEC_RANDPID
17632 +       {
17633 +               .ctl_name       = GS_RANDPID,
17634 +               .procname       = "rand_pids",
17635 +               .data           = &grsec_enable_randpid,
17636 +               .maxlen         = sizeof(int),
17637 +               .mode           = 0600,
17638 +               .proc_handler   = &proc_dointvec,
17639 +       },
17640 +#endif
17641 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
17642 +       {
17643 +               .ctl_name       = GS_SOCKET_ALL,
17644 +               .procname       = "socket_all",
17645 +               .data           = &grsec_enable_socket_all,
17646 +               .maxlen         = sizeof(int),
17647 +               .mode           = 0600,
17648 +               .proc_handler   = &proc_dointvec,
17649 +       },
17650 +       {
17651 +               .ctl_name       = GS_SOCKET_ALL_GID,
17652 +               .procname       = "socket_all_gid",
17653 +               .data           = &grsec_socket_all_gid,
17654 +               .maxlen         = sizeof(int),
17655 +               .mode           = 0600,
17656 +               .proc_handler   = &proc_dointvec,
17657 +       },
17658 +#endif
17659 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
17660 +       {
17661 +               .ctl_name       = GS_SOCKET_CLIENT,
17662 +               .procname       = "socket_client",
17663 +               .data           = &grsec_enable_socket_client,
17664 +               .maxlen         = sizeof(int),
17665 +               .mode           = 0600,
17666 +               .proc_handler   = &proc_dointvec,
17667 +       },
17668 +       {
17669 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
17670 +               .procname       = "socket_client_gid",
17671 +               .data           = &grsec_socket_client_gid,
17672 +               .maxlen         = sizeof(int),
17673 +               .mode           = 0600,
17674 +               .proc_handler   = &proc_dointvec,
17675 +       },
17676 +#endif
17677 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
17678 +       {
17679 +               .ctl_name       = GS_SOCKET_SERVER,
17680 +               .procname       = "socket_server",
17681 +               .data           = &grsec_enable_socket_server,
17682 +               .maxlen         = sizeof(int),
17683 +               .mode           = 0600,
17684 +               .proc_handler   = &proc_dointvec,
17685 +       },
17686 +       {
17687 +               .ctl_name       = GS_SOCKET_SERVER_GID,
17688 +               .procname       = "socket_server_gid",
17689 +               .data           = &grsec_socket_server_gid,
17690 +               .maxlen         = sizeof(int),
17691 +               .mode           = 0600,
17692 +               .proc_handler   = &proc_dointvec,
17693 +       },
17694 +#endif
17695 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
17696 +       {
17697 +               .ctl_name       = GS_GROUP,
17698 +               .procname       = "audit_group",
17699 +               .data           = &grsec_enable_group,
17700 +               .maxlen         = sizeof(int),
17701 +               .mode           = 0600,
17702 +               .proc_handler   = &proc_dointvec,
17703 +       },
17704 +       {
17705 +               .ctl_name       = GS_GID,
17706 +               .procname       = "audit_gid",
17707 +               .data           = &grsec_audit_gid,
17708 +               .maxlen         = sizeof(int),
17709 +               .mode           = 0600,
17710 +               .proc_handler   = &proc_dointvec,
17711 +       },
17712 +#endif
17713 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
17714 +       {
17715 +               .ctl_name       = GS_ACHDIR,
17716 +               .procname       = "audit_chdir",
17717 +               .data           = &grsec_enable_chdir,
17718 +               .maxlen         = sizeof(int),
17719 +               .mode           = 0600,
17720 +               .proc_handler   = &proc_dointvec,
17721 +       },
17722 +#endif
17723 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17724 +       {
17725 +               .ctl_name       = GS_AMOUNT,
17726 +               .procname       = "audit_mount",
17727 +               .data           = &grsec_enable_mount,
17728 +               .maxlen         = sizeof(int),
17729 +               .mode           = 0600,
17730 +               .proc_handler   = &proc_dointvec,
17731 +       },
17732 +#endif
17733 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17734 +       {
17735 +               .ctl_name       = GS_AIPC,
17736 +               .procname       = "audit_ipc",
17737 +               .data           = &grsec_enable_audit_ipc,
17738 +               .maxlen         = sizeof(int),
17739 +               .mode           = 0600,
17740 +               .proc_handler   = &proc_dointvec,
17741 +       },
17742 +#endif
17743 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
17744 +       {
17745 +               .ctl_name       = GS_TEXTREL,
17746 +               .procname       = "audit_textrel",
17747 +               .data           = &grsec_enable_audit_textrel,
17748 +               .maxlen         = sizeof(int),
17749 +               .mode           = 0600,
17750 +               .proc_handler   = &proc_dointvec,
17751 +       },
17752 +#endif
17753 +#ifdef CONFIG_GRKERNSEC_DMESG
17754 +       {
17755 +               .ctl_name       = GS_DMSG,
17756 +               .procname       = "dmesg",
17757 +               .data           = &grsec_enable_dmesg,
17758 +               .maxlen         = sizeof(int),
17759 +               .mode           = 0600,
17760 +               .proc_handler   = &proc_dointvec,
17761 +       },
17762 +#endif
17763 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
17764 +       {
17765 +               .ctl_name       = GS_FINDTASK,
17766 +               .procname       = "chroot_findtask",
17767 +               .data           = &grsec_enable_chroot_findtask,
17768 +               .maxlen         = sizeof(int),
17769 +               .mode           = 0600,
17770 +               .proc_handler   = &proc_dointvec,
17771 +       },
17772 +#endif
17773 +#ifdef CONFIG_GRKERNSEC_SHM
17774 +       {
17775 +               .ctl_name       = GS_SHM,
17776 +               .procname       = "destroy_unused_shm",
17777 +               .data           = &grsec_enable_shm,
17778 +               .maxlen         = sizeof(int),
17779 +               .mode           = 0600,
17780 +               .proc_handler   = &proc_dointvec,
17781 +       },
17782 +#endif
17783 +#ifdef CONFIG_GRKERNSEC_RESLOG
17784 +       {
17785 +               .ctl_name       = GS_RESLOG,
17786 +               .procname       = "resource_logging",
17787 +               .data           = &grsec_resource_logging,
17788 +               .maxlen         = sizeof(int),
17789 +               .mode           = 0600,
17790 +               .proc_handler   = &proc_dointvec,
17791 +       },
17792 +#endif
17793 +       {
17794 +               .ctl_name       = GS_LOCK,
17795 +               .procname       = "grsec_lock",
17796 +               .data           = &grsec_lock,
17797 +               .maxlen         = sizeof(int),
17798 +               .mode           = 0600,
17799 +               .proc_handler   = &proc_dointvec,
17800 +       },
17801 +#endif
17802 +#ifdef CONFIG_GRKERNSEC_MODSTOP
17803 +       {
17804 +               .ctl_name       = GS_MODSTOP,
17805 +               .procname       = "disable_modules",
17806 +               .data           = &grsec_modstop,
17807 +               .maxlen         = sizeof(int),
17808 +               .mode           = 0600,
17809 +               .proc_handler   = &proc_dointvec,
17810 +       },
17811 +#endif
17812 +       { .ctl_name = 0 }
17813 +};
17814 +#endif
17815 +
17816 +int gr_check_modstop(void)
17817 +{
17818 +#ifdef CONFIG_GRKERNSEC_MODSTOP
17819 +       if (grsec_modstop == 1) {
17820 +               gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
17821 +               return 1;
17822 +       }
17823 +#endif
17824 +       return 0;
17825 +}
17826 diff -urNp linux-2.6.17.11/grsecurity/grsec_textrel.c linux-2.6.17.11/grsecurity/grsec_textrel.c
17827 --- linux-2.6.17.11/grsecurity/grsec_textrel.c  1969-12-31 19:00:00.000000000 -0500
17828 +++ linux-2.6.17.11/grsecurity/grsec_textrel.c  2006-09-01 16:20:28.000000000 -0400
17829 @@ -0,0 +1,16 @@
17830 +#include <linux/kernel.h>
17831 +#include <linux/sched.h>
17832 +#include <linux/mm.h>
17833 +#include <linux/file.h>
17834 +#include <linux/grinternal.h>
17835 +#include <linux/grsecurity.h>
17836 +
17837 +void
17838 +gr_log_textrel(struct vm_area_struct * vma)
17839 +{
17840 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
17841 +       if (grsec_enable_audit_textrel)
17842 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
17843 +#endif
17844 +       return;
17845 +}
17846 diff -urNp linux-2.6.17.11/grsecurity/grsec_time.c linux-2.6.17.11/grsecurity/grsec_time.c
17847 --- linux-2.6.17.11/grsecurity/grsec_time.c     1969-12-31 19:00:00.000000000 -0500
17848 +++ linux-2.6.17.11/grsecurity/grsec_time.c     2006-09-01 16:20:28.000000000 -0400
17849 @@ -0,0 +1,13 @@
17850 +#include <linux/kernel.h>
17851 +#include <linux/sched.h>
17852 +#include <linux/grinternal.h>
17853 +
17854 +void
17855 +gr_log_timechange(void)
17856 +{
17857 +#ifdef CONFIG_GRKERNSEC_TIME
17858 +       if (grsec_enable_time)
17859 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
17860 +#endif
17861 +       return;
17862 +}
17863 diff -urNp linux-2.6.17.11/grsecurity/grsec_tpe.c linux-2.6.17.11/grsecurity/grsec_tpe.c
17864 --- linux-2.6.17.11/grsecurity/grsec_tpe.c      1969-12-31 19:00:00.000000000 -0500
17865 +++ linux-2.6.17.11/grsecurity/grsec_tpe.c      2006-09-01 16:20:28.000000000 -0400
17866 @@ -0,0 +1,37 @@
17867 +#include <linux/kernel.h>
17868 +#include <linux/sched.h>
17869 +#include <linux/file.h>
17870 +#include <linux/fs.h>
17871 +#include <linux/grinternal.h>
17872 +
17873 +extern int gr_acl_tpe_check(void);
17874 +
17875 +int
17876 +gr_tpe_allow(const struct file *file)
17877 +{
17878 +#ifdef CONFIG_GRKERNSEC
17879 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
17880 +
17881 +       if (current->uid && ((grsec_enable_tpe &&
17882 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
17883 +           !in_group_p(grsec_tpe_gid)
17884 +#else
17885 +           in_group_p(grsec_tpe_gid)
17886 +#endif
17887 +           ) || gr_acl_tpe_check()) &&
17888 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
17889 +                                               (inode->i_mode & S_IWOTH))))) {
17890 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
17891 +               return 0;
17892 +       }
17893 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
17894 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
17895 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
17896 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
17897 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
17898 +               return 0;
17899 +       }
17900 +#endif
17901 +#endif
17902 +       return 1;
17903 +}
17904 diff -urNp linux-2.6.17.11/grsecurity/grsum.c linux-2.6.17.11/grsecurity/grsum.c
17905 --- linux-2.6.17.11/grsecurity/grsum.c  1969-12-31 19:00:00.000000000 -0500
17906 +++ linux-2.6.17.11/grsecurity/grsum.c  2006-09-01 16:20:28.000000000 -0400
17907 @@ -0,0 +1,59 @@
17908 +#include <linux/kernel.h>
17909 +#include <linux/sched.h>
17910 +#include <linux/mm.h>
17911 +#include <asm/scatterlist.h>
17912 +#include <linux/crypto.h>
17913 +#include <linux/gracl.h>
17914 +
17915 +
17916 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
17917 +#error "crypto and sha256 must be built into the kernel"
17918 +#endif
17919 +
17920 +int
17921 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
17922 +{
17923 +       char *p;
17924 +       struct crypto_tfm *tfm;
17925 +       unsigned char temp_sum[GR_SHA_LEN];
17926 +       struct scatterlist sg[2];
17927 +       volatile int retval = 0;
17928 +       volatile int dummy = 0;
17929 +       unsigned int i;
17930 +
17931 +       tfm = crypto_alloc_tfm("sha256", 0);
17932 +       if (tfm == NULL) {
17933 +               /* should never happen, since sha256 should be built in */
17934 +               return 1;
17935 +       }
17936 +
17937 +       crypto_digest_init(tfm);
17938 +
17939 +       p = salt;
17940 +       sg[0].page = virt_to_page(p);
17941 +       sg[0].offset = ((long) p & ~PAGE_MASK);
17942 +       sg[0].length = GR_SALT_LEN;
17943 +       
17944 +       crypto_digest_update(tfm, sg, 1);
17945 +
17946 +       p = entry->pw;
17947 +       sg[0].page = virt_to_page(p);
17948 +       sg[0].offset = ((long) p & ~PAGE_MASK);
17949 +       sg[0].length = strlen(entry->pw);
17950 +
17951 +       crypto_digest_update(tfm, sg, 1);
17952 +
17953 +       crypto_digest_final(tfm, temp_sum);
17954 +
17955 +       memset(entry->pw, 0, GR_PW_LEN);
17956 +
17957 +       for (i = 0; i < GR_SHA_LEN; i++)
17958 +               if (sum[i] != temp_sum[i])
17959 +                       retval = 1;
17960 +               else
17961 +                       dummy = 1;      // waste a cycle
17962 +
17963 +       crypto_free_tfm(tfm);
17964 +
17965 +       return retval;
17966 +}
17967 diff -urNp linux-2.6.17.11/grsecurity/Kconfig linux-2.6.17.11/grsecurity/Kconfig
17968 --- linux-2.6.17.11/grsecurity/Kconfig  1969-12-31 19:00:00.000000000 -0500
17969 +++ linux-2.6.17.11/grsecurity/Kconfig  2006-09-01 16:20:28.000000000 -0400
17970 @@ -0,0 +1,890 @@
17971 +#
17972 +# grecurity configuration
17973 +#
17974 +
17975 +menu "Grsecurity"
17976 +
17977 +config GRKERNSEC
17978 +       bool "Grsecurity"
17979 +       select CRYPTO
17980 +       select CRYPTO_SHA256
17981 +       help
17982 +         If you say Y here, you will be able to configure many features
17983 +         that will enhance the security of your system.  It is highly
17984 +         recommended that you say Y here and read through the help
17985 +         for each option so that you fully understand the features and
17986 +         can evaluate their usefulness for your machine.
17987 +
17988 +choice
17989 +       prompt "Security Level"
17990 +       depends GRKERNSEC
17991 +       default GRKERNSEC_CUSTOM
17992 +
17993 +config GRKERNSEC_LOW
17994 +       bool "Low"
17995 +       select GRKERNSEC_LINK
17996 +       select GRKERNSEC_FIFO
17997 +       select GRKERNSEC_RANDPID
17998 +       select GRKERNSEC_EXECVE
17999 +       select GRKERNSEC_RANDNET
18000 +       select GRKERNSEC_DMESG
18001 +       select GRKERNSEC_CHROOT_CHDIR
18002 +       select GRKERNSEC_MODSTOP if (MODULES)
18003 +
18004 +       help
18005 +         If you choose this option, several of the grsecurity options will
18006 +         be enabled that will give you greater protection against a number
18007 +         of attacks, while assuring that none of your software will have any
18008 +         conflicts with the additional security measures.  If you run a lot
18009 +         of unusual software, or you are having problems with the higher
18010 +         security levels, you should say Y here.  With this option, the
18011 +         following features are enabled:
18012 +
18013 +         - Linking restrictions
18014 +         - FIFO restrictions
18015 +         - Randomized PIDs
18016 +         - Enforcing RLIMIT_NPROC on execve
18017 +         - Restricted dmesg
18018 +         - Enforced chdir("/") on chroot
18019 +         - Runtime module disabling
18020 +
18021 +config GRKERNSEC_MEDIUM
18022 +       bool "Medium"
18023 +       select PAX
18024 +       select PAX_EI_PAX
18025 +       select PAX_PT_PAX_FLAGS
18026 +       select PAX_HAVE_ACL_FLAGS
18027 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
18028 +       select GRKERNSEC_CHROOT_SYSCTL
18029 +       select GRKERNSEC_LINK
18030 +       select GRKERNSEC_FIFO
18031 +       select GRKERNSEC_RANDPID
18032 +       select GRKERNSEC_EXECVE
18033 +       select GRKERNSEC_DMESG
18034 +       select GRKERNSEC_RANDNET
18035 +       select GRKERNSEC_FORKFAIL
18036 +       select GRKERNSEC_TIME
18037 +       select GRKERNSEC_SIGNAL
18038 +       select GRKERNSEC_CHROOT
18039 +       select GRKERNSEC_CHROOT_UNIX
18040 +       select GRKERNSEC_CHROOT_MOUNT
18041 +       select GRKERNSEC_CHROOT_PIVOT
18042 +       select GRKERNSEC_CHROOT_DOUBLE
18043 +       select GRKERNSEC_CHROOT_CHDIR
18044 +       select GRKERNSEC_CHROOT_MKNOD
18045 +       select GRKERNSEC_PROC
18046 +       select GRKERNSEC_PROC_USERGROUP
18047 +       select GRKERNSEC_MODSTOP if (MODULES)
18048 +       select PAX_RANDUSTACK
18049 +       select PAX_ASLR
18050 +       select PAX_RANDMMAP
18051 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
18052 +
18053 +       help
18054 +         If you say Y here, several features in addition to those included
18055 +         in the low additional security level will be enabled.  These
18056 +         features provide even more security to your system, though in rare
18057 +         cases they may be incompatible with very old or poorly written
18058 +         software.  If you enable this option, make sure that your auth
18059 +         service (identd) is running as gid 1001.  With this option, 
18060 +         the following features (in addition to those provided in the 
18061 +         low additional security level) will be enabled:
18062 +
18063 +         - Randomized TCP source ports
18064 +         - Failed fork logging
18065 +         - Time change logging
18066 +         - Signal logging
18067 +         - Deny mounts in chroot
18068 +         - Deny double chrooting
18069 +         - Deny sysctl writes in chroot
18070 +         - Deny mknod in chroot
18071 +         - Deny access to abstract AF_UNIX sockets out of chroot
18072 +         - Deny pivot_root in chroot
18073 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
18074 +         - /proc restrictions with special GID set to 10 (usually wheel)
18075 +         - Address Space Layout Randomization (ASLR)
18076 +
18077 +config GRKERNSEC_HIGH
18078 +       bool "High"
18079 +       select GRKERNSEC_LINK
18080 +       select GRKERNSEC_FIFO
18081 +       select GRKERNSEC_RANDPID
18082 +       select GRKERNSEC_EXECVE
18083 +       select GRKERNSEC_DMESG
18084 +       select GRKERNSEC_FORKFAIL
18085 +       select GRKERNSEC_TIME
18086 +       select GRKERNSEC_SIGNAL
18087 +       select GRKERNSEC_CHROOT_SHMAT
18088 +       select GRKERNSEC_CHROOT_UNIX
18089 +       select GRKERNSEC_CHROOT_MOUNT
18090 +       select GRKERNSEC_CHROOT_FCHDIR
18091 +       select GRKERNSEC_CHROOT_PIVOT
18092 +       select GRKERNSEC_CHROOT_DOUBLE
18093 +       select GRKERNSEC_CHROOT_CHDIR
18094 +       select GRKERNSEC_CHROOT_MKNOD
18095 +       select GRKERNSEC_CHROOT_CAPS
18096 +       select GRKERNSEC_CHROOT_SYSCTL
18097 +       select GRKERNSEC_CHROOT_FINDTASK
18098 +       select GRKERNSEC_PROC
18099 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
18100 +       select GRKERNSEC_HIDESYM
18101 +       select GRKERNSEC_BRUTE
18102 +       select GRKERNSEC_SHM if (SYSVIPC)
18103 +       select GRKERNSEC_PROC_USERGROUP
18104 +       select GRKERNSEC_KMEM
18105 +       select GRKERNSEC_RESLOG
18106 +       select GRKERNSEC_RANDNET
18107 +       select GRKERNSEC_PROC_ADD
18108 +       select GRKERNSEC_CHROOT_CHMOD
18109 +       select GRKERNSEC_CHROOT_NICE
18110 +       select GRKERNSEC_AUDIT_MOUNT
18111 +       select GRKERNSEC_MODSTOP if (MODULES)
18112 +       select PAX
18113 +       select PAX_RANDUSTACK
18114 +       select PAX_ASLR
18115 +       select PAX_RANDMMAP
18116 +       select PAX_NOEXEC
18117 +       select PAX_MPROTECT
18118 +       select PAX_EI_PAX
18119 +       select PAX_PT_PAX_FLAGS
18120 +       select PAX_HAVE_ACL_FLAGS
18121 +       select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
18122 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
18123 +       select PAX_SEGMEXEC if (X86 && !X86_64)
18124 +       select PAX_PAGEEXEC if (!X86)
18125 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
18126 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
18127 +       select PAX_SYSCALL if (PPC32)
18128 +       select PAX_EMUTRAMP if (PARISC)
18129 +       select PAX_EMUSIGRT if (PARISC)
18130 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
18131 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
18132 +       help
18133 +         If you say Y here, many of the features of grsecurity will be
18134 +         enabled, which will protect you against many kinds of attacks
18135 +         against your system.  The heightened security comes at a cost
18136 +         of an increased chance of incompatibilities with rare software
18137 +         on your machine.  Since this security level enables PaX, you should
18138 +         view <http://pax.grsecurity.net> and read about the PaX
18139 +         project.  While you are there, download chpax and run it on
18140 +         binaries that cause problems with PaX.  Also remember that
18141 +         since the /proc restrictions are enabled, you must run your
18142 +         identd as gid 1001.  This security level enables the following 
18143 +         features in addition to those listed in the low and medium 
18144 +         security levels:
18145 +
18146 +         - Additional /proc restrictions
18147 +         - Chmod restrictions in chroot
18148 +         - No signals, ptrace, or viewing of processes outside of chroot
18149 +         - Capability restrictions in chroot
18150 +         - Deny fchdir out of chroot
18151 +         - Priority restrictions in chroot
18152 +         - Segmentation-based implementation of PaX
18153 +         - Mprotect restrictions
18154 +         - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
18155 +         - Kernel stack randomization
18156 +         - Mount/unmount/remount logging
18157 +         - Kernel symbol hiding
18158 +         - Destroy unused shared memory        
18159 +         - Prevention of memory exhaustion-based exploits
18160 +config GRKERNSEC_CUSTOM
18161 +       bool "Custom"
18162 +       help
18163 +         If you say Y here, you will be able to configure every grsecurity
18164 +         option, which allows you to enable many more features that aren't
18165 +         covered in the basic security levels.  These additional features
18166 +         include TPE, socket restrictions, and the sysctl system for
18167 +         grsecurity.  It is advised that you read through the help for
18168 +         each option to determine its usefulness in your situation.
18169 +
18170 +endchoice
18171 +
18172 +menu "Address Space Protection"
18173 +depends on GRKERNSEC
18174 +
18175 +config GRKERNSEC_KMEM
18176 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
18177 +       help
18178 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
18179 +         be written to via mmap or otherwise to modify the running kernel.
18180 +         /dev/port will also not be allowed to be opened. If you have module
18181 +         support disabled, enabling this will close up four ways that are
18182 +         currently used  to insert malicious code into the running kernel.
18183 +         Even with all these features enabled, we still highly recommend that
18184 +         you use the RBAC system, as it is still possible for an attacker to
18185 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
18186 +         If you are not using XFree86, you may be able to stop this additional
18187 +         case by enabling the 'Disable privileged I/O' option. Though nothing
18188 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
18189 +         but only to video memory, which is the only writing we allow in this
18190 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
18191 +         not be allowed to mprotect it with PROT_WRITE later.
18192 +         It is highly recommended that you say Y here if you meet all the
18193 +         conditions above.
18194 +
18195 +config GRKERNSEC_IO
18196 +       bool "Disable privileged I/O"
18197 +       depends on X86
18198 +       select RTC
18199 +       help
18200 +         If you say Y here, all ioperm and iopl calls will return an error.
18201 +         Ioperm and iopl can be used to modify the running kernel.
18202 +         Unfortunately, some programs need this access to operate properly,
18203 +         the most notable of which are XFree86 and hwclock.  hwclock can be
18204 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
18205 +         enabled if this option is enabled, to ensure that hwclock operates
18206 +         correctly.  XFree86 still will not operate correctly with this option
18207 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
18208 +         and you still want to protect your kernel against modification,
18209 +         use the RBAC system.
18210 +
18211 +config GRKERNSEC_PROC_MEMMAP
18212 +       bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
18213 +       depends on PAX_NOEXEC || PAX_ASLR
18214 +       help
18215 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
18216 +         give no information about the addresses of its mappings if
18217 +         PaX features that rely on random addresses are enabled on the task.
18218 +         If you use PaX it is greatly recommended that you say Y here as it
18219 +         closes up a hole that makes the full ASLR useless for suid
18220 +         binaries.
18221 +
18222 +config GRKERNSEC_BRUTE
18223 +       bool "Deter exploit bruteforcing"
18224 +       help
18225 +         If you say Y here, attempts to bruteforce exploits against forking
18226 +         daemons such as apache or sshd will be deterred.  When a child of a
18227 +         forking daemon is killed by PaX or crashes due to an illegal
18228 +         instruction, the parent process will be delayed 30 seconds upon every
18229 +         subsequent fork until the administrator is able to assess the
18230 +         situation and restart the daemon.  It is recommended that you also
18231 +         enable signal logging in the auditing section so that logs are
18232 +         generated when a process performs an illegal instruction.
18233 +
18234 +config GRKERNSEC_MODSTOP
18235 +       bool "Runtime module disabling"
18236 +       depends on MODULES
18237 +       help
18238 +         If you say Y here, you will be able to disable the ability to (un)load
18239 +         modules at runtime.  This feature is useful if you need the ability
18240 +         to load kernel modules at boot time, but do not want to allow an
18241 +         attacker to load a rootkit kernel module into the system, or to remove
18242 +         a loaded kernel module important to system functioning.  You should
18243 +         enable the /dev/mem protection feature as well, since rootkits can be
18244 +         inserted into the kernel via other methods than kernel modules.  Since
18245 +         an untrusted module could still be loaded by modifying init scripts and
18246 +         rebooting the system, it is also recommended that you enable the RBAC
18247 +         system.  If you enable this option, a sysctl option with name
18248 +         "disable_modules" will be created.  Setting this option to "1" disables
18249 +         module loading.  After this option is set, no further writes to it are
18250 +         allowed until the system is rebooted.
18251 +
18252 +config GRKERNSEC_HIDESYM
18253 +       bool "Hide kernel symbols"
18254 +       help
18255 +         If you say Y here, getting information on loaded modules, and
18256 +         displaying all kernel symbols through a syscall will be restricted
18257 +         to users with CAP_SYS_MODULE.  This option is only effective
18258 +         provided the following conditions are met:
18259 +         1) The kernel using grsecurity is not precompiled by some distribution
18260 +         2) You are using the RBAC system and hiding other files such as your
18261 +            kernel image and System.map
18262 +         3) You have the additional /proc restrictions enabled, which removes
18263 +            /proc/kcore
18264 +         If the above conditions are met, this option will aid to provide a
18265 +         useful protection against local and remote kernel exploitation of
18266 +         overflows and arbitrary read/write vulnerabilities.
18267 +
18268 +endmenu
18269 +menu "Role Based Access Control Options"
18270 +depends on GRKERNSEC
18271 +
18272 +config GRKERNSEC_ACL_HIDEKERN
18273 +       bool "Hide kernel processes"
18274 +       help
18275 +         If you say Y here, all kernel threads will be hidden to all
18276 +         processes but those whose subject has the "view hidden processes"
18277 +         flag.
18278 +
18279 +config GRKERNSEC_ACL_MAXTRIES
18280 +       int "Maximum tries before password lockout"
18281 +       default 3
18282 +       help
18283 +         This option enforces the maximum number of times a user can attempt
18284 +         to authorize themselves with the grsecurity RBAC system before being
18285 +         denied the ability to attempt authorization again for a specified time.
18286 +         The lower the number, the harder it will be to brute-force a password.
18287 +
18288 +config GRKERNSEC_ACL_TIMEOUT
18289 +       int "Time to wait after max password tries, in seconds"
18290 +       default 30
18291 +       help
18292 +         This option specifies the time the user must wait after attempting to
18293 +         authorize to the RBAC system with the maximum number of invalid
18294 +         passwords.  The higher the number, the harder it will be to brute-force
18295 +         a password.
18296 +
18297 +endmenu
18298 +menu "Filesystem Protections"
18299 +depends on GRKERNSEC
18300 +
18301 +config GRKERNSEC_PROC
18302 +       bool "Proc restrictions"
18303 +       help
18304 +         If you say Y here, the permissions of the /proc filesystem
18305 +         will be altered to enhance system security and privacy.  You MUST
18306 +         choose either a user only restriction or a user and group restriction.
18307 +         Depending upon the option you choose, you can either restrict users to
18308 +         see only the processes they themselves run, or choose a group that can
18309 +         view all processes and files normally restricted to root if you choose
18310 +         the "restrict to user only" option.  NOTE: If you're running identd as
18311 +         a non-root user, you will have to run it as the group you specify here.
18312 +
18313 +config GRKERNSEC_PROC_USER
18314 +       bool "Restrict /proc to user only"
18315 +       depends on GRKERNSEC_PROC
18316 +       help
18317 +         If you say Y here, non-root users will only be able to view their own
18318 +         processes, and restricts them from viewing network-related information,
18319 +         and viewing kernel symbol and module information.
18320 +
18321 +config GRKERNSEC_PROC_USERGROUP
18322 +       bool "Allow special group"
18323 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
18324 +       help
18325 +         If you say Y here, you will be able to select a group that will be
18326 +         able to view all processes, network-related information, and
18327 +         kernel and symbol information.  This option is useful if you want
18328 +         to run identd as a non-root user.
18329 +
18330 +config GRKERNSEC_PROC_GID
18331 +       int "GID for special group"
18332 +       depends on GRKERNSEC_PROC_USERGROUP
18333 +       default 1001
18334 +
18335 +config GRKERNSEC_PROC_ADD
18336 +       bool "Additional restrictions"
18337 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
18338 +       help
18339 +         If you say Y here, additional restrictions will be placed on
18340 +         /proc that keep normal users from viewing device information and 
18341 +         slabinfo information that could be useful for exploits.
18342 +
18343 +config GRKERNSEC_LINK
18344 +       bool "Linking restrictions"
18345 +       help
18346 +         If you say Y here, /tmp race exploits will be prevented, since users
18347 +         will no longer be able to follow symlinks owned by other users in
18348 +         world-writable +t directories (i.e. /tmp), unless the owner of the
18349 +         symlink is the owner of the directory. users will also not be
18350 +         able to hardlink to files they do not own.  If the sysctl option is
18351 +         enabled, a sysctl option with name "linking_restrictions" is created.
18352 +
18353 +config GRKERNSEC_FIFO
18354 +       bool "FIFO restrictions"
18355 +       help
18356 +         If you say Y here, users will not be able to write to FIFOs they don't
18357 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
18358 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
18359 +         option is enabled, a sysctl option with name "fifo_restrictions" is
18360 +         created.
18361 +
18362 +config GRKERNSEC_CHROOT
18363 +       bool "Chroot jail restrictions"
18364 +       help
18365 +         If you say Y here, you will be able to choose several options that will
18366 +         make breaking out of a chrooted jail much more difficult.  If you
18367 +         encounter no software incompatibilities with the following options, it
18368 +         is recommended that you enable each one.
18369 +
18370 +config GRKERNSEC_CHROOT_MOUNT
18371 +       bool "Deny mounts"
18372 +       depends on GRKERNSEC_CHROOT
18373 +       help
18374 +         If you say Y here, processes inside a chroot will not be able to
18375 +         mount or remount filesystems.  If the sysctl option is enabled, a
18376 +         sysctl option with name "chroot_deny_mount" is created.
18377 +
18378 +config GRKERNSEC_CHROOT_DOUBLE
18379 +       bool "Deny double-chroots"
18380 +       depends on GRKERNSEC_CHROOT
18381 +       help
18382 +         If you say Y here, processes inside a chroot will not be able to chroot
18383 +         again outside the chroot.  This is a widely used method of breaking
18384 +         out of a chroot jail and should not be allowed.  If the sysctl 
18385 +         option is enabled, a sysctl option with name 
18386 +         "chroot_deny_chroot" is created.
18387 +
18388 +config GRKERNSEC_CHROOT_PIVOT
18389 +       bool "Deny pivot_root in chroot"
18390 +       depends on GRKERNSEC_CHROOT
18391 +       help
18392 +         If you say Y here, processes inside a chroot will not be able to use
18393 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
18394 +         works similar to chroot in that it changes the root filesystem.  This
18395 +         function could be misused in a chrooted process to attempt to break out
18396 +         of the chroot, and therefore should not be allowed.  If the sysctl
18397 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
18398 +         created.
18399 +
18400 +config GRKERNSEC_CHROOT_CHDIR
18401 +       bool "Enforce chdir(\"/\") on all chroots"
18402 +       depends on GRKERNSEC_CHROOT
18403 +       help
18404 +         If you say Y here, the current working directory of all newly-chrooted
18405 +         applications will be set to the the root directory of the chroot.
18406 +         The man page on chroot(2) states:
18407 +         Note that this call does not change  the  current  working
18408 +         directory,  so  that `.' can be outside the tree rooted at
18409 +         `/'.  In particular, the  super-user  can  escape  from  a
18410 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
18411 +
18412 +         It is recommended that you say Y here, since it's not known to break
18413 +         any software.  If the sysctl option is enabled, a sysctl option with
18414 +         name "chroot_enforce_chdir" is created.
18415 +
18416 +config GRKERNSEC_CHROOT_CHMOD
18417 +       bool "Deny (f)chmod +s"
18418 +       depends on GRKERNSEC_CHROOT
18419 +       help
18420 +         If you say Y here, processes inside a chroot will not be able to chmod
18421 +         or fchmod files to make them have suid or sgid bits.  This protects
18422 +         against another published method of breaking a chroot.  If the sysctl
18423 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
18424 +         created.
18425 +
18426 +config GRKERNSEC_CHROOT_FCHDIR
18427 +       bool "Deny fchdir out of chroot"
18428 +       depends on GRKERNSEC_CHROOT
18429 +       help
18430 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
18431 +         to a file descriptor of the chrooting process that points to a directory
18432 +         outside the filesystem will be stopped.  If the sysctl option
18433 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
18434 +
18435 +config GRKERNSEC_CHROOT_MKNOD
18436 +       bool "Deny mknod"
18437 +       depends on GRKERNSEC_CHROOT
18438 +       help
18439 +         If you say Y here, processes inside a chroot will not be allowed to
18440 +         mknod.  The problem with using mknod inside a chroot is that it
18441 +         would allow an attacker to create a device entry that is the same
18442 +         as one on the physical root of your system, which could range from
18443 +         anything from the console device to a device for your harddrive (which
18444 +         they could then use to wipe the drive or steal data).  It is recommended
18445 +         that you say Y here, unless you run into software incompatibilities.
18446 +         If the sysctl option is enabled, a sysctl option with name
18447 +         "chroot_deny_mknod" is created.
18448 +
18449 +config GRKERNSEC_CHROOT_SHMAT
18450 +       bool "Deny shmat() out of chroot"
18451 +       depends on GRKERNSEC_CHROOT
18452 +       help
18453 +         If you say Y here, processes inside a chroot will not be able to attach
18454 +         to shared memory segments that were created outside of the chroot jail.
18455 +         It is recommended that you say Y here.  If the sysctl option is enabled,
18456 +         a sysctl option with name "chroot_deny_shmat" is created.
18457 +
18458 +config GRKERNSEC_CHROOT_UNIX
18459 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
18460 +       depends on GRKERNSEC_CHROOT
18461 +       help
18462 +         If you say Y here, processes inside a chroot will not be able to
18463 +         connect to abstract (meaning not belonging to a filesystem) Unix
18464 +         domain sockets that were bound outside of a chroot.  It is recommended
18465 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
18466 +         with name "chroot_deny_unix" is created.
18467 +
18468 +config GRKERNSEC_CHROOT_FINDTASK
18469 +       bool "Protect outside processes"
18470 +       depends on GRKERNSEC_CHROOT
18471 +       help
18472 +         If you say Y here, processes inside a chroot will not be able to
18473 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
18474 +         getsid, or view any process outside of the chroot.  If the sysctl
18475 +         option is enabled, a sysctl option with name "chroot_findtask" is
18476 +         created.
18477 +
18478 +config GRKERNSEC_CHROOT_NICE
18479 +       bool "Restrict priority changes"
18480 +       depends on GRKERNSEC_CHROOT
18481 +       help
18482 +         If you say Y here, processes inside a chroot will not be able to raise
18483 +         the priority of processes in the chroot, or alter the priority of
18484 +         processes outside the chroot.  This provides more security than simply
18485 +         removing CAP_SYS_NICE from the process' capability set.  If the
18486 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
18487 +         is created.
18488 +
18489 +config GRKERNSEC_CHROOT_SYSCTL
18490 +       bool "Deny sysctl writes"
18491 +       depends on GRKERNSEC_CHROOT
18492 +       help
18493 +         If you say Y here, an attacker in a chroot will not be able to
18494 +         write to sysctl entries, either by sysctl(2) or through a /proc
18495 +         interface.  It is strongly recommended that you say Y here. If the
18496 +         sysctl option is enabled, a sysctl option with name
18497 +         "chroot_deny_sysctl" is created.
18498 +
18499 +config GRKERNSEC_CHROOT_CAPS
18500 +       bool "Capability restrictions"
18501 +       depends on GRKERNSEC_CHROOT
18502 +       help
18503 +         If you say Y here, the capabilities on all root processes within a
18504 +         chroot jail will be lowered to stop module insertion, raw i/o,
18505 +         system and net admin tasks, rebooting the system, modifying immutable
18506 +         files, modifying IPC owned by another, and changing the system time.
18507 +         This is left an option because it can break some apps.  Disable this
18508 +         if your chrooted apps are having problems performing those kinds of
18509 +         tasks.  If the sysctl option is enabled, a sysctl option with
18510 +         name "chroot_caps" is created.
18511 +
18512 +endmenu
18513 +menu "Kernel Auditing"
18514 +depends on GRKERNSEC
18515 +
18516 +config GRKERNSEC_AUDIT_GROUP
18517 +       bool "Single group for auditing"
18518 +       help
18519 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
18520 +         will only operate on a group you specify.  This option is recommended
18521 +         if you only want to watch certain users instead of having a large
18522 +         amount of logs from the entire system.  If the sysctl option is enabled,
18523 +         a sysctl option with name "audit_group" is created.
18524 +
18525 +config GRKERNSEC_AUDIT_GID
18526 +       int "GID for auditing"
18527 +       depends on GRKERNSEC_AUDIT_GROUP
18528 +       default 1007
18529 +
18530 +config GRKERNSEC_EXECLOG
18531 +       bool "Exec logging"
18532 +       help
18533 +         If you say Y here, all execve() calls will be logged (since the
18534 +         other exec*() calls are frontends to execve(), all execution
18535 +         will be logged).  Useful for shell-servers that like to keep track
18536 +         of their users.  If the sysctl option is enabled, a sysctl option with
18537 +         name "exec_logging" is created.
18538 +         WARNING: This option when enabled will produce a LOT of logs, especially
18539 +         on an active system.
18540 +
18541 +config GRKERNSEC_RESLOG
18542 +       bool "Resource logging"
18543 +       help
18544 +         If you say Y here, all attempts to overstep resource limits will
18545 +         be logged with the resource name, the requested size, and the current
18546 +         limit.  It is highly recommended that you say Y here.  If the sysctl
18547 +         option is enabled, a sysctl option with name "resource_logging" is
18548 +         created.  If the RBAC system is enabled, the sysctl value is ignored.
18549 +
18550 +config GRKERNSEC_CHROOT_EXECLOG
18551 +       bool "Log execs within chroot"
18552 +       help
18553 +         If you say Y here, all executions inside a chroot jail will be logged
18554 +         to syslog.  This can cause a large amount of logs if certain
18555 +         applications (eg. djb's daemontools) are installed on the system, and
18556 +         is therefore left as an option.  If the sysctl option is enabled, a
18557 +         sysctl option with name "chroot_execlog" is created.
18558 +
18559 +config GRKERNSEC_AUDIT_CHDIR
18560 +       bool "Chdir logging"
18561 +       help
18562 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
18563 +         option is enabled, a sysctl option with name "audit_chdir" is created.
18564 +
18565 +config GRKERNSEC_AUDIT_MOUNT
18566 +       bool "(Un)Mount logging"
18567 +       help
18568 +         If you say Y here, all mounts and unmounts will be logged.  If the
18569 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
18570 +         created.
18571 +
18572 +config GRKERNSEC_AUDIT_IPC
18573 +       bool "IPC logging"
18574 +       help
18575 +         If you say Y here, creation and removal of message queues, semaphores,
18576 +         and shared memory will be logged.  If the sysctl option is enabled, a
18577 +         sysctl option with name "audit_ipc" is created.
18578 +
18579 +config GRKERNSEC_SIGNAL
18580 +       bool "Signal logging"
18581 +       help
18582 +         If you say Y here, certain important signals will be logged, such as
18583 +         SIGSEGV, which will as a result inform you of when a error in a program
18584 +         occurred, which in some cases could mean a possible exploit attempt.
18585 +         If the sysctl option is enabled, a sysctl option with name
18586 +         "signal_logging" is created.
18587 +
18588 +config GRKERNSEC_FORKFAIL
18589 +       bool "Fork failure logging"
18590 +       help
18591 +         If you say Y here, all failed fork() attempts will be logged.
18592 +         This could suggest a fork bomb, or someone attempting to overstep
18593 +         their process limit.  If the sysctl option is enabled, a sysctl option
18594 +         with name "forkfail_logging" is created.
18595 +
18596 +config GRKERNSEC_TIME
18597 +       bool "Time change logging"
18598 +       help
18599 +         If you say Y here, any changes of the system clock will be logged.
18600 +         If the sysctl option is enabled, a sysctl option with name
18601 +         "timechange_logging" is created.
18602 +
18603 +config GRKERNSEC_PROC_IPADDR
18604 +       bool "/proc/<pid>/ipaddr support"
18605 +       help
18606 +         If you say Y here, a new entry will be added to each /proc/<pid>
18607 +         directory that contains the IP address of the person using the task.
18608 +         The IP is carried across local TCP and AF_UNIX stream sockets.
18609 +         This information can be useful for IDS/IPSes to perform remote response
18610 +         to a local attack.  The entry is readable by only the owner of the
18611 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
18612 +         the RBAC system), and thus does not create privacy concerns.
18613 +
18614 +config GRKERNSEC_AUDIT_TEXTREL
18615 +       bool 'ELF text relocations logging (READ HELP)'
18616 +       depends on PAX_MPROTECT
18617 +       help
18618 +         If you say Y here, text relocations will be logged with the filename
18619 +         of the offending library or binary.  The purpose of the feature is
18620 +         to help Linux distribution developers get rid of libraries and
18621 +         binaries that need text relocations which hinder the future progress
18622 +         of PaX.  Only Linux distribution developers should say Y here, and
18623 +         never on a production machine, as this option creates an information
18624 +         leak that could aid an attacker in defeating the randomization of
18625 +         a single memory region.  If the sysctl option is enabled, a sysctl
18626 +         option with name "audit_textrel" is created.
18627 +
18628 +endmenu
18629 +
18630 +menu "Executable Protections"
18631 +depends on GRKERNSEC
18632 +
18633 +config GRKERNSEC_EXECVE
18634 +       bool "Enforce RLIMIT_NPROC on execs"
18635 +       help
18636 +         If you say Y here, users with a resource limit on processes will
18637 +         have the value checked during execve() calls.  The current system
18638 +         only checks the system limit during fork() calls.  If the sysctl option
18639 +         is enabled, a sysctl option with name "execve_limiting" is created.
18640 +
18641 +config GRKERNSEC_SHM
18642 +       bool "Destroy unused shared memory"
18643 +       depends on SYSVIPC
18644 +       help
18645 +         If you say Y here, shared memory will be destroyed when no one is
18646 +         attached to it.  Otherwise, resources involved with the shared
18647 +         memory can be used up and not be associated with any process (as the
18648 +         shared memory still exists, and the creating process has exited).  If
18649 +         the sysctl option is enabled, a sysctl option with name
18650 +         "destroy_unused_shm" is created.
18651 +
18652 +config GRKERNSEC_DMESG
18653 +       bool "Dmesg(8) restriction"
18654 +       help
18655 +         If you say Y here, non-root users will not be able to use dmesg(8)
18656 +         to view up to the last 4kb of messages in the kernel's log buffer.
18657 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
18658 +         created.
18659 +
18660 +config GRKERNSEC_RANDPID
18661 +       bool "Randomized PIDs"
18662 +       help
18663 +         If you say Y here, all PIDs created on the system will be
18664 +         pseudo-randomly generated.  This is extremely effective along
18665 +         with the /proc restrictions to disallow an attacker from guessing
18666 +         pids of daemons, etc.  PIDs are also used in some cases as part
18667 +         of a naming system for temporary files, so this option would keep
18668 +         those filenames from being predicted as well.  We also use code
18669 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
18670 +         option is enabled, a sysctl option with name "rand_pids" is created.
18671 +
18672 +config GRKERNSEC_TPE
18673 +       bool "Trusted Path Execution (TPE)"
18674 +       help
18675 +         If you say Y here, you will be able to choose a gid to add to the
18676 +         supplementary groups of users you want to mark as "untrusted."
18677 +         These users will not be able to execute any files that are not in
18678 +         root-owned directories writable only by root.  If the sysctl option
18679 +         is enabled, a sysctl option with name "tpe" is created.
18680 +
18681 +config GRKERNSEC_TPE_ALL
18682 +       bool "Partially restrict non-root users"
18683 +       depends on GRKERNSEC_TPE
18684 +       help
18685 +         If you say Y here, All non-root users other than the ones in the
18686 +         group specified in the main TPE option will only be allowed to
18687 +         execute files in directories they own that are not group or
18688 +         world-writable, or in directories owned by root and writable only by
18689 +         root.  If the sysctl option is enabled, a sysctl option with name
18690 +         "tpe_restrict_all" is created.
18691 +
18692 +config GRKERNSEC_TPE_INVERT
18693 +       bool "Invert GID option"
18694 +       depends on GRKERNSEC_TPE
18695 +       help
18696 +         If you say Y here, the group you specify in the TPE configuration will
18697 +         decide what group TPE restrictions will be *disabled* for.  This
18698 +         option is useful if you want TPE restrictions to be applied to most
18699 +         users on the system.
18700 +
18701 +config GRKERNSEC_TPE_GID
18702 +       int "GID for untrusted users"
18703 +       depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
18704 +       default 1005
18705 +       help
18706 +         If you have selected the "Invert GID option" above, setting this
18707 +         GID determines what group TPE restrictions will be *disabled* for.
18708 +         If you have not selected the "Invert GID option" above, setting this
18709 +         GID determines what group TPE restrictions will be *enabled* for.
18710 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
18711 +         is created.
18712 +
18713 +config GRKERNSEC_TPE_GID
18714 +       int "GID for trusted users"
18715 +       depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
18716 +       default 1005
18717 +       help
18718 +         If you have selected the "Invert GID option" above, setting this
18719 +         GID determines what group TPE restrictions will be *disabled* for.
18720 +         If you have not selected the "Invert GID option" above, setting this
18721 +         GID determines what group TPE restrictions will be *enabled* for.
18722 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
18723 +         is created.
18724 +
18725 +endmenu
18726 +menu "Network Protections"
18727 +depends on GRKERNSEC
18728 +
18729 +config GRKERNSEC_RANDNET
18730 +       bool "Larger entropy pools"
18731 +       help
18732 +         If you say Y here, the entropy pools used for many features of Linux
18733 +         and grsecurity will be doubled in size.  Since several grsecurity
18734 +         features use additional randomness, it is recommended that you say Y
18735 +         here.  Saying Y here has a similar effect as modifying
18736 +         /proc/sys/kernel/random/poolsize.
18737 +
18738 +config GRKERNSEC_SOCKET
18739 +       bool "Socket restrictions"
18740 +       help
18741 +         If you say Y here, you will be able to choose from several options.
18742 +         If you assign a GID on your system and add it to the supplementary
18743 +         groups of users you want to restrict socket access to, this patch
18744 +         will perform up to three things, based on the option(s) you choose.
18745 +
18746 +config GRKERNSEC_SOCKET_ALL
18747 +       bool "Deny any sockets to group"
18748 +       depends on GRKERNSEC_SOCKET
18749 +       help
18750 +         If you say Y here, you will be able to choose a GID of whose users will
18751 +         be unable to connect to other hosts from your machine or run server
18752 +         applications from your machine.  If the sysctl option is enabled, a
18753 +         sysctl option with name "socket_all" is created.
18754 +
18755 +config GRKERNSEC_SOCKET_ALL_GID
18756 +       int "GID to deny all sockets for"
18757 +       depends on GRKERNSEC_SOCKET_ALL
18758 +       default 1004
18759 +       help
18760 +         Here you can choose the GID to disable socket access for. Remember to
18761 +         add the users you want socket access disabled for to the GID
18762 +         specified here.  If the sysctl option is enabled, a sysctl option
18763 +         with name "socket_all_gid" is created.
18764 +
18765 +config GRKERNSEC_SOCKET_CLIENT
18766 +       bool "Deny client sockets to group"
18767 +       depends on GRKERNSEC_SOCKET
18768 +       help
18769 +         If you say Y here, you will be able to choose a GID of whose users will
18770 +         be unable to connect to other hosts from your machine, but will be
18771 +         able to run servers.  If this option is enabled, all users in the group
18772 +         you specify will have to use passive mode when initiating ftp transfers
18773 +         from the shell on your machine.  If the sysctl option is enabled, a
18774 +         sysctl option with name "socket_client" is created.
18775 +
18776 +config GRKERNSEC_SOCKET_CLIENT_GID
18777 +       int "GID to deny client sockets for"
18778 +       depends on GRKERNSEC_SOCKET_CLIENT
18779 +       default 1003
18780 +       help
18781 +         Here you can choose the GID to disable client socket access for.
18782 +         Remember to add the users you want client socket access disabled for to
18783 +         the GID specified here.  If the sysctl option is enabled, a sysctl
18784 +         option with name "socket_client_gid" is created.
18785 +
18786 +config GRKERNSEC_SOCKET_SERVER
18787 +       bool "Deny server sockets to group"
18788 +       depends on GRKERNSEC_SOCKET
18789 +       help
18790 +         If you say Y here, you will be able to choose a GID of whose users will
18791 +         be unable to run server applications from your machine.  If the sysctl
18792 +         option is enabled, a sysctl option with name "socket_server" is created.
18793 +
18794 +config GRKERNSEC_SOCKET_SERVER_GID
18795 +       int "GID to deny server sockets for"
18796 +       depends on GRKERNSEC_SOCKET_SERVER
18797 +       default 1002
18798 +       help
18799 +         Here you can choose the GID to disable server socket access for.
18800 +         Remember to add the users you want server socket access disabled for to
18801 +         the GID specified here.  If the sysctl option is enabled, a sysctl
18802 +         option with name "socket_server_gid" is created.
18803 +
18804 +endmenu
18805 +menu "Sysctl support"
18806 +depends on GRKERNSEC && SYSCTL
18807 +
18808 +config GRKERNSEC_SYSCTL
18809 +       bool "Sysctl support"
18810 +       help
18811 +         If you say Y here, you will be able to change the options that
18812 +         grsecurity runs with at bootup, without having to recompile your
18813 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
18814 +         to enable (1) or disable (0) various features.  All the sysctl entries
18815 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
18816 +         All features enabled in the kernel configuration are disabled at boot
18817 +         if you do not say Y to the "Turn on features by default" option.
18818 +         All options should be set at startup, and the grsec_lock entry should
18819 +         be set to a non-zero value after all the options are set.
18820 +         *THIS IS EXTREMELY IMPORTANT*
18821 +
18822 +config GRKERNSEC_SYSCTL_ON
18823 +       bool "Turn on features by default"
18824 +       depends on GRKERNSEC_SYSCTL
18825 +       help
18826 +         If you say Y here, instead of having all features enabled in the
18827 +         kernel configuration disabled at boot time, the features will be
18828 +         enabled at boot time.  It is recommended you say Y here unless
18829 +         there is some reason you would want all sysctl-tunable features to
18830 +         be disabled by default.  As mentioned elsewhere, it is important
18831 +         to enable the grsec_lock entry once you have finished modifying
18832 +         the sysctl entries.
18833 +
18834 +endmenu
18835 +menu "Logging Options"
18836 +depends on GRKERNSEC
18837 +
18838 +config GRKERNSEC_FLOODTIME
18839 +       int "Seconds in between log messages (minimum)"
18840 +       default 10
18841 +       help
18842 +         This option allows you to enforce the number of seconds between
18843 +         grsecurity log messages.  The default should be suitable for most
18844 +         people, however, if you choose to change it, choose a value small enough
18845 +         to allow informative logs to be produced, but large enough to
18846 +         prevent flooding.
18847 +
18848 +config GRKERNSEC_FLOODBURST
18849 +       int "Number of messages in a burst (maximum)"
18850 +       default 4
18851 +       help
18852 +         This option allows you to choose the maximum number of messages allowed
18853 +         within the flood time interval you chose in a separate option.  The
18854 +         default should be suitable for most people, however if you find that
18855 +         many of your logs are being interpreted as flooding, you may want to
18856 +         raise this value.
18857 +
18858 +endmenu
18859 +
18860 +endmenu
18861 diff -urNp linux-2.6.17.11/grsecurity/Makefile linux-2.6.17.11/grsecurity/Makefile
18862 --- linux-2.6.17.11/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
18863 +++ linux-2.6.17.11/grsecurity/Makefile 2006-09-01 16:20:28.000000000 -0400
18864 @@ -0,0 +1,20 @@
18865 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
18866 +# during 2001-2005 it has been completely redesigned by Brad Spengler
18867 +# into an RBAC system
18868 +#
18869 +# All code in this directory and various hooks inserted throughout the kernel
18870 +# are copyright Brad Spengler, and released under the GPL v2 or higher
18871 +
18872 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
18873 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
18874 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
18875 +
18876 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
18877 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
18878 +       gracl_learn.o grsec_log.o
18879 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
18880 +
18881 +ifndef CONFIG_GRKERNSEC
18882 +obj-y += grsec_disabled.o
18883 +endif
18884 +
18885 diff -urNp linux-2.6.17.11/include/asm-alpha/a.out.h linux-2.6.17.11/include/asm-alpha/a.out.h
18886 --- linux-2.6.17.11/include/asm-alpha/a.out.h   2006-08-07 00:18:54.000000000 -0400
18887 +++ linux-2.6.17.11/include/asm-alpha/a.out.h   2006-09-01 16:20:29.000000000 -0400
18888 @@ -98,7 +98,7 @@ struct exec
18889         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
18890                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
18891  
18892 -#define STACK_TOP \
18893 +#define __STACK_TOP \
18894    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
18895  
18896  #endif
18897 diff -urNp linux-2.6.17.11/include/asm-alpha/elf.h linux-2.6.17.11/include/asm-alpha/elf.h
18898 --- linux-2.6.17.11/include/asm-alpha/elf.h     2006-08-07 00:18:54.000000000 -0400
18899 +++ linux-2.6.17.11/include/asm-alpha/elf.h     2006-09-01 16:20:29.000000000 -0400
18900 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
18901  
18902  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
18903  
18904 +#ifdef CONFIG_PAX_ASLR
18905 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
18906 +
18907 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18908 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
18909 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18910 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
18911 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18912 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
18913 +#endif
18914 +
18915  /* $0 is set by ld.so to a pointer to a function which might be 
18916     registered using atexit.  This provides a mean for the dynamic
18917     linker to call DT_FINI functions for shared libraries that have
18918 diff -urNp linux-2.6.17.11/include/asm-alpha/kmap_types.h linux-2.6.17.11/include/asm-alpha/kmap_types.h
18919 --- linux-2.6.17.11/include/asm-alpha/kmap_types.h      2006-08-07 00:18:54.000000000 -0400
18920 +++ linux-2.6.17.11/include/asm-alpha/kmap_types.h      2006-09-01 16:20:29.000000000 -0400
18921 @@ -25,7 +25,8 @@ D(9)  KM_IRQ0,
18922  D(10)  KM_IRQ1,
18923  D(11)  KM_SOFTIRQ0,
18924  D(12)  KM_SOFTIRQ1,
18925 -D(13)  KM_TYPE_NR
18926 +D(13)  KM_CLEARPAGE,
18927 +D(14)  KM_TYPE_NR
18928  };
18929  
18930  #undef D
18931 diff -urNp linux-2.6.17.11/include/asm-alpha/page.h linux-2.6.17.11/include/asm-alpha/page.h
18932 --- linux-2.6.17.11/include/asm-alpha/page.h    2006-08-07 00:18:54.000000000 -0400
18933 +++ linux-2.6.17.11/include/asm-alpha/page.h    2006-09-01 16:20:29.000000000 -0400
18934 @@ -95,6 +95,16 @@ typedef unsigned long pgprot_t;
18935  
18936  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
18937                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18938 +
18939 +#ifdef CONFIG_PAX_PAGEEXEC
18940 +#ifdef CONFIG_PAX_MPROTECT
18941 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18942 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18943 +#else
18944 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18945 +#endif
18946 +#endif
18947 +
18948  #endif /* __KERNEL__ */
18949  
18950  #include <asm-generic/memory_model.h>
18951 diff -urNp linux-2.6.17.11/include/asm-alpha/pgtable.h linux-2.6.17.11/include/asm-alpha/pgtable.h
18952 --- linux-2.6.17.11/include/asm-alpha/pgtable.h 2006-08-07 00:18:54.000000000 -0400
18953 +++ linux-2.6.17.11/include/asm-alpha/pgtable.h 2006-09-01 16:20:29.000000000 -0400
18954 @@ -102,6 +102,17 @@ struct vm_area_struct;
18955  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
18956  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
18957  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
18958 +
18959 +#ifdef CONFIG_PAX_PAGEEXEC
18960 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
18961 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
18962 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
18963 +#else
18964 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18965 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18966 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18967 +#endif
18968 +
18969  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
18970  
18971  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
18972 diff -urNp linux-2.6.17.11/include/asm-arm/a.out.h linux-2.6.17.11/include/asm-arm/a.out.h
18973 --- linux-2.6.17.11/include/asm-arm/a.out.h     2006-08-07 00:18:54.000000000 -0400
18974 +++ linux-2.6.17.11/include/asm-arm/a.out.h     2006-09-01 16:20:29.000000000 -0400
18975 @@ -28,7 +28,7 @@ struct exec
18976  #define M_ARM 103
18977  
18978  #ifdef __KERNEL__
18979 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
18980 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
18981                          TASK_SIZE : TASK_SIZE_26)
18982  #endif
18983  
18984 diff -urNp linux-2.6.17.11/include/asm-arm/elf.h linux-2.6.17.11/include/asm-arm/elf.h
18985 --- linux-2.6.17.11/include/asm-arm/elf.h       2006-08-07 00:18:54.000000000 -0400
18986 +++ linux-2.6.17.11/include/asm-arm/elf.h       2006-09-01 16:20:29.000000000 -0400
18987 @@ -56,6 +56,17 @@ typedef struct user_fp elf_fpregset_t;
18988  
18989  #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
18990  
18991 +#ifdef CONFIG_PAX_ASLR
18992 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x00008000UL
18993 +
18994 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18995 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
18996 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18997 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
18998 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18999 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
19000 +#endif
19001 +
19002  /* When the program starts, a1 contains a pointer to a function to be 
19003     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
19004     have no such handler.  */
19005 diff -urNp linux-2.6.17.11/include/asm-arm/kmap_types.h linux-2.6.17.11/include/asm-arm/kmap_types.h
19006 --- linux-2.6.17.11/include/asm-arm/kmap_types.h        2006-08-07 00:18:54.000000000 -0400
19007 +++ linux-2.6.17.11/include/asm-arm/kmap_types.h        2006-09-01 16:20:29.000000000 -0400
19008 @@ -18,6 +18,7 @@ enum km_type {
19009         KM_IRQ1,
19010         KM_SOFTIRQ0,
19011         KM_SOFTIRQ1,
19012 +       KM_CLEARPAGE,
19013         KM_TYPE_NR
19014  };
19015  
19016 diff -urNp linux-2.6.17.11/include/asm-arm26/kmap_types.h linux-2.6.17.11/include/asm-arm26/kmap_types.h
19017 --- linux-2.6.17.11/include/asm-arm26/kmap_types.h      2006-08-07 00:18:54.000000000 -0400
19018 +++ linux-2.6.17.11/include/asm-arm26/kmap_types.h      2006-09-01 16:20:29.000000000 -0400
19019 @@ -6,7 +6,8 @@
19020   */
19021  enum km_type {
19022          KM_IRQ0,
19023 -        KM_USER1
19024 +        KM_USER1,
19025 +        KM_CLEARPAGE
19026  };
19027  
19028  #endif
19029 diff -urNp linux-2.6.17.11/include/asm-cris/kmap_types.h linux-2.6.17.11/include/asm-cris/kmap_types.h
19030 --- linux-2.6.17.11/include/asm-cris/kmap_types.h       2006-08-07 00:18:54.000000000 -0400
19031 +++ linux-2.6.17.11/include/asm-cris/kmap_types.h       2006-09-01 16:20:29.000000000 -0400
19032 @@ -19,6 +19,7 @@ enum km_type {
19033         KM_IRQ1,
19034         KM_SOFTIRQ0,
19035         KM_SOFTIRQ1,
19036 +       KM_CLEARPAGE,
19037         KM_TYPE_NR
19038  };
19039  
19040 diff -urNp linux-2.6.17.11/include/asm-frv/kmap_types.h linux-2.6.17.11/include/asm-frv/kmap_types.h
19041 --- linux-2.6.17.11/include/asm-frv/kmap_types.h        2006-08-07 00:18:54.000000000 -0400
19042 +++ linux-2.6.17.11/include/asm-frv/kmap_types.h        2006-09-01 16:20:29.000000000 -0400
19043 @@ -23,6 +23,7 @@ enum km_type {
19044         KM_IRQ1,
19045         KM_SOFTIRQ0,
19046         KM_SOFTIRQ1,
19047 +       KM_CLEARPAGE,
19048         KM_TYPE_NR
19049  };
19050  
19051 diff -urNp linux-2.6.17.11/include/asm-h8300/kmap_types.h linux-2.6.17.11/include/asm-h8300/kmap_types.h
19052 --- linux-2.6.17.11/include/asm-h8300/kmap_types.h      2006-08-07 00:18:54.000000000 -0400
19053 +++ linux-2.6.17.11/include/asm-h8300/kmap_types.h      2006-09-01 16:20:29.000000000 -0400
19054 @@ -15,6 +15,7 @@ enum km_type {
19055         KM_IRQ1,
19056         KM_SOFTIRQ0,
19057         KM_SOFTIRQ1,
19058 +       KM_CLEARPAGE,
19059         KM_TYPE_NR
19060  };
19061  
19062 diff -urNp linux-2.6.17.11/include/asm-i386/alternative.h linux-2.6.17.11/include/asm-i386/alternative.h
19063 --- linux-2.6.17.11/include/asm-i386/alternative.h      2006-08-07 00:18:54.000000000 -0400
19064 +++ linux-2.6.17.11/include/asm-i386/alternative.h      2006-09-01 16:20:29.000000000 -0400
19065 @@ -47,7 +47,7 @@ extern void alternatives_smp_switch(int 
19066                       "  .byte 662b-661b\n"       /* sourcelen */       \
19067                       "  .byte 664f-663f\n"       /* replacementlen */  \
19068                       ".previous\n"                                     \
19069 -                     ".section .altinstr_replacement,\"ax\"\n"         \
19070 +                     ".section .altinstr_replacement,\"a\"\n"          \
19071                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
19072                       ".previous" :: "i" (feature) : "memory")
19073  
19074 @@ -71,7 +71,7 @@ extern void alternatives_smp_switch(int 
19075                       "  .byte 662b-661b\n"       /* sourcelen */       \
19076                       "  .byte 664f-663f\n"       /* replacementlen */  \
19077                       ".previous\n"                                     \
19078 -                     ".section .altinstr_replacement,\"ax\"\n"         \
19079 +                     ".section .altinstr_replacement,\"a\"\n"          \
19080                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
19081                       ".previous" :: "i" (feature), ##input)
19082  
19083 @@ -110,7 +110,7 @@ extern void alternatives_smp_switch(int 
19084                       "  .byte 662b-661b\n"       /* sourcelen */       \
19085                       "  .byte 664f-663f\n"       /* replacementlen */  \
19086                       ".previous\n"                                     \
19087 -                     ".section .smp_altinstr_replacement,\"awx\"\n"    \
19088 +                     ".section .smp_altinstr_replacement,\"aw\"\n"     \
19089                       "663:\n\t" upinstr "\n"     /* replacement */     \
19090                       "664:\n\t.fill 662b-661b,1,0x42\n" /* space for original */ \
19091                       ".previous" : args)
19092 diff -urNp linux-2.6.17.11/include/asm-i386/a.out.h linux-2.6.17.11/include/asm-i386/a.out.h
19093 --- linux-2.6.17.11/include/asm-i386/a.out.h    2006-08-07 00:18:54.000000000 -0400
19094 +++ linux-2.6.17.11/include/asm-i386/a.out.h    2006-09-01 16:20:29.000000000 -0400
19095 @@ -19,7 +19,11 @@ struct exec
19096  
19097  #ifdef __KERNEL__
19098  
19099 -#define STACK_TOP      TASK_SIZE
19100 +#ifdef CONFIG_PAX_SEGMEXEC
19101 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
19102 +#else
19103 +#define __STACK_TOP TASK_SIZE
19104 +#endif
19105  
19106  #endif
19107  
19108 diff -urNp linux-2.6.17.11/include/asm-i386/auxvec.h linux-2.6.17.11/include/asm-i386/auxvec.h
19109 --- linux-2.6.17.11/include/asm-i386/auxvec.h   2006-08-07 00:18:54.000000000 -0400
19110 +++ linux-2.6.17.11/include/asm-i386/auxvec.h   2006-09-01 16:20:29.000000000 -0400
19111 @@ -5,7 +5,9 @@
19112   * Architecture-neutral AT_ values in 0-17, leave some room
19113   * for more of them, start the x86-specific ones at 32.
19114   */
19115 +#ifndef CONFIG_PAX_NOVSYSCALL
19116  #define AT_SYSINFO             32
19117  #define AT_SYSINFO_EHDR                33
19118 +#endif
19119  
19120  #endif
19121 diff -urNp linux-2.6.17.11/include/asm-i386/bug.h linux-2.6.17.11/include/asm-i386/bug.h
19122 --- linux-2.6.17.11/include/asm-i386/bug.h      2006-08-07 00:18:54.000000000 -0400
19123 +++ linux-2.6.17.11/include/asm-i386/bug.h      2006-09-01 16:20:31.000000000 -0400
19124 @@ -12,10 +12,9 @@
19125  #ifdef CONFIG_BUG
19126  #define HAVE_ARCH_BUG
19127  #ifdef CONFIG_DEBUG_BUGVERBOSE
19128 -#define BUG()                          \
19129 - __asm__ __volatile__( "ud2\n"         \
19130 -                       "\t.word %c0\n" \
19131 -                       "\t.long %c1\n" \
19132 +#define BUG()                                  \
19133 + __asm__ __volatile__( "ud2\n\t"               \
19134 +                       "ljmp %0, %1\n\t"       \
19135                          : : "i" (__LINE__), "i" (__FILE__))
19136  #else
19137  #define BUG() __asm__ __volatile__("ud2\n")
19138 diff -urNp linux-2.6.17.11/include/asm-i386/checksum.h linux-2.6.17.11/include/asm-i386/checksum.h
19139 --- linux-2.6.17.11/include/asm-i386/checksum.h 2006-08-07 00:18:54.000000000 -0400
19140 +++ linux-2.6.17.11/include/asm-i386/checksum.h 2006-09-01 16:20:29.000000000 -0400
19141 @@ -30,6 +30,12 @@ asmlinkage unsigned int csum_partial(con
19142  asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned char *dst,
19143                                                   int len, int sum, int *src_err_ptr, int *dst_err_ptr);
19144  
19145 +asmlinkage unsigned int csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
19146 +                                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
19147 +
19148 +asmlinkage unsigned int csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
19149 +                                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
19150 +
19151  /*
19152   *     Note: when you get a NULL pointer exception here this means someone
19153   *     passed in an incorrect kernel address to one of these functions.
19154 @@ -49,7 +55,7 @@ unsigned int csum_partial_copy_from_user
19155                                                 int len, int sum, int *err_ptr)
19156  {
19157         might_sleep();
19158 -       return csum_partial_copy_generic((__force unsigned char *)src, dst,
19159 +       return csum_partial_copy_generic_from_user((__force unsigned char *)src, dst,
19160                                         len, sum, err_ptr, NULL);
19161  }
19162  
19163 @@ -183,7 +189,7 @@ static __inline__ unsigned int csum_and_
19164  {
19165         might_sleep();
19166         if (access_ok(VERIFY_WRITE, dst, len))
19167 -               return csum_partial_copy_generic(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
19168 +               return csum_partial_copy_generic_to_user(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
19169  
19170         if (len)
19171                 *err_ptr = -EFAULT;
19172 diff -urNp linux-2.6.17.11/include/asm-i386/desc.h linux-2.6.17.11/include/asm-i386/desc.h
19173 --- linux-2.6.17.11/include/asm-i386/desc.h     2006-08-07 00:18:54.000000000 -0400
19174 +++ linux-2.6.17.11/include/asm-i386/desc.h     2006-09-01 16:20:29.000000000 -0400
19175 @@ -10,11 +10,13 @@
19176  
19177  #include <linux/preempt.h>
19178  #include <linux/smp.h>
19179 -#include <linux/percpu.h>
19180 +#include <linux/sched.h>
19181  
19182  #include <asm/mmu.h>
19183 +#include <asm/pgtable.h>
19184 +#include <asm/tlbflush.h>
19185  
19186 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
19187 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
19188  
19189  DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
19190  
19191 @@ -24,13 +26,53 @@ struct Xgt_desc_struct {
19192         unsigned short pad;
19193  } __attribute__ ((packed));
19194  
19195 -extern struct Xgt_desc_struct idt_descr;
19196 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
19197 -
19198 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
19199  
19200  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
19201  {
19202 -       return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
19203 +       return cpu_gdt_table[cpu];
19204 +}
19205 +
19206 +#define pax_open_kernel(cr0)           \
19207 +do {                                   \
19208 +       typecheck(unsigned long,cr0);   \
19209 +       preempt_disable();              \
19210 +       cr0 = read_cr0();               \
19211 +       write_cr0(cr0 & ~0x10000UL);    \
19212 +} while(0)
19213 +
19214 +#define pax_close_kernel(cr0)          \
19215 +do {                                   \
19216 +       typecheck(unsigned long,cr0);   \
19217 +       write_cr0(cr0);                 \
19218 +       preempt_enable_no_resched();    \
19219 +} while(0)
19220 +
19221 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
19222 +{
19223 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19224 +       unsigned long base = mm->context.user_cs_base;
19225 +       unsigned long limit = mm->context.user_cs_limit;
19226 +
19227 +#ifdef CONFIG_PAX_KERNEXEC
19228 +       unsigned long cr0;
19229 +
19230 +       pax_open_kernel(cr0);
19231 +#endif
19232 +
19233 +       if (likely(limit)) {
19234 +               limit -= 1UL;
19235 +               limit >>= 12;
19236 +       }
19237 +
19238 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
19239 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
19240 +
19241 +#ifdef CONFIG_PAX_KERNEXEC
19242 +       pax_close_kernel(cr0);
19243 +#endif
19244 +
19245 +#endif
19246  }
19247  
19248  #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
19249 @@ -50,7 +92,7 @@ static inline struct desc_struct *get_cp
19250   * This is the ldt that every process will get unless we need
19251   * something other than this.
19252   */
19253 -extern struct desc_struct default_ldt[];
19254 +extern const struct desc_struct default_ldt[];
19255  extern void set_intr_gate(unsigned int irq, void * addr);
19256  
19257  #define _set_tssldt_desc(n,addr,limit,type) \
19258 @@ -64,7 +106,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
19259         "rorl $16,%1" \
19260         : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
19261  
19262 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
19263 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
19264  {
19265         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
19266                 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
19267 @@ -72,11 +114,28 @@ static inline void __set_tss_desc(unsign
19268  
19269  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
19270  
19271 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
19272 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
19273  {
19274         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
19275  }
19276  
19277 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
19278 +{
19279 +
19280 +#ifdef CONFIG_PAX_KERNEXEC
19281 +       unsigned long cr0;
19282 +
19283 +       pax_open_kernel(cr0);
19284 +#endif
19285 +
19286 +       _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
19287 +
19288 +#ifdef CONFIG_PAX_KERNEXEC
19289 +       pax_close_kernel(cr0);
19290 +#endif
19291 +
19292 +}
19293 +
19294  #define LDT_entry_a(info) \
19295         ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
19296  
19297 @@ -90,7 +149,7 @@ static inline void set_ldt_desc(unsigned
19298         ((info)->seg_32bit << 22) | \
19299         ((info)->limit_in_pages << 23) | \
19300         ((info)->useable << 20) | \
19301 -       0x7000)
19302 +       0x7100)
19303  
19304  #define LDT_empty(info) (\
19305         (info)->base_addr       == 0    && \
19306 @@ -134,7 +193,7 @@ static inline void clear_LDT(void)
19307   */
19308  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
19309  {
19310 -       void *segments = pc->ldt;
19311 +       const void *segments = pc->ldt;
19312         int count = pc->size;
19313  
19314         if (likely(!count)) {
19315 @@ -162,6 +221,22 @@ static inline unsigned long get_desc_bas
19316         return base;
19317  }
19318  
19319 +static inline void _load_LDT(mm_context_t *pc)
19320 +{
19321 +       int cpu = get_cpu();
19322 +       const void *segments = pc->ldt;
19323 +       int count = pc->size;
19324 +
19325 +       if (likely(!count)) {
19326 +               segments = &default_ldt[0];
19327 +               count = 5;
19328 +       }
19329 +               
19330 +       __set_ldt_desc(cpu, segments, count);
19331 +       load_LDT_desc();
19332 +       put_cpu();
19333 +}
19334 +
19335  #endif /* !__ASSEMBLY__ */
19336  
19337  #endif
19338 diff -urNp linux-2.6.17.11/include/asm-i386/elf.h linux-2.6.17.11/include/asm-i386/elf.h
19339 --- linux-2.6.17.11/include/asm-i386/elf.h      2006-08-07 00:18:54.000000000 -0400
19340 +++ linux-2.6.17.11/include/asm-i386/elf.h      2006-09-01 16:20:29.000000000 -0400
19341 @@ -73,6 +73,17 @@ typedef struct user_fxsr_struct elf_fpxr
19342  
19343  #define ELF_ET_DYN_BASE                ((TASK_UNMAPPED_BASE) * 2)
19344  
19345 +#ifdef CONFIG_PAX_ASLR
19346 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
19347 +
19348 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
19349 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
19350 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
19351 +#define PAX_DELTA_EXEC_LEN(tsk)                15
19352 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
19353 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
19354 +#endif
19355 +
19356  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
19357     now struct_user_regs, they are different) */
19358  
19359 @@ -131,7 +146,14 @@ extern int dump_task_extended_fpu (struc
19360  
19361  #define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
19362  #define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
19363 +
19364 +#ifndef CONFIG_PAX_NOVSYSCALL
19365 +#ifdef CONFIG_PAX_SEGMEXEC
19366 +#define VSYSCALL_ENTRY ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
19367 +#else
19368  #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
19369 +#endif
19370 +
19371  extern void __kernel_vsyscall;
19372  
19373  #define ARCH_DLINFO                                            \
19374 @@ -187,3 +209,5 @@ do {                                                                              \
19375  #endif
19376  
19377  #endif
19378 +
19379 +#endif
19380 diff -urNp linux-2.6.17.11/include/asm-i386/i387.h linux-2.6.17.11/include/asm-i386/i387.h
19381 --- linux-2.6.17.11/include/asm-i386/i387.h     2006-08-07 00:18:54.000000000 -0400
19382 +++ linux-2.6.17.11/include/asm-i386/i387.h     2006-09-01 16:20:29.000000000 -0400
19383 @@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
19384  #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
19385  
19386  /* We need a safe address that is cheap to find and that is already
19387 -   in L1 during context switch. The best choices are unfortunately
19388 -   different for UP and SMP */
19389 -#ifdef CONFIG_SMP
19390 -#define safe_address (__per_cpu_offset[0])
19391 -#else
19392 -#define safe_address (kstat_cpu(0).cpustat.user)
19393 -#endif
19394 +   in L1 during context switch. */
19395 +#define safe_address (init_tss[smp_processor_id()].esp0)
19396  
19397  /*
19398   * These must be called with preempt disabled
19399 diff -urNp linux-2.6.17.11/include/asm-i386/kmap_types.h linux-2.6.17.11/include/asm-i386/kmap_types.h
19400 --- linux-2.6.17.11/include/asm-i386/kmap_types.h       2006-08-07 00:18:54.000000000 -0400
19401 +++ linux-2.6.17.11/include/asm-i386/kmap_types.h       2006-09-01 16:20:29.000000000 -0400
19402 @@ -23,7 +23,8 @@ D(9)  KM_IRQ0,
19403  D(10)  KM_IRQ1,
19404  D(11)  KM_SOFTIRQ0,
19405  D(12)  KM_SOFTIRQ1,
19406 -D(13)  KM_TYPE_NR
19407 +D(13)  KM_CLEARPAGE,
19408 +D(14)  KM_TYPE_NR
19409  };
19410  
19411  #undef D
19412 diff -urNp linux-2.6.17.11/include/asm-i386/mach-default/apm.h linux-2.6.17.11/include/asm-i386/mach-default/apm.h
19413 --- linux-2.6.17.11/include/asm-i386/mach-default/apm.h 2006-08-07 00:18:54.000000000 -0400
19414 +++ linux-2.6.17.11/include/asm-i386/mach-default/apm.h 2006-09-01 16:20:29.000000000 -0400
19415 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
19416         __asm__ __volatile__(APM_DO_ZERO_SEGS
19417                 "pushl %%edi\n\t"
19418                 "pushl %%ebp\n\t"
19419 -               "lcall *%%cs:apm_bios_entry\n\t"
19420 +               "lcall *%%ss:apm_bios_entry\n\t"
19421                 "setc %%al\n\t"
19422                 "popl %%ebp\n\t"
19423                 "popl %%edi\n\t"
19424 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
19425         __asm__ __volatile__(APM_DO_ZERO_SEGS
19426                 "pushl %%edi\n\t"
19427                 "pushl %%ebp\n\t"
19428 -               "lcall *%%cs:apm_bios_entry\n\t"
19429 +               "lcall *%%ss:apm_bios_entry\n\t"
19430                 "setc %%bl\n\t"
19431                 "popl %%ebp\n\t"
19432                 "popl %%edi\n\t"
19433 diff -urNp linux-2.6.17.11/include/asm-i386/mach-default/do_timer.h linux-2.6.17.11/include/asm-i386/mach-default/do_timer.h
19434 --- linux-2.6.17.11/include/asm-i386/mach-default/do_timer.h    2006-08-07 00:18:54.000000000 -0400
19435 +++ linux-2.6.17.11/include/asm-i386/mach-default/do_timer.h    2006-09-01 16:20:29.000000000 -0400
19436 @@ -18,7 +18,7 @@ static inline void do_timer_interrupt_ho
19437  {
19438         do_timer(regs);
19439  #ifndef CONFIG_SMP
19440 -       update_process_times(user_mode_vm(regs));
19441 +       update_process_times(user_mode(regs));
19442  #endif
19443  /*
19444   * In the SMP case we use the local APIC timer interrupt to do the
19445 diff -urNp linux-2.6.17.11/include/asm-i386/mach-visws/do_timer.h linux-2.6.17.11/include/asm-i386/mach-visws/do_timer.h
19446 --- linux-2.6.17.11/include/asm-i386/mach-visws/do_timer.h      2006-08-07 00:18:54.000000000 -0400
19447 +++ linux-2.6.17.11/include/asm-i386/mach-visws/do_timer.h      2006-09-01 16:20:29.000000000 -0400
19448 @@ -11,7 +11,7 @@ static inline void do_timer_interrupt_ho
19449  
19450         do_timer(regs);
19451  #ifndef CONFIG_SMP
19452 -       update_process_times(user_mode_vm(regs));
19453 +       update_process_times(user_mode(regs));
19454  #endif
19455  /*
19456   * In the SMP case we use the local APIC timer interrupt to do the
19457 diff -urNp linux-2.6.17.11/include/asm-i386/mach-voyager/do_timer.h linux-2.6.17.11/include/asm-i386/mach-voyager/do_timer.h
19458 --- linux-2.6.17.11/include/asm-i386/mach-voyager/do_timer.h    2006-08-07 00:18:54.000000000 -0400
19459 +++ linux-2.6.17.11/include/asm-i386/mach-voyager/do_timer.h    2006-09-01 16:20:29.000000000 -0400
19460 @@ -5,7 +5,7 @@ static inline void do_timer_interrupt_ho
19461  {
19462         do_timer(regs);
19463  #ifndef CONFIG_SMP
19464 -       update_process_times(user_mode_vm(regs));
19465 +       update_process_times(user_mode(regs));
19466  #endif
19467  
19468         voyager_timer_interrupt(regs);
19469 diff -urNp linux-2.6.17.11/include/asm-i386/mman.h linux-2.6.17.11/include/asm-i386/mman.h
19470 --- linux-2.6.17.11/include/asm-i386/mman.h     2006-08-07 00:18:54.000000000 -0400
19471 +++ linux-2.6.17.11/include/asm-i386/mman.h     2006-09-01 16:20:29.000000000 -0400
19472 @@ -11,6 +11,10 @@
19473  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
19474  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
19475  
19476 +#ifdef CONFIG_PAX_SEGMEXEC
19477 +#define MAP_MIRROR     0x20000
19478 +#endif
19479 +
19480  #define MCL_CURRENT    1               /* lock all current mappings */
19481  #define MCL_FUTURE     2               /* lock all future mappings */
19482  
19483 diff -urNp linux-2.6.17.11/include/asm-i386/mmu_context.h linux-2.6.17.11/include/asm-i386/mmu_context.h
19484 --- linux-2.6.17.11/include/asm-i386/mmu_context.h      2006-08-07 00:18:54.000000000 -0400
19485 +++ linux-2.6.17.11/include/asm-i386/mmu_context.h      2006-09-01 16:20:29.000000000 -0400
19486 @@ -46,6 +46,18 @@ static inline void switch_mm(struct mm_s
19487                  */
19488                 if (unlikely(prev->context.ldt != next->context.ldt))
19489                         load_LDT_nolock(&next->context, cpu);
19490 +
19491 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
19492 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
19493 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
19494 +#endif
19495 +
19496 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19497 +               if (prev->context.user_cs_base != next->context.user_cs_base ||
19498 +                   prev->context.user_cs_limit != next->context.user_cs_limit)
19499 +#endif
19500 +
19501 +                       set_user_cs(next, cpu);
19502         }
19503  #ifdef CONFIG_SMP
19504         else {
19505 @@ -58,6 +70,12 @@ static inline void switch_mm(struct mm_s
19506                          */
19507                         load_cr3(next->pgd);
19508                         load_LDT_nolock(&next->context, cpu);
19509 +
19510 +#ifdef CONFIG_PAX_PAGEEXEC
19511 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
19512 +#endif
19513 +
19514 +                       set_user_cs(next, cpu);
19515                 }
19516         }
19517  #endif
19518 diff -urNp linux-2.6.17.11/include/asm-i386/mmu.h linux-2.6.17.11/include/asm-i386/mmu.h
19519 --- linux-2.6.17.11/include/asm-i386/mmu.h      2006-08-07 00:18:54.000000000 -0400
19520 +++ linux-2.6.17.11/include/asm-i386/mmu.h      2006-09-01 16:20:29.000000000 -0400
19521 @@ -12,6 +12,17 @@ typedef struct { 
19522         int size;
19523         struct semaphore sem;
19524         void *ldt;
19525 +
19526 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19527 +       unsigned long user_cs_base;
19528 +       unsigned long user_cs_limit;
19529 +
19530 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
19531 +       cpumask_t cpu_user_cs_mask;
19532 +#endif
19533 +
19534 +#endif
19535 +
19536  } mm_context_t;
19537  
19538  #endif
19539 diff -urNp linux-2.6.17.11/include/asm-i386/module.h linux-2.6.17.11/include/asm-i386/module.h
19540 --- linux-2.6.17.11/include/asm-i386/module.h   2006-08-07 00:18:54.000000000 -0400
19541 +++ linux-2.6.17.11/include/asm-i386/module.h   2006-09-01 16:20:29.000000000 -0400
19542 @@ -72,6 +72,12 @@ struct mod_arch_specific
19543  #define MODULE_STACKSIZE ""
19544  #endif
19545  
19546 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
19547 +#ifdef CONFIG_GRKERNSEC
19548 +#define MODULE_GRSEC "GRSECURITY "
19549 +#else
19550 +#define MODULE_GRSEC ""
19551 +#endif
19552 +
19553 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
19554  
19555  #endif /* _ASM_I386_MODULE_H */
19556 diff -urNp linux-2.6.17.11/include/asm-i386/page.h linux-2.6.17.11/include/asm-i386/page.h
19557 --- linux-2.6.17.11/include/asm-i386/page.h     2006-08-07 00:18:54.000000000 -0400
19558 +++ linux-2.6.17.11/include/asm-i386/page.h     2006-09-01 16:20:31.000000000 -0400
19559 @@ -52,13 +52,14 @@ typedef struct { unsigned long long pgpr
19560  #define pmd_val(x)     ((x).pmd)
19561  #define pte_val(x)     ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
19562  #define __pmd(x) ((pmd_t) { (x) } )
19563 +#define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
19564  #define HPAGE_SHIFT    21
19565  #else
19566  typedef struct { unsigned long pte_low; } pte_t;
19567  typedef struct { unsigned long pgd; } pgd_t;
19568  typedef struct { unsigned long pgprot; } pgprot_t;
19569 -#define boot_pte_t pte_t /* or would you rather have a typedef */
19570  #define pte_val(x)     ((x).pte_low)
19571 +#define __pte(x) ((pte_t) { (x) } )
19572  #define HPAGE_SHIFT    22
19573  #endif
19574  #define PTE_MASK       PAGE_MASK
19575 @@ -73,7 +74,6 @@ typedef struct { unsigned long pgprot; }
19576  #define pgd_val(x)     ((x).pgd)
19577  #define pgprot_val(x)  ((x).pgprot)
19578  
19579 -#define __pte(x) ((pte_t) { (x) } )
19580  #define __pgd(x) ((pgd_t) { (x) } )
19581  #define __pgprot(x)    ((pgprot_t) { (x) } )
19582  
19583 @@ -118,6 +118,15 @@ extern int page_is_ram(unsigned long pag
19584  #endif
19585  #define __KERNEL_START         (__PAGE_OFFSET + __PHYSICAL_START)
19586  
19587 +#ifdef CONFIG_PAX_KERNEXEC
19588 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + ((__PHYSICAL_START + ~(4*1024*1024)) & (4*1024*1024)))
19589 +#ifndef __ASSEMBLY__
19590 +extern unsigned char MODULES_VADDR[];
19591 +extern unsigned char MODULES_END[];
19592 +#endif
19593 +#else
19594 +#define __KERNEL_TEXT_OFFSET   (0)
19595 +#endif
19596  
19597  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
19598  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
19599 @@ -137,6 +146,19 @@ extern int page_is_ram(unsigned long pag
19600         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
19601                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
19602  
19603 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19604 +#ifdef CONFIG_PAX_MPROTECT
19605 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
19606 +                         ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
19607 +#else
19608 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
19609 +#endif
19610 +#endif
19611 +
19612 +#ifdef CONFIG_PAX_PAGEEXEC
19613 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
19614 +#endif
19615 +
19616  #endif /* __KERNEL__ */
19617  
19618  #include <asm-generic/memory_model.h>
19619 diff -urNp linux-2.6.17.11/include/asm-i386/pgalloc.h linux-2.6.17.11/include/asm-i386/pgalloc.h
19620 --- linux-2.6.17.11/include/asm-i386/pgalloc.h  2006-08-07 00:18:54.000000000 -0400
19621 +++ linux-2.6.17.11/include/asm-i386/pgalloc.h  2006-09-01 16:20:29.000000000 -0400
19622 @@ -3,11 +3,17 @@
19623  
19624  #include <linux/config.h>
19625  #include <asm/fixmap.h>
19626 +#include <asm/desc.h>
19627  #include <linux/threads.h>
19628  #include <linux/mm.h>          /* for struct page */
19629  
19630 +#ifdef CONFIG_PAX_NOVSYSCALL
19631 +#define pmd_populate_kernel(mm, pmd, pte) \
19632 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
19633 +#else
19634  #define pmd_populate_kernel(mm, pmd, pte) \
19635                 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
19636 +#endif
19637  
19638  #define pmd_populate(mm, pmd, pte)                             \
19639         set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
19640 diff -urNp linux-2.6.17.11/include/asm-i386/pgtable.h linux-2.6.17.11/include/asm-i386/pgtable.h
19641 --- linux-2.6.17.11/include/asm-i386/pgtable.h  2006-08-07 00:18:54.000000000 -0400
19642 +++ linux-2.6.17.11/include/asm-i386/pgtable.h  2006-09-01 16:20:29.000000000 -0400
19643 @@ -34,7 +34,6 @@ struct vm_area_struct;
19644   */
19645  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
19646  extern unsigned long empty_zero_page[1024];
19647 -extern pgd_t swapper_pg_dir[1024];
19648  extern kmem_cache_t *pgd_cache;
19649  extern kmem_cache_t *pmd_cache;
19650  extern spinlock_t pgd_lock;
19651 @@ -59,6 +58,11 @@ void paging_init(void);
19652  # include <asm/pgtable-2level-defs.h>
19653  #endif
19654  
19655 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
19656 +#ifdef CONFIG_X86_PAE
19657 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
19658 +#endif
19659 +
19660  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
19661  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
19662  
19663 @@ -68,9 +72,11 @@ void paging_init(void);
19664  #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
19665  #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
19666  
19667 +#ifndef CONFIG_X86_PAE
19668  #define TWOLEVEL_PGDIR_SHIFT   22
19669  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
19670  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
19671 +#endif
19672  
19673  /* Just any arbitrary offset to the start of the vmalloc VM area: the
19674   * current 8MB value just means that there will be a 8MB "hole" after the
19675 @@ -141,17 +147,26 @@ void paging_init(void);
19676  
19677  #define PAGE_SHARED_EXEC \
19678         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
19679 -#define PAGE_COPY_NOEXEC \
19680 -       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19681  #define PAGE_COPY_EXEC \
19682         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
19683 -#define PAGE_COPY \
19684 -       PAGE_COPY_NOEXEC
19685  #define PAGE_READONLY \
19686         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19687  #define PAGE_READONLY_EXEC \
19688         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
19689  
19690 +#ifdef CONFIG_PAX_PAGEEXEC
19691 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
19692 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
19693 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
19694 +#else
19695 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
19696 +# define PAGE_COPY_NOEXEC \
19697 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19698 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
19699 +#endif
19700 +
19701 +#define PAGE_COPY \
19702 +       PAGE_COPY_NOEXEC
19703  #define _PAGE_KERNEL \
19704         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
19705  #define _PAGE_KERNEL_EXEC \
19706 @@ -176,18 +191,18 @@ extern unsigned long long __PAGE_KERNEL,
19707   * This is the closest we can get..
19708   */
19709  #define __P000 PAGE_NONE
19710 -#define __P001 PAGE_READONLY
19711 -#define __P010 PAGE_COPY
19712 -#define __P011 PAGE_COPY
19713 +#define __P001 PAGE_READONLY_NOEXEC
19714 +#define __P010 PAGE_COPY_NOEXEC
19715 +#define __P011 PAGE_COPY_NOEXEC
19716  #define __P100 PAGE_READONLY_EXEC
19717  #define __P101 PAGE_READONLY_EXEC
19718  #define __P110 PAGE_COPY_EXEC
19719  #define __P111 PAGE_COPY_EXEC
19720  
19721  #define __S000 PAGE_NONE
19722 -#define __S001 PAGE_READONLY
19723 -#define __S010 PAGE_SHARED
19724 -#define __S011 PAGE_SHARED
19725 +#define __S001 PAGE_READONLY_NOEXEC
19726 +#define __S010 PAGE_SHARED_NOEXEC
19727 +#define __S011 PAGE_SHARED_NOEXEC
19728  #define __S100 PAGE_READONLY_EXEC
19729  #define __S101 PAGE_READONLY_EXEC
19730  #define __S110 PAGE_SHARED_EXEC
19731 @@ -431,6 +446,9 @@ extern void noexec_setup(const char *str
19732  
19733  #endif /* !__ASSEMBLY__ */
19734  
19735 +#define HAVE_ARCH_UNMAPPED_AREA
19736 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
19737 +
19738  #ifdef CONFIG_FLATMEM
19739  #define kern_addr_valid(addr)  (1)
19740  #endif /* CONFIG_FLATMEM */
19741 diff -urNp linux-2.6.17.11/include/asm-i386/processor.h linux-2.6.17.11/include/asm-i386/processor.h
19742 --- linux-2.6.17.11/include/asm-i386/processor.h        2006-08-07 00:18:54.000000000 -0400
19743 +++ linux-2.6.17.11/include/asm-i386/processor.h        2006-09-01 16:20:29.000000000 -0400
19744 @@ -19,7 +19,6 @@
19745  #include <linux/cache.h>
19746  #include <linux/config.h>
19747  #include <linux/threads.h>
19748 -#include <asm/percpu.h>
19749  #include <linux/cpumask.h>
19750  
19751  /* flag for disabling the tsc */
19752 @@ -94,8 +93,6 @@ struct cpuinfo_x86 {
19753  
19754  extern struct cpuinfo_x86 boot_cpu_data;
19755  extern struct cpuinfo_x86 new_cpu_data;
19756 -extern struct tss_struct doublefault_tss;
19757 -DECLARE_PER_CPU(struct tss_struct, init_tss);
19758  
19759  #ifdef CONFIG_SMP
19760  extern struct cpuinfo_x86 cpu_data[];
19761 @@ -325,10 +322,19 @@ extern int bootloader_type;
19762   */
19763  #define TASK_SIZE      (PAGE_OFFSET)
19764  
19765 +#ifdef CONFIG_PAX_SEGMEXEC
19766 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
19767 +#endif
19768 +
19769  /* This decides where the kernel will search for a free chunk of vm
19770   * space during mmap's.
19771   */
19772 +
19773 +#ifdef CONFIG_PAX_SEGMEXEC
19774 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
19775 +#else
19776  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
19777 +#endif
19778  
19779  #define HAVE_ARCH_PICK_MMAP_LAYOUT
19780  
19781 @@ -444,6 +450,9 @@ struct tss_struct {
19782  
19783  #define ARCH_MIN_TASKALIGN     16
19784  
19785 +extern struct tss_struct doublefault_tss;
19786 +extern struct tss_struct init_tss[NR_CPUS];
19787 +
19788  struct thread_struct {
19789  /* cached TLS descriptors. */
19790         struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
19791 @@ -472,6 +481,7 @@ struct thread_struct {
19792  };
19793  
19794  #define INIT_THREAD  {                                                 \
19795 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
19796         .vm86_info = NULL,                                              \
19797         .sysenter_cs = __KERNEL_CS,                                     \
19798         .io_bitmap_ptr = NULL,                                          \
19799 @@ -484,7 +494,7 @@ struct thread_struct {
19800   * be within the limit.
19801   */
19802  #define INIT_TSS  {                                                    \
19803 -       .esp0           = sizeof(init_stack) + (long)&init_stack,       \
19804 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
19805         .ss0            = __KERNEL_DS,                                  \
19806         .ss1            = __KERNEL_CS,                                  \
19807         .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,                     \
19808 @@ -560,11 +570,7 @@ void show_trace(struct task_struct *task
19809  unsigned long get_wchan(struct task_struct *p);
19810  
19811  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
19812 -#define KSTK_TOP(info)                                                 \
19813 -({                                                                     \
19814 -       unsigned long *__ptr = (unsigned long *)(info);                 \
19815 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
19816 -})
19817 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
19818  
19819  /*
19820   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
19821 @@ -579,7 +585,7 @@ unsigned long get_wchan(struct task_stru
19822  #define task_pt_regs(task)                                             \
19823  ({                                                                     \
19824         struct pt_regs *__regs__;                                       \
19825 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
19826 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
19827         __regs__ - 1;                                                   \
19828  })
19829  
19830 diff -urNp linux-2.6.17.11/include/asm-i386/ptrace.h linux-2.6.17.11/include/asm-i386/ptrace.h
19831 --- linux-2.6.17.11/include/asm-i386/ptrace.h   2006-08-07 00:18:54.000000000 -0400
19832 +++ linux-2.6.17.11/include/asm-i386/ptrace.h   2006-09-01 16:20:29.000000000 -0400
19833 @@ -65,17 +65,18 @@ struct task_struct;
19834  extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
19835  
19836  /*
19837 - * user_mode_vm(regs) determines whether a register set came from user mode.
19838 + * user_mode(regs) determines whether a register set came from user mode.
19839   * This is true if V8086 mode was enabled OR if the register set was from
19840   * protected mode with RPL-3 CS value.  This tricky test checks that with
19841   * one comparison.  Many places in the kernel can bypass this full check
19842 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
19843 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
19844 + * be used.
19845   */
19846 -static inline int user_mode(struct pt_regs *regs)
19847 +static inline int user_mode_novm(struct pt_regs *regs)
19848  {
19849         return (regs->xcs & 3) != 0;
19850  }
19851 -static inline int user_mode_vm(struct pt_regs *regs)
19852 +static inline int user_mode(struct pt_regs *regs)
19853  {
19854         return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
19855  }
19856 diff -urNp linux-2.6.17.11/include/asm-i386/system.h linux-2.6.17.11/include/asm-i386/system.h
19857 --- linux-2.6.17.11/include/asm-i386/system.h   2006-08-07 00:18:54.000000000 -0400
19858 +++ linux-2.6.17.11/include/asm-i386/system.h   2006-09-01 16:20:29.000000000 -0400
19859 @@ -5,6 +5,7 @@
19860  #include <linux/kernel.h>
19861  #include <asm/segment.h>
19862  #include <asm/cpufeature.h>
19863 +#include <asm/page.h>
19864  #include <linux/bitops.h> /* for LOCK_PREFIX */
19865  
19866  #ifdef __KERNEL__
19867 @@ -151,7 +152,7 @@ static inline unsigned long get_limit(un
19868         unsigned long __limit;
19869         __asm__("lsll %1,%0"
19870                 :"=r" (__limit):"r" (segment));
19871 -       return __limit+1;
19872 +       return __limit;
19873  }
19874  
19875  #define nop() __asm__ __volatile__ ("nop")
19876 @@ -496,7 +497,7 @@ static inline void sched_cacheflush(void
19877         wbinvd();
19878  }
19879  
19880 -extern unsigned long arch_align_stack(unsigned long sp);
19881 +#define arch_align_stack(x) (x)
19882  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
19883  
19884  void default_idle(void);
19885 diff -urNp linux-2.6.17.11/include/asm-i386/uaccess.h linux-2.6.17.11/include/asm-i386/uaccess.h
19886 --- linux-2.6.17.11/include/asm-i386/uaccess.h  2006-08-07 00:18:54.000000000 -0400
19887 +++ linux-2.6.17.11/include/asm-i386/uaccess.h  2006-09-01 16:20:29.000000000 -0400
19888 @@ -10,6 +10,8 @@
19889  #include <linux/prefetch.h>
19890  #include <linux/string.h>
19891  #include <asm/page.h>
19892 +#include <asm/segment.h>
19893 +#include <asm/desc.h>
19894  
19895  #define VERIFY_READ 0
19896  #define VERIFY_WRITE 1
19897 @@ -30,7 +32,8 @@
19898  
19899  #define get_ds()       (KERNEL_DS)
19900  #define get_fs()       (current_thread_info()->addr_limit)
19901 -#define set_fs(x)      (current_thread_info()->addr_limit = (x))
19902 +void __set_fs(mm_segment_t x, int cpu);
19903 +void set_fs(mm_segment_t x);
19904  
19905  #define segment_eq(a,b)        ((a).seg == (b).seg)
19906  
19907 @@ -281,9 +284,12 @@ extern void __put_user_8(void);
19908  
19909  #define __put_user_u64(x, addr, err)                           \
19910         __asm__ __volatile__(                                   \
19911 -               "1:     movl %%eax,0(%2)\n"                     \
19912 -               "2:     movl %%edx,4(%2)\n"                     \
19913 +               "       movw %w5,%%ds\n"                        \
19914 +               "1:     movl %%eax,%%ds:0(%2)\n"                \
19915 +               "2:     movl %%edx,%%ds:4(%2)\n"                \
19916                 "3:\n"                                          \
19917 +               "       pushl %%ss\n"                           \
19918 +               "       popl %%ds\n"                            \
19919                 ".section .fixup,\"ax\"\n"                      \
19920                 "4:     movl %3,%0\n"                           \
19921                 "       jmp 3b\n"                               \
19922 @@ -294,7 +300,8 @@ extern void __put_user_8(void);
19923                 "       .long 2b,4b\n"                          \
19924                 ".previous"                                     \
19925                 : "=r"(err)                                     \
19926 -               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
19927 +               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err),  \
19928 +                 "r"(__USER_DS))
19929  
19930  #ifdef CONFIG_X86_WP_WORKS_OK
19931  
19932 @@ -333,8 +340,11 @@ struct __large_struct { unsigned long bu
19933   */
19934  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
19935         __asm__ __volatile__(                                           \
19936 -               "1:     mov"itype" %"rtype"1,%2\n"                      \
19937 +               "       movw %w5,%%ds\n"                                \
19938 +               "1:     mov"itype" %"rtype"1,%%ds:%2\n"                 \
19939                 "2:\n"                                                  \
19940 +               "       pushl %%ss\n"                                   \
19941 +               "       popl %%ds\n"                                    \
19942                 ".section .fixup,\"ax\"\n"                              \
19943                 "3:     movl %3,%0\n"                                   \
19944                 "       jmp 2b\n"                                       \
19945 @@ -344,7 +354,8 @@ struct __large_struct { unsigned long bu
19946                 "       .long 1b,3b\n"                                  \
19947                 ".previous"                                             \
19948                 : "=r"(err)                                             \
19949 -               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
19950 +               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err),     \
19951 +                 "r"(__USER_DS))
19952  
19953  
19954  #define __get_user_nocheck(x,ptr,size)                         \
19955 @@ -372,8 +383,11 @@ do {                                                                       \
19956  
19957  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
19958         __asm__ __volatile__(                                           \
19959 -               "1:     mov"itype" %2,%"rtype"1\n"                      \
19960 +               "       movw %w5,%%ds\n"                                \
19961 +               "1:     mov"itype" %%ds:%2,%"rtype"1\n"                 \
19962                 "2:\n"                                                  \
19963 +               "       pushl %%ss\n"                                   \
19964 +               "       popl %%ds\n"                                    \
19965                 ".section .fixup,\"ax\"\n"                              \
19966                 "3:     movl %3,%0\n"                                   \
19967                 "       xor"itype" %"rtype"1,%"rtype"1\n"               \
19968 @@ -384,7 +398,7 @@ do {                                                                        \
19969                 "       .long 1b,3b\n"                                  \
19970                 ".previous"                                             \
19971                 : "=r"(err), ltype (x)                                  \
19972 -               : "m"(__m(addr)), "i"(errret), "0"(err))
19973 +               : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
19974  
19975  
19976  unsigned long __must_check __copy_to_user_ll(void __user *to,
19977 diff -urNp linux-2.6.17.11/include/asm-ia64/elf.h linux-2.6.17.11/include/asm-ia64/elf.h
19978 --- linux-2.6.17.11/include/asm-ia64/elf.h      2006-08-07 00:18:54.000000000 -0400
19979 +++ linux-2.6.17.11/include/asm-ia64/elf.h      2006-09-01 16:20:29.000000000 -0400
19980 @@ -163,6 +163,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
19981  typedef struct ia64_fpreg elf_fpreg_t;
19982  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
19983  
19984 +#ifdef CONFIG_PAX_ASLR
19985 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
19986 +
19987 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
19988 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19989 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
19990 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19991 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
19992 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19993 +#endif
19994  
19995  
19996  struct pt_regs;        /* forward declaration... */
19997 diff -urNp linux-2.6.17.11/include/asm-ia64/kmap_types.h linux-2.6.17.11/include/asm-ia64/kmap_types.h
19998 --- linux-2.6.17.11/include/asm-ia64/kmap_types.h       2006-08-07 00:18:54.000000000 -0400
19999 +++ linux-2.6.17.11/include/asm-ia64/kmap_types.h       2006-09-01 16:20:29.000000000 -0400
20000 @@ -23,7 +23,8 @@ D(9)  KM_IRQ0,
20001  D(10)  KM_IRQ1,
20002  D(11)  KM_SOFTIRQ0,
20003  D(12)  KM_SOFTIRQ1,
20004 -D(13)  KM_TYPE_NR
20005 +D(13)  KM_CLEARPAGE,
20006 +D(14)  KM_TYPE_NR
20007  };
20008  
20009  #undef D
20010 diff -urNp linux-2.6.17.11/include/asm-ia64/page.h linux-2.6.17.11/include/asm-ia64/page.h
20011 --- linux-2.6.17.11/include/asm-ia64/page.h     2006-08-07 00:18:54.000000000 -0400
20012 +++ linux-2.6.17.11/include/asm-ia64/page.h     2006-09-01 16:20:29.000000000 -0400
20013 @@ -229,4 +229,13 @@ get_order (unsigned long size)
20014                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
20015                                           ? VM_EXEC : 0))
20016  
20017 +#ifdef CONFIG_PAX_PAGEEXEC
20018 +#ifdef CONFIG_PAX_MPROTECT
20019 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20020 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20021 +#else
20022 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20023 +#endif
20024 +#endif
20025 +
20026  #endif /* _ASM_IA64_PAGE_H */
20027 diff -urNp linux-2.6.17.11/include/asm-ia64/pgtable.h linux-2.6.17.11/include/asm-ia64/pgtable.h
20028 --- linux-2.6.17.11/include/asm-ia64/pgtable.h  2006-08-07 00:18:54.000000000 -0400
20029 +++ linux-2.6.17.11/include/asm-ia64/pgtable.h  2006-09-01 16:20:29.000000000 -0400
20030 @@ -144,6 +144,17 @@
20031  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
20032  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
20033  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
20034 +
20035 +#ifdef CONFIG_PAX_PAGEEXEC
20036 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
20037 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
20038 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
20039 +#else
20040 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20041 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20042 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20043 +#endif
20044 +
20045  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
20046  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
20047  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
20048 diff -urNp linux-2.6.17.11/include/asm-ia64/processor.h linux-2.6.17.11/include/asm-ia64/processor.h
20049 --- linux-2.6.17.11/include/asm-ia64/processor.h        2006-08-07 00:18:54.000000000 -0400
20050 +++ linux-2.6.17.11/include/asm-ia64/processor.h        2006-09-01 16:20:29.000000000 -0400
20051 @@ -284,7 +284,7 @@ struct thread_struct {
20052         .on_ustack =    0,                                      \
20053         .ksp =          0,                                      \
20054         .map_base =     DEFAULT_MAP_BASE,                       \
20055 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
20056 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
20057         .task_size =    DEFAULT_TASK_SIZE,                      \
20058         .last_fph_cpu =  -1,                                    \
20059         INIT_THREAD_IA32                                        \
20060 diff -urNp linux-2.6.17.11/include/asm-ia64/ustack.h linux-2.6.17.11/include/asm-ia64/ustack.h
20061 --- linux-2.6.17.11/include/asm-ia64/ustack.h   2006-08-07 00:18:54.000000000 -0400
20062 +++ linux-2.6.17.11/include/asm-ia64/ustack.h   2006-09-01 16:20:29.000000000 -0400
20063 @@ -11,6 +11,6 @@
20064  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
20065  /* Make a default stack size of 2GB */
20066  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
20067 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
20068 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
20069  
20070  #endif /* _ASM_IA64_USTACK_H */
20071 diff -urNp linux-2.6.17.11/include/asm-m32r/kmap_types.h linux-2.6.17.11/include/asm-m32r/kmap_types.h
20072 --- linux-2.6.17.11/include/asm-m32r/kmap_types.h       2006-08-07 00:18:54.000000000 -0400
20073 +++ linux-2.6.17.11/include/asm-m32r/kmap_types.h       2006-09-01 16:20:29.000000000 -0400
20074 @@ -25,7 +25,8 @@ D(9)  KM_IRQ0,
20075  D(10)  KM_IRQ1,
20076  D(11)  KM_SOFTIRQ0,
20077  D(12)  KM_SOFTIRQ1,
20078 -D(13)  KM_TYPE_NR
20079 +D(13)  KM_CLEARPAGE,
20080 +D(14)  KM_TYPE_NR
20081  };
20082  
20083  #undef D
20084 diff -urNp linux-2.6.17.11/include/asm-m68k/kmap_types.h linux-2.6.17.11/include/asm-m68k/kmap_types.h
20085 --- linux-2.6.17.11/include/asm-m68k/kmap_types.h       2006-08-07 00:18:54.000000000 -0400
20086 +++ linux-2.6.17.11/include/asm-m68k/kmap_types.h       2006-09-01 16:20:29.000000000 -0400
20087 @@ -15,6 +15,7 @@ enum km_type {
20088         KM_IRQ1,
20089         KM_SOFTIRQ0,
20090         KM_SOFTIRQ1,
20091 +       KM_CLEARPAGE,
20092         KM_TYPE_NR
20093  };
20094  
20095 diff -urNp linux-2.6.17.11/include/asm-m68knommu/kmap_types.h linux-2.6.17.11/include/asm-m68knommu/kmap_types.h
20096 --- linux-2.6.17.11/include/asm-m68knommu/kmap_types.h  2006-08-07 00:18:54.000000000 -0400
20097 +++ linux-2.6.17.11/include/asm-m68knommu/kmap_types.h  2006-09-01 16:20:29.000000000 -0400
20098 @@ -15,6 +15,7 @@ enum km_type {
20099         KM_IRQ1,
20100         KM_SOFTIRQ0,
20101         KM_SOFTIRQ1,
20102 +       KM_CLEARPAGE,
20103         KM_TYPE_NR
20104  };
20105  
20106 diff -urNp linux-2.6.17.11/include/asm-mips/a.out.h linux-2.6.17.11/include/asm-mips/a.out.h
20107 --- linux-2.6.17.11/include/asm-mips/a.out.h    2006-08-07 00:18:54.000000000 -0400
20108 +++ linux-2.6.17.11/include/asm-mips/a.out.h    2006-09-01 16:20:29.000000000 -0400
20109 @@ -36,10 +36,10 @@ struct exec
20110  #ifdef __KERNEL__
20111  
20112  #ifdef CONFIG_32BIT
20113 -#define STACK_TOP      TASK_SIZE
20114 +#define __STACK_TOP    TASK_SIZE
20115  #endif
20116  #ifdef CONFIG_64BIT
20117 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
20118 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
20119  #endif
20120  
20121  #endif
20122 diff -urNp linux-2.6.17.11/include/asm-mips/elf.h linux-2.6.17.11/include/asm-mips/elf.h
20123 --- linux-2.6.17.11/include/asm-mips/elf.h      2006-08-07 00:18:54.000000000 -0400
20124 +++ linux-2.6.17.11/include/asm-mips/elf.h      2006-09-01 16:20:29.000000000 -0400
20125 @@ -372,4 +372,15 @@ extern int dump_task_fpu(struct task_str
20126  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
20127  #endif
20128  
20129 +#ifdef CONFIG_PAX_ASLR
20130 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
20131 +
20132 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20133 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
20134 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20135 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
20136 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20137 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
20138 +#endif
20139 +
20140  #endif /* _ASM_ELF_H */
20141 diff -urNp linux-2.6.17.11/include/asm-mips/kmap_types.h linux-2.6.17.11/include/asm-mips/kmap_types.h
20142 --- linux-2.6.17.11/include/asm-mips/kmap_types.h       2006-08-07 00:18:54.000000000 -0400
20143 +++ linux-2.6.17.11/include/asm-mips/kmap_types.h       2006-09-01 16:20:29.000000000 -0400
20144 @@ -23,7 +23,8 @@ D(9)  KM_IRQ0,
20145  D(10)  KM_IRQ1,
20146  D(11)  KM_SOFTIRQ0,
20147  D(12)  KM_SOFTIRQ1,
20148 -D(13)  KM_TYPE_NR
20149 +D(13)  KM_CLEARPAGE,
20150 +D(14)  KM_TYPE_NR
20151  };
20152  
20153  #undef D
20154 diff -urNp linux-2.6.17.11/include/asm-mips/page.h linux-2.6.17.11/include/asm-mips/page.h
20155 --- linux-2.6.17.11/include/asm-mips/page.h     2006-08-07 00:18:54.000000000 -0400
20156 +++ linux-2.6.17.11/include/asm-mips/page.h     2006-09-01 16:20:31.000000000 -0400
20157 @@ -79,15 +79,17 @@ static inline void copy_user_page(void *
20158    #ifdef CONFIG_CPU_MIPS32
20159      typedef struct { unsigned long pte_low, pte_high; } pte_t;
20160      #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
20161 +    #define __pte(x)   ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
20162    #else
20163       typedef struct { unsigned long long pte; } pte_t;
20164       #define pte_val(x)        ((x).pte)
20165 +     #define __pte(x)  ((pte_t) { (x) } )
20166    #endif
20167  #else
20168  typedef struct { unsigned long pte; } pte_t;
20169  #define pte_val(x)     ((x).pte)
20170 -#endif
20171  #define __pte(x)       ((pte_t) { (x) } )
20172 +#endif
20173  
20174  /*
20175   * For 3-level pagetables we defines these ourselves, for 2-level the
20176 @@ -151,6 +153,15 @@ typedef struct { unsigned long pgprot; }
20177  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
20178                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20179  
20180 +#ifdef CONFIG_PAX_PAGEEXEC
20181 +#ifdef CONFIG_PAX_MPROTECT
20182 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20183 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20184 +#else
20185 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20186 +#endif
20187 +#endif
20188 +
20189  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
20190  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
20191  
20192 diff -urNp linux-2.6.17.11/include/asm-parisc/a.out.h linux-2.6.17.11/include/asm-parisc/a.out.h
20193 --- linux-2.6.17.11/include/asm-parisc/a.out.h  2006-08-07 00:18:54.000000000 -0400
20194 +++ linux-2.6.17.11/include/asm-parisc/a.out.h  2006-09-01 16:20:29.000000000 -0400
20195 @@ -22,7 +22,7 @@ struct exec
20196  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
20197   * prumpf */
20198  
20199 -#define STACK_TOP      TASK_SIZE
20200 +#define __STACK_TOP    TASK_SIZE
20201  
20202  #endif
20203  
20204 diff -urNp linux-2.6.17.11/include/asm-parisc/elf.h linux-2.6.17.11/include/asm-parisc/elf.h
20205 --- linux-2.6.17.11/include/asm-parisc/elf.h    2006-08-07 00:18:54.000000000 -0400
20206 +++ linux-2.6.17.11/include/asm-parisc/elf.h    2006-09-01 16:20:29.000000000 -0400
20207 @@ -337,6 +337,17 @@ struct pt_regs;    /* forward declaration..
20208  
20209  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
20210  
20211 +#ifdef CONFIG_PAX_ASLR
20212 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
20213 +
20214 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20215 +#define PAX_DELTA_MMAP_LEN(tsk)                16
20216 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20217 +#define PAX_DELTA_EXEC_LEN(tsk)                16
20218 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20219 +#define PAX_DELTA_STACK_LEN(tsk)       16
20220 +#endif
20221 +
20222  /* This yields a mask that user programs can use to figure out what
20223     instruction set this CPU supports.  This could be done in user space,
20224     but it's not easy, and we've already done it here.  */
20225 diff -urNp linux-2.6.17.11/include/asm-parisc/kmap_types.h linux-2.6.17.11/include/asm-parisc/kmap_types.h
20226 --- linux-2.6.17.11/include/asm-parisc/kmap_types.h     2006-08-07 00:18:54.000000000 -0400
20227 +++ linux-2.6.17.11/include/asm-parisc/kmap_types.h     2006-09-01 16:20:29.000000000 -0400
20228 @@ -23,7 +23,8 @@ D(9)  KM_IRQ0,
20229  D(10)  KM_IRQ1,
20230  D(11)  KM_SOFTIRQ0,
20231  D(12)  KM_SOFTIRQ1,
20232 -D(13)  KM_TYPE_NR
20233 +D(13)  KM_CLEARPAGE,
20234 +D(14)  KM_TYPE_NR
20235  };
20236  
20237  #undef D
20238 diff -urNp linux-2.6.17.11/include/asm-parisc/page.h linux-2.6.17.11/include/asm-parisc/page.h
20239 --- linux-2.6.17.11/include/asm-parisc/page.h   2006-08-07 00:18:54.000000000 -0400
20240 +++ linux-2.6.17.11/include/asm-parisc/page.h   2006-09-01 16:20:29.000000000 -0400
20241 @@ -189,6 +189,15 @@ extern int npmem_ranges;
20242  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
20243                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20244  
20245 +#ifdef CONFIG_PAX_PAGEEXEC
20246 +#ifdef CONFIG_PAX_MPROTECT
20247 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20248 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20249 +#else
20250 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20251 +#endif
20252 +#endif
20253 +
20254  #endif /* __KERNEL__ */
20255  
20256  #include <asm-generic/memory_model.h>
20257 diff -urNp linux-2.6.17.11/include/asm-parisc/pgtable.h linux-2.6.17.11/include/asm-parisc/pgtable.h
20258 --- linux-2.6.17.11/include/asm-parisc/pgtable.h        2006-08-07 00:18:54.000000000 -0400
20259 +++ linux-2.6.17.11/include/asm-parisc/pgtable.h        2006-09-01 16:20:29.000000000 -0400
20260 @@ -220,6 +220,17 @@ extern  void *vmalloc_start;
20261  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
20262  #define PAGE_COPY       PAGE_EXECREAD
20263  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
20264 +
20265 +#ifdef CONFIG_PAX_PAGEEXEC
20266 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
20267 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
20268 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
20269 +#else
20270 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20271 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20272 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20273 +#endif
20274 +
20275  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
20276  #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
20277  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
20278 diff -urNp linux-2.6.17.11/include/asm-powerpc/a.out.h linux-2.6.17.11/include/asm-powerpc/a.out.h
20279 --- linux-2.6.17.11/include/asm-powerpc/a.out.h 2006-08-07 00:18:54.000000000 -0400
20280 +++ linux-2.6.17.11/include/asm-powerpc/a.out.h 2006-09-01 16:20:29.000000000 -0400
20281 @@ -23,12 +23,12 @@ struct exec
20282  #define STACK_TOP_USER64 TASK_SIZE_USER64
20283  #define STACK_TOP_USER32 TASK_SIZE_USER32
20284  
20285 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20286 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20287                    STACK_TOP_USER32 : STACK_TOP_USER64)
20288  
20289  #else /* __powerpc64__ */
20290  
20291 -#define STACK_TOP TASK_SIZE
20292 +#define __STACK_TOP TASK_SIZE
20293  
20294  #endif /* __powerpc64__ */
20295  #endif /* __KERNEL__ */
20296 diff -urNp linux-2.6.17.11/include/asm-powerpc/elf.h linux-2.6.17.11/include/asm-powerpc/elf.h
20297 --- linux-2.6.17.11/include/asm-powerpc/elf.h   2006-08-07 00:18:54.000000000 -0400
20298 +++ linux-2.6.17.11/include/asm-powerpc/elf.h   2006-09-01 16:20:29.000000000 -0400
20299 @@ -176,6 +176,26 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF
20300  
20301  #define ELF_ET_DYN_BASE         (0x08000000)
20302  
20303 +#ifdef CONFIG_PAX_ASLR
20304 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
20305 +
20306 +#ifdef __powerpc64__
20307 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20308 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
20309 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20310 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
20311 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20312 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 16 : 28)
20313 +#else
20314 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20315 +#define PAX_DELTA_MMAP_LEN(tsk)                15
20316 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20317 +#define PAX_DELTA_EXEC_LEN(tsk)                15
20318 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20319 +#define PAX_DELTA_STACK_LEN(tsk)       15
20320 +#endif
20321 +#endif
20322 +
20323  #ifdef __KERNEL__
20324  
20325  /* Common routine for both 32-bit and 64-bit processes */
20326 diff -urNp linux-2.6.17.11/include/asm-powerpc/kmap_types.h linux-2.6.17.11/include/asm-powerpc/kmap_types.h
20327 --- linux-2.6.17.11/include/asm-powerpc/kmap_types.h    2006-08-07 00:18:54.000000000 -0400
20328 +++ linux-2.6.17.11/include/asm-powerpc/kmap_types.h    2006-09-01 16:20:29.000000000 -0400
20329 @@ -26,6 +26,7 @@ enum km_type {
20330         KM_SOFTIRQ1,
20331         KM_PPC_SYNC_PAGE,
20332         KM_PPC_SYNC_ICACHE,
20333 +       KM_CLEARPAGE,
20334         KM_TYPE_NR
20335  };
20336  
20337 diff -urNp linux-2.6.17.11/include/asm-powerpc/page_64.h linux-2.6.17.11/include/asm-powerpc/page_64.h
20338 --- linux-2.6.17.11/include/asm-powerpc/page_64.h       2006-08-07 00:18:54.000000000 -0400
20339 +++ linux-2.6.17.11/include/asm-powerpc/page_64.h       2006-09-01 16:20:29.000000000 -0400
20340 @@ -170,6 +170,15 @@ extern unsigned int HPAGE_SHIFT;
20341         (test_thread_flag(TIF_32BIT) ? \
20342          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
20343  
20344 +#ifdef CONFIG_PAX_PAGEEXEC
20345 +#ifdef CONFIG_PAX_MPROTECT
20346 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20347 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20348 +#else
20349 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20350 +#endif
20351 +#endif
20352 +
20353  #include <asm-generic/page.h>
20354  
20355  #endif /* __KERNEL__ */
20356 diff -urNp linux-2.6.17.11/include/asm-ppc/page.h linux-2.6.17.11/include/asm-ppc/page.h
20357 --- linux-2.6.17.11/include/asm-ppc/page.h      2006-08-07 00:18:54.000000000 -0400
20358 +++ linux-2.6.17.11/include/asm-ppc/page.h      2006-09-01 16:20:29.000000000 -0400
20359 @@ -175,6 +175,15 @@ extern __inline__ int get_order(unsigned
20360  /* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
20361  #define __HAVE_ARCH_GATE_AREA          1
20362  
20363 +#ifdef CONFIG_PAX_PAGEEXEC
20364 +#ifdef CONFIG_PAX_MPROTECT
20365 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20366 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20367 +#else
20368 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20369 +#endif
20370 +#endif
20371 +
20372  #include <asm-generic/memory_model.h>
20373  #endif /* __KERNEL__ */
20374  #endif /* _PPC_PAGE_H */
20375 diff -urNp linux-2.6.17.11/include/asm-ppc/pgtable.h linux-2.6.17.11/include/asm-ppc/pgtable.h
20376 --- linux-2.6.17.11/include/asm-ppc/pgtable.h   2006-08-07 00:18:54.000000000 -0400
20377 +++ linux-2.6.17.11/include/asm-ppc/pgtable.h   2006-09-01 16:20:29.000000000 -0400
20378 @@ -441,11 +441,21 @@ extern unsigned long ioremap_bot, iorema
20379  
20380  #define PAGE_NONE      __pgprot(_PAGE_BASE)
20381  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
20382 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
20383 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
20384  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
20385 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
20386 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
20387  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
20388 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
20389 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
20390 +
20391 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
20392 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
20393 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
20394 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
20395 +#else
20396 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20397 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20398 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20399 +#endif
20400  
20401  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
20402  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
20403 @@ -457,21 +467,21 @@ extern unsigned long ioremap_bot, iorema
20404   * This is the closest we can get..
20405   */
20406  #define __P000 PAGE_NONE
20407 -#define __P001 PAGE_READONLY_X
20408 -#define __P010 PAGE_COPY
20409 -#define __P011 PAGE_COPY_X
20410 -#define __P100 PAGE_READONLY
20411 +#define __P001 PAGE_READONLY_NOEXEC
20412 +#define __P010 PAGE_COPY_NOEXEC
20413 +#define __P011 PAGE_COPY_NOEXEC
20414 +#define __P100 PAGE_READONLY_X
20415  #define __P101 PAGE_READONLY_X
20416 -#define __P110 PAGE_COPY
20417 +#define __P110 PAGE_COPY_X
20418  #define __P111 PAGE_COPY_X
20419  
20420  #define __S000 PAGE_NONE
20421 -#define __S001 PAGE_READONLY_X
20422 -#define __S010 PAGE_SHARED
20423 -#define __S011 PAGE_SHARED_X
20424 -#define __S100 PAGE_READONLY
20425 +#define __S001 PAGE_READONLY_NOEXEC
20426 +#define __S010 PAGE_SHARED_NOEXEC
20427 +#define __S011 PAGE_SHARED_NOEXEC
20428 +#define __S100 PAGE_READONLY_X
20429  #define __S101 PAGE_READONLY_X
20430 -#define __S110 PAGE_SHARED
20431 +#define __S110 PAGE_SHARED_X
20432  #define __S111 PAGE_SHARED_X
20433  
20434  #ifndef __ASSEMBLY__
20435 diff -urNp linux-2.6.17.11/include/asm-s390/kmap_types.h linux-2.6.17.11/include/asm-s390/kmap_types.h
20436 --- linux-2.6.17.11/include/asm-s390/kmap_types.h       2006-08-07 00:18:54.000000000 -0400
20437 +++ linux-2.6.17.11/include/asm-s390/kmap_types.h       2006-09-01 16:20:29.000000000 -0400
20438 @@ -16,6 +16,7 @@ enum km_type {
20439         KM_IRQ1,
20440         KM_SOFTIRQ0,
20441         KM_SOFTIRQ1,    
20442 +       KM_CLEARPAGE,
20443         KM_TYPE_NR
20444  };
20445  
20446 diff -urNp linux-2.6.17.11/include/asm-sh/kmap_types.h linux-2.6.17.11/include/asm-sh/kmap_types.h
20447 --- linux-2.6.17.11/include/asm-sh/kmap_types.h 2006-08-07 00:18:54.000000000 -0400
20448 +++ linux-2.6.17.11/include/asm-sh/kmap_types.h 2006-09-01 16:20:29.000000000 -0400
20449 @@ -25,7 +25,8 @@ D(9)  KM_IRQ0,
20450  D(10)  KM_IRQ1,
20451  D(11)  KM_SOFTIRQ0,
20452  D(12)  KM_SOFTIRQ1,
20453 -D(13)  KM_TYPE_NR
20454 +D(13)  KM_CLEARPAGE,
20455 +D(14)  KM_TYPE_NR
20456  };
20457  
20458  #undef D
20459 diff -urNp linux-2.6.17.11/include/asm-sparc/a.out.h linux-2.6.17.11/include/asm-sparc/a.out.h
20460 --- linux-2.6.17.11/include/asm-sparc/a.out.h   2006-08-07 00:18:54.000000000 -0400
20461 +++ linux-2.6.17.11/include/asm-sparc/a.out.h   2006-09-01 16:20:29.000000000 -0400
20462 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
20463  
20464  #include <asm/page.h>
20465  
20466 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
20467 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
20468  
20469  #endif /* __KERNEL__ */
20470  
20471 diff -urNp linux-2.6.17.11/include/asm-sparc/elf.h linux-2.6.17.11/include/asm-sparc/elf.h
20472 --- linux-2.6.17.11/include/asm-sparc/elf.h     2006-08-07 00:18:54.000000000 -0400
20473 +++ linux-2.6.17.11/include/asm-sparc/elf.h     2006-09-01 16:20:29.000000000 -0400
20474 @@ -145,6 +145,17 @@ typedef struct {
20475  
20476  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
20477  
20478 +#ifdef CONFIG_PAX_ASLR
20479 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
20480 +
20481 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20482 +#define PAX_DELTA_MMAP_LEN(tsk)                16
20483 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20484 +#define PAX_DELTA_EXEC_LEN(tsk)                16
20485 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20486 +#define PAX_DELTA_STACK_LEN(tsk)       16
20487 +#endif
20488 +
20489  /* This yields a mask that user programs can use to figure out what
20490     instruction set this cpu supports.  This can NOT be done in userspace
20491     on Sparc.  */
20492 diff -urNp linux-2.6.17.11/include/asm-sparc/kmap_types.h linux-2.6.17.11/include/asm-sparc/kmap_types.h
20493 --- linux-2.6.17.11/include/asm-sparc/kmap_types.h      2006-08-07 00:18:54.000000000 -0400
20494 +++ linux-2.6.17.11/include/asm-sparc/kmap_types.h      2006-09-01 16:20:29.000000000 -0400
20495 @@ -15,6 +15,7 @@ enum km_type {
20496         KM_IRQ1,
20497         KM_SOFTIRQ0,
20498         KM_SOFTIRQ1,
20499 +       KM_CLEARPAGE,
20500         KM_TYPE_NR
20501  };
20502  
20503 diff -urNp linux-2.6.17.11/include/asm-sparc/page.h linux-2.6.17.11/include/asm-sparc/page.h
20504 --- linux-2.6.17.11/include/asm-sparc/page.h    2006-08-07 00:18:54.000000000 -0400
20505 +++ linux-2.6.17.11/include/asm-sparc/page.h    2006-09-01 16:20:29.000000000 -0400
20506 @@ -163,6 +163,15 @@ extern unsigned long pfn_base;
20507  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
20508                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20509  
20510 +#ifdef CONFIG_PAX_PAGEEXEC
20511 +#ifdef CONFIG_PAX_MPROTECT
20512 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20513 +                        ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20514 +#else
20515 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20516 +#endif
20517 +#endif
20518 +
20519  #endif /* __KERNEL__ */
20520  
20521  #include <asm-generic/memory_model.h>
20522 diff -urNp linux-2.6.17.11/include/asm-sparc/pgtable.h linux-2.6.17.11/include/asm-sparc/pgtable.h
20523 --- linux-2.6.17.11/include/asm-sparc/pgtable.h 2006-08-07 00:18:54.000000000 -0400
20524 +++ linux-2.6.17.11/include/asm-sparc/pgtable.h 2006-09-01 16:20:29.000000000 -0400
20525 @@ -50,6 +50,13 @@ BTFIXUPDEF_INT(page_none)
20526  BTFIXUPDEF_INT(page_shared)
20527  BTFIXUPDEF_INT(page_copy)
20528  BTFIXUPDEF_INT(page_readonly)
20529 +
20530 +#ifdef CONFIG_PAX_PAGEEXEC
20531 +BTFIXUPDEF_INT(page_shared_noexec)
20532 +BTFIXUPDEF_INT(page_copy_noexec)
20533 +BTFIXUPDEF_INT(page_readonly_noexec)
20534 +#endif
20535 +
20536  BTFIXUPDEF_INT(page_kernel)
20537  
20538  #define PMD_SHIFT              SUN4C_PMD_SHIFT
20539 @@ -71,6 +78,16 @@ BTFIXUPDEF_INT(page_kernel)
20540  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
20541  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
20542  
20543 +#ifdef CONFIG_PAX_PAGEEXEC
20544 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
20545 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
20546 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
20547 +#else
20548 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20549 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20550 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20551 +#endif
20552 +
20553  extern unsigned long page_kernel;
20554  
20555  #ifdef MODULE
20556 diff -urNp linux-2.6.17.11/include/asm-sparc/pgtsrmmu.h linux-2.6.17.11/include/asm-sparc/pgtsrmmu.h
20557 --- linux-2.6.17.11/include/asm-sparc/pgtsrmmu.h        2006-08-07 00:18:54.000000000 -0400
20558 +++ linux-2.6.17.11/include/asm-sparc/pgtsrmmu.h        2006-09-01 16:20:29.000000000 -0400
20559 @@ -115,6 +115,16 @@
20560                                     SRMMU_EXEC | SRMMU_REF)
20561  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20562                                     SRMMU_EXEC | SRMMU_REF)
20563 +
20564 +#ifdef CONFIG_PAX_PAGEEXEC
20565 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20566 +                                          SRMMU_WRITE | SRMMU_REF)
20567 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20568 +                                          SRMMU_REF)
20569 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20570 +                                          SRMMU_REF)
20571 +#endif
20572 +
20573  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
20574                                     SRMMU_DIRTY | SRMMU_REF)
20575  
20576 diff -urNp linux-2.6.17.11/include/asm-sparc/uaccess.h linux-2.6.17.11/include/asm-sparc/uaccess.h
20577 --- linux-2.6.17.11/include/asm-sparc/uaccess.h 2006-08-07 00:18:54.000000000 -0400
20578 +++ linux-2.6.17.11/include/asm-sparc/uaccess.h 2006-09-01 16:20:29.000000000 -0400
20579 @@ -41,7 +41,7 @@
20580   * No one can read/write anything from userland in the kernel space by setting
20581   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
20582   */
20583 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
20584 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
20585  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
20586  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
20587  #define access_ok(type, addr, size)                                    \
20588 diff -urNp linux-2.6.17.11/include/asm-sparc64/a.out.h linux-2.6.17.11/include/asm-sparc64/a.out.h
20589 --- linux-2.6.17.11/include/asm-sparc64/a.out.h 2006-08-07 00:18:54.000000000 -0400
20590 +++ linux-2.6.17.11/include/asm-sparc64/a.out.h 2006-09-01 16:20:29.000000000 -0400
20591 @@ -98,7 +98,7 @@ struct relocation_info /* used when head
20592  #define STACK_TOP32    ((1UL << 32UL) - PAGE_SIZE)
20593  #define STACK_TOP64    (0x0000080000000000UL - (1UL << 32UL))
20594  
20595 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20596 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20597                    STACK_TOP32 : STACK_TOP64)
20598  
20599  #endif
20600 diff -urNp linux-2.6.17.11/include/asm-sparc64/elf.h linux-2.6.17.11/include/asm-sparc64/elf.h
20601 --- linux-2.6.17.11/include/asm-sparc64/elf.h   2006-08-07 00:18:54.000000000 -0400
20602 +++ linux-2.6.17.11/include/asm-sparc64/elf.h   2006-09-01 16:20:29.000000000 -0400
20603 @@ -142,6 +142,16 @@ typedef struct {
20604  #define ELF_ET_DYN_BASE         0x0000010000000000UL
20605  #endif
20606  
20607 +#ifdef CONFIG_PAX_ASLR
20608 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
20609 +
20610 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
20611 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
20612 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
20613 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
20614 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20615 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
20616 +#endif
20617  
20618  /* This yields a mask that user programs can use to figure out what
20619     instruction set this cpu supports.  */
20620 diff -urNp linux-2.6.17.11/include/asm-sparc64/kmap_types.h linux-2.6.17.11/include/asm-sparc64/kmap_types.h
20621 --- linux-2.6.17.11/include/asm-sparc64/kmap_types.h    2006-08-07 00:18:54.000000000 -0400
20622 +++ linux-2.6.17.11/include/asm-sparc64/kmap_types.h    2006-09-01 16:20:29.000000000 -0400
20623 @@ -19,6 +19,7 @@ enum km_type {
20624         KM_IRQ1,
20625         KM_SOFTIRQ0,
20626         KM_SOFTIRQ1,
20627 +       KM_CLEARPAGE,
20628         KM_TYPE_NR
20629  };
20630  
20631 diff -urNp linux-2.6.17.11/include/asm-sparc64/page.h linux-2.6.17.11/include/asm-sparc64/page.h
20632 --- linux-2.6.17.11/include/asm-sparc64/page.h  2006-08-07 00:18:54.000000000 -0400
20633 +++ linux-2.6.17.11/include/asm-sparc64/page.h  2006-09-01 16:20:29.000000000 -0400
20634 @@ -144,6 +144,15 @@ typedef unsigned long pgprot_t;
20635  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
20636                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20637  
20638 +#ifdef CONFIG_PAX_PAGEEXEC
20639 +#ifdef CONFIG_PAX_MPROTECT
20640 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20641 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20642 +#else
20643 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20644 +#endif
20645 +#endif
20646 +
20647  #endif /* !(__KERNEL__) */
20648  
20649  #include <asm-generic/page.h>
20650 diff -urNp linux-2.6.17.11/include/asm-v850/kmap_types.h linux-2.6.17.11/include/asm-v850/kmap_types.h
20651 --- linux-2.6.17.11/include/asm-v850/kmap_types.h       2006-08-07 00:18:54.000000000 -0400
20652 +++ linux-2.6.17.11/include/asm-v850/kmap_types.h       2006-09-01 16:20:29.000000000 -0400
20653 @@ -13,6 +13,7 @@ enum km_type {
20654         KM_PTE1,
20655         KM_IRQ0,
20656         KM_IRQ1,
20657 +       KM_CLEARPAGE,
20658         KM_TYPE_NR
20659  };
20660  
20661 diff -urNp linux-2.6.17.11/include/asm-x86_64/a.out.h linux-2.6.17.11/include/asm-x86_64/a.out.h
20662 --- linux-2.6.17.11/include/asm-x86_64/a.out.h  2006-08-07 00:18:54.000000000 -0400
20663 +++ linux-2.6.17.11/include/asm-x86_64/a.out.h  2006-09-01 16:20:29.000000000 -0400
20664 @@ -21,7 +21,7 @@ struct exec
20665  
20666  #ifdef __KERNEL__
20667  #include <linux/thread_info.h>
20668 -#define STACK_TOP TASK_SIZE
20669 +#define __STACK_TOP TASK_SIZE
20670  #endif
20671  
20672  #endif /* __A_OUT_GNU_H__ */
20673 diff -urNp linux-2.6.17.11/include/asm-x86_64/elf.h linux-2.6.17.11/include/asm-x86_64/elf.h
20674 --- linux-2.6.17.11/include/asm-x86_64/elf.h    2006-08-07 00:18:54.000000000 -0400
20675 +++ linux-2.6.17.11/include/asm-x86_64/elf.h    2006-09-01 16:20:29.000000000 -0400
20676 @@ -90,6 +90,17 @@ typedef struct user_i387_struct elf_fpre
20677  
20678  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
20679  
20680 +#ifdef CONFIG_PAX_ASLR
20681 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
20682 +
20683 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20684 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
20685 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20686 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
20687 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20688 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 32)
20689 +#endif
20690 +
20691  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
20692     now struct_user_regs, they are different). Assumes current is the process
20693     getting dumped. */
20694 diff -urNp linux-2.6.17.11/include/asm-x86_64/ia32.h linux-2.6.17.11/include/asm-x86_64/ia32.h
20695 --- linux-2.6.17.11/include/asm-x86_64/ia32.h   2006-08-07 00:18:54.000000000 -0400
20696 +++ linux-2.6.17.11/include/asm-x86_64/ia32.h   2006-09-01 16:20:29.000000000 -0400
20697 @@ -157,7 +157,13 @@ struct ustat32 {
20698         char                    f_fpack[6];
20699  };
20700  
20701 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
20702 +#ifdef CONFIG_PAX_RANDUSTACK
20703 +#define IA32_DELTA_STACK (current->mm->delta_stack)
20704 +#else
20705 +#define IA32_DELTA_STACK 0UL
20706 +#endif
20707 +
20708 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
20709  
20710  #ifdef __KERNEL__
20711  struct user_desc;
20712 diff -urNp linux-2.6.17.11/include/asm-x86_64/kmap_types.h linux-2.6.17.11/include/asm-x86_64/kmap_types.h
20713 --- linux-2.6.17.11/include/asm-x86_64/kmap_types.h     2006-08-07 00:18:54.000000000 -0400
20714 +++ linux-2.6.17.11/include/asm-x86_64/kmap_types.h     2006-09-01 16:20:29.000000000 -0400
20715 @@ -13,6 +13,7 @@ enum km_type {
20716         KM_IRQ1,
20717         KM_SOFTIRQ0,
20718         KM_SOFTIRQ1,
20719 +       KM_CLEARPAGE,
20720         KM_TYPE_NR
20721  };
20722  
20723 diff -urNp linux-2.6.17.11/include/asm-x86_64/page.h linux-2.6.17.11/include/asm-x86_64/page.h
20724 --- linux-2.6.17.11/include/asm-x86_64/page.h   2006-08-07 00:18:54.000000000 -0400
20725 +++ linux-2.6.17.11/include/asm-x86_64/page.h   2006-09-01 16:20:29.000000000 -0400
20726 @@ -134,6 +134,15 @@ typedef struct { unsigned long pgprot; }
20727         (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
20728          VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20729  
20730 +#ifdef CONFIG_PAX_PAGEEXEC
20731 +#ifdef CONFIG_PAX_MPROTECT
20732 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20733 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20734 +#else
20735 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20736 +#endif
20737 +#endif
20738 +
20739  #define __HAVE_ARCH_GATE_AREA 1        
20740  
20741  #endif /* __KERNEL__ */
20742 diff -urNp linux-2.6.17.11/include/asm-x86_64/pgalloc.h linux-2.6.17.11/include/asm-x86_64/pgalloc.h
20743 --- linux-2.6.17.11/include/asm-x86_64/pgalloc.h        2006-08-07 00:18:54.000000000 -0400
20744 +++ linux-2.6.17.11/include/asm-x86_64/pgalloc.h        2006-09-01 16:20:29.000000000 -0400
20745 @@ -7,7 +7,7 @@
20746  #include <linux/mm.h>
20747  
20748  #define pmd_populate_kernel(mm, pmd, pte) \
20749 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
20750 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
20751  #define pud_populate(mm, pud, pmd) \
20752                 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
20753  #define pgd_populate(mm, pgd, pud) \
20754 diff -urNp linux-2.6.17.11/include/asm-x86_64/pgtable.h linux-2.6.17.11/include/asm-x86_64/pgtable.h
20755 --- linux-2.6.17.11/include/asm-x86_64/pgtable.h        2006-08-07 00:18:54.000000000 -0400
20756 +++ linux-2.6.17.11/include/asm-x86_64/pgtable.h        2006-09-01 16:20:29.000000000 -0400
20757 @@ -180,6 +180,10 @@ static inline pte_t ptep_get_and_clear_f
20758  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
20759  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
20760  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
20761 +
20762 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
20763 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
20764 +
20765  #define __PAGE_KERNEL \
20766         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
20767  #define __PAGE_KERNEL_EXEC \
20768 @@ -268,7 +272,13 @@ static inline pte_t pfn_pte(unsigned lon
20769  #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
20770  static inline int pte_user(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
20771  static inline int pte_read(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
20772 -static inline int pte_exec(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
20773 +extern inline int pte_exec(pte_t pte)
20774 +{
20775 +       if (__supported_pte_mask & _PAGE_NX)
20776 +               return pte_val(pte) & _PAGE_NX;
20777 +       else
20778 +               return pte_val(pte) & _PAGE_USER;
20779 +}
20780  static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
20781  static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
20782  static inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_RW; }
20783 @@ -276,12 +286,26 @@ static inline int pte_file(pte_t pte)             {
20784  static inline int pte_huge(pte_t pte)          { return pte_val(pte) & _PAGE_PSE; }
20785  
20786  static inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
20787 -static inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
20788 +extern inline pte_t pte_exprotect(pte_t pte)
20789 +{
20790 +       if (__supported_pte_mask & _PAGE_NX)
20791 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
20792 +       else
20793 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
20794 +       return pte;
20795 +}
20796  static inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
20797  static inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
20798  static inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
20799  static inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
20800 -static inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
20801 +extern inline pte_t pte_mkexec(pte_t pte)
20802 +{
20803 +       if (__supported_pte_mask & _PAGE_NX)
20804 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
20805 +       else
20806 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
20807 +       return pte;
20808 +}
20809  static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
20810  static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
20811  static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
20812 diff -urNp linux-2.6.17.11/include/asm-x86_64/system.h linux-2.6.17.11/include/asm-x86_64/system.h
20813 --- linux-2.6.17.11/include/asm-x86_64/system.h 2006-08-07 00:18:54.000000000 -0400
20814 +++ linux-2.6.17.11/include/asm-x86_64/system.h 2006-09-01 16:20:29.000000000 -0400
20815 @@ -366,6 +366,6 @@ static inline unsigned long __cmpxchg(vo
20816  
20817  void cpu_idle_wait(void);
20818  
20819 -extern unsigned long arch_align_stack(unsigned long sp);
20820 +#define arch_align_stack(x) (x)
20821  
20822  #endif
20823 diff -urNp linux-2.6.17.11/include/asm-xtensa/kmap_types.h linux-2.6.17.11/include/asm-xtensa/kmap_types.h
20824 --- linux-2.6.17.11/include/asm-xtensa/kmap_types.h     2006-08-07 00:18:54.000000000 -0400
20825 +++ linux-2.6.17.11/include/asm-xtensa/kmap_types.h     2006-09-01 16:20:29.000000000 -0400
20826 @@ -25,6 +25,7 @@ enum km_type {
20827    KM_IRQ1,
20828    KM_SOFTIRQ0,
20829    KM_SOFTIRQ1,
20830 +  KM_CLEARPAGE,
20831    KM_TYPE_NR
20832  };
20833  
20834 diff -urNp linux-2.6.17.11/include/linux/a.out.h linux-2.6.17.11/include/linux/a.out.h
20835 --- linux-2.6.17.11/include/linux/a.out.h       2006-08-07 00:18:54.000000000 -0400
20836 +++ linux-2.6.17.11/include/linux/a.out.h       2006-09-01 16:20:29.000000000 -0400
20837 @@ -7,6 +7,16 @@
20838  
20839  #include <asm/a.out.h>
20840  
20841 +#ifdef CONFIG_PAX_RANDUSTACK
20842 +#define __DELTA_STACK (current->mm->delta_stack)
20843 +#else
20844 +#define __DELTA_STACK 0UL
20845 +#endif
20846 +
20847 +#ifndef STACK_TOP
20848 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
20849 +#endif
20850 +
20851  #endif /* __STRUCT_EXEC_OVERRIDE__ */
20852  
20853  /* these go in the N_MACHTYPE field */
20854 @@ -37,6 +47,14 @@ enum machine_type {
20855    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
20856  };
20857  
20858 +/* Constants for the N_FLAGS field */
20859 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
20860 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
20861 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
20862 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
20863 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
20864 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
20865 +
20866  #if !defined (N_MAGIC)
20867  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
20868  #endif
20869 diff -urNp linux-2.6.17.11/include/linux/binfmts.h linux-2.6.17.11/include/linux/binfmts.h
20870 --- linux-2.6.17.11/include/linux/binfmts.h     2006-08-07 00:18:54.000000000 -0400
20871 +++ linux-2.6.17.11/include/linux/binfmts.h     2006-09-01 16:20:29.000000000 -0400
20872 @@ -7,10 +7,10 @@ struct pt_regs;
20873  
20874  /*
20875   * MAX_ARG_PAGES defines the number of pages allocated for arguments
20876 - * and envelope for the new program. 32 should suffice, this gives
20877 - * a maximum env+arg of 128kB w/4KB pages!
20878 + * and envelope for the new program. 33 should suffice, this gives
20879 + * a maximum env+arg of 132kB w/4KB pages!
20880   */
20881 -#define MAX_ARG_PAGES 32
20882 +#define MAX_ARG_PAGES 33
20883  
20884  /* sizeof(linux_binprm->buf) */
20885  #define BINPRM_BUF_SIZE 128
20886 @@ -38,6 +38,7 @@ struct linux_binprm{
20887         unsigned interp_flags;
20888         unsigned interp_data;
20889         unsigned long loader, exec;
20890 +       int misc;
20891  };
20892  
20893  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
20894 @@ -87,5 +88,8 @@ extern void compute_creds(struct linux_b
20895  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
20896  extern int set_binfmt(struct linux_binfmt *new);
20897  
20898 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
20899 +void pax_report_insns(void *pc, void *sp);
20900 +
20901  #endif /* __KERNEL__ */
20902  #endif /* _LINUX_BINFMTS_H */
20903 diff -urNp linux-2.6.17.11/include/linux/capability.h linux-2.6.17.11/include/linux/capability.h
20904 --- linux-2.6.17.11/include/linux/capability.h  2006-08-07 00:18:54.000000000 -0400
20905 +++ linux-2.6.17.11/include/linux/capability.h  2006-09-01 16:20:29.000000000 -0400
20906 @@ -364,6 +364,7 @@ static inline kernel_cap_t cap_invert(ke
20907  #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
20908  
20909  int capable(int cap);
20910 +int capable_nolog(int cap);
20911  int __capable(struct task_struct *t, int cap);
20912  
20913  #endif /* __KERNEL__ */
20914 diff -urNp linux-2.6.17.11/include/linux/elf.h linux-2.6.17.11/include/linux/elf.h
20915 --- linux-2.6.17.11/include/linux/elf.h 2006-08-07 00:18:54.000000000 -0400
20916 +++ linux-2.6.17.11/include/linux/elf.h 2006-09-01 16:20:29.000000000 -0400
20917 @@ -5,6 +5,10 @@
20918  #include <linux/auxvec.h>
20919  #include <asm/elf.h>
20920  
20921 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20922 +#undef elf_read_implies_exec
20923 +#endif
20924 +
20925  #ifndef elf_read_implies_exec
20926    /* Executables for which elf_read_implies_exec() returns TRUE will
20927       have the READ_IMPLIES_EXEC personality flag set automatically.
20928 @@ -46,6 +50,16 @@ typedef __s64        Elf64_Sxword;
20929  
20930  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
20931  
20932 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
20933 +
20934 +/* Constants for the e_flags field */
20935 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
20936 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
20937 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
20938 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
20939 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
20940 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
20941 +
20942  /* These constants define the different elf file types */
20943  #define ET_NONE   0
20944  #define ET_REL    1
20945 @@ -138,6 +152,8 @@ typedef __s64       Elf64_Sxword;
20946  #define DT_DEBUG       21
20947  #define DT_TEXTREL     22
20948  #define DT_JMPREL      23
20949 +#define DT_FLAGS       30
20950 +  #define DF_TEXTREL   0x00000004
20951  #define DT_LOPROC      0x70000000
20952  #define DT_HIPROC      0x7fffffff
20953  
20954 @@ -267,6 +283,19 @@ typedef struct elf64_hdr {
20955  #define PF_W           0x2
20956  #define PF_X           0x1
20957  
20958 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
20959 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
20960 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
20961 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
20962 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
20963 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
20964 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
20965 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
20966 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
20967 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
20968 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
20969 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
20970 +
20971  typedef struct elf32_phdr{
20972    Elf32_Word   p_type;
20973    Elf32_Off    p_offset;
20974 @@ -359,6 +388,8 @@ typedef struct elf64_shdr {
20975  #define        EI_OSABI        7
20976  #define        EI_PAD          8
20977  
20978 +#define        EI_PAX          14
20979 +
20980  #define        ELFMAG0         0x7f            /* EI_MAG */
20981  #define        ELFMAG1         'E'
20982  #define        ELFMAG2         'L'
20983 @@ -415,6 +446,7 @@ extern Elf32_Dyn _DYNAMIC [];
20984  #define elfhdr         elf32_hdr
20985  #define elf_phdr       elf32_phdr
20986  #define elf_note       elf32_note
20987 +#define elf_dyn                Elf32_Dyn
20988  
20989  #else
20990  
20991 @@ -422,6 +454,7 @@ extern Elf64_Dyn _DYNAMIC [];
20992  #define elfhdr         elf64_hdr
20993  #define elf_phdr       elf64_phdr
20994  #define elf_note       elf64_note
20995 +#define elf_dyn                Elf64_Dyn
20996  
20997  #endif
20998  
20999 diff -urNp linux-2.6.17.11/include/linux/gracl.h linux-2.6.17.11/include/linux/gracl.h
21000 --- linux-2.6.17.11/include/linux/gracl.h       1969-12-31 19:00:00.000000000 -0500
21001 +++ linux-2.6.17.11/include/linux/gracl.h       2006-09-01 16:20:29.000000000 -0400
21002 @@ -0,0 +1,316 @@
21003 +#ifndef GR_ACL_H
21004 +#define GR_ACL_H
21005 +
21006 +#include <linux/grdefs.h>
21007 +#include <linux/resource.h>
21008 +#include <linux/dcache.h>
21009 +#include <asm/resource.h>
21010 +
21011 +/* Major status information */
21012 +
21013 +#define GR_VERSION  "grsecurity 2.1.9"
21014 +#define GRSECURITY_VERSION 0x219
21015 +
21016 +enum {
21017 +
21018 +       SHUTDOWN = 0,
21019 +       ENABLE = 1,
21020 +       SPROLE = 2,
21021 +       RELOAD = 3,
21022 +       SEGVMOD = 4,
21023 +       STATUS = 5,
21024 +       UNSPROLE = 6,
21025 +       PASSSET = 7,
21026 +       SPROLEPAM = 8
21027 +};
21028 +
21029 +/* Password setup definitions
21030 + * kernel/grhash.c */
21031 +enum {
21032 +       GR_PW_LEN = 128,
21033 +       GR_SALT_LEN = 16,
21034 +       GR_SHA_LEN = 32,
21035 +};
21036 +
21037 +enum {
21038 +       GR_SPROLE_LEN = 64,
21039 +};
21040 +
21041 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
21042 +
21043 +/* Begin Data Structures */
21044 +
21045 +struct sprole_pw {
21046 +       unsigned char *rolename;
21047 +       unsigned char salt[GR_SALT_LEN];
21048 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
21049 +};
21050 +
21051 +struct name_entry {
21052 +       __u32 key;
21053 +       ino_t inode;
21054 +       dev_t device;
21055 +       char *name;
21056 +       __u16 len;
21057 +       struct name_entry *prev;
21058 +       struct name_entry *next;
21059 +};
21060 +
21061 +struct inodev_entry {
21062 +       struct name_entry *nentry;
21063 +       struct inodev_entry *prev;
21064 +       struct inodev_entry *next;
21065 +};
21066 +
21067 +struct acl_role_db {
21068 +       struct acl_role_label **r_hash;
21069 +       __u32 r_size;
21070 +};
21071 +
21072 +struct inodev_db {
21073 +       struct inodev_entry **i_hash;
21074 +       __u32 i_size;
21075 +};
21076 +
21077 +struct name_db {
21078 +       struct name_entry **n_hash;
21079 +       __u32 n_size;
21080 +};
21081 +
21082 +struct crash_uid {
21083 +       uid_t uid;
21084 +       unsigned long expires;
21085 +};
21086 +
21087 +struct gr_hash_struct {
21088 +       void **table;
21089 +       void **nametable;
21090 +       void *first;
21091 +       __u32 table_size;
21092 +       __u32 used_size;
21093 +       int type;
21094 +};
21095 +
21096 +/* Userspace Grsecurity ACL data structures */
21097 +
21098 +struct acl_subject_label {
21099 +       char *filename;
21100 +       ino_t inode;
21101 +       dev_t device;
21102 +       __u32 mode;
21103 +       __u32 cap_mask;
21104 +       __u32 cap_lower;
21105 +
21106 +       struct rlimit res[GR_NLIMITS];
21107 +       __u16 resmask;
21108 +
21109 +       __u8 user_trans_type;
21110 +       __u8 group_trans_type;
21111 +       uid_t *user_transitions;
21112 +       gid_t *group_transitions;
21113 +       __u16 user_trans_num;
21114 +       __u16 group_trans_num;
21115 +
21116 +       __u32 ip_proto[8];
21117 +       __u32 ip_type;
21118 +       struct acl_ip_label **ips;
21119 +       __u32 ip_num;
21120 +
21121 +       __u32 crashes;
21122 +       unsigned long expires;
21123 +
21124 +       struct acl_subject_label *parent_subject;
21125 +       struct gr_hash_struct *hash;
21126 +       struct acl_subject_label *prev;
21127 +       struct acl_subject_label *next;
21128 +
21129 +       struct acl_object_label **obj_hash;
21130 +       __u32 obj_hash_size;
21131 +       __u16 pax_flags;
21132 +};
21133 +
21134 +struct role_allowed_ip {
21135 +       __u32 addr;
21136 +       __u32 netmask;
21137 +
21138 +       struct role_allowed_ip *prev;
21139 +       struct role_allowed_ip *next;
21140 +};
21141 +
21142 +struct role_transition {
21143 +       char *rolename;
21144 +
21145 +       struct role_transition *prev;
21146 +       struct role_transition *next;
21147 +};
21148 +
21149 +struct acl_role_label {
21150 +       char *rolename;
21151 +       uid_t uidgid;
21152 +       __u16 roletype;
21153 +
21154 +       __u16 auth_attempts;
21155 +       unsigned long expires;
21156 +
21157 +       struct acl_subject_label *root_label;
21158 +       struct gr_hash_struct *hash;
21159 +
21160 +       struct acl_role_label *prev;
21161 +       struct acl_role_label *next;
21162 +
21163 +       struct role_transition *transitions;
21164 +       struct role_allowed_ip *allowed_ips;
21165 +       uid_t *domain_children;
21166 +       __u16 domain_child_num;
21167 +
21168 +       struct acl_subject_label **subj_hash;
21169 +       __u32 subj_hash_size;
21170 +};
21171 +
21172 +struct user_acl_role_db {
21173 +       struct acl_role_label **r_table;
21174 +       __u32 num_pointers;             /* Number of allocations to track */
21175 +       __u32 num_roles;                /* Number of roles */
21176 +       __u32 num_domain_children;      /* Number of domain children */
21177 +       __u32 num_subjects;             /* Number of subjects */
21178 +       __u32 num_objects;              /* Number of objects */
21179 +};
21180 +
21181 +struct acl_object_label {
21182 +       char *filename;
21183 +       ino_t inode;
21184 +       dev_t device;
21185 +       __u32 mode;
21186 +
21187 +       struct acl_subject_label *nested;
21188 +       struct acl_object_label *globbed;
21189 +
21190 +       /* next two structures not used */
21191 +
21192 +       struct acl_object_label *prev;
21193 +       struct acl_object_label *next;
21194 +};
21195 +
21196 +struct acl_ip_label {
21197 +       char *iface;
21198 +       __u32 addr;
21199 +       __u32 netmask;
21200 +       __u16 low, high;
21201 +       __u8 mode;
21202 +       __u32 type;
21203 +       __u32 proto[8];
21204 +
21205 +       /* next two structures not used */
21206 +
21207 +       struct acl_ip_label *prev;
21208 +       struct acl_ip_label *next;
21209 +};
21210 +
21211 +struct gr_arg {
21212 +       struct user_acl_role_db role_db;
21213 +       unsigned char pw[GR_PW_LEN];
21214 +       unsigned char salt[GR_SALT_LEN];
21215 +       unsigned char sum[GR_SHA_LEN];
21216 +       unsigned char sp_role[GR_SPROLE_LEN];
21217 +       struct sprole_pw *sprole_pws;
21218 +       dev_t segv_device;
21219 +       ino_t segv_inode;
21220 +       uid_t segv_uid;
21221 +       __u16 num_sprole_pws;
21222 +       __u16 mode;
21223 +};
21224 +
21225 +struct gr_arg_wrapper {
21226 +       struct gr_arg *arg;
21227 +       __u32 version;
21228 +       __u32 size;
21229 +};
21230 +
21231 +struct subject_map {
21232 +       struct acl_subject_label *user;
21233 +       struct acl_subject_label *kernel;
21234 +       struct subject_map *prev;
21235 +       struct subject_map *next;
21236 +};
21237 +
21238 +struct acl_subj_map_db {
21239 +       struct subject_map **s_hash;
21240 +       __u32 s_size;
21241 +};
21242 +
21243 +/* End Data Structures Section */
21244 +
21245 +/* Hash functions generated by empirical testing by Brad Spengler
21246 +   Makes good use of the low bits of the inode.  Generally 0-1 times
21247 +   in loop for successful match.  0-3 for unsuccessful match.
21248 +   Shift/add algorithm with modulus of table size and an XOR*/
21249 +
21250 +static __inline__ unsigned int
21251 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
21252 +{
21253 +       return (((uid << type) + (uid ^ type)) % sz);
21254 +}
21255 +
21256 + static __inline__ unsigned int
21257 +shash(const struct acl_subject_label *userp, const unsigned int sz)
21258 +{
21259 +       return ((const unsigned long)userp % sz);
21260 +}
21261 +
21262 +static __inline__ unsigned int
21263 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
21264 +{
21265 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
21266 +}
21267 +
21268 +static __inline__ unsigned int
21269 +nhash(const char *name, const __u16 len, const unsigned int sz)
21270 +{
21271 +       return full_name_hash(name, len) % sz;
21272 +}
21273 +
21274 +#define FOR_EACH_ROLE_START(role,iter) \
21275 +       role = NULL; \
21276 +       iter = 0; \
21277 +       while (iter < acl_role_set.r_size) { \
21278 +               if (role == NULL) \
21279 +                       role = acl_role_set.r_hash[iter]; \
21280 +               if (role == NULL) { \
21281 +                       iter++; \
21282 +                       continue; \
21283 +               }
21284 +
21285 +#define FOR_EACH_ROLE_END(role,iter) \
21286 +               role = role->next; \
21287 +               if (role == NULL) \
21288 +                       iter++; \
21289 +       }
21290 +
21291 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
21292 +       subj = NULL; \
21293 +       iter = 0; \
21294 +       while (iter < role->subj_hash_size) { \
21295 +               if (subj == NULL) \
21296 +                       subj = role->subj_hash[iter]; \
21297 +               if (subj == NULL) { \
21298 +                       iter++; \
21299 +                       continue; \
21300 +               }
21301 +
21302 +#define FOR_EACH_SUBJECT_END(subj,iter) \
21303 +               subj = subj->next; \
21304 +               if (subj == NULL) \
21305 +                       iter++; \
21306 +       }
21307 +
21308 +
21309 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
21310 +       subj = role->hash->first; \
21311 +       while (subj != NULL) {
21312 +
21313 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
21314 +               subj = subj->next; \
21315 +       }
21316 +
21317 +#endif
21318 +
21319 diff -urNp linux-2.6.17.11/include/linux/gralloc.h linux-2.6.17.11/include/linux/gralloc.h
21320 --- linux-2.6.17.11/include/linux/gralloc.h     1969-12-31 19:00:00.000000000 -0500
21321 +++ linux-2.6.17.11/include/linux/gralloc.h     2006-09-01 16:20:29.000000000 -0400
21322 @@ -0,0 +1,8 @@
21323 +#ifndef __GRALLOC_H
21324 +#define __GRALLOC_H
21325 +
21326 +void acl_free_all(void);
21327 +int acl_alloc_stack_init(unsigned long size);
21328 +void *acl_alloc(unsigned long len);
21329 +
21330 +#endif
21331 diff -urNp linux-2.6.17.11/include/linux/grdefs.h linux-2.6.17.11/include/linux/grdefs.h
21332 --- linux-2.6.17.11/include/linux/grdefs.h      1969-12-31 19:00:00.000000000 -0500
21333 +++ linux-2.6.17.11/include/linux/grdefs.h      2006-09-01 16:20:29.000000000 -0400
21334 @@ -0,0 +1,131 @@
21335 +#ifndef GRDEFS_H
21336 +#define GRDEFS_H
21337 +
21338 +/* Begin grsecurity status declarations */
21339 +
21340 +enum {
21341 +       GR_READY = 0x01,
21342 +       GR_STATUS_INIT = 0x00   // disabled state
21343 +};
21344 +
21345 +/* Begin  ACL declarations */
21346 +
21347 +/* Role flags */
21348 +
21349 +enum {
21350 +       GR_ROLE_USER = 0x0001,
21351 +       GR_ROLE_GROUP = 0x0002,
21352 +       GR_ROLE_DEFAULT = 0x0004,
21353 +       GR_ROLE_SPECIAL = 0x0008,
21354 +       GR_ROLE_AUTH = 0x0010,
21355 +       GR_ROLE_NOPW = 0x0020,
21356 +       GR_ROLE_GOD = 0x0040,
21357 +       GR_ROLE_LEARN = 0x0080,
21358 +       GR_ROLE_TPE = 0x0100,
21359 +       GR_ROLE_DOMAIN = 0x0200,
21360 +       GR_ROLE_PAM = 0x0400
21361 +};
21362 +
21363 +/* ACL Subject and Object mode flags */
21364 +enum {
21365 +       GR_DELETED = 0x80000000
21366 +};
21367 +
21368 +/* ACL Object-only mode flags */
21369 +enum {
21370 +       GR_READ         = 0x00000001,
21371 +       GR_APPEND       = 0x00000002,
21372 +       GR_WRITE        = 0x00000004,
21373 +       GR_EXEC         = 0x00000008,
21374 +       GR_FIND         = 0x00000010,
21375 +       GR_INHERIT      = 0x00000020,
21376 +       GR_SETID        = 0x00000040,
21377 +       GR_CREATE       = 0x00000080,
21378 +       GR_DELETE       = 0x00000100,
21379 +       GR_LINK         = 0x00000200,
21380 +       GR_AUDIT_READ   = 0x00000400,
21381 +       GR_AUDIT_APPEND = 0x00000800,
21382 +       GR_AUDIT_WRITE  = 0x00001000,
21383 +       GR_AUDIT_EXEC   = 0x00002000,
21384 +       GR_AUDIT_FIND   = 0x00004000,
21385 +       GR_AUDIT_INHERIT= 0x00008000,
21386 +       GR_AUDIT_SETID  = 0x00010000,
21387 +       GR_AUDIT_CREATE = 0x00020000,
21388 +       GR_AUDIT_DELETE = 0x00040000,
21389 +       GR_AUDIT_LINK   = 0x00080000,
21390 +       GR_PTRACERD     = 0x00100000,
21391 +       GR_NOPTRACE     = 0x00200000,
21392 +       GR_SUPPRESS     = 0x00400000,
21393 +       GR_NOLEARN      = 0x00800000
21394 +};
21395 +
21396 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
21397 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
21398 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
21399 +
21400 +/* ACL subject-only mode flags */
21401 +enum {
21402 +       GR_KILL         = 0x00000001,
21403 +       GR_VIEW         = 0x00000002,
21404 +       GR_PROTECTED    = 0x00000004,
21405 +       GR_LEARN        = 0x00000008,
21406 +       GR_OVERRIDE     = 0x00000010,
21407 +       /* just a placeholder, this mode is only used in userspace */
21408 +       GR_DUMMY        = 0x00000020,
21409 +       GR_PROTSHM      = 0x00000040,
21410 +       GR_KILLPROC     = 0x00000080,
21411 +       GR_KILLIPPROC   = 0x00000100,
21412 +       /* just a placeholder, this mode is only used in userspace */
21413 +       GR_NOTROJAN     = 0x00000200,
21414 +       GR_PROTPROCFD   = 0x00000400,
21415 +       GR_PROCACCT     = 0x00000800,
21416 +       GR_RELAXPTRACE  = 0x00001000,
21417 +       GR_NESTED       = 0x00002000,
21418 +       GR_INHERITLEARN = 0x00004000,
21419 +       GR_PROCFIND     = 0x00008000,
21420 +       GR_POVERRIDE    = 0x00010000,
21421 +       GR_KERNELAUTH   = 0x00020000,
21422 +};
21423 +
21424 +enum {
21425 +       GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
21426 +       GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
21427 +       GR_PAX_ENABLE_MPROTECT  = 0x0004,
21428 +       GR_PAX_ENABLE_RANDMMAP  = 0x0008,
21429 +       GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
21430 +       GR_PAX_DISABLE_SEGMEXEC = 0x8001,
21431 +       GR_PAX_DISABLE_PAGEEXEC = 0x8002,
21432 +       GR_PAX_DISABLE_MPROTECT = 0x8004,
21433 +       GR_PAX_DISABLE_RANDMMAP = 0x8008,
21434 +       GR_PAX_DISABLE_EMUTRAMP = 0x8010,
21435 +};
21436 +
21437 +enum {
21438 +       GR_ID_USER      = 0x01,
21439 +       GR_ID_GROUP     = 0x02,
21440 +};
21441 +
21442 +enum {
21443 +       GR_ID_ALLOW     = 0x01,
21444 +       GR_ID_DENY      = 0x02,
21445 +};
21446 +
21447 +#define GR_CRASH_RES   11
21448 +#define GR_UIDTABLE_MAX 500
21449 +
21450 +/* begin resource learning section */
21451 +enum {
21452 +       GR_RLIM_CPU_BUMP = 60,
21453 +       GR_RLIM_FSIZE_BUMP = 50000,
21454 +       GR_RLIM_DATA_BUMP = 10000,
21455 +       GR_RLIM_STACK_BUMP = 1000,
21456 +       GR_RLIM_CORE_BUMP = 10000,
21457 +       GR_RLIM_RSS_BUMP = 500000,
21458 +       GR_RLIM_NPROC_BUMP = 1,
21459 +       GR_RLIM_NOFILE_BUMP = 5,
21460 +       GR_RLIM_MEMLOCK_BUMP = 50000,
21461 +       GR_RLIM_AS_BUMP = 500000,
21462 +       GR_RLIM_LOCKS_BUMP = 2
21463 +};
21464 +
21465 +#endif
21466 diff -urNp linux-2.6.17.11/include/linux/grinternal.h linux-2.6.17.11/include/linux/grinternal.h
21467 --- linux-2.6.17.11/include/linux/grinternal.h  1969-12-31 19:00:00.000000000 -0500
21468 +++ linux-2.6.17.11/include/linux/grinternal.h  2006-09-01 16:20:29.000000000 -0400
21469 @@ -0,0 +1,211 @@
21470 +#ifndef __GRINTERNAL_H
21471 +#define __GRINTERNAL_H
21472 +
21473 +#ifdef CONFIG_GRKERNSEC
21474 +
21475 +#include <linux/fs.h>
21476 +#include <linux/gracl.h>
21477 +#include <linux/grdefs.h>
21478 +#include <linux/grmsg.h>
21479 +
21480 +extern void gr_add_learn_entry(const char *fmt, ...);
21481 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
21482 +                           const struct vfsmount *mnt);
21483 +extern __u32 gr_check_create(const struct dentry *new_dentry,
21484 +                            const struct dentry *parent,
21485 +                            const struct vfsmount *mnt, const __u32 mode);
21486 +extern int gr_check_protected_task(const struct task_struct *task);
21487 +extern __u32 to_gr_audit(const __u32 reqmode);
21488 +extern int gr_set_acls(const int type);
21489 +
21490 +extern int gr_acl_is_enabled(void);
21491 +extern char gr_roletype_to_char(void);
21492 +
21493 +extern void gr_handle_alertkill(struct task_struct *task);
21494 +extern char *gr_to_filename(const struct dentry *dentry,
21495 +                           const struct vfsmount *mnt);
21496 +extern char *gr_to_filename1(const struct dentry *dentry,
21497 +                           const struct vfsmount *mnt);
21498 +extern char *gr_to_filename2(const struct dentry *dentry,
21499 +                           const struct vfsmount *mnt);
21500 +extern char *gr_to_filename3(const struct dentry *dentry,
21501 +                           const struct vfsmount *mnt);
21502 +
21503 +extern int grsec_enable_link;
21504 +extern int grsec_enable_fifo;
21505 +extern int grsec_enable_execve;
21506 +extern int grsec_enable_shm;
21507 +extern int grsec_enable_execlog;
21508 +extern int grsec_enable_signal;
21509 +extern int grsec_enable_forkfail;
21510 +extern int grsec_enable_time;
21511 +extern int grsec_enable_chroot_shmat;
21512 +extern int grsec_enable_chroot_findtask;
21513 +extern int grsec_enable_chroot_mount;
21514 +extern int grsec_enable_chroot_double;
21515 +extern int grsec_enable_chroot_pivot;
21516 +extern int grsec_enable_chroot_chdir;
21517 +extern int grsec_enable_chroot_chmod;
21518 +extern int grsec_enable_chroot_mknod;
21519 +extern int grsec_enable_chroot_fchdir;
21520 +extern int grsec_enable_chroot_nice;
21521 +extern int grsec_enable_chroot_execlog;
21522 +extern int grsec_enable_chroot_caps;
21523 +extern int grsec_enable_chroot_sysctl;
21524 +extern int grsec_enable_chroot_unix;
21525 +extern int grsec_enable_tpe;
21526 +extern int grsec_tpe_gid;
21527 +extern int grsec_enable_tpe_all;
21528 +extern int grsec_enable_sidcaps;
21529 +extern int grsec_enable_randpid;
21530 +extern int grsec_enable_socket_all;
21531 +extern int grsec_socket_all_gid;
21532 +extern int grsec_enable_socket_client;
21533 +extern int grsec_socket_client_gid;
21534 +extern int grsec_enable_socket_server;
21535 +extern int grsec_socket_server_gid;
21536 +extern int grsec_audit_gid;
21537 +extern int grsec_enable_group;
21538 +extern int grsec_enable_audit_ipc;
21539 +extern int grsec_enable_audit_textrel;
21540 +extern int grsec_enable_mount;
21541 +extern int grsec_enable_chdir;
21542 +extern int grsec_resource_logging;
21543 +extern int grsec_lock;
21544 +
21545 +extern struct task_struct *child_reaper;
21546 +
21547 +extern spinlock_t grsec_alert_lock;
21548 +extern unsigned long grsec_alert_wtime;
21549 +extern unsigned long grsec_alert_fyet;
21550 +
21551 +extern spinlock_t grsec_audit_lock;
21552 +
21553 +extern rwlock_t grsec_exec_file_lock;
21554 +
21555 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
21556 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
21557 +                       tsk->exec_file->f_vfsmnt) : "/")
21558 +
21559 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
21560 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
21561 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
21562 +
21563 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
21564 +                       gr_to_filename(tsk->exec_file->f_dentry, \
21565 +                       tsk->exec_file->f_vfsmnt) : "/")
21566 +
21567 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
21568 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
21569 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
21570 +
21571 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
21572 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
21573 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
21574 +                         (tsk_a->fs->root->d_inode->i_ino != \
21575 +                         child_reaper->fs->root->d_inode->i_ino)))
21576 +
21577 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
21578 +                         (tsk_a->fs->root->d_inode->i_sb->s_dev == \
21579 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
21580 +                         (tsk_a->fs->root->d_inode->i_ino == \
21581 +                         tsk_b->fs->root->d_inode->i_ino))
21582 +
21583 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
21584 +                      task->pid, task->uid, \
21585 +                      task->euid, task->gid, task->egid, \
21586 +                      gr_parent_task_fullpath(task), \
21587 +                      task->parent->comm, task->parent->pid, \
21588 +                      task->parent->uid, task->parent->euid, \
21589 +                      task->parent->gid, task->parent->egid
21590 +
21591 +#define GR_CHROOT_CAPS ( \
21592 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
21593 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
21594 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
21595 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
21596 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
21597 +       CAP_TO_MASK(CAP_IPC_OWNER))
21598 +
21599 +#define security_learn(normal_msg,args...) \
21600 +({ \
21601 +       read_lock(&grsec_exec_file_lock); \
21602 +       gr_add_learn_entry(normal_msg "\n", ## args); \
21603 +       read_unlock(&grsec_exec_file_lock); \
21604 +})
21605 +
21606 +enum {
21607 +       GR_DO_AUDIT,
21608 +       GR_DONT_AUDIT,
21609 +       GR_DONT_AUDIT_GOOD
21610 +};
21611 +
21612 +enum {
21613 +       GR_TTYSNIFF,
21614 +       GR_RBAC,
21615 +       GR_RBAC_STR,
21616 +       GR_STR_RBAC,
21617 +       GR_RBAC_MODE2,
21618 +       GR_RBAC_MODE3,
21619 +       GR_FILENAME,
21620 +       GR_NOARGS,
21621 +       GR_ONE_INT,
21622 +       GR_ONE_INT_TWO_STR,
21623 +       GR_ONE_STR,
21624 +       GR_STR_INT,
21625 +       GR_TWO_INT,
21626 +       GR_THREE_INT,
21627 +       GR_FIVE_INT_TWO_STR,
21628 +       GR_TWO_STR,
21629 +       GR_THREE_STR,
21630 +       GR_FOUR_STR,
21631 +       GR_STR_FILENAME,
21632 +       GR_FILENAME_STR,
21633 +       GR_FILENAME_TWO_INT,
21634 +       GR_FILENAME_TWO_INT_STR,
21635 +       GR_TEXTREL,
21636 +       GR_PTRACE,
21637 +       GR_RESOURCE,
21638 +       GR_CAP,
21639 +       GR_SIG,
21640 +       GR_CRASH1,
21641 +       GR_CRASH2,
21642 +       GR_PSACCT
21643 +};
21644 +
21645 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
21646 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
21647 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
21648 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
21649 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
21650 +#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)
21651 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
21652 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
21653 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
21654 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
21655 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
21656 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
21657 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
21658 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
21659 +#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)
21660 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
21661 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
21662 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
21663 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
21664 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
21665 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
21666 +#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)
21667 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
21668 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
21669 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
21670 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
21671 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
21672 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
21673 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
21674 +#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)
21675 +
21676 +extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
21677 +
21678 +#endif
21679 +
21680 +#endif
21681 diff -urNp linux-2.6.17.11/include/linux/grmsg.h linux-2.6.17.11/include/linux/grmsg.h
21682 --- linux-2.6.17.11/include/linux/grmsg.h       1969-12-31 19:00:00.000000000 -0500
21683 +++ linux-2.6.17.11/include/linux/grmsg.h       2006-09-01 16:20:29.000000000 -0400
21684 @@ -0,0 +1,108 @@
21685 +#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"
21686 +#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"
21687 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
21688 +#define GR_STOPMOD_MSG "denied modification of module state by "
21689 +#define GR_IOPERM_MSG "denied use of ioperm() by "
21690 +#define GR_IOPL_MSG "denied use of iopl() by "
21691 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
21692 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
21693 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
21694 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
21695 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
21696 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
21697 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
21698 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
21699 +#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"
21700 +#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"
21701 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
21702 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
21703 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
21704 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
21705 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
21706 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
21707 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
21708 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
21709 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
21710 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
21711 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
21712 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
21713 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
21714 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
21715 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
21716 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
21717 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
21718 +#define GR_NPROC_MSG "denied overstep of process limit by "
21719 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
21720 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
21721 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
21722 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
21723 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
21724 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
21725 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
21726 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
21727 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
21728 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
21729 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
21730 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
21731 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
21732 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
21733 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
21734 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
21735 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
21736 +#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"
21737 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
21738 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
21739 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
21740 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
21741 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
21742 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
21743 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
21744 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
21745 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
21746 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
21747 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
21748 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
21749 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
21750 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
21751 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
21752 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
21753 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
21754 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
21755 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
21756 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
21757 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
21758 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
21759 +#define GR_NICE_CHROOT_MSG "denied priority change by "
21760 +#define GR_UNISIGLOG_MSG "signal %d sent to "
21761 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
21762 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
21763 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
21764 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
21765 +#define GR_TIME_MSG "time set by "
21766 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
21767 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
21768 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
21769 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
21770 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
21771 +#define GR_BIND_MSG "denied bind() by "
21772 +#define GR_CONNECT_MSG "denied connect() by "
21773 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
21774 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
21775 +#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"
21776 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
21777 +#define GR_CAP_ACL_MSG "use of %s denied for "
21778 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
21779 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
21780 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
21781 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
21782 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
21783 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
21784 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
21785 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
21786 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
21787 +#define GR_SEM_AUDIT_MSG "semaphore created by "
21788 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
21789 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
21790 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
21791 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
21792 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
21793 diff -urNp linux-2.6.17.11/include/linux/grsecurity.h linux-2.6.17.11/include/linux/grsecurity.h
21794 --- linux-2.6.17.11/include/linux/grsecurity.h  1969-12-31 19:00:00.000000000 -0500
21795 +++ linux-2.6.17.11/include/linux/grsecurity.h  2006-09-01 16:20:29.000000000 -0400
21796 @@ -0,0 +1,196 @@
21797 +#ifndef GR_SECURITY_H
21798 +#define GR_SECURITY_H
21799 +#include <linux/fs.h>
21800 +#include <linux/binfmts.h>
21801 +#include <linux/gracl.h>
21802 +
21803 +extern void gr_handle_brute_attach(struct task_struct *p);
21804 +extern void gr_handle_brute_check(void);
21805 +
21806 +extern char gr_roletype_to_char(void);
21807 +
21808 +extern int gr_check_user_change(int real, int effective, int fs);
21809 +extern int gr_check_group_change(int real, int effective, int fs);
21810 +
21811 +extern void gr_del_task_from_ip_table(struct task_struct *p);
21812 +
21813 +extern int gr_pid_is_chrooted(struct task_struct *p);
21814 +extern int gr_handle_chroot_nice(void);
21815 +extern int gr_handle_chroot_sysctl(const int op);
21816 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
21817 +                                       const int niceval);
21818 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
21819 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
21820 +                                  const struct vfsmount *mnt);
21821 +extern void gr_handle_chroot_caps(struct task_struct *task);
21822 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
21823 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
21824 +                                 const struct vfsmount *mnt, const int mode);
21825 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
21826 +                                 const struct vfsmount *mnt, const int mode);
21827 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
21828 +                                 const struct vfsmount *mnt,
21829 +                                 const char *dev_name);
21830 +extern int gr_handle_chroot_pivot(void);
21831 +extern int gr_handle_chroot_unix(const pid_t pid);
21832 +
21833 +extern int gr_handle_rawio(const struct inode *inode);
21834 +extern int gr_handle_nproc(void);
21835 +
21836 +extern void gr_handle_ioperm(void);
21837 +extern void gr_handle_iopl(void);
21838 +
21839 +extern int gr_tpe_allow(const struct file *file);
21840 +
21841 +extern int gr_random_pid(void);
21842 +
21843 +extern void gr_log_forkfail(const int retval);
21844 +extern void gr_log_timechange(void);
21845 +extern void gr_log_signal(const int sig, const struct task_struct *t);
21846 +extern void gr_log_chdir(const struct dentry *dentry,
21847 +                        const struct vfsmount *mnt);
21848 +extern void gr_log_chroot_exec(const struct dentry *dentry,
21849 +                              const struct vfsmount *mnt);
21850 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
21851 +extern void gr_log_remount(const char *devname, const int retval);
21852 +extern void gr_log_unmount(const char *devname, const int retval);
21853 +extern void gr_log_mount(const char *from, const char *to, const int retval);
21854 +extern void gr_log_msgget(const int ret, const int msgflg);
21855 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
21856 +extern void gr_log_semget(const int err, const int semflg);
21857 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
21858 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
21859 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
21860 +extern void gr_log_textrel(struct vm_area_struct *vma);
21861 +
21862 +extern int gr_handle_follow_link(const struct inode *parent,
21863 +                                const struct inode *inode,
21864 +                                const struct dentry *dentry,
21865 +                                const struct vfsmount *mnt);
21866 +extern int gr_handle_fifo(const struct dentry *dentry,
21867 +                         const struct vfsmount *mnt,
21868 +                         const struct dentry *dir, const int flag,
21869 +                         const int acc_mode);
21870 +extern int gr_handle_hardlink(const struct dentry *dentry,
21871 +                             const struct vfsmount *mnt,
21872 +                             struct inode *inode,
21873 +                             const int mode, const char *to);
21874 +
21875 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
21876 +extern int gr_is_capable_nolog(const int cap);
21877 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
21878 +                             const unsigned long wanted, const int gt);
21879 +extern void gr_copy_label(struct task_struct *tsk);
21880 +extern void gr_handle_crash(struct task_struct *task, const int sig);
21881 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
21882 +extern int gr_check_crash_uid(const uid_t uid);
21883 +extern int gr_check_protected_task(const struct task_struct *task);
21884 +extern int gr_acl_handle_mmap(const struct file *file,
21885 +                             const unsigned long prot);
21886 +extern int gr_acl_handle_mprotect(const struct file *file,
21887 +                                 const unsigned long prot);
21888 +extern int gr_check_hidden_task(const struct task_struct *tsk);
21889 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
21890 +                                   const struct vfsmount *mnt);
21891 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
21892 +                                const struct vfsmount *mnt);
21893 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
21894 +                                 const struct vfsmount *mnt, const int fmode);
21895 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
21896 +                                 const struct vfsmount *mnt, mode_t mode);
21897 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
21898 +                                const struct vfsmount *mnt, mode_t mode);
21899 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
21900 +                                const struct vfsmount *mnt);
21901 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
21902 +extern int gr_handle_proc_ptrace(struct task_struct *task);
21903 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
21904 +                                 const struct vfsmount *mnt);
21905 +extern int gr_check_crash_exec(const struct file *filp);
21906 +extern int gr_acl_is_enabled(void);
21907 +extern void gr_set_kernel_label(struct task_struct *task);
21908 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
21909 +                             const gid_t gid);
21910 +extern int gr_set_proc_label(const struct dentry *dentry,
21911 +                             const struct vfsmount *mnt);
21912 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
21913 +                                      const struct vfsmount *mnt);
21914 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
21915 +                               const struct vfsmount *mnt, const int fmode);
21916 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
21917 +                                const struct dentry *p_dentry,
21918 +                                const struct vfsmount *p_mnt, const int fmode,
21919 +                                const int imode);
21920 +extern void gr_handle_create(const struct dentry *dentry,
21921 +                            const struct vfsmount *mnt);
21922 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
21923 +                                const struct dentry *parent_dentry,
21924 +                                const struct vfsmount *parent_mnt,
21925 +                                const int mode);
21926 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
21927 +                                const struct dentry *parent_dentry,
21928 +                                const struct vfsmount *parent_mnt);
21929 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
21930 +                                const struct vfsmount *mnt);
21931 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
21932 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
21933 +                                 const struct vfsmount *mnt);
21934 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
21935 +                                  const struct dentry *parent_dentry,
21936 +                                  const struct vfsmount *parent_mnt,
21937 +                                  const char *from);
21938 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
21939 +                               const struct dentry *parent_dentry,
21940 +                               const struct vfsmount *parent_mnt,
21941 +                               const struct dentry *old_dentry,
21942 +                               const struct vfsmount *old_mnt, const char *to);
21943 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
21944 +                               struct dentry *parent_dentry,
21945 +                               const struct vfsmount *parent_mnt,
21946 +                               struct dentry *old_dentry,
21947 +                               struct inode *old_parent_inode,
21948 +                               struct vfsmount *old_mnt, const char *newname);
21949 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
21950 +                               struct dentry *old_dentry,
21951 +                               struct dentry *new_dentry,
21952 +                               struct vfsmount *mnt, const __u8 replace);
21953 +extern __u32 gr_check_link(const struct dentry *new_dentry,
21954 +                          const struct dentry *parent_dentry,
21955 +                          const struct vfsmount *parent_mnt,
21956 +                          const struct dentry *old_dentry,
21957 +                          const struct vfsmount *old_mnt);
21958 +extern int gr_acl_handle_filldir(const struct file *file, const char *name,
21959 +                                const unsigned int namelen, const ino_t ino);
21960 +
21961 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
21962 +                               const struct vfsmount *mnt);
21963 +extern void gr_acl_handle_exit(void);
21964 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
21965 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
21966 +extern __u32 gr_cap_rtnetlink(void);
21967 +
21968 +#ifdef CONFIG_SYSVIPC
21969 +extern void gr_shm_exit(struct task_struct *task);
21970 +#else
21971 +static inline void gr_shm_exit(struct task_struct *task)
21972 +{
21973 +       return;
21974 +}
21975 +#endif
21976 +
21977 +#ifdef CONFIG_GRKERNSEC
21978 +extern void gr_handle_mem_write(void);
21979 +extern void gr_handle_kmem_write(void);
21980 +extern void gr_handle_open_port(void);
21981 +extern int gr_handle_mem_mmap(const unsigned long offset,
21982 +                             struct vm_area_struct *vma);
21983 +
21984 +extern unsigned long pax_get_random_long(void);
21985 +#define get_random_long() pax_get_random_long()
21986 +
21987 +extern int grsec_enable_dmesg;
21988 +extern int grsec_enable_randsrc;
21989 +extern int grsec_enable_shm;
21990 +#endif
21991 +
21992 +#endif
21993 diff -urNp linux-2.6.17.11/include/linux/highmem.h linux-2.6.17.11/include/linux/highmem.h
21994 --- linux-2.6.17.11/include/linux/highmem.h     2006-08-07 00:18:54.000000000 -0400
21995 +++ linux-2.6.17.11/include/linux/highmem.h     2006-09-01 16:20:29.000000000 -0400
21996 @@ -70,9 +70,9 @@ alloc_zeroed_user_highpage(struct vm_are
21997  
21998  static inline void clear_highpage(struct page *page)
21999  {
22000 -       void *kaddr = kmap_atomic(page, KM_USER0);
22001 +       void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
22002         clear_page(kaddr);
22003 -       kunmap_atomic(kaddr, KM_USER0);
22004 +       kunmap_atomic(kaddr, KM_CLEARPAGE);
22005  }
22006  
22007  /*
22008 diff -urNp linux-2.6.17.11/include/linux/mman.h linux-2.6.17.11/include/linux/mman.h
22009 --- linux-2.6.17.11/include/linux/mman.h        2006-08-07 00:18:54.000000000 -0400
22010 +++ linux-2.6.17.11/include/linux/mman.h        2006-09-01 16:20:29.000000000 -0400
22011 @@ -59,6 +59,11 @@ static inline unsigned long
22012  calc_vm_flag_bits(unsigned long flags)
22013  {
22014         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
22015 +
22016 +#ifdef CONFIG_PAX_SEGMEXEC
22017 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
22018 +#endif
22019 +
22020                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
22021                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
22022                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
22023 diff -urNp linux-2.6.17.11/include/linux/mm.h linux-2.6.17.11/include/linux/mm.h
22024 --- linux-2.6.17.11/include/linux/mm.h  2006-08-07 00:18:54.000000000 -0400
22025 +++ linux-2.6.17.11/include/linux/mm.h  2006-09-01 16:20:29.000000000 -0400
22026 @@ -38,6 +38,7 @@ extern int sysctl_legacy_va_layout;
22027  #include <asm/pgtable.h>
22028  #include <asm/processor.h>
22029  #include <asm/atomic.h>
22030 +#include <asm/mman.h>
22031  
22032  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
22033  
22034 @@ -111,8 +112,43 @@ struct vm_area_struct {
22035  #ifdef CONFIG_NUMA
22036         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
22037  #endif
22038 +
22039 +       unsigned long vm_mirror;        /* PaX: mirror distance */
22040  };
22041  
22042 +#ifdef CONFIG_PAX_SOFTMODE
22043 +extern unsigned int pax_softmode;
22044 +#endif
22045 +
22046 +extern int pax_check_flags(unsigned long *);
22047 +
22048 +/* if tsk != current then task_lock must be held on it */
22049 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
22050 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
22051 +{
22052 +       if (likely(tsk->mm))
22053 +               return tsk->mm->pax_flags;
22054 +       else
22055 +               return 0UL;
22056 +}
22057 +
22058 +/* if tsk != current then task_lock must be held on it */
22059 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
22060 +{
22061 +       if (likely(tsk->mm)) {
22062 +               tsk->mm->pax_flags = flags;
22063 +               return 0;
22064 +       }
22065 +       return -EINVAL;
22066 +}
22067 +#endif
22068 +
22069 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
22070 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
22071 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
22072 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
22073 +#endif
22074 +
22075  /*
22076   * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
22077   * disabled, then there's a single shared list of VMAs maintained by the
22078 @@ -167,6 +203,18 @@ extern unsigned int kobjsize(const void 
22079  #define VM_MAPPED_COPY 0x01000000      /* T if mapped copy of data (nommu mmap) */
22080  #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
22081  
22082 +#ifdef CONFIG_PAX_SEGMEXEC
22083 +#define VM_MIRROR      0x04000000      /* vma is mirroring another */
22084 +#endif
22085 +
22086 +#ifdef CONFIG_PAX_MPROTECT
22087 +#define VM_MAYNOTWRITE 0x08000000      /* vma cannot be granted VM_WRITE any more */
22088 +#endif
22089 +
22090 +#ifdef __VM_STACK_FLAGS
22091 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
22092 +#endif
22093 +
22094  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
22095  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
22096  #endif
22097 @@ -1058,5 +1106,11 @@ void drop_slab(void);
22098  extern int randomize_va_space;
22099  #endif
22100  
22101 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22102 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
22103 +#else
22104 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
22105 +#endif
22106 +
22107  #endif /* __KERNEL__ */
22108  #endif /* _LINUX_MM_H */
22109 diff -urNp linux-2.6.17.11/include/linux/module.h linux-2.6.17.11/include/linux/module.h
22110 --- linux-2.6.17.11/include/linux/module.h      2006-08-07 00:18:54.000000000 -0400
22111 +++ linux-2.6.17.11/include/linux/module.h      2006-09-01 16:20:29.000000000 -0400
22112 @@ -273,16 +273,16 @@ struct module
22113         int (*init)(void);
22114  
22115         /* If this is non-NULL, vfree after init() returns */
22116 -       void *module_init;
22117 +       void *module_init_rx, *module_init_rw;
22118  
22119         /* Here is the actual code + data, vfree'd on unload. */
22120 -       void *module_core;
22121 +       void *module_core_rx, *module_core_rw;
22122  
22123         /* Here are the sizes of the init and core sections */
22124 -       unsigned long init_size, core_size;
22125 +       unsigned long init_size_rw, core_size_rw;
22126  
22127         /* The size of the executable code in each section.  */
22128 -       unsigned long init_text_size, core_text_size;
22129 +       unsigned long init_size_rx, core_size_rx;
22130  
22131         /* Arch-specific module values */
22132         struct mod_arch_specific arch;
22133 diff -urNp linux-2.6.17.11/include/linux/moduleloader.h linux-2.6.17.11/include/linux/moduleloader.h
22134 --- linux-2.6.17.11/include/linux/moduleloader.h        2006-08-07 00:18:54.000000000 -0400
22135 +++ linux-2.6.17.11/include/linux/moduleloader.h        2006-09-01 16:20:29.000000000 -0400
22136 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
22137     sections.  Returns NULL on failure. */
22138  void *module_alloc(unsigned long size);
22139  
22140 +#ifdef CONFIG_PAX_KERNEXEC
22141 +void *module_alloc_exec(unsigned long size);
22142 +#else
22143 +#define module_alloc_exec(x) module_alloc(x)
22144 +#endif
22145 +
22146  /* Free memory returned from module_alloc. */
22147  void module_free(struct module *mod, void *module_region);
22148  
22149 +#ifdef CONFIG_PAX_KERNEXEC
22150 +void module_free_exec(struct module *mod, void *module_region);
22151 +#else
22152 +#define module_free_exec(x, y) module_free(x, y)
22153 +#endif
22154 +
22155  /* Apply the given relocation to the (simplified) ELF.  Return -error
22156     or 0. */
22157  int apply_relocate(Elf_Shdr *sechdrs,
22158 diff -urNp linux-2.6.17.11/include/linux/random.h linux-2.6.17.11/include/linux/random.h
22159 --- linux-2.6.17.11/include/linux/random.h      2006-08-07 00:18:54.000000000 -0400
22160 +++ linux-2.6.17.11/include/linux/random.h      2006-09-01 16:20:29.000000000 -0400
22161 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
22162  extern u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
22163                                        __u16 sport, __u16 dport);
22164  
22165 +extern unsigned long pax_get_random_long(void);
22166 +
22167  #ifndef MODULE
22168  extern struct file_operations random_fops, urandom_fops;
22169  #endif
22170 diff -urNp linux-2.6.17.11/include/linux/sched.h linux-2.6.17.11/include/linux/sched.h
22171 --- linux-2.6.17.11/include/linux/sched.h       2006-08-07 00:18:54.000000000 -0400
22172 +++ linux-2.6.17.11/include/linux/sched.h       2006-09-01 16:20:29.000000000 -0400
22173 @@ -41,6 +41,7 @@
22174  #include <linux/auxvec.h>      /* For AT_VECTOR_SIZE */
22175  
22176  struct exec_domain;
22177 +struct linux_binprm;
22178  
22179  /*
22180   * cloning flags:
22181 @@ -357,8 +358,34 @@ struct mm_struct {
22182         /* aio bits */
22183         rwlock_t                ioctx_list_lock;
22184         struct kioctx           *ioctx_list;
22185 +
22186 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
22187 +       unsigned long pax_flags;
22188 +#endif
22189 +
22190 +#ifdef CONFIG_PAX_DLRESOLVE
22191 +       unsigned long call_dl_resolve;
22192 +#endif
22193 +
22194 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
22195 +       unsigned long call_syscall;
22196 +#endif
22197 +
22198 +#ifdef CONFIG_PAX_ASLR
22199 +       unsigned long delta_mmap;               /* randomized offset */
22200 +       unsigned long delta_exec;               /* randomized offset */
22201 +       unsigned long delta_stack;              /* randomized offset */
22202 +#endif
22203 +
22204  };
22205  
22206 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
22207 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
22208 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
22209 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
22210 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
22211 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
22212 +
22213  struct sighand_struct {
22214         atomic_t                count;
22215         struct k_sigaction      action[_NSIG];
22216 @@ -456,6 +483,15 @@ struct signal_struct {
22217         struct key *session_keyring;    /* keyring inherited over fork */
22218         struct key *process_keyring;    /* keyring private to this process */
22219  #endif
22220 +
22221 +#ifdef CONFIG_GRKERNSEC
22222 +       u32 curr_ip;
22223 +       u32 gr_saddr;
22224 +       u32 gr_daddr;
22225 +       u16 gr_sport;
22226 +       u16 gr_dport;
22227 +       u8 used_accept:1;
22228 +#endif
22229  };
22230  
22231  /* Context switch must be unlocked if interrupts are to be enabled */
22232 @@ -898,6 +934,17 @@ struct task_struct {
22233         struct compat_robust_list_head __user *compat_robust_list;
22234  #endif
22235  
22236 +#ifdef CONFIG_GRKERNSEC
22237 +       /* grsecurity */
22238 +       struct acl_subject_label *acl;
22239 +       struct acl_role_label *role;
22240 +       struct file *exec_file;
22241 +       u16 acl_role_id;
22242 +       u8 acl_sp_role:1;
22243 +       u8 is_writable:1;
22244 +       u8 brute:1;
22245 +#endif
22246 +
22247         atomic_t fs_excl;       /* holding fs exclusive resources */
22248         struct rcu_head rcu;
22249  
22250 @@ -1416,6 +1463,12 @@ extern void arch_pick_mmap_layout(struct
22251  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
22252  {
22253         mm->mmap_base = TASK_UNMAPPED_BASE;
22254 +
22255 +#ifdef CONFIG_PAX_RANDMMAP
22256 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
22257 +               mm->mmap_base += mm->delta_mmap;
22258 +#endif
22259 +
22260         mm->get_unmapped_area = arch_get_unmapped_area;
22261         mm->unmap_area = arch_unmap_area;
22262  }
22263 diff -urNp linux-2.6.17.11/include/linux/shm.h linux-2.6.17.11/include/linux/shm.h
22264 --- linux-2.6.17.11/include/linux/shm.h 2006-08-07 00:18:54.000000000 -0400
22265 +++ linux-2.6.17.11/include/linux/shm.h 2006-09-01 16:20:29.000000000 -0400
22266 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
22267         pid_t                   shm_cprid;
22268         pid_t                   shm_lprid;
22269         struct user_struct      *mlock_user;
22270 +#ifdef CONFIG_GRKERNSEC
22271 +       time_t                  shm_createtime;
22272 +       pid_t                   shm_lapid;
22273 +#endif
22274  };
22275  
22276  /* shm_mode upper byte flags */
22277 diff -urNp linux-2.6.17.11/include/linux/sysctl.h linux-2.6.17.11/include/linux/sysctl.h
22278 --- linux-2.6.17.11/include/linux/sysctl.h      2006-08-07 00:18:54.000000000 -0400
22279 +++ linux-2.6.17.11/include/linux/sysctl.h      2006-09-01 16:20:29.000000000 -0400
22280 @@ -78,9 +78,22 @@
22281         INOTIFY_MAX_QUEUED_EVENTS=3     /* max queued events per instance */
22282  };
22283  
22284 +#ifdef CONFIG_PAX_SOFTMODE
22285 +enum {
22286 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
22287 +};
22288 +#endif
22289 +
22290  /* CTL_KERN names: */
22291  enum
22292  {
22293 +#ifdef CONFIG_GRKERNSEC
22294 +       KERN_GRSECURITY=98,     /* grsecurity */
22295 +#endif
22296 +
22297 +#ifdef CONFIG_PAX_SOFTMODE
22298 +       KERN_PAX=99,            /* PaX control */
22299 +#endif
22300         KERN_OSTYPE=1,          /* string: system version */
22301         KERN_OSRELEASE=2,       /* string: system release */
22302         KERN_OSREV=3,           /* int: system revision */
22303 diff -urNp linux-2.6.17.11/init/Kconfig linux-2.6.17.11/init/Kconfig
22304 --- linux-2.6.17.11/init/Kconfig        2006-08-07 00:18:54.000000000 -0400
22305 +++ linux-2.6.17.11/init/Kconfig        2006-09-01 16:20:29.000000000 -0400
22306 @@ -268,6 +268,7 @@ menuconfig EMBEDDED
22307  config KALLSYMS
22308          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
22309          default y
22310 +        depends on !GRKERNSEC_HIDESYM
22311          help
22312            Say Y here to let the kernel print out symbolic crash information and
22313            symbolic stack backtraces. This increases the size of the kernel
22314 diff -urNp linux-2.6.17.11/init/main.c linux-2.6.17.11/init/main.c
22315 --- linux-2.6.17.11/init/main.c 2006-08-07 00:18:54.000000000 -0400
22316 +++ linux-2.6.17.11/init/main.c 2006-09-01 16:20:29.000000000 -0400
22317 @@ -100,6 +100,7 @@ static inline void mark_rodata_ro(void) 
22318  #ifdef CONFIG_TC
22319  extern void tc_init(void);
22320  #endif
22321 +extern void grsecurity_init(void);
22322  
22323  enum system_states system_state;
22324  EXPORT_SYMBOL(system_state);
22325 @@ -150,6 +151,15 @@ static int __init maxcpus(char *str)
22326  
22327  __setup("maxcpus=", maxcpus);
22328  
22329 +#ifdef CONFIG_PAX_SOFTMODE
22330 +static int __init setup_pax_softmode(char *str)
22331 +{
22332 +       get_option(&str, &pax_softmode);
22333 +       return 1;
22334 +}
22335 +__setup("pax_softmode=", setup_pax_softmode);
22336 +#endif
22337 +
22338  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
22339  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
22340  static const char *panic_later, *panic_param;
22341 @@ -694,6 +704,8 @@ static int init(void * unused)
22342                 prepare_namespace();
22343         }
22344  
22345 +       grsecurity_init();
22346 +
22347         /*
22348          * Ok, we have completed the initial bootup, and
22349          * we're essentially up and running. Get rid of the
22350 diff -urNp linux-2.6.17.11/ipc/msg.c linux-2.6.17.11/ipc/msg.c
22351 --- linux-2.6.17.11/ipc/msg.c   2006-08-07 00:18:54.000000000 -0400
22352 +++ linux-2.6.17.11/ipc/msg.c   2006-09-01 16:20:29.000000000 -0400
22353 @@ -32,6 +32,7 @@
22354  #include <linux/audit.h>
22355  #include <linux/seq_file.h>
22356  #include <linux/mutex.h>
22357 +#include <linux/grsecurity.h>
22358  
22359  #include <asm/current.h>
22360  #include <asm/uaccess.h>
22361 @@ -238,6 +239,9 @@ asmlinkage long sys_msgget (key_t key, i
22362                 msg_unlock(msq);
22363         }
22364         mutex_unlock(&msg_ids.mutex);
22365 +
22366 +       gr_log_msgget(ret, msgflg);
22367 +
22368         return ret;
22369  }
22370  
22371 @@ -496,6 +500,8 @@ asmlinkage long sys_msgctl (int msqid, i
22372                 break;
22373         }
22374         case IPC_RMID:
22375 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
22376 +
22377                 freeque (msq, msqid); 
22378                 break;
22379         }
22380 diff -urNp linux-2.6.17.11/ipc/sem.c linux-2.6.17.11/ipc/sem.c
22381 --- linux-2.6.17.11/ipc/sem.c   2006-08-07 00:18:54.000000000 -0400
22382 +++ linux-2.6.17.11/ipc/sem.c   2006-09-01 16:20:29.000000000 -0400
22383 @@ -80,6 +80,7 @@
22384  #include <linux/seq_file.h>
22385  #include <linux/mutex.h>
22386  #include <linux/vs_limit.h>
22387 +#include <linux/grsecurity.h>
22388  
22389  #include <asm/uaccess.h>
22390  #include "util.h"
22391 @@ -247,6 +248,9 @@ asmlinkage long sys_semget (key_t key, i
22392         }
22393  
22394         mutex_unlock(&sem_ids.mutex);
22395 +
22396 +       gr_log_semget(err, semflg);
22397 +
22398         return err;
22399  }
22400  
22401 @@ -840,6 +844,8 @@ static int semctl_down(int semid, int se
22402  
22403         switch(cmd){
22404         case IPC_RMID:
22405 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
22406 +
22407                 freeary(sma, semid);
22408                 err = 0;
22409                 break;
22410 diff -urNp linux-2.6.17.11/ipc/shm.c linux-2.6.17.11/ipc/shm.c
22411 --- linux-2.6.17.11/ipc/shm.c   2006-08-07 00:18:54.000000000 -0400
22412 +++ linux-2.6.17.11/ipc/shm.c   2006-09-01 16:20:29.000000000 -0400
22413 @@ -33,6 +33,7 @@
22414  #include <linux/mutex.h>
22415  #include <linux/vs_context.h>
22416  #include <linux/vs_limit.h>
22417 +#include <linux/grsecurity.h>
22418  
22419  #include <asm/uaccess.h>
22420  
22421 @@ -56,6 +57,14 @@ static void shm_close (struct vm_area_st
22422  static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
22423  #endif
22424  
22425 +#ifdef CONFIG_GRKERNSEC
22426 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22427 +                          const time_t shm_createtime, const uid_t cuid,
22428 +                          const int shmid);
22429 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22430 +                          const time_t shm_createtime);
22431 +#endif
22432 +
22433  size_t shm_ctlmax = SHMMAX;
22434  size_t         shm_ctlall = SHMALL;
22435  int    shm_ctlmni = SHMMNI;
22436 @@ -149,6 +158,17 @@ static void shm_close (struct vm_area_st
22437         shp->shm_lprid = current->tgid;
22438         shp->shm_dtim = get_seconds();
22439         shp->shm_nattch--;
22440 +#ifdef CONFIG_GRKERNSEC_SHM
22441 +       if (grsec_enable_shm) {
22442 +               if (shp->shm_nattch == 0) {
22443 +                       shp->shm_perm.mode |= SHM_DEST;
22444 +                       shm_destroy(shp);
22445 +               } else
22446 +                       shm_unlock(shp);
22447 +               mutex_unlock(&shm_ids.mutex);
22448 +               return;
22449 +       }
22450 +#endif
22451         if(shp->shm_nattch == 0 &&
22452            shp->shm_perm.mode & SHM_DEST)
22453                 shm_destroy (shp);
22454 @@ -248,6 +268,9 @@ static int newseg (key_t key, int shmflg
22455         shp->shm_lprid = 0;
22456         shp->shm_atim = shp->shm_dtim = 0;
22457         shp->shm_ctim = get_seconds();
22458 +#ifdef CONFIG_GRKERNSEC
22459 +       shp->shm_createtime = get_seconds();
22460 +#endif
22461         shp->shm_segsz = size;
22462         shp->shm_nattch = 0;
22463         shp->id = shm_buildid(id,shp->shm_perm.seq);
22464 @@ -302,6 +325,8 @@ asmlinkage long sys_shmget (key_t key, s
22465         }
22466         mutex_unlock(&shm_ids.mutex);
22467  
22468 +       gr_log_shmget(err, shmflg, size);
22469 +
22470         return err;
22471  }
22472  
22473 @@ -615,6 +640,8 @@ asmlinkage long sys_shmctl (int shmid, i
22474                 if (err)
22475                         goto out_unlock_up;
22476  
22477 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
22478 +
22479                 if (shp->shm_nattch){
22480                         shp->shm_perm.mode |= SHM_DEST;
22481                         /* Do not find it any more */
22482 @@ -763,9 +790,27 @@ long do_shmat(int shmid, char __user *sh
22483                 return err;
22484         }
22485                 
22486 +#ifdef CONFIG_GRKERNSEC
22487 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
22488 +                            shp->shm_perm.cuid, shmid)) {
22489 +               shm_unlock(shp);
22490 +               return -EACCES;
22491 +       }
22492 +
22493 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
22494 +               shm_unlock(shp);
22495 +               return -EACCES;
22496 +       }
22497 +#endif
22498 +
22499         file = shp->shm_file;
22500         size = i_size_read(file->f_dentry->d_inode);
22501         shp->shm_nattch++;
22502 +
22503 +#ifdef CONFIG_GRKERNSEC
22504 +       shp->shm_lapid = current->pid;
22505 +#endif
22506 +
22507         shm_unlock(shp);
22508  
22509         down_write(&current->mm->mmap_sem);
22510 @@ -935,3 +980,24 @@ static int sysvipc_shm_proc_show(struct 
22511                           shp->shm_ctim);
22512  }
22513  #endif
22514 +
22515 +void gr_shm_exit(struct task_struct *task)
22516 +{
22517 +#ifdef CONFIG_GRKERNSEC_SHM
22518 +       int i;
22519 +       struct shmid_kernel *shp;
22520 +
22521 +       if (!grsec_enable_shm)
22522 +               return;
22523 +
22524 +       for (i = 0; i <= shm_ids.max_id; i++) {
22525 +               shp = shm_get(i);
22526 +               if (shp && (shp->shm_cprid == task->pid) &&
22527 +                   (shp->shm_nattch <= 0)) {
22528 +                       shp->shm_perm.mode |= SHM_DEST;
22529 +                       shm_destroy(shp);
22530 +               }
22531 +       }
22532 +#endif
22533 +       return;
22534 +}
22535 diff -urNp linux-2.6.17.11/kernel/capability.c linux-2.6.17.11/kernel/capability.c
22536 --- linux-2.6.17.11/kernel/capability.c 2006-08-07 00:18:54.000000000 -0400
22537 +++ linux-2.6.17.11/kernel/capability.c 2006-09-01 16:20:29.000000000 -0400
22538 @@ -13,6 +13,7 @@
22539  #include <linux/security.h>
22540  #include <linux/syscalls.h>
22541  #include <linux/vs_pid.h>
22542 +#include <linux/grsecurity.h>
22543  #include <asm/uaccess.h>
22544  
22545  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
22546 @@ -235,14 +236,25 @@ out:
22547       return ret;
22548  }
22549  
22550 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
22551 +extern int gr_is_capable_nolog(const int cap);
22552 +
22553  int __capable(struct task_struct *t, int cap)
22554  {
22555 -       if (security_capable(t, cap) == 0) {
22556 +       if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
22557                 t->flags |= PF_SUPERPRIV;
22558                 return 1;
22559         }
22560         return 0;
22561  }
22562 +int capable_nolog(int cap)
22563 +{
22564 +       if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
22565 +               current->flags |= PF_SUPERPRIV;
22566 +               return 1;
22567 +       }
22568 +       return 0;
22569 +}
22570  EXPORT_SYMBOL(__capable);
22571  
22572  int capable(int cap)
22573 @@ -253,3 +265,4 @@ int capable(int cap)
22574         return __capable(current, cap);
22575  }
22576  EXPORT_SYMBOL(capable);
22577 +EXPORT_SYMBOL(capable_nolog);
22578 diff -urNp linux-2.6.17.11/kernel/configs.c linux-2.6.17.11/kernel/configs.c
22579 --- linux-2.6.17.11/kernel/configs.c    2006-08-07 00:18:54.000000000 -0400
22580 +++ linux-2.6.17.11/kernel/configs.c    2006-09-01 16:20:29.000000000 -0400
22581 @@ -89,8 +89,16 @@ static int __init ikconfig_init(void)
22582         struct proc_dir_entry *entry;
22583  
22584         /* create the current config file */
22585 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
22586 +#ifdef CONFIG_GRKERNSEC_PROC_USER
22587 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
22588 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22589 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
22590 +#endif
22591 +#else
22592         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
22593                                   &proc_root);
22594 +#endif
22595         if (!entry)
22596                 return -ENOMEM;
22597  
22598 diff -urNp linux-2.6.17.11/kernel/exit.c linux-2.6.17.11/kernel/exit.c
22599 --- linux-2.6.17.11/kernel/exit.c       2006-08-07 00:18:54.000000000 -0400
22600 +++ linux-2.6.17.11/kernel/exit.c       2006-09-01 16:20:29.000000000 -0400
22601 @@ -40,6 +40,11 @@
22602  #include <linux/vs_context.h>
22603  #include <linux/vs_network.h>
22604  #include <linux/vs_pid.h>
22605 +#include <linux/grsecurity.h>
22606 +
22607 +#ifdef CONFIG_GRKERNSEC
22608 +extern rwlock_t grsec_exec_file_lock;
22609 +#endif
22610  
22611  #include <asm/uaccess.h>
22612  #include <asm/unistd.h>
22613 @@ -119,6 +124,7 @@ static void __exit_signal(struct task_st
22614  
22615         __unhash_process(tsk);
22616  
22617 +       gr_del_task_from_ip_table(tsk);
22618         tsk->signal = NULL;
22619         tsk->sighand = NULL;
22620         spin_unlock(&sighand->siglock);
22621 @@ -291,6 +297,15 @@ static void reparent_to_init(void)
22622  {
22623         write_lock_irq(&tasklist_lock);
22624  
22625 +#ifdef CONFIG_GRKERNSEC
22626 +       write_lock(&grsec_exec_file_lock);
22627 +       if (current->exec_file) {
22628 +               fput(current->exec_file);
22629 +               current->exec_file = NULL;
22630 +       }
22631 +       write_unlock(&grsec_exec_file_lock);
22632 +#endif
22633 +
22634         ptrace_unlink(current);
22635         /* Reparent to init */
22636         remove_parent(current);
22637 @@ -298,6 +313,8 @@ static void reparent_to_init(void)
22638         current->real_parent = child_reaper;
22639         add_parent(current);
22640  
22641 +       gr_set_kernel_label(current);
22642 +
22643         /* Set the exit signal to SIGCHLD so we signal init on exit */
22644         current->exit_signal = SIGCHLD;
22645  
22646 @@ -394,6 +411,17 @@ void daemonize(const char *name, ...)
22647         vsnprintf(current->comm, sizeof(current->comm), name, args);
22648         va_end(args);
22649  
22650 +#ifdef CONFIG_GRKERNSEC
22651 +       write_lock(&grsec_exec_file_lock);
22652 +       if (current->exec_file) {
22653 +               fput(current->exec_file);
22654 +               current->exec_file = NULL;
22655 +       }
22656 +       write_unlock(&grsec_exec_file_lock);
22657 +#endif
22658 +
22659 +       gr_set_kernel_label(current);
22660 +
22661         /*
22662          * If we were started as result of loading a module, close all of the
22663          * user space pages.  We don't need them, and if we didn't close them
22664 @@ -915,9 +943,14 @@ fastcall NORET_TYPE void do_exit(long co
22665  #endif
22666         if (unlikely(tsk->audit_context))
22667                 audit_free(tsk);
22668 +
22669 +       gr_acl_handle_psacct(tsk, code);
22670 +       gr_acl_handle_exit();
22671 +
22672         exit_mm(tsk);
22673  
22674         exit_sem(tsk);
22675 +       gr_shm_exit(tsk);
22676         __exit_files(tsk);
22677         __exit_fs(tsk);
22678         exit_namespace(tsk);
22679 diff -urNp linux-2.6.17.11/kernel/fork.c linux-2.6.17.11/kernel/fork.c
22680 --- linux-2.6.17.11/kernel/fork.c       2006-08-07 00:18:54.000000000 -0400
22681 +++ linux-2.6.17.11/kernel/fork.c       2006-09-01 16:20:29.000000000 -0400
22682 @@ -48,6 +48,7 @@
22683  #include <linux/vs_network.h>
22684  #include <linux/vs_limit.h>
22685  #include <linux/vs_memory.h>
22686 +#include <linux/grsecurity.h>
22687  
22688  #include <asm/pgtable.h>
22689  #include <asm/pgalloc.h>
22690 @@ -204,8 +205,8 @@ static inline int dup_mmap(struct mm_str
22691         mm->locked_vm = 0;
22692         mm->mmap = NULL;
22693         mm->mmap_cache = NULL;
22694 -       mm->free_area_cache = oldmm->mmap_base;
22695 -       mm->cached_hole_size = ~0UL;
22696 +       mm->free_area_cache = oldmm->free_area_cache;
22697 +       mm->cached_hole_size = oldmm->cached_hole_size;
22698         mm->map_count = 0;
22699         __set_mm_counter(mm, file_rss, 0);
22700         __set_mm_counter(mm, anon_rss, 0);
22701 @@ -330,7 +331,7 @@ static struct mm_struct * mm_init(struct
22702         spin_lock_init(&mm->page_table_lock);
22703         rwlock_init(&mm->ioctx_list_lock);
22704         mm->ioctx_list = NULL;
22705 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
22706 +       mm->free_area_cache = ~0UL;
22707         mm->cached_hole_size = ~0UL;
22708  
22709         if (likely(!mm_alloc_pgd(mm))) {
22710 @@ -988,6 +989,8 @@ static task_t *copy_process(unsigned lon
22711         if (!vx_nproc_avail(1))
22712                 goto bad_fork_cleanup_vm;
22713  
22714 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
22715 +
22716         if (atomic_read(&p->user->processes) >=
22717                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
22718                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
22719 @@ -1098,6 +1101,8 @@ static task_t *copy_process(unsigned lon
22720         if (retval)
22721                 goto bad_fork_cleanup_namespace;
22722  
22723 +       gr_copy_label(p);
22724 +
22725         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
22726         /*
22727          * Clear TID on mm_release()?
22728 @@ -1302,6 +1307,8 @@ bad_fork_cleanup_count:
22729  bad_fork_free:
22730         free_task(p);
22731  fork_out:
22732 +       gr_log_forkfail(retval);
22733 +
22734         return ERR_PTR(retval);
22735  }
22736  
22737 @@ -1384,6 +1391,8 @@ long do_fork(unsigned long clone_flags,
22738         if (!IS_ERR(p)) {
22739                 struct completion vfork;
22740  
22741 +               gr_handle_brute_check();
22742 +
22743                 if (clone_flags & CLONE_VFORK) {
22744                         p->vfork_done = &vfork;
22745                         init_completion(&vfork);
22746 diff -urNp linux-2.6.17.11/kernel/futex.c linux-2.6.17.11/kernel/futex.c
22747 --- linux-2.6.17.11/kernel/futex.c      2006-08-07 00:18:54.000000000 -0400
22748 +++ linux-2.6.17.11/kernel/futex.c      2006-09-01 16:20:29.000000000 -0400
22749 @@ -152,6 +152,11 @@ static int get_futex_key(unsigned long u
22750         struct page *page;
22751         int err;
22752  
22753 +#ifdef CONFIG_PAX_SEGMEXEC
22754 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (uaddr >= SEGMEXEC_TASK_SIZE))
22755 +               return -EFAULT;
22756 +#endif
22757 +
22758         /*
22759          * The futex address must be "naturally" aligned.
22760          */
22761 diff -urNp linux-2.6.17.11/kernel/kallsyms.c linux-2.6.17.11/kernel/kallsyms.c
22762 --- linux-2.6.17.11/kernel/kallsyms.c   2006-08-07 00:18:54.000000000 -0400
22763 +++ linux-2.6.17.11/kernel/kallsyms.c   2006-09-01 16:20:29.000000000 -0400
22764 @@ -301,7 +301,6 @@ static unsigned long get_ksymbol_core(st
22765  
22766  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
22767  {
22768 -       iter->name[0] = '\0';
22769         iter->nameoff = get_symbol_offset(new_pos);
22770         iter->pos = new_pos;
22771  }
22772 @@ -380,7 +379,7 @@ static int kallsyms_open(struct inode *i
22773         struct kallsym_iter *iter;
22774         int ret;
22775  
22776 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
22777 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
22778         if (!iter)
22779                 return -ENOMEM;
22780         reset_iter(iter, 0);
22781 @@ -411,7 +410,15 @@ static int __init kallsyms_init(void)
22782  {
22783         struct proc_dir_entry *entry;
22784  
22785 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
22786 +#ifdef CONFIG_GRKERNSEC_PROC_USER
22787 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
22788 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22789 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
22790 +#endif
22791 +#else
22792         entry = create_proc_entry("kallsyms", 0444, NULL);
22793 +#endif
22794         if (entry)
22795                 entry->proc_fops = &kallsyms_operations;
22796         return 0;
22797 diff -urNp linux-2.6.17.11/kernel/kprobes.c linux-2.6.17.11/kernel/kprobes.c
22798 --- linux-2.6.17.11/kernel/kprobes.c    2006-08-07 00:18:54.000000000 -0400
22799 +++ linux-2.6.17.11/kernel/kprobes.c    2006-09-01 16:20:29.000000000 -0400
22800 @@ -106,7 +106,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
22801          * kernel image and loaded module images reside. This is required
22802          * so x86_64 can correctly handle the %rip-relative fixups.
22803          */
22804 -       kip->insns = module_alloc(PAGE_SIZE);
22805 +       kip->insns = module_alloc_exec(PAGE_SIZE);
22806         if (!kip->insns) {
22807                 kfree(kip);
22808                 return NULL;
22809 diff -urNp linux-2.6.17.11/kernel/module.c linux-2.6.17.11/kernel/module.c
22810 --- linux-2.6.17.11/kernel/module.c     2006-08-07 00:18:54.000000000 -0400
22811 +++ linux-2.6.17.11/kernel/module.c     2006-09-01 16:20:29.000000000 -0400
22812 @@ -40,10 +40,15 @@
22813  #include <linux/string.h>
22814  #include <linux/sched.h>
22815  #include <linux/mutex.h>
22816 +#include <linux/kallsyms.h>
22817  #include <asm/uaccess.h>
22818  #include <asm/semaphore.h>
22819  #include <asm/cacheflush.h>
22820  
22821 +#ifdef CONFIG_PAX_KERNEXEC
22822 +#include <asm/desc.h>
22823 +#endif
22824 +
22825  #if 0
22826  #define DEBUGP printk
22827  #else
22828 @@ -66,6 +71,8 @@ static LIST_HEAD(modules);
22829  
22830  static BLOCKING_NOTIFIER_HEAD(module_notify_list);
22831  
22832 +extern int gr_check_modstop(void);
22833 +
22834  int register_module_notifier(struct notifier_block * nb)
22835  {
22836         return blocking_notifier_chain_register(&module_notify_list, nb);
22837 @@ -594,6 +601,9 @@ sys_delete_module(const char __user *nam
22838         char name[MODULE_NAME_LEN];
22839         int ret, forced = 0;
22840  
22841 +       if (gr_check_modstop())
22842 +               return -EPERM;
22843 +
22844         if (!capable(CAP_SYS_MODULE))
22845                 return -EPERM;
22846  
22847 @@ -1058,13 +1068,15 @@ static void free_module(struct module *m
22848         module_unload_free(mod);
22849  
22850         /* This may be NULL, but that's OK */
22851 -       module_free(mod, mod->module_init);
22852 +       module_free(mod, mod->module_init_rw);
22853 +       module_free_exec(mod, mod->module_init_rx);
22854         kfree(mod->args);
22855         if (mod->percpu)
22856                 percpu_modfree(mod->percpu);
22857  
22858         /* Finally, free the core (containing the module structure) */
22859 -       module_free(mod, mod->module_core);
22860 +       module_free_exec(mod, mod->module_core_rx);
22861 +       module_free(mod, mod->module_core_rw);
22862  }
22863  
22864  void *__symbol_get(const char *symbol)
22865 @@ -1221,11 +1233,14 @@ static void layout_sections(struct modul
22866                             || strncmp(secstrings + s->sh_name,
22867                                        ".init", 5) == 0)
22868                                 continue;
22869 -                       s->sh_entsize = get_offset(&mod->core_size, s);
22870 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
22871 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
22872 +                       else
22873 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
22874                         DEBUGP("\t%s\n", secstrings + s->sh_name);
22875                 }
22876                 if (m == 0)
22877 -                       mod->core_text_size = mod->core_size;
22878 +                       mod->core_size_rx = mod->core_size_rx;
22879         }
22880  
22881         DEBUGP("Init section allocation order:\n");
22882 @@ -1239,12 +1254,15 @@ static void layout_sections(struct modul
22883                             || strncmp(secstrings + s->sh_name,
22884                                        ".init", 5) != 0)
22885                                 continue;
22886 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
22887 -                                        | INIT_OFFSET_MASK);
22888 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
22889 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
22890 +                       else
22891 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
22892 +                       s->sh_entsize |= INIT_OFFSET_MASK;
22893                         DEBUGP("\t%s\n", secstrings + s->sh_name);
22894                 }
22895                 if (m == 0)
22896 -                       mod->init_text_size = mod->init_size;
22897 +                       mod->init_size_rx = mod->init_size_rx;
22898         }
22899  }
22900  
22901 @@ -1419,6 +1437,10 @@ static struct module *load_module(void _
22902         struct exception_table_entry *extable;
22903         mm_segment_t old_fs;
22904  
22905 +#ifdef CONFIG_PAX_KERNEXEC
22906 +       unsigned long cr0;
22907 +#endif
22908 +
22909         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
22910                umod, len, uargs);
22911         if (len < sizeof(*hdr))
22912 @@ -1568,21 +1590,57 @@ static struct module *load_module(void _
22913         layout_sections(mod, hdr, sechdrs, secstrings);
22914  
22915         /* Do the allocs. */
22916 -       ptr = module_alloc(mod->core_size);
22917 +       ptr = module_alloc(mod->core_size_rw);
22918         if (!ptr) {
22919                 err = -ENOMEM;
22920                 goto free_percpu;
22921         }
22922 -       memset(ptr, 0, mod->core_size);
22923 -       mod->module_core = ptr;
22924 +       memset(ptr, 0, mod->core_size_rw);
22925 +       mod->module_core_rw = ptr;
22926  
22927 -       ptr = module_alloc(mod->init_size);
22928 -       if (!ptr && mod->init_size) {
22929 +       ptr = module_alloc(mod->init_size_rw);
22930 +       if (!ptr && mod->init_size_rw) {
22931                 err = -ENOMEM;
22932 -               goto free_core;
22933 +               goto free_core_rw;
22934         }
22935 -       memset(ptr, 0, mod->init_size);
22936 -       mod->module_init = ptr;
22937 +       memset(ptr, 0, mod->init_size_rw);
22938 +       mod->module_init_rw = ptr;
22939 +
22940 +       ptr = module_alloc_exec(mod->core_size_rx);
22941 +       if (!ptr) {
22942 +               err = -ENOMEM;
22943 +               goto free_init_rw;
22944 +       }
22945 +
22946 +#ifdef CONFIG_PAX_KERNEXEC
22947 +       pax_open_kernel(cr0);
22948 +#endif
22949 +
22950 +       memset(ptr, 0, mod->core_size_rx);
22951 +
22952 +#ifdef CONFIG_PAX_KERNEXEC
22953 +       pax_close_kernel(cr0);
22954 +#endif
22955 +
22956 +       mod->module_core_rx = ptr;
22957 +
22958 +       ptr = module_alloc_exec(mod->init_size_rx);
22959 +       if (!ptr && mod->init_size_rx) {
22960 +               err = -ENOMEM;
22961 +               goto free_core_rx;
22962 +       }
22963 +
22964 +#ifdef CONFIG_PAX_KERNEXEC
22965 +       pax_open_kernel(cr0);
22966 +#endif
22967 +
22968 +       memset(ptr, 0, mod->init_size_rx);
22969 +
22970 +#ifdef CONFIG_PAX_KERNEXEC
22971 +       pax_close_kernel(cr0);
22972 +#endif
22973 +
22974 +       mod->module_init_rx = ptr;
22975  
22976         /* Transfer each section which specifies SHF_ALLOC */
22977         DEBUGP("final section addresses:\n");
22978 @@ -1592,17 +1650,44 @@ static struct module *load_module(void _
22979                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
22980                         continue;
22981  
22982 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
22983 -                       dest = mod->module_init
22984 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22985 -               else
22986 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
22987 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
22988 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
22989 +                               dest = mod->module_init_rw
22990 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22991 +                       else
22992 +                               dest = mod->module_init_rx
22993 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22994 +               } else {
22995 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
22996 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
22997 +                       else
22998 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
22999 +               }
23000 +
23001 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
23002  
23003 -               if (sechdrs[i].sh_type != SHT_NOBITS)
23004 -                       memcpy(dest, (void *)sechdrs[i].sh_addr,
23005 -                              sechdrs[i].sh_size);
23006 +#ifdef CONFIG_PAX_KERNEXEC
23007 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
23008 +                               pax_open_kernel(cr0);
23009 +#endif
23010 +
23011 +                       memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
23012 +
23013 +#ifdef CONFIG_PAX_KERNEXEC
23014 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
23015 +                               pax_close_kernel(cr0);
23016 +#endif
23017 +
23018 +               }
23019                 /* Update sh_addr to point to copy in image. */
23020 -               sechdrs[i].sh_addr = (unsigned long)dest;
23021 +
23022 +#ifdef CONFIG_PAX_KERNEXEC
23023 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
23024 +                       sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
23025 +               else
23026 +#endif
23027 +
23028 +                       sechdrs[i].sh_addr = (unsigned long)dest;
23029                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
23030         }
23031         /* Module has been moved. */
23032 @@ -1623,8 +1708,18 @@ static struct module *load_module(void _
23033         setup_modinfo(mod, sechdrs, infoindex);
23034  
23035         /* Fix up syms, so that st_value is a pointer to location. */
23036 +
23037 +#ifdef CONFIG_PAX_KERNEXEC
23038 +       pax_open_kernel(cr0);
23039 +#endif
23040 +
23041         err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
23042                                mod);
23043 +
23044 +#ifdef CONFIG_PAX_KERNEXEC
23045 +       pax_close_kernel(cr0);
23046 +#endif
23047 +
23048         if (err < 0)
23049                 goto cleanup;
23050  
23051 @@ -1666,11 +1761,20 @@ static struct module *load_module(void _
23052                 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
23053                         continue;
23054  
23055 +#ifdef CONFIG_PAX_KERNEXEC
23056 +       pax_open_kernel(cr0);
23057 +#endif
23058 +
23059                 if (sechdrs[i].sh_type == SHT_REL)
23060                         err = apply_relocate(sechdrs, strtab, symindex, i,mod);
23061                 else if (sechdrs[i].sh_type == SHT_RELA)
23062                         err = apply_relocate_add(sechdrs, strtab, symindex, i,
23063                                                  mod);
23064 +
23065 +#ifdef CONFIG_PAX_KERNEXEC
23066 +       pax_close_kernel(cr0);
23067 +#endif
23068 +
23069                 if (err < 0)
23070                         goto cleanup;
23071         }
23072 @@ -1684,14 +1788,31 @@ static struct module *load_module(void _
23073         /* Set up and sort exception table */
23074         mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
23075         mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
23076 +
23077 +#ifdef CONFIG_PAX_KERNEXEC
23078 +       pax_open_kernel(cr0);
23079 +#endif
23080 +
23081         sort_extable(extable, extable + mod->num_exentries);
23082  
23083 +#ifdef CONFIG_PAX_KERNEXEC
23084 +       pax_close_kernel(cr0);
23085 +#endif
23086 +
23087         /* Finally, copy percpu area over. */
23088         percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
23089                        sechdrs[pcpuindex].sh_size);
23090  
23091 +#ifdef CONFIG_PAX_KERNEXEC
23092 +       pax_open_kernel(cr0);
23093 +#endif
23094 +
23095         add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
23096  
23097 +#ifdef CONFIG_PAX_KERNEXEC
23098 +       pax_close_kernel(cr0);
23099 +#endif
23100 +
23101         err = module_finalize(hdr, sechdrs, mod);
23102         if (err < 0)
23103                 goto cleanup;
23104 @@ -1705,12 +1826,12 @@ static struct module *load_module(void _
23105          * Do it before processing of module parameters, so the module
23106          * can provide parameter accessor functions of its own.
23107          */
23108 -       if (mod->module_init)
23109 -               flush_icache_range((unsigned long)mod->module_init,
23110 -                                  (unsigned long)mod->module_init
23111 -                                  + mod->init_size);
23112 -       flush_icache_range((unsigned long)mod->module_core,
23113 -                          (unsigned long)mod->module_core + mod->core_size);
23114 +       if (mod->module_init_rx)
23115 +               flush_icache_range((unsigned long)mod->module_init_rx,
23116 +                                  (unsigned long)mod->module_init_rx
23117 +                                  + mod->init_size_rx);
23118 +       flush_icache_range((unsigned long)mod->module_core_rx,
23119 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
23120  
23121         set_fs(old_fs);
23122  
23123 @@ -1748,9 +1869,13 @@ static struct module *load_module(void _
23124         module_arch_cleanup(mod);
23125   cleanup:
23126         module_unload_free(mod);
23127 -       module_free(mod, mod->module_init);
23128 - free_core:
23129 -       module_free(mod, mod->module_core);
23130 +       module_free_exec(mod, mod->module_init_rx);
23131 + free_core_rx:
23132 +       module_free_exec(mod, mod->module_core_rx);
23133 + free_init_rw:
23134 +       module_free(mod, mod->module_init_rw);
23135 + free_core_rw:
23136 +       module_free(mod, mod->module_core_rw);
23137   free_percpu:
23138         if (percpu)
23139                 percpu_modfree(percpu);
23140 @@ -1786,6 +1911,9 @@ sys_init_module(void __user *umod,
23141         struct module *mod;
23142         int ret = 0;
23143  
23144 +       if (gr_check_modstop())
23145 +               return -EPERM;
23146 +
23147         /* Must have permission */
23148         if (!capable(CAP_SYS_MODULE))
23149                 return -EPERM;
23150 @@ -1836,10 +1964,12 @@ sys_init_module(void __user *umod,
23151         mod->state = MODULE_STATE_LIVE;
23152         /* Drop initial reference. */
23153         module_put(mod);
23154 -       module_free(mod, mod->module_init);
23155 -       mod->module_init = NULL;
23156 -       mod->init_size = 0;
23157 -       mod->init_text_size = 0;
23158 +       module_free(mod, mod->module_init_rw);
23159 +       module_free_exec(mod, mod->module_init_rx);
23160 +       mod->module_init_rw = NULL;
23161 +       mod->module_init_rx = NULL;
23162 +       mod->init_size_rw = 0;
23163 +       mod->init_size_rx = 0;
23164         mutex_unlock(&module_mutex);
23165  
23166         return 0;
23167 @@ -1870,10 +2000,14 @@ static const char *get_ksymbol(struct mo
23168         unsigned long nextval;
23169  
23170         /* At worse, next value is at end of module */
23171 -       if (within(addr, mod->module_init, mod->init_size))
23172 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
23173 -       else 
23174 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
23175 +       if (within(addr, mod->module_init_rx, mod->init_size_rx))
23176 +               nextval = (unsigned long)mod->module_init_rw;
23177 +       else if (within(addr, mod->module_init_rw, mod->init_size_rw))
23178 +               nextval = (unsigned long)mod->module_core_rx;
23179 +       else if (within(addr, mod->module_core_rx, mod->core_size_rx))
23180 +               nextval = (unsigned long)mod->module_core_rw;
23181 +       else
23182 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
23183  
23184         /* Scan for closest preceeding symbol, and next symbol. (ELF
23185             starts real symbols at 1). */
23186 @@ -1914,8 +2048,10 @@ const char *module_address_lookup(unsign
23187         struct module *mod;
23188  
23189         list_for_each_entry(mod, &modules, list) {
23190 -               if (within(addr, mod->module_init, mod->init_size)
23191 -                   || within(addr, mod->module_core, mod->core_size)) {
23192 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
23193 +                   || within(addr, mod->module_init_rw, mod->init_size_rw)
23194 +                   || within(addr, mod->module_core_rx, mod->core_size_rx)
23195 +                   || within(addr, mod->module_core_rw, mod->core_size_rw)) {
23196                         *modname = mod->name;
23197                         return get_ksymbol(mod, addr, size, offset);
23198                 }
23199 @@ -1926,7 +2062,7 @@ const char *module_address_lookup(unsign
23200  struct module *module_get_kallsym(unsigned int symnum,
23201                                   unsigned long *value,
23202                                   char *type,
23203 -                                 char namebuf[128])
23204 +                                 char namebuf[KSYM_NAME_LEN+1])
23205  {
23206         struct module *mod;
23207  
23208 @@ -1937,7 +2073,7 @@ struct module *module_get_kallsym(unsign
23209                         *type = mod->symtab[symnum].st_info;
23210                         strncpy(namebuf,
23211                                 mod->strtab + mod->symtab[symnum].st_name,
23212 -                               127);
23213 +                               KSYM_NAME_LEN);
23214                         mutex_unlock(&module_mutex);
23215                         return mod;
23216                 }
23217 @@ -2014,7 +2150,7 @@ static int m_show(struct seq_file *m, vo
23218  {
23219         struct module *mod = list_entry(p, struct module, list);
23220         seq_printf(m, "%s %lu",
23221 -                  mod->name, mod->init_size + mod->core_size);
23222 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
23223         print_unload_info(m, mod);
23224  
23225         /* Informative for users. */
23226 @@ -2023,7 +2159,7 @@ static int m_show(struct seq_file *m, vo
23227                    mod->state == MODULE_STATE_COMING ? "Loading":
23228                    "Live");
23229         /* Used by oprofile and other similar tools. */
23230 -       seq_printf(m, " 0x%p", mod->module_core);
23231 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
23232  
23233         seq_printf(m, "\n");
23234         return 0;
23235 @@ -2072,8 +2208,8 @@ struct module *__module_text_address(uns
23236         struct module *mod;
23237  
23238         list_for_each_entry(mod, &modules, list)
23239 -               if (within(addr, mod->module_init, mod->init_text_size)
23240 -                   || within(addr, mod->module_core, mod->core_text_size))
23241 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
23242 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
23243                         return mod;
23244         return NULL;
23245  }
23246 diff -urNp linux-2.6.17.11/kernel/pid.c linux-2.6.17.11/kernel/pid.c
23247 --- linux-2.6.17.11/kernel/pid.c        2006-08-07 00:18:54.000000000 -0400
23248 +++ linux-2.6.17.11/kernel/pid.c        2006-09-01 16:20:29.000000000 -0400
23249 @@ -26,6 +26,7 @@
23250  #include <linux/init.h>
23251  #include <linux/bootmem.h>
23252  #include <linux/hash.h>
23253 +#include <linux/grsecurity.h>
23254  
23255  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
23256  static struct hlist_head *pid_hash;
23257 @@ -90,7 +91,9 @@ static int alloc_pidmap(void)
23258         int i, offset, max_scan, pid, last = last_pid;
23259         pidmap_t *map;
23260  
23261 -       pid = last + 1;
23262 +       pid = gr_random_pid();
23263 +       if (!pid)
23264 +               pid = last_pid + 1;
23265         if (pid >= pid_max)
23266                 pid = RESERVED_PIDS;
23267         offset = pid & BITS_PER_PAGE_MASK;
23268 @@ -269,7 +272,14 @@ struct task_struct * fastcall pid_task(s
23269   */
23270  task_t *find_task_by_pid_type(int type, int nr)
23271  {
23272 -       return pid_task(find_pid(nr), type);
23273 +       task_t *task;
23274 +       
23275 +       task = pid_task(find_pid(nr), type);
23276 +
23277 +       if (gr_pid_is_chrooted(task))
23278 +               return NULL;
23279 +
23280 +       return task;
23281  }
23282  
23283  EXPORT_SYMBOL(find_task_by_pid_type);
23284 diff -urNp linux-2.6.17.11/kernel/posix-cpu-timers.c linux-2.6.17.11/kernel/posix-cpu-timers.c
23285 --- linux-2.6.17.11/kernel/posix-cpu-timers.c   2006-08-07 00:18:54.000000000 -0400
23286 +++ linux-2.6.17.11/kernel/posix-cpu-timers.c   2006-09-01 16:20:29.000000000 -0400
23287 @@ -7,6 +7,7 @@
23288  #include <asm/uaccess.h>
23289  #include <linux/errno.h>
23290  #include <linux/vs_pid.h>
23291 +#include <linux/grsecurity.h>
23292  
23293  static int check_clock(const clockid_t which_clock)
23294  {
23295 @@ -1126,6 +1127,7 @@ static void check_process_timers(struct 
23296                         __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
23297                         return;
23298                 }
23299 +               gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
23300                 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
23301                         /*
23302                          * At the soft limit, send a SIGXCPU every second.
23303 diff -urNp linux-2.6.17.11/kernel/printk.c linux-2.6.17.11/kernel/printk.c
23304 --- linux-2.6.17.11/kernel/printk.c     2006-08-07 00:18:54.000000000 -0400
23305 +++ linux-2.6.17.11/kernel/printk.c     2006-09-01 16:20:29.000000000 -0400
23306 @@ -33,6 +33,7 @@
23307  #include <linux/syscalls.h>
23308  #include <linux/vs_context.h>
23309  #include <linux/vserver/cvirt.h>
23310 +#include <linux/grsecurity.h>
23311  
23312  #include <asm/uaccess.h>
23313  
23314 @@ -187,6 +188,11 @@ int do_syslog(int type, char __user *buf
23315         char c;
23316         int error;
23317  
23318 +#ifdef CONFIG_GRKERNSEC_DMESG
23319 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
23320 +               return -EPERM;
23321 +#endif
23322 +
23323         error = security_syslog(type);
23324         if (error)
23325                 return error;
23326 diff -urNp linux-2.6.17.11/kernel/ptrace.c linux-2.6.17.11/kernel/ptrace.c
23327 --- linux-2.6.17.11/kernel/ptrace.c     2006-08-07 00:18:54.000000000 -0400
23328 +++ linux-2.6.17.11/kernel/ptrace.c     2006-09-01 16:20:29.000000000 -0400
23329 @@ -19,6 +19,7 @@
23330  #include <linux/security.h>
23331  #include <linux/signal.h>
23332  #include <linux/vs_pid.h>
23333 +#include <linux/grsecurity.h>
23334  
23335  #include <asm/pgtable.h>
23336  #include <asm/uaccess.h>
23337 @@ -128,10 +129,10 @@ static int may_attach(struct task_struct
23338              (current->uid != task->uid) ||
23339              (current->gid != task->egid) ||
23340              (current->gid != task->sgid) ||
23341 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
23342 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
23343                 return -EPERM;
23344         smp_rmb();
23345 -       if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
23346 +       if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
23347                 return -EPERM;
23348         if (!vx_check(task->xid, VX_ADMIN_P|VX_IDENT))
23349                 return -EPERM;
23350 @@ -525,6 +526,11 @@ asmlinkage long sys_ptrace(long request,
23351         if (ret < 0)
23352                 goto out_put_task_struct;
23353  
23354 +       if (gr_handle_ptrace(child, request)) {
23355 +               ret = -EPERM;
23356 +               goto out_put_task_struct;
23357 +       }
23358 +
23359         ret = arch_ptrace(child, request, addr, data);
23360         if (ret < 0)
23361                 goto out_put_task_struct;
23362 diff -urNp linux-2.6.17.11/kernel/resource.c linux-2.6.17.11/kernel/resource.c
23363 --- linux-2.6.17.11/kernel/resource.c   2006-08-07 00:18:54.000000000 -0400
23364 +++ linux-2.6.17.11/kernel/resource.c   2006-09-01 16:20:29.000000000 -0400
23365 @@ -136,10 +136,27 @@ static int __init ioresources_init(void)
23366  {
23367         struct proc_dir_entry *entry;
23368  
23369 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
23370 +#ifdef CONFIG_GRKERNSEC_PROC_USER
23371 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
23372 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
23373 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
23374 +#endif
23375 +#else
23376         entry = create_proc_entry("ioports", 0, NULL);
23377 +#endif
23378         if (entry)
23379                 entry->proc_fops = &proc_ioports_operations;
23380 +
23381 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
23382 +#ifdef CONFIG_GRKERNSEC_PROC_USER
23383 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
23384 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
23385 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
23386 +#endif
23387 +#else
23388         entry = create_proc_entry("iomem", 0, NULL);
23389 +#endif
23390         if (entry)
23391                 entry->proc_fops = &proc_iomem_operations;
23392         return 0;
23393 diff -urNp linux-2.6.17.11/kernel/sched.c linux-2.6.17.11/kernel/sched.c
23394 --- linux-2.6.17.11/kernel/sched.c      2006-08-07 00:18:54.000000000 -0400
23395 +++ linux-2.6.17.11/kernel/sched.c      2006-09-01 16:20:29.000000000 -0400
23396 @@ -50,6 +50,7 @@
23397  #include <linux/times.h>
23398  #include <linux/acct.h>
23399  #include <linux/kprobes.h>
23400 +#include <linux/grsecurity.h>
23401  #include <asm/tlb.h>
23402  
23403  #include <asm/unistd.h>
23404 @@ -3636,7 +3637,8 @@ asmlinkage long sys_nice(int increment)
23405         if (nice > 19)
23406                 nice = 19;
23407  
23408 -       if (increment < 0 && !can_nice(current, nice))
23409 +       if (increment < 0 && (!can_nice(current, nice) ||
23410 +                             gr_handle_chroot_nice()))
23411                 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
23412  
23413         retval = security_task_setnice(current, nice);
23414 diff -urNp linux-2.6.17.11/kernel/signal.c linux-2.6.17.11/kernel/signal.c
23415 --- linux-2.6.17.11/kernel/signal.c     2006-08-07 00:18:54.000000000 -0400
23416 +++ linux-2.6.17.11/kernel/signal.c     2006-09-01 16:20:29.000000000 -0400
23417 @@ -26,6 +26,7 @@
23418  #include <linux/audit.h>
23419  #include <linux/capability.h>
23420  #include <linux/vs_pid.h>
23421 +#include <linux/grsecurity.h>
23422  #include <asm/param.h>
23423  #include <asm/uaccess.h>
23424  #include <asm/unistd.h>
23425 @@ -583,11 +583,11 @@ static int check_kill_permission(int sig
23426                 (!is_si_special(info) && SI_FROMUSER(info)));
23427  
23428         error = -EPERM;
23429 -       if (user && ((sig != SIGCONT) ||
23430 +       if (user && ((((sig != SIGCONT) ||
23431                 (current->signal->session != t->signal->session))
23432             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
23433             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
23434 -           && !capable(CAP_KILL))
23435 +           && !capable(CAP_KILL)) || gr_handle_signal(t, sig)))
23436                 return error;
23437  
23438         error = -ESRCH;
23439 @@ -595,8 +595,10 @@ static int check_kill_permission(int sig
23440                 return error;
23441  
23442         error = security_task_kill(t, info, sig);
23443 -       if (!error)
23444 +       if (!error) {
23445                 audit_signal_info(sig, t); /* Let audit system see the signal */
23446 +               gr_log_signal(sig, t);
23447 +       }
23448         return error;
23449  }
23450  
23451 @@ -774,7 +777,7 @@ out_set:
23452         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
23453  
23454  
23455 -static int
23456 +int
23457  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
23458  {
23459         int ret = 0;
23460 @@ -819,6 +822,10 @@ force_sig_info(int sig, struct siginfo *
23461         }
23462         recalc_sigpending_tsk(t);
23463         ret = specific_send_sig_info(sig, info, t);
23464 +
23465 +       gr_log_signal(sig, t);
23466 +       gr_handle_crash(t, sig);
23467 +
23468         spin_unlock_irqrestore(&t->sighand->siglock, flags);
23469  
23470         return ret;
23471 diff -urNp linux-2.6.17.11/kernel/sys.c linux-2.6.17.11/kernel/sys.c
23472 --- linux-2.6.17.11/kernel/sys.c        2006-08-07 00:18:54.000000000 -0400
23473 +++ linux-2.6.17.11/kernel/sys.c        2006-09-01 16:20:29.000000000 -0400
23474 @@ -33,6 +33,7 @@
23475  #include <linux/cn_proc.h>
23476  #include <linux/vs_cvirt.h>
23477  #include <linux/vs_pid.h>
23478 +#include <linux/grsecurity.h>
23479  
23480  #include <linux/compat.h>
23481  #include <linux/syscalls.h>
23482 @@ -448,6 +449,12 @@ static int set_one_prio(struct task_stru
23483                         error = -EACCES;
23484                 goto out;
23485         }
23486 +
23487 +       if (gr_handle_chroot_setpriority(p, niceval)) {
23488 +               error = -EACCES;
23489 +               goto out;
23490 +       }
23491 +
23492         no_nice = security_task_setnice(p, niceval);
23493         if (no_nice) {
23494                 error = no_nice;
23495 @@ -845,6 +852,9 @@ asmlinkage long sys_setregid(gid_t rgid,
23496         if (rgid != (gid_t) -1 ||
23497             (egid != (gid_t) -1 && egid != old_rgid))
23498                 current->sgid = new_egid;
23499 +
23500 +       gr_set_role_label(current, current->uid, new_rgid);
23501 +
23502         current->fsgid = new_egid;
23503         current->egid = new_egid;
23504         current->gid = new_rgid;
23505 @@ -874,6 +884,9 @@ asmlinkage long sys_setgid(gid_t gid)
23506                         current->mm->dumpable = suid_dumpable;
23507                         smp_wmb();
23508                 }
23509 +
23510 +               gr_set_role_label(current, current->uid, gid);
23511 +
23512                 current->gid = current->egid = current->sgid = current->fsgid = gid;
23513         }
23514         else if ((gid == current->gid) || (gid == current->sgid))
23515 @@ -915,6 +928,9 @@ static int set_user(uid_t new_ruid, int 
23516                 current->mm->dumpable = suid_dumpable;
23517                 smp_wmb();
23518         }
23519 +
23520 +       gr_set_role_label(current, new_ruid, current->gid);
23521 +
23522         current->uid = new_ruid;
23523         return 0;
23524  }
23525 @@ -1018,6 +1034,9 @@ asmlinkage long sys_setuid(uid_t uid)
23526         } else if ((uid != current->uid) && (uid != new_suid))
23527                 return -EPERM;
23528  
23529 +       if (gr_check_crash_uid(uid))
23530 +               return -EPERM;
23531 +
23532         if (old_euid != uid)
23533         {
23534                 current->mm->dumpable = suid_dumpable;
23535 @@ -1123,8 +1142,10 @@ asmlinkage long sys_setresgid(gid_t rgid
23536                 current->egid = egid;
23537         }
23538         current->fsgid = current->egid;
23539 -       if (rgid != (gid_t) -1)
23540 +       if (rgid != (gid_t) -1) {
23541 +               gr_set_role_label(current, current->uid, rgid);
23542                 current->gid = rgid;
23543 +       }
23544         if (sgid != (gid_t) -1)
23545                 current->sgid = sgid;
23546  
23547 diff -urNp linux-2.6.17.11/kernel/sysctl.c linux-2.6.17.11/kernel/sysctl.c
23548 --- linux-2.6.17.11/kernel/sysctl.c     2006-08-07 00:18:54.000000000 -0400
23549 +++ linux-2.6.17.11/kernel/sysctl.c     2006-09-01 16:20:29.000000000 -0400
23550 @@ -54,6 +54,14 @@ extern int proc_nr_files(ctl_table *tabl
23551                       void __user *buffer, size_t *lenp, loff_t *ppos);
23552  
23553  #if defined(CONFIG_SYSCTL)
23554 +#include <linux/grsecurity.h>
23555 +#include <linux/grinternal.h>
23556 +
23557 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
23558 +                             const void *newval);
23559 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
23560 +                               const int op);
23561 +extern int gr_handle_chroot_sysctl(const int op);
23562  
23563  /* External variables not in a header file. */
23564  extern int C_A_D;
23565 @@ -157,6 +165,22 @@ extern ctl_table inotify_table[];
23566  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
23567  int sysctl_legacy_va_layout;
23568  #endif
23569 +extern ctl_table grsecurity_table[];
23570 +
23571 +#ifdef CONFIG_PAX_SOFTMODE
23572 +static ctl_table pax_table[] = {
23573 +       {
23574 +               .ctl_name       = PAX_SOFTMODE,
23575 +               .procname       = "softmode",
23576 +               .data           = &pax_softmode,
23577 +               .maxlen         = sizeof(unsigned int),
23578 +               .mode           = 0600,
23579 +               .proc_handler   = &proc_dointvec,
23580 +       },
23581 +
23582 +       { .ctl_name = 0 }
23583 +};
23584 +#endif
23585  
23586  /* /proc declarations: */
23587  
23588 @@ -683,6 +707,24 @@ static ctl_table kern_table[] = {
23589                 .proc_handler   = &proc_dointvec,
23590         },
23591  #endif
23592 +
23593 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
23594 +       {
23595 +               .ctl_name       = KERN_GRSECURITY,
23596 +               .procname       = "grsecurity",
23597 +               .mode           = 0500,
23598 +               .child          = grsecurity_table,
23599 +       },
23600 +#endif
23601 +
23602 +#ifdef CONFIG_PAX_SOFTMODE
23603 +       {
23604 +               .ctl_name       = KERN_PAX,
23605 +               .procname       = "pax",
23606 +               .mode           = 0500,
23607 +               .child          = pax_table,
23608 +       },
23609 +#endif
23610         { .ctl_name = 0 }
23611  };
23612  
23613 @@ -1180,6 +1222,10 @@ static int test_perm(int mode, int op)
23614  static inline int ctl_perm(ctl_table *table, int op)
23615  {
23616         int error;
23617 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
23618 +               return -EACCES;
23619 +       if (gr_handle_chroot_sysctl(op))
23620 +               return -EACCES;
23621         error = security_sysctl(table, op);
23622         if (error)
23623                 return error;
23624 @@ -1216,6 +1262,10 @@ repeat:
23625                                 table = table->child;
23626                                 goto repeat;
23627                         }
23628 +
23629 +                       if (!gr_handle_sysctl(table, oldval, newval))
23630 +                               return -EPERM;
23631 +
23632                         error = do_sysctl_strategy(table, name, nlen,
23633                                                    oldval, oldlenp,
23634                                                    newval, newlen, context);
23635 diff -urNp linux-2.6.17.11/kernel/time.c linux-2.6.17.11/kernel/time.c
23636 --- linux-2.6.17.11/kernel/time.c       2006-08-07 00:18:54.000000000 -0400
23637 +++ linux-2.6.17.11/kernel/time.c       2006-09-01 16:20:29.000000000 -0400
23638 @@ -36,6 +36,7 @@
23639  #include <linux/security.h>
23640  #include <linux/fs.h>
23641  #include <linux/module.h>
23642 +#include <linux/grsecurity.h>
23643  
23644  #include <asm/uaccess.h>
23645  #include <asm/unistd.h>
23646 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user 
23647                 return err;
23648  
23649         vx_settimeofday(&tv);
23650 +
23651 +       gr_log_timechange();
23652 +
23653         return 0;
23654  }
23655  
23656 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct 
23657                         return -EFAULT;
23658         }
23659  
23660 +       gr_log_timechange();
23661 +
23662         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
23663  }
23664  
23665 diff -urNp linux-2.6.17.11/Makefile linux-2.6.17.11/Makefile
23666 --- linux-2.6.17.11/Makefile    2006-08-23 19:30:00.000000000 -0400
23667 +++ linux-2.6.17.11/Makefile    2006-09-01 16:20:29.000000000 -0400
23668 @@ -518,7 +518,7 @@ export MODLIB
23669  
23670  
23671  ifeq ($(KBUILD_EXTMOD),)
23672 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
23673 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
23674  
23675  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
23676                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
23677 diff -urNp linux-2.6.17.11/mm/filemap.c linux-2.6.17.11/mm/filemap.c
23678 --- linux-2.6.17.11/mm/filemap.c        2006-08-07 00:18:54.000000000 -0400
23679 +++ linux-2.6.17.11/mm/filemap.c        2006-09-01 16:20:29.000000000 -0400
23680 @@ -30,6 +30,7 @@
23681  #include <linux/security.h>
23682  #include <linux/syscalls.h>
23683  #include <linux/cpuset.h>
23684 +#include <linux/grsecurity.h>
23685  #include "filemap.h"
23686  #include "internal.h"
23687  
23688 @@ -1650,7 +1651,13 @@ int generic_file_mmap(struct file * file
23689         struct address_space *mapping = file->f_mapping;
23690  
23691         if (!mapping->a_ops->readpage)
23692 -               return -ENOEXEC;
23693 +               return -ENODEV;
23694 +
23695 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
23696 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
23697 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
23698 +#endif
23699 +
23700         file_accessed(file);
23701         vma->vm_ops = &generic_file_vm_ops;
23702         return 0;
23703 @@ -1872,6 +1879,7 @@ inline int generic_write_checks(struct f
23704                          *pos = i_size_read(inode);
23705  
23706                 if (limit != RLIM_INFINITY) {
23707 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
23708                         if (*pos >= limit) {
23709                                 send_sig(SIGXFSZ, current, 0);
23710                                 return -EFBIG;
23711 diff -urNp linux-2.6.17.11/mm/madvise.c linux-2.6.17.11/mm/madvise.c
23712 --- linux-2.6.17.11/mm/madvise.c        2006-08-07 00:18:54.000000000 -0400
23713 +++ linux-2.6.17.11/mm/madvise.c        2006-09-01 16:20:29.000000000 -0400
23714 @@ -15,9 +15,46 @@
23715   * We can potentially split a vm area into separate
23716   * areas, each area with its own behavior.
23717   */
23718 +
23719 +#ifdef CONFIG_PAX_SEGMEXEC
23720 +static long __madvise_behavior(struct vm_area_struct * vma,
23721 +                    struct vm_area_struct **prev,
23722 +                    unsigned long start, unsigned long end, int behavior);
23723 +
23724 +static long madvise_behavior(struct vm_area_struct * vma,
23725 +                    struct vm_area_struct **prev,
23726 +                    unsigned long start, unsigned long end, int behavior)
23727 +{
23728 +       if (vma->vm_flags & VM_MIRROR) {
23729 +               struct vm_area_struct * vma_m, * prev_m;
23730 +               unsigned long start_m, end_m;
23731 +               int error;
23732 +
23733 +               start_m = vma->vm_start + vma->vm_mirror;
23734 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
23735 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
23736 +                       start_m = start + vma->vm_mirror;
23737 +                       end_m = end + vma->vm_mirror;
23738 +                       error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
23739 +                       if (error)
23740 +                               return error;
23741 +               } else {
23742 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
23743 +                       return -ENOMEM;
23744 +               }
23745 +       }
23746 +
23747 +       return __madvise_behavior(vma, prev, start, end, behavior);
23748 +}
23749 +
23750 +static long __madvise_behavior(struct vm_area_struct * vma,
23751 +                    struct vm_area_struct **prev,
23752 +                    unsigned long start, unsigned long end, int behavior)
23753 +#else
23754  static long madvise_behavior(struct vm_area_struct * vma,
23755                      struct vm_area_struct **prev,
23756                      unsigned long start, unsigned long end, int behavior)
23757 +#endif
23758  {
23759         struct mm_struct * mm = vma->vm_mm;
23760         int error = 0;
23761 diff -urNp linux-2.6.17.11/mm/memory.c linux-2.6.17.11/mm/memory.c
23762 --- linux-2.6.17.11/mm/memory.c 2006-08-07 00:18:54.000000000 -0400
23763 +++ linux-2.6.17.11/mm/memory.c 2006-09-01 16:20:29.000000000 -0400
23764 @@ -48,6 +48,7 @@
23765  #include <linux/rmap.h>
23766  #include <linux/module.h>
23767  #include <linux/init.h>
23768 +#include <linux/grsecurity.h>
23769  
23770  #include <asm/pgalloc.h>
23771  #include <asm/uaccess.h>
23772 @@ -320,6 +321,11 @@ int __pte_alloc(struct mm_struct *mm, pm
23773  
23774  int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
23775  {
23776 +
23777 +#ifdef CONFIG_PAX_KERNEXEC
23778 +       unsigned long cr0;
23779 +#endif
23780 +
23781         pte_t *new = pte_alloc_one_kernel(&init_mm, address);
23782         if (!new)
23783                 return -ENOMEM;
23784 @@ -327,8 +333,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
23785         spin_lock(&init_mm.page_table_lock);
23786         if (pmd_present(*pmd))          /* Another has populated it */
23787                 pte_free_kernel(new);
23788 -       else
23789 +       else {
23790 +
23791 +#ifdef CONFIG_PAX_KERNEXEC
23792 +               pax_open_kernel(cr0);
23793 +#endif
23794 +
23795                 pmd_populate_kernel(&init_mm, pmd, new);
23796 +
23797 +#ifdef CONFIG_PAX_KERNEXEC
23798 +               pax_close_kernel(cr0);
23799 +#endif
23800 +
23801 +       }
23802         spin_unlock(&init_mm.page_table_lock);
23803         return 0;
23804  }
23805 @@ -1430,6 +1447,88 @@ static inline void cow_user_page(struct 
23806         copy_user_highpage(dst, src, va);
23807  }
23808  
23809 +#ifdef CONFIG_PAX_SEGMEXEC
23810 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
23811 + *
23812 + * the ptl of the lower mapped page is held on entry and is not released on exit
23813 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
23814 + */
23815 +static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
23816 +{
23817 +       struct mm_struct *mm = vma->vm_mm;
23818 +       unsigned long address_m, pfn_m;
23819 +       struct vm_area_struct * vma_m = NULL;
23820 +       pte_t * pte_m, entry_m;
23821 +       struct page * page_m = NULL;
23822 +
23823 +       address_m = vma->vm_start + vma->vm_mirror;
23824 +       vma_m = find_vma(mm, address_m);
23825 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
23826 +
23827 +       address_m = address + vma->vm_mirror;
23828 +       pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
23829 +
23830 +       if (pte_same(*pte, *pte_m)) {
23831 +               pte_unmap_nested(pte_m);
23832 +               return;
23833 +       }
23834 +
23835 +       pfn_m = pte_pfn(*pte);
23836 +       if (pte_present(*pte_m)) {
23837 +               page_m = vm_normal_page(vma_m, address_m, *pte_m);
23838 +               if (page_m) {
23839 +                       flush_cache_page(vma_m, address_m, pfn_m);
23840 +                       flush_icache_page(vma_m, page_m);
23841 +               }
23842 +       }
23843 +
23844 +       if (pte_present(*pte_m))
23845 +               entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
23846 +       else
23847 +               entry_m = ptep_get_and_clear(mm, address_m, pte_m);
23848 +
23849 +       if (pte_none(entry_m)) {
23850 +       } else if (pte_present(entry_m)) {
23851 +               if (page_m) {
23852 +                       page_remove_rmap(page_m);
23853 +                       if (PageAnon(page_m))
23854 +                               dec_mm_counter(mm, anon_rss);
23855 +                       else
23856 +                               dec_mm_counter(mm, file_rss);
23857 +                       page_cache_release(page_m);
23858 +               }
23859 +       } else if (!pte_file(entry_m)) {
23860 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
23861 +       } else {
23862 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
23863 +                               address, vma->vm_start, address_m, vma_m->vm_start);
23864 +       }
23865 +
23866 +       page_m = vm_normal_page(vma, address, *pte);
23867 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
23868 +       if (pte_write(*pte))
23869 +               entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
23870 +       if (page_m) {
23871 +               page_cache_get(page_m);
23872 +               /*
23873 +                * we can test PAGE_MAPPING_ANON without holding page_map_lock because
23874 +                * we hold the page table lock and have a reference to page_m
23875 +                */
23876 +               if (PageAnon(page_m)) {
23877 +                       page_add_anon_rmap(page_m, vma_m, address_m);
23878 +                       inc_mm_counter(mm, anon_rss);
23879 +               } else {
23880 +                       page_add_file_rmap(page_m);
23881 +                       inc_mm_counter(mm, file_rss);
23882 +               }
23883 +       }
23884 +       set_pte_at(mm, address_m, pte_m, entry_m);
23885 +       update_mmu_cache(vma_m, address_m, entry_m);
23886 +       lazy_mmu_prot_update(entry_m);
23887 +       pte_unmap_nested(pte_m);
23888 +}
23889 +#endif
23890 +
23891  /*
23892   * This routine handles present pages, when users try to write
23893   * to a shared page. It is done by copying the page to a new address
23894 @@ -1520,6 +1619,12 @@ gotten:
23895                 /* Free the old page.. */
23896                 new_page = old_page;
23897                 ret |= VM_FAULT_WRITE;
23898 +
23899 +#ifdef CONFIG_PAX_SEGMEXEC
23900 +               if (vma->vm_flags & VM_MIRROR)
23901 +                       pax_mirror_fault(vma, address, page_table);
23902 +#endif
23903 +
23904         }
23905         if (new_page)
23906                 page_cache_release(new_page);
23907 @@ -1770,6 +1875,7 @@ int vmtruncate(struct inode * inode, lof
23908  
23909  do_expand:
23910         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
23911 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
23912         if (limit != RLIM_INFINITY && offset > limit)
23913                 goto out_sig;
23914         if (offset > inode->i_sb->s_maxbytes)
23915 @@ -1963,6 +2069,12 @@ again:
23916         /* No need to invalidate - it was non-present before */
23917         update_mmu_cache(vma, address, pte);
23918         lazy_mmu_prot_update(pte);
23919 +
23920 +#ifdef CONFIG_PAX_SEGMEXEC
23921 +       if (vma->vm_flags & VM_MIRROR)
23922 +               pax_mirror_fault(vma, address, page_table);
23923 +#endif
23924 +
23925  unlock:
23926         pte_unmap_unlock(page_table, ptl);
23927  out:
23928 @@ -2027,6 +2139,12 @@ static int do_anonymous_page(struct mm_s
23929         /* No need to invalidate - it was non-present before */
23930         update_mmu_cache(vma, address, entry);
23931         lazy_mmu_prot_update(entry);
23932 +
23933 +#ifdef CONFIG_PAX_SEGMEXEC
23934 +       if (vma->vm_flags & VM_MIRROR)
23935 +               pax_mirror_fault(vma, address, page_table);
23936 +#endif
23937 +
23938  unlock:
23939         pte_unmap_unlock(page_table, ptl);
23940         return VM_FAULT_MINOR;
23941 @@ -2155,6 +2273,12 @@ retry:
23942         /* no need to invalidate: a not-present page shouldn't be cached */
23943         update_mmu_cache(vma, address, entry);
23944         lazy_mmu_prot_update(entry);
23945 +
23946 +#ifdef CONFIG_PAX_SEGMEXEC
23947 +       if (vma->vm_flags & VM_MIRROR)
23948 +               pax_mirror_fault(vma, address, page_table);
23949 +#endif
23950 +
23951  unlock:
23952         pte_unmap_unlock(page_table, ptl);
23953         return ret;
23954 @@ -2278,6 +2402,12 @@ static inline int handle_pte_fault(struc
23955                         flush_tlb_page(vma, address);
23956         }
23957  unlock:
23958 +
23959 +#ifdef CONFIG_PAX_SEGMEXEC
23960 +       if (vma->vm_flags & VM_MIRROR)
23961 +               pax_mirror_fault(vma, address, pte);
23962 +#endif
23963 +
23964         pte_unmap_unlock(pte, ptl);
23965         ret = VM_FAULT_MINOR;
23966  out:
23967 @@ -2303,6 +2433,49 @@ int __handle_mm_fault(struct mm_struct *
23968         if (unlikely(is_vm_hugetlb_page(vma)))
23969                 return hugetlb_fault(mm, vma, address, write_access);
23970  
23971 +#ifdef CONFIG_PAX_SEGMEXEC
23972 +       if (vma->vm_flags & VM_MIRROR) {
23973 +               unsigned long address_m;
23974 +               struct vm_area_struct * vma_m;
23975 +               pgd_t *pgd_m;
23976 +               pud_t *pud_m;
23977 +               pmd_t *pmd_m;
23978 +
23979 +               address_m = vma->vm_start + vma->vm_mirror;
23980 +               vma_m = find_vma(mm, address_m);
23981 +
23982 +               /* PaX: sanity checks */
23983 +               if (!vma_m) {
23984 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
23985 +                              address, vma, address_m, vma_m);
23986 +                       return VM_FAULT_SIGBUS;
23987 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
23988 +                       vma_m->vm_start != address_m ||
23989 +                       vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
23990 +               {
23991 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
23992 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
23993 +                       return VM_FAULT_SIGBUS;
23994 +               }
23995 +
23996 +               if (address_m < address) {
23997 +                       address += vma->vm_mirror;
23998 +                       vma = vma_m;
23999 +               }
24000 +
24001 +               address_m = address + vma->vm_mirror;
24002 +               pgd_m = pgd_offset(mm, address_m);
24003 +               pud_m = pud_alloc(mm, pgd_m, address_m);
24004 +               if (!pud_m)
24005 +                       return VM_FAULT_OOM;
24006 +               pmd_m = pmd_alloc(mm, pud_m, address_m);
24007 +               if (!pmd_m)
24008 +                       return VM_FAULT_OOM;
24009 +               if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
24010 +                       return VM_FAULT_OOM;
24011 +       }
24012 +#endif
24013 +
24014         pgd = pgd_offset(mm, address);
24015         pud = pud_alloc(mm, pgd, address);
24016         if (!pud)
24017 diff -urNp linux-2.6.17.11/mm/mempolicy.c linux-2.6.17.11/mm/mempolicy.c
24018 --- linux-2.6.17.11/mm/mempolicy.c      2006-08-07 00:18:54.000000000 -0400
24019 +++ linux-2.6.17.11/mm/mempolicy.c      2006-09-01 16:20:29.000000000 -0400
24020 @@ -346,6 +346,12 @@ check_range(struct mm_struct *mm, unsign
24021                         if (prev && prev->vm_end < vma->vm_start)
24022                                 return ERR_PTR(-EFAULT);
24023                 }
24024 +
24025 +#ifdef CONFIG_PAX_SEGMEXEC
24026 +               if (vma->vm_flags & VM_MIRROR)
24027 +                       return ERR_PTR(-EFAULT);
24028 +#endif
24029 +
24030                 if (!is_vm_hugetlb_page(vma) &&
24031                     ((flags & MPOL_MF_STRICT) ||
24032                      ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
24033 diff -urNp linux-2.6.17.11/mm/mlock.c linux-2.6.17.11/mm/mlock.c
24034 --- linux-2.6.17.11/mm/mlock.c  2006-08-07 00:18:54.000000000 -0400
24035 +++ linux-2.6.17.11/mm/mlock.c  2006-09-01 16:20:29.000000000 -0400
24036 @@ -10,14 +10,85 @@
24037  #include <linux/mempolicy.h>
24038  #include <linux/syscalls.h>
24039  #include <linux/vs_memory.h>
24040 +#include <linux/grsecurity.h>
24041  
24042 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
24043 +       unsigned long start, unsigned long end, unsigned int newflags);
24044  
24045  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
24046         unsigned long start, unsigned long end, unsigned int newflags)
24047  {
24048         struct mm_struct * mm = vma->vm_mm;
24049 -       pgoff_t pgoff;
24050         int pages;
24051 +       int ret;
24052 +
24053 +#ifdef CONFIG_PAX_SEGMEXEC
24054 +       struct vm_area_struct * vma_m = NULL, *prev_m;
24055 +       unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
24056 +
24057 +       if (vma->vm_flags & VM_MIRROR) {
24058 +               start_m = vma->vm_start + vma->vm_mirror;
24059 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
24060 +               if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
24061 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
24062 +                       return -ENOMEM;
24063 +               }
24064 +
24065 +               start_m = start + vma->vm_mirror;
24066 +               end_m = end + vma->vm_mirror;
24067 +               if (newflags & VM_LOCKED)
24068 +                       newflags_m = vma_m->vm_flags | VM_LOCKED;
24069 +               else
24070 +                       newflags_m = vma_m->vm_flags & ~VM_LOCKED;
24071 +               ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
24072 +               if (ret)
24073 +                       return ret;
24074 +       }
24075 +#endif
24076 +
24077 +       ret = __mlock_fixup(vma, prev, start, end, newflags);
24078 +       if (ret)
24079 +               return ret;
24080 +
24081 +       /*
24082 +        * vm_flags is protected by the mmap_sem held in write mode.
24083 +        * It's okay if try_to_unmap_one unmaps a page just after we
24084 +        * set VM_LOCKED, make_pages_present below will bring it back.
24085 +        */
24086 +       vma->vm_flags = newflags;
24087 +
24088 +#ifdef CONFIG_PAX_SEGMEXEC
24089 +       if (vma->vm_flags & VM_MIRROR)
24090 +               vma_m->vm_flags = newflags_m;
24091 +#endif
24092 +
24093 +       /*
24094 +        * Keep track of amount of locked VM.
24095 +        */
24096 +       pages = (end - start) >> PAGE_SHIFT;
24097 +       if (newflags & VM_LOCKED) {
24098 +               pages = -pages;
24099 +               if (!(newflags & VM_IO))
24100 +                       ret = make_pages_present(start, end);
24101 +       }
24102 +
24103 +       mm->locked_vm -= pages;
24104 +
24105 +#ifdef CONFIG_PAX_SEGMEXEC
24106 +       if (vma->vm_flags & VM_MIRROR)
24107 +               mm->locked_vm -= pages;
24108 +#endif
24109 +
24110 +       if (ret == -ENOMEM)
24111 +               ret = -EAGAIN;
24112 +       return ret;
24113 +}
24114 +
24115 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
24116 +       unsigned long start, unsigned long end, unsigned int newflags)
24117 +{
24118 +       struct mm_struct * mm = vma->vm_mm;
24119 +       pgoff_t pgoff;
24120         int ret = 0;
24121  
24122         if (newflags == vma->vm_flags) {
24123 @@ -30,7 +101,7 @@ static int mlock_fixup(struct vm_area_st
24124                           vma->vm_file, pgoff, vma_policy(vma));
24125         if (*prev) {
24126                 vma = *prev;
24127 -               goto success;
24128 +               goto out;
24129         }
24130  
24131         *prev = vma;
24132 @@ -41,31 +112,9 @@ static int mlock_fixup(struct vm_area_st
24133                         goto out;
24134         }
24135  
24136 -       if (end != vma->vm_end) {
24137 +       if (end != vma->vm_end)
24138                 ret = split_vma(mm, vma, end, 0);
24139 -               if (ret)
24140 -                       goto out;
24141 -       }
24142  
24143 -success:
24144 -       /*
24145 -        * vm_flags is protected by the mmap_sem held in write mode.
24146 -        * It's okay if try_to_unmap_one unmaps a page just after we
24147 -        * set VM_LOCKED, make_pages_present below will bring it back.
24148 -        */
24149 -       vma->vm_flags = newflags;
24150 -
24151 -       /*
24152 -        * Keep track of amount of locked VM.
24153 -        */
24154 -       pages = (end - start) >> PAGE_SHIFT;
24155 -       if (newflags & VM_LOCKED) {
24156 -               pages = -pages;
24157 -               if (!(newflags & VM_IO))
24158 -                       ret = make_pages_present(start, end);
24159 -       }
24160 -
24161 -       vx_vmlocked_sub(vma->vm_mm, pages);
24162  out:
24163         if (ret == -ENOMEM)
24164                 ret = -EAGAIN;
24165 @@ -84,6 +133,17 @@ static int do_mlock(unsigned long start,
24166                 return -EINVAL;
24167         if (end == start)
24168                 return 0;
24169 +
24170 +#ifdef CONFIG_PAX_SEGMEXEC
24171 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
24172 +               if (end > SEGMEXEC_TASK_SIZE)
24173 +                       return -EINVAL;
24174 +       } else
24175 +#endif
24176 +
24177 +       if (end > TASK_SIZE)
24178 +               return -EINVAL;
24179 +
24180         vma = find_vma_prev(current->mm, start, &prev);
24181         if (!vma || vma->vm_start > start)
24182                 return -ENOMEM;
24183 @@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long 
24184         lock_limit >>= PAGE_SHIFT;
24185  
24186         /* check against resource limits */
24187 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
24188         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
24189                 error = do_mlock(start, len, 1);
24190  out:
24191 @@ -173,6 +234,16 @@ static int do_mlockall(int flags)
24192         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
24193                 unsigned int newflags;
24194  
24195 +#ifdef CONFIG_PAX_SEGMEXEC
24196 +               if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
24197 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
24198 +                               break;
24199 +               } else
24200 +#endif
24201 +
24202 +               if (vma->vm_end > TASK_SIZE)
24203 +                       break;
24204 +
24205                 newflags = vma->vm_flags | VM_LOCKED;
24206                 if (!(flags & MCL_CURRENT))
24207                         newflags &= ~VM_LOCKED;
24208 @@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
24209         ret = -ENOMEM;
24210         if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
24211                 goto out;
24212 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
24213         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
24214             capable(CAP_IPC_LOCK))
24215                 ret = do_mlockall(flags);
24216 diff -urNp linux-2.6.17.11/mm/mmap.c linux-2.6.17.11/mm/mmap.c
24217 --- linux-2.6.17.11/mm/mmap.c   2006-08-23 19:30:01.000000000 -0400
24218 +++ linux-2.6.17.11/mm/mmap.c   2006-09-01 16:20:29.000000000 -0400
24219 @@ -25,6 +25,7 @@
24220  #include <linux/mount.h>
24221  #include <linux/mempolicy.h>
24222  #include <linux/rmap.h>
24223 +#include <linux/grsecurity.h>
24224  
24225  #include <asm/uaccess.h>
24226  #include <asm/cacheflush.h>
24227 @@ -240,6 +241,7 @@ asmlinkage unsigned long sys_brk(unsigne
24228          * not page aligned -Ram Gupta
24229          */
24230         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
24231 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
24232         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
24233                 goto out;
24234  
24235 @@ -628,11 +630,17 @@ again:                    remove_next = 1 + (end > next->
24236   * If the vma has a ->close operation then the driver probably needs to release
24237   * per-vma resources, so we don't attempt to merge those.
24238   */
24239 +#ifdef CONFIG_PAX_SEGMEXEC
24240 +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
24241 +#else
24242  #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
24243 +#endif
24244  
24245  static inline int is_mergeable_vma(struct vm_area_struct *vma,
24246                         struct file *file, unsigned long vm_flags)
24247  {
24248 +       if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
24249 +               return 0;
24250         if (vma->vm_flags != vm_flags)
24251                 return 0;
24252         if (vma->vm_file != file)
24253 @@ -857,14 +865,11 @@ none:
24254  void vm_stat_account(struct mm_struct *mm, unsigned long flags,
24255                                                 struct file *file, long pages)
24256  {
24257 -       const unsigned long stack_flags
24258 -               = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
24259 -
24260         if (file) {
24261                 mm->shared_vm += pages;
24262                 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
24263                         mm->exec_vm += pages;
24264 -       } else if (flags & stack_flags)
24265 +       } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
24266                 mm->stack_vm += pages;
24267         if (flags & (VM_RESERVED|VM_IO))
24268                 mm->reserved_vm += pages;
24269 @@ -875,10 +880,55 @@ void vm_stat_account(struct mm_struct *m
24270   * The caller must hold down_write(current->mm->mmap_sem).
24271   */
24272  
24273 +#ifdef CONFIG_PAX_SEGMEXEC
24274 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
24275 +                       unsigned long len, unsigned long prot,
24276 +                       unsigned long flags, unsigned long pgoff);
24277 +
24278  unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
24279                         unsigned long len, unsigned long prot,
24280                         unsigned long flags, unsigned long pgoff)
24281  {
24282 +       unsigned long ret = -EINVAL;
24283 +
24284 +       if (flags & MAP_MIRROR)
24285 +               return ret;
24286 +
24287 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
24288 +           (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
24289 +               return ret;
24290 +
24291 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
24292 +
24293 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
24294 +
24295 +#ifdef CONFIG_PAX_MPROTECT
24296 +           && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
24297 +#endif
24298 +
24299 +          )
24300 +       {
24301 +               unsigned long ret_m;
24302 +               prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
24303 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
24304 +               if (ret_m >= TASK_SIZE) {
24305 +                       do_munmap(current->mm, ret, len);
24306 +                       ret = ret_m;
24307 +               }
24308 +       }
24309 +
24310 +       return ret;
24311 +}
24312 +
24313 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
24314 +                       unsigned long len, unsigned long prot,
24315 +                       unsigned long flags, unsigned long pgoff)
24316 +#else
24317 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
24318 +                       unsigned long len, unsigned long prot,
24319 +                       unsigned long flags, unsigned long pgoff)
24320 +#endif
24321 +{
24322         struct mm_struct * mm = current->mm;
24323         struct vm_area_struct * vma, * prev;
24324         struct inode *inode;
24325 @@ -889,6 +939,28 @@ unsigned long do_mmap_pgoff(struct file 
24326         int accountable = 1;
24327         unsigned long charged = 0, reqprot = prot;
24328  
24329 +#ifdef CONFIG_PAX_SEGMEXEC
24330 +       struct vm_area_struct * vma_m = NULL;
24331 +
24332 +       if (flags & MAP_MIRROR) {
24333 +               /* PaX: sanity checks, to be removed when proved to be stable */
24334 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
24335 +                       return -EINVAL;
24336 +
24337 +               vma_m = find_vma(mm, pgoff);
24338 +
24339 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
24340 +                   vma_m->vm_start != pgoff ||
24341 +                   (vma_m->vm_flags & VM_SPECIAL) ||
24342 +                   (prot & PROT_WRITE))
24343 +                       return -EINVAL;
24344 +
24345 +               file = vma_m->vm_file;
24346 +               pgoff = vma_m->vm_pgoff;
24347 +               len = vma_m->vm_end - vma_m->vm_start;
24348 +       }
24349 +#endif
24350 +
24351         if (file) {
24352                 if (is_file_hugepages(file))
24353                         accountable = 0;
24354 @@ -906,7 +978,7 @@ unsigned long do_mmap_pgoff(struct file 
24355          * (the exception is when the underlying filesystem is noexec
24356          *  mounted, in which case we dont add PROT_EXEC.)
24357          */
24358 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
24359 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
24360                 if (!(file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)))
24361                         prot |= PROT_EXEC;
24362  
24363 @@ -933,7 +1005,7 @@ unsigned long do_mmap_pgoff(struct file 
24364         /* Obtain the address to map to. we verify (or select) it and ensure
24365          * that it represents a valid section of the address space.
24366          */
24367 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
24368 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
24369         if (addr & ~PAGE_MASK)
24370                 return addr;
24371  
24372 @@ -944,6 +1016,24 @@ unsigned long do_mmap_pgoff(struct file 
24373         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
24374                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
24375  
24376 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
24377 +               vm_flags &= ~VM_MAYEXEC;
24378 +
24379 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
24380 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
24381 +
24382 +#ifdef CONFIG_PAX_MPROTECT
24383 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
24384 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
24385 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
24386 +                       else
24387 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
24388 +               }
24389 +#endif
24390 +
24391 +       }
24392 +#endif
24393 +
24394         if (flags & MAP_LOCKED) {
24395                 if (!can_do_mlock())
24396                         return -EPERM;
24397 @@ -956,6 +1046,7 @@ unsigned long do_mmap_pgoff(struct file 
24398                 locked += mm->locked_vm;
24399                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
24400                 lock_limit >>= PAGE_SHIFT;
24401 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24402                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
24403                         return -EAGAIN;
24404         }
24405 @@ -1003,6 +1094,11 @@ unsigned long do_mmap_pgoff(struct file 
24406                         /*
24407                          * Set pgoff according to addr for anon_vma.
24408                          */
24409 +
24410 +#ifdef CONFIG_PAX_SEGMEXEC
24411 +                       if (!(flags & MAP_MIRROR))
24412 +#endif
24413 +
24414                         pgoff = addr >> PAGE_SHIFT;
24415                         break;
24416                 default:
24417 @@ -1014,14 +1110,17 @@ unsigned long do_mmap_pgoff(struct file 
24418         if (error)
24419                 return error;
24420                 
24421 +       if (!gr_acl_handle_mmap(file, prot))
24422 +               return -EACCES;
24423 +
24424         /* Clear old maps */
24425         error = -ENOMEM;
24426 -munmap_back:
24427         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24428         if (vma && vma->vm_start < addr + len) {
24429                 if (do_munmap(mm, addr, len))
24430                         return -ENOMEM;
24431 -               goto munmap_back;
24432 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24433 +               BUG_ON(vma && vma->vm_start < addr + len);
24434         }
24435  
24436         /* Check against address space limit. */
24437 @@ -1069,7 +1168,14 @@ munmap_back:
24438         vma->vm_start = addr;
24439         vma->vm_end = addr + len;
24440         vma->vm_flags = vm_flags;
24441 -       vma->vm_page_prot = protection_map[vm_flags & 0x0f];
24442 +
24443 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
24444 +       if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
24445 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
24446 +       else
24447 +#endif
24448 +
24449 +       vma->vm_page_prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
24450         vma->vm_pgoff = pgoff;
24451  
24452         if (file) {
24453 @@ -1093,6 +1199,14 @@ munmap_back:
24454                         goto free_vma;
24455         }
24456  
24457 +#ifdef CONFIG_PAX_SEGMEXEC
24458 +       if (flags & MAP_MIRROR) {
24459 +               vma_m->vm_flags |= VM_MIRROR;
24460 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
24461 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
24462 +       }
24463 +#endif
24464 +
24465         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
24466          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
24467          * that memory reservation must be checked; but that reservation
24468 @@ -1128,6 +1242,7 @@ munmap_back:
24469  out:   
24470         vx_vmpages_add(mm, len >> PAGE_SHIFT);
24471         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
24472 +       track_exec_limit(mm, addr, addr + len, vm_flags);
24473         if (vm_flags & VM_LOCKED) {
24474                 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
24475                 make_pages_present(addr, addr + len);
24476 @@ -1182,6 +1297,10 @@ arch_get_unmapped_area(struct file *filp
24477         if (len > TASK_SIZE)
24478                 return -ENOMEM;
24479  
24480 +#ifdef CONFIG_PAX_RANDMMAP
24481 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
24482 +#endif
24483 +
24484         if (addr) {
24485                 addr = PAGE_ALIGN(addr);
24486                 vma = find_vma(mm, addr);
24487 @@ -1192,7 +1311,7 @@ arch_get_unmapped_area(struct file *filp
24488         if (len > mm->cached_hole_size) {
24489                 start_addr = addr = mm->free_area_cache;
24490         } else {
24491 -               start_addr = addr = TASK_UNMAPPED_BASE;
24492 +               start_addr = addr = mm->mmap_base;
24493                 mm->cached_hole_size = 0;
24494         }
24495  
24496 @@ -1204,9 +1323,8 @@ full_search:
24497                          * Start a new search - just in case we missed
24498                          * some holes.
24499                          */
24500 -                       if (start_addr != TASK_UNMAPPED_BASE) {
24501 -                               addr = TASK_UNMAPPED_BASE;
24502 -                               start_addr = addr;
24503 +                       if (start_addr != mm->mmap_base) {
24504 +                               start_addr = addr = mm->mmap_base;
24505                                 mm->cached_hole_size = 0;
24506                                 goto full_search;
24507                         }
24508 @@ -1231,7 +1349,7 @@ void arch_unmap_area(struct mm_struct *m
24509         /*
24510          * Is this a new hole at the lowest possible address?
24511          */
24512 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
24513 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
24514                 mm->free_area_cache = addr;
24515                 mm->cached_hole_size = ~0UL;
24516         }
24517 @@ -1249,12 +1367,16 @@ arch_get_unmapped_area_topdown(struct fi
24518  {
24519         struct vm_area_struct *vma;
24520         struct mm_struct *mm = current->mm;
24521 -       unsigned long addr = addr0;
24522 +       unsigned long base = mm->mmap_base, addr = addr0;
24523  
24524         /* requested length too big for entire address space */
24525         if (len > TASK_SIZE)
24526                 return -ENOMEM;
24527  
24528 +#ifdef CONFIG_PAX_RANDMMAP
24529 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
24530 +#endif
24531 +
24532         /* requesting a specific address */
24533         if (addr) {
24534                 addr = PAGE_ALIGN(addr);
24535 @@ -1312,13 +1434,21 @@ bottomup:
24536          * can happen with large stack limits and large mmap()
24537          * allocations.
24538          */
24539 +       mm->mmap_base = TASK_UNMAPPED_BASE;
24540 +
24541 +#ifdef CONFIG_PAX_RANDMMAP
24542 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
24543 +               mm->mmap_base += mm->delta_mmap;
24544 +#endif
24545 +
24546 +       mm->free_area_cache = mm->mmap_base;
24547         mm->cached_hole_size = ~0UL;
24548 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
24549         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
24550         /*
24551          * Restore the topdown base:
24552          */
24553 -       mm->free_area_cache = mm->mmap_base;
24554 +       mm->mmap_base = base;
24555 +       mm->free_area_cache = base;
24556         mm->cached_hole_size = ~0UL;
24557  
24558         return addr;
24559 @@ -1334,8 +1464,10 @@ void arch_unmap_area_topdown(struct mm_s
24560                 mm->free_area_cache = addr;
24561  
24562         /* dont allow allocations above current base */
24563 -       if (mm->free_area_cache > mm->mmap_base)
24564 +       if (mm->free_area_cache > mm->mmap_base) {
24565                 mm->free_area_cache = mm->mmap_base;
24566 +               mm->cached_hole_size = ~0UL;
24567 +       }
24568  }
24569  
24570  unsigned long
24571 @@ -1468,6 +1600,7 @@ static int acct_stack_growth(struct vm_a
24572                 return -ENOMEM;
24573  
24574         /* Stack limit test */
24575 +       gr_learn_resource(current, RLIMIT_STACK, size, 1);
24576         if (size > rlim[RLIMIT_STACK].rlim_cur)
24577                 return -ENOMEM;
24578  
24579 @@ -1477,6 +1610,7 @@ static int acct_stack_growth(struct vm_a
24580                 unsigned long limit;
24581                 locked = mm->locked_vm + grow;
24582                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
24583 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24584                 if (locked > limit && !capable(CAP_IPC_LOCK))
24585                         return -ENOMEM;
24586         }
24587 @@ -1594,13 +1728,49 @@ int expand_stack(struct vm_area_struct *
24588         if (address < vma->vm_start) {
24589                 unsigned long size, grow;
24590  
24591 +#ifdef CONFIG_PAX_SEGMEXEC
24592 +               struct vm_area_struct *vma_m = NULL;
24593 +               unsigned long address_m = 0UL;
24594 +
24595 +               if (vma->vm_flags & VM_MIRROR) {
24596 +                       address_m = vma->vm_start + vma->vm_mirror;
24597 +                       vma_m = find_vma(vma->vm_mm, address_m);
24598 +                       if (!vma_m || vma_m->vm_start != address_m ||
24599 +                           !(vma_m->vm_flags & VM_MIRROR) ||
24600 +                           vma->vm_end - vma->vm_start !=
24601 +                           vma_m->vm_end - vma_m->vm_start ||
24602 +                           vma->anon_vma != vma_m->anon_vma) {
24603 +                               printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
24604 +                                      address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
24605 +                               anon_vma_unlock(vma);
24606 +                               return -EFAULT;
24607 +                       }
24608 +                       address_m = address + vma->vm_mirror;
24609 +               }
24610 +#endif
24611 +
24612                 size = vma->vm_end - address;
24613                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
24614  
24615 +#ifdef CONFIG_PAX_SEGMEXEC
24616 +               if (vma_m)
24617 +                       error = acct_stack_growth(vma, size, 2*grow);
24618 +               else
24619 +#endif
24620 +
24621                 error = acct_stack_growth(vma, size, grow);
24622                 if (!error) {
24623                         vma->vm_start = address;
24624                         vma->vm_pgoff -= grow;
24625 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
24626 +
24627 +#ifdef CONFIG_PAX_SEGMEXEC
24628 +                       if (vma_m) {
24629 +                               vma_m->vm_start = address_m;
24630 +                               vma_m->vm_pgoff -= grow;
24631 +                       }
24632 +#endif
24633 +
24634                 }
24635         }
24636         anon_vma_unlock(vma);
24637 @@ -1762,7 +1932,24 @@ int split_vma(struct mm_struct * mm, str
24638   * work.  This now handles partial unmappings.
24639   * Jeremy Fitzhardinge <jeremy@goop.org>
24640   */
24641 +#ifdef CONFIG_PAX_SEGMEXEC
24642 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
24643 +
24644 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24645 +{
24646 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
24647 +               int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
24648 +               if (ret)
24649 +                       return ret;
24650 +       }
24651 +
24652 +       return __do_munmap(mm, start, len);
24653 +}
24654 +
24655 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24656 +#else
24657  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24658 +#endif
24659  {
24660         unsigned long end;
24661         struct vm_area_struct *vma, *prev, *last;
24662 @@ -1816,6 +2003,8 @@ int do_munmap(struct mm_struct *mm, unsi
24663         /* Fix up all other VM information */
24664         remove_vma_list(mm, vma);
24665  
24666 +       track_exec_limit(mm, start, end, 0UL);
24667 +
24668         return 0;
24669  }
24670  
24671 @@ -1828,6 +2017,12 @@ asmlinkage long sys_munmap(unsigned long
24672  
24673         profile_munmap(addr);
24674  
24675 +#ifdef CONFIG_PAX_SEGMEXEC
24676 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
24677 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
24678 +               return -EINVAL;
24679 +#endif
24680 +
24681         down_write(&mm->mmap_sem);
24682         ret = do_munmap(mm, addr, len);
24683         up_write(&mm->mmap_sem);
24684 @@ -1849,11 +2044,35 @@ static inline void verify_mm_writelocked
24685   *  anonymous maps.  eventually we may be able to do some
24686   *  brk-specific accounting here.
24687   */
24688 +#ifdef CONFIG_PAX_SEGMEXEC
24689 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
24690 +
24691 +unsigned long do_brk(unsigned long addr, unsigned long len)
24692 +{
24693 +       unsigned long ret;
24694 +
24695 +       ret = __do_brk(addr, len);
24696 +       if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
24697 +               unsigned long ret_m;
24698 +
24699 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
24700 +               if (ret_m > TASK_SIZE) {
24701 +                       do_munmap(current->mm, addr, len);
24702 +                       ret = ret_m;
24703 +               }
24704 +       }
24705 +
24706 +       return ret;
24707 +}
24708 +
24709 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
24710 +#else
24711  unsigned long do_brk(unsigned long addr, unsigned long len)
24712 +#endif
24713  {
24714         struct mm_struct * mm = current->mm;
24715         struct vm_area_struct * vma, * prev;
24716 -       unsigned long flags;
24717 +       unsigned long flags, task_size = TASK_SIZE;
24718         struct rb_node ** rb_link, * rb_parent;
24719         pgoff_t pgoff = addr >> PAGE_SHIFT;
24720         int error;
24721 @@ -1862,11 +2081,28 @@ unsigned long do_brk(unsigned long addr,
24722         if (!len)
24723                 return addr;
24724  
24725 -       if ((addr + len) > TASK_SIZE || (addr + len) < addr)
24726 +#ifdef CONFIG_PAX_SEGMEXEC
24727 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
24728 +               task_size = SEGMEXEC_TASK_SIZE;
24729 +#endif
24730 +
24731 +       if ((addr + len) > task_size || (addr + len) < addr)
24732                 return -EINVAL;
24733  
24734         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
24735  
24736 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
24737 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
24738 +               flags &= ~VM_EXEC;
24739 +
24740 +#ifdef CONFIG_PAX_MPROTECT
24741 +               if (mm->pax_flags & MF_PAX_MPROTECT)
24742 +                       flags &= ~VM_MAYEXEC;
24743 +#endif
24744 +
24745 +       }
24746 +#endif
24747 +
24748         error = arch_mmap_check(addr, len, flags);
24749         if (error)
24750                 return error;
24751 @@ -1880,6 +2116,7 @@ unsigned long do_brk(unsigned long addr,
24752                 locked += mm->locked_vm;
24753                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
24754                 lock_limit >>= PAGE_SHIFT;
24755 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24756                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
24757                         return -EAGAIN;
24758                 if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
24759 @@ -1895,12 +2132,12 @@ unsigned long do_brk(unsigned long addr,
24760         /*
24761          * Clear old maps.  this also does some error checking for us
24762          */
24763 - munmap_back:
24764         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24765         if (vma && vma->vm_start < addr + len) {
24766                 if (do_munmap(mm, addr, len))
24767                         return -ENOMEM;
24768 -               goto munmap_back;
24769 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24770 +               BUG_ON(vma && vma->vm_start < addr + len);
24771         }
24772  
24773         /* Check against address space limits *after* clearing old maps... */
24774 @@ -1933,7 +2170,14 @@ unsigned long do_brk(unsigned long addr,
24775         vma->vm_end = addr + len;
24776         vma->vm_pgoff = pgoff;
24777         vma->vm_flags = flags;
24778 -       vma->vm_page_prot = protection_map[flags & 0x0f];
24779 +
24780 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
24781 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
24782 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
24783 +       else
24784 +#endif
24785 +
24786 +       vma->vm_page_prot = protection_map[flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
24787         vma_link(mm, vma, prev, rb_link, rb_parent);
24788  out:
24789         vx_vmpages_add(mm, len >> PAGE_SHIFT);
24790 @@ -1941,6 +2185,7 @@ out:
24791                 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
24792                 make_pages_present(addr, addr + len);
24793         }
24794 +       track_exec_limit(mm, addr, addr + len, flags);
24795         return addr;
24796  }
24797  
24798 @@ -2079,7 +2324,7 @@ int may_expand_vm(struct mm_struct *mm, 
24799         unsigned long lim;
24800  
24801         lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
24802 -
24803 +       gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
24804         if (cur + npages > lim)
24805                 return 0;
24806         if (!vx_vmpages_avail(mm, npages))
24807 diff -urNp linux-2.6.17.11/mm/mprotect.c linux-2.6.17.11/mm/mprotect.c
24808 --- linux-2.6.17.11/mm/mprotect.c       2006-08-07 00:18:54.000000000 -0400
24809 +++ linux-2.6.17.11/mm/mprotect.c       2006-09-01 16:20:29.000000000 -0400
24810 @@ -19,11 +19,18 @@
24811  #include <linux/mempolicy.h>
24812  #include <linux/personality.h>
24813  #include <linux/syscalls.h>
24814 +#include <linux/grsecurity.h>
24815 +
24816 +#ifdef CONFIG_PAX_MPROTECT
24817 +#include <linux/elf.h>
24818 +#include <linux/fs.h>
24819 +#endif
24820  
24821  #include <asm/uaccess.h>
24822  #include <asm/pgtable.h>
24823  #include <asm/cacheflush.h>
24824  #include <asm/tlbflush.h>
24825 +#include <asm/mmu_context.h>
24826  
24827  static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
24828                 unsigned long addr, unsigned long end, pgprot_t newprot)
24829 @@ -98,6 +105,94 @@ static void change_protection(struct vm_
24830         flush_tlb_range(vma, start, end);
24831  }
24832  
24833 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24834 +/* called while holding the mmap semaphor for writing */
24835 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
24836 +{
24837 +       struct vm_area_struct *vma = find_vma(mm, start);
24838 +
24839 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
24840 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
24841 +
24842 +}
24843 +
24844 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
24845 +{
24846 +       unsigned long oldlimit, newlimit = 0UL;
24847 +
24848 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
24849 +               return;
24850 +
24851 +       spin_lock(&mm->page_table_lock);
24852 +       oldlimit = mm->context.user_cs_limit;
24853 +       if ((prot & VM_EXEC) && oldlimit < end)
24854 +               /* USER_CS limit moved up */
24855 +               newlimit = end;
24856 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
24857 +               /* USER_CS limit moved down */
24858 +               newlimit = start;
24859 +
24860 +       if (newlimit) {
24861 +               mm->context.user_cs_limit = newlimit;
24862 +
24863 +#ifdef CONFIG_SMP
24864 +               wmb();
24865 +               cpus_clear(mm->context.cpu_user_cs_mask);
24866 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
24867 +#endif
24868 +
24869 +               set_user_cs(mm, smp_processor_id());
24870 +       }
24871 +       spin_unlock(&mm->page_table_lock);
24872 +       if (newlimit == end)
24873 +               establish_user_cs_limit(mm, oldlimit, end);
24874 +}
24875 +#endif
24876 +
24877 +#ifdef CONFIG_PAX_SEGMEXEC
24878 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24879 +       unsigned long start, unsigned long end, unsigned int newflags);
24880 +
24881 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24882 +       unsigned long start, unsigned long end, unsigned int newflags)
24883 +{
24884 +       if (vma->vm_flags & VM_MIRROR) {
24885 +               struct vm_area_struct * vma_m, * prev_m;
24886 +               unsigned long start_m, end_m;
24887 +               int error;
24888 +
24889 +               start_m = vma->vm_start + vma->vm_mirror;
24890 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
24891 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
24892 +                       start_m = start + vma->vm_mirror;
24893 +                       end_m = end + vma->vm_mirror;
24894 +
24895 +                       if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
24896 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
24897 +                       else
24898 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
24899 +                       if (error)
24900 +                               return error;
24901 +               } else {
24902 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
24903 +                       return -ENOMEM;
24904 +               }
24905 +       }
24906 +
24907 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
24908 +}
24909 +
24910 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24911 +       unsigned long start, unsigned long end, unsigned int newflags)
24912 +{
24913 +       struct mm_struct * mm = vma->vm_mm;
24914 +       unsigned long oldflags = vma->vm_flags;
24915 +       long nrpages = (end - start) >> PAGE_SHIFT;
24916 +       unsigned long charged = 0;
24917 +       pgprot_t newprot;
24918 +       pgoff_t pgoff;
24919 +       int error;
24920 +#else
24921  static int
24922  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24923         unsigned long start, unsigned long end, unsigned long newflags)
24924 @@ -114,6 +209,7 @@ mprotect_fixup(struct vm_area_struct *vm
24925                 *pprev = vma;
24926                 return 0;
24927         }
24928 +#endif
24929  
24930         /*
24931          * If we make a private mapping writable we increase our commit;
24932 @@ -132,7 +228,13 @@ mprotect_fixup(struct vm_area_struct *vm
24933                 }
24934         }
24935  
24936 -       newprot = protection_map[newflags & 0xf];
24937 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
24938 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
24939 +               newprot = protection_map[(newflags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
24940 +       else
24941 +#endif
24942 +
24943 +       newprot = protection_map[newflags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
24944  
24945         /*
24946          * First try to merge with previous and/or next vma.
24947 @@ -179,6 +281,69 @@ fail:
24948         return error;
24949  }
24950  
24951 +#ifdef CONFIG_PAX_MPROTECT
24952 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
24953 + * therefore we'll grant them VM_MAYWRITE once during their life.
24954 + *
24955 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
24956 + * basis because we want to allow the common case and not the special ones.
24957 + */
24958 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
24959 +{
24960 +       struct elfhdr elf_h;
24961 +       struct elf_phdr elf_p, p_dyn;
24962 +       elf_dyn dyn;
24963 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
24964 +
24965 +#ifndef CONFIG_PAX_NOELFRELOCS
24966 +       if ((vma->vm_start != start) ||
24967 +           !vma->vm_file ||
24968 +           !(vma->vm_flags & VM_MAYEXEC) ||
24969 +           (vma->vm_flags & VM_MAYNOTWRITE))
24970 +#endif
24971 +
24972 +               return;
24973 +
24974 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
24975 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
24976 +
24977 +#ifdef CONFIG_PAX_ETEXECRELOCS
24978 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
24979 +#else
24980 +           elf_h.e_type != ET_DYN ||
24981 +#endif
24982 +
24983 +           !elf_check_arch(&elf_h) ||
24984 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
24985 +           elf_h.e_phnum > j)
24986 +               return;
24987 +
24988 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
24989 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
24990 +                       return;
24991 +               if (elf_p.p_type == PT_DYNAMIC) {
24992 +                       p_dyn = elf_p;
24993 +                       j = i;
24994 +               }
24995 +       }
24996 +       if (elf_h.e_phnum <= j)
24997 +               return;
24998 +
24999 +       i = 0UL;
25000 +       do {
25001 +               if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
25002 +                       return;
25003 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
25004 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
25005 +                       gr_log_textrel(vma);
25006 +                       return;
25007 +               }
25008 +               i++;
25009 +       } while (dyn.d_tag != DT_NULL);
25010 +       return;
25011 +}
25012 +#endif
25013 +
25014  asmlinkage long
25015  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
25016  {
25017 @@ -198,6 +363,17 @@ sys_mprotect(unsigned long start, size_t
25018         end = start + len;
25019         if (end <= start)
25020                 return -ENOMEM;
25021 +
25022 +#ifdef CONFIG_PAX_SEGMEXEC
25023 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
25024 +               if (end > SEGMEXEC_TASK_SIZE)
25025 +                       return -EINVAL;
25026 +       } else
25027 +#endif
25028 +
25029 +       if (end > TASK_SIZE)
25030 +               return -EINVAL;
25031 +
25032         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
25033                 return -EINVAL;
25034  
25035 @@ -205,7 +381,7 @@ sys_mprotect(unsigned long start, size_t
25036         /*
25037          * Does the application expect PROT_READ to imply PROT_EXEC:
25038          */
25039 -       if (unlikely((prot & PROT_READ) &&
25040 +       if (unlikely((prot & (PROT_READ | PROT_WRITE)) &&
25041                         (current->personality & READ_IMPLIES_EXEC)))
25042                 prot |= PROT_EXEC;
25043  
25044 @@ -238,6 +414,16 @@ sys_mprotect(unsigned long start, size_t
25045         if (start > vma->vm_start)
25046                 prev = vma;
25047  
25048 +#ifdef CONFIG_PAX_MPROTECT
25049 +       if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
25050 +               pax_handle_maywrite(vma, start);
25051 +#endif
25052 +
25053 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
25054 +               error = -EACCES;
25055 +               goto out;
25056 +       }
25057 +
25058         for (nstart = start ; ; ) {
25059                 unsigned long newflags;
25060  
25061 @@ -251,6 +437,12 @@ sys_mprotect(unsigned long start, size_t
25062                         goto out;
25063                 }
25064  
25065 +#ifdef CONFIG_PAX_MPROTECT
25066 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
25067 +               if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
25068 +                       newflags &= ~VM_MAYWRITE;
25069 +#endif
25070 +
25071                 error = security_file_mprotect(vma, reqprot, prot);
25072                 if (error)
25073                         goto out;
25074 @@ -274,6 +466,9 @@ sys_mprotect(unsigned long start, size_t
25075                         goto out;
25076                 }
25077         }
25078 +
25079 +       track_exec_limit(current->mm, start, end, vm_flags);
25080 +
25081  out:
25082         up_write(&current->mm->mmap_sem);
25083         return error;
25084 diff -urNp linux-2.6.17.11/mm/mremap.c linux-2.6.17.11/mm/mremap.c
25085 --- linux-2.6.17.11/mm/mremap.c 2006-08-07 00:18:54.000000000 -0400
25086 +++ linux-2.6.17.11/mm/mremap.c 2006-09-01 16:20:29.000000000 -0400
25087 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
25088                 pte = ptep_clear_flush(vma, old_addr, old_pte);
25089                 /* ZERO_PAGE can be dependant on virtual addr */
25090                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
25091 +
25092 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
25093 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
25094 +                       pte_exprotect(pte);
25095 +#endif
25096 +
25097                 set_pte_at(mm, new_addr, new_pte, pte);
25098         }
25099  
25100 @@ -253,6 +259,7 @@ unsigned long do_mremap(unsigned long ad
25101         struct vm_area_struct *vma;
25102         unsigned long ret = -EINVAL;
25103         unsigned long charged = 0;
25104 +       unsigned long task_size = TASK_SIZE;
25105  
25106         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
25107                 goto out;
25108 @@ -271,6 +278,15 @@ unsigned long do_mremap(unsigned long ad
25109         if (!new_len)
25110                 goto out;
25111  
25112 +#ifdef CONFIG_PAX_SEGMEXEC
25113 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
25114 +               task_size = SEGMEXEC_TASK_SIZE;
25115 +#endif
25116 +
25117 +       if (new_len > task_size || addr > task_size-new_len ||
25118 +           old_len > task_size || addr > task_size-old_len)
25119 +               goto out;
25120 +
25121         /* new_addr is only valid if MREMAP_FIXED is specified */
25122         if (flags & MREMAP_FIXED) {
25123                 if (new_addr & ~PAGE_MASK)
25124 @@ -278,16 +294,13 @@ unsigned long do_mremap(unsigned long ad
25125                 if (!(flags & MREMAP_MAYMOVE))
25126                         goto out;
25127  
25128 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
25129 +               if (new_addr > task_size - new_len)
25130                         goto out;
25131  
25132                 /* Check if the location we're moving into overlaps the
25133                  * old location at all, and fail if it does.
25134                  */
25135 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
25136 -                       goto out;
25137 -
25138 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
25139 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
25140                         goto out;
25141  
25142                 ret = do_munmap(mm, new_addr, new_len);
25143 @@ -321,6 +334,14 @@ unsigned long do_mremap(unsigned long ad
25144                 ret = -EINVAL;
25145                 goto out;
25146         }
25147 +
25148 +#ifdef CONFIG_PAX_SEGMEXEC
25149 +       if (vma->vm_flags & VM_MIRROR) {
25150 +               ret = -EINVAL;
25151 +               goto out;
25152 +       }
25153 +#endif
25154 +
25155         /* We can't remap across vm area boundaries */
25156         if (old_len > vma->vm_end - addr)
25157                 goto out;
25158 @@ -354,7 +375,7 @@ unsigned long do_mremap(unsigned long ad
25159         if (old_len == vma->vm_end - addr &&
25160             !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
25161             (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
25162 -               unsigned long max_addr = TASK_SIZE;
25163 +               unsigned long max_addr = task_size;
25164                 if (vma->vm_next)
25165                         max_addr = vma->vm_next->vm_start;
25166                 /* can we just expand the current mapping? */
25167 @@ -372,6 +393,7 @@ unsigned long do_mremap(unsigned long ad
25168                                                    addr + new_len);
25169                         }
25170                         ret = addr;
25171 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
25172                         goto out;
25173                 }
25174         }
25175 @@ -382,8 +404,8 @@ unsigned long do_mremap(unsigned long ad
25176          */
25177         ret = -ENOMEM;
25178         if (flags & MREMAP_MAYMOVE) {
25179 +               unsigned long map_flags = 0;
25180                 if (!(flags & MREMAP_FIXED)) {
25181 -                       unsigned long map_flags = 0;
25182                         if (vma->vm_flags & VM_MAYSHARE)
25183                                 map_flags |= MAP_SHARED;
25184  
25185 @@ -393,7 +415,12 @@ unsigned long do_mremap(unsigned long ad
25186                         if (new_addr & ~PAGE_MASK)
25187                                 goto out;
25188                 }
25189 +               map_flags = vma->vm_flags;
25190                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
25191 +               if (!(ret & ~PAGE_MASK)) {
25192 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
25193 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
25194 +               }
25195         }
25196  out:
25197         if (ret & ~PAGE_MASK)
25198 diff -urNp linux-2.6.17.11/mm/page_alloc.c linux-2.6.17.11/mm/page_alloc.c
25199 --- linux-2.6.17.11/mm/page_alloc.c     2006-08-07 00:18:54.000000000 -0400
25200 +++ linux-2.6.17.11/mm/page_alloc.c     2006-09-01 16:20:29.000000000 -0400
25201 @@ -334,7 +334,7 @@ static inline int page_is_buddy(struct p
25202  static inline void __free_one_page(struct page *page,
25203                 struct zone *zone, unsigned int order)
25204  {
25205 -       unsigned long page_idx;
25206 +       unsigned long page_idx, index;
25207         int order_size = 1 << order;
25208  
25209         if (unlikely(PageCompound(page)))
25210 @@ -345,6 +345,11 @@ static inline void __free_one_page(struc
25211         BUG_ON(page_idx & (order_size - 1));
25212         BUG_ON(bad_range(zone, page));
25213  
25214 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
25215 +       for (index = order_size; index; --index)
25216 +               clear_highpage(page + index - 1);
25217 +#endif
25218 +
25219         zone->free_pages += order_size;
25220         while (order < MAX_ORDER-1) {
25221                 unsigned long combined_idx;
25222 diff -urNp linux-2.6.17.11/mm/rmap.c linux-2.6.17.11/mm/rmap.c
25223 --- linux-2.6.17.11/mm/rmap.c   2006-08-07 00:18:54.000000000 -0400
25224 +++ linux-2.6.17.11/mm/rmap.c   2006-09-01 16:20:29.000000000 -0400
25225 @@ -107,6 +107,19 @@ int anon_vma_prepare(struct vm_area_stru
25226                         list_add(&vma->anon_vma_node, &anon_vma->head);
25227                         allocated = NULL;
25228                 }
25229 +
25230 +#ifdef CONFIG_PAX_SEGMEXEC
25231 +               if (vma->vm_flags & VM_MIRROR) {
25232 +                       struct vm_area_struct *vma_m;
25233 +
25234 +                       vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
25235 +                       BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
25236 +                       BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
25237 +                       vma_m->anon_vma = anon_vma;
25238 +                       __anon_vma_link(vma_m);
25239 +               }
25240 +#endif
25241 +
25242                 spin_unlock(&mm->page_table_lock);
25243  
25244                 if (locked)
25245 diff -urNp linux-2.6.17.11/mm/shmem.c linux-2.6.17.11/mm/shmem.c
25246 --- linux-2.6.17.11/mm/shmem.c  2006-08-07 00:18:54.000000000 -0400
25247 +++ linux-2.6.17.11/mm/shmem.c  2006-09-01 16:20:29.000000000 -0400
25248 @@ -2244,7 +2244,7 @@ static struct file_system_type tmpfs_fs_
25249         .get_sb         = shmem_get_sb,
25250         .kill_sb        = kill_litter_super,
25251  };
25252 -static struct vfsmount *shm_mnt;
25253 +struct vfsmount *shm_mnt;
25254  
25255  static int __init init_tmpfs(void)
25256  {
25257 diff -urNp linux-2.6.17.11/mm/slab.c linux-2.6.17.11/mm/slab.c
25258 --- linux-2.6.17.11/mm/slab.c   2006-08-07 00:18:54.000000000 -0400
25259 +++ linux-2.6.17.11/mm/slab.c   2006-09-01 16:20:29.000000000 -0400
25260 @@ -1534,6 +1534,11 @@ static void store_stackinfo(struct kmem_
25261  
25262                 while (!kstack_end(sptr)) {
25263                         svalue = *sptr++;
25264 +
25265 +#ifdef CONFIG_PAX_KERNEXEC
25266 +                       svalue += __KERNEL_TEXT_OFFSET;
25267 +#endif
25268 +
25269                         if (kernel_text_address(svalue)) {
25270                                 *addr++ = svalue;
25271                                 size -= sizeof(unsigned long);
25272 diff -urNp linux-2.6.17.11/mm/tiny-shmem.c linux-2.6.17.11/mm/tiny-shmem.c
25273 --- linux-2.6.17.11/mm/tiny-shmem.c     2006-08-07 00:18:54.000000000 -0400
25274 +++ linux-2.6.17.11/mm/tiny-shmem.c     2006-09-01 16:20:29.000000000 -0400
25275 @@ -27,7 +27,7 @@ static struct file_system_type tmpfs_fs_
25276         .kill_sb        = kill_litter_super,
25277  };
25278  
25279 -static struct vfsmount *shm_mnt;
25280 +struct vfsmount *shm_mnt;
25281  
25282  static int __init init_tmpfs(void)
25283  {
25284 diff -urNp linux-2.6.17.11/mm/vmalloc.c linux-2.6.17.11/mm/vmalloc.c
25285 --- linux-2.6.17.11/mm/vmalloc.c        2006-08-07 00:18:54.000000000 -0400
25286 +++ linux-2.6.17.11/mm/vmalloc.c        2006-09-01 16:20:29.000000000 -0400
25287 @@ -193,6 +193,8 @@ struct vm_struct *__get_vm_area_node(uns
25288  
25289         write_lock(&vmlist_lock);
25290         for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
25291 +               if (addr > end - size)
25292 +                       goto out;
25293                 if ((unsigned long)tmp->addr < addr) {
25294                         if((unsigned long)tmp->addr + tmp->size >= addr)
25295                                 addr = ALIGN(tmp->size + 
25296 @@ -204,8 +206,6 @@ struct vm_struct *__get_vm_area_node(uns
25297                 if (size + addr <= (unsigned long)tmp->addr)
25298                         goto found;
25299                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
25300 -               if (addr > end - size)
25301 -                       goto out;
25302         }
25303  
25304  found:
25305 diff -urNp linux-2.6.17.11/net/ipv4/inet_connection_sock.c linux-2.6.17.11/net/ipv4/inet_connection_sock.c
25306 --- linux-2.6.17.11/net/ipv4/inet_connection_sock.c     2006-08-07 00:18:54.000000000 -0400
25307 +++ linux-2.6.17.11/net/ipv4/inet_connection_sock.c     2006-09-01 16:20:29.000000000 -0400
25308 @@ -16,6 +16,7 @@
25309  #include <linux/config.h>
25310  #include <linux/module.h>
25311  #include <linux/jhash.h>
25312 +#include <linux/grsecurity.h>
25313  
25314  #include <net/inet_connection_sock.h>
25315  #include <net/inet_hashtables.h>
25316 diff -urNp linux-2.6.17.11/net/ipv4/inet_hashtables.c linux-2.6.17.11/net/ipv4/inet_hashtables.c
25317 --- linux-2.6.17.11/net/ipv4/inet_hashtables.c  2006-08-07 00:18:54.000000000 -0400
25318 +++ linux-2.6.17.11/net/ipv4/inet_hashtables.c  2006-09-01 16:20:29.000000000 -0400
25319 @@ -19,11 +19,14 @@
25320  #include <linux/sched.h>
25321  #include <linux/slab.h>
25322  #include <linux/wait.h>
25323 +#include <linux/grsecurity.h>
25324  
25325  #include <net/inet_connection_sock.h>
25326  #include <net/inet_hashtables.h>
25327  #include <net/ip.h>
25328  
25329 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
25330 +
25331  /*
25332   * Allocate and initialize a new local port bind bucket.
25333   * The bindhash mutex for snum's hash chain must be held here.
25334 @@ -309,6 +312,8 @@ ok:
25335                 }
25336                 spin_unlock(&head->lock);
25337  
25338 +               gr_update_task_in_ip_table(current, inet_sk(sk));
25339 +
25340                 if (tw) {
25341                         inet_twsk_deschedule(tw, death_row);
25342                         inet_twsk_put(tw);
25343 diff -urNp linux-2.6.17.11/net/ipv4/netfilter/ipt_stealth.c linux-2.6.17.11/net/ipv4/netfilter/ipt_stealth.c
25344 --- linux-2.6.17.11/net/ipv4/netfilter/ipt_stealth.c    1969-12-31 19:00:00.000000000 -0500
25345 +++ linux-2.6.17.11/net/ipv4/netfilter/ipt_stealth.c    2006-09-01 16:20:29.000000000 -0400
25346 @@ -0,0 +1,116 @@
25347 +/* Kernel module to add stealth support.
25348 + *
25349 + * Copyright (C) 2002,2005 Brad Spengler  <spender@grsecurity.net>
25350 + *
25351 + */
25352 +
25353 +#include <linux/kernel.h>
25354 +#include <linux/module.h>
25355 +#include <linux/skbuff.h>
25356 +#include <linux/net.h>
25357 +#include <linux/sched.h>
25358 +#include <linux/inet.h>
25359 +#include <linux/stddef.h>
25360 +
25361 +#include <net/ip.h>
25362 +#include <net/sock.h>
25363 +#include <net/tcp.h>
25364 +#include <net/udp.h>
25365 +#include <net/route.h>
25366 +#include <net/inet_common.h>
25367 +
25368 +#include <linux/netfilter_ipv4/ip_tables.h>
25369 +
25370 +MODULE_LICENSE("GPL");
25371 +
25372 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
25373 +
25374 +static int
25375 +match(const struct sk_buff *skb,
25376 +      const struct net_device *in,
25377 +      const struct net_device *out,
25378 +      const struct xt_match *match,
25379 +      const void *matchinfo,
25380 +      int offset,
25381 +      unsigned int protoff,
25382 +      int *hotdrop)
25383 +{
25384 +       struct iphdr *ip = skb->nh.iph;
25385 +       struct tcphdr th;
25386 +       struct udphdr uh;
25387 +       struct sock *sk = NULL;
25388 +
25389 +       if (!ip || offset) return 0;
25390 +
25391 +       switch(ip->protocol) {
25392 +       case IPPROTO_TCP:
25393 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
25394 +                       *hotdrop = 1;
25395 +                       return 0;
25396 +               }
25397 +               if (!(th.syn && !th.ack)) return 0;
25398 +               sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);        
25399 +               break;
25400 +       case IPPROTO_UDP:
25401 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
25402 +                       *hotdrop = 1;
25403 +                       return 0;
25404 +               }
25405 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
25406 +               break;
25407 +       default:
25408 +               return 0;
25409 +       }
25410 +
25411 +       if(!sk) // port is being listened on, match this
25412 +               return 1;
25413 +       else {
25414 +               sock_put(sk);
25415 +               return 0;
25416 +       }
25417 +}
25418 +
25419 +/* Called when user tries to insert an entry of this type. */
25420 +static int
25421 +checkentry(const char *tablename,
25422 +           const void *nip,
25423 +          const struct xt_match *match,
25424 +           void *matchinfo,
25425 +           unsigned int matchsize,
25426 +           unsigned int hook_mask)
25427 +{
25428 +       const struct ipt_ip *ip = (const struct ipt_ip *)nip;
25429 +        if (matchsize != IPT_ALIGN(0))
25430 +                return 0;
25431 +
25432 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
25433 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
25434 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
25435 +                       return 1;
25436 +
25437 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
25438 +
25439 +        return 0;
25440 +}
25441 +
25442 +
25443 +static struct ipt_match stealth_match = {
25444 +       .name = "stealth",
25445 +       .match = match,
25446 +       .checkentry = checkentry,
25447 +       .destroy = NULL,
25448 +       .me = THIS_MODULE
25449 +};
25450 +
25451 +static int __init init(void)
25452 +{
25453 +       return ipt_register_match(&stealth_match);
25454 +}
25455 +
25456 +static void __exit fini(void)
25457 +{
25458 +       ipt_unregister_match(&stealth_match);
25459 +}
25460 +
25461 +module_init(init);
25462 +module_exit(fini);
25463 diff -urNp linux-2.6.17.11/net/ipv4/netfilter/Kconfig linux-2.6.17.11/net/ipv4/netfilter/Kconfig
25464 --- linux-2.6.17.11/net/ipv4/netfilter/Kconfig  2006-08-07 00:18:54.000000000 -0400
25465 +++ linux-2.6.17.11/net/ipv4/netfilter/Kconfig  2006-09-01 16:20:29.000000000 -0400
25466 @@ -314,6 +314,21 @@ config IP_NF_MATCH_HASHLIMIT
25467           destination IP' or `500pps from any given source IP'  with a single
25468           IPtables rule.
25469  
25470 +config IP_NF_MATCH_STEALTH
25471 +       tristate "stealth match support"
25472 +       depends on IP_NF_IPTABLES
25473 +       help
25474 +         Enabling this option will drop all syn packets coming to unserved tcp
25475 +         ports as well as all packets coming to unserved udp ports.  If you
25476 +         are using your system to route any type of packets (ie. via NAT)
25477 +         you should put this module at the end of your ruleset, since it will
25478 +         drop packets that aren't going to ports that are listening on your
25479 +         machine itself, it doesn't take into account that the packet might be
25480 +         destined for someone on your internal network if you're using NAT for
25481 +         instance.
25482 +
25483 +         To compile it as a module, choose M here.  If unsure, say N.
25484 +
25485  # `filter', generic and specific targets
25486  config IP_NF_FILTER
25487         tristate "Packet filtering"
25488 @@ -829,4 +844,3 @@ config IP_NF_ARP_MANGLE
25489           Documentation/modules.txt.  If unsure, say `N'.
25490  
25491  endmenu
25492 -
25493 diff -urNp linux-2.6.17.11/net/ipv4/netfilter/Makefile linux-2.6.17.11/net/ipv4/netfilter/Makefile
25494 --- linux-2.6.17.11/net/ipv4/netfilter/Makefile 2006-08-07 00:18:54.000000000 -0400
25495 +++ linux-2.6.17.11/net/ipv4/netfilter/Makefile 2006-09-01 16:20:29.000000000 -0400
25496 @@ -80,6 +80,7 @@ obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_ds
25497  obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
25498  obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
25499  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
25500 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
25501  
25502  # targets
25503  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
25504 diff -urNp linux-2.6.17.11/net/ipv4/tcp_ipv4.c linux-2.6.17.11/net/ipv4/tcp_ipv4.c
25505 --- linux-2.6.17.11/net/ipv4/tcp_ipv4.c 2006-08-07 00:18:54.000000000 -0400
25506 +++ linux-2.6.17.11/net/ipv4/tcp_ipv4.c 2006-09-01 16:20:29.000000000 -0400
25507 @@ -62,6 +62,7 @@
25508  #include <linux/jhash.h>
25509  #include <linux/init.h>
25510  #include <linux/times.h>
25511 +#include <linux/grsecurity.h>
25512  
25513  #include <net/icmp.h>
25514  #include <net/inet_hashtables.h>
25515 diff -urNp linux-2.6.17.11/net/ipv4/udp.c linux-2.6.17.11/net/ipv4/udp.c
25516 --- linux-2.6.17.11/net/ipv4/udp.c      2006-08-07 00:18:54.000000000 -0400
25517 +++ linux-2.6.17.11/net/ipv4/udp.c      2006-09-01 16:20:29.000000000 -0400
25518 @@ -102,6 +102,7 @@
25519  #include <linux/skbuff.h>
25520  #include <linux/proc_fs.h>
25521  #include <linux/seq_file.h>
25522 +#include <linux/grsecurity.h>
25523  #include <net/sock.h>
25524  #include <net/udp.h>
25525  #include <net/icmp.h>
25526 @@ -110,6 +111,12 @@
25527  #include <net/checksum.h>
25528  #include <net/xfrm.h>
25529  
25530 +extern int gr_search_udp_recvmsg(const struct sock *sk,
25531 +                                const struct sk_buff *skb);
25532 +extern int gr_search_udp_sendmsg(const struct sock *sk,
25533 +                                const struct sockaddr_in *addr);
25534 +
25535 +
25536  /*
25537   *     Snmp MIB for the UDP layer
25538   */
25539 @@ -266,8 +273,7 @@ static struct sock *udp_v4_lookup_longwa
25540         return result;
25541  }
25542  
25543 -static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
25544 -                                            u32 daddr, u16 dport, int dif)
25545 +struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
25546  {
25547         struct sock *sk;
25548  
25549 @@ -542,9 +548,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
25550                 dport = usin->sin_port;
25551                 if (dport == 0)
25552                         return -EINVAL;
25553 +
25554 +               if (!gr_search_udp_sendmsg(sk, usin))
25555 +                       return -EPERM;
25556         } else {
25557                 if (sk->sk_state != TCP_ESTABLISHED)
25558                         return -EDESTADDRREQ;
25559 +
25560 +               if (!gr_search_udp_sendmsg(sk, NULL))
25561 +                       return -EPERM;
25562 +
25563                 daddr = inet->daddr;
25564                 dport = inet->dport;
25565                 /* Open fast path for connected socket.
25566 @@ -798,6 +811,11 @@ try_again:
25567         if (!skb)
25568                 goto out;
25569    
25570 +       if (!gr_search_udp_recvmsg(sk, skb)) {
25571 +               err = -EPERM;
25572 +               goto out_free;
25573 +       }
25574 +
25575         copied = skb->len - sizeof(struct udphdr);
25576         if (copied > len) {
25577                 copied = len;
25578 diff -urNp linux-2.6.17.11/net/socket.c linux-2.6.17.11/net/socket.c
25579 --- linux-2.6.17.11/net/socket.c        2006-08-07 00:18:54.000000000 -0400
25580 +++ linux-2.6.17.11/net/socket.c        2006-09-01 16:20:29.000000000 -0400
25581 @@ -86,6 +86,7 @@
25582  #include <linux/kmod.h>
25583  #include <linux/audit.h>
25584  #include <linux/wireless.h>
25585 +#include <linux/in.h>
25586  
25587  #include <asm/uaccess.h>
25588  #include <asm/unistd.h>
25589 @@ -96,6 +97,21 @@
25590  #include <linux/netfilter.h>
25591  #include <linux/vs_socket.h>
25592  
25593 +extern void gr_attach_curr_ip(const struct sock *sk);
25594 +extern int gr_handle_sock_all(const int family, const int type,
25595 +                             const int protocol);
25596 +extern int gr_handle_sock_server(const struct sockaddr *sck);
25597 +extern int gr_handle_sock_server_other(const struct socket *sck);
25598 +extern int gr_handle_sock_client(const struct sockaddr *sck);
25599 +extern int gr_search_connect(const struct socket * sock,
25600 +                            const struct sockaddr_in * addr);
25601 +extern int gr_search_bind(const struct socket * sock,
25602 +                          const struct sockaddr_in * addr);
25603 +extern int gr_search_listen(const struct socket * sock);
25604 +extern int gr_search_accept(const struct socket * sock);
25605 +extern int gr_search_socket(const int domain, const int type,
25606 +                           const int protocol);
25607 +
25608  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
25609  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
25610                          size_t size, loff_t pos);
25611 @@ -342,7 +358,7 @@ static struct super_block *sockfs_get_sb
25612         return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
25613  }
25614  
25615 -static struct vfsmount *sock_mnt __read_mostly;
25616 +struct vfsmount *sock_mnt __read_mostly;
25617  
25618  static struct file_system_type sock_fs_type = {
25619         .name =         "sockfs",
25620 @@ -1269,6 +1285,16 @@ asmlinkage long sys_socket(int family, i
25621         int retval;
25622         struct socket *sock;
25623  
25624 +       if(!gr_search_socket(family, type, protocol)) {
25625 +               retval = -EACCES;
25626 +               goto out;
25627 +       }
25628 +
25629 +       if (gr_handle_sock_all(family, type, protocol)) {
25630 +               retval = -EACCES;
25631 +               goto out;
25632 +       }
25633 +
25634         retval = sock_create(family, type, protocol, &sock);
25635         if (retval < 0)
25636                 goto out;
25637 @@ -1367,16 +1393,25 @@ asmlinkage long sys_bind(int fd, struct 
25638  {
25639         struct socket *sock;
25640         char address[MAX_SOCK_ADDR];
25641 +       struct sockaddr *sck;
25642         int err, fput_needed;
25643  
25644         if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
25645         {
25646                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
25647 +                       sck = (struct sockaddr *)address;
25648 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck) ||
25649 +                           gr_handle_sock_server(sck)) {
25650 +                               err = -EACCES;
25651 +                               goto error;
25652 +                       }
25653 +
25654                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
25655                         if (!err)
25656                                 err = sock->ops->bind(sock,
25657                                         (struct sockaddr *)address, addrlen);
25658                 }
25659 +error:
25660                 fput_light(sock->file, fput_needed);
25661         }                       
25662         return err;
25663 @@ -1400,10 +1435,17 @@ asmlinkage long sys_listen(int fd, int b
25664                 if ((unsigned) backlog > sysctl_somaxconn)
25665                         backlog = sysctl_somaxconn;
25666  
25667 +               if (gr_handle_sock_server_other(sock) ||
25668 +                   !gr_search_listen(sock)) {
25669 +                       err = -EPERM;
25670 +                       goto error;
25671 +               }
25672 +
25673                 err = security_socket_listen(sock, backlog);
25674                 if (!err)
25675                         err = sock->ops->listen(sock, backlog);
25676  
25677 +error:
25678                 fput_light(sock->file, fput_needed);
25679         }
25680         return err;
25681 @@ -1440,6 +1482,13 @@ asmlinkage long sys_accept(int fd, struc
25682         newsock->type = sock->type;
25683         newsock->ops = sock->ops;
25684  
25685 +       if (gr_handle_sock_server_other(sock) ||
25686 +           !gr_search_accept(sock)) {
25687 +               err = -EPERM;
25688 +               sock_release(newsock);
25689 +               goto out_put;
25690 +       }
25691 +
25692         /*
25693          * We don't need try_module_get here, as the listening socket (sock)
25694          * has the protocol module (sock->ops->owner) held.
25695 @@ -1481,6 +1530,7 @@ asmlinkage long sys_accept(int fd, struc
25696         err = newfd;
25697  
25698         security_socket_post_accept(sock, newsock);
25699 +       gr_attach_curr_ip(newsock->sk);
25700  
25701  out_put:
25702         fput_light(sock->file, fput_needed);
25703 @@ -1509,6 +1559,7 @@ asmlinkage long sys_connect(int fd, stru
25704  {
25705         struct socket *sock;
25706         char address[MAX_SOCK_ADDR];
25707 +       struct sockaddr *sck;
25708         int err, fput_needed;
25709  
25710         sock = sockfd_lookup_light(fd, &err, &fput_needed);
25711 @@ -1518,6 +1569,13 @@ asmlinkage long sys_connect(int fd, stru
25712         if (err < 0)
25713                 goto out_put;
25714  
25715 +       sck = (struct sockaddr *)address;
25716 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
25717 +           gr_handle_sock_client(sck)) {
25718 +               err = -EACCES;
25719 +               goto out_put;
25720 +       }
25721 +
25722         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
25723         if (err)
25724                 goto out_put;
25725 @@ -1772,6 +1830,7 @@ asmlinkage long sys_shutdown(int fd, int
25726                         err = sock->ops->shutdown(sock, how);
25727                 fput_light(sock->file, fput_needed);
25728         }
25729 +
25730         return err;
25731  }
25732  
25733 diff -urNp linux-2.6.17.11/net/unix/af_unix.c linux-2.6.17.11/net/unix/af_unix.c
25734 --- linux-2.6.17.11/net/unix/af_unix.c  2006-08-07 00:18:54.000000000 -0400
25735 +++ linux-2.6.17.11/net/unix/af_unix.c  2006-09-01 16:20:29.000000000 -0400
25736 @@ -120,6 +120,7 @@
25737  #include <linux/vs_context.h>
25738  #include <linux/vs_network.h>
25739  #include <linux/vs_limit.h>
25740 +#include <linux/grsecurity.h>
25741  
25742  int sysctl_unix_max_dgram_qlen = 10;
25743  
25744 @@ -685,6 +686,11 @@ static struct sock *unix_find_other(stru
25745                 if (err)
25746                         goto put_fail;
25747  
25748 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
25749 +                       err = -EACCES;
25750 +                       goto put_fail;
25751 +               }
25752 +
25753                 err = -ECONNREFUSED;
25754                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
25755                         goto put_fail;
25756 @@ -708,6 +714,13 @@ static struct sock *unix_find_other(stru
25757                 if (u) {
25758                         struct dentry *dentry;
25759                         dentry = unix_sk(u)->dentry;
25760 +
25761 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
25762 +                               err = -EPERM;
25763 +                               sock_put(u);
25764 +                               goto fail;
25765 +                       }
25766 +
25767                         if (dentry)
25768                                 touch_atime(unix_sk(u)->mnt, dentry);
25769                 } else
25770 @@ -786,9 +799,18 @@ static int unix_bind(struct socket *sock
25771                  */
25772                 mode = S_IFSOCK |
25773                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
25774 +
25775 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
25776 +                       err = -EACCES;
25777 +                       goto out_mknod_dput;
25778 +               }
25779 +
25780                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
25781                 if (err)
25782                         goto out_mknod_dput;
25783 +
25784 +               gr_handle_create(dentry, nd.mnt);
25785 +
25786                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
25787                 dput(nd.dentry);
25788                 nd.dentry = dentry;
25789 @@ -806,6 +828,10 @@ static int unix_bind(struct socket *sock
25790                         goto out_unlock;
25791                 }
25792  
25793 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25794 +               sk->sk_peercred.pid = current->pid;
25795 +#endif
25796 +
25797                 list = &unix_socket_table[addr->hash];
25798         } else {
25799                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
25800 diff -urNp linux-2.6.17.11/security/commoncap.c linux-2.6.17.11/security/commoncap.c
25801 --- linux-2.6.17.11/security/commoncap.c        2006-08-07 00:18:54.000000000 -0400
25802 +++ linux-2.6.17.11/security/commoncap.c        2006-09-01 16:20:29.000000000 -0400
25803 @@ -24,6 +24,7 @@
25804  #include <linux/ptrace.h>
25805  #include <linux/xattr.h>
25806  #include <linux/hugetlb.h>
25807 +#include <linux/grsecurity.h>
25808  
25809  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
25810  {
25811 @@ -45,7 +46,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
25812  int cap_capable (struct task_struct *tsk, int cap)
25813  {
25814         /* Derived from include/linux/sched.h:capable. */
25815 -       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
25816 +       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
25817 +               return 0;
25818 +       return -EPERM;
25819 +}
25820 +
25821 +int cap_capable_nolog (struct task_struct *tsk, int cap)
25822 +{
25823 +       /* Derived from include/linux/sched.h:capable. */
25824 +       if (cap_raised (tsk->cap_effective, cap))
25825                 return 0;
25826         return -EPERM;
25827  }
25828 @@ -165,8 +174,11 @@ void cap_bprm_apply_creds (struct linux_
25829                 }
25830         }
25831  
25832 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
25833 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
25834 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
25835 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
25836 +
25837 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
25838 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
25839  
25840         /* For init, we want to retain the capabilities set
25841          * in the init_task struct. Thus we skip the usual
25842 @@ -177,6 +189,8 @@ void cap_bprm_apply_creds (struct linux_
25843                     cap_intersect (new_permitted, bprm->cap_effective);
25844         }
25845  
25846 +       gr_handle_chroot_caps(current);
25847 +
25848         /* AUD: Audit candidate if current->cap_effective is set */
25849  
25850         current->keep_capabilities = 0;
25851 @@ -323,12 +337,13 @@ int cap_vm_enough_memory(long pages)
25852  {
25853         int cap_sys_admin = 0;
25854  
25855 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
25856 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
25857                 cap_sys_admin = 1;
25858         return __vm_enough_memory(pages, cap_sys_admin);
25859  }
25860  
25861  EXPORT_SYMBOL(cap_capable);
25862 +EXPORT_SYMBOL(cap_capable_nolog);
25863  EXPORT_SYMBOL(cap_settime);
25864  EXPORT_SYMBOL(cap_ptrace);
25865  EXPORT_SYMBOL(cap_capget);
25866 diff -urNp linux-2.6.17.11/security/dummy.c linux-2.6.17.11/security/dummy.c
25867 --- linux-2.6.17.11/security/dummy.c    2006-08-07 00:18:54.000000000 -0400
25868 +++ linux-2.6.17.11/security/dummy.c    2006-09-01 16:20:29.000000000 -0400
25869 @@ -29,6 +29,7 @@
25870  #include <linux/hugetlb.h>
25871  #include <linux/ptrace.h>
25872  #include <linux/file.h>
25873 +#include <linux/grsecurity.h>
25874  
25875  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
25876  {
25877 @@ -139,8 +140,11 @@ static void dummy_bprm_apply_creds (stru
25878                 }
25879         }
25880  
25881 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
25882 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
25883 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
25884 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
25885 +
25886 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
25887 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
25888  
25889         dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
25890  }
25891 diff -urNp linux-2.6.17.11/security/Kconfig linux-2.6.17.11/security/Kconfig
25892 --- linux-2.6.17.11/security/Kconfig    2006-08-07 00:18:54.000000000 -0400
25893 +++ linux-2.6.17.11/security/Kconfig    2006-09-01 16:20:29.000000000 -0400
25894 @@ -4,6 +4,453 @@
25895  
25896  menu "Security options"
25897  
25898 +menu "PaX"
25899 +
25900 +config PAX
25901 +       bool "Enable various PaX features"
25902 +       depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
25903 +       help
25904 +         This allows you to enable various PaX features.  PaX adds
25905 +         intrusion prevention mechanisms to the kernel that reduce
25906 +         the risks posed by exploitable memory corruption bugs.
25907 +
25908 +menu "PaX Control"
25909 +       depends on PAX
25910 +
25911 +config PAX_SOFTMODE
25912 +       bool 'Support soft mode'
25913 +       help
25914 +         Enabling this option will allow you to run PaX in soft mode, that
25915 +         is, PaX features will not be enforced by default, only on executables
25916 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
25917 +         is the only way to mark executables for soft mode use.
25918 +
25919 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
25920 +         line option on boot.  Furthermore you can control various PaX features
25921 +         at runtime via the entries in /proc/sys/kernel/pax.
25922 +
25923 +config PAX_EI_PAX
25924 +       bool 'Use legacy ELF header marking'
25925 +       help
25926 +         Enabling this option will allow you to control PaX features on
25927 +         a per executable basis via the 'chpax' utility available at
25928 +         http://pax.grsecurity.net/.  The control flags will be read from
25929 +         an otherwise reserved part of the ELF header.  This marking has
25930 +         numerous drawbacks (no support for soft-mode, toolchain does not
25931 +         know about the non-standard use of the ELF header) therefore it
25932 +         has been deprecated in favour of PT_PAX_FLAGS support.
25933 +
25934 +         If you have applications not marked by the PT_PAX_FLAGS ELF
25935 +         program header then you MUST enable this option otherwise they
25936 +         will not get any protection.
25937 +
25938 +         Note that if you enable PT_PAX_FLAGS marking support as well,
25939 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
25940 +
25941 +config PAX_PT_PAX_FLAGS
25942 +       bool 'Use ELF program header marking'
25943 +       help
25944 +         Enabling this option will allow you to control PaX features on
25945 +         a per executable basis via the 'paxctl' utility available at
25946 +         http://pax.grsecurity.net/.  The control flags will be read from
25947 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
25948 +         has the benefits of supporting both soft mode and being fully
25949 +         integrated into the toolchain (the binutils patch is available
25950 +         from http://pax.grsecurity.net).
25951 +
25952 +         If you have applications not marked by the PT_PAX_FLAGS ELF
25953 +         program header then you MUST enable the EI_PAX marking support
25954 +         otherwise they will not get any protection.
25955 +
25956 +         Note that if you enable the legacy EI_PAX marking support as well,
25957 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
25958 +
25959 +choice
25960 +       prompt 'MAC system integration'
25961 +       default PAX_HAVE_ACL_FLAGS
25962 +       help
25963 +         Mandatory Access Control systems have the option of controlling
25964 +         PaX flags on a per executable basis, choose the method supported
25965 +         by your particular system.
25966 +
25967 +         - "none": if your MAC system does not interact with PaX,
25968 +         - "direct": if your MAC system defines pax_set_flags() itself,
25969 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
25970 +
25971 +         NOTE: this option is for developers/integrators only.
25972 +
25973 +config PAX_NO_ACL_FLAGS
25974 +       bool 'none'
25975 +
25976 +config PAX_HAVE_ACL_FLAGS
25977 +       bool 'direct'
25978 +
25979 +config PAX_HOOK_ACL_FLAGS
25980 +       bool 'hook'
25981 +endchoice
25982 +
25983 +endmenu
25984 +
25985 +menu "Non-executable pages"
25986 +       depends on PAX
25987 +
25988 +config PAX_NOEXEC
25989 +       bool "Enforce non-executable pages"
25990 +       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)
25991 +       help
25992 +         By design some architectures do not allow for protecting memory
25993 +         pages against execution or even if they do, Linux does not make
25994 +         use of this feature.  In practice this means that if a page is
25995 +         readable (such as the stack or heap) it is also executable.
25996 +
25997 +         There is a well known exploit technique that makes use of this
25998 +         fact and a common programming mistake where an attacker can
25999 +         introduce code of his choice somewhere in the attacked program's
26000 +         memory (typically the stack or the heap) and then execute it.
26001 +
26002 +         If the attacked program was running with different (typically
26003 +         higher) privileges than that of the attacker, then he can elevate
26004 +         his own privilege level (e.g. get a root shell, write to files for
26005 +         which he does not have write access to, etc).
26006 +
26007 +         Enabling this option will let you choose from various features
26008 +         that prevent the injection and execution of 'foreign' code in
26009 +         a program.
26010 +
26011 +         This will also break programs that rely on the old behaviour and
26012 +         expect that dynamically allocated memory via the malloc() family
26013 +         of functions is executable (which it is not).  Notable examples
26014 +         are the XFree86 4.x server, the java runtime and wine.
26015 +
26016 +config PAX_PAGEEXEC
26017 +       bool "Paging based non-executable pages"
26018 +       depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
26019 +       select PAX_NOVSYSCALL if X86_32
26020 +       help
26021 +         This implementation is based on the paging feature of the CPU.
26022 +         On i386 and ppc there is a variable but usually low performance
26023 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
26024 +         and x86_64 there is no performance impact.
26025 +
26026 +config PAX_SEGMEXEC
26027 +       bool "Segmentation based non-executable pages"
26028 +       depends on PAX_NOEXEC && X86_32
26029 +       select PAX_NOVSYSCALL
26030 +       help
26031 +         This implementation is based on the segmentation feature of the
26032 +         CPU and has little performance impact, however applications will
26033 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
26034 +
26035 +choice
26036 +       prompt "Default non-executable page method"
26037 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
26038 +       default PAX_DEFAULT_SEGMEXEC
26039 +       help
26040 +         Select the default non-executable page method applied to applications
26041 +         that do not select one themselves.
26042 +
26043 +config PAX_DEFAULT_PAGEEXEC
26044 +       bool "PAGEEXEC"
26045 +
26046 +config PAX_DEFAULT_SEGMEXEC
26047 +       bool "SEGMEXEC"
26048 +endchoice
26049 +
26050 +config PAX_EMUTRAMP
26051 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
26052 +       default y if PARISC || PPC32
26053 +       help
26054 +         There are some programs and libraries that for one reason or
26055 +         another attempt to execute special small code snippets from
26056 +         non-executable memory pages.  Most notable examples are the
26057 +         signal handler return code generated by the kernel itself and
26058 +         the GCC trampolines.
26059 +
26060 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
26061 +         such programs will no longer work under your kernel.
26062 +
26063 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
26064 +         utilities to enable trampoline emulation for the affected programs
26065 +         yet still have the protection provided by the non-executable pages.
26066 +
26067 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
26068 +         well, otherwise your system will not even boot.
26069 +
26070 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
26071 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
26072 +         for the affected files.
26073 +
26074 +         NOTE: enabling this feature *may* open up a loophole in the
26075 +         protection provided by non-executable pages that an attacker
26076 +         could abuse.  Therefore the best solution is to not have any
26077 +         files on your system that would require this option.  This can
26078 +         be achieved by not using libc5 (which relies on the kernel
26079 +         signal handler return code) and not using or rewriting programs
26080 +         that make use of the nested function implementation of GCC.
26081 +         Skilled users can just fix GCC itself so that it implements
26082 +         nested function calls in a way that does not interfere with PaX.
26083 +
26084 +config PAX_EMUSIGRT
26085 +       bool "Automatically emulate sigreturn trampolines"
26086 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
26087 +       default y
26088 +       help
26089 +         Enabling this option will have the kernel automatically detect
26090 +         and emulate signal return trampolines executing on the stack
26091 +         that would otherwise lead to task termination.
26092 +
26093 +         This solution is intended as a temporary one for users with
26094 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
26095 +         Modula-3 runtime, etc) or executables linked to such, basically
26096 +         everything that does not specify its own SA_RESTORER function in
26097 +         normal executable memory like glibc 2.1+ does.
26098 +
26099 +         On parisc and ppc you MUST enable this option, otherwise your
26100 +         system will not even boot.
26101 +
26102 +         NOTE: this feature cannot be disabled on a per executable basis
26103 +         and since it *does* open up a loophole in the protection provided
26104 +         by non-executable pages, the best solution is to not have any
26105 +         files on your system that would require this option.
26106 +
26107 +config PAX_MPROTECT
26108 +       bool "Restrict mprotect()"
26109 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
26110 +       help
26111 +         Enabling this option will prevent programs from
26112 +          - changing the executable status of memory pages that were
26113 +            not originally created as executable,
26114 +          - making read-only executable pages writable again,
26115 +          - creating executable pages from anonymous memory.
26116 +
26117 +         You should say Y here to complete the protection provided by
26118 +         the enforcement of non-executable pages.
26119 +
26120 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
26121 +         this feature on a per file basis.
26122 +
26123 +config PAX_NOELFRELOCS
26124 +       bool "Disallow ELF text relocations"
26125 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
26126 +       help
26127 +         Non-executable pages and mprotect() restrictions are effective
26128 +         in preventing the introduction of new executable code into an
26129 +         attacked task's address space.  There remain only two venues
26130 +         for this kind of attack: if the attacker can execute already
26131 +         existing code in the attacked task then he can either have it
26132 +         create and mmap() a file containing his code or have it mmap()
26133 +         an already existing ELF library that does not have position
26134 +         independent code in it and use mprotect() on it to make it
26135 +         writable and copy his code there.  While protecting against
26136 +         the former approach is beyond PaX, the latter can be prevented
26137 +         by having only PIC ELF libraries on one's system (which do not
26138 +         need to relocate their code).  If you are sure this is your case,
26139 +         then enable this option otherwise be careful as you may not even
26140 +         be able to boot or log on your system (for example, some PAM
26141 +         modules are erroneously compiled as non-PIC by default).
26142 +
26143 +         NOTE: if you are using dynamic ELF executables (as suggested
26144 +         when using ASLR) then you must have made sure that you linked
26145 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
26146 +         referenced there has already been updated to support this).
26147 +
26148 +config PAX_ETEXECRELOCS
26149 +       bool "Allow ELF ET_EXEC text relocations"
26150 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
26151 +       default y
26152 +       help
26153 +         On some architectures there are incorrectly created applications
26154 +         that require text relocations and would not work without enabling
26155 +         this option.  If you are an alpha, ia64 or parisc user, you should
26156 +         enable this option and disable it once you have made sure that
26157 +         none of your applications need it.
26158 +
26159 +config PAX_EMUPLT
26160 +       bool "Automatically emulate ELF PLT"
26161 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
26162 +       default y
26163 +       help
26164 +         Enabling this option will have the kernel automatically detect
26165 +         and emulate the Procedure Linkage Table entries in ELF files.
26166 +         On some architectures such entries are in writable memory, and
26167 +         become non-executable leading to task termination.  Therefore
26168 +         it is mandatory that you enable this option on alpha, parisc, ppc,
26169 +         sparc and sparc64, otherwise your system would not even boot.
26170 +
26171 +         NOTE: this feature *does* open up a loophole in the protection
26172 +         provided by the non-executable pages, therefore the proper
26173 +         solution is to modify the toolchain to produce a PLT that does
26174 +         not need to be writable.
26175 +
26176 +config PAX_DLRESOLVE
26177 +       bool
26178 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
26179 +       default y
26180 +
26181 +config PAX_SYSCALL
26182 +       bool
26183 +       depends on PAX_PAGEEXEC && PPC32
26184 +       default y
26185 +
26186 +config PAX_KERNEXEC
26187 +       bool "Enforce non-executable kernel pages"
26188 +       depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !DEBUG_RODATA
26189 +       select PAX_NOVSYSCALL
26190 +       help
26191 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
26192 +         that is, enabling this option will make it harder to inject
26193 +         and execute 'foreign' code in kernel memory itself.
26194 +
26195 +endmenu
26196 +
26197 +menu "Address Space Layout Randomization"
26198 +       depends on PAX
26199 +
26200 +config PAX_ASLR
26201 +       bool "Address Space Layout Randomization"
26202 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
26203 +       help
26204 +         Many if not most exploit techniques rely on the knowledge of
26205 +         certain addresses in the attacked program.  The following options
26206 +         will allow the kernel to apply a certain amount of randomization
26207 +         to specific parts of the program thereby forcing an attacker to
26208 +         guess them in most cases.  Any failed guess will most likely crash
26209 +         the attacked program which allows the kernel to detect such attempts
26210 +         and react on them.  PaX itself provides no reaction mechanisms,
26211 +         instead it is strongly encouraged that you make use of Nergal's
26212 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
26213 +         (http://www.grsecurity.net/) built-in crash detection features or
26214 +         develop one yourself.
26215 +
26216 +         By saying Y here you can choose to randomize the following areas:
26217 +          - top of the task's kernel stack
26218 +          - top of the task's userland stack
26219 +          - base address for mmap() requests that do not specify one
26220 +            (this includes all libraries)
26221 +          - base address of the main executable
26222 +
26223 +         It is strongly recommended to say Y here as address space layout
26224 +         randomization has negligible impact on performance yet it provides
26225 +         a very effective protection.
26226 +
26227 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
26228 +         this feature on a per file basis.
26229 +
26230 +config PAX_RANDKSTACK
26231 +       bool "Randomize kernel stack base"
26232 +       depends on PAX_ASLR && X86_TSC && X86_32
26233 +       help
26234 +         By saying Y here the kernel will randomize every task's kernel
26235 +         stack on every system call.  This will not only force an attacker
26236 +         to guess it but also prevent him from making use of possible
26237 +         leaked information about it.
26238 +
26239 +         Since the kernel stack is a rather scarce resource, randomization
26240 +         may cause unexpected stack overflows, therefore you should very
26241 +         carefully test your system.  Note that once enabled in the kernel
26242 +         configuration, this feature cannot be disabled on a per file basis.
26243 +
26244 +config PAX_RANDUSTACK
26245 +       bool "Randomize user stack base"
26246 +       depends on PAX_ASLR
26247 +       help
26248 +         By saying Y here the kernel will randomize every task's userland
26249 +         stack.  The randomization is done in two steps where the second
26250 +         one may apply a big amount of shift to the top of the stack and
26251 +         cause problems for programs that want to use lots of memory (more
26252 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
26253 +         For this reason the second step can be controlled by 'chpax' or
26254 +         'paxctl' on a per file basis.
26255 +
26256 +config PAX_RANDMMAP
26257 +       bool "Randomize mmap() base"
26258 +       depends on PAX_ASLR
26259 +       help
26260 +         By saying Y here the kernel will use a randomized base address for
26261 +         mmap() requests that do not specify one themselves.  As a result
26262 +         all dynamically loaded libraries will appear at random addresses
26263 +         and therefore be harder to exploit by a technique where an attacker
26264 +         attempts to execute library code for his purposes (e.g. spawn a
26265 +         shell from an exploited program that is running at an elevated
26266 +         privilege level).
26267 +
26268 +         Furthermore, if a program is relinked as a dynamic ELF file, its
26269 +         base address will be randomized as well, completing the full
26270 +         randomization of the address space layout.  Attacking such programs
26271 +         becomes a guess game.  You can find an example of doing this at
26272 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
26273 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
26274 +
26275 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
26276 +         feature on a per file basis.
26277 +
26278 +config PAX_NOVSYSCALL
26279 +       bool "Disable the vsyscall page"
26280 +       depends on PAX_ASLR && X86_32
26281 +       help
26282 +         The Linux 2.6 kernel introduced a new feature that speeds up or
26283 +         simplifies certain operations, such as system calls or returns
26284 +         from signal handlers.
26285 +
26286 +         Unfortunately the implementation also gives a powerful instrument
26287 +         into the hands of exploit writers: the so-called vsyscall page exists
26288 +         in every task at the same fixed address and it contains machine code
26289 +         that is very useful in performing the return-to-libc style attack.
26290 +
26291 +         Since this exploit technique cannot in general be protected against
26292 +         via kernel solutions, this option will allow you to disable the use
26293 +         of the vsyscall page and revert back to the old behaviour.
26294 +
26295 +endmenu
26296 +
26297 +menu "Miscellaneous hardening features"
26298 +
26299 +config PAX_MEMORY_SANITIZE
26300 +       bool "Sanitize all freed memory"
26301 +       help
26302 +         By saying Y here the kernel will erase memory pages as soon as they
26303 +         are freed.  This in turn reduces the lifetime of data stored in the
26304 +         pages, making it less likely that sensitive information such as
26305 +         passwords, cryptographic secrets, etc stay in memory for too long.
26306 +
26307 +         This is especially useful for programs whose runtime is short, long
26308 +         lived processes and the kernel itself benefit from this as long as
26309 +         they operate on whole memory pages and ensure timely freeing of pages
26310 +         that may hold sensitive information.
26311 +
26312 +         The tradeoff is performance impact, on a single CPU system kernel
26313 +         compilation sees a 3% slowdown, other systems and workloads may vary
26314 +         and you are advised to test this feature on your expected workload
26315 +         before deploying it.
26316 +
26317 +         Note that this feature does not protect data stored in live pages,
26318 +         e.g., process memory swapped to disk may stay there for a long time.
26319 +
26320 +config PAX_MEMORY_UDEREF
26321 +       bool "Prevent invalid userland pointer dereference"
26322 +       depends on X86_32
26323 +       select PAX_NOVSYSCALL
26324 +       help
26325 +         By saying Y here the kernel will be prevented from dereferencing
26326 +         userland pointers in contexts where the kernel expects only kernel
26327 +         pointers.  This is both a useful runtime debugging feature and a
26328 +         security measure that prevents exploiting a class of kernel bugs.
26329 +
26330 +         The tradeoff is that some virtualization solutions may experience
26331 +         a huge slowdown and therefore you should not enable this feature
26332 +         for kernels meant to run in such environments.  Whether a given VM
26333 +         solution is affected or not is best determined by simply trying it
26334 +         out, the performance impact will be obvious right on boot as this
26335 +         mechanism engages from very early on.  A good rule of thumb is that
26336 +         VMs running on CPUs without hardware virtualization support (i.e.,
26337 +         the majority of IA-32 CPUs) will likely experience the slowdown.
26338 +
26339 +endmenu
26340 +
26341 +endmenu
26342 +
26343 +source grsecurity/Kconfig
26344 +
26345  config KEYS
26346         bool "Enable access key retention support"
26347         help
This page took 2.341475 seconds and 3 git commands to generate.