]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.1.9-2.6.17.7.patch
- _rel 0.7,
[packages/kernel.git] / grsecurity-2.1.9-2.6.17.7.patch
1 diff -urNp linux-2.6.17.7/Makefile linux-2.6.17.7/Makefile
2 --- linux-2.6.17.7/Makefile     2006-07-24 23:36:01.000000000 -0400
3 +++ linux-2.6.17.7/Makefile     2006-08-01 20:29:48.000000000 -0400
4 @@ -518,7 +518,7 @@ export MODLIB
5  
6  
7  ifeq ($(KBUILD_EXTMOD),)
8 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
9 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
10  
11  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
12                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
13 diff -urNp linux-2.6.17.7/arch/alpha/kernel/module.c linux-2.6.17.7/arch/alpha/kernel/module.c
14 --- linux-2.6.17.7/arch/alpha/kernel/module.c   2006-07-24 23:36:01.000000000 -0400
15 +++ linux-2.6.17.7/arch/alpha/kernel/module.c   2006-08-01 20:29:45.000000000 -0400
16 @@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, 
17  
18         /* The small sections were sorted to the end of the segment.
19            The following should definitely cover them.  */
20 -       gp = (u64)me->module_core + me->core_size - 0x8000;
21 +       gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
22         got = sechdrs[me->arch.gotsecindex].sh_addr;
23  
24         for (i = 0; i < n; i++) {
25 diff -urNp linux-2.6.17.7/arch/alpha/kernel/osf_sys.c linux-2.6.17.7/arch/alpha/kernel/osf_sys.c
26 --- linux-2.6.17.7/arch/alpha/kernel/osf_sys.c  2006-07-24 23:36:01.000000000 -0400
27 +++ linux-2.6.17.7/arch/alpha/kernel/osf_sys.c  2006-08-01 20:29:45.000000000 -0400
28 @@ -1273,6 +1273,10 @@ arch_get_unmapped_area(struct file *filp
29            merely specific addresses, but regions of memory -- perhaps
30            this feature should be incorporated into all ports?  */
31  
32 +#ifdef CONFIG_PAX_RANDMMAP
33 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
34 +#endif
35 +
36         if (addr) {
37                 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
38                 if (addr != (unsigned long) -ENOMEM)
39 @@ -1280,8 +1284,8 @@ arch_get_unmapped_area(struct file *filp
40         }
41  
42         /* Next, try allocating at TASK_UNMAPPED_BASE.  */
43 -       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
44 -                                        len, limit);
45 +       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
46 +
47         if (addr != (unsigned long) -ENOMEM)
48                 return addr;
49  
50 diff -urNp linux-2.6.17.7/arch/alpha/kernel/ptrace.c linux-2.6.17.7/arch/alpha/kernel/ptrace.c
51 --- linux-2.6.17.7/arch/alpha/kernel/ptrace.c   2006-07-24 23:36:01.000000000 -0400
52 +++ linux-2.6.17.7/arch/alpha/kernel/ptrace.c   2006-08-01 20:29:45.000000000 -0400
53 @@ -15,6 +15,7 @@
54  #include <linux/security.h>
55  #include <linux/signal.h>
56  #include <linux/vs_pid.h>
57 +#include <linux/grsecurity.h>
58  
59  #include <asm/uaccess.h>
60  #include <asm/pgtable.h>
61 @@ -283,6 +284,9 @@ do_sys_ptrace(long request, long pid, lo
62                 goto out_notsk;
63         }
64  
65 +       if (gr_handle_ptrace(child, request))
66 +               goto out;
67 +
68         if (request == PTRACE_ATTACH) {
69                 ret = ptrace_attach(child);
70                 goto out;
71 diff -urNp linux-2.6.17.7/arch/alpha/mm/fault.c linux-2.6.17.7/arch/alpha/mm/fault.c
72 --- linux-2.6.17.7/arch/alpha/mm/fault.c        2006-07-24 23:36:01.000000000 -0400
73 +++ linux-2.6.17.7/arch/alpha/mm/fault.c        2006-08-01 20:29:45.000000000 -0400
74 @@ -25,6 +25,7 @@
75  #include <linux/smp_lock.h>
76  #include <linux/interrupt.h>
77  #include <linux/module.h>
78 +#include <linux/binfmts.h>
79  
80  #include <asm/system.h>
81  #include <asm/uaccess.h>
82 @@ -56,6 +57,124 @@ __load_new_mm_context(struct mm_struct *
83         __reload_thread(pcb);
84  }
85  
86 +#ifdef CONFIG_PAX_PAGEEXEC
87 +/*
88 + * PaX: decide what to do with offenders (regs->pc = fault address)
89 + *
90 + * returns 1 when task should be killed
91 + *         2 when patched PLT trampoline was detected
92 + *         3 when unpatched PLT trampoline was detected
93 + */
94 +static int pax_handle_fetch_fault(struct pt_regs *regs)
95 +{
96 +
97 +#ifdef CONFIG_PAX_EMUPLT
98 +       int err;
99 +
100 +       do { /* PaX: patched PLT emulation #1 */
101 +               unsigned int ldah, ldq, jmp;
102 +
103 +               err = get_user(ldah, (unsigned int *)regs->pc);
104 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
105 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
106 +
107 +               if (err)
108 +                       break;
109 +
110 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
111 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
112 +                   jmp == 0x6BFB0000U)
113 +               {
114 +                       unsigned long r27, addr;
115 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
116 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
117 +
118 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
119 +                       err = get_user(r27, (unsigned long*)addr);
120 +                       if (err)
121 +                               break;
122 +
123 +                       regs->r27 = r27;
124 +                       regs->pc = r27;
125 +                       return 2;
126 +               }
127 +       } while (0);
128 +
129 +       do { /* PaX: patched PLT emulation #2 */
130 +               unsigned int ldah, lda, br;
131 +
132 +               err = get_user(ldah, (unsigned int *)regs->pc);
133 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
134 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
135 +
136 +               if (err)
137 +                       break;
138 +
139 +               if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
140 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
141 +                   (br & 0xFFE00000U) == 0xC3E00000U)
142 +               {
143 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
144 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
145 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
146 +
147 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
148 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
149 +                       return 2;
150 +               }
151 +       } while (0);
152 +
153 +       do { /* PaX: unpatched PLT emulation */
154 +               unsigned int br;
155 +
156 +               err = get_user(br, (unsigned int *)regs->pc);
157 +
158 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
159 +                       unsigned int br2, ldq, nop, jmp;
160 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
161 +
162 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
163 +                       err = get_user(br2, (unsigned int *)addr);
164 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
165 +                       err |= get_user(nop, (unsigned int *)(addr+8));
166 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
167 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
168 +
169 +                       if (err)
170 +                               break;
171 +
172 +                       if (br2 == 0xC3600000U &&
173 +                           ldq == 0xA77B000CU &&
174 +                           nop == 0x47FF041FU &&
175 +                           jmp == 0x6B7B0000U)
176 +                       {
177 +                               regs->r28 = regs->pc+4;
178 +                               regs->r27 = addr+16;
179 +                               regs->pc = resolver;
180 +                               return 3;
181 +                       }
182 +               }
183 +       } while (0);
184 +#endif
185 +
186 +       return 1;
187 +}
188 +
189 +void pax_report_insns(void *pc, void *sp)
190 +{
191 +       unsigned long i;
192 +
193 +       printk(KERN_ERR "PAX: bytes at PC: ");
194 +       for (i = 0; i < 5; i++) {
195 +               unsigned int c;
196 +               if (get_user(c, (unsigned int*)pc+i))
197 +                       printk("???????? ");
198 +               else
199 +                       printk("%08x ", c);
200 +       }
201 +       printk("\n");
202 +}
203 +#endif
204  
205  /*
206   * This routine handles page faults.  It determines the address,
207 @@ -133,8 +252,29 @@ do_page_fault(unsigned long address, uns
208   good_area:
209         si_code = SEGV_ACCERR;
210         if (cause < 0) {
211 -               if (!(vma->vm_flags & VM_EXEC))
212 +               if (!(vma->vm_flags & VM_EXEC)) {
213 +
214 +#ifdef CONFIG_PAX_PAGEEXEC
215 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
216 +                               goto bad_area;
217 +
218 +                       up_read(&mm->mmap_sem);
219 +                       switch(pax_handle_fetch_fault(regs)) {
220 +
221 +#ifdef CONFIG_PAX_EMUPLT
222 +                       case 2:
223 +                       case 3:
224 +                               return;
225 +#endif
226 +
227 +                       }
228 +                       pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
229 +                       do_exit(SIGKILL);
230 +#else
231                         goto bad_area;
232 +#endif
233 +
234 +               }
235         } else if (!cause) {
236                 /* Allow reads even for write-only mappings */
237                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
238 diff -urNp linux-2.6.17.7/arch/arm/mm/mmap.c linux-2.6.17.7/arch/arm/mm/mmap.c
239 --- linux-2.6.17.7/arch/arm/mm/mmap.c   2006-07-24 23:36:01.000000000 -0400
240 +++ linux-2.6.17.7/arch/arm/mm/mmap.c   2006-08-01 20:29:45.000000000 -0400
241 @@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
242         if (len > TASK_SIZE)
243                 return -ENOMEM;
244  
245 +#ifdef CONFIG_PAX_RANDMMAP
246 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
247 +#endif
248 +
249         if (addr) {
250                 if (do_align)
251                         addr = COLOUR_ALIGN(addr, pgoff);
252 @@ -76,7 +80,7 @@ arch_get_unmapped_area(struct file *filp
253         if (len > mm->cached_hole_size) {
254                 start_addr = addr = mm->free_area_cache;
255         } else {
256 -               start_addr = addr = TASK_UNMAPPED_BASE;
257 +               start_addr = addr = mm->mmap_base;
258                 mm->cached_hole_size = 0;
259         }
260  
261 @@ -93,8 +97,8 @@ full_search:
262                          * Start a new search - just in case we missed
263                          * some holes.
264                          */
265 -                       if (start_addr != TASK_UNMAPPED_BASE) {
266 -                               start_addr = addr = TASK_UNMAPPED_BASE;
267 +                       if (start_addr != mm->mmap_base) {
268 +                               start_addr = addr = mm->mmap_base;
269                                 mm->cached_hole_size = 0;
270                                 goto full_search;
271                         }
272 diff -urNp linux-2.6.17.7/arch/i386/Kconfig linux-2.6.17.7/arch/i386/Kconfig
273 --- linux-2.6.17.7/arch/i386/Kconfig    2006-07-24 23:36:01.000000000 -0400
274 +++ linux-2.6.17.7/arch/i386/Kconfig    2006-08-01 20:29:45.000000000 -0400
275 @@ -980,7 +980,7 @@ endchoice
276  
277  config PCI_BIOS
278         bool
279 -       depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
280 +       depends on !X86_VISWS && PCI && PCI_GOBIOS
281         default y
282  
283  config PCI_DIRECT
284 diff -urNp linux-2.6.17.7/arch/i386/Kconfig.cpu linux-2.6.17.7/arch/i386/Kconfig.cpu
285 --- linux-2.6.17.7/arch/i386/Kconfig.cpu        2006-07-24 23:36:01.000000000 -0400
286 +++ linux-2.6.17.7/arch/i386/Kconfig.cpu        2006-08-01 20:29:45.000000000 -0400
287 @@ -251,7 +251,7 @@ config X86_PPRO_FENCE
288  
289  config X86_F00F_BUG
290         bool
291 -       depends on M586MMX || M586TSC || M586 || M486 || M386
292 +       depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
293         default y
294  
295  config X86_WP_WORKS_OK
296 @@ -281,7 +281,7 @@ config X86_CMPXCHG64
297  
298  config X86_ALIGNMENT_16
299         bool
300 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
301 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
302         default y
303  
304  config X86_GOOD_APIC
305 diff -urNp linux-2.6.17.7/arch/i386/Kconfig.debug linux-2.6.17.7/arch/i386/Kconfig.debug
306 --- linux-2.6.17.7/arch/i386/Kconfig.debug      2006-07-24 23:36:01.000000000 -0400
307 +++ linux-2.6.17.7/arch/i386/Kconfig.debug      2006-08-01 20:29:45.000000000 -0400
308 @@ -53,7 +53,7 @@ config DEBUG_PAGEALLOC
309  
310  config DEBUG_RODATA
311         bool "Write protect kernel read-only data structures"
312 -       depends on DEBUG_KERNEL
313 +       depends on DEBUG_KERNEL && 0
314         help
315           Mark the kernel read-only data as write-protected in the pagetables,
316           in order to catch accidental (and incorrect) writes to such const
317 diff -urNp linux-2.6.17.7/arch/i386/boot/compressed/head.S linux-2.6.17.7/arch/i386/boot/compressed/head.S
318 --- linux-2.6.17.7/arch/i386/boot/compressed/head.S     2006-07-24 23:36:01.000000000 -0400
319 +++ linux-2.6.17.7/arch/i386/boot/compressed/head.S     2006-08-01 20:29:45.000000000 -0400
320 @@ -39,11 +39,13 @@ startup_32:
321         movl %eax,%gs
322  
323         lss stack_start,%esp
324 +       movl 0x000000,%ecx
325         xorl %eax,%eax
326  1:     incl %eax               # check that A20 really IS enabled
327         movl %eax,0x000000      # loop forever if it isn't
328         cmpl %eax,0x100000
329         je 1b
330 +       movl %ecx,0x000000
331  
332  /*
333   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
334 diff -urNp linux-2.6.17.7/arch/i386/kernel/acpi/sleep.c linux-2.6.17.7/arch/i386/kernel/acpi/sleep.c
335 --- linux-2.6.17.7/arch/i386/kernel/acpi/sleep.c        2006-07-24 23:36:01.000000000 -0400
336 +++ linux-2.6.17.7/arch/i386/kernel/acpi/sleep.c        2006-08-01 20:29:45.000000000 -0400
337 @@ -10,6 +10,7 @@
338  #include <linux/dmi.h>
339  #include <asm/smp.h>
340  #include <asm/tlbflush.h>
341 +#include <asm/desc.h>
342  
343  /* address in low memory of the wakeup routine. */
344  unsigned long acpi_wakeup_address = 0;
345 @@ -24,11 +25,22 @@ static void init_low_mapping(pgd_t * pgd
346  {
347         int pgd_ofs = 0;
348  
349 +#ifdef CONFIG_PAX_KERNEXEC
350 +       unsigned long cr0;
351 +
352 +       pax_open_kernel(cr0);
353 +#endif
354 +
355         while ((pgd_ofs < pgd_limit)
356                && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
357                 set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD));
358                 pgd_ofs++, pgd++;
359         }
360 +
361 +#ifdef CONFIG_PAX_KERNEXEC
362 +       pax_close_kernel(cr0);
363 +#endif
364 +
365         flush_tlb_all();
366  }
367  
368 @@ -55,7 +67,18 @@ int acpi_save_state_mem(void)
369   */
370  void acpi_restore_state_mem(void)
371  {
372 +#ifdef CONFIG_PAX_KERNEXEC
373 +       unsigned long cr0;
374 +
375 +       pax_open_kernel(cr0);
376 +#endif
377 +
378         zap_low_mappings();
379 +
380 +#ifdef CONFIG_PAX_KERNEXEC
381 +       pax_close_kernel(cr0);
382 +#endif
383 +
384  }
385  
386  /**
387 diff -urNp linux-2.6.17.7/arch/i386/kernel/alternative.c linux-2.6.17.7/arch/i386/kernel/alternative.c
388 --- linux-2.6.17.7/arch/i386/kernel/alternative.c       2006-07-24 23:36:01.000000000 -0400
389 +++ linux-2.6.17.7/arch/i386/kernel/alternative.c       2006-08-01 20:29:45.000000000 -0400
390 @@ -3,6 +3,7 @@
391  #include <linux/list.h>
392  #include <asm/alternative.h>
393  #include <asm/sections.h>
394 +#include <asm/desc.h>
395  
396  #define DEBUG 0
397  #if DEBUG
398 @@ -101,71 +102,128 @@ void apply_alternatives(struct alt_instr
399         struct alt_instr *a;
400         int diff, i, k;
401  
402 +#ifdef CONFIG_PAX_KERNEXEC
403 +       unsigned long cr0;
404 +
405 +       pax_open_kernel(cr0);
406 +#endif
407 +
408         DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
409         for (a = start; a < end; a++) {
410                 BUG_ON(a->replacementlen > a->instrlen);
411                 if (!boot_cpu_has(a->cpuid))
412                         continue;
413 -               memcpy(a->instr, a->replacement, a->replacementlen);
414 +               memcpy(a->instr + __KERNEL_TEXT_OFFSET, a->replacement, a->replacementlen);
415                 diff = a->instrlen - a->replacementlen;
416                 /* Pad the rest with nops */
417                 for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
418                         k = diff;
419                         if (k > ASM_NOP_MAX)
420                                 k = ASM_NOP_MAX;
421 -                       memcpy(a->instr + i, noptable[k], k);
422 +                       memcpy(a->instr + i + __KERNEL_TEXT_OFFSET, noptable[k], k);
423                 }
424         }
425 +
426 +#ifdef CONFIG_PAX_KERNEXEC
427 +       pax_close_kernel(cr0);
428 +#endif
429 +
430  }
431  
432  static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end)
433  {
434         struct alt_instr *a;
435  
436 +#ifdef CONFIG_PAX_KERNEXEC
437 +       unsigned long cr0;
438 +
439 +       pax_open_kernel(cr0);
440 +#endif
441 +
442         DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
443         for (a = start; a < end; a++) {
444                 memcpy(a->replacement + a->replacementlen,
445 -                      a->instr,
446 +                      a->instr + __KERNEL_TEXT_OFFSET,
447                        a->instrlen);
448         }
449 +
450 +#ifdef CONFIG_PAX_KERNEXEC
451 +       pax_close_kernel(cr0);
452 +#endif
453 +
454  }
455  
456  static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
457  {
458         struct alt_instr *a;
459  
460 +#ifdef CONFIG_PAX_KERNEXEC
461 +       unsigned long cr0;
462 +
463 +       pax_open_kernel(cr0);
464 +#endif
465 +
466         for (a = start; a < end; a++) {
467 -               memcpy(a->instr,
468 +               memcpy(a->instr + __KERNEL_TEXT_OFFSET,
469                        a->replacement + a->replacementlen,
470                        a->instrlen);
471         }
472 +
473 +#ifdef CONFIG_PAX_KERNEXEC
474 +       pax_close_kernel(cr0);
475 +#endif
476 +
477  }
478  
479  static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
480  {
481 -       u8 **ptr;
482 +       u8 *ptr;
483 +
484 +#ifdef CONFIG_PAX_KERNEXEC
485 +       unsigned long cr0;
486  
487 -       for (ptr = start; ptr < end; ptr++) {
488 -               if (*ptr < text)
489 +       pax_open_kernel(cr0);
490 +#endif
491 +
492 +       for (; start < end; start++) {
493 +               ptr = *start + __KERNEL_TEXT_OFFSET;
494 +               if (ptr < text)
495                         continue;
496 -               if (*ptr > text_end)
497 +               if (ptr > text_end)
498                         continue;
499 -               **ptr = 0xf0; /* lock prefix */
500 +               *ptr = 0xf0; /* lock prefix */
501         };
502 +
503 +#ifdef CONFIG_PAX_KERNEXEC
504 +       pax_close_kernel(cr0);
505 +#endif
506 +
507  }
508  
509  static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
510  {
511         unsigned char **noptable = find_nop_table();
512 -       u8 **ptr;
513 +       u8 *ptr;
514 +
515 +#ifdef CONFIG_PAX_KERNEXEC
516 +       unsigned long cr0;
517 +
518 +       pax_open_kernel(cr0);
519 +#endif
520  
521 -       for (ptr = start; ptr < end; ptr++) {
522 -               if (*ptr < text)
523 +       for (; start < end; start++) {
524 +               ptr = *start + __KERNEL_TEXT_OFFSET;
525 +               if (ptr < text)
526                         continue;
527 -               if (*ptr > text_end)
528 +               if (ptr > text_end)
529                         continue;
530 -               **ptr = noptable[1][0];
531 +               *ptr = noptable[1][0];
532         };
533 +
534 +#ifdef CONFIG_PAX_KERNEXEC
535 +       pax_close_kernel(cr0);
536 +#endif
537 +
538  }
539  
540  struct smp_alt_module {
541 diff -urNp linux-2.6.17.7/arch/i386/kernel/apic.c linux-2.6.17.7/arch/i386/kernel/apic.c
542 --- linux-2.6.17.7/arch/i386/kernel/apic.c      2006-07-24 23:36:01.000000000 -0400
543 +++ linux-2.6.17.7/arch/i386/kernel/apic.c      2006-08-01 20:29:45.000000000 -0400
544 @@ -1176,7 +1176,7 @@ inline void smp_local_timer_interrupt(st
545  {
546         profile_tick(CPU_PROFILING, regs);
547  #ifdef CONFIG_SMP
548 -       update_process_times(user_mode_vm(regs));
549 +       update_process_times(user_mode(regs));
550  #endif
551  
552         /*
553 diff -urNp linux-2.6.17.7/arch/i386/kernel/apm.c linux-2.6.17.7/arch/i386/kernel/apm.c
554 --- linux-2.6.17.7/arch/i386/kernel/apm.c       2006-07-24 23:36:01.000000000 -0400
555 +++ linux-2.6.17.7/arch/i386/kernel/apm.c       2006-08-01 20:29:45.000000000 -0400
556 @@ -589,9 +589,18 @@ static u8 apm_bios_call(u32 func, u32 eb
557         struct desc_struct      save_desc_40;
558         struct desc_struct      *gdt;
559  
560 +#ifdef CONFIG_PAX_KERNEXEC
561 +       unsigned long           cr0;
562 +#endif
563 +
564         cpus = apm_save_cpus();
565         
566         cpu = get_cpu();
567 +
568 +#ifdef CONFIG_PAX_KERNEXEC
569 +       pax_open_kernel(cr0);
570 +#endif
571 +
572         gdt = get_cpu_gdt_table(cpu);
573         save_desc_40 = gdt[0x40 / 8];
574         gdt[0x40 / 8] = bad_bios_desc;
575 @@ -603,6 +612,11 @@ static u8 apm_bios_call(u32 func, u32 eb
576         APM_DO_RESTORE_SEGS;
577         local_irq_restore(flags);
578         gdt[0x40 / 8] = save_desc_40;
579 +
580 +#ifdef CONFIG_PAX_KERNEXEC
581 +       pax_close_kernel(cr0);
582 +#endif
583 +
584         put_cpu();
585         apm_restore_cpus(cpus);
586         
587 @@ -633,9 +647,18 @@ static u8 apm_bios_call_simple(u32 func,
588         struct desc_struct      save_desc_40;
589         struct desc_struct      *gdt;
590  
591 +#ifdef CONFIG_PAX_KERNEXEC
592 +       unsigned long           cr0;
593 +#endif
594 +
595         cpus = apm_save_cpus();
596         
597         cpu = get_cpu();
598 +
599 +#ifdef CONFIG_PAX_KERNEXEC
600 +       pax_open_kernel(cr0);
601 +#endif
602 +
603         gdt = get_cpu_gdt_table(cpu);
604         save_desc_40 = gdt[0x40 / 8];
605         gdt[0x40 / 8] = bad_bios_desc;
606 @@ -647,6 +670,11 @@ static u8 apm_bios_call_simple(u32 func,
607         APM_DO_RESTORE_SEGS;
608         local_irq_restore(flags);
609         gdt[0x40 / 8] = save_desc_40;
610 +
611 +#ifdef CONFIG_PAX_KERNEXEC
612 +       pax_close_kernel(cr0);
613 +#endif
614 +
615         put_cpu();
616         apm_restore_cpus(cpus);
617         return error;
618 diff -urNp linux-2.6.17.7/arch/i386/kernel/asm-offsets.c linux-2.6.17.7/arch/i386/kernel/asm-offsets.c
619 --- linux-2.6.17.7/arch/i386/kernel/asm-offsets.c       2006-07-24 23:36:01.000000000 -0400
620 +++ linux-2.6.17.7/arch/i386/kernel/asm-offsets.c       2006-08-01 20:29:45.000000000 -0400
621 @@ -68,5 +68,6 @@ void foo(void)
622                  sizeof(struct tss_struct));
623  
624         DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
625 +       DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
626         DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
627  }
628 diff -urNp linux-2.6.17.7/arch/i386/kernel/cpu/common.c linux-2.6.17.7/arch/i386/kernel/cpu/common.c
629 --- linux-2.6.17.7/arch/i386/kernel/cpu/common.c        2006-07-24 23:36:01.000000000 -0400
630 +++ linux-2.6.17.7/arch/i386/kernel/cpu/common.c        2006-08-01 20:29:45.000000000 -0400
631 @@ -4,7 +4,6 @@
632  #include <linux/smp.h>
633  #include <linux/module.h>
634  #include <linux/percpu.h>
635 -#include <linux/bootmem.h>
636  #include <asm/semaphore.h>
637  #include <asm/processor.h>
638  #include <asm/i387.h>
639 @@ -19,9 +18,6 @@
640  
641  #include "cpu.h"
642  
643 -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
644 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
645 -
646  DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
647  EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
648  
649 @@ -401,6 +397,10 @@ void __cpuinit identify_cpu(struct cpuin
650         if (this_cpu->c_init)
651                 this_cpu->c_init(c);
652  
653 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
654 +       clear_bit(X86_FEATURE_SEP, c->x86_capability);
655 +#endif
656 +
657         /* Disable the PN if appropriate */
658         squash_the_stupid_serial_number(c);
659  
660 @@ -590,11 +590,10 @@ void __init early_cpu_init(void)
661  void __cpuinit cpu_init(void)
662  {
663         int cpu = smp_processor_id();
664 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
665 +       struct tss_struct * t = init_tss + cpu;
666         struct thread_struct *thread = &current->thread;
667 -       struct desc_struct *gdt;
668 +       struct desc_struct *gdt = get_cpu_gdt_table(cpu);
669         __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
670 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
671  
672         if (cpu_test_and_set(cpu, cpu_initialized)) {
673                 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
674 @@ -612,29 +611,11 @@ void __cpuinit cpu_init(void)
675         }
676  
677         /*
678 -        * This is a horrible hack to allocate the GDT.  The problem
679 -        * is that cpu_init() is called really early for the boot CPU
680 -        * (and hence needs bootmem) but much later for the secondary
681 -        * CPUs, when bootmem will have gone away
682 -        */
683 -       if (NODE_DATA(0)->bdata->node_bootmem_map) {
684 -               gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
685 -               /* alloc_bootmem_pages panics on failure, so no check */
686 -               memset(gdt, 0, PAGE_SIZE);
687 -       } else {
688 -               gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
689 -               if (unlikely(!gdt)) {
690 -                       printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
691 -                       for (;;)
692 -                               local_irq_enable();
693 -               }
694 -       }
695 -
696 -       /*
697          * Initialize the per-CPU GDT with the boot GDT,
698          * and set up the GDT descriptor:
699          */
700 -       memcpy(gdt, cpu_gdt_table, GDT_SIZE);
701 +       if (cpu)
702 +               memcpy(gdt, cpu_gdt_table, GDT_SIZE);
703  
704         /* Set up GDT entry for 16bit stack */
705         *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
706 @@ -642,10 +623,10 @@ void __cpuinit cpu_init(void)
707                 ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
708                 (CPU_16BIT_STACK_SIZE - 1);
709  
710 -       cpu_gdt_descr->size = GDT_SIZE - 1;
711 -       cpu_gdt_descr->address = (unsigned long)gdt;
712 +       cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
713 +       cpu_gdt_descr[cpu].address = (unsigned long)gdt;
714  
715 -       load_gdt(cpu_gdt_descr);
716 +       load_gdt(&cpu_gdt_descr[cpu]);
717         load_idt(&idt_descr);
718  
719         /*
720 @@ -660,7 +641,7 @@ void __cpuinit cpu_init(void)
721         load_esp0(t, thread);
722         set_tss_desc(cpu,t);
723         load_TR_desc();
724 -       load_LDT(&init_mm.context);
725 +       _load_LDT(&init_mm.context);
726  
727  #ifdef CONFIG_DOUBLEFAULT
728         /* Set up doublefault TSS pointer in the GDT */
729 @@ -668,7 +649,7 @@ void __cpuinit cpu_init(void)
730  #endif
731  
732         /* Clear %fs and %gs. */
733 -       asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
734 +       asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r"(0));
735  
736         /* Clear all 6 debug registers: */
737         set_debugreg(0, 0);
738 diff -urNp linux-2.6.17.7/arch/i386/kernel/crash.c linux-2.6.17.7/arch/i386/kernel/crash.c
739 --- linux-2.6.17.7/arch/i386/kernel/crash.c     2006-07-24 23:36:01.000000000 -0400
740 +++ linux-2.6.17.7/arch/i386/kernel/crash.c     2006-08-01 20:29:45.000000000 -0400
741 @@ -105,7 +105,7 @@ static int crash_nmi_callback(struct pt_
742                 return 1;
743         local_irq_disable();
744  
745 -       if (!user_mode_vm(regs)) {
746 +       if (!user_mode(regs)) {
747                 crash_fixup_ss_esp(&fixed_regs, regs);
748                 regs = &fixed_regs;
749         }
750 diff -urNp linux-2.6.17.7/arch/i386/kernel/doublefault.c linux-2.6.17.7/arch/i386/kernel/doublefault.c
751 --- linux-2.6.17.7/arch/i386/kernel/doublefault.c       2006-07-24 23:36:01.000000000 -0400
752 +++ linux-2.6.17.7/arch/i386/kernel/doublefault.c       2006-08-01 20:29:45.000000000 -0400
753 @@ -11,7 +11,7 @@
754  
755  #define DOUBLEFAULT_STACKSIZE (1024)
756  static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
757 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
758 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
759  
760  #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
761  
762 @@ -56,10 +56,10 @@ struct tss_struct doublefault_tss __cach
763         .eip            = (unsigned long) doublefault_fn,
764         .eflags         = X86_EFLAGS_SF | 0x2,  /* 0x2 bit is always set */
765         .esp            = STACK_START,
766 -       .es             = __USER_DS,
767 +       .es             = __KERNEL_DS,
768         .cs             = __KERNEL_CS,
769         .ss             = __KERNEL_DS,
770 -       .ds             = __USER_DS,
771 +       .ds             = __KERNEL_DS,
772  
773         .__cr3          = __pa(swapper_pg_dir)
774  };
775 diff -urNp linux-2.6.17.7/arch/i386/kernel/efi.c linux-2.6.17.7/arch/i386/kernel/efi.c
776 --- linux-2.6.17.7/arch/i386/kernel/efi.c       2006-07-24 23:36:01.000000000 -0400
777 +++ linux-2.6.17.7/arch/i386/kernel/efi.c       2006-08-01 20:29:45.000000000 -0400
778 @@ -64,82 +64,48 @@ extern void * boot_ioremap(unsigned long
779  
780  static unsigned long efi_rt_eflags;
781  static DEFINE_SPINLOCK(efi_rt_lock);
782 -static pgd_t efi_bak_pg_dir_pointer[2];
783 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
784  
785 -static void efi_call_phys_prelog(void)
786 +static void __init efi_call_phys_prelog(void)
787  {
788 -       unsigned long cr4;
789 -       unsigned long temp;
790 -       struct Xgt_desc_struct *cpu_gdt_descr;
791 -
792         spin_lock(&efi_rt_lock);
793         local_irq_save(efi_rt_eflags);
794  
795 -       cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
796 -
797 -       /*
798 -        * If I don't have PSE, I should just duplicate two entries in page
799 -        * directory. If I have PSE, I just need to duplicate one entry in
800 -        * page directory.
801 -        */
802 -       cr4 = read_cr4();
803 -
804 -       if (cr4 & X86_CR4_PSE) {
805 -               efi_bak_pg_dir_pointer[0].pgd =
806 -                   swapper_pg_dir[pgd_index(0)].pgd;
807 -               swapper_pg_dir[0].pgd =
808 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
809 -       } else {
810 -               efi_bak_pg_dir_pointer[0].pgd =
811 -                   swapper_pg_dir[pgd_index(0)].pgd;
812 -               efi_bak_pg_dir_pointer[1].pgd =
813 -                   swapper_pg_dir[pgd_index(0x400000)].pgd;
814 -               swapper_pg_dir[pgd_index(0)].pgd =
815 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
816 -               temp = PAGE_OFFSET + 0x400000;
817 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
818 -                   swapper_pg_dir[pgd_index(temp)].pgd;
819 +       clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
820 +       if (USER_PTRS_PER_PGD >= KERNEL_PGD_PTRS)
821 +               clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PTRS_PER_PGD, KERNEL_PGD_PTRS);
822 +       else {
823 +               unsigned long i;
824 +               for (i = 0; i < KERNEL_PGD_PTRS; ++i)
825 +                       clone_pgd_range(swapper_pg_dir + i, swapper_pg_dir + USER_PTRS_PER_PGD + i, 1);
826         }
827  
828         /*
829          * After the lock is released, the original page table is restored.
830          */
831 -       local_flush_tlb();
832 +       __flush_tlb_all();
833  
834 -       cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
835 -       load_gdt(cpu_gdt_descr);
836 +       cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
837 +       load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
838  }
839  
840 -static void efi_call_phys_epilog(void)
841 +static void __init efi_call_phys_epilog(void)
842  {
843 -       unsigned long cr4;
844 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
845 -
846 -       cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address);
847 -       load_gdt(cpu_gdt_descr);
848 +       cpu_gdt_descr[0].address = (unsigned long) __va(cpu_gdt_descr[0].address);
849 +       load_gdt(&cpu_gdt_descr[0]);
850  
851 -       cr4 = read_cr4();
852 -
853 -       if (cr4 & X86_CR4_PSE) {
854 -               swapper_pg_dir[pgd_index(0)].pgd =
855 -                   efi_bak_pg_dir_pointer[0].pgd;
856 -       } else {
857 -               swapper_pg_dir[pgd_index(0)].pgd =
858 -                   efi_bak_pg_dir_pointer[0].pgd;
859 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
860 -                   efi_bak_pg_dir_pointer[1].pgd;
861 -       }
862 +       clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
863  
864         /*
865          * After the lock is released, the original page table is restored.
866          */
867 -       local_flush_tlb();
868 +       __flush_tlb_all();
869  
870         local_irq_restore(efi_rt_eflags);
871         spin_unlock(&efi_rt_lock);
872  }
873  
874 -static efi_status_t
875 +static efi_status_t __init
876  phys_efi_set_virtual_address_map(unsigned long memory_map_size,
877                                  unsigned long descriptor_size,
878                                  u32 descriptor_version,
879 @@ -155,7 +121,7 @@ phys_efi_set_virtual_address_map(unsigne
880         return status;
881  }
882  
883 -static efi_status_t
884 +static efi_status_t __init
885  phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
886  {
887         efi_status_t status;
888 diff -urNp linux-2.6.17.7/arch/i386/kernel/efi_stub.S linux-2.6.17.7/arch/i386/kernel/efi_stub.S
889 --- linux-2.6.17.7/arch/i386/kernel/efi_stub.S  2006-07-24 23:36:01.000000000 -0400
890 +++ linux-2.6.17.7/arch/i386/kernel/efi_stub.S  2006-08-01 20:29:45.000000000 -0400
891 @@ -7,6 +7,7 @@
892  
893  #include <linux/config.h>
894  #include <linux/linkage.h>
895 +#include <linux/init.h>
896  #include <asm/page.h>
897  #include <asm/pgtable.h>
898  
899 @@ -22,7 +23,7 @@
900   * service functions will comply with gcc calling convention, too.
901   */
902  
903 -.text
904 +__INIT
905  ENTRY(efi_call_phys)
906         /*
907          * 0. The function can only be called in Linux kernel. So CS has been
908 @@ -38,9 +39,7 @@ ENTRY(efi_call_phys)
909          * The mapping of lower virtual memory has been created in prelog and
910          * epilog.
911          */
912 -       movl    $1f, %edx
913 -       subl    $__PAGE_OFFSET, %edx
914 -       jmp     *%edx
915 +       jmp     1f-__PAGE_OFFSET
916  1:
917  
918         /*
919 @@ -49,14 +48,8 @@ ENTRY(efi_call_phys)
920          * parameter 2, ..., param n. To make things easy, we save the return
921          * address of efi_call_phys in a global variable.
922          */
923 -       popl    %edx
924 -       movl    %edx, saved_return_addr
925 -       /* get the function pointer into ECX*/
926 -       popl    %ecx
927 -       movl    %ecx, efi_rt_function_ptr
928 -       movl    $2f, %edx
929 -       subl    $__PAGE_OFFSET, %edx
930 -       pushl   %edx
931 +       popl    (saved_return_addr)
932 +       popl    (efi_rt_function_ptr)
933  
934         /*
935          * 3. Clear PG bit in %CR0.
936 @@ -75,9 +68,8 @@ ENTRY(efi_call_phys)
937         /*
938          * 5. Call the physical function.
939          */
940 -       jmp     *%ecx
941 +       call    *(efi_rt_function_ptr-__PAGE_OFFSET)
942  
943 -2:
944         /*
945          * 6. After EFI runtime service returns, control will return to
946          * following instruction. We'd better readjust stack pointer first.
947 @@ -87,37 +79,29 @@ ENTRY(efi_call_phys)
948         /*
949          * 7. Restore PG bit
950          */
951 -       movl    %cr0, %edx
952 -       orl     $0x80000000, %edx
953 -       movl    %edx, %cr0
954 -       jmp     1f
955 -1:
956         /*
957          * 8. Now restore the virtual mode from flat mode by
958          * adding EIP with PAGE_OFFSET.
959          */
960 -       movl    $1f, %edx
961 -       jmp     *%edx
962 +       movl    %cr0, %edx
963 +       orl     $0x80000000, %edx
964 +       movl    %edx, %cr0
965 +       jmp     1f+__PAGE_OFFSET
966  1:
967  
968         /*
969          * 9. Balance the stack. And because EAX contain the return value,
970          * we'd better not clobber it.
971          */
972 -       leal    efi_rt_function_ptr, %edx
973 -       movl    (%edx), %ecx
974 -       pushl   %ecx
975 +       pushl   (efi_rt_function_ptr)
976  
977         /*
978 -        * 10. Push the saved return address onto the stack and return.
979 +        * 10. Return to the saved return address.
980          */
981 -       leal    saved_return_addr, %edx
982 -       movl    (%edx), %ecx
983 -       pushl   %ecx
984 -       ret
985 +       jmpl    *(saved_return_addr)
986  .previous
987  
988 -.data
989 +__INITDATA
990  saved_return_addr:
991         .long 0
992  efi_rt_function_ptr:
993 diff -urNp linux-2.6.17.7/arch/i386/kernel/entry.S linux-2.6.17.7/arch/i386/kernel/entry.S
994 --- linux-2.6.17.7/arch/i386/kernel/entry.S     2006-07-24 23:36:01.000000000 -0400
995 +++ linux-2.6.17.7/arch/i386/kernel/entry.S     2006-08-01 20:29:45.000000000 -0400
996 @@ -82,7 +82,7 @@ VM_MASK               = 0x00020000
997  #define resume_kernel          restore_nocheck
998  #endif
999  
1000 -#define SAVE_ALL \
1001 +#define __SAVE_ALL(_DS) \
1002         cld; \
1003         pushl %es; \
1004         pushl %ds; \
1005 @@ -93,10 +93,24 @@ VM_MASK             = 0x00020000
1006         pushl %edx; \
1007         pushl %ecx; \
1008         pushl %ebx; \
1009 -       movl $(__USER_DS), %edx; \
1010 +       movl $(_DS), %edx; \
1011         movl %edx, %ds; \
1012         movl %edx, %es;
1013  
1014 +#ifdef CONFIG_PAX_KERNEXEC
1015 +#define SAVE_ALL \
1016 +       __SAVE_ALL(__KERNEL_DS) \
1017 +       movl %cr0, %edx; \
1018 +       movl %edx, %esi; \
1019 +       orl $0x10000, %edx; \
1020 +       xorl %edx, %esi; \
1021 +       movl %edx, %cr0;
1022 +#elif defined(CONFIG_PAX_NOVSYSCALL)
1023 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1024 +#else
1025 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
1026 +#endif
1027 +
1028  #define RESTORE_INT_REGS \
1029         popl %ebx;      \
1030         popl %ecx;      \
1031 @@ -146,7 +160,19 @@ ret_from_intr:
1032         movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
1033         movb CS(%esp), %al
1034         testl $(VM_MASK | 3), %eax
1035 +
1036 +#ifdef CONFIG_PAX_KERNEXEC
1037 +       jnz resume_userspace
1038 +
1039 +       movl %cr0, %edx
1040 +       xorl %esi, %edx
1041 +       movl %edx, %cr0
1042 +       jmp resume_kernel
1043 +#else
1044         jz resume_kernel
1045 +#endif
1046 +
1047 +
1048  ENTRY(resume_userspace)
1049         cli                             # make sure we don't miss an interrupt
1050                                         # setting need_resched or sigpending
1051 @@ -213,13 +239,33 @@ sysenter_past_esp:
1052         movl TI_flags(%ebp), %ecx
1053         testw $_TIF_ALLWORK_MASK, %cx
1054         jne syscall_exit_work
1055 +
1056 +#ifdef CONFIG_PAX_RANDKSTACK
1057 +       pushl %eax
1058 +       call pax_randomize_kstack
1059 +       popl %eax
1060 +#endif
1061 +
1062  /* if something modifies registers it must also disable sysexit */
1063         movl EIP(%esp), %edx
1064         movl OLDESP(%esp), %ecx
1065 +1:     mov DS(%esp), %ds
1066 +2:     mov ES(%esp), %es
1067         xorl %ebp,%ebp
1068         sti
1069         sysexit
1070  
1071 +.section .fixup,"ax"
1072 +3:     movl $0,DS(%esp)
1073 +       jmp 1b
1074 +4:     movl $0,ES(%esp)
1075 +       jmp 2b
1076 +.previous
1077 +.section __ex_table,"a"
1078 +       .align 4
1079 +       .long 1b,3b
1080 +       .long 2b,4b
1081 +.previous
1082  
1083         # system call handler stub
1084  ENTRY(system_call)
1085 @@ -247,6 +293,10 @@ syscall_exit:
1086         testw $_TIF_ALLWORK_MASK, %cx   # current->work
1087         jne syscall_exit_work
1088  
1089 +#ifdef CONFIG_PAX_RANDKSTACK
1090 +       call pax_randomize_kstack
1091 +#endif
1092 +
1093  restore_all:
1094         movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
1095         # Warning: OLDSS(%esp) contains the wrong/random values if we
1096 @@ -402,7 +452,7 @@ syscall_badsys:
1097   * Build the entry stubs and pointer table with
1098   * some assembler magic.
1099   */
1100 -.data
1101 +.section .rodata,"a",@progbits
1102  ENTRY(interrupt)
1103  .text
1104  
1105 @@ -412,7 +462,7 @@ ENTRY(irq_entries_start)
1106         ALIGN
1107  1:     pushl $vector-256
1108         jmp common_interrupt
1109 -.data
1110 +.section .rodata,"a",@progbits
1111         .long 1b
1112  .text
1113  vector=vector+1
1114 @@ -459,10 +509,19 @@ error_code:
1115         movl ORIG_EAX(%esp), %edx       # get the error code
1116         movl %eax, ORIG_EAX(%esp)
1117         movl %ecx, ES(%esp)
1118 -       movl $(__USER_DS), %ecx
1119 +       movl $(__KERNEL_DS), %ecx
1120         movl %ecx, %ds
1121         movl %ecx, %es
1122         movl %esp,%eax                  # pt_regs pointer
1123 +
1124 +#ifdef CONFIG_PAX_KERNEXEC
1125 +       movl %cr0, %ecx
1126 +       movl %ecx, %esi
1127 +       orl $0x10000, %ecx
1128 +       xorl %ecx, %esi
1129 +       movl %ecx, %cr0
1130 +#endif
1131 +
1132         call *%edi
1133         jmp ret_from_exception
1134  
1135 @@ -558,6 +617,13 @@ nmi_stack_correct:
1136         xorl %edx,%edx          # zero error code
1137         movl %esp,%eax          # pt_regs pointer
1138         call do_nmi
1139 +
1140 +#ifdef CONFIG_PAX_KERNEXEC
1141 +       movl %cr0, %edx
1142 +       xorl %esi, %edx
1143 +       movl %edx, %cr0
1144 +#endif
1145 +
1146         jmp restore_all
1147  
1148  nmi_stack_fixup:
1149 @@ -588,6 +654,13 @@ nmi_16bit_stack:
1150         FIXUP_ESPFIX_STACK              # %eax == %esp
1151         xorl %edx,%edx                  # zero error code
1152         call do_nmi
1153 +
1154 +#ifdef CONFIG_PAX_KERNEXEC
1155 +       movl %cr0, %edx
1156 +       xorl %esi, %edx
1157 +       movl %edx, %cr0
1158 +#endif
1159 +
1160         RESTORE_REGS
1161         lss 12+4(%esp), %esp            # back to 16bit stack
1162  1:     iret
1163 @@ -663,7 +736,6 @@ ENTRY(spurious_interrupt_bug)
1164         pushl $do_spurious_interrupt_bug
1165         jmp error_code
1166  
1167 -.section .rodata,"a"
1168  #include "syscall_table.S"
1169  
1170  syscall_table_size=(.-sys_call_table)
1171 diff -urNp linux-2.6.17.7/arch/i386/kernel/head.S linux-2.6.17.7/arch/i386/kernel/head.S
1172 --- linux-2.6.17.7/arch/i386/kernel/head.S      2006-07-24 23:36:01.000000000 -0400
1173 +++ linux-2.6.17.7/arch/i386/kernel/head.S      2006-08-01 20:29:45.000000000 -0400
1174 @@ -46,6 +46,16 @@
1175   */
1176  #define INIT_MAP_BEYOND_END    (128*1024)
1177  
1178 +#ifdef CONFIG_PAX_KERNEXEC
1179 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1180 +.fill 4096,1,0xcc
1181 +#endif
1182 +
1183 +/*
1184 + * Real beginning of normal "text" segment
1185 + */
1186 +ENTRY(stext)
1187 +ENTRY(_stext)
1188  
1189  /*
1190   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
1191 @@ -67,6 +77,26 @@ ENTRY(startup_32)
1192         movl %eax,%fs
1193         movl %eax,%gs
1194  
1195 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1196 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1197 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1198 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0f300),%eax
1199 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_DEFAULT_USER_DS * 8 + 4)
1200 +#endif
1201 +
1202 +#ifdef CONFIG_PAX_KERNEXEC
1203 +       movl $ __KERNEL_TEXT_OFFSET,%eax
1204 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1205 +       rorl $16,%eax
1206 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1207 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1208 +
1209 +       movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
1210 +       movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
1211 +       rorl $16,%eax
1212 +       movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
1213 +#endif
1214 +
1215  /*
1216   * Clear BSS first so that there are no surprises...
1217   * No need to cld as DF is already clear from cld above...
1218 @@ -114,24 +144,42 @@ ENTRY(startup_32)
1219   * Warning: don't use %esi or the stack in this code.  However, %esp
1220   * can be used as a GPR if you really need it...
1221   */
1222 -page_pde_offset = (__PAGE_OFFSET >> 20);
1223 -
1224 +#ifdef CONFIG_X86_PAE
1225 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
1226 +#else
1227 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
1228 +#endif
1229         movl $(pg0 - __PAGE_OFFSET), %edi
1230 +#ifdef CONFIG_X86_PAE
1231 +       movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1232 +#else
1233         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1234 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
1235 +#endif
1236 +       movl $0x063, %eax                       /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1237  10:
1238 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
1239 +       leal 0x063(%edi),%ecx                   /* Create PDE entry */
1240         movl %ecx,(%edx)                        /* Store identity PDE entry */
1241         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
1242 +#ifdef CONFIG_X86_PAE
1243 +       movl $0,4(%edx)
1244 +       movl $0,page_pde_offset+4(%edx)
1245 +       addl $8,%edx
1246 +       movl $512, %ecx
1247 +#else
1248         addl $4,%edx
1249         movl $1024, %ecx
1250 +#endif
1251  11:
1252         stosl
1253 +#ifdef CONFIG_X86_PAE
1254 +       movl $0,(%edi)
1255 +       addl $4,%edi
1256 +#endif
1257         addl $0x1000,%eax
1258         loop 11b
1259         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1260 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1261 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1262 +       /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1263 +       leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1264         cmpl %ebp,%eax
1265         jb 10b
1266         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1267 @@ -154,6 +202,11 @@ ENTRY(startup_32_smp)
1268         movl %eax,%fs
1269         movl %eax,%gs
1270  
1271 +       /* This is a secondary processor (AP) */
1272 +       xorl %ebx,%ebx
1273 +       incl %ebx
1274 +#endif /* CONFIG_SMP */
1275 +
1276  /*
1277   *     New page tables may be in 4Mbyte page mode and may
1278   *     be using the global pages. 
1279 @@ -169,26 +222,27 @@ ENTRY(startup_32_smp)
1280   *     not yet offset PAGE_OFFSET..
1281   */
1282  #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1283 +3:
1284         movl cr4_bits,%edx
1285         andl %edx,%edx
1286 -       jz 6f
1287 +       jz 5f
1288         movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
1289         orl %edx,%eax
1290         movl %eax,%cr4
1291  
1292 -       btl $5, %eax            # check if PAE is enabled
1293 -       jnc 6f
1294 +#ifdef CONFIG_X86_PAE
1295 +       movl %ebx,%edi
1296  
1297         /* Check if extended functions are implemented */
1298         movl $0x80000000, %eax
1299         cpuid
1300         cmpl $0x80000000, %eax
1301 -       jbe 6f
1302 +       jbe 4f
1303         mov $0x80000001, %eax
1304         cpuid
1305         /* Execute Disable bit supported? */
1306         btl $20, %edx
1307 -       jnc 6f
1308 +       jnc 4f
1309  
1310         /* Setup EFER (Extended Feature Enable Register) */
1311         movl $0xc0000080, %ecx
1312 @@ -197,14 +251,12 @@ ENTRY(startup_32_smp)
1313         btsl $11, %eax
1314         /* Make changes effective */
1315         wrmsr
1316 +       btsl $63,__supported_pte_mask-__PAGE_OFFSET
1317  
1318 -6:
1319 -       /* This is a secondary processor (AP) */
1320 -       xorl %ebx,%ebx
1321 -       incl %ebx
1322 -
1323 -3:
1324 -#endif /* CONFIG_SMP */
1325 +4:
1326 +       movl %edi,%ebx
1327 +#endif
1328 +5:
1329  
1330  /*
1331   * Enable paging
1332 @@ -229,9 +281,7 @@ ENTRY(startup_32_smp)
1333  
1334  #ifdef CONFIG_SMP
1335         andl %ebx,%ebx
1336 -       jz  1f                          /* Initial CPU cleans BSS */
1337 -       jmp checkCPUtype
1338 -1:
1339 +       jnz checkCPUtype        /* Initial CPU cleans BSS */
1340  #endif /* CONFIG_SMP */
1341  
1342  /*
1343 @@ -308,8 +358,6 @@ is386:      movl $2,%ecx            # set MP
1344         ljmp $(__KERNEL_CS),$1f
1345  1:     movl $(__KERNEL_DS),%eax        # reload all the segment registers
1346         movl %eax,%ss                   # after changing gdt.
1347 -
1348 -       movl $(__USER_DS),%eax          # DS/ES contains default USER segment
1349         movl %eax,%ds
1350         movl %eax,%es
1351  
1352 @@ -412,32 +460,50 @@ ignore_int:
1353  #endif
1354         iret
1355  
1356 -/*
1357 - * Real beginning of normal "text" segment
1358 - */
1359 -ENTRY(stext)
1360 -ENTRY(_stext)
1361 -
1362 -/*
1363 - * BSS section
1364 - */
1365 -.section ".bss.page_aligned","w"
1366 +.section .swapper_pg_dir,"a",@progbits
1367  ENTRY(swapper_pg_dir)
1368 +#ifdef CONFIG_X86_PAE
1369 +       .long swapper_pm_dir-__PAGE_OFFSET+1
1370 +       .long 0
1371 +       .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1372 +       .long 0
1373 +       .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1374 +       .long 0
1375 +       .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1376 +       .long 0
1377 +#else
1378         .fill 1024,4,0
1379 +#endif
1380 +
1381 +#ifdef CONFIG_X86_PAE
1382 +.section .swapper_pm_dir,"a",@progbits
1383 +ENTRY(swapper_pm_dir)
1384 +       .fill 512,8,0
1385 +       .fill 512,8,0
1386 +       .fill 512,8,0
1387 +       .fill 512,8,0
1388 +#endif
1389 +
1390 +.section .empty_zero_page,"a",@progbits
1391  ENTRY(empty_zero_page)
1392         .fill 4096,1,0
1393  
1394  /*
1395 - * This starts the data section.
1396 - */
1397 -.data
1398 + * The IDT has to be page-aligned to simplify the Pentium
1399 + * F0 0F bug workaround.. We have a special link segment
1400 + * for this.
1401 + */
1402 +.section .idt,"a",@progbits
1403 +ENTRY(idt_table)
1404 +       .fill 256,8,0
1405 +
1406 +.section .rodata,"a",@progbits
1407 +ready: .byte 0
1408  
1409  ENTRY(stack_start)
1410 -       .long init_thread_union+THREAD_SIZE
1411 +       .long init_thread_union+THREAD_SIZE-8
1412         .long __BOOT_DS
1413  
1414 -ready: .byte 0
1415 -
1416  int_msg:
1417         .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
1418  
1419 @@ -465,7 +531,7 @@ idt_descr:
1420  
1421  # boot GDT descriptor (later on used by CPU#0):
1422         .word 0                         # 32 bit align gdt_desc.address
1423 -cpu_gdt_descr:
1424 +ENTRY(cpu_gdt_descr)
1425         .word GDT_ENTRIES*8-1
1426         .long cpu_gdt_table
1427  
1428 @@ -476,13 +542,13 @@ cpu_gdt_descr:
1429         .align L1_CACHE_BYTES
1430  ENTRY(boot_gdt_table)
1431         .fill GDT_ENTRY_BOOT_CS,8,0
1432 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
1433 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
1434 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
1435 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
1436  
1437  /*
1438   * The Global Descriptor Table contains 28 quadwords, per-CPU.
1439   */
1440 -       .align L1_CACHE_BYTES
1441 +       .align 4096
1442  ENTRY(cpu_gdt_table)
1443         .quad 0x0000000000000000        /* NULL descriptor */
1444         .quad 0x0000000000000000        /* 0x0b reserved */
1445 @@ -497,10 +563,10 @@ ENTRY(cpu_gdt_table)
1446         .quad 0x0000000000000000        /* 0x53 reserved */
1447         .quad 0x0000000000000000        /* 0x5b reserved */
1448  
1449 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1450 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1451 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1452 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1453 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1454 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1455 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1456 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1457  
1458         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
1459         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
1460 @@ -510,24 +576,30 @@ ENTRY(cpu_gdt_table)
1461          * They code segments and data segments have fixed 64k limits,
1462          * the transfer segment sizes are set at run time.
1463          */
1464 -       .quad 0x00409a000000ffff        /* 0x90 32-bit code */
1465 -       .quad 0x00009a000000ffff        /* 0x98 16-bit code */
1466 -       .quad 0x000092000000ffff        /* 0xa0 16-bit data */
1467 -       .quad 0x0000920000000000        /* 0xa8 16-bit data */
1468 -       .quad 0x0000920000000000        /* 0xb0 16-bit data */
1469 +       .quad 0x00409b000000ffff        /* 0x90 32-bit code */
1470 +       .quad 0x00009b000000ffff        /* 0x98 16-bit code */
1471 +       .quad 0x000093000000ffff        /* 0xa0 16-bit data */
1472 +       .quad 0x0000930000000000        /* 0xa8 16-bit data */
1473 +       .quad 0x0000930000000000        /* 0xb0 16-bit data */
1474  
1475         /*
1476          * The APM segments have byte granularity and their bases
1477          * are set at run time.  All have 64k limits.
1478          */
1479 -       .quad 0x00409a000000ffff        /* 0xb8 APM CS    code */
1480 -       .quad 0x00009a000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1481 -       .quad 0x004092000000ffff        /* 0xc8 APM DS    data */
1482 +       .quad 0x00409b000000ffff        /* 0xb8 APM CS    code */
1483 +       .quad 0x00009b000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1484 +       .quad 0x004093000000ffff        /* 0xc8 APM DS    data */
1485  
1486 -       .quad 0x0000920000000000        /* 0xd0 - ESPFIX 16-bit SS */
1487 +       .quad 0x0000930000000000        /* 0xd0 - ESPFIX 16-bit SS */
1488         .quad 0x0000000000000000        /* 0xd8 - unused */
1489         .quad 0x0000000000000000        /* 0xe0 - unused */
1490         .quad 0x0000000000000000        /* 0xe8 - unused */
1491         .quad 0x0000000000000000        /* 0xf0 - unused */
1492         .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
1493  
1494 +       /* Be sure this is zeroed to avoid false validations in Xen */
1495 +       .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
1496 +
1497 +#ifdef CONFIG_SMP
1498 +       .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
1499 +#endif
1500 diff -urNp linux-2.6.17.7/arch/i386/kernel/i386_ksyms.c linux-2.6.17.7/arch/i386/kernel/i386_ksyms.c
1501 --- linux-2.6.17.7/arch/i386/kernel/i386_ksyms.c        2006-07-24 23:36:01.000000000 -0400
1502 +++ linux-2.6.17.7/arch/i386/kernel/i386_ksyms.c        2006-08-01 20:52:30.000000000 -0400
1503 @@ -3,12 +3,16 @@
1504  #include <asm/checksum.h>
1505  #include <asm/desc.h>
1506  
1507 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
1508 +
1509  EXPORT_SYMBOL(__down_failed);
1510  EXPORT_SYMBOL(__down_failed_interruptible);
1511  EXPORT_SYMBOL(__down_failed_trylock);
1512  EXPORT_SYMBOL(__up_wakeup);
1513  /* Networking helper routines. */
1514  EXPORT_SYMBOL(csum_partial_copy_generic);
1515 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
1516 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
1517  
1518  EXPORT_SYMBOL(__get_user_1);
1519  EXPORT_SYMBOL(__get_user_2);
1520 diff -urNp linux-2.6.17.7/arch/i386/kernel/init_task.c linux-2.6.17.7/arch/i386/kernel/init_task.c
1521 --- linux-2.6.17.7/arch/i386/kernel/init_task.c 2006-07-24 23:36:01.000000000 -0400
1522 +++ linux-2.6.17.7/arch/i386/kernel/init_task.c 2006-08-01 20:29:45.000000000 -0400
1523 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
1524   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
1525   * no more per-task TSS's.
1526   */ 
1527 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
1528 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
1529  
1530 diff -urNp linux-2.6.17.7/arch/i386/kernel/ioport.c linux-2.6.17.7/arch/i386/kernel/ioport.c
1531 --- linux-2.6.17.7/arch/i386/kernel/ioport.c    2006-07-24 23:36:01.000000000 -0400
1532 +++ linux-2.6.17.7/arch/i386/kernel/ioport.c    2006-08-01 20:29:45.000000000 -0400
1533 @@ -16,6 +16,7 @@
1534  #include <linux/stddef.h>
1535  #include <linux/slab.h>
1536  #include <linux/thread_info.h>
1537 +#include <linux/grsecurity.h>
1538  
1539  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
1540  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
1541 @@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
1542  
1543         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
1544                 return -EINVAL;
1545 +#ifdef CONFIG_GRKERNSEC_IO
1546 +       if (turn_on) {
1547 +               gr_handle_ioperm();
1548 +#else
1549         if (turn_on && !capable(CAP_SYS_RAWIO))
1550 +#endif
1551                 return -EPERM;
1552 -
1553 +#ifdef CONFIG_GRKERNSEC_IO
1554 +       }
1555 +#endif
1556         /*
1557          * If it's the first ioperm() call in this thread's lifetime, set the
1558          * IO bitmap up. ioperm() is much less timing critical than clone(),
1559 @@ -88,7 +96,7 @@ asmlinkage long sys_ioperm(unsigned long
1560          * because the ->io_bitmap_max value must match the bitmap
1561          * contents:
1562          */
1563 -       tss = &per_cpu(init_tss, get_cpu());
1564 +       tss = init_tss + get_cpu();
1565  
1566         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
1567  
1568 @@ -142,8 +150,13 @@ asmlinkage long sys_iopl(unsigned long u
1569                 return -EINVAL;
1570         /* Trying to gain more privileges? */
1571         if (level > old) {
1572 +#ifdef CONFIG_GRKERNSEC_IO
1573 +               gr_handle_iopl();
1574 +               return -EPERM;
1575 +#else
1576                 if (!capable(CAP_SYS_RAWIO))
1577                         return -EPERM;
1578 +#endif
1579         }
1580         t->iopl = level << 12;
1581         regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
1582 diff -urNp linux-2.6.17.7/arch/i386/kernel/irq.c linux-2.6.17.7/arch/i386/kernel/irq.c
1583 --- linux-2.6.17.7/arch/i386/kernel/irq.c       2006-07-24 23:36:01.000000000 -0400
1584 +++ linux-2.6.17.7/arch/i386/kernel/irq.c       2006-08-01 20:29:45.000000000 -0400
1585 @@ -91,7 +91,7 @@ fastcall unsigned int do_IRQ(struct pt_r
1586                 int arg1, arg2, ebx;
1587  
1588                 /* build the stack frame on the IRQ stack */
1589 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1590 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1591                 irqctx->tinfo.task = curctx->tinfo.task;
1592                 irqctx->tinfo.previous_esp = current_stack_pointer;
1593  
1594 @@ -119,10 +119,10 @@ fastcall unsigned int do_IRQ(struct pt_r
1595   * gcc's 3.0 and earlier don't handle that correctly.
1596   */
1597  static char softirq_stack[NR_CPUS * THREAD_SIZE]
1598 -               __attribute__((__aligned__(THREAD_SIZE)));
1599 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1600  
1601  static char hardirq_stack[NR_CPUS * THREAD_SIZE]
1602 -               __attribute__((__aligned__(THREAD_SIZE)));
1603 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1604  
1605  /*
1606   * allocate per-cpu stacks for hardirq and for softirq processing
1607 @@ -182,7 +182,7 @@ asmlinkage void do_softirq(void)
1608                 irqctx->tinfo.previous_esp = current_stack_pointer;
1609  
1610                 /* build the stack frame on the softirq stack */
1611 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1612 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1613  
1614                 asm volatile(
1615                         "       xchgl   %%ebx,%%esp     \n"
1616 diff -urNp linux-2.6.17.7/arch/i386/kernel/ldt.c linux-2.6.17.7/arch/i386/kernel/ldt.c
1617 --- linux-2.6.17.7/arch/i386/kernel/ldt.c       2006-07-24 23:36:01.000000000 -0400
1618 +++ linux-2.6.17.7/arch/i386/kernel/ldt.c       2006-08-01 20:29:45.000000000 -0400
1619 @@ -103,6 +103,19 @@ int init_new_context(struct task_struct 
1620                 retval = copy_ldt(&mm->context, &old_mm->context);
1621                 up(&old_mm->context.sem);
1622         }
1623 +
1624 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1625 +       if (!mm->context.user_cs_limit) {
1626 +               mm->context.user_cs_base = 0UL;
1627 +               mm->context.user_cs_limit = ~0UL;
1628 +
1629 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
1630 +               cpus_clear(mm->context.cpu_user_cs_mask);
1631 +#endif
1632 +
1633 +       }
1634 +#endif
1635 +
1636         return retval;
1637  }
1638  
1639 @@ -160,7 +173,7 @@ static int read_default_ldt(void __user 
1640  {
1641         int err;
1642         unsigned long size;
1643 -       void *address;
1644 +       const void *address;
1645  
1646         err = 0;
1647         address = &default_ldt[0];
1648 @@ -215,6 +228,13 @@ static int write_ldt(void __user * ptr, 
1649                 }
1650         }
1651  
1652 +#ifdef CONFIG_PAX_SEGMEXEC
1653 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
1654 +               error = -EINVAL;
1655 +               goto out_unlock;
1656 +       }
1657 +#endif
1658 +
1659         entry_1 = LDT_entry_a(&ldt_info);
1660         entry_2 = LDT_entry_b(&ldt_info);
1661         if (oldmode)
1662 diff -urNp linux-2.6.17.7/arch/i386/kernel/module.c linux-2.6.17.7/arch/i386/kernel/module.c
1663 --- linux-2.6.17.7/arch/i386/kernel/module.c    2006-07-24 23:36:01.000000000 -0400
1664 +++ linux-2.6.17.7/arch/i386/kernel/module.c    2006-08-01 20:29:45.000000000 -0400
1665 @@ -21,6 +21,7 @@
1666  #include <linux/fs.h>
1667  #include <linux/string.h>
1668  #include <linux/kernel.h>
1669 +#include <asm/desc.h>
1670  
1671  #if 0
1672  #define DEBUGP printk
1673 @@ -32,9 +33,30 @@ void *module_alloc(unsigned long size)
1674  {
1675         if (size == 0)
1676                 return NULL;
1677 +
1678 +#ifdef CONFIG_PAX_KERNEXEC
1679 +       return vmalloc(size);
1680 +#else
1681         return vmalloc_exec(size);
1682 +#endif
1683 +
1684  }
1685  
1686 +#ifdef CONFIG_PAX_KERNEXEC
1687 +void *module_alloc_exec(unsigned long size)
1688 +{
1689 +       struct vm_struct *area;
1690 +
1691 +       if (size == 0)
1692 +               return NULL;
1693 +
1694 +       area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
1695 +       if (area)
1696 +               return area->addr;
1697 +
1698 +       return NULL;
1699 +}
1700 +#endif
1701  
1702  /* Free memory returned from module_alloc */
1703  void module_free(struct module *mod, void *module_region)
1704 @@ -44,6 +66,45 @@ void module_free(struct module *mod, voi
1705             table entries. */
1706  }
1707  
1708 +#ifdef CONFIG_PAX_KERNEXEC
1709 +void module_free_exec(struct module *mod, void *module_region)
1710 +{
1711 +       struct vm_struct **p, *tmp;
1712 +
1713 +       if (!module_region)
1714 +               return;
1715 +
1716 +       if ((PAGE_SIZE-1) & (unsigned long)module_region) {
1717 +               printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
1718 +               WARN_ON(1);
1719 +               return;
1720 +       }
1721 +
1722 +       write_lock(&vmlist_lock);
1723 +       for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
1724 +                if (tmp->addr == module_region)
1725 +                       break;
1726 +
1727 +       if (tmp) {
1728 +               unsigned long cr0;
1729 +
1730 +               pax_open_kernel(cr0);
1731 +               memset(tmp->addr, 0xCC, tmp->size);
1732 +               pax_close_kernel(cr0);
1733 +
1734 +               *p = tmp->next;
1735 +               kfree(tmp);
1736 +       }
1737 +       write_unlock(&vmlist_lock);
1738 +
1739 +       if (!tmp) {
1740 +               printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
1741 +                               module_region);
1742 +               WARN_ON(1);
1743 +       }
1744 +}
1745 +#endif
1746 +
1747  /* We don't need anything special. */
1748  int module_frob_arch_sections(Elf_Ehdr *hdr,
1749                               Elf_Shdr *sechdrs,
1750 @@ -62,14 +123,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1751         unsigned int i;
1752         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
1753         Elf32_Sym *sym;
1754 -       uint32_t *location;
1755 +       uint32_t *plocation, location;
1756  
1757         DEBUGP("Applying relocate section %u to %u\n", relsec,
1758                sechdrs[relsec].sh_info);
1759         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
1760                 /* This is where to make the change */
1761 -               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
1762 -                       + rel[i].r_offset;
1763 +               plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
1764 +               location = (uint32_t)plocation;
1765 +               if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
1766 +                       plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
1767                 /* This is the symbol it is referring to.  Note that all
1768                    undefined symbols have been resolved.  */
1769                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
1770 @@ -78,11 +141,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1771                 switch (ELF32_R_TYPE(rel[i].r_info)) {
1772                 case R_386_32:
1773                         /* We add the value into the location given */
1774 -                       *location += sym->st_value;
1775 +                       *plocation += sym->st_value;
1776                         break;
1777                 case R_386_PC32:
1778                         /* Add the value, subtract its postition */
1779 -                       *location += sym->st_value - (uint32_t)location;
1780 +                       *plocation += sym->st_value - location;
1781                         break;
1782                 default:
1783                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
1784 diff -urNp linux-2.6.17.7/arch/i386/kernel/process.c linux-2.6.17.7/arch/i386/kernel/process.c
1785 --- linux-2.6.17.7/arch/i386/kernel/process.c   2006-07-24 23:36:01.000000000 -0400
1786 +++ linux-2.6.17.7/arch/i386/kernel/process.c   2006-08-01 20:29:45.000000000 -0400
1787 @@ -69,7 +69,7 @@ EXPORT_SYMBOL(boot_option_idle_override)
1788   */
1789  unsigned long thread_saved_pc(struct task_struct *tsk)
1790  {
1791 -       return ((unsigned long *)tsk->thread.esp)[3];
1792 +       return tsk->thread.eip;
1793  }
1794  
1795  /*
1796 @@ -294,7 +294,7 @@ void show_regs(struct pt_regs * regs)
1797         printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
1798         print_symbol("EIP is at %s\n", regs->eip);
1799  
1800 -       if (user_mode_vm(regs))
1801 +       if (user_mode(regs))
1802                 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
1803         printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
1804                regs->eflags, print_tainted(), system_utsname.release,
1805 @@ -343,8 +343,8 @@ int kernel_thread(int (*fn)(void *), voi
1806         regs.ebx = (unsigned long) fn;
1807         regs.edx = (unsigned long) arg;
1808  
1809 -       regs.xds = __USER_DS;
1810 -       regs.xes = __USER_DS;
1811 +       regs.xds = __KERNEL_DS;
1812 +       regs.xes = __KERNEL_DS;
1813         regs.orig_eax = -1;
1814         regs.eip = (unsigned long) kernel_thread_helper;
1815         regs.xcs = __KERNEL_CS;
1816 @@ -366,7 +366,7 @@ void exit_thread(void)
1817         /* The process may have allocated an io port bitmap... nuke it. */
1818         if (unlikely(NULL != t->io_bitmap_ptr)) {
1819                 int cpu = get_cpu();
1820 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
1821 +               struct tss_struct *tss = init_tss + cpu;
1822  
1823                 kfree(t->io_bitmap_ptr);
1824                 t->io_bitmap_ptr = NULL;
1825 @@ -386,6 +386,9 @@ void flush_thread(void)
1826  {
1827         struct task_struct *tsk = current;
1828  
1829 +       __asm__("mov %0,%%fs\n"
1830 +               "mov %0,%%gs\n"
1831 +               : : "r" (0) : "memory");
1832         memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
1833         memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
1834         /*
1835 @@ -418,7 +421,7 @@ int copy_thread(int nr, unsigned long cl
1836         struct task_struct *tsk;
1837         int err;
1838  
1839 -       childregs = task_pt_regs(p);
1840 +       childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
1841         *childregs = *regs;
1842         childregs->eax = 0;
1843         childregs->esp = esp;
1844 @@ -461,6 +464,11 @@ int copy_thread(int nr, unsigned long cl
1845                 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1846                         goto out;
1847  
1848 +#ifdef CONFIG_PAX_SEGMEXEC
1849 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1850 +                       goto out;
1851 +#endif
1852 +
1853                 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
1854                 desc->a = LDT_entry_a(&info);
1855                 desc->b = LDT_entry_b(&info);
1856 @@ -625,7 +633,11 @@ struct task_struct fastcall * __switch_t
1857         struct thread_struct *prev = &prev_p->thread,
1858                                  *next = &next_p->thread;
1859         int cpu = smp_processor_id();
1860 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1861 +       struct tss_struct *tss = init_tss + cpu;
1862 +
1863 +#ifdef CONFIG_PAX_KERNEXEC
1864 +       unsigned long cr0;
1865 +#endif
1866  
1867         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
1868  
1869 @@ -648,11 +660,23 @@ struct task_struct fastcall * __switch_t
1870         savesegment(fs, prev->fs);
1871         savesegment(gs, prev->gs);
1872  
1873 +#ifdef CONFIG_PAX_KERNEXEC
1874 +       pax_open_kernel(cr0);
1875 +#endif
1876 +
1877 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1878 +       __set_fs(get_fs(), cpu);
1879 +#endif
1880 +
1881         /*
1882          * Load the per-thread Thread-Local Storage descriptor.
1883          */
1884         load_TLS(next, cpu);
1885  
1886 +#ifdef CONFIG_PAX_KERNEXEC
1887 +       pax_close_kernel(cr0);
1888 +#endif
1889 +
1890         /*
1891          * Restore %fs and %gs if needed.
1892          *
1893 @@ -806,8 +830,18 @@ asmlinkage int sys_set_thread_area(struc
1894         struct desc_struct *desc;
1895         int cpu, idx;
1896  
1897 +#ifdef CONFIG_PAX_KERNEXEC
1898 +       unsigned long cr0;
1899 +#endif
1900 +
1901         if (copy_from_user(&info, u_info, sizeof(info)))
1902                 return -EFAULT;
1903 +
1904 +#ifdef CONFIG_PAX_SEGMEXEC
1905 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1906 +               return -EINVAL;
1907 +#endif
1908 +
1909         idx = info.entry_number;
1910  
1911         /*
1912 @@ -839,8 +873,17 @@ asmlinkage int sys_set_thread_area(struc
1913                 desc->a = LDT_entry_a(&info);
1914                 desc->b = LDT_entry_b(&info);
1915         }
1916 +
1917 +#ifdef CONFIG_PAX_KERNEXEC
1918 +       pax_open_kernel(cr0);
1919 +#endif
1920 +
1921         load_TLS(t, cpu);
1922  
1923 +#ifdef CONFIG_PAX_KERNEXEC
1924 +       pax_close_kernel(cr0);
1925 +#endif
1926 +
1927         put_cpu();
1928  
1929         return 0;
1930 @@ -896,9 +939,27 @@ asmlinkage int sys_get_thread_area(struc
1931         return 0;
1932  }
1933  
1934 -unsigned long arch_align_stack(unsigned long sp)
1935 +#ifdef CONFIG_PAX_RANDKSTACK
1936 +asmlinkage void pax_randomize_kstack(void)
1937  {
1938 -       if (randomize_va_space)
1939 -               sp -= get_random_int() % 8192;
1940 -       return sp & ~0xf;
1941 +       struct tss_struct *tss = init_tss + smp_processor_id();
1942 +       unsigned long time;
1943 +
1944 +       if (!randomize_va_space)
1945 +               return;
1946 +
1947 +       rdtscl(time);
1948 +
1949 +       /* P4 seems to return a 0 LSB, ignore it */
1950 +#ifdef CONFIG_MPENTIUM4
1951 +       time &= 0x1EUL;
1952 +       time <<= 2;
1953 +#else
1954 +       time &= 0xFUL;
1955 +       time <<= 3;
1956 +#endif
1957 +
1958 +       tss->esp0 ^= time;
1959 +       current->thread.esp0 = tss->esp0;
1960  }
1961 +#endif
1962 diff -urNp linux-2.6.17.7/arch/i386/kernel/ptrace.c linux-2.6.17.7/arch/i386/kernel/ptrace.c
1963 --- linux-2.6.17.7/arch/i386/kernel/ptrace.c    2006-07-24 23:36:01.000000000 -0400
1964 +++ linux-2.6.17.7/arch/i386/kernel/ptrace.c    2006-08-01 20:29:45.000000000 -0400
1965 @@ -17,6 +17,7 @@
1966  #include <linux/audit.h>
1967  #include <linux/seccomp.h>
1968  #include <linux/signal.h>
1969 +#include <linux/grsecurity.h>
1970  
1971  #include <asm/uaccess.h>
1972  #include <asm/pgtable.h>
1973 @@ -342,6 +343,11 @@ ptrace_set_thread_area(struct task_struc
1974         if (copy_from_user(&info, user_desc, sizeof(info)))
1975                 return -EFAULT;
1976  
1977 +#ifdef CONFIG_PAX_SEGMEXEC
1978 +       if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1979 +               return -EINVAL;
1980 +#endif
1981 +
1982         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1983                 return -EINVAL;
1984  
1985 @@ -432,6 +438,17 @@ long arch_ptrace(struct task_struct *chi
1986                           if(addr == (long) &dummy->u_debugreg[5]) break;
1987                           if(addr < (long) &dummy->u_debugreg[4] &&
1988                              ((unsigned long) data) >= TASK_SIZE-3) break;
1989 +
1990 +#ifdef CONFIG_GRKERNSEC
1991 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
1992 +                            addr <= (long) &dummy->u_debugreg[3]){
1993 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
1994 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
1995 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
1996 +                               if((type & 1) && (data & align))
1997 +                                       break;
1998 +                         }
1999 +#endif
2000                           
2001                           /* Sanity-check data. Take one half-byte at once with
2002                            * check = (val >> (16 + 4*i)) & 0xf. It contains the
2003 @@ -645,7 +662,7 @@ void send_sigtrap(struct task_struct *ts
2004         info.si_code = TRAP_BRKPT;
2005  
2006         /* User-mode eip? */
2007 -       info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2008 +       info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2009  
2010         /* Send us the fakey SIGTRAP */
2011         force_sig_info(SIGTRAP, &info, tsk);
2012 diff -urNp linux-2.6.17.7/arch/i386/kernel/reboot.c linux-2.6.17.7/arch/i386/kernel/reboot.c
2013 --- linux-2.6.17.7/arch/i386/kernel/reboot.c    2006-07-24 23:36:01.000000000 -0400
2014 +++ linux-2.6.17.7/arch/i386/kernel/reboot.c    2006-08-01 20:29:45.000000000 -0400
2015 @@ -138,18 +138,18 @@ core_initcall(reboot_init);
2016     doesn't work with at least one type of 486 motherboard.  It is easy
2017     to stop this code working; hence the copious comments. */
2018  
2019 -static unsigned long long
2020 +static const unsigned long long
2021  real_mode_gdt_entries [3] =
2022  {
2023         0x0000000000000000ULL,  /* Null descriptor */
2024 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
2025 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
2026 +       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
2027 +       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
2028  };
2029  
2030  static struct
2031  {
2032         unsigned short       size __attribute__ ((packed));
2033 -       unsigned long long * base __attribute__ ((packed));
2034 +       const unsigned long long * base __attribute__ ((packed));
2035  }
2036  real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
2037  real_mode_idt = { 0x3ff, NULL },
2038 @@ -203,6 +203,10 @@ void machine_real_restart(unsigned char 
2039  {
2040         unsigned long flags;
2041  
2042 +#ifdef CONFIG_PAX_KERNEXEC
2043 +       unsigned long cr0;
2044 +#endif
2045 +
2046         local_irq_disable();
2047  
2048         /* Write zero to CMOS register number 0x0f, which the BIOS POST
2049 @@ -223,9 +227,17 @@ void machine_real_restart(unsigned char 
2050            from the kernel segment.  This assumes the kernel segment starts at
2051            virtual address PAGE_OFFSET. */
2052  
2053 +#ifdef CONFIG_PAX_KERNEXEC
2054 +       pax_open_kernel(cr0);
2055 +#endif
2056 +
2057         memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2058                 sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2059  
2060 +#ifdef CONFIG_PAX_KERNEXEC
2061 +       pax_close_kernel(cr0);
2062 +#endif
2063 +
2064         /*
2065          * Use `swapper_pg_dir' as our page directory.
2066          */
2067 diff -urNp linux-2.6.17.7/arch/i386/kernel/setup.c linux-2.6.17.7/arch/i386/kernel/setup.c
2068 --- linux-2.6.17.7/arch/i386/kernel/setup.c     2006-07-24 23:36:01.000000000 -0400
2069 +++ linux-2.6.17.7/arch/i386/kernel/setup.c     2006-08-01 20:29:45.000000000 -0400
2070 @@ -88,7 +88,11 @@ struct cpuinfo_x86 new_cpu_data __initda
2071  struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2072  EXPORT_SYMBOL(boot_cpu_data);
2073  
2074 +#ifdef CONFIG_X86_PAE
2075 +unsigned long mmu_cr4_features = X86_CR4_PAE;
2076 +#else
2077  unsigned long mmu_cr4_features;
2078 +#endif
2079  
2080  #ifdef CONFIG_ACPI
2081         int acpi_disabled = 0;
2082 @@ -1493,14 +1497,14 @@ void __init setup_arch(char **cmdline_p)
2083  
2084         if (!MOUNT_ROOT_RDONLY)
2085                 root_mountflags &= ~MS_RDONLY;
2086 -       init_mm.start_code = (unsigned long) _text;
2087 -       init_mm.end_code = (unsigned long) _etext;
2088 +       init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2089 +       init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2090         init_mm.end_data = (unsigned long) _edata;
2091         init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2092  
2093 -       code_resource.start = virt_to_phys(_text);
2094 -       code_resource.end = virt_to_phys(_etext)-1;
2095 -       data_resource.start = virt_to_phys(_etext);
2096 +       code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
2097 +       code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
2098 +       data_resource.start = virt_to_phys(_data);
2099         data_resource.end = virt_to_phys(_edata)-1;
2100  
2101         parse_cmdline_early(cmdline_p);
2102 diff -urNp linux-2.6.17.7/arch/i386/kernel/signal.c linux-2.6.17.7/arch/i386/kernel/signal.c
2103 --- linux-2.6.17.7/arch/i386/kernel/signal.c    2006-07-24 23:36:01.000000000 -0400
2104 +++ linux-2.6.17.7/arch/i386/kernel/signal.c    2006-08-01 20:29:45.000000000 -0400
2105 @@ -351,7 +351,17 @@ static int setup_frame(int sig, struct k
2106                         goto give_sigsegv;
2107         }
2108  
2109 +#ifdef CONFIG_PAX_NOVSYSCALL
2110 +       restorer = frame->retcode;
2111 +#else
2112         restorer = &__kernel_sigreturn;
2113 +
2114 +#ifdef CONFIG_PAX_SEGMEXEC
2115 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2116 +               restorer -= SEGMEXEC_TASK_SIZE;
2117 +#endif
2118 +#endif
2119 +
2120         if (ka->sa.sa_flags & SA_RESTORER)
2121                 restorer = ka->sa.sa_restorer;
2122  
2123 @@ -447,7 +457,18 @@ static int setup_rt_frame(int sig, struc
2124                 goto give_sigsegv;
2125  
2126         /* Set up to return from userspace.  */
2127 +
2128 +#ifdef CONFIG_PAX_NOVSYSCALL
2129 +       restorer = frame->retcode;
2130 +#else
2131         restorer = &__kernel_rt_sigreturn;
2132 +
2133 +#ifdef CONFIG_PAX_SEGMEXEC
2134 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2135 +               restorer -= SEGMEXEC_TASK_SIZE;
2136 +#endif
2137 +#endif
2138 +
2139         if (ka->sa.sa_flags & SA_RESTORER)
2140                 restorer = ka->sa.sa_restorer;
2141         err |= __put_user(restorer, &frame->pretcode);
2142 @@ -580,7 +601,7 @@ static void fastcall do_signal(struct pt
2143          * before reaching here, so testing against kernel
2144          * CS suffices.
2145          */
2146 -       if (!user_mode(regs))
2147 +       if (!user_mode_novm(regs))
2148                 return;
2149  
2150         if (test_thread_flag(TIF_RESTORE_SIGMASK))
2151 diff -urNp linux-2.6.17.7/arch/i386/kernel/sys_i386.c linux-2.6.17.7/arch/i386/kernel/sys_i386.c
2152 --- linux-2.6.17.7/arch/i386/kernel/sys_i386.c  2006-07-24 23:36:01.000000000 -0400
2153 +++ linux-2.6.17.7/arch/i386/kernel/sys_i386.c  2006-08-01 20:29:45.000000000 -0400
2154 @@ -99,6 +99,191 @@ out:
2155         return err;
2156  }
2157  
2158 +unsigned long
2159 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
2160 +               unsigned long len, unsigned long pgoff, unsigned long flags)
2161 +{
2162 +       struct mm_struct *mm = current->mm;
2163 +       struct vm_area_struct *vma;
2164 +       unsigned long start_addr, task_size = TASK_SIZE;
2165 +
2166 +#ifdef CONFIG_PAX_SEGMEXEC
2167 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
2168 +               task_size = SEGMEXEC_TASK_SIZE;
2169 +#endif
2170 +
2171 +       if (len > task_size)
2172 +               return -ENOMEM;
2173 +
2174 +#ifdef CONFIG_PAX_RANDMMAP
2175 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2176 +#endif
2177 +
2178 +       if (addr) {
2179 +               addr = PAGE_ALIGN(addr);
2180 +               vma = find_vma(mm, addr);
2181 +               if (task_size - len >= addr &&
2182 +                   (!vma || addr + len <= vma->vm_start))
2183 +                       return addr;
2184 +       }
2185 +       if (len > mm->cached_hole_size) {
2186 +               start_addr = addr = mm->free_area_cache;
2187 +       } else {
2188 +               start_addr = addr = mm->mmap_base;
2189 +               mm->cached_hole_size = 0;
2190 +       }
2191 +
2192 +#ifdef CONFIG_PAX_PAGEEXEC
2193 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
2194 +               start_addr = 0x00110000UL;
2195 +
2196 +#ifdef CONFIG_PAX_RANDMMAP
2197 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
2198 +                       start_addr += mm->delta_mmap & 0x03FFF000UL;
2199 +#endif
2200 +
2201 +               if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
2202 +                       start_addr = addr = mm->mmap_base;
2203 +               else
2204 +                       addr = start_addr;
2205 +       }
2206 +#endif
2207 +
2208 +full_search:
2209 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2210 +               /* At this point:  (!vma || addr < vma->vm_end). */
2211 +               if (task_size - len < addr) {
2212 +                       /*
2213 +                        * Start a new search - just in case we missed
2214 +                        * some holes.
2215 +                        */
2216 +                       if (start_addr != mm->mmap_base) {
2217 +                               start_addr = addr = mm->mmap_base;
2218 +                               mm->cached_hole_size = 0;
2219 +                               goto full_search;
2220 +                       }
2221 +                       return -ENOMEM;
2222 +               }
2223 +               if (!vma || addr + len <= vma->vm_start) {
2224 +                       /*
2225 +                        * Remember the place where we stopped the search:
2226 +                        */
2227 +                       mm->free_area_cache = addr + len;
2228 +                       return addr;
2229 +               }
2230 +               if (addr + mm->cached_hole_size < vma->vm_start)
2231 +                       mm->cached_hole_size = vma->vm_start - addr;
2232 +               addr = vma->vm_end;
2233 +               if (mm->start_brk <= addr && addr < mm->mmap_base) {
2234 +                       start_addr = addr = mm->mmap_base;
2235 +                       goto full_search;
2236 +               }
2237 +       }
2238 +}
2239 +
2240 +unsigned long
2241 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
2242 +                         const unsigned long len, const unsigned long pgoff,
2243 +                         const unsigned long flags)
2244 +{
2245 +       struct vm_area_struct *vma;
2246 +       struct mm_struct *mm = current->mm;
2247 +       unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
2248 +
2249 +#ifdef CONFIG_PAX_SEGMEXEC
2250 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
2251 +               task_size = SEGMEXEC_TASK_SIZE;
2252 +#endif
2253 +
2254 +       /* requested length too big for entire address space */
2255 +       if (len > task_size)
2256 +               return -ENOMEM;
2257 +
2258 +#ifdef CONFIG_PAX_PAGEEXEC
2259 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
2260 +               goto bottomup;
2261 +#endif
2262 +
2263 +#ifdef CONFIG_PAX_RANDMMAP
2264 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2265 +#endif
2266 +
2267 +       /* requesting a specific address */
2268 +       if (addr) {
2269 +               addr = PAGE_ALIGN(addr);
2270 +               vma = find_vma(mm, addr);
2271 +               if (task_size - len >= addr &&
2272 +                               (!vma || addr + len <= vma->vm_start))
2273 +                       return addr;
2274 +       }
2275 +
2276 +       /* check if free_area_cache is useful for us */
2277 +       if (len <= mm->cached_hole_size) {
2278 +               mm->cached_hole_size = 0;
2279 +               mm->free_area_cache = mm->mmap_base;
2280 +       }
2281 +
2282 +       /* either no address requested or can't fit in requested address hole */
2283 +       addr = mm->free_area_cache;
2284 +
2285 +       /* make sure it can fit in the remaining address space */
2286 +       if (addr > len) {
2287 +               vma = find_vma(mm, addr-len);
2288 +               if (!vma || addr <= vma->vm_start)
2289 +                       /* remember the address as a hint for next time */
2290 +                       return (mm->free_area_cache = addr-len);
2291 +       }
2292 +
2293 +       if (mm->mmap_base < len)
2294 +               goto bottomup;
2295 +
2296 +       addr = mm->mmap_base-len;
2297 +
2298 +       do {
2299 +               /*
2300 +                * Lookup failure means no vma is above this address,
2301 +                * else if new region fits below vma->vm_start,
2302 +                * return with success:
2303 +                */
2304 +               vma = find_vma(mm, addr);
2305 +               if (!vma || addr+len <= vma->vm_start)
2306 +                       /* remember the address as a hint for next time */
2307 +                       return (mm->free_area_cache = addr);
2308 +
2309 +               /* remember the largest hole we saw so far */
2310 +               if (addr + mm->cached_hole_size < vma->vm_start)
2311 +                       mm->cached_hole_size = vma->vm_start - addr;
2312 +
2313 +               /* try just below the current vma->vm_start */
2314 +               addr = vma->vm_start-len;
2315 +       } while (len < vma->vm_start);
2316 +
2317 +bottomup:
2318 +       /*
2319 +        * A failed mmap() very likely causes application failure,
2320 +        * so fall back to the bottom-up function here. This scenario
2321 +        * can happen with large stack limits and large mmap()
2322 +        * allocations.
2323 +        */
2324 +       mm->mmap_base = TASK_UNMAPPED_BASE;
2325 +
2326 +#ifdef CONFIG_PAX_RANDMMAP
2327 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
2328 +               mm->mmap_base += mm->delta_mmap;
2329 +#endif
2330 +
2331 +       mm->free_area_cache = mm->mmap_base;
2332 +       mm->cached_hole_size = ~0UL;
2333 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
2334 +       /*
2335 +        * Restore the topdown base:
2336 +        */
2337 +       mm->mmap_base = base;
2338 +       mm->free_area_cache = base;
2339 +       mm->cached_hole_size = ~0UL;
2340 +
2341 +       return addr;
2342 +}
2343  
2344  struct sel_arg_struct {
2345         unsigned long n;
2346 diff -urNp linux-2.6.17.7/arch/i386/kernel/syscall_table.S linux-2.6.17.7/arch/i386/kernel/syscall_table.S
2347 --- linux-2.6.17.7/arch/i386/kernel/syscall_table.S     2006-07-24 23:36:01.000000000 -0400
2348 +++ linux-2.6.17.7/arch/i386/kernel/syscall_table.S     2006-08-01 20:29:45.000000000 -0400
2349 @@ -1,3 +1,4 @@
2350 +.section .rodata,"a",@progbits
2351  ENTRY(sys_call_table)
2352         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
2353         .long sys_exit
2354 diff -urNp linux-2.6.17.7/arch/i386/kernel/sysenter.c linux-2.6.17.7/arch/i386/kernel/sysenter.c
2355 --- linux-2.6.17.7/arch/i386/kernel/sysenter.c  2006-07-24 23:36:01.000000000 -0400
2356 +++ linux-2.6.17.7/arch/i386/kernel/sysenter.c  2006-08-01 20:29:45.000000000 -0400
2357 @@ -24,7 +24,7 @@ extern asmlinkage void sysenter_entry(vo
2358  void enable_sep_cpu(void)
2359  {
2360         int cpu = get_cpu();
2361 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2362 +       struct tss_struct *tss = init_tss + cpu;
2363  
2364         if (!boot_cpu_has(X86_FEATURE_SEP)) {
2365                 put_cpu();
2366 @@ -48,6 +48,7 @@ extern const char vsyscall_sysenter_star
2367  
2368  int __init sysenter_setup(void)
2369  {
2370 +#ifndef CONFIG_PAX_NOVSYSCALL
2371         void *page = (void *)get_zeroed_page(GFP_ATOMIC);
2372  
2373         __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
2374 @@ -62,6 +63,7 @@ int __init sysenter_setup(void)
2375         memcpy(page,
2376                &vsyscall_sysenter_start,
2377                &vsyscall_sysenter_end - &vsyscall_sysenter_start);
2378 +#endif
2379  
2380         return 0;
2381  }
2382 diff -urNp linux-2.6.17.7/arch/i386/kernel/traps.c linux-2.6.17.7/arch/i386/kernel/traps.c
2383 --- linux-2.6.17.7/arch/i386/kernel/traps.c     2006-07-24 23:36:01.000000000 -0400
2384 +++ linux-2.6.17.7/arch/i386/kernel/traps.c     2006-08-01 20:29:45.000000000 -0400
2385 @@ -28,6 +28,7 @@
2386  #include <linux/utsname.h>
2387  #include <linux/kprobes.h>
2388  #include <linux/kexec.h>
2389 +#include <linux/binfmts.h>
2390  
2391  #ifdef CONFIG_EISA
2392  #include <linux/ioport.h>
2393 @@ -58,18 +59,13 @@
2394  
2395  asmlinkage int system_call(void);
2396  
2397 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2398 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2399                 { 0, 0 }, { 0, 0 } };
2400  
2401  /* Do we ignore FPU interrupts ? */
2402  char ignore_fpu_irq = 0;
2403  
2404 -/*
2405 - * The IDT has to be page-aligned to simplify the Pentium
2406 - * F0 0F bug workaround.. We have a special link segment
2407 - * for this.
2408 - */
2409 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
2410 +extern struct desc_struct idt_table[256];
2411  
2412  asmlinkage void divide_error(void);
2413  asmlinkage void debug(void);
2414 @@ -144,18 +140,22 @@ static inline unsigned long print_contex
2415  {
2416         unsigned long addr;
2417         int printed = 0; /* nr of entries already printed on current line */
2418 +       int i = kstack_depth_to_print;
2419  
2420  #ifdef CONFIG_FRAME_POINTER
2421         while (valid_stack_ptr(tinfo, (void *)ebp)) {
2422                 addr = *(unsigned long *)(ebp + 4);
2423                 printed = print_addr_and_symbol(addr, log_lvl, printed);
2424                 ebp = *(unsigned long *)ebp;
2425 +               --i;
2426         }
2427  #else
2428         while (valid_stack_ptr(tinfo, stack)) {
2429                 addr = *stack++;
2430 -               if (__kernel_text_address(addr))
2431 +               if (__kernel_text_address(addr)) {
2432                         printed = print_addr_and_symbol(addr, log_lvl, printed);
2433 +                       --i;
2434 +               }
2435         }
2436  #endif
2437         if (printed)
2438 @@ -249,7 +249,7 @@ void show_registers(struct pt_regs *regs
2439  
2440         esp = (unsigned long) (&regs->esp);
2441         savesegment(ss, ss);
2442 -       if (user_mode_vm(regs)) {
2443 +       if (user_mode(regs)) {
2444                 in_kernel = 0;
2445                 esp = regs->esp;
2446                 ss = regs->xss & 0xffff;
2447 @@ -276,13 +276,15 @@ void show_registers(struct pt_regs *regs
2448          */
2449         if (in_kernel) {
2450                 u8 __user *eip;
2451 +               mm_segment_t old_fs = get_fs();
2452  
2453                 printk("\n" KERN_EMERG "Stack: ");
2454                 show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG);
2455  
2456                 printk(KERN_EMERG "Code: ");
2457  
2458 -               eip = (u8 __user *)regs->eip - 43;
2459 +               set_fs(KERNEL_DS);
2460 +               eip = (u8 __user *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
2461                 for (i = 0; i < 64; i++, eip++) {
2462                         unsigned char c;
2463  
2464 @@ -290,11 +292,12 @@ void show_registers(struct pt_regs *regs
2465                                 printk(" Bad EIP value.");
2466                                 break;
2467                         }
2468 -                       if (eip == (u8 __user *)regs->eip)
2469 +                       if (eip == (u8 __user *)regs->eip + __KERNEL_TEXT_OFFSET)
2470                                 printk("<%02x> ", c);
2471                         else
2472                                 printk("%02x ", c);
2473                 }
2474 +               set_fs(old_fs);
2475         }
2476         printk("\n");
2477  }      
2478 @@ -306,9 +309,11 @@ static void handle_BUG(struct pt_regs *r
2479         char *file;
2480         char c;
2481         unsigned long eip;
2482 +       mm_segment_t old_fs = get_fs();
2483  
2484 -       eip = regs->eip;
2485 +       eip = regs->eip + __KERNEL_TEXT_OFFSET;
2486  
2487 +       set_fs(KERNEL_DS);
2488         if (eip < PAGE_OFFSET)
2489                 goto no_bug;
2490         if (__get_user(ud2, (unsigned short __user *)eip))
2491 @@ -325,10 +330,12 @@ static void handle_BUG(struct pt_regs *r
2492         printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
2493  
2494  no_bug:
2495 +       set_fs(old_fs);
2496         return;
2497  
2498         /* Here we know it was a BUG but file-n-line is unavailable */
2499  bug:
2500 +       set_fs(old_fs);
2501         printk(KERN_EMERG "Kernel BUG\n");
2502  }
2503  
2504 @@ -430,7 +437,7 @@ void die(const char * str, struct pt_reg
2505  
2506  static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
2507  {
2508 -       if (!user_mode_vm(regs))
2509 +       if (!user_mode(regs))
2510                 die(str, regs, err);
2511  }
2512  
2513 @@ -448,7 +455,7 @@ static void __kprobes do_trap(int trapnr
2514                 goto trap_signal;
2515         }
2516  
2517 -       if (!user_mode(regs))
2518 +       if (!user_mode_novm(regs))
2519                 goto kernel_trap;
2520  
2521         trap_signal: {
2522 @@ -536,7 +543,7 @@ fastcall void __kprobes do_general_prote
2523                                               long error_code)
2524  {
2525         int cpu = get_cpu();
2526 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2527 +       struct tss_struct *tss = &init_tss[cpu];
2528         struct thread_struct *thread = &current->thread;
2529  
2530         /*
2531 @@ -572,9 +579,25 @@ fastcall void __kprobes do_general_prote
2532         if (regs->eflags & VM_MASK)
2533                 goto gp_in_vm86;
2534  
2535 -       if (!user_mode(regs))
2536 +       if (!user_mode_novm(regs))
2537                 goto gp_in_kernel;
2538  
2539 +#ifdef CONFIG_PAX_PAGEEXEC
2540 +       if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
2541 +               struct mm_struct *mm = current->mm;
2542 +               unsigned long limit;
2543 +
2544 +               down_write(&mm->mmap_sem);
2545 +               limit = mm->context.user_cs_limit;
2546 +               if (limit < TASK_SIZE) {
2547 +                       track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
2548 +                       up_write(&mm->mmap_sem);
2549 +                       return;
2550 +               }
2551 +               up_write(&mm->mmap_sem);
2552 +       }
2553 +#endif
2554 +
2555         current->thread.error_code = error_code;
2556         current->thread.trap_no = 13;
2557         force_sig(SIGSEGV, current);
2558 @@ -590,6 +613,13 @@ gp_in_kernel:
2559                 if (notify_die(DIE_GPF, "general protection fault", regs,
2560                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
2561                         return;
2562 +
2563 +#ifdef CONFIG_PAX_KERNEXEC
2564 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
2565 +                       die("PAX: suspicious general protection fault", regs, error_code);
2566 +               else
2567 +#endif
2568 +
2569                 die("general protection fault", regs, error_code);
2570         }
2571  }
2572 @@ -663,7 +693,7 @@ void die_nmi (struct pt_regs *regs, cons
2573         /* If we are in kernel we are probably nested up pretty bad
2574          * and might aswell get out now while we still can.
2575         */
2576 -       if (!user_mode_vm(regs)) {
2577 +       if (!user_mode(regs)) {
2578                 current->thread.trap_no = 2;
2579                 crash_kexec(regs);
2580         }
2581 @@ -816,7 +846,7 @@ fastcall void __kprobes do_debug(struct 
2582                  * check for kernel mode by just checking the CPL
2583                  * of CS.
2584                  */
2585 -               if (!user_mode(regs))
2586 +               if (!user_mode_novm(regs))
2587                         goto clear_TF_reenable;
2588         }
2589  
2590 @@ -1106,7 +1136,19 @@ do { \
2591   */
2592  void set_intr_gate(unsigned int n, void *addr)
2593  {
2594 +
2595 +#ifdef CONFIG_PAX_KERNEXEC
2596 +       unsigned long cr0;
2597 +
2598 +       pax_open_kernel(cr0);
2599 +#endif
2600 +
2601         _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
2602 +
2603 +#ifdef CONFIG_PAX_KERNEXEC
2604 +       pax_close_kernel(cr0);
2605 +#endif
2606 +
2607  }
2608  
2609  /*
2610 diff -urNp linux-2.6.17.7/arch/i386/kernel/vm86.c linux-2.6.17.7/arch/i386/kernel/vm86.c
2611 --- linux-2.6.17.7/arch/i386/kernel/vm86.c      2006-07-24 23:36:01.000000000 -0400
2612 +++ linux-2.6.17.7/arch/i386/kernel/vm86.c      2006-08-01 20:29:45.000000000 -0400
2613 @@ -123,7 +123,7 @@ struct pt_regs * fastcall save_v86_state
2614                 do_exit(SIGSEGV);
2615         }
2616  
2617 -       tss = &per_cpu(init_tss, get_cpu());
2618 +       tss = init_tss + get_cpu();
2619         current->thread.esp0 = current->thread.saved_esp0;
2620         current->thread.sysenter_cs = __KERNEL_CS;
2621         load_esp0(tss, &current->thread);
2622 @@ -297,7 +297,7 @@ static void do_sys_vm86(struct kernel_vm
2623         savesegment(fs, tsk->thread.saved_fs);
2624         savesegment(gs, tsk->thread.saved_gs);
2625  
2626 -       tss = &per_cpu(init_tss, get_cpu());
2627 +       tss = init_tss + get_cpu();
2628         tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
2629         if (cpu_has_sep)
2630                 tsk->thread.sysenter_cs = 0;
2631 diff -urNp linux-2.6.17.7/arch/i386/kernel/vmlinux.lds.S linux-2.6.17.7/arch/i386/kernel/vmlinux.lds.S
2632 --- linux-2.6.17.7/arch/i386/kernel/vmlinux.lds.S       2006-07-24 23:36:01.000000000 -0400
2633 +++ linux-2.6.17.7/arch/i386/kernel/vmlinux.lds.S       2006-08-01 20:29:45.000000000 -0400
2634 @@ -4,10 +4,19 @@
2635  
2636  #define LOAD_OFFSET __PAGE_OFFSET
2637  
2638 +#include <linux/config.h>
2639 +
2640  #include <asm-generic/vmlinux.lds.h>
2641  #include <asm/thread_info.h>
2642  #include <asm/page.h>
2643  #include <asm/cache.h>
2644 +#include <asm/segment.h>
2645 +
2646 +#ifdef CONFIG_X86_PAE
2647 +#define PMD_SHIFT 21
2648 +#else
2649 +#define PMD_SHIFT 22
2650 +#endif
2651  
2652  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2653  OUTPUT_ARCH(i386)
2654 @@ -16,59 +25,14 @@ jiffies = jiffies_64;
2655  SECTIONS
2656  {
2657    . = __KERNEL_START;
2658 -  phys_startup_32 = startup_32 - LOAD_OFFSET;
2659 -  /* read-only */
2660 -  _text = .;                   /* Text and read-only data */
2661 -  .text : AT(ADDR(.text) - LOAD_OFFSET) {
2662 -       *(.text)
2663 -       SCHED_TEXT
2664 -       LOCK_TEXT
2665 -       KPROBES_TEXT
2666 -       *(.fixup)
2667 -       *(.gnu.warning)
2668 -       } = 0x9090
2669 -
2670 -  _etext = .;                  /* End of text section */
2671 -
2672 -  . = ALIGN(16);               /* Exception table */
2673 -  __start___ex_table = .;
2674 -  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2675 -  __stop___ex_table = .;
2676 -
2677 -  RODATA
2678 +  phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
2679  
2680 -  /* writeable */
2681 -  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2682 -       *(.data)
2683 -       CONSTRUCTORS
2684 +  .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
2685 +       BYTE(0xEA) /* jmp far */
2686 +       LONG(phys_startup_32)
2687 +       SHORT(__BOOT_CS)
2688         }
2689  
2690 -  . = ALIGN(4096);
2691 -  __nosave_begin = .;
2692 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2693 -  . = ALIGN(4096);
2694 -  __nosave_end = .;
2695 -
2696 -  . = ALIGN(4096);
2697 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
2698 -       *(.data.idt)
2699 -  }
2700 -
2701 -  . = ALIGN(32);
2702 -  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2703 -       *(.data.cacheline_aligned)
2704 -  }
2705 -
2706 -  /* rarely changed data like cpu maps */
2707 -  . = ALIGN(32);
2708 -  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2709 -  _edata = .;                  /* End of data section */
2710 -
2711 -  . = ALIGN(THREAD_SIZE);      /* init_task */
2712 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2713 -       *(.data.init_task)
2714 -  }
2715 -
2716    /* might get freed after init */
2717    . = ALIGN(4096);
2718    __smp_alt_begin = .;
2719 @@ -92,11 +56,6 @@ SECTIONS
2720    /* will be freed after init */
2721    . = ALIGN(4096);             /* Init code and data */
2722    __init_begin = .;
2723 -  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
2724 -       _sinittext = .;
2725 -       *(.init.text)
2726 -       _einittext = .;
2727 -  }
2728    .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
2729    . = ALIGN(16);
2730    __setup_start = .;
2731 @@ -128,9 +87,7 @@ SECTIONS
2732    .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
2733         *(.altinstr_replacement)
2734    }
2735 -  /* .exit.text is discard at runtime, not link time, to deal with references
2736 -     from .altinstructions and .eh_frame */
2737 -  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
2738 +
2739    .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
2740    . = ALIGN(4096);
2741    __initramfs_start = .;
2742 @@ -140,10 +97,108 @@ SECTIONS
2743    __per_cpu_start = .;
2744    .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
2745    __per_cpu_end = .;
2746 +
2747 +  /* read-only */
2748 +
2749    . = ALIGN(4096);
2750 -  __init_end = .;
2751 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2752 +       _sinittext = .;
2753 +       *(.init.text)
2754 +       _einittext = .;
2755 +  }
2756 +
2757 +  /* .exit.text is discard at runtime, not link time, to deal with references
2758 +     from .altinstructions and .eh_frame */
2759 +  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
2760 +
2761 +#ifdef CONFIG_PAX_KERNEXEC
2762 +  .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2763 +       . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
2764 +       BYTE(0)
2765 +  }
2766 +#else
2767 +  . = ALIGN(4096);
2768 +#endif
2769 +
2770 +  __init_end = . + __KERNEL_TEXT_OFFSET;
2771    /* freed after init ends here */
2772 -       
2773 +
2774 +  _text = .;                   /* Text and read-only data */
2775 +  .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2776 +       *(.text)
2777 +       SCHED_TEXT
2778 +       LOCK_TEXT
2779 +       KPROBES_TEXT
2780 +       *(.fixup)
2781 +       *(.gnu.warning)
2782 +       } = 0x9090
2783 +
2784 +  _etext = .;                  /* End of text section */
2785 +  . += __KERNEL_TEXT_OFFSET;
2786 +  . = ALIGN(16);               /* Exception table */
2787 +  __start___ex_table = .;
2788 +  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2789 +  __stop___ex_table = .;
2790 +
2791 +  . = ALIGN(4096);
2792 +  .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
2793 +       *(.empty_zero_page)
2794 +
2795 +#ifdef CONFIG_X86_PAE
2796 +       *(.swapper_pm_dir)
2797 +#endif
2798 +
2799 +       *(.swapper_pg_dir)
2800 +       *(.idt)
2801 +       }
2802 +
2803 +  RODATA
2804 +
2805 +#ifdef CONFIG_PAX_KERNEXEC
2806 +  . = ALIGN(4096);
2807 +  MODULES_VADDR = .;
2808 +
2809 +  .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
2810 +       . += (4 * 1024 * 1024);
2811 +       . = ALIGN(1 << PMD_SHIFT) - 1;
2812 +       BYTE(0)
2813 +  }
2814 +
2815 +  MODULES_END = .;
2816 +#else
2817 +  . = ALIGN(32);
2818 +#endif
2819 +
2820 +  /* writeable */
2821 +  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2822 +       _data = .;
2823 +       *(.data)
2824 +       CONSTRUCTORS
2825 +       }
2826 +
2827 +  . = ALIGN(4096);
2828 +  __nosave_begin = .;
2829 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2830 +  . = ALIGN(4096);
2831 +  __nosave_end = .;
2832 +
2833 +  . = ALIGN(32);
2834 +  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2835 +       *(.data.cacheline_aligned)
2836 +  }
2837 +
2838 +  /* rarely changed data like cpu maps */
2839 +  . = ALIGN(32);
2840 +  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2841 +
2842 +  . = ALIGN(THREAD_SIZE);      /* init_task */
2843 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2844 +       *(.data.init_task)
2845 +  }
2846 +
2847 +  _edata = .;                  /* End of data section */
2848 +
2849 +  . = ALIGN(4096);
2850    __bss_start = .;             /* BSS */
2851    .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
2852         *(.bss.page_aligned)
2853 diff -urNp linux-2.6.17.7/arch/i386/lib/checksum.S linux-2.6.17.7/arch/i386/lib/checksum.S
2854 --- linux-2.6.17.7/arch/i386/lib/checksum.S     2006-07-24 23:36:01.000000000 -0400
2855 +++ linux-2.6.17.7/arch/i386/lib/checksum.S     2006-08-01 20:29:45.000000000 -0400
2856 @@ -27,7 +27,8 @@
2857  
2858  #include <linux/config.h>
2859  #include <asm/errno.h>
2860 -                               
2861 +#include <asm/segment.h>
2862 +
2863  /*
2864   * computes a partial checksum, e.g. for TCP/UDP fragments
2865   */
2866 @@ -281,12 +282,23 @@ unsigned int csum_partial_copy_generic (
2867  
2868  .align 4
2869  .globl csum_partial_copy_generic
2870 -                               
2871 +.globl csum_partial_copy_generic_to_user
2872 +.globl csum_partial_copy_generic_from_user
2873 +
2874  #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
2875  
2876  #define ARGBASE 16             
2877  #define FP             12
2878 -               
2879 +
2880 +csum_partial_copy_generic_to_user:
2881 +       pushl $(__USER_DS)
2882 +       popl %es
2883 +       jmp csum_partial_copy_generic
2884 +
2885 +csum_partial_copy_generic_from_user:
2886 +       pushl $(__USER_DS)
2887 +       popl %ds
2888 +
2889  csum_partial_copy_generic:
2890         subl  $4,%esp   
2891         pushl %edi
2892 @@ -305,7 +317,7 @@ csum_partial_copy_generic:
2893         jmp 4f
2894  SRC(1: movw (%esi), %bx        )
2895         addl $2, %esi
2896 -DST(   movw %bx, (%edi)        )
2897 +DST(   movw %bx, %es:(%edi)    )
2898         addl $2, %edi
2899         addw %bx, %ax   
2900         adcl $0, %eax
2901 @@ -317,30 +329,30 @@ DST(      movw %bx, (%edi)        )
2902  SRC(1: movl (%esi), %ebx       )
2903  SRC(   movl 4(%esi), %edx      )
2904         adcl %ebx, %eax
2905 -DST(   movl %ebx, (%edi)       )
2906 +DST(   movl %ebx, %es:(%edi)   )
2907         adcl %edx, %eax
2908 -DST(   movl %edx, 4(%edi)      )
2909 +DST(   movl %edx, %es:4(%edi)  )
2910  
2911  SRC(   movl 8(%esi), %ebx      )
2912  SRC(   movl 12(%esi), %edx     )
2913         adcl %ebx, %eax
2914 -DST(   movl %ebx, 8(%edi)      )
2915 +DST(   movl %ebx, %es:8(%edi)  )
2916         adcl %edx, %eax
2917 -DST(   movl %edx, 12(%edi)     )
2918 +DST(   movl %edx, %es:12(%edi) )
2919  
2920  SRC(   movl 16(%esi), %ebx     )
2921  SRC(   movl 20(%esi), %edx     )
2922         adcl %ebx, %eax
2923 -DST(   movl %ebx, 16(%edi)     )
2924 +DST(   movl %ebx, %es:16(%edi) )
2925         adcl %edx, %eax
2926 -DST(   movl %edx, 20(%edi)     )
2927 +DST(   movl %edx, %es:20(%edi) )
2928  
2929  SRC(   movl 24(%esi), %ebx     )
2930  SRC(   movl 28(%esi), %edx     )
2931         adcl %ebx, %eax
2932 -DST(   movl %ebx, 24(%edi)     )
2933 +DST(   movl %ebx, %es:24(%edi) )
2934         adcl %edx, %eax
2935 -DST(   movl %edx, 28(%edi)     )
2936 +DST(   movl %edx, %es:28(%edi) )
2937  
2938         lea 32(%esi), %esi
2939         lea 32(%edi), %edi
2940 @@ -354,7 +366,7 @@ DST(        movl %edx, 28(%edi)     )
2941         shrl $2, %edx                   # This clears CF
2942  SRC(3: movl (%esi), %ebx       )
2943         adcl %ebx, %eax
2944 -DST(   movl %ebx, (%edi)       )
2945 +DST(   movl %ebx, %es:(%edi)   )
2946         lea 4(%esi), %esi
2947         lea 4(%edi), %edi
2948         dec %edx
2949 @@ -366,12 +378,12 @@ DST(      movl %ebx, (%edi)       )
2950         jb 5f
2951  SRC(   movw (%esi), %cx        )
2952         leal 2(%esi), %esi
2953 -DST(   movw %cx, (%edi)        )
2954 +DST(   movw %cx, %es:(%edi)    )
2955         leal 2(%edi), %edi
2956         je 6f
2957         shll $16,%ecx
2958  SRC(5: movb (%esi), %cl        )
2959 -DST(   movb %cl, (%edi)        )
2960 +DST(   movb %cl, %es:(%edi)    )
2961  6:     addl %ecx, %eax
2962         adcl $0, %eax
2963  7:
2964 @@ -382,7 +394,7 @@ DST(        movb %cl, (%edi)        )
2965  
2966  6001:
2967         movl ARGBASE+20(%esp), %ebx     # src_err_ptr
2968 -       movl $-EFAULT, (%ebx)
2969 +       movl $-EFAULT, %ss:(%ebx)
2970  
2971         # zero the complete destination - computing the rest
2972         # is too much work 
2973 @@ -395,11 +407,15 @@ DST(      movb %cl, (%edi)        )
2974  
2975  6002:
2976         movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
2977 -       movl $-EFAULT,(%ebx)
2978 +       movl $-EFAULT,%ss:(%ebx)
2979         jmp 5000b
2980  
2981  .previous
2982  
2983 +       pushl %ss
2984 +       popl %ds
2985 +       pushl %ss
2986 +       popl %es
2987         popl %ebx
2988         popl %esi
2989         popl %edi
2990 @@ -411,17 +427,28 @@ DST(      movb %cl, (%edi)        )
2991  /* Version for PentiumII/PPro */
2992  
2993  #define ROUND1(x) \
2994 +       nop; nop; nop;                          \
2995         SRC(movl x(%esi), %ebx  )       ;       \
2996         addl %ebx, %eax                 ;       \
2997 -       DST(movl %ebx, x(%edi)  )       ; 
2998 +       DST(movl %ebx, %es:x(%edi));
2999  
3000  #define ROUND(x) \
3001 +       nop; nop; nop;                          \
3002         SRC(movl x(%esi), %ebx  )       ;       \
3003         adcl %ebx, %eax                 ;       \
3004 -       DST(movl %ebx, x(%edi)  )       ;
3005 +       DST(movl %ebx, %es:x(%edi));
3006  
3007  #define ARGBASE 12
3008 -               
3009 +
3010 +csum_partial_copy_generic_to_user:
3011 +       pushl $(__USER_DS)
3012 +       popl %es
3013 +       jmp csum_partial_copy_generic
3014 +
3015 +csum_partial_copy_generic_from_user:
3016 +       pushl $(__USER_DS)
3017 +       popl %ds
3018 +
3019  csum_partial_copy_generic:
3020         pushl %ebx
3021         pushl %edi
3022 @@ -440,7 +467,7 @@ csum_partial_copy_generic:
3023         subl %ebx, %edi  
3024         lea  -1(%esi),%edx
3025         andl $-32,%edx
3026 -       lea 3f(%ebx,%ebx), %ebx
3027 +       lea 3f(%ebx,%ebx,2), %ebx
3028         testl %esi, %esi 
3029         jmp *%ebx
3030  1:     addl $64,%esi
3031 @@ -461,19 +488,19 @@ csum_partial_copy_generic:
3032         jb 5f
3033  SRC(   movw (%esi), %dx         )
3034         leal 2(%esi), %esi
3035 -DST(   movw %dx, (%edi)         )
3036 +DST(   movw %dx, %es:(%edi)     )
3037         leal 2(%edi), %edi
3038         je 6f
3039         shll $16,%edx
3040  5:
3041  SRC(   movb (%esi), %dl         )
3042 -DST(   movb %dl, (%edi)         )
3043 +DST(   movb %dl, %es:(%edi)     )
3044  6:     addl %edx, %eax
3045         adcl $0, %eax
3046  7:
3047  .section .fixup, "ax"
3048  6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
3049 -       movl $-EFAULT, (%ebx)
3050 +       movl $-EFAULT, %ss:(%ebx)
3051         # zero the complete destination (computing the rest is too much work)
3052         movl ARGBASE+8(%esp),%edi       # dst
3053         movl ARGBASE+12(%esp),%ecx      # len
3054 @@ -481,10 +508,14 @@ DST(      movb %dl, (%edi)         )
3055         rep; stosb
3056         jmp 7b
3057  6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
3058 -       movl $-EFAULT, (%ebx)
3059 +       movl $-EFAULT, %ss:(%ebx)
3060         jmp  7b                 
3061  .previous                              
3062  
3063 +       pushl %ss
3064 +       popl %ds
3065 +       pushl %ss
3066 +       popl %es
3067         popl %esi
3068         popl %edi
3069         popl %ebx
3070 diff -urNp linux-2.6.17.7/arch/i386/lib/getuser.S linux-2.6.17.7/arch/i386/lib/getuser.S
3071 --- linux-2.6.17.7/arch/i386/lib/getuser.S      2006-07-24 23:36:01.000000000 -0400
3072 +++ linux-2.6.17.7/arch/i386/lib/getuser.S      2006-08-01 20:29:45.000000000 -0400
3073 @@ -9,6 +9,7 @@
3074   * return value.
3075   */
3076  #include <asm/thread_info.h>
3077 +#include <asm/segment.h>
3078  
3079  
3080  /*
3081 @@ -30,8 +31,12 @@ __get_user_1:
3082         GET_THREAD_INFO(%edx)
3083         cmpl TI_addr_limit(%edx),%eax
3084         jae bad_get_user
3085 +       pushl $(__USER_DS)
3086 +       popl %ds
3087  1:     movzbl (%eax),%edx
3088         xorl %eax,%eax
3089 +       pushl %ss
3090 +       pop %ds
3091         ret
3092  
3093  .align 4
3094 @@ -42,7 +47,11 @@ __get_user_2:
3095         GET_THREAD_INFO(%edx)
3096         cmpl TI_addr_limit(%edx),%eax
3097         jae bad_get_user
3098 +       pushl $(__USER_DS)
3099 +       popl %ds
3100  2:     movzwl -1(%eax),%edx
3101 +       pushl %ss
3102 +       pop %ds
3103         xorl %eax,%eax
3104         ret
3105  
3106 @@ -54,11 +63,17 @@ __get_user_4:
3107         GET_THREAD_INFO(%edx)
3108         cmpl TI_addr_limit(%edx),%eax
3109         jae bad_get_user
3110 +       pushl $(__USER_DS)
3111 +       popl %ds
3112  3:     movl -3(%eax),%edx
3113 +       pushl %ss
3114 +       pop %ds
3115         xorl %eax,%eax
3116         ret
3117  
3118  bad_get_user:
3119 +       pushl %ss
3120 +       pop %ds
3121         xorl %edx,%edx
3122         movl $-14,%eax
3123         ret
3124 diff -urNp linux-2.6.17.7/arch/i386/lib/mmx.c linux-2.6.17.7/arch/i386/lib/mmx.c
3125 --- linux-2.6.17.7/arch/i386/lib/mmx.c  2006-07-24 23:36:01.000000000 -0400
3126 +++ linux-2.6.17.7/arch/i386/lib/mmx.c  2006-08-01 20:29:45.000000000 -0400
3127 @@ -48,14 +48,30 @@ void *_mmx_memcpy(void *to, const void *
3128                 "   prefetch 256(%0)\n"
3129                 "2:  \n"
3130                 ".section .fixup, \"ax\"\n"
3131 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3132 +               "3:  \n"
3133 +
3134 +#ifdef CONFIG_PAX_KERNEXEC
3135 +               "   cli\n"
3136 +               "   movl %%cr0, %%eax\n"
3137 +               "   andl $0xFFFEFFFF, %%eax\n"
3138 +               "   movl %%eax, %%cr0\n"
3139 +#endif
3140 +
3141 +               " movw $0x1AEB, 1b\n"   /* jmp on 26 bytes */
3142 +
3143 +#ifdef CONFIG_PAX_KERNEXEC
3144 +               "   orl $0x00010000, %%eax\n"
3145 +               "   movl %%eax, %%cr0\n"
3146 +               "   sti\n"
3147 +#endif
3148 +
3149                 "   jmp 2b\n"
3150                 ".previous\n"
3151                 ".section __ex_table,\"a\"\n"
3152                 "       .align 4\n"
3153                 "       .long 1b, 3b\n"
3154                 ".previous"
3155 -               : : "r" (from) );
3156 +               : : "r" (from) : "ax");
3157                 
3158         
3159         for(; i>5; i--)
3160 @@ -79,14 +95,30 @@ void *_mmx_memcpy(void *to, const void *
3161                 "  movq %%mm2, 48(%1)\n"
3162                 "  movq %%mm3, 56(%1)\n"
3163                 ".section .fixup, \"ax\"\n"
3164 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3165 +               "3:\n"
3166 +
3167 +#ifdef CONFIG_PAX_KERNEXEC
3168 +               "  cli\n"
3169 +               "  movl %%cr0, %%eax\n"
3170 +               "  andl $0xFFFEFFFF, %%eax\n"
3171 +               "  movl %%eax, %%cr0\n"
3172 +#endif
3173 +
3174 +               "  movw $0x05EB, 1b\n"  /* jmp on 5 bytes */
3175 +
3176 +#ifdef CONFIG_PAX_KERNEXEC
3177 +               "  orl $0x00010000, %%eax\n"
3178 +               "  movl %%eax, %%cr0\n"
3179 +               "  sti\n"
3180 +#endif
3181 +
3182                 "   jmp 2b\n"
3183                 ".previous\n"
3184                 ".section __ex_table,\"a\"\n"
3185                 "       .align 4\n"
3186                 "       .long 1b, 3b\n"
3187                 ".previous"
3188 -               : : "r" (from), "r" (to) : "memory");
3189 +               : : "r" (from), "r" (to) : "memory", "ax");
3190                 from+=64;
3191                 to+=64;
3192         }
3193 @@ -179,14 +211,30 @@ static void fast_copy_page(void *to, voi
3194                 "   prefetch 256(%0)\n"
3195                 "2:  \n"
3196                 ".section .fixup, \"ax\"\n"
3197 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3198 +               "3:  \n"
3199 +
3200 +#ifdef CONFIG_PAX_KERNEXEC
3201 +               "   cli\n"
3202 +               "   movl %%cr0, %%eax\n"
3203 +               "   andl $0xFFFEFFFF, %%eax\n"
3204 +               "   movl %%eax, %%cr0\n"
3205 +#endif
3206 +
3207 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3208 +
3209 +#ifdef CONFIG_PAX_KERNEXEC
3210 +               "   orl $0x00010000, %%eax\n"
3211 +               "   movl %%eax, %%cr0\n"
3212 +               "   sti\n"
3213 +#endif
3214 +
3215                 "   jmp 2b\n"
3216                 ".previous\n"
3217                 ".section __ex_table,\"a\"\n"
3218                 "       .align 4\n"
3219                 "       .long 1b, 3b\n"
3220                 ".previous"
3221 -               : : "r" (from) );
3222 +               : : "r" (from) : "ax");
3223  
3224         for(i=0; i<(4096-320)/64; i++)
3225         {
3226 @@ -209,14 +257,30 @@ static void fast_copy_page(void *to, voi
3227                 "   movq 56(%0), %%mm7\n"
3228                 "   movntq %%mm7, 56(%1)\n"
3229                 ".section .fixup, \"ax\"\n"
3230 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3231 +               "3:\n"
3232 +
3233 +#ifdef CONFIG_PAX_KERNEXEC
3234 +               "   cli\n"
3235 +               "   movl %%cr0, %%eax\n"
3236 +               "   andl $0xFFFEFFFF, %%eax\n"
3237 +               "   movl %%eax, %%cr0\n"
3238 +#endif
3239 +
3240 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3241 +
3242 +#ifdef CONFIG_PAX_KERNEXEC
3243 +               "   orl $0x00010000, %%eax\n"
3244 +               "   movl %%eax, %%cr0\n"
3245 +               "   sti\n"
3246 +#endif
3247 +
3248                 "   jmp 2b\n"
3249                 ".previous\n"
3250                 ".section __ex_table,\"a\"\n"
3251                 "       .align 4\n"
3252                 "       .long 1b, 3b\n"
3253                 ".previous"
3254 -               : : "r" (from), "r" (to) : "memory");
3255 +               : : "r" (from), "r" (to) : "memory", "ax");
3256                 from+=64;
3257                 to+=64;
3258         }
3259 @@ -309,14 +373,30 @@ static void fast_copy_page(void *to, voi
3260                 "   prefetch 256(%0)\n"
3261                 "2:  \n"
3262                 ".section .fixup, \"ax\"\n"
3263 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3264 +               "3:  \n"
3265 +
3266 +#ifdef CONFIG_PAX_KERNEXEC
3267 +               "   cli\n"
3268 +               "   movl %%cr0, %%eax\n"
3269 +               "   andl $0xFFFEFFFF, %%eax\n"
3270 +               "   movl %%eax, %%cr0\n"
3271 +#endif
3272 +
3273 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3274 +
3275 +#ifdef CONFIG_PAX_KERNEXEC
3276 +               "   orl $0x00010000, %%eax\n"
3277 +               "   movl %%eax, %%cr0\n"
3278 +               "   sti\n"
3279 +#endif
3280 +
3281                 "   jmp 2b\n"
3282                 ".previous\n"
3283                 ".section __ex_table,\"a\"\n"
3284                 "       .align 4\n"
3285                 "       .long 1b, 3b\n"
3286                 ".previous"
3287 -               : : "r" (from) );
3288 +               : : "r" (from) : "ax");
3289  
3290         for(i=0; i<4096/64; i++)
3291         {
3292 @@ -339,14 +419,30 @@ static void fast_copy_page(void *to, voi
3293                 "   movq %%mm2, 48(%1)\n"
3294                 "   movq %%mm3, 56(%1)\n"
3295                 ".section .fixup, \"ax\"\n"
3296 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3297 +               "3:\n"
3298 +
3299 +#ifdef CONFIG_PAX_KERNEXEC
3300 +               "   cli\n"
3301 +               "   movl %%cr0, %%eax\n"
3302 +               "   andl $0xFFFEFFFF, %%eax\n"
3303 +               "   movl %%eax, %%cr0\n"
3304 +#endif
3305 +
3306 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3307 +
3308 +#ifdef CONFIG_PAX_KERNEXEC
3309 +               "   orl $0x00010000, %%eax\n"
3310 +               "   movl %%eax, %%cr0\n"
3311 +               "   sti\n"
3312 +#endif
3313 +
3314                 "   jmp 2b\n"
3315                 ".previous\n"
3316                 ".section __ex_table,\"a\"\n"
3317                 "       .align 4\n"
3318                 "       .long 1b, 3b\n"
3319                 ".previous"
3320 -               : : "r" (from), "r" (to) : "memory");
3321 +               : : "r" (from), "r" (to) : "memory", "ax");
3322                 from+=64;
3323                 to+=64;
3324         }
3325 diff -urNp linux-2.6.17.7/arch/i386/lib/putuser.S linux-2.6.17.7/arch/i386/lib/putuser.S
3326 --- linux-2.6.17.7/arch/i386/lib/putuser.S      2006-07-24 23:36:01.000000000 -0400
3327 +++ linux-2.6.17.7/arch/i386/lib/putuser.S      2006-08-01 20:29:45.000000000 -0400
3328 @@ -9,6 +9,7 @@
3329   * return value.
3330   */
3331  #include <asm/thread_info.h>
3332 +#include <asm/segment.h>
3333  
3334  
3335  /*
3336 @@ -33,7 +34,11 @@ __put_user_1:
3337         ENTER
3338         cmpl TI_addr_limit(%ebx),%ecx
3339         jae bad_put_user
3340 +       pushl $(__USER_DS)
3341 +       popl %ds
3342  1:     movb %al,(%ecx)
3343 +       pushl %ss
3344 +       popl %ds
3345         xorl %eax,%eax
3346         EXIT
3347  
3348 @@ -45,7 +50,11 @@ __put_user_2:
3349         subl $1,%ebx
3350         cmpl %ebx,%ecx
3351         jae bad_put_user
3352 +       pushl $(__USER_DS)
3353 +       popl %ds
3354  2:     movw %ax,(%ecx)
3355 +       pushl %ss
3356 +       popl %ds
3357         xorl %eax,%eax
3358         EXIT
3359  
3360 @@ -57,7 +66,11 @@ __put_user_4:
3361         subl $3,%ebx
3362         cmpl %ebx,%ecx
3363         jae bad_put_user
3364 +       pushl $(__USER_DS)
3365 +       popl %ds
3366  3:     movl %eax,(%ecx)
3367 +       pushl %ss
3368 +       popl %ds
3369         xorl %eax,%eax
3370         EXIT
3371  
3372 @@ -69,12 +82,18 @@ __put_user_8:
3373         subl $7,%ebx
3374         cmpl %ebx,%ecx
3375         jae bad_put_user
3376 +       pushl $(__USER_DS)
3377 +       popl %ds
3378  4:     movl %eax,(%ecx)
3379  5:     movl %edx,4(%ecx)
3380 +       pushl %ss
3381 +       popl %ds
3382         xorl %eax,%eax
3383         EXIT
3384  
3385  bad_put_user:
3386 +       pushl %ss
3387 +       popl %ds
3388         movl $-14,%eax
3389         EXIT
3390  
3391 diff -urNp linux-2.6.17.7/arch/i386/lib/usercopy.c linux-2.6.17.7/arch/i386/lib/usercopy.c
3392 --- linux-2.6.17.7/arch/i386/lib/usercopy.c     2006-07-24 23:36:01.000000000 -0400
3393 +++ linux-2.6.17.7/arch/i386/lib/usercopy.c     2006-08-01 20:29:45.000000000 -0400
3394 @@ -33,6 +33,7 @@ do {                                                                     \
3395         int __d0, __d1, __d2;                                              \
3396         might_sleep();                                                     \
3397         __asm__ __volatile__(                                              \
3398 +               "       movw %w10,%%ds\n"                                  \
3399                 "       testl %1,%1\n"                                     \
3400                 "       jz 2f\n"                                           \
3401                 "0:     lodsb\n"                                           \
3402 @@ -43,6 +44,8 @@ do {                                                                     \
3403                 "       jnz 0b\n"                                          \
3404                 "1:     subl %1,%0\n"                                      \
3405                 "2:\n"                                                     \
3406 +               "       pushl %%ss\n"                                      \
3407 +               "       popl %%ds\n"                                       \
3408                 ".section .fixup,\"ax\"\n"                                 \
3409                 "3:     movl %5,%0\n"                                      \
3410                 "       jmp 2b\n"                                          \
3411 @@ -53,7 +56,8 @@ do {                                                                     \
3412                 ".previous"                                                \
3413                 : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
3414                   "=&D" (__d2)                                             \
3415 -               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
3416 +               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),\
3417 +                 "r"(__USER_DS)                                           \
3418                 : "memory");                                               \
3419  } while (0)
3420  
3421 @@ -123,10 +127,13 @@ do {                                                                      \
3422         int __d0;                                                       \
3423         might_sleep();                                                  \
3424         __asm__ __volatile__(                                           \
3425 +               "       movw %w6,%%es\n"                                \
3426                 "0:     rep; stosl\n"                                   \
3427                 "       movl %2,%0\n"                                   \
3428                 "1:     rep; stosb\n"                                   \
3429                 "2:\n"                                                  \
3430 +               "       pushl %%ss\n"                                   \
3431 +               "       popl %%es\n"                                    \
3432                 ".section .fixup,\"ax\"\n"                              \
3433                 "3:     lea 0(%2,%0,4),%0\n"                            \
3434                 "       jmp 2b\n"                                       \
3435 @@ -137,7 +144,8 @@ do {                                                                        \
3436                 "       .long 1b,2b\n"                                  \
3437                 ".previous"                                             \
3438                 : "=&c"(size), "=&D" (__d0)                             \
3439 -               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
3440 +               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),      \
3441 +                 "r"(__USER_DS));                                      \
3442  } while (0)
3443  
3444  /**
3445 @@ -198,14 +206,17 @@ long strnlen_user(const char __user *s, 
3446         might_sleep();
3447  
3448         __asm__ __volatile__(
3449 +               "       movw %w8,%%es\n"
3450                 "       testl %0, %0\n"
3451                 "       jz 3f\n"
3452 -               "       andl %0,%%ecx\n"
3453 +               "       movl %0,%%ecx\n"
3454                 "0:     repne; scasb\n"
3455                 "       setne %%al\n"
3456                 "       subl %%ecx,%0\n"
3457                 "       addl %0,%%eax\n"
3458                 "1:\n"
3459 +               "       pushl %%ss\n"
3460 +               "       popl %%es\n"
3461                 ".section .fixup,\"ax\"\n"
3462                 "2:     xorl %%eax,%%eax\n"
3463                 "       jmp 1b\n"
3464 @@ -217,7 +228,7 @@ long strnlen_user(const char __user *s, 
3465                 "       .long 0b,2b\n"
3466                 ".previous"
3467                 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
3468 -               :"0" (n), "1" (s), "2" (0), "3" (mask)
3469 +               :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
3470                 :"cc");
3471         return res & mask;
3472  }
3473 @@ -229,6 +240,7 @@ __copy_user_intel(void __user *to, const
3474  {
3475         int d0, d1;
3476         __asm__ __volatile__(
3477 +                      "       movw %w6, %%es\n"
3478                        "       .align 2,0x90\n"
3479                        "1:     movl 32(%4), %%eax\n"
3480                        "       cmpl $67, %0\n"
3481 @@ -237,36 +249,36 @@ __copy_user_intel(void __user *to, const
3482                        "       .align 2,0x90\n"
3483                        "3:     movl 0(%4), %%eax\n"
3484                        "4:     movl 4(%4), %%edx\n"
3485 -                      "5:     movl %%eax, 0(%3)\n"
3486 -                      "6:     movl %%edx, 4(%3)\n"
3487 +                      "5:     movl %%eax, %%es:0(%3)\n"
3488 +                      "6:     movl %%edx, %%es:4(%3)\n"
3489                        "7:     movl 8(%4), %%eax\n"
3490                        "8:     movl 12(%4),%%edx\n"
3491 -                      "9:     movl %%eax, 8(%3)\n"
3492 -                      "10:    movl %%edx, 12(%3)\n"
3493 +                      "9:     movl %%eax, %%es:8(%3)\n"
3494 +                      "10:    movl %%edx, %%es:12(%3)\n"
3495                        "11:    movl 16(%4), %%eax\n"
3496                        "12:    movl 20(%4), %%edx\n"
3497 -                      "13:    movl %%eax, 16(%3)\n"
3498 -                      "14:    movl %%edx, 20(%3)\n"
3499 +                      "13:    movl %%eax, %%es:16(%3)\n"
3500 +                      "14:    movl %%edx, %%es:20(%3)\n"
3501                        "15:    movl 24(%4), %%eax\n"
3502                        "16:    movl 28(%4), %%edx\n"
3503 -                      "17:    movl %%eax, 24(%3)\n"
3504 -                      "18:    movl %%edx, 28(%3)\n"
3505 +                      "17:    movl %%eax, %%es:24(%3)\n"
3506 +                      "18:    movl %%edx, %%es:28(%3)\n"
3507                        "19:    movl 32(%4), %%eax\n"
3508                        "20:    movl 36(%4), %%edx\n"
3509 -                      "21:    movl %%eax, 32(%3)\n"
3510 -                      "22:    movl %%edx, 36(%3)\n"
3511 +                      "21:    movl %%eax, %%es:32(%3)\n"
3512 +                      "22:    movl %%edx, %%es:36(%3)\n"
3513                        "23:    movl 40(%4), %%eax\n"
3514                        "24:    movl 44(%4), %%edx\n"
3515 -                      "25:    movl %%eax, 40(%3)\n"
3516 -                      "26:    movl %%edx, 44(%3)\n"
3517 +                      "25:    movl %%eax, %%es:40(%3)\n"
3518 +                      "26:    movl %%edx, %%es:44(%3)\n"
3519                        "27:    movl 48(%4), %%eax\n"
3520                        "28:    movl 52(%4), %%edx\n"
3521 -                      "29:    movl %%eax, 48(%3)\n"
3522 -                      "30:    movl %%edx, 52(%3)\n"
3523 +                      "29:    movl %%eax, %%es:48(%3)\n"
3524 +                      "30:    movl %%edx, %%es:52(%3)\n"
3525                        "31:    movl 56(%4), %%eax\n"
3526                        "32:    movl 60(%4), %%edx\n"
3527 -                      "33:    movl %%eax, 56(%3)\n"
3528 -                      "34:    movl %%edx, 60(%3)\n"
3529 +                      "33:    movl %%eax, %%es:56(%3)\n"
3530 +                      "34:    movl %%edx, %%es:60(%3)\n"
3531                        "       addl $-64, %0\n"
3532                        "       addl $64, %4\n"
3533                        "       addl $64, %3\n"
3534 @@ -280,6 +292,8 @@ __copy_user_intel(void __user *to, const
3535                        "36:    movl %%eax, %0\n"
3536                        "37:    rep; movsb\n"
3537                        "100:\n"
3538 +                      "       pushl %%ss\n"
3539 +                      "       popl %%es\n"
3540                        ".section .fixup,\"ax\"\n"
3541                        "101:   lea 0(%%eax,%0,4),%0\n"
3542                        "       jmp 100b\n"
3543 @@ -326,7 +340,7 @@ __copy_user_intel(void __user *to, const
3544                        "       .long 99b,101b\n"
3545                        ".previous"
3546                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
3547 -                      :  "1"(to), "2"(from), "0"(size)
3548 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3549                        : "eax", "edx", "memory");
3550         return size;
3551  }
3552 @@ -336,6 +350,7 @@ __copy_user_zeroing_intel(void *to, cons
3553  {
3554         int d0, d1;
3555         __asm__ __volatile__(
3556 +                      "        movw %w6, %%ds\n"
3557                        "        .align 2,0x90\n"
3558                        "0:      movl 32(%4), %%eax\n"
3559                        "        cmpl $67, %0\n"      
3560 @@ -344,36 +359,36 @@ __copy_user_zeroing_intel(void *to, cons
3561                        "        .align 2,0x90\n"     
3562                        "2:      movl 0(%4), %%eax\n" 
3563                        "21:     movl 4(%4), %%edx\n" 
3564 -                      "        movl %%eax, 0(%3)\n" 
3565 -                      "        movl %%edx, 4(%3)\n" 
3566 +                      "        movl %%eax, %%es:0(%3)\n" 
3567 +                      "        movl %%edx, %%es:4(%3)\n" 
3568                        "3:      movl 8(%4), %%eax\n" 
3569                        "31:     movl 12(%4),%%edx\n" 
3570 -                      "        movl %%eax, 8(%3)\n" 
3571 -                      "        movl %%edx, 12(%3)\n"
3572 +                      "        movl %%eax, %%es:8(%3)\n" 
3573 +                      "        movl %%edx, %%es:12(%3)\n"
3574                        "4:      movl 16(%4), %%eax\n"
3575                        "41:     movl 20(%4), %%edx\n"
3576 -                      "        movl %%eax, 16(%3)\n"
3577 -                      "        movl %%edx, 20(%3)\n"
3578 +                      "        movl %%eax, %%es:16(%3)\n"
3579 +                      "        movl %%edx, %%es:20(%3)\n"
3580                        "10:     movl 24(%4), %%eax\n"
3581                        "51:     movl 28(%4), %%edx\n"
3582 -                      "        movl %%eax, 24(%3)\n"
3583 -                      "        movl %%edx, 28(%3)\n"
3584 +                      "        movl %%eax, %%es:24(%3)\n"
3585 +                      "        movl %%edx, %%es:28(%3)\n"
3586                        "11:     movl 32(%4), %%eax\n"
3587                        "61:     movl 36(%4), %%edx\n"
3588 -                      "        movl %%eax, 32(%3)\n"
3589 -                      "        movl %%edx, 36(%3)\n"
3590 +                      "        movl %%eax, %%es:32(%3)\n"
3591 +                      "        movl %%edx, %%es:36(%3)\n"
3592                        "12:     movl 40(%4), %%eax\n"
3593                        "71:     movl 44(%4), %%edx\n"
3594 -                      "        movl %%eax, 40(%3)\n"
3595 -                      "        movl %%edx, 44(%3)\n"
3596 +                      "        movl %%eax, %%es:40(%3)\n"
3597 +                      "        movl %%edx, %%es:44(%3)\n"
3598                        "13:     movl 48(%4), %%eax\n"
3599                        "81:     movl 52(%4), %%edx\n"
3600 -                      "        movl %%eax, 48(%3)\n"
3601 -                      "        movl %%edx, 52(%3)\n"
3602 +                      "        movl %%eax, %%es:48(%3)\n"
3603 +                      "        movl %%edx, %%es:52(%3)\n"
3604                        "14:     movl 56(%4), %%eax\n"
3605                        "91:     movl 60(%4), %%edx\n"
3606 -                      "        movl %%eax, 56(%3)\n"
3607 -                      "        movl %%edx, 60(%3)\n"
3608 +                      "        movl %%eax, %%es:56(%3)\n"
3609 +                      "        movl %%edx, %%es:60(%3)\n"
3610                        "        addl $-64, %0\n"     
3611                        "        addl $64, %4\n"      
3612                        "        addl $64, %3\n"      
3613 @@ -387,6 +402,8 @@ __copy_user_zeroing_intel(void *to, cons
3614                        "        movl %%eax,%0\n"
3615                        "7:      rep; movsb\n"   
3616                        "8:\n"                   
3617 +                      "        pushl %%ss\n"
3618 +                      "        popl %%ds\n"
3619                        ".section .fixup,\"ax\"\n"
3620                        "9:      lea 0(%%eax,%0,4),%0\n" 
3621                        "16:     pushl %0\n"     
3622 @@ -421,7 +438,7 @@ __copy_user_zeroing_intel(void *to, cons
3623                        "        .long 7b,16b\n" 
3624                        ".previous"              
3625                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
3626 -                      :  "1"(to), "2"(from), "0"(size)
3627 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
3628                        : "eax", "edx", "memory");
3629         return size;
3630  }
3631 @@ -441,6 +458,7 @@ __copy_user_intel(void __user *to, const
3632  do {                                                                   \
3633         int __d0, __d1, __d2;                                           \
3634         __asm__ __volatile__(                                           \
3635 +               "       movw %w8,%%es\n"                                \
3636                 "       cmp  $7,%0\n"                                   \
3637                 "       jbe  1f\n"                                      \
3638                 "       movl %1,%0\n"                                   \
3639 @@ -456,6 +474,8 @@ do {                                                                        \
3640                 "       movl %3,%0\n"                                   \
3641                 "1:     rep; movsb\n"                                   \
3642                 "2:\n"                                                  \
3643 +               "       pushl %%ss\n"                                   \
3644 +               "       popl %%es\n"                                    \
3645                 ".section .fixup,\"ax\"\n"                              \
3646                 "5:     addl %3,%0\n"                                   \
3647                 "       jmp 2b\n"                                       \
3648 @@ -469,7 +489,7 @@ do {                                                                        \
3649                 "       .long 1b,2b\n"                                  \
3650                 ".previous"                                             \
3651                 : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
3652 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
3653 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)\
3654                 : "memory");                                            \
3655  } while (0)
3656  
3657 @@ -477,6 +497,7 @@ do {                                                                        \
3658  do {                                                                   \
3659         int __d0, __d1, __d2;                                           \
3660         __asm__ __volatile__(                                           \
3661 +               "       movw %w8,%%ds\n"                                \
3662                 "       cmp  $7,%0\n"                                   \
3663                 "       jbe  1f\n"                                      \
3664                 "       movl %1,%0\n"                                   \
3665 @@ -492,6 +513,8 @@ do {                                                                        \
3666                 "       movl %3,%0\n"                                   \
3667                 "1:     rep; movsb\n"                                   \
3668                 "2:\n"                                                  \
3669 +               "       pushl %%ss\n"                                   \
3670 +               "       popl %%ds\n"                                    \
3671                 ".section .fixup,\"ax\"\n"                              \
3672                 "5:     addl %3,%0\n"                                   \
3673                 "       jmp 6f\n"                                       \
3674 @@ -511,7 +534,7 @@ do {                                                                        \
3675                 "       .long 1b,6b\n"                                  \
3676                 ".previous"                                             \
3677                 : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
3678 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
3679 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)\
3680                 : "memory");                                            \
3681  } while (0)
3682  
3683 @@ -640,3 +663,45 @@ copy_from_user(void *to, const void __us
3684         return n;
3685  }
3686  EXPORT_SYMBOL(copy_from_user);
3687 +
3688 +#ifdef CONFIG_PAX_MEMORY_UDEREF
3689 +void __set_fs(mm_segment_t x, int cpu)
3690 +{
3691 +       unsigned long limit = x.seg;
3692 +
3693 +       current_thread_info()->addr_limit = x;
3694 +       if (likely(limit)) {
3695 +               limit -= 1UL;
3696 +               limit >>= 12;
3697 +       }
3698 +
3699 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].a = (limit & 0xFFFFUL);
3700 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_DS].b = (limit & 0xF0000UL) | 0xC0F300UL;
3701 +}
3702 +
3703 +void set_fs(mm_segment_t x)
3704 +{
3705 +       int cpu = get_cpu();
3706 +
3707 +#ifdef CONFIG_PAX_KERNEXEC
3708 +       unsigned long cr0;
3709 +
3710 +       pax_open_kernel(cr0);
3711 +#endif
3712 +
3713 +       __set_fs(x, cpu);
3714 +
3715 +#ifdef CONFIG_PAX_KERNEXEC
3716 +       pax_close_kernel(cr0);
3717 +#endif
3718 +
3719 +       put_cpu_no_resched();
3720 +}
3721 +#else
3722 +void set_fs(mm_segment_t x)
3723 +{
3724 +       current_thread_info()->addr_limit = x;
3725 +}
3726 +#endif
3727 +
3728 +EXPORT_SYMBOL(set_fs);
3729 diff -urNp linux-2.6.17.7/arch/i386/mach-voyager/voyager_smp.c linux-2.6.17.7/arch/i386/mach-voyager/voyager_smp.c
3730 --- linux-2.6.17.7/arch/i386/mach-voyager/voyager_smp.c 2006-07-24 23:36:01.000000000 -0400
3731 +++ linux-2.6.17.7/arch/i386/mach-voyager/voyager_smp.c 2006-08-01 20:29:45.000000000 -0400
3732 @@ -1295,7 +1295,7 @@ smp_local_timer_interrupt(struct pt_regs
3733                                                 per_cpu(prof_counter, cpu);
3734                 }
3735  
3736 -               update_process_times(user_mode_vm(regs));
3737 +               update_process_times(user_mode(regs));
3738         }
3739  
3740         if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
3741 diff -urNp linux-2.6.17.7/arch/i386/mm/boot_ioremap.c linux-2.6.17.7/arch/i386/mm/boot_ioremap.c
3742 --- linux-2.6.17.7/arch/i386/mm/boot_ioremap.c  2006-07-24 23:36:01.000000000 -0400
3743 +++ linux-2.6.17.7/arch/i386/mm/boot_ioremap.c  2006-08-01 20:29:45.000000000 -0400
3744 @@ -8,53 +8,37 @@
3745   */
3746  
3747  
3748 -/*
3749 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
3750 - * keeps that from happenning.  If anyone has a better way, I'm listening.
3751 - *
3752 - * boot_pte_t is defined only if this all works correctly
3753 - */
3754 -
3755  #include <linux/config.h>
3756 -#undef CONFIG_X86_PAE
3757  #include <asm/page.h>
3758  #include <asm/pgtable.h>
3759  #include <asm/tlbflush.h>
3760  #include <linux/init.h>
3761  #include <linux/stddef.h>
3762  
3763 -/* 
3764 - * I'm cheating here.  It is known that the two boot PTE pages are 
3765 - * allocated next to each other.  I'm pretending that they're just
3766 - * one big array. 
3767 - */
3768 -
3769 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
3770 -#define boot_pte_index(address) \
3771 -            (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
3772 -
3773 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
3774 -{
3775 -       boot_pte_t* boot_pg = (boot_pte_t*)pg0;
3776 -       return &boot_pg[boot_pte_index((unsigned long)address)];
3777 -}
3778  
3779  /*
3780   * This is only for a caller who is clever enough to page-align
3781   * phys_addr and virtual_source, and who also has a preference
3782   * about which virtual address from which to steal ptes
3783   */
3784 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
3785 -                   void* virtual_source)
3786 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned int nrpages,
3787 +                   char* virtual_source)
3788  {
3789 -       boot_pte_t* pte;
3790 -       int i;
3791 -       char *vaddr = virtual_source;
3792 +       pgd_t *pgd;
3793 +       pud_t *pud;
3794 +       pmd_t *pmd;
3795 +       pte_t* pte;
3796 +       unsigned int i;
3797 +       unsigned long vaddr = (unsigned long)virtual_source;
3798 +
3799 +       pgd = pgd_offset_k(vaddr);
3800 +       pud = pud_offset(pgd, vaddr);
3801 +       pmd = pmd_offset(pud, vaddr);
3802 +       pte = pte_offset_kernel(pmd, vaddr);
3803  
3804 -       pte = boot_vaddr_to_pte(virtual_source);
3805         for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
3806                 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
3807 -               __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
3808 +               __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
3809         }
3810  }
3811  
3812 diff -urNp linux-2.6.17.7/arch/i386/mm/extable.c linux-2.6.17.7/arch/i386/mm/extable.c
3813 --- linux-2.6.17.7/arch/i386/mm/extable.c       2006-07-24 23:36:01.000000000 -0400
3814 +++ linux-2.6.17.7/arch/i386/mm/extable.c       2006-08-01 20:29:45.000000000 -0400
3815 @@ -12,7 +12,7 @@ int fixup_exception(struct pt_regs *regs
3816         const struct exception_table_entry *fixup;
3817  
3818  #ifdef CONFIG_PNPBIOS
3819 -       if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
3820 +       if (unlikely(regs->xcs == (GDT_ENTRY_PNPBIOS_BASE << 3)))
3821         {
3822                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
3823                 extern u32 pnp_bios_is_utter_crap;
3824 diff -urNp linux-2.6.17.7/arch/i386/mm/fault.c linux-2.6.17.7/arch/i386/mm/fault.c
3825 --- linux-2.6.17.7/arch/i386/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
3826 +++ linux-2.6.17.7/arch/i386/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
3827 @@ -22,6 +22,9 @@
3828  #include <linux/highmem.h>
3829  #include <linux/module.h>
3830  #include <linux/kprobes.h>
3831 +#include <linux/unistd.h>
3832 +#include <linux/compiler.h>
3833 +#include <linux/binfmts.h>
3834  
3835  #include <asm/system.h>
3836  #include <asm/uaccess.h>
3837 @@ -82,11 +85,13 @@ static inline unsigned long get_segment_
3838  
3839         /* Unlikely, but must come before segment checks. */
3840         if (unlikely((regs->eflags & VM_MASK) != 0))
3841 -               return eip + (seg << 4);
3842 +               return (eip & 0xFFFF) + (seg << 4);
3843         
3844         /* By far the most common cases. */
3845 -       if (likely(seg == __USER_CS || seg == __KERNEL_CS))
3846 +       if (likely(seg == __USER_CS))
3847                 return eip;
3848 +       if (likely(seg == __KERNEL_CS))
3849 +               return eip + __KERNEL_TEXT_OFFSET;
3850  
3851         /* Check the segment exists, is within the current LDT/GDT size,
3852            that kernel/user (ring 0..3) has the appropriate privilege,
3853 @@ -214,6 +219,30 @@ static noinline void force_sig_info_faul
3854  
3855  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
3856  
3857 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
3858 +static int pax_handle_fetch_fault(struct pt_regs *regs);
3859 +#endif
3860 +
3861 +#ifdef CONFIG_PAX_PAGEEXEC
3862 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
3863 +{
3864 +       pgd_t *pgd;
3865 +       pud_t *pud;
3866 +       pmd_t *pmd;
3867 +
3868 +       pgd = pgd_offset(mm, address);
3869 +       if (!pgd_present(*pgd))
3870 +               return NULL;
3871 +       pud = pud_offset(pgd, address);
3872 +       if (!pud_present(*pud))
3873 +               return NULL;
3874 +       pmd = pmd_offset(pud, address);
3875 +       if (!pmd_present(*pmd))
3876 +               return NULL;
3877 +       return pmd;
3878 +}
3879 +#endif
3880 +
3881  static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
3882  {
3883         unsigned index = pgd_index(address);
3884 @@ -295,13 +324,20 @@ fastcall void __kprobes do_page_fault(st
3885         struct mm_struct *mm;
3886         struct vm_area_struct * vma;
3887         unsigned long address;
3888 -       unsigned long page;
3889         int write, si_code;
3890  
3891 +#ifdef CONFIG_PAX_PAGEEXEC
3892 +       pmd_t *pmd;
3893 +       pte_t *pte;
3894 +       spinlock_t *ptl;
3895 +       unsigned char pte_mask;
3896 +#endif
3897 +
3898         /* get the address */
3899          address = read_cr2();
3900  
3901         tsk = current;
3902 +       mm = tsk->mm;
3903  
3904         si_code = SEGV_MAPERR;
3905  
3906 @@ -340,14 +376,12 @@ fastcall void __kprobes do_page_fault(st
3907         if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
3908                 local_irq_enable();
3909  
3910 -       mm = tsk->mm;
3911 -
3912         /*
3913          * If we're in an interrupt, have no user context or are running in an
3914          * atomic region then we must not take the fault..
3915          */
3916         if (in_atomic() || !mm)
3917 -               goto bad_area_nosemaphore;
3918 +               goto bad_area_nopax;
3919  
3920         /* When running in the kernel we expect faults to occur only to
3921          * addresses in user space.  All other faults represent errors in the
3922 @@ -367,10 +401,101 @@ fastcall void __kprobes do_page_fault(st
3923         if (!down_read_trylock(&mm->mmap_sem)) {
3924                 if ((error_code & 4) == 0 &&
3925                     !search_exception_tables(regs->eip))
3926 -                       goto bad_area_nosemaphore;
3927 +                       goto bad_area_nopax;
3928                 down_read(&mm->mmap_sem);
3929         }
3930  
3931 +#ifdef CONFIG_PAX_PAGEEXEC
3932 +       if (unlikely((error_code & 5) != 5 ||
3933 +                    (regs->eflags & X86_EFLAGS_VM) ||
3934 +                    !(mm->pax_flags & MF_PAX_PAGEEXEC)))
3935 +               goto not_pax_fault;
3936 +
3937 +       /* PaX: it's our fault, let's handle it if we can */
3938 +
3939 +       /* PaX: take a look at read faults before acquiring any locks */
3940 +       if (unlikely(!(error_code & 2) && (regs->eip == address))) {
3941 +               /* instruction fetch attempt from a protected page in user mode */
3942 +               up_read(&mm->mmap_sem);
3943 +               switch (pax_handle_fetch_fault(regs)) {
3944 +
3945 +#ifdef CONFIG_PAX_EMUTRAMP
3946 +               case 2:
3947 +                       return;
3948 +#endif
3949 +
3950 +               }
3951 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
3952 +               do_exit(SIGKILL);
3953 +       }
3954 +
3955 +       pmd = pax_get_pmd(mm, address);
3956 +       if (unlikely(!pmd))
3957 +               goto not_pax_fault;
3958 +
3959 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
3960 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
3961 +               pte_unmap_unlock(pte, ptl);
3962 +               goto not_pax_fault;
3963 +       }
3964 +
3965 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
3966 +               /* write attempt to a protected page in user mode */
3967 +               pte_unmap_unlock(pte, ptl);
3968 +               goto not_pax_fault;
3969 +       }
3970 +
3971 +#ifdef CONFIG_SMP
3972 +       if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
3973 +#else
3974 +       if (likely(address > get_limit(regs->xcs)))
3975 +#endif
3976 +       {
3977 +               set_pte(pte, pte_mkread(*pte));
3978 +               __flush_tlb_one(address);
3979 +               pte_unmap_unlock(pte, ptl);
3980 +               up_read(&mm->mmap_sem);
3981 +               return;
3982 +       }
3983 +
3984 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
3985 +
3986 +       /*
3987 +        * PaX: fill DTLB with user rights and retry
3988 +        */
3989 +       __asm__ __volatile__ (
3990 +               "movw %w4,%%ds\n"
3991 +               "orb %2,%%ss:(%1)\n"
3992 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
3993 +/*
3994 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
3995 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
3996 + * page fault when examined during a TLB load attempt. this is true not only
3997 + * for PTEs holding a non-present entry but also present entries that will
3998 + * raise a page fault (such as those set up by PaX, or the copy-on-write
3999 + * mechanism). in effect it means that we do *not* need to flush the TLBs
4000 + * for our target pages since their PTEs are simply not in the TLBs at all.
4001 +
4002 + * the best thing in omitting it is that we gain around 15-20% speed in the
4003 + * fast path of the page fault handler and can get rid of tracing since we
4004 + * can no longer flush unintended entries.
4005 + */
4006 +               "invlpg (%0)\n"
4007 +#endif
4008 +               "testb $0,(%0)\n"
4009 +               "xorb %3,%%ss:(%1)\n"
4010 +               "pushl %%ss\n"
4011 +               "popl %%ds\n"
4012 +               :
4013 +               : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
4014 +               : "memory", "cc");
4015 +       pte_unmap_unlock(pte, ptl);
4016 +       up_read(&mm->mmap_sem);
4017 +       return;
4018 +
4019 +not_pax_fault:
4020 +#endif
4021 +
4022         vma = find_vma(mm, address);
4023         if (!vma)
4024                 goto bad_area;
4025 @@ -456,6 +581,37 @@ bad_area:
4026         up_read(&mm->mmap_sem);
4027  
4028  bad_area_nosemaphore:
4029 +
4030 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4031 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
4032 +
4033 +#ifdef CONFIG_PAX_PAGEEXEC
4034 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
4035 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4036 +                       do_exit(SIGKILL);
4037 +               }
4038 +#endif
4039 +
4040 +#ifdef CONFIG_PAX_SEGMEXEC
4041 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
4042 +
4043 +                       switch (pax_handle_fetch_fault(regs)) {
4044 +
4045 +#ifdef CONFIG_PAX_EMUTRAMP
4046 +                       case 2:
4047 +                               return;
4048 +#endif
4049 +
4050 +                       }
4051 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4052 +                       do_exit(SIGKILL);
4053 +               }
4054 +#endif
4055 +
4056 +       }
4057 +#endif
4058 +
4059 +bad_area_nopax:
4060         /* User mode accesses just cause a SIGSEGV */
4061         if (error_code & 4) {
4062                 /* 
4063 @@ -523,6 +679,21 @@ no_context:
4064                 if (address < PAGE_SIZE)
4065                         printk(KERN_ALERT "BUG: unable to handle kernel NULL "
4066                                         "pointer dereference");
4067 +
4068 +#ifdef CONFIG_PAX_KERNEXEC
4069 +#ifdef CONFIG_MODULES
4070 +               else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
4071 +#else
4072 +               else if (init_mm.start_code <= address && address < init_mm.end_code)
4073 +#endif
4074 +                       if (tsk->signal->curr_ip)
4075 +                               printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
4076 +                                        NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
4077 +                       else
4078 +                               printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
4079 +                                        tsk->comm, tsk->pid, tsk->uid, tsk->euid);
4080 +#endif
4081 +
4082                 else
4083                         printk(KERN_ALERT "BUG: unable to handle kernel paging"
4084                                         " request");
4085 @@ -530,24 +701,34 @@ no_context:
4086                 printk(KERN_ALERT " printing eip:\n");
4087                 printk("%08lx\n", regs->eip);
4088         }
4089 -       page = read_cr3();
4090 -       page = ((unsigned long *) __va(page))[address >> 22];
4091 -       if (oops_may_print())
4092 -               printk(KERN_ALERT "*pde = %08lx\n", page);
4093 -       /*
4094 -        * We must not directly access the pte in the highpte
4095 -        * case, the page table might be allocated in highmem.
4096 -        * And lets rather not kmap-atomic the pte, just in case
4097 -        * it's allocated already.
4098 -        */
4099 +
4100 +       if (oops_may_print()) {
4101 +               unsigned long index = pgd_index(address);
4102 +               pgd_t *pgd;
4103 +               pud_t *pud;
4104 +               pmd_t *pmd;
4105 +               pte_t *pte;
4106 +
4107 +               pgd = index + (pgd_t *)__va(read_cr3());
4108 +               printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
4109 +               if (pgd_present(*pgd)) {
4110 +                       pud = pud_offset(pgd, address);
4111 +                       pmd = pmd_offset(pud, address);
4112 +                       printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
4113 +                       /*
4114 +                        * We must not directly access the pte in the highpte
4115 +                        * case, the page table might be allocated in highmem.
4116 +                        * And lets rather not kmap-atomic the pte, just in case
4117 +                        * it's allocated already.
4118 +                        */
4119  #ifndef CONFIG_HIGHPTE
4120 -       if ((page & 1) && oops_may_print()) {
4121 -               page &= PAGE_MASK;
4122 -               address &= 0x003ff000;
4123 -               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
4124 -               printk(KERN_ALERT "*pte = %08lx\n", page);
4125 -       }
4126 +                       if (pmd_present(*pmd) && !pmd_large(*pmd)) {
4127 +                               pte = pte_offset_kernel(pmd, address);
4128 +                               printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
4129 +                       }
4130  #endif
4131 +               }
4132 +       }
4133         tsk->thread.cr2 = address;
4134         tsk->thread.trap_no = 14;
4135         tsk->thread.error_code = error_code;
4136 @@ -624,3 +805,105 @@ void vmalloc_sync_all(void)
4137         }
4138  }
4139  #endif
4140 +
4141 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4142 +/*
4143 + * PaX: decide what to do with offenders (regs->eip = fault address)
4144 + *
4145 + * returns 1 when task should be killed
4146 + *         2 when gcc trampoline was detected
4147 + */
4148 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4149 +{
4150 +
4151 +#ifdef CONFIG_PAX_EMUTRAMP
4152 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
4153 +       int err;
4154 +#endif
4155 +
4156 +       if (regs->eflags & X86_EFLAGS_VM)
4157 +               return 1;
4158 +
4159 +#ifdef CONFIG_PAX_EMUTRAMP
4160 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
4161 +               return 1;
4162 +
4163 +       do { /* PaX: gcc trampoline emulation #1 */
4164 +               unsigned char mov1, mov2;
4165 +               unsigned short jmp;
4166 +               unsigned long addr1, addr2;
4167 +
4168 +               err = get_user(mov1, (unsigned char __user *)regs->eip);
4169 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
4170 +               err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
4171 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
4172 +               err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
4173 +
4174 +               if (err)
4175 +                       break;
4176 +
4177 +               if ((mov1 & 0xF8) == 0xB8 &&
4178 +                   (mov2 & 0xF8) == 0xB8 &&
4179 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
4180 +                   (jmp & 0xF8FF) == 0xE0FF &&
4181 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07))
4182 +               {
4183 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
4184 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
4185 +                       regs->eip = addr2;
4186 +                       return 2;
4187 +               }
4188 +       } while (0);
4189 +
4190 +       do { /* PaX: gcc trampoline emulation #2 */
4191 +               unsigned char mov, jmp;
4192 +               unsigned long addr1, addr2;
4193 +
4194 +               err = get_user(mov, (unsigned char __user *)regs->eip);
4195 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
4196 +               err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
4197 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
4198 +
4199 +               if (err)
4200 +                       break;
4201 +
4202 +               if ((mov & 0xF8) == 0xB8 &&
4203 +                   jmp == 0xE9)
4204 +               {
4205 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
4206 +                       regs->eip += addr2 + 10;
4207 +                       return 2;
4208 +               }
4209 +       } while (0);
4210 +#endif
4211 +
4212 +       return 1; /* PaX in action */
4213 +}
4214 +#endif
4215 +
4216 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4217 +void pax_report_insns(void *pc, void *sp)
4218 +{
4219 +       long i;
4220 +
4221 +       printk(KERN_ERR "PAX: bytes at PC: ");
4222 +       for (i = 0; i < 20; i++) {
4223 +               unsigned char c;
4224 +               if (get_user(c, (unsigned char __user *)pc+i))
4225 +                       printk("?? ");
4226 +               else
4227 +                       printk("%02x ", c);
4228 +       }
4229 +       printk("\n");
4230 +
4231 +       printk(KERN_ERR "PAX: bytes at SP-4: ");
4232 +       for (i = -1; i < 20; i++) {
4233 +               unsigned long c;
4234 +               if (get_user(c, (unsigned long __user *)sp+i))
4235 +                       printk("???????? ");
4236 +               else
4237 +                       printk("%08lx ", c);
4238 +       }
4239 +       printk("\n");
4240 +}
4241 +#endif
4242 diff -urNp linux-2.6.17.7/arch/i386/mm/hugetlbpage.c linux-2.6.17.7/arch/i386/mm/hugetlbpage.c
4243 --- linux-2.6.17.7/arch/i386/mm/hugetlbpage.c   2006-07-24 23:36:01.000000000 -0400
4244 +++ linux-2.6.17.7/arch/i386/mm/hugetlbpage.c   2006-08-01 20:29:45.000000000 -0400
4245 @@ -121,7 +121,12 @@ static unsigned long hugetlb_get_unmappe
4246  {
4247         struct mm_struct *mm = current->mm;
4248         struct vm_area_struct *vma;
4249 -       unsigned long start_addr;
4250 +       unsigned long start_addr, task_size = TASK_SIZE;
4251 +
4252 +#ifdef CONFIG_PAX_SEGMEXEC
4253 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
4254 +               task_size = SEGMEXEC_TASK_SIZE;
4255 +#endif
4256  
4257         if (len > mm->cached_hole_size) {
4258                 start_addr = mm->free_area_cache;
4259 @@ -135,7 +140,7 @@ full_search:
4260  
4261         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
4262                 /* At this point:  (!vma || addr < vma->vm_end). */
4263 -               if (TASK_SIZE - len < addr) {
4264 +               if (task_size - len < addr) {
4265                         /*
4266                          * Start a new search - just in case we missed
4267                          * some holes.
4268 @@ -163,9 +168,8 @@ static unsigned long hugetlb_get_unmappe
4269  {
4270         struct mm_struct *mm = current->mm;
4271         struct vm_area_struct *vma, *prev_vma;
4272 -       unsigned long base = mm->mmap_base, addr = addr0;
4273 +       unsigned long base = mm->mmap_base, addr;
4274         unsigned long largest_hole = mm->cached_hole_size;
4275 -       int first_time = 1;
4276  
4277         /* don't allow allocations above current base */
4278         if (mm->free_area_cache > base)
4279 @@ -175,7 +179,7 @@ static unsigned long hugetlb_get_unmappe
4280                 largest_hole = 0;
4281                 mm->free_area_cache  = base;
4282         }
4283 -try_again:
4284 +
4285         /* make sure it can fit in the remaining address space */
4286         if (mm->free_area_cache < len)
4287                 goto fail;
4288 @@ -217,16 +221,6 @@ try_again:
4289  
4290  fail:
4291         /*
4292 -        * if hint left us with no space for the requested
4293 -        * mapping then try again:
4294 -        */
4295 -       if (first_time) {
4296 -               mm->free_area_cache = base;
4297 -               largest_hole = 0;
4298 -               first_time = 0;
4299 -               goto try_again;
4300 -       }
4301 -       /*
4302          * A failed mmap() very likely causes application failure,
4303          * so fall back to the bottom-up function here. This scenario
4304          * can happen with large stack limits and large mmap()
4305 @@ -252,16 +246,23 @@ hugetlb_get_unmapped_area(struct file *f
4306  {
4307         struct mm_struct *mm = current->mm;
4308         struct vm_area_struct *vma;
4309 +       unsigned long task_size = TASK_SIZE;
4310  
4311         if (len & ~HPAGE_MASK)
4312                 return -EINVAL;
4313 -       if (len > TASK_SIZE)
4314 +
4315 +#ifdef CONFIG_PAX_SEGMEXEC
4316 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
4317 +               task_size = SEGMEXEC_TASK_SIZE;
4318 +#endif
4319 +
4320 +       if (len > task_size || addr > task_size - len)
4321                 return -ENOMEM;
4322  
4323         if (addr) {
4324                 addr = ALIGN(addr, HPAGE_SIZE);
4325                 vma = find_vma(mm, addr);
4326 -               if (TASK_SIZE - len >= addr &&
4327 +               if (task_size - len >= addr &&
4328                     (!vma || addr + len <= vma->vm_start))
4329                         return addr;
4330         }
4331 diff -urNp linux-2.6.17.7/arch/i386/mm/init.c linux-2.6.17.7/arch/i386/mm/init.c
4332 --- linux-2.6.17.7/arch/i386/mm/init.c  2006-07-24 23:36:01.000000000 -0400
4333 +++ linux-2.6.17.7/arch/i386/mm/init.c  2006-08-01 20:29:45.000000000 -0400
4334 @@ -41,6 +41,7 @@
4335  #include <asm/tlb.h>
4336  #include <asm/tlbflush.h>
4337  #include <asm/sections.h>
4338 +#include <asm/desc.h>
4339  
4340  unsigned int __VMALLOC_RESERVE = 128 << 20;
4341  
4342 @@ -50,30 +51,6 @@ unsigned long highstart_pfn, highend_pfn
4343  static int noinline do_test_wp_bit(void);
4344  
4345  /*
4346 - * Creates a middle page table and puts a pointer to it in the
4347 - * given global directory entry. This only returns the gd entry
4348 - * in non-PAE compilation mode, since the middle layer is folded.
4349 - */
4350 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
4351 -{
4352 -       pud_t *pud;
4353 -       pmd_t *pmd_table;
4354 -               
4355 -#ifdef CONFIG_X86_PAE
4356 -       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
4357 -       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
4358 -       pud = pud_offset(pgd, 0);
4359 -       if (pmd_table != pmd_offset(pud, 0)) 
4360 -               BUG();
4361 -#else
4362 -       pud = pud_offset(pgd, 0);
4363 -       pmd_table = pmd_offset(pud, 0);
4364 -#endif
4365 -
4366 -       return pmd_table;
4367 -}
4368 -
4369 -/*
4370   * Create a page table and place a pointer to it in a middle page
4371   * directory entry.
4372   */
4373 @@ -81,7 +58,11 @@ static pte_t * __init one_page_table_ini
4374  {
4375         if (pmd_none(*pmd)) {
4376                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
4377 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4378 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
4379 +#else
4380                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
4381 +#endif
4382                 if (page_table != pte_offset_kernel(pmd, 0))
4383                         BUG();  
4384  
4385 @@ -116,8 +97,6 @@ static void __init page_table_range_init
4386         pgd = pgd_base + pgd_idx;
4387  
4388         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
4389 -               if (pgd_none(*pgd)) 
4390 -                       one_md_table_init(pgd);
4391                 pud = pud_offset(pgd, vaddr);
4392                 pmd = pmd_offset(pud, vaddr);
4393                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
4394 @@ -130,11 +109,22 @@ static void __init page_table_range_init
4395         }
4396  }
4397  
4398 -static inline int is_kernel_text(unsigned long addr)
4399 +static inline int is_kernel_text(unsigned long start, unsigned long end)
4400  {
4401 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
4402 -               return 1;
4403 -       return 0;
4404 +       unsigned long etext;
4405 +
4406 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
4407 +       etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
4408 +#else
4409 +       etext = (unsigned long)&_etext;
4410 +#endif
4411 +
4412 +       if ((start > etext + __KERNEL_TEXT_OFFSET ||
4413 +            end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
4414 +           (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
4415 +            end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
4416 +               return 0;
4417 +       return 1;
4418  }
4419  
4420  /*
4421 @@ -146,26 +136,24 @@ static void __init kernel_physical_mappi
4422  {
4423         unsigned long pfn;
4424         pgd_t *pgd;
4425 +       pud_t *pud;
4426         pmd_t *pmd;
4427         pte_t *pte;
4428 -       int pgd_idx, pmd_idx, pte_ofs;
4429 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
4430  
4431         pgd_idx = pgd_index(PAGE_OFFSET);
4432         pgd = pgd_base + pgd_idx;
4433         pfn = 0;
4434  
4435 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
4436 -               pmd = one_md_table_init(pgd);
4437 -               if (pfn >= max_low_pfn)
4438 -                       continue;
4439 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
4440 +               pud = pud_offset(pgd, 0);
4441 +               pmd = pmd_offset(pud, 0);
4442                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
4443 -                       unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
4444 +                       unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
4445  
4446                         /* Map with big pages if possible, otherwise create normal page tables. */
4447                         if (cpu_has_pse) {
4448 -                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
4449 -
4450 -                               if (is_kernel_text(address) || is_kernel_text(address2))
4451 +                               if (is_kernel_text(address, address + PMD_SIZE))
4452                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
4453                                 else
4454                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
4455 @@ -174,7 +162,7 @@ static void __init kernel_physical_mappi
4456                                 pte = one_page_table_init(pmd);
4457  
4458                                 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
4459 -                                               if (is_kernel_text(address))
4460 +                                               if (is_kernel_text(address, address + PAGE_SIZE))
4461                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
4462                                                 else
4463                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
4464 @@ -341,13 +329,6 @@ static void __init pagetable_init (void)
4465         unsigned long vaddr;
4466         pgd_t *pgd_base = swapper_pg_dir;
4467  
4468 -#ifdef CONFIG_X86_PAE
4469 -       int i;
4470 -       /* Init entries of the first-level page table to the zero page */
4471 -       for (i = 0; i < PTRS_PER_PGD; i++)
4472 -               set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
4473 -#endif
4474 -
4475         /* Enable PSE if available */
4476         if (cpu_has_pse) {
4477                 set_in_cr4(X86_CR4_PSE);
4478 @@ -371,17 +352,6 @@ static void __init pagetable_init (void)
4479         page_table_range_init(vaddr, 0, pgd_base);
4480  
4481         permanent_kmaps_init(pgd_base);
4482 -
4483 -#ifdef CONFIG_X86_PAE
4484 -       /*
4485 -        * Add low memory identity-mappings - SMP needs it when
4486 -        * starting up on an AP from real-mode. In the non-PAE
4487 -        * case we already have these mappings through head.S.
4488 -        * All user-space mappings are explicitly cleared after
4489 -        * SMP startup.
4490 -        */
4491 -       set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
4492 -#endif
4493  }
4494  
4495  #ifdef CONFIG_SOFTWARE_SUSPEND
4496 @@ -423,7 +393,6 @@ void zap_low_mappings (void)
4497         flush_tlb_all();
4498  }
4499  
4500 -static int disable_nx __initdata = 0;
4501  u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
4502  
4503  /*
4504 @@ -437,11 +406,9 @@ u64 __supported_pte_mask __read_mostly =
4505  void __init noexec_setup(const char *str)
4506  {
4507         if (!strncmp(str, "on",2) && cpu_has_nx) {
4508 -               __supported_pte_mask |= _PAGE_NX;
4509 -               disable_nx = 0;
4510 +               nx_enabled = 1;
4511         } else if (!strncmp(str,"off",3)) {
4512 -               disable_nx = 1;
4513 -               __supported_pte_mask &= ~_PAGE_NX;
4514 +               nx_enabled = 0;
4515         }
4516  }
4517  
4518 @@ -450,17 +417,13 @@ int nx_enabled = 0;
4519  
4520  static void __init set_nx(void)
4521  {
4522 -       unsigned int v[4], l, h;
4523 +       if (!nx_enabled && cpu_has_nx) {
4524 +               unsigned l, h;
4525  
4526 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
4527 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
4528 -               if ((v[3] & (1 << 20)) && !disable_nx) {
4529 -                       rdmsr(MSR_EFER, l, h);
4530 -                       l |= EFER_NX;
4531 -                       wrmsr(MSR_EFER, l, h);
4532 -                       nx_enabled = 1;
4533 -                       __supported_pte_mask |= _PAGE_NX;
4534 -               }
4535 +               __supported_pte_mask &= ~_PAGE_NX;
4536 +               rdmsr(MSR_EFER, l, h);
4537 +               l &= ~EFER_NX;
4538 +               wrmsr(MSR_EFER, l, h);
4539         }
4540  }
4541  
4542 @@ -512,14 +475,6 @@ void __init paging_init(void)
4543  
4544         load_cr3(swapper_pg_dir);
4545  
4546 -#ifdef CONFIG_X86_PAE
4547 -       /*
4548 -        * We will bail out later - printk doesn't work right now so
4549 -        * the user would just see a hanging kernel.
4550 -        */
4551 -       if (cpu_has_pae)
4552 -               set_in_cr4(X86_CR4_PAE);
4553 -#endif
4554         __flush_tlb_all();
4555  
4556         kmap_init();
4557 @@ -611,7 +566,7 @@ void __init mem_init(void)
4558         set_highmem_pages_init(bad_ppro);
4559  
4560         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
4561 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
4562 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
4563         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
4564  
4565         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
4566 @@ -628,10 +583,6 @@ void __init mem_init(void)
4567                 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
4568                );
4569  
4570 -#ifdef CONFIG_X86_PAE
4571 -       if (!cpu_has_pae)
4572 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
4573 -#endif
4574         if (boot_cpu_data.wp_works_ok < 0)
4575                 test_wp_bit();
4576  
4577 @@ -761,6 +712,37 @@ void free_init_pages(char *what, unsigne
4578  
4579  void free_initmem(void)
4580  {
4581 +
4582 +#ifdef CONFIG_PAX_KERNEXEC
4583 +       /* PaX: limit KERNEL_CS to actual size */
4584 +       unsigned long addr, limit;
4585 +       int cpu;
4586 +       pgd_t *pgd;
4587 +       pud_t *pud;
4588 +       pmd_t *pmd;
4589 +
4590 +#ifdef CONFIG_MODULES
4591 +       limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
4592 +#else
4593 +       limit = (unsigned long)&_etext;
4594 +#endif
4595 +       limit = (limit - 1UL) >> PAGE_SHIFT;
4596 +
4597 +       for (cpu = 0; cpu < NR_CPUS; cpu++) {
4598 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
4599 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
4600 +       }
4601 +
4602 +       /* PaX: make KERNEL_CS read-only */
4603 +       for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
4604 +               pgd = pgd_offset_k(addr);
4605 +               pud = pud_offset(pgd, addr);
4606 +               pmd = pmd_offset(pud, addr);
4607 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
4608 +       }
4609 +       flush_tlb_all();
4610 +#endif
4611 +
4612         free_init_pages("unused kernel memory",
4613                         (unsigned long)(&__init_begin),
4614                         (unsigned long)(&__init_end));
4615 diff -urNp linux-2.6.17.7/arch/i386/mm/mmap.c linux-2.6.17.7/arch/i386/mm/mmap.c
4616 --- linux-2.6.17.7/arch/i386/mm/mmap.c  2006-07-24 23:36:01.000000000 -0400
4617 +++ linux-2.6.17.7/arch/i386/mm/mmap.c  2006-08-01 20:29:45.000000000 -0400
4618 @@ -34,12 +34,18 @@
4619   * Leave an at least ~128 MB hole.
4620   */
4621  #define MIN_GAP (128*1024*1024)
4622 -#define MAX_GAP (TASK_SIZE/6*5)
4623 +#define MAX_GAP (task_size/6*5)
4624  
4625  static inline unsigned long mmap_base(struct mm_struct *mm)
4626  {
4627         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
4628         unsigned long random_factor = 0;
4629 +       unsigned long task_size = TASK_SIZE;
4630 +
4631 +#ifdef CONFIG_PAX_SEGMEXEC
4632 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
4633 +               task_size = SEGMEXEC_TASK_SIZE;
4634 +#endif
4635  
4636         if (current->flags & PF_RANDOMIZE)
4637                 random_factor = get_random_int() % (1024*1024);
4638 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
4639         else if (gap > MAX_GAP)
4640                 gap = MAX_GAP;
4641  
4642 -       return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
4643 +       return PAGE_ALIGN(task_size - gap - random_factor);
4644  }
4645  
4646  /*
4647 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
4648                         (current->personality & ADDR_COMPAT_LAYOUT) ||
4649                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
4650                 mm->mmap_base = TASK_UNMAPPED_BASE;
4651 +
4652 +#ifdef CONFIG_PAX_RANDMMAP
4653 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
4654 +                       mm->mmap_base += mm->delta_mmap;
4655 +#endif
4656 +
4657                 mm->get_unmapped_area = arch_get_unmapped_area;
4658                 mm->unmap_area = arch_unmap_area;
4659         } else {
4660                 mm->mmap_base = mmap_base(mm);
4661 +
4662 +#ifdef CONFIG_PAX_RANDMMAP
4663 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
4664 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
4665 +#endif
4666 +
4667                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4668                 mm->unmap_area = arch_unmap_area_topdown;
4669         }
4670 diff -urNp linux-2.6.17.7/arch/i386/mm/pageattr.c linux-2.6.17.7/arch/i386/mm/pageattr.c
4671 --- linux-2.6.17.7/arch/i386/mm/pageattr.c      2006-07-24 23:36:01.000000000 -0400
4672 +++ linux-2.6.17.7/arch/i386/mm/pageattr.c      2006-08-01 20:29:45.000000000 -0400
4673 @@ -14,6 +14,7 @@
4674  #include <asm/tlbflush.h>
4675  #include <asm/pgalloc.h>
4676  #include <asm/sections.h>
4677 +#include <asm/desc.h>
4678  
4679  static DEFINE_SPINLOCK(cpa_lock);
4680  static struct list_head df_list = LIST_HEAD_INIT(df_list);
4681 @@ -84,7 +85,18 @@ static void set_pmd_pte(pte_t *kpte, uns
4682         struct page *page;
4683         unsigned long flags;
4684  
4685 +#ifdef CONFIG_PAX_KERNEXEC
4686 +       unsigned long cr0;
4687 +
4688 +       pax_open_kernel(cr0);
4689 +#endif
4690 +
4691         set_pte_atomic(kpte, pte);      /* change init_mm */
4692 +
4693 +#ifdef CONFIG_PAX_KERNEXEC
4694 +       pax_close_kernel(cr0);
4695 +#endif
4696 +
4697         if (PTRS_PER_PMD > 1)
4698                 return;
4699  
4700 @@ -111,7 +123,7 @@ static inline void revert_page(struct pa
4701         pte_t *linear;
4702  
4703         ref_prot =
4704 -       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
4705 +       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
4706                 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
4707  
4708         linear = (pte_t *)
4709 @@ -143,7 +155,7 @@ __change_page_attr(struct page *page, pg
4710                         struct page *split;
4711  
4712                         ref_prot =
4713 -                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
4714 +                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
4715                                 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
4716                         split = split_large_page(address, prot, ref_prot);
4717                         if (!split)
4718 diff -urNp linux-2.6.17.7/arch/i386/oprofile/backtrace.c linux-2.6.17.7/arch/i386/oprofile/backtrace.c
4719 --- linux-2.6.17.7/arch/i386/oprofile/backtrace.c       2006-07-24 23:36:01.000000000 -0400
4720 +++ linux-2.6.17.7/arch/i386/oprofile/backtrace.c       2006-08-01 20:29:45.000000000 -0400
4721 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
4722         head = (struct frame_head *)regs->ebp;
4723  #endif
4724  
4725 -       if (!user_mode_vm(regs)) {
4726 +       if (!user_mode(regs)) {
4727                 while (depth-- && valid_kernel_stack(head, regs))
4728                         head = dump_kernel_backtrace(head);
4729                 return;
4730 diff -urNp linux-2.6.17.7/arch/i386/power/cpu.c linux-2.6.17.7/arch/i386/power/cpu.c
4731 --- linux-2.6.17.7/arch/i386/power/cpu.c        2006-07-24 23:36:01.000000000 -0400
4732 +++ linux-2.6.17.7/arch/i386/power/cpu.c        2006-08-01 20:29:45.000000000 -0400
4733 @@ -62,7 +62,7 @@ static void do_fpu_end(void)
4734  static void fix_processor_context(void)
4735  {
4736         int cpu = smp_processor_id();
4737 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
4738 +       struct tss_struct * t = init_tss + cpu;
4739  
4740         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. */
4741  
4742 diff -urNp linux-2.6.17.7/arch/ia64/ia32/binfmt_elf32.c linux-2.6.17.7/arch/ia64/ia32/binfmt_elf32.c
4743 --- linux-2.6.17.7/arch/ia64/ia32/binfmt_elf32.c        2006-07-24 23:36:01.000000000 -0400
4744 +++ linux-2.6.17.7/arch/ia64/ia32/binfmt_elf32.c        2006-08-01 20:29:45.000000000 -0400
4745 @@ -46,6 +46,17 @@ randomize_stack_top(unsigned long stack_
4746  
4747  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
4748  
4749 +#ifdef CONFIG_PAX_ASLR
4750 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
4751 +
4752 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
4753 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4754 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
4755 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4756 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
4757 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
4758 +#endif
4759 +
4760  /* Ugly but avoids duplication */
4761  #include "../../../fs/binfmt_elf.c"
4762  
4763 diff -urNp linux-2.6.17.7/arch/ia64/ia32/ia32priv.h linux-2.6.17.7/arch/ia64/ia32/ia32priv.h
4764 --- linux-2.6.17.7/arch/ia64/ia32/ia32priv.h    2006-07-24 23:36:01.000000000 -0400
4765 +++ linux-2.6.17.7/arch/ia64/ia32/ia32priv.h    2006-08-01 20:29:45.000000000 -0400
4766 @@ -305,7 +305,14 @@ struct old_linux32_dirent {
4767  #define ELF_DATA       ELFDATA2LSB
4768  #define ELF_ARCH       EM_386
4769  
4770 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
4771 +#ifdef CONFIG_PAX_RANDUSTACK
4772 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
4773 +#else
4774 +#define __IA32_DELTA_STACK     0UL
4775 +#endif
4776 +
4777 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
4778 +
4779  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
4780  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
4781  
4782 diff -urNp linux-2.6.17.7/arch/ia64/kernel/module.c linux-2.6.17.7/arch/ia64/kernel/module.c
4783 --- linux-2.6.17.7/arch/ia64/kernel/module.c    2006-07-24 23:36:01.000000000 -0400
4784 +++ linux-2.6.17.7/arch/ia64/kernel/module.c    2006-08-01 20:29:45.000000000 -0400
4785 @@ -322,7 +322,7 @@ module_alloc (unsigned long size)
4786  void
4787  module_free (struct module *mod, void *module_region)
4788  {
4789 -       if (mod->arch.init_unw_table && module_region == mod->module_init) {
4790 +       if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
4791                 unw_remove_unwind_table(mod->arch.init_unw_table);
4792                 mod->arch.init_unw_table = NULL;
4793         }
4794 @@ -500,15 +500,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
4795  }
4796  
4797  static inline int
4798 +in_init_rx (const struct module *mod, uint64_t addr)
4799 +{
4800 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
4801 +}
4802 +
4803 +static inline int
4804 +in_init_rw (const struct module *mod, uint64_t addr)
4805 +{
4806 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
4807 +}
4808 +
4809 +static inline int
4810  in_init (const struct module *mod, uint64_t addr)
4811  {
4812 -       return addr - (uint64_t) mod->module_init < mod->init_size;
4813 +       return in_init_rx(mod, value) || in_init_rw(mod, value);
4814 +}
4815 +
4816 +static inline int
4817 +in_core_rx (const struct module *mod, uint64_t addr)
4818 +{
4819 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
4820 +}
4821 +
4822 +static inline int
4823 +in_core_rw (const struct module *mod, uint64_t addr)
4824 +{
4825 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
4826  }
4827  
4828  static inline int
4829  in_core (const struct module *mod, uint64_t addr)
4830  {
4831 -       return addr - (uint64_t) mod->module_core < mod->core_size;
4832 +       return in_core_rx(mod, value) || in_core_rw(mod, value);
4833  }
4834  
4835  static inline int
4836 @@ -692,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_
4837                 break;
4838  
4839               case RV_BDREL:
4840 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
4841 +               if (in_init_rx(mod, val))
4842 +                       val -= (uint64_t) mod->module_init_rx;
4843 +               else if (in_init_rw(mod, val))
4844 +                       val -= (uint64_t) mod->module_init_rw;
4845 +               else if (in_core_rx(mod, val))
4846 +                       val -= (uint64_t) mod->module_core_rx;
4847 +               else if (in_core_rw(mod, val))
4848 +                       val -= (uint64_t) mod->module_core_rw;
4849                 break;
4850  
4851               case RV_LTV:
4852 @@ -826,15 +857,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
4853                  *     addresses have been selected...
4854                  */
4855                 uint64_t gp;
4856 -               if (mod->core_size > MAX_LTOFF)
4857 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
4858                         /*
4859                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
4860                          * at the end of the module.
4861                          */
4862 -                       gp = mod->core_size - MAX_LTOFF / 2;
4863 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
4864                 else
4865 -                       gp = mod->core_size / 2;
4866 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
4867 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
4868 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
4869                 mod->arch.gp = gp;
4870                 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
4871         }
4872 diff -urNp linux-2.6.17.7/arch/ia64/kernel/ptrace.c linux-2.6.17.7/arch/ia64/kernel/ptrace.c
4873 --- linux-2.6.17.7/arch/ia64/kernel/ptrace.c    2006-07-24 23:36:01.000000000 -0400
4874 +++ linux-2.6.17.7/arch/ia64/kernel/ptrace.c    2006-08-01 20:29:45.000000000 -0400
4875 @@ -18,6 +18,7 @@
4876  #include <linux/audit.h>
4877  #include <linux/signal.h>
4878  #include <linux/vs_pid.h>
4879 +#include <linux/grsecurity.h>
4880  
4881  #include <asm/pgtable.h>
4882  #include <asm/processor.h>
4883 @@ -1447,6 +1448,9 @@ sys_ptrace (long request, pid_t pid, uns
4884         if (pid == 1)           /* no messing around with init! */
4885                 goto out_tsk;
4886  
4887 +       if (gr_handle_ptrace(child, request))
4888 +               goto out_tsk;
4889 +
4890         if (request == PTRACE_ATTACH) {
4891                 ret = ptrace_attach(child);
4892                 goto out_tsk;
4893 diff -urNp linux-2.6.17.7/arch/ia64/kernel/sys_ia64.c linux-2.6.17.7/arch/ia64/kernel/sys_ia64.c
4894 --- linux-2.6.17.7/arch/ia64/kernel/sys_ia64.c  2006-07-24 23:36:01.000000000 -0400
4895 +++ linux-2.6.17.7/arch/ia64/kernel/sys_ia64.c  2006-08-01 20:29:45.000000000 -0400
4896 @@ -38,6 +38,13 @@ arch_get_unmapped_area (struct file *fil
4897         if (REGION_NUMBER(addr) == RGN_HPAGE)
4898                 addr = 0;
4899  #endif
4900 +
4901 +#ifdef CONFIG_PAX_RANDMMAP
4902 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
4903 +               addr = mm->free_area_cache;
4904 +       else
4905 +#endif
4906 +
4907         if (!addr)
4908                 addr = mm->free_area_cache;
4909  
4910 @@ -56,9 +63,9 @@ arch_get_unmapped_area (struct file *fil
4911         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
4912                 /* At this point:  (!vma || addr < vma->vm_end). */
4913                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
4914 -                       if (start_addr != TASK_UNMAPPED_BASE) {
4915 +                       if (start_addr != mm->mmap_base) {
4916                                 /* Start a new search --- just in case we missed some holes.  */
4917 -                               addr = TASK_UNMAPPED_BASE;
4918 +                               addr = mm->mmap_base;
4919                                 goto full_search;
4920                         }
4921                         return -ENOMEM;
4922 diff -urNp linux-2.6.17.7/arch/ia64/mm/fault.c linux-2.6.17.7/arch/ia64/mm/fault.c
4923 --- linux-2.6.17.7/arch/ia64/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
4924 +++ linux-2.6.17.7/arch/ia64/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
4925 @@ -10,6 +10,7 @@
4926  #include <linux/interrupt.h>
4927  #include <linux/kprobes.h>
4928  #include <linux/vs_memory.h>
4929 +#include <linux/binfmts.h>
4930  
4931  #include <asm/pgtable.h>
4932  #include <asm/processor.h>
4933 @@ -51,6 +52,23 @@ mapped_kernel_page_is_present (unsigned 
4934         return pte_present(pte);
4935  }
4936  
4937 +#ifdef CONFIG_PAX_PAGEEXEC
4938 +void pax_report_insns(void *pc, void *sp)
4939 +{
4940 +       unsigned long i;
4941 +
4942 +       printk(KERN_ERR "PAX: bytes at PC: ");
4943 +       for (i = 0; i < 8; i++) {
4944 +               unsigned int c;
4945 +               if (get_user(c, (unsigned int*)pc+i))
4946 +                       printk("???????? ");
4947 +               else
4948 +                       printk("%08x ", c);
4949 +       }
4950 +       printk("\n");
4951 +}
4952 +#endif
4953 +
4954  void __kprobes
4955  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
4956  {
4957 @@ -116,9 +134,23 @@ ia64_do_page_fault (unsigned long addres
4958                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
4959                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
4960  
4961 -       if ((vma->vm_flags & mask) != mask)
4962 +       if ((vma->vm_flags & mask) != mask) {
4963 +
4964 +#ifdef CONFIG_PAX_PAGEEXEC
4965 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
4966 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
4967 +                               goto bad_area;
4968 +
4969 +                       up_read(&mm->mmap_sem);
4970 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
4971 +                       do_exit(SIGKILL);
4972 +               }
4973 +#endif
4974 +
4975                 goto bad_area;
4976  
4977 +       }
4978 +
4979    survive:
4980         /*
4981          * If for any reason at all we couldn't handle the fault, make
4982 diff -urNp linux-2.6.17.7/arch/ia64/mm/init.c linux-2.6.17.7/arch/ia64/mm/init.c
4983 --- linux-2.6.17.7/arch/ia64/mm/init.c  2006-07-24 23:36:01.000000000 -0400
4984 +++ linux-2.6.17.7/arch/ia64/mm/init.c  2006-08-01 20:29:45.000000000 -0400
4985 @@ -20,8 +20,8 @@
4986  #include <linux/swap.h>
4987  #include <linux/proc_fs.h>
4988  #include <linux/bitops.h>
4989 +#include <linux/a.out.h>
4990  
4991 -#include <asm/a.out.h>
4992  #include <asm/dma.h>
4993  #include <asm/ia32.h>
4994  #include <asm/io.h>
4995 diff -urNp linux-2.6.17.7/arch/mips/kernel/binfmt_elfn32.c linux-2.6.17.7/arch/mips/kernel/binfmt_elfn32.c
4996 --- linux-2.6.17.7/arch/mips/kernel/binfmt_elfn32.c     2006-07-24 23:36:01.000000000 -0400
4997 +++ linux-2.6.17.7/arch/mips/kernel/binfmt_elfn32.c     2006-08-01 20:29:45.000000000 -0400
4998 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
4999  #undef ELF_ET_DYN_BASE
5000  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
5001  
5002 +#ifdef CONFIG_PAX_ASLR
5003 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5004 +
5005 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5006 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5007 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5008 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5009 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5010 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5011 +#endif
5012 +
5013  #include <asm/processor.h>
5014  #include <linux/module.h>
5015  #include <linux/elfcore.h>
5016 diff -urNp linux-2.6.17.7/arch/mips/kernel/binfmt_elfo32.c linux-2.6.17.7/arch/mips/kernel/binfmt_elfo32.c
5017 --- linux-2.6.17.7/arch/mips/kernel/binfmt_elfo32.c     2006-07-24 23:36:01.000000000 -0400
5018 +++ linux-2.6.17.7/arch/mips/kernel/binfmt_elfo32.c     2006-08-01 20:29:45.000000000 -0400
5019 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
5020  #undef ELF_ET_DYN_BASE
5021  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
5022  
5023 +#ifdef CONFIG_PAX_ASLR
5024 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
5025 +
5026 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5027 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5028 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5029 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5030 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5031 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
5032 +#endif
5033 +
5034  #include <asm/processor.h>
5035  #include <linux/module.h>
5036  #include <linux/elfcore.h>
5037 diff -urNp linux-2.6.17.7/arch/mips/kernel/syscall.c linux-2.6.17.7/arch/mips/kernel/syscall.c
5038 --- linux-2.6.17.7/arch/mips/kernel/syscall.c   2006-07-24 23:36:01.000000000 -0400
5039 +++ linux-2.6.17.7/arch/mips/kernel/syscall.c   2006-08-01 20:29:45.000000000 -0400
5040 @@ -89,6 +89,11 @@ unsigned long arch_get_unmapped_area(str
5041         do_color_align = 0;
5042         if (filp || (flags & MAP_SHARED))
5043                 do_color_align = 1;
5044 +
5045 +#ifdef CONFIG_PAX_RANDMMAP
5046 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5047 +#endif
5048 +
5049         if (addr) {
5050                 if (do_color_align)
5051                         addr = COLOUR_ALIGN(addr, pgoff);
5052 @@ -99,7 +104,7 @@ unsigned long arch_get_unmapped_area(str
5053                     (!vmm || addr + len <= vmm->vm_start))
5054                         return addr;
5055         }
5056 -       addr = TASK_UNMAPPED_BASE;
5057 +       addr = current->mm->mmap_base;
5058         if (do_color_align)
5059                 addr = COLOUR_ALIGN(addr, pgoff);
5060         else
5061 diff -urNp linux-2.6.17.7/arch/mips/mm/fault.c linux-2.6.17.7/arch/mips/mm/fault.c
5062 --- linux-2.6.17.7/arch/mips/mm/fault.c 2006-07-24 23:36:01.000000000 -0400
5063 +++ linux-2.6.17.7/arch/mips/mm/fault.c 2006-08-01 20:29:45.000000000 -0400
5064 @@ -27,6 +27,23 @@
5065  #include <asm/ptrace.h>
5066  #include <asm/highmem.h>               /* For VMALLOC_END */
5067  
5068 +#ifdef CONFIG_PAX_PAGEEXEC
5069 +void pax_report_insns(void *pc)
5070 +{
5071 +       unsigned long i;
5072 +
5073 +       printk(KERN_ERR "PAX: bytes at PC: ");
5074 +       for (i = 0; i < 5; i++) {
5075 +               unsigned int c;
5076 +               if (get_user(c, (unsigned int*)pc+i))
5077 +                       printk("???????? ");
5078 +               else
5079 +                       printk("%08x ", c);
5080 +       }
5081 +       printk("\n");
5082 +}
5083 +#endif
5084 +
5085  /*
5086   * This routine handles page faults.  It determines the address,
5087   * and the problem, and then passes it off to one of the appropriate
5088 diff -urNp linux-2.6.17.7/arch/parisc/kernel/module.c linux-2.6.17.7/arch/parisc/kernel/module.c
5089 --- linux-2.6.17.7/arch/parisc/kernel/module.c  2006-07-24 23:36:01.000000000 -0400
5090 +++ linux-2.6.17.7/arch/parisc/kernel/module.c  2006-08-01 20:29:45.000000000 -0400
5091 @@ -72,16 +72,38 @@
5092  
5093  /* three functions to determine where in the module core
5094   * or init pieces the location is */
5095 +static inline int is_init_rx(struct module *me, void *loc)
5096 +{
5097 +       return (loc >= me->module_init_rx &&
5098 +               loc < (me->module_init_rx + me->init_size_rx));
5099 +}
5100 +
5101 +static inline int is_init_rw(struct module *me, void *loc)
5102 +{
5103 +       return (loc >= me->module_init_rw &&
5104 +               loc < (me->module_init_rw + me->init_size_rw));
5105 +}
5106 +
5107  static inline int is_init(struct module *me, void *loc)
5108  {
5109 -       return (loc >= me->module_init &&
5110 -               loc <= (me->module_init + me->init_size));
5111 +       return is_init_rx(me, loc) || is_init_rw(me, loc);
5112 +}
5113 +
5114 +static inline int is_core_rx(struct module *me, void *loc)
5115 +{
5116 +       return (loc >= me->module_core_rx &&
5117 +               loc < (me->module_core_rx + me->core_size_rx));
5118 +}
5119 +
5120 +static inline int is_core_rw(struct module *me, void *loc)
5121 +{
5122 +       return (loc >= me->module_core_rw &&
5123 +               loc < (me->module_core_rw + me->core_size_rw));
5124  }
5125  
5126  static inline int is_core(struct module *me, void *loc)
5127  {
5128 -       return (loc >= me->module_core &&
5129 -               loc <= (me->module_core + me->core_size));
5130 +       return is_core_rx(me, loc) || is_core_rw(me, loc);
5131  }
5132  
5133  static inline int is_local(struct module *me, void *loc)
5134 @@ -289,21 +311,21 @@ int module_frob_arch_sections(CONST Elf_
5135         }
5136  
5137         /* align things a bit */
5138 -       me->core_size = ALIGN(me->core_size, 16);
5139 -       me->arch.got_offset = me->core_size;
5140 -       me->core_size += gots * sizeof(struct got_entry);
5141 -
5142 -       me->core_size = ALIGN(me->core_size, 16);
5143 -       me->arch.fdesc_offset = me->core_size;
5144 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
5145 -
5146 -       me->core_size = ALIGN(me->core_size, 16);
5147 -       me->arch.stub_offset = me->core_size;
5148 -       me->core_size += stubs * sizeof(struct stub_entry);
5149 -
5150 -       me->init_size = ALIGN(me->init_size, 16);
5151 -       me->arch.init_stub_offset = me->init_size;
5152 -       me->init_size += init_stubs * sizeof(struct stub_entry);
5153 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
5154 +       me->arch.got_offset = me->core_size_rw;
5155 +       me->core_size_rw += gots * sizeof(struct got_entry);
5156 +
5157 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
5158 +       me->arch.fdesc_offset = me->core_size_rw;
5159 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
5160 +
5161 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
5162 +       me->arch.stub_offset = me->core_size_rx;
5163 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
5164 +
5165 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
5166 +       me->arch.init_stub_offset = me->init_size_rx;
5167 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
5168  
5169         me->arch.got_max = gots;
5170         me->arch.fdesc_max = fdescs;
5171 @@ -323,7 +345,7 @@ static Elf64_Word get_got(struct module 
5172  
5173         BUG_ON(value == 0);
5174  
5175 -       got = me->module_core + me->arch.got_offset;
5176 +       got = me->module_core_rw + me->arch.got_offset;
5177         for (i = 0; got[i].addr; i++)
5178                 if (got[i].addr == value)
5179                         goto out;
5180 @@ -341,7 +363,7 @@ static Elf64_Word get_got(struct module 
5181  #ifdef __LP64__
5182  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
5183  {
5184 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
5185 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
5186  
5187         if (!value) {
5188                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
5189 @@ -359,7 +381,7 @@ static Elf_Addr get_fdesc(struct module 
5190  
5191         /* Create new one */
5192         fdesc->addr = value;
5193 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
5194 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
5195         return (Elf_Addr)fdesc;
5196  }
5197  #endif /* __LP64__ */
5198 @@ -373,12 +395,12 @@ static Elf_Addr get_stub(struct module *
5199         if(init_section) {
5200                 i = me->arch.init_stub_count++;
5201                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
5202 -               stub = me->module_init + me->arch.init_stub_offset + 
5203 +               stub = me->module_init_rx + me->arch.init_stub_offset + 
5204                         i * sizeof(struct stub_entry);
5205         } else {
5206                 i = me->arch.stub_count++;
5207                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
5208 -               stub = me->module_core + me->arch.stub_offset + 
5209 +               stub = me->module_core_rx + me->arch.stub_offset + 
5210                         i * sizeof(struct stub_entry);
5211         }
5212  
5213 @@ -721,7 +743,7 @@ register_unwind_table(struct module *me,
5214  
5215         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
5216         end = table + sechdrs[me->arch.unwind_section].sh_size;
5217 -       gp = (Elf_Addr)me->module_core + me->arch.got_offset;
5218 +       gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
5219  
5220         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
5221                me->arch.unwind_section, table, end, gp);
5222 diff -urNp linux-2.6.17.7/arch/parisc/kernel/ptrace.c linux-2.6.17.7/arch/parisc/kernel/ptrace.c
5223 --- linux-2.6.17.7/arch/parisc/kernel/ptrace.c  2006-07-24 23:36:01.000000000 -0400
5224 +++ linux-2.6.17.7/arch/parisc/kernel/ptrace.c  2006-08-01 20:29:45.000000000 -0400
5225 @@ -18,6 +18,7 @@
5226  #include <linux/security.h>
5227  #include <linux/compat.h>
5228  #include <linux/signal.h>
5229 +#include <linux/grsecurity.h>
5230  
5231  #include <asm/uaccess.h>
5232  #include <asm/pgtable.h>
5233 diff -urNp linux-2.6.17.7/arch/parisc/kernel/sys_parisc.c linux-2.6.17.7/arch/parisc/kernel/sys_parisc.c
5234 --- linux-2.6.17.7/arch/parisc/kernel/sys_parisc.c      2006-07-24 23:36:01.000000000 -0400
5235 +++ linux-2.6.17.7/arch/parisc/kernel/sys_parisc.c      2006-08-01 20:29:45.000000000 -0400
5236 @@ -105,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
5237         if (len > TASK_SIZE)
5238                 return -ENOMEM;
5239         if (!addr)
5240 -               addr = TASK_UNMAPPED_BASE;
5241 +               addr = current->mm->mmap_base;
5242  
5243         if (filp) {
5244                 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
5245 diff -urNp linux-2.6.17.7/arch/parisc/kernel/traps.c linux-2.6.17.7/arch/parisc/kernel/traps.c
5246 --- linux-2.6.17.7/arch/parisc/kernel/traps.c   2006-07-24 23:36:01.000000000 -0400
5247 +++ linux-2.6.17.7/arch/parisc/kernel/traps.c   2006-08-01 20:29:45.000000000 -0400
5248 @@ -711,9 +711,7 @@ void handle_interruption(int code, struc
5249  
5250                         down_read(&current->mm->mmap_sem);
5251                         vma = find_vma(current->mm,regs->iaoq[0]);
5252 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
5253 -                               && (vma->vm_flags & VM_EXEC)) {
5254 -
5255 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
5256                                 fault_address = regs->iaoq[0];
5257                                 fault_space = regs->iasq[0];
5258  
5259 diff -urNp linux-2.6.17.7/arch/parisc/mm/fault.c linux-2.6.17.7/arch/parisc/mm/fault.c
5260 --- linux-2.6.17.7/arch/parisc/mm/fault.c       2006-07-24 23:36:01.000000000 -0400
5261 +++ linux-2.6.17.7/arch/parisc/mm/fault.c       2006-08-01 20:29:45.000000000 -0400
5262 @@ -16,6 +16,8 @@
5263  #include <linux/sched.h>
5264  #include <linux/interrupt.h>
5265  #include <linux/module.h>
5266 +#include <linux/unistd.h>
5267 +#include <linux/binfmts.h>
5268  
5269  #include <asm/uaccess.h>
5270  #include <asm/traps.h>
5271 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
5272  static unsigned long
5273  parisc_acctyp(unsigned long code, unsigned int inst)
5274  {
5275 -       if (code == 6 || code == 16)
5276 +       if (code == 6 || code == 7 || code == 16)
5277             return VM_EXEC;
5278  
5279         switch (inst & 0xf0000000) {
5280 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
5281                         }
5282  #endif
5283  
5284 +#ifdef CONFIG_PAX_PAGEEXEC
5285 +/*
5286 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
5287 + *
5288 + * returns 1 when task should be killed
5289 + *         2 when rt_sigreturn trampoline was detected
5290 + *         3 when unpatched PLT trampoline was detected
5291 + */
5292 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5293 +{
5294 +
5295 +#ifdef CONFIG_PAX_EMUPLT
5296 +       int err;
5297 +
5298 +       do { /* PaX: unpatched PLT emulation */
5299 +               unsigned int bl, depwi;
5300 +
5301 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
5302 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
5303 +
5304 +               if (err)
5305 +                       break;
5306 +
5307 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
5308 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
5309 +
5310 +                       err = get_user(ldw, (unsigned int*)addr);
5311 +                       err |= get_user(bv, (unsigned int*)(addr+4));
5312 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
5313 +
5314 +                       if (err)
5315 +                               break;
5316 +
5317 +                       if (ldw == 0x0E801096U &&
5318 +                           bv == 0xEAC0C000U &&
5319 +                           ldw2 == 0x0E881095U)
5320 +                       {
5321 +                               unsigned int resolver, map;
5322 +
5323 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
5324 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
5325 +                               if (err)
5326 +                                       break;
5327 +
5328 +                               regs->gr[20] = instruction_pointer(regs)+8;
5329 +                               regs->gr[21] = map;
5330 +                               regs->gr[22] = resolver;
5331 +                               regs->iaoq[0] = resolver | 3UL;
5332 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
5333 +                               return 3;
5334 +                       }
5335 +               }
5336 +       } while (0);
5337 +#endif
5338 +
5339 +#ifdef CONFIG_PAX_EMUTRAMP
5340 +
5341 +#ifndef CONFIG_PAX_EMUSIGRT
5342 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
5343 +               return 1;
5344 +#endif
5345 +
5346 +       do { /* PaX: rt_sigreturn emulation */
5347 +               unsigned int ldi1, ldi2, bel, nop;
5348 +
5349 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
5350 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
5351 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
5352 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
5353 +
5354 +               if (err)
5355 +                       break;
5356 +
5357 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
5358 +                   ldi2 == 0x3414015AU &&
5359 +                   bel == 0xE4008200U &&
5360 +                   nop == 0x08000240U)
5361 +               {
5362 +                       regs->gr[25] = (ldi1 & 2) >> 1;
5363 +                       regs->gr[20] = __NR_rt_sigreturn;
5364 +                       regs->gr[31] = regs->iaoq[1] + 16;
5365 +                       regs->sr[0] = regs->iasq[1];
5366 +                       regs->iaoq[0] = 0x100UL;
5367 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
5368 +                       regs->iasq[0] = regs->sr[2];
5369 +                       regs->iasq[1] = regs->sr[2];
5370 +                       return 2;
5371 +               }
5372 +       } while (0);
5373 +#endif
5374 +
5375 +       return 1;
5376 +}
5377 +
5378 +void pax_report_insns(void *pc, void *sp)
5379 +{
5380 +       unsigned long i;
5381 +
5382 +       printk(KERN_ERR "PAX: bytes at PC: ");
5383 +       for (i = 0; i < 5; i++) {
5384 +               unsigned int c;
5385 +               if (get_user(c, (unsigned int*)pc+i))
5386 +                       printk("???????? ");
5387 +               else
5388 +                       printk("%08x ", c);
5389 +       }
5390 +       printk("\n");
5391 +}
5392 +#endif
5393 +
5394  void do_page_fault(struct pt_regs *regs, unsigned long code,
5395                               unsigned long address)
5396  {
5397 @@ -168,8 +280,33 @@ good_area:
5398  
5399         acc_type = parisc_acctyp(code,regs->iir);
5400  
5401 -       if ((vma->vm_flags & acc_type) != acc_type)
5402 +       if ((vma->vm_flags & acc_type) != acc_type) {
5403 +
5404 +#ifdef CONFIG_PAX_PAGEEXEC
5405 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
5406 +                   (address & ~3UL) == instruction_pointer(regs))
5407 +               {
5408 +                       up_read(&mm->mmap_sem);
5409 +                       switch(pax_handle_fetch_fault(regs)) {
5410 +
5411 +#ifdef CONFIG_PAX_EMUPLT
5412 +                       case 3:
5413 +                               return;
5414 +#endif
5415 +
5416 +#ifdef CONFIG_PAX_EMUTRAMP
5417 +                       case 2:
5418 +                               return;
5419 +#endif
5420 +
5421 +                       }
5422 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
5423 +                       do_exit(SIGKILL);
5424 +               }
5425 +#endif
5426 +
5427                 goto bad_area;
5428 +       }
5429  
5430         /*
5431          * If for any reason at all we couldn't handle the fault, make
5432 diff -urNp linux-2.6.17.7/arch/powerpc/kernel/module_32.c linux-2.6.17.7/arch/powerpc/kernel/module_32.c
5433 --- linux-2.6.17.7/arch/powerpc/kernel/module_32.c      2006-07-24 23:36:01.000000000 -0400
5434 +++ linux-2.6.17.7/arch/powerpc/kernel/module_32.c      2006-08-01 20:29:45.000000000 -0400
5435 @@ -123,7 +123,7 @@ int module_frob_arch_sections(Elf32_Ehdr
5436                         me->arch.core_plt_section = i;
5437         }
5438         if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
5439 -               printk("Module doesn't contain .plt or .init.plt sections.\n");
5440 +               printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
5441                 return -ENOEXEC;
5442         }
5443  
5444 @@ -164,11 +164,16 @@ static uint32_t do_plt_call(void *locati
5445  
5446         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
5447         /* Init, or core PLT? */
5448 -       if (location >= mod->module_core
5449 -           && location < mod->module_core + mod->core_size)
5450 +       if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
5451 +           (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
5452                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
5453 -       else
5454 +       else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
5455 +                (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
5456                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
5457 +       else {
5458 +               printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
5459 +               return ~0UL;
5460 +       }
5461  
5462         /* Find this entry, or if that fails, the next avail. entry */
5463         while (entry->jump[0]) {
5464 diff -urNp linux-2.6.17.7/arch/powerpc/mm/fault.c linux-2.6.17.7/arch/powerpc/mm/fault.c
5465 --- linux-2.6.17.7/arch/powerpc/mm/fault.c      2006-07-24 23:36:01.000000000 -0400
5466 +++ linux-2.6.17.7/arch/powerpc/mm/fault.c      2006-08-01 20:29:45.000000000 -0400
5467 @@ -29,6 +29,7 @@
5468  #include <linux/highmem.h>
5469  #include <linux/module.h>
5470  #include <linux/kprobes.h>
5471 +#include <linux/binfmts.h>
5472  
5473  #include <asm/page.h>
5474  #include <asm/pgtable.h>
5475 @@ -103,6 +104,38 @@ static void do_dabr(struct pt_regs *regs
5476  }
5477  #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
5478  
5479 +#ifdef CONFIG_PAX_PAGEEXEC
5480 +/*
5481 + * PaX: decide what to do with offenders (regs->nip = fault address)
5482 + *
5483 + * returns 1 when task should be killed
5484 + */
5485 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5486 +{
5487 +
5488 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
5489 +       int err;
5490 +#endif
5491 +
5492 +       return 1;
5493 +}
5494 +
5495 +void pax_report_insns(void *pc, void *sp)
5496 +{
5497 +       unsigned long i;
5498 +
5499 +       printk(KERN_ERR "PAX: bytes at PC: ");
5500 +       for (i = 0; i < 5; i++) {
5501 +               unsigned int c;
5502 +               if (get_user(c, (unsigned int*)pc+i))
5503 +                       printk("???????? ");
5504 +               else
5505 +                       printk("%08x ", c);
5506 +       }
5507 +       printk("\n");
5508 +}
5509 +#endif
5510 +
5511  /*
5512   * For 600- and 800-family processors, the error_code parameter is DSISR
5513   * for a data fault, SRR1 for an instruction fault. For 400-family processors
5514 @@ -335,6 +368,19 @@ bad_area:
5515  bad_area_nosemaphore:
5516         /* User mode accesses cause a SIGSEGV */
5517         if (user_mode(regs)) {
5518 +
5519 +#ifdef CONFIG_PAX_PAGEEXEC
5520 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
5521 +                       if (is_exec && (error_code & DSISR_PROTFAULT)) {
5522 +                               switch (pax_handle_fetch_fault(regs)) {
5523 +                               }
5524 +
5525 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
5526 +                               do_exit(SIGKILL);
5527 +                       }
5528 +               }
5529 +#endif
5530 +
5531                 _exception(SIGSEGV, regs, code, address);
5532                 return 0;
5533         }
5534 diff -urNp linux-2.6.17.7/arch/powerpc/mm/mmap.c linux-2.6.17.7/arch/powerpc/mm/mmap.c
5535 --- linux-2.6.17.7/arch/powerpc/mm/mmap.c       2006-07-24 23:36:01.000000000 -0400
5536 +++ linux-2.6.17.7/arch/powerpc/mm/mmap.c       2006-08-01 20:29:45.000000000 -0400
5537 @@ -74,10 +74,22 @@ void arch_pick_mmap_layout(struct mm_str
5538          */
5539         if (mmap_is_legacy()) {
5540                 mm->mmap_base = TASK_UNMAPPED_BASE;
5541 +
5542 +#ifdef CONFIG_PAX_RANDMMAP
5543 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5544 +                       mm->mmap_base += mm->delta_mmap;
5545 +#endif
5546 +
5547                 mm->get_unmapped_area = arch_get_unmapped_area;
5548                 mm->unmap_area = arch_unmap_area;
5549         } else {
5550                 mm->mmap_base = mmap_base();
5551 +
5552 +#ifdef CONFIG_PAX_RANDMMAP
5553 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5554 +                       mm->mmap_base -= mm->delta_mmap;
5555 +#endif
5556 +
5557                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
5558                 mm->unmap_area = arch_unmap_area_topdown;
5559         }
5560 diff -urNp linux-2.6.17.7/arch/ppc/mm/fault.c linux-2.6.17.7/arch/ppc/mm/fault.c
5561 --- linux-2.6.17.7/arch/ppc/mm/fault.c  2006-07-24 23:36:01.000000000 -0400
5562 +++ linux-2.6.17.7/arch/ppc/mm/fault.c  2006-08-01 20:29:46.000000000 -0400
5563 @@ -26,6 +26,11 @@
5564  #include <linux/interrupt.h>
5565  #include <linux/highmem.h>
5566  #include <linux/module.h>
5567 +#include <linux/slab.h>
5568 +#include <linux/pagemap.h>
5569 +#include <linux/compiler.h>
5570 +#include <linux/binfmts.h>
5571 +#include <linux/unistd.h>
5572  
5573  #include <asm/page.h>
5574  #include <asm/pgtable.h>
5575 @@ -49,6 +54,364 @@ unsigned long pte_misses;   /* updated by 
5576  unsigned long pte_errors;      /* updated by do_page_fault() */
5577  unsigned int probingmem;
5578  
5579 +#ifdef CONFIG_PAX_EMUSIGRT
5580 +void pax_syscall_close(struct vm_area_struct * vma)
5581 +{
5582 +       vma->vm_mm->call_syscall = 0UL;
5583 +}
5584 +
5585 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
5586 +{
5587 +       struct page* page;
5588 +       unsigned int *kaddr;
5589 +
5590 +       page = alloc_page(GFP_HIGHUSER);
5591 +       if (!page)
5592 +               return NOPAGE_OOM;
5593 +
5594 +       kaddr = kmap(page);
5595 +       memset(kaddr, 0, PAGE_SIZE);
5596 +       kaddr[0] = 0x44000002U; /* sc */
5597 +       __flush_dcache_icache(kaddr);
5598 +       kunmap(page);
5599 +       if (type)
5600 +               *type = VM_FAULT_MAJOR;
5601 +       return page;
5602 +}
5603 +
5604 +static struct vm_operations_struct pax_vm_ops = {
5605 +       .close = pax_syscall_close,
5606 +       .nopage = pax_syscall_nopage,
5607 +};
5608 +
5609 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
5610 +{
5611 +       int ret;
5612 +
5613 +       memset(vma, 0, sizeof(*vma));
5614 +       vma->vm_mm = current->mm;
5615 +       vma->vm_start = addr;
5616 +       vma->vm_end = addr + PAGE_SIZE;
5617 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
5618 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
5619 +       vma->vm_ops = &pax_vm_ops;
5620 +
5621 +       ret = insert_vm_struct(current->mm, vma);
5622 +       if (ret)
5623 +               return ret;
5624 +
5625 +       ++current->mm->total_vm;
5626 +       return 0;
5627 +}
5628 +#endif
5629 +
5630 +#ifdef CONFIG_PAX_PAGEEXEC
5631 +/*
5632 + * PaX: decide what to do with offenders (regs->nip = fault address)
5633 + *
5634 + * returns 1 when task should be killed
5635 + *         2 when patched GOT trampoline was detected
5636 + *         3 when patched PLT trampoline was detected
5637 + *         4 when unpatched PLT trampoline was detected
5638 + *         5 when sigreturn trampoline was detected
5639 + *         7 when rt_sigreturn trampoline was detected
5640 + */
5641 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5642 +{
5643 +
5644 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
5645 +       int err;
5646 +#endif
5647 +
5648 +#ifdef CONFIG_PAX_EMUPLT
5649 +       do { /* PaX: patched GOT emulation */
5650 +               unsigned int blrl;
5651 +
5652 +               err = get_user(blrl, (unsigned int*)regs->nip);
5653 +
5654 +               if (!err && blrl == 0x4E800021U) {
5655 +                       unsigned long temp = regs->nip;
5656 +
5657 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
5658 +                       regs->link = temp + 4UL;
5659 +                       return 2;
5660 +               }
5661 +       } while (0);
5662 +
5663 +       do { /* PaX: patched PLT emulation #1 */
5664 +               unsigned int b;
5665 +
5666 +               err = get_user(b, (unsigned int *)regs->nip);
5667 +
5668 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
5669 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
5670 +                       return 3;
5671 +               }
5672 +       } while (0);
5673 +
5674 +       do { /* PaX: unpatched PLT emulation #1 */
5675 +               unsigned int li, b;
5676 +
5677 +               err = get_user(li, (unsigned int *)regs->nip);
5678 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
5679 +
5680 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
5681 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
5682 +                       unsigned long addr = b | 0xFC000000UL;
5683 +
5684 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5685 +                       err = get_user(rlwinm, (unsigned int*)addr);
5686 +                       err |= get_user(add, (unsigned int*)(addr+4));
5687 +                       err |= get_user(li2, (unsigned int*)(addr+8));
5688 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
5689 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
5690 +                       err |= get_user(li3, (unsigned int*)(addr+20));
5691 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
5692 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
5693 +
5694 +                       if (err)
5695 +                               break;
5696 +
5697 +                       if (rlwinm == 0x556C083CU &&
5698 +                           add == 0x7D6C5A14U &&
5699 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
5700 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
5701 +                           mtctr == 0x7D8903A6U &&
5702 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
5703 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
5704 +                           bctr == 0x4E800420U)
5705 +                       {
5706 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5707 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5708 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
5709 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5710 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
5711 +                               regs->nip = regs->ctr;
5712 +                               return 4;
5713 +                       }
5714 +               }
5715 +       } while (0);
5716 +
5717 +#if 0
5718 +       do { /* PaX: unpatched PLT emulation #2 */
5719 +               unsigned int lis, lwzu, b, bctr;
5720 +
5721 +               err = get_user(lis, (unsigned int *)regs->nip);
5722 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
5723 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
5724 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
5725 +
5726 +               if (err)
5727 +                       break;
5728 +
5729 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
5730 +                   (lwzu & 0xU) == 0xU &&
5731 +                   (b & 0xFC000003U) == 0x48000000U &&
5732 +                   bctr == 0x4E800420U)
5733 +               {
5734 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
5735 +                       unsigned long addr = b | 0xFC000000UL;
5736 +
5737 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5738 +                       err = get_user(addis, (unsigned int*)addr);
5739 +                       err |= get_user(addi, (unsigned int*)(addr+4));
5740 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
5741 +                       err |= get_user(add, (unsigned int*)(addr+12));
5742 +                       err |= get_user(li2, (unsigned int*)(addr+16));
5743 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
5744 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
5745 +                       err |= get_user(li3, (unsigned int*)(addr+28));
5746 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
5747 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
5748 +
5749 +                       if (err)
5750 +                               break;
5751 +
5752 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
5753 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
5754 +                           rlwinm == 0x556C083CU &&
5755 +                           add == 0x7D6C5A14U &&
5756 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
5757 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
5758 +                           mtctr == 0x7D8903A6U &&
5759 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
5760 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
5761 +                           bctr == 0x4E800420U)
5762 +                       {
5763 +                               regs->gpr[PT_R11] = 
5764 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5765 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5766 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
5767 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5768 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
5769 +                               regs->nip = regs->ctr;
5770 +                               return 4;
5771 +                       }
5772 +               }
5773 +       } while (0);
5774 +#endif
5775 +
5776 +       do { /* PaX: unpatched PLT emulation #3 */
5777 +               unsigned int li, b;
5778 +
5779 +               err = get_user(li, (unsigned int *)regs->nip);
5780 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
5781 +
5782 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
5783 +                       unsigned int addis, lwz, mtctr, bctr;
5784 +                       unsigned long addr = b | 0xFC000000UL;
5785 +
5786 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
5787 +                       err = get_user(addis, (unsigned int*)addr);
5788 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
5789 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
5790 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
5791 +
5792 +                       if (err)
5793 +                               break;
5794 +
5795 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
5796 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
5797 +                           mtctr == 0x7D6903A6U &&
5798 +                           bctr == 0x4E800420U)
5799 +                       {
5800 +                               unsigned int r11;
5801 +
5802 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5803 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
5804 +
5805 +                               err = get_user(r11, (unsigned int*)addr);
5806 +                               if (err)
5807 +                                       break;
5808 +
5809 +                               regs->gpr[PT_R11] = r11;
5810 +                               regs->ctr = r11;
5811 +                               regs->nip = r11;
5812 +                               return 4;
5813 +                       }
5814 +               }
5815 +       } while (0);
5816 +#endif
5817 +
5818 +#ifdef CONFIG_PAX_EMUSIGRT
5819 +       do { /* PaX: sigreturn emulation */
5820 +               unsigned int li, sc;
5821 +
5822 +               err = get_user(li, (unsigned int *)regs->nip);
5823 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
5824 +
5825 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
5826 +                       struct vm_area_struct *vma;
5827 +                       unsigned long call_syscall;
5828 +
5829 +                       down_read(&current->mm->mmap_sem);
5830 +                       call_syscall = current->mm->call_syscall;
5831 +                       up_read(&current->mm->mmap_sem);
5832 +                       if (likely(call_syscall))
5833 +                               goto emulate;
5834 +
5835 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5836 +
5837 +                       down_write(&current->mm->mmap_sem);
5838 +                       if (current->mm->call_syscall) {
5839 +                               call_syscall = current->mm->call_syscall;
5840 +                               up_write(&current->mm->mmap_sem);
5841 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
5842 +                               goto emulate;
5843 +                       }
5844 +
5845 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5846 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
5847 +                               up_write(&current->mm->mmap_sem);
5848 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
5849 +                               return 1;
5850 +                       }
5851 +
5852 +                       if (pax_insert_vma(vma, call_syscall)) {
5853 +                               up_write(&current->mm->mmap_sem);
5854 +                               kmem_cache_free(vm_area_cachep, vma);
5855 +                               return 1;
5856 +                       }
5857 +
5858 +                       current->mm->call_syscall = call_syscall;
5859 +                       up_write(&current->mm->mmap_sem);
5860 +
5861 +emulate:
5862 +                       regs->gpr[PT_R0] = __NR_sigreturn;
5863 +                       regs->nip = call_syscall;
5864 +                       return 5;
5865 +               }
5866 +       } while (0);
5867 +
5868 +       do { /* PaX: rt_sigreturn emulation */
5869 +               unsigned int li, sc;
5870 +
5871 +               err = get_user(li, (unsigned int *)regs->nip);
5872 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
5873 +
5874 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
5875 +                       struct vm_area_struct *vma;
5876 +                       unsigned int call_syscall;
5877 +
5878 +                       down_read(&current->mm->mmap_sem);
5879 +                       call_syscall = current->mm->call_syscall;
5880 +                       up_read(&current->mm->mmap_sem);
5881 +                       if (likely(call_syscall))
5882 +                               goto rt_emulate;
5883 +
5884 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5885 +
5886 +                       down_write(&current->mm->mmap_sem);
5887 +                       if (current->mm->call_syscall) {
5888 +                               call_syscall = current->mm->call_syscall;
5889 +                               up_write(&current->mm->mmap_sem);
5890 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
5891 +                               goto rt_emulate;
5892 +                       }
5893 +
5894 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5895 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
5896 +                               up_write(&current->mm->mmap_sem);
5897 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
5898 +                               return 1;
5899 +                       }
5900 +
5901 +                       if (pax_insert_vma(vma, call_syscall)) {
5902 +                               up_write(&current->mm->mmap_sem);
5903 +                               kmem_cache_free(vm_area_cachep, vma);
5904 +                               return 1;
5905 +                       }
5906 +
5907 +                       current->mm->call_syscall = call_syscall;
5908 +                       up_write(&current->mm->mmap_sem);
5909 +
5910 +rt_emulate:
5911 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
5912 +                       regs->nip = call_syscall;
5913 +                       return 6;
5914 +               }
5915 +       } while (0);
5916 +#endif
5917 +
5918 +       return 1;
5919 +}
5920 +
5921 +void pax_report_insns(void *pc, void *sp)
5922 +{
5923 +       unsigned long i;
5924 +
5925 +       printk(KERN_ERR "PAX: bytes at PC: ");
5926 +       for (i = 0; i < 5; i++) {
5927 +               unsigned int c;
5928 +               if (get_user(c, (unsigned int*)pc+i))
5929 +                       printk("???????? ");
5930 +               else
5931 +                       printk("%08x ", c);
5932 +       }
5933 +       printk("\n");
5934 +}
5935 +#endif
5936 +
5937  /*
5938   * Check whether the instruction at regs->nip is a store using
5939   * an update addressing form which will update r1.
5940 @@ -109,7 +472,7 @@ int do_page_fault(struct pt_regs *regs, 
5941          * indicate errors in DSISR but can validly be set in SRR1.
5942          */
5943         if (TRAP(regs) == 0x400)
5944 -               error_code &= 0x48200000;
5945 +               error_code &= 0x58200000;
5946         else
5947                 is_write = error_code & 0x02000000;
5948  #endif /* CONFIG_4xx || CONFIG_BOOKE */
5949 @@ -204,15 +567,14 @@ good_area:
5950                 pte_t *ptep;
5951                 pmd_t *pmdp;
5952  
5953 -#if 0
5954 +#if 1
5955                 /* It would be nice to actually enforce the VM execute
5956                    permission on CPUs which can do so, but far too
5957                    much stuff in userspace doesn't get the permissions
5958                    right, so we let any page be executed for now. */
5959                 if (! (vma->vm_flags & VM_EXEC))
5960                         goto bad_area;
5961 -#endif
5962 -
5963 +#else
5964                 /* Since 4xx/Book-E supports per-page execute permission,
5965                  * we lazily flush dcache to icache. */
5966                 ptep = NULL;
5967 @@ -235,6 +597,7 @@ good_area:
5968                         pte_unmap_unlock(ptep, ptl);
5969                 }
5970  #endif
5971 +#endif
5972         /* a read */
5973         } else {
5974                 /* protection fault */
5975 @@ -280,6 +643,33 @@ bad_area:
5976  
5977         /* User mode accesses cause a SIGSEGV */
5978         if (user_mode(regs)) {
5979 +
5980 +#ifdef CONFIG_PAX_PAGEEXEC
5981 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
5982 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
5983 +                               switch (pax_handle_fetch_fault(regs)) {
5984 +
5985 +#ifdef CONFIG_PAX_EMUPLT
5986 +                               case 2:
5987 +                               case 3:
5988 +                               case 4:
5989 +                                       return 0;
5990 +#endif
5991 +
5992 +#ifdef CONFIG_PAX_EMUSIGRT
5993 +                               case 5:
5994 +                               case 6:
5995 +                                       return 0;
5996 +#endif
5997 +
5998 +                               }
5999 +
6000 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
6001 +                               do_exit(SIGKILL);
6002 +                       }
6003 +               }
6004 +#endif
6005 +
6006                 _exception(SIGSEGV, regs, code, address);
6007                 return 0;
6008         }
6009 diff -urNp linux-2.6.17.7/arch/s390/kernel/module.c linux-2.6.17.7/arch/s390/kernel/module.c
6010 --- linux-2.6.17.7/arch/s390/kernel/module.c    2006-07-24 23:36:01.000000000 -0400
6011 +++ linux-2.6.17.7/arch/s390/kernel/module.c    2006-08-01 20:29:46.000000000 -0400
6012 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
6013  
6014         /* Increase core size by size of got & plt and set start
6015            offsets for got and plt. */
6016 -       me->core_size = ALIGN(me->core_size, 4);
6017 -       me->arch.got_offset = me->core_size;
6018 -       me->core_size += me->arch.got_size;
6019 -       me->arch.plt_offset = me->core_size;
6020 -       me->core_size += me->arch.plt_size;
6021 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
6022 +       me->arch.got_offset = me->core_size_rw;
6023 +       me->core_size_rw += me->arch.got_size;
6024 +       me->arch.plt_offset = me->core_size_rx;
6025 +       me->core_size_rx += me->arch.plt_size;
6026         return 0;
6027  }
6028  
6029 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6030                 if (info->got_initialized == 0) {
6031                         Elf_Addr *gotent;
6032  
6033 -                       gotent = me->module_core + me->arch.got_offset +
6034 +                       gotent = me->module_core_rw + me->arch.got_offset +
6035                                 info->got_offset;
6036                         *gotent = val;
6037                         info->got_initialized = 1;
6038 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6039                 else if (r_type == R_390_GOTENT ||
6040                          r_type == R_390_GOTPLTENT)
6041                         *(unsigned int *) loc =
6042 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
6043 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
6044                 else if (r_type == R_390_GOT64 ||
6045                          r_type == R_390_GOTPLT64)
6046                         *(unsigned long *) loc = val;
6047 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6048         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
6049                 if (info->plt_initialized == 0) {
6050                         unsigned int *ip;
6051 -                       ip = me->module_core + me->arch.plt_offset +
6052 +                       ip = me->module_core_rx + me->arch.plt_offset +
6053                                 info->plt_offset;
6054  #ifndef CONFIG_64BIT
6055                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
6056 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6057                         val = me->arch.plt_offset - me->arch.got_offset +
6058                                 info->plt_offset + rela->r_addend;
6059                 else
6060 -                       val =  (Elf_Addr) me->module_core +
6061 +                       val =  (Elf_Addr) me->module_core_rx +
6062                                 me->arch.plt_offset + info->plt_offset + 
6063                                 rela->r_addend - loc;
6064                 if (r_type == R_390_PLT16DBL)
6065 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6066         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
6067         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
6068                 val = val + rela->r_addend -
6069 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
6070 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
6071                 if (r_type == R_390_GOTOFF16)
6072                         *(unsigned short *) loc = val;
6073                 else if (r_type == R_390_GOTOFF32)
6074 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
6075                 break;
6076         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
6077         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
6078 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
6079 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
6080                         rela->r_addend - loc;
6081                 if (r_type == R_390_GOTPC)
6082                         *(unsigned int *) loc = val;
6083 diff -urNp linux-2.6.17.7/arch/sparc/Makefile linux-2.6.17.7/arch/sparc/Makefile
6084 --- linux-2.6.17.7/arch/sparc/Makefile  2006-07-24 23:36:01.000000000 -0400
6085 +++ linux-2.6.17.7/arch/sparc/Makefile  2006-08-01 20:29:46.000000000 -0400
6086 @@ -34,7 +34,7 @@ libs-y += arch/sparc/prom/ arch/sparc/li
6087  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
6088  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
6089  CORE_Y         := $(core-y)
6090 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
6091 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
6092  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
6093  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
6094  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
6095 diff -urNp linux-2.6.17.7/arch/sparc/kernel/ptrace.c linux-2.6.17.7/arch/sparc/kernel/ptrace.c
6096 --- linux-2.6.17.7/arch/sparc/kernel/ptrace.c   2006-07-24 23:36:01.000000000 -0400
6097 +++ linux-2.6.17.7/arch/sparc/kernel/ptrace.c   2006-08-01 20:29:46.000000000 -0400
6098 @@ -19,6 +19,7 @@
6099  #include <linux/security.h>
6100  #include <linux/signal.h>
6101  #include <linux/vs_pid.h>
6102 +#include <linux/grsecurity.h>
6103  
6104  #include <asm/pgtable.h>
6105  #include <asm/system.h>
6106 @@ -300,6 +301,11 @@ asmlinkage void do_ptrace(struct pt_regs
6107                 goto out;
6108         }
6109  
6110 +       if (gr_handle_ptrace(child, request)) {
6111 +               pt_error_return(regs, EPERM);
6112 +               goto out_tsk;
6113 +       }
6114 +
6115         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
6116             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
6117                 if (ptrace_attach(child)) {
6118 diff -urNp linux-2.6.17.7/arch/sparc/kernel/sys_sparc.c linux-2.6.17.7/arch/sparc/kernel/sys_sparc.c
6119 --- linux-2.6.17.7/arch/sparc/kernel/sys_sparc.c        2006-07-24 23:36:01.000000000 -0400
6120 +++ linux-2.6.17.7/arch/sparc/kernel/sys_sparc.c        2006-08-01 20:29:46.000000000 -0400
6121 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
6122         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
6123                 return -ENOMEM;
6124         if (!addr)
6125 -               addr = TASK_UNMAPPED_BASE;
6126 +               addr = current->mm->mmap_base;
6127  
6128         if (flags & MAP_SHARED)
6129                 addr = COLOUR_ALIGN(addr);
6130 diff -urNp linux-2.6.17.7/arch/sparc/mm/fault.c linux-2.6.17.7/arch/sparc/mm/fault.c
6131 --- linux-2.6.17.7/arch/sparc/mm/fault.c        2006-07-24 23:36:01.000000000 -0400
6132 +++ linux-2.6.17.7/arch/sparc/mm/fault.c        2006-08-01 20:29:46.000000000 -0400
6133 @@ -21,6 +21,10 @@
6134  #include <linux/smp_lock.h>
6135  #include <linux/interrupt.h>
6136  #include <linux/module.h>
6137 +#include <linux/slab.h>
6138 +#include <linux/pagemap.h>
6139 +#include <linux/compiler.h>
6140 +#include <linux/binfmts.h>
6141  
6142  #include <asm/system.h>
6143  #include <asm/page.h>
6144 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
6145         return safe_compute_effective_address(regs, insn);
6146  }
6147  
6148 +#ifdef CONFIG_PAX_PAGEEXEC
6149 +void pax_emuplt_close(struct vm_area_struct * vma)
6150 +{
6151 +       vma->vm_mm->call_dl_resolve = 0UL;
6152 +}
6153 +
6154 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6155 +{
6156 +       struct page* page;
6157 +       unsigned int *kaddr;
6158 +
6159 +       page = alloc_page(GFP_HIGHUSER);
6160 +       if (!page)
6161 +               return NOPAGE_OOM;
6162 +
6163 +       kaddr = kmap(page);
6164 +       memset(kaddr, 0, PAGE_SIZE);
6165 +       kaddr[0] = 0x9DE3BFA8U; /* save */
6166 +       flush_dcache_page(page);
6167 +       kunmap(page);
6168 +       if (type)
6169 +               *type = VM_FAULT_MAJOR;
6170 +
6171 +       return page;
6172 +}
6173 +
6174 +static struct vm_operations_struct pax_vm_ops = {
6175 +       .close = pax_emuplt_close,
6176 +       .nopage = pax_emuplt_nopage,
6177 +};
6178 +
6179 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6180 +{
6181 +       int ret;
6182 +
6183 +       memset(vma, 0, sizeof(*vma));
6184 +       vma->vm_mm = current->mm;
6185 +       vma->vm_start = addr;
6186 +       vma->vm_end = addr + PAGE_SIZE;
6187 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6188 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6189 +       vma->vm_ops = &pax_vm_ops;
6190 +
6191 +       ret = insert_vm_struct(current->mm, vma);
6192 +       if (ret)
6193 +               return ret;
6194 +
6195 +       ++current->mm->total_vm;
6196 +       return 0;
6197 +}
6198 +
6199 +/*
6200 + * PaX: decide what to do with offenders (regs->pc = fault address)
6201 + *
6202 + * returns 1 when task should be killed
6203 + *         2 when patched PLT trampoline was detected
6204 + *         3 when unpatched PLT trampoline was detected
6205 + */
6206 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6207 +{
6208 +
6209 +#ifdef CONFIG_PAX_EMUPLT
6210 +       int err;
6211 +
6212 +       do { /* PaX: patched PLT emulation #1 */
6213 +               unsigned int sethi1, sethi2, jmpl;
6214 +
6215 +               err = get_user(sethi1, (unsigned int*)regs->pc);
6216 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
6217 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
6218 +
6219 +               if (err)
6220 +                       break;
6221 +
6222 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6223 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
6224 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
6225 +               {
6226 +                       unsigned int addr;
6227 +
6228 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
6229 +                       addr = regs->u_regs[UREG_G1];
6230 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
6231 +                       regs->pc = addr;
6232 +                       regs->npc = addr+4;
6233 +                       return 2;
6234 +               }
6235 +       } while (0);
6236 +
6237 +       { /* PaX: patched PLT emulation #2 */
6238 +               unsigned int ba;
6239 +
6240 +               err = get_user(ba, (unsigned int*)regs->pc);
6241 +
6242 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
6243 +                       unsigned int addr;
6244 +
6245 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
6246 +                       regs->pc = addr;
6247 +                       regs->npc = addr+4;
6248 +                       return 2;
6249 +               }
6250 +       }
6251 +
6252 +       do { /* PaX: patched PLT emulation #3 */
6253 +               unsigned int sethi, jmpl, nop;
6254 +
6255 +               err = get_user(sethi, (unsigned int*)regs->pc);
6256 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
6257 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
6258 +
6259 +               if (err)
6260 +                       break;
6261 +
6262 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6263 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
6264 +                   nop == 0x01000000U)
6265 +               {
6266 +                       unsigned int addr;
6267 +
6268 +                       addr = (sethi & 0x003FFFFFU) << 10;
6269 +                       regs->u_regs[UREG_G1] = addr;
6270 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
6271 +                       regs->pc = addr;
6272 +                       regs->npc = addr+4;
6273 +                       return 2;
6274 +               }
6275 +       } while (0);
6276 +
6277 +       do { /* PaX: unpatched PLT emulation step 1 */
6278 +               unsigned int sethi, ba, nop;
6279 +
6280 +               err = get_user(sethi, (unsigned int*)regs->pc);
6281 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
6282 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
6283 +
6284 +               if (err)
6285 +                       break;
6286 +
6287 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6288 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
6289 +                   nop == 0x01000000U)
6290 +               {
6291 +                       unsigned int addr, save, call;
6292 +
6293 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
6294 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
6295 +                       else
6296 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
6297 +
6298 +                       err = get_user(save, (unsigned int*)addr);
6299 +                       err |= get_user(call, (unsigned int*)(addr+4));
6300 +                       err |= get_user(nop, (unsigned int*)(addr+8));
6301 +                       if (err)
6302 +                               break;
6303 +
6304 +                       if (save == 0x9DE3BFA8U &&
6305 +                           (call & 0xC0000000U) == 0x40000000U &&
6306 +                           nop == 0x01000000U)
6307 +                       {
6308 +                               struct vm_area_struct *vma;
6309 +                               unsigned long call_dl_resolve;
6310 +
6311 +                               down_read(&current->mm->mmap_sem);
6312 +                               call_dl_resolve = current->mm->call_dl_resolve;
6313 +                               up_read(&current->mm->mmap_sem);
6314 +                               if (likely(call_dl_resolve))
6315 +                                       goto emulate;
6316 +
6317 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6318 +
6319 +                               down_write(&current->mm->mmap_sem);
6320 +                               if (current->mm->call_dl_resolve) {
6321 +                                       call_dl_resolve = current->mm->call_dl_resolve;
6322 +                                       up_write(&current->mm->mmap_sem);
6323 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
6324 +                                       goto emulate;
6325 +                               }
6326 +
6327 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6328 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
6329 +                                       up_write(&current->mm->mmap_sem);
6330 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
6331 +                                       return 1;
6332 +                               }
6333 +
6334 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
6335 +                                       up_write(&current->mm->mmap_sem);
6336 +                                       kmem_cache_free(vm_area_cachep, vma);
6337 +                                       return 1;
6338 +                               }
6339 +
6340 +                               current->mm->call_dl_resolve = call_dl_resolve;
6341 +                               up_write(&current->mm->mmap_sem);
6342 +
6343 +emulate:
6344 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
6345 +                               regs->pc = call_dl_resolve;
6346 +                               regs->npc = addr+4;
6347 +                               return 3;
6348 +                       }
6349 +               }
6350 +       } while (0);
6351 +
6352 +       do { /* PaX: unpatched PLT emulation step 2 */
6353 +               unsigned int save, call, nop;
6354 +
6355 +               err = get_user(save, (unsigned int*)(regs->pc-4));
6356 +               err |= get_user(call, (unsigned int*)regs->pc);
6357 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
6358 +               if (err)
6359 +                       break;
6360 +
6361 +               if (save == 0x9DE3BFA8U &&
6362 +                   (call & 0xC0000000U) == 0x40000000U &&
6363 +                   nop == 0x01000000U)
6364 +               {
6365 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
6366 +
6367 +                       regs->u_regs[UREG_RETPC] = regs->pc;
6368 +                       regs->pc = dl_resolve;
6369 +                       regs->npc = dl_resolve+4;
6370 +                       return 3;
6371 +               }
6372 +       } while (0);
6373 +#endif
6374 +
6375 +       return 1;
6376 +}
6377 +
6378 +void pax_report_insns(void *pc, void *sp)
6379 +{
6380 +       unsigned long i;
6381 +
6382 +       printk(KERN_ERR "PAX: bytes at PC: ");
6383 +       for (i = 0; i < 5; i++) {
6384 +               unsigned int c;
6385 +               if (get_user(c, (unsigned int*)pc+i))
6386 +                       printk("???????? ");
6387 +               else
6388 +                       printk("%08x ", c);
6389 +       }
6390 +       printk("\n");
6391 +}
6392 +#endif
6393 +
6394  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
6395                                unsigned long address)
6396  {
6397 @@ -280,6 +530,24 @@ good_area:
6398                 if(!(vma->vm_flags & VM_WRITE))
6399                         goto bad_area;
6400         } else {
6401 +
6402 +#ifdef CONFIG_PAX_PAGEEXEC
6403 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
6404 +                       up_read(&mm->mmap_sem);
6405 +                       switch (pax_handle_fetch_fault(regs)) {
6406 +
6407 +#ifdef CONFIG_PAX_EMUPLT
6408 +                       case 2:
6409 +                       case 3:
6410 +                               return;
6411 +#endif
6412 +
6413 +                       }
6414 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
6415 +                       do_exit(SIGKILL);
6416 +               }
6417 +#endif
6418 +
6419                 /* Allow reads even for write-only mappings */
6420                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
6421                         goto bad_area;
6422 diff -urNp linux-2.6.17.7/arch/sparc/mm/init.c linux-2.6.17.7/arch/sparc/mm/init.c
6423 --- linux-2.6.17.7/arch/sparc/mm/init.c 2006-07-24 23:36:01.000000000 -0400
6424 +++ linux-2.6.17.7/arch/sparc/mm/init.c 2006-08-01 20:29:46.000000000 -0400
6425 @@ -333,17 +333,17 @@ void __init paging_init(void)
6426  
6427         /* Initialize the protection map with non-constant, MMU dependent values. */
6428         protection_map[0] = PAGE_NONE;
6429 -       protection_map[1] = PAGE_READONLY;
6430 -       protection_map[2] = PAGE_COPY;
6431 -       protection_map[3] = PAGE_COPY;
6432 +       protection_map[1] = PAGE_READONLY_NOEXEC;
6433 +       protection_map[2] = PAGE_COPY_NOEXEC;
6434 +       protection_map[3] = PAGE_COPY_NOEXEC;
6435         protection_map[4] = PAGE_READONLY;
6436         protection_map[5] = PAGE_READONLY;
6437         protection_map[6] = PAGE_COPY;
6438         protection_map[7] = PAGE_COPY;
6439         protection_map[8] = PAGE_NONE;
6440 -       protection_map[9] = PAGE_READONLY;
6441 -       protection_map[10] = PAGE_SHARED;
6442 -       protection_map[11] = PAGE_SHARED;
6443 +       protection_map[9] = PAGE_READONLY_NOEXEC;
6444 +       protection_map[10] = PAGE_SHARED_NOEXEC;
6445 +       protection_map[11] = PAGE_SHARED_NOEXEC;
6446         protection_map[12] = PAGE_READONLY;
6447         protection_map[13] = PAGE_READONLY;
6448         protection_map[14] = PAGE_SHARED;
6449 diff -urNp linux-2.6.17.7/arch/sparc/mm/srmmu.c linux-2.6.17.7/arch/sparc/mm/srmmu.c
6450 --- linux-2.6.17.7/arch/sparc/mm/srmmu.c        2006-07-24 23:36:01.000000000 -0400
6451 +++ linux-2.6.17.7/arch/sparc/mm/srmmu.c        2006-08-01 20:29:46.000000000 -0400
6452 @@ -2161,6 +2161,13 @@ void __init ld_mmu_srmmu(void)
6453         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
6454         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
6455         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
6456 +
6457 +#ifdef CONFIG_PAX_PAGEEXEC
6458 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
6459 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
6460 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
6461 +#endif
6462 +
6463         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
6464         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
6465  
6466 diff -urNp linux-2.6.17.7/arch/sparc64/kernel/ptrace.c linux-2.6.17.7/arch/sparc64/kernel/ptrace.c
6467 --- linux-2.6.17.7/arch/sparc64/kernel/ptrace.c 2006-07-24 23:36:01.000000000 -0400
6468 +++ linux-2.6.17.7/arch/sparc64/kernel/ptrace.c 2006-08-01 20:29:46.000000000 -0400
6469 @@ -22,6 +22,7 @@
6470  #include <linux/audit.h>
6471  #include <linux/signal.h>
6472  #include <linux/vs_pid.h>
6473 +#include <linux/grsecurity.h>
6474  
6475  #include <asm/asi.h>
6476  #include <asm/pgtable.h>
6477 @@ -213,6 +214,11 @@ asmlinkage void do_ptrace(struct pt_regs
6478                 goto out;
6479         }
6480  
6481 +       if (gr_handle_ptrace(child, (long)request)) {
6482 +               pt_error_return(regs, EPERM);
6483 +               goto out_tsk;
6484 +       }
6485 +
6486         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
6487             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
6488                 if (ptrace_attach(child)) {
6489 diff -urNp linux-2.6.17.7/arch/sparc64/kernel/sys_sparc.c linux-2.6.17.7/arch/sparc64/kernel/sys_sparc.c
6490 --- linux-2.6.17.7/arch/sparc64/kernel/sys_sparc.c      2006-07-24 23:36:01.000000000 -0400
6491 +++ linux-2.6.17.7/arch/sparc64/kernel/sys_sparc.c      2006-08-01 20:29:46.000000000 -0400
6492 @@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str
6493         if (filp || (flags & MAP_SHARED))
6494                 do_color_align = 1;
6495  
6496 +#ifdef CONFIG_PAX_RANDMMAP
6497 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6498 +#endif
6499 +
6500         if (addr) {
6501                 if (do_color_align)
6502                         addr = COLOUR_ALIGN(addr, pgoff);
6503 @@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
6504         }
6505  
6506         if (len > mm->cached_hole_size) {
6507 -               start_addr = addr = mm->free_area_cache;
6508 +               start_addr = addr = mm->free_area_cache;
6509         } else {
6510 -               start_addr = addr = TASK_UNMAPPED_BASE;
6511 +               start_addr = addr = mm->mmap_base;
6512                 mm->cached_hole_size = 0;
6513         }
6514  
6515 @@ -175,8 +179,8 @@ full_search:
6516                         vma = find_vma(mm, VA_EXCLUDE_END);
6517                 }
6518                 if (unlikely(task_size < addr)) {
6519 -                       if (start_addr != TASK_UNMAPPED_BASE) {
6520 -                               start_addr = addr = TASK_UNMAPPED_BASE;
6521 +                       if (start_addr != mm->mmap_base) {
6522 +                               start_addr = addr = mm->mmap_base;
6523                                 mm->cached_hole_size = 0;
6524                                 goto full_search;
6525                         }
6526 diff -urNp linux-2.6.17.7/arch/sparc64/mm/fault.c linux-2.6.17.7/arch/sparc64/mm/fault.c
6527 --- linux-2.6.17.7/arch/sparc64/mm/fault.c      2006-07-24 23:36:01.000000000 -0400
6528 +++ linux-2.6.17.7/arch/sparc64/mm/fault.c      2006-08-01 20:29:46.000000000 -0400
6529 @@ -19,6 +19,10 @@
6530  #include <linux/init.h>
6531  #include <linux/interrupt.h>
6532  #include <linux/kprobes.h>
6533 +#include <linux/slab.h>
6534 +#include <linux/pagemap.h>
6535 +#include <linux/compiler.h>
6536 +#include <linux/binfmts.h>
6537  
6538  #include <asm/page.h>
6539  #include <asm/pgtable.h>
6540 @@ -253,6 +257,369 @@ cannot_handle:
6541         unhandled_fault (address, current, regs);
6542  }
6543  
6544 +#ifdef CONFIG_PAX_PAGEEXEC
6545 +#ifdef CONFIG_PAX_EMUPLT
6546 +static void pax_emuplt_close(struct vm_area_struct * vma)
6547 +{
6548 +       vma->vm_mm->call_dl_resolve = 0UL;
6549 +}
6550 +
6551 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6552 +{
6553 +       struct page* page;
6554 +       unsigned int *kaddr;
6555 +
6556 +       page = alloc_page(GFP_HIGHUSER);
6557 +       if (!page)
6558 +               return NOPAGE_OOM;
6559 +
6560 +       kaddr = kmap(page);
6561 +       memset(kaddr, 0, PAGE_SIZE);
6562 +       kaddr[0] = 0x9DE3BFA8U; /* save */
6563 +       flush_dcache_page(page);
6564 +       kunmap(page);
6565 +       if (type)
6566 +               *type = VM_FAULT_MAJOR;
6567 +       return page;
6568 +}
6569 +
6570 +static struct vm_operations_struct pax_vm_ops = {
6571 +       .close = pax_emuplt_close,
6572 +       .nopage = pax_emuplt_nopage,
6573 +};
6574 +
6575 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6576 +{
6577 +       int ret;
6578 +
6579 +       memset(vma, 0, sizeof(*vma));
6580 +       vma->vm_mm = current->mm;
6581 +       vma->vm_start = addr;
6582 +       vma->vm_end = addr + PAGE_SIZE;
6583 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6584 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
6585 +       vma->vm_ops = &pax_vm_ops;
6586 +
6587 +       ret = insert_vm_struct(current->mm, vma);
6588 +       if (ret)
6589 +               return ret;
6590 +
6591 +       ++current->mm->total_vm;
6592 +       return 0;
6593 +}
6594 +#endif
6595 +
6596 +/*
6597 + * PaX: decide what to do with offenders (regs->tpc = fault address)
6598 + *
6599 + * returns 1 when task should be killed
6600 + *         2 when patched PLT trampoline was detected
6601 + *         3 when unpatched PLT trampoline was detected
6602 + */
6603 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6604 +{
6605 +
6606 +#ifdef CONFIG_PAX_EMUPLT
6607 +       int err;
6608 +
6609 +       do { /* PaX: patched PLT emulation #1 */
6610 +               unsigned int sethi1, sethi2, jmpl;
6611 +
6612 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
6613 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6614 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
6615 +
6616 +               if (err)
6617 +                       break;
6618 +
6619 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6620 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
6621 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
6622 +               {
6623 +                       unsigned long addr;
6624 +
6625 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
6626 +                       addr = regs->u_regs[UREG_G1];
6627 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
6628 +                       regs->tpc = addr;
6629 +                       regs->tnpc = addr+4;
6630 +                       return 2;
6631 +               }
6632 +       } while (0);
6633 +
6634 +       { /* PaX: patched PLT emulation #2 */
6635 +               unsigned int ba;
6636 +
6637 +               err = get_user(ba, (unsigned int*)regs->tpc);
6638 +
6639 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
6640 +                       unsigned long addr;
6641 +
6642 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
6643 +                       regs->tpc = addr;
6644 +                       regs->tnpc = addr+4;
6645 +                       return 2;
6646 +               }
6647 +       }
6648 +
6649 +       do { /* PaX: patched PLT emulation #3 */
6650 +               unsigned int sethi, jmpl, nop;
6651 +
6652 +               err = get_user(sethi, (unsigned int*)regs->tpc);
6653 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
6654 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6655 +
6656 +               if (err)
6657 +                       break;
6658 +
6659 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6660 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
6661 +                   nop == 0x01000000U)
6662 +               {
6663 +                       unsigned long addr;
6664 +
6665 +                       addr = (sethi & 0x003FFFFFU) << 10;
6666 +                       regs->u_regs[UREG_G1] = addr;
6667 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
6668 +                       regs->tpc = addr;
6669 +                       regs->tnpc = addr+4;
6670 +                       return 2;
6671 +               }
6672 +       } while (0);
6673 +
6674 +       do { /* PaX: patched PLT emulation #4 */
6675 +               unsigned int mov1, call, mov2;
6676 +
6677 +               err = get_user(mov1, (unsigned int*)regs->tpc);
6678 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
6679 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
6680 +
6681 +               if (err)
6682 +                       break;
6683 +
6684 +               if (mov1 == 0x8210000FU &&
6685 +                   (call & 0xC0000000U) == 0x40000000U &&
6686 +                   mov2 == 0x9E100001U)
6687 +               {
6688 +                       unsigned long addr;
6689 +
6690 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
6691 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
6692 +                       regs->tpc = addr;
6693 +                       regs->tnpc = addr+4;
6694 +                       return 2;
6695 +               }
6696 +       } while (0);
6697 +
6698 +       do { /* PaX: patched PLT emulation #5 */
6699 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
6700 +
6701 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
6702 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6703 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
6704 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
6705 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
6706 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
6707 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
6708 +
6709 +               if (err)
6710 +                       break;
6711 +
6712 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6713 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
6714 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
6715 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
6716 +                   sllx == 0x83287020 &&
6717 +                   jmpl == 0x81C04005U &&
6718 +                   nop == 0x01000000U)
6719 +               {
6720 +                       unsigned long addr;
6721 +
6722 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
6723 +                       regs->u_regs[UREG_G1] <<= 32;
6724 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
6725 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
6726 +                       regs->tpc = addr;
6727 +                       regs->tnpc = addr+4;
6728 +                       return 2;
6729 +               }
6730 +       } while (0);
6731 +
6732 +       do { /* PaX: patched PLT emulation #6 */
6733 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
6734 +
6735 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
6736 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
6737 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
6738 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
6739 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
6740 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
6741 +
6742 +               if (err)
6743 +                       break;
6744 +
6745 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
6746 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
6747 +                   sllx == 0x83287020 &&
6748 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
6749 +                   jmpl == 0x81C04005U &&
6750 +                   nop == 0x01000000U)
6751 +               {
6752 +                       unsigned long addr;
6753 +
6754 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
6755 +                       regs->u_regs[UREG_G1] <<= 32;
6756 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
6757 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
6758 +                       regs->tpc = addr;
6759 +                       regs->tnpc = addr+4;
6760 +                       return 2;
6761 +               }
6762 +       } while (0);
6763 +
6764 +       do { /* PaX: patched PLT emulation #7 */
6765 +               unsigned int sethi, ba, nop;
6766 +
6767 +               err = get_user(sethi, (unsigned int*)regs->tpc);
6768 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
6769 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6770 +
6771 +               if (err)
6772 +                       break;
6773 +
6774 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6775 +                   (ba & 0xFFF00000U) == 0x30600000U &&
6776 +                   nop == 0x01000000U)
6777 +               {
6778 +                       unsigned long addr;
6779 +
6780 +                       addr = (sethi & 0x003FFFFFU) << 10;
6781 +                       regs->u_regs[UREG_G1] = addr;
6782 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
6783 +                       regs->tpc = addr;
6784 +                       regs->tnpc = addr+4;
6785 +                       return 2;
6786 +               }
6787 +       } while (0);
6788 +
6789 +       do { /* PaX: unpatched PLT emulation step 1 */
6790 +               unsigned int sethi, ba, nop;
6791 +
6792 +               err = get_user(sethi, (unsigned int*)regs->tpc);
6793 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
6794 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
6795 +
6796 +               if (err)
6797 +                       break;
6798 +
6799 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
6800 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
6801 +                   nop == 0x01000000U)
6802 +               {
6803 +                       unsigned long addr;
6804 +                       unsigned int save, call;
6805 +
6806 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
6807 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
6808 +                       else
6809 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
6810 +
6811 +                       err = get_user(save, (unsigned int*)addr);
6812 +                       err |= get_user(call, (unsigned int*)(addr+4));
6813 +                       err |= get_user(nop, (unsigned int*)(addr+8));
6814 +                       if (err)
6815 +                               break;
6816 +
6817 +                       if (save == 0x9DE3BFA8U &&
6818 +                           (call & 0xC0000000U) == 0x40000000U &&
6819 +                           nop == 0x01000000U)
6820 +                       {
6821 +                               struct vm_area_struct *vma;
6822 +                               unsigned long call_dl_resolve;
6823 +
6824 +                               down_read(&current->mm->mmap_sem);
6825 +                               call_dl_resolve = current->mm->call_dl_resolve;
6826 +                               up_read(&current->mm->mmap_sem);
6827 +                               if (likely(call_dl_resolve))
6828 +                                       goto emulate;
6829 +
6830 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6831 +
6832 +                               down_write(&current->mm->mmap_sem);
6833 +                               if (current->mm->call_dl_resolve) {
6834 +                                       call_dl_resolve = current->mm->call_dl_resolve;
6835 +                                       up_write(&current->mm->mmap_sem);
6836 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
6837 +                                       goto emulate;
6838 +                               }
6839 +
6840 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6841 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
6842 +                                       up_write(&current->mm->mmap_sem);
6843 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
6844 +                                       return 1;
6845 +                               }
6846 +
6847 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
6848 +                                       up_write(&current->mm->mmap_sem);
6849 +                                       kmem_cache_free(vm_area_cachep, vma);
6850 +                                       return 1;
6851 +                               }
6852 +
6853 +                               current->mm->call_dl_resolve = call_dl_resolve;
6854 +                               up_write(&current->mm->mmap_sem);
6855 +
6856 +emulate:
6857 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
6858 +                               regs->tpc = call_dl_resolve;
6859 +                               regs->tnpc = addr+4;
6860 +                               return 3;
6861 +                       }
6862 +               }
6863 +       } while (0);
6864 +
6865 +       do { /* PaX: unpatched PLT emulation step 2 */
6866 +               unsigned int save, call, nop;
6867 +
6868 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
6869 +               err |= get_user(call, (unsigned int*)regs->tpc);
6870 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
6871 +               if (err)
6872 +                       break;
6873 +
6874 +               if (save == 0x9DE3BFA8U &&
6875 +                   (call & 0xC0000000U) == 0x40000000U &&
6876 +                   nop == 0x01000000U)
6877 +               {
6878 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
6879 +
6880 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
6881 +                       regs->tpc = dl_resolve;
6882 +                       regs->tnpc = dl_resolve+4;
6883 +                       return 3;
6884 +               }
6885 +       } while (0);
6886 +#endif
6887 +
6888 +       return 1;
6889 +}
6890 +
6891 +void pax_report_insns(void *pc, void *sp)
6892 +{
6893 +       unsigned long i;
6894 +
6895 +       printk(KERN_ERR "PAX: bytes at PC: ");
6896 +       for (i = 0; i < 5; i++) {
6897 +               unsigned int c;
6898 +               if (get_user(c, (unsigned int*)pc+i))
6899 +                       printk("???????? ");
6900 +               else
6901 +                       printk("%08x ", c);
6902 +       }
6903 +       printk("\n");
6904 +}
6905 +#endif
6906 +
6907  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
6908  {
6909         struct mm_struct *mm = current->mm;
6910 @@ -295,8 +662,10 @@ asmlinkage void __kprobes do_sparc64_fau
6911                 goto intr_or_no_mm;
6912  
6913         if (test_thread_flag(TIF_32BIT)) {
6914 -               if (!(regs->tstate & TSTATE_PRIV))
6915 +               if (!(regs->tstate & TSTATE_PRIV)) {
6916                         regs->tpc &= 0xffffffff;
6917 +                       regs->tnpc &= 0xffffffff;
6918 +               }
6919                 address &= 0xffffffff;
6920         }
6921  
6922 @@ -313,6 +682,29 @@ asmlinkage void __kprobes do_sparc64_fau
6923         if (!vma)
6924                 goto bad_area;
6925  
6926 +#ifdef CONFIG_PAX_PAGEEXEC
6927 +       /* PaX: detect ITLB misses on non-exec pages */
6928 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
6929 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
6930 +       {
6931 +               if (address != regs->tpc)
6932 +                       goto good_area;
6933 +
6934 +               up_read(&mm->mmap_sem);
6935 +               switch (pax_handle_fetch_fault(regs)) {
6936 +
6937 +#ifdef CONFIG_PAX_EMUPLT
6938 +               case 2:
6939 +               case 3:
6940 +                       return;
6941 +#endif
6942 +
6943 +               }
6944 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
6945 +               do_exit(SIGKILL);
6946 +       }
6947 +#endif
6948 +
6949         /* Pure DTLB misses do not tell us whether the fault causing
6950          * load/store/atomic was a write or not, it only says that there
6951          * was no match.  So in such a case we (carefully) read the
6952 diff -urNp linux-2.6.17.7/arch/v850/kernel/module.c linux-2.6.17.7/arch/v850/kernel/module.c
6953 --- linux-2.6.17.7/arch/v850/kernel/module.c    2006-07-24 23:36:01.000000000 -0400
6954 +++ linux-2.6.17.7/arch/v850/kernel/module.c    2006-08-01 20:29:46.000000000 -0400
6955 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
6956         tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
6957  
6958         /* Init, or core PLT? */
6959 -       if (location >= mod->module_core
6960 -           && location < mod->module_core + mod->core_size)
6961 +       if (location >= mod->module_core_rx
6962 +           && location < mod->module_core_rx + mod->core_size_rx)
6963                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
6964         else
6965                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
6966 diff -urNp linux-2.6.17.7/arch/x86_64/boot/compressed/head.S linux-2.6.17.7/arch/x86_64/boot/compressed/head.S
6967 --- linux-2.6.17.7/arch/x86_64/boot/compressed/head.S   2006-07-24 23:36:01.000000000 -0400
6968 +++ linux-2.6.17.7/arch/x86_64/boot/compressed/head.S   2006-08-01 20:29:46.000000000 -0400
6969 @@ -41,11 +41,13 @@ startup_32:
6970         movl %eax,%gs
6971  
6972         lss stack_start,%esp
6973 +       movl 0x000000,%ecx
6974         xorl %eax,%eax
6975  1:     incl %eax               # check that A20 really IS enabled
6976         movl %eax,0x000000      # loop forever if it isn't
6977         cmpl %eax,0x100000
6978         je 1b
6979 +       movl %ecx,0x000000
6980  
6981  /*
6982   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
6983 diff -urNp linux-2.6.17.7/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.17.7/arch/x86_64/ia32/ia32_binfmt.c
6984 --- linux-2.6.17.7/arch/x86_64/ia32/ia32_binfmt.c       2006-07-24 23:36:01.000000000 -0400
6985 +++ linux-2.6.17.7/arch/x86_64/ia32/ia32_binfmt.c       2006-08-01 20:29:46.000000000 -0400
6986 @@ -186,6 +186,17 @@ struct elf_prpsinfo
6987  //#include <asm/ia32.h>
6988  #include <linux/elf.h>
6989  
6990 +#ifdef CONFIG_PAX_ASLR
6991 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
6992 +
6993 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
6994 +#define PAX_DELTA_MMAP_LEN(tsk)                16
6995 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
6996 +#define PAX_DELTA_EXEC_LEN(tsk)                16
6997 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
6998 +#define PAX_DELTA_STACK_LEN(tsk)       16
6999 +#endif
7000 +
7001  typedef struct user_i387_ia32_struct elf_fpregset_t;
7002  typedef struct user32_fxsr_struct elf_fpxregset_t;
7003  
7004 diff -urNp linux-2.6.17.7/arch/x86_64/ia32/mmap32.c linux-2.6.17.7/arch/x86_64/ia32/mmap32.c
7005 --- linux-2.6.17.7/arch/x86_64/ia32/mmap32.c    2006-07-24 23:36:01.000000000 -0400
7006 +++ linux-2.6.17.7/arch/x86_64/ia32/mmap32.c    2006-08-01 20:29:46.000000000 -0400
7007 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
7008                         (current->personality & ADDR_COMPAT_LAYOUT) ||
7009                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
7010                 mm->mmap_base = TASK_UNMAPPED_BASE;
7011 +
7012 +#ifdef CONFIG_PAX_RANDMMAP
7013 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7014 +                       mm->mmap_base += mm->delta_mmap;
7015 +#endif
7016 +
7017                 mm->get_unmapped_area = arch_get_unmapped_area;
7018                 mm->unmap_area = arch_unmap_area;
7019         } else {
7020                 mm->mmap_base = mmap_base(mm);
7021 +
7022 +#ifdef CONFIG_PAX_RANDMMAP
7023 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
7024 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7025 +#endif
7026 +
7027                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7028                 mm->unmap_area = arch_unmap_area_topdown;
7029         }
7030 diff -urNp linux-2.6.17.7/arch/x86_64/kernel/process.c linux-2.6.17.7/arch/x86_64/kernel/process.c
7031 --- linux-2.6.17.7/arch/x86_64/kernel/process.c 2006-07-24 23:36:01.000000000 -0400
7032 +++ linux-2.6.17.7/arch/x86_64/kernel/process.c 2006-08-01 20:29:46.000000000 -0400
7033 @@ -830,9 +830,3 @@ int dump_task_regs(struct task_struct *t
7034         return 1;
7035  }
7036  
7037 -unsigned long arch_align_stack(unsigned long sp)
7038 -{
7039 -       if (randomize_va_space)
7040 -               sp -= get_random_int() % 8192;
7041 -       return sp & ~0xf;
7042 -}
7043 diff -urNp linux-2.6.17.7/arch/x86_64/kernel/ptrace.c linux-2.6.17.7/arch/x86_64/kernel/ptrace.c
7044 --- linux-2.6.17.7/arch/x86_64/kernel/ptrace.c  2006-07-24 23:36:01.000000000 -0400
7045 +++ linux-2.6.17.7/arch/x86_64/kernel/ptrace.c  2006-08-01 20:29:46.000000000 -0400
7046 @@ -19,6 +19,7 @@
7047  #include <linux/audit.h>
7048  #include <linux/seccomp.h>
7049  #include <linux/signal.h>
7050 +#include <linux/grsecurity.h>
7051  
7052  #include <asm/uaccess.h>
7053  #include <asm/pgtable.h>
7054 diff -urNp linux-2.6.17.7/arch/x86_64/kernel/setup64.c linux-2.6.17.7/arch/x86_64/kernel/setup64.c
7055 --- linux-2.6.17.7/arch/x86_64/kernel/setup64.c 2006-07-24 23:36:01.000000000 -0400
7056 +++ linux-2.6.17.7/arch/x86_64/kernel/setup64.c 2006-08-01 20:29:46.000000000 -0400
7057 @@ -38,7 +38,6 @@ struct desc_ptr idt_descr = { 256 * 16 -
7058  char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
7059  
7060  unsigned long __supported_pte_mask __read_mostly = ~0UL;
7061 -static int do_not_nx __cpuinitdata = 0;
7062  
7063  /* noexec=on|off
7064  Control non executable mappings for 64bit processes.
7065 @@ -50,16 +49,14 @@ int __init nonx_setup(char *str)
7066  {
7067         if (!strncmp(str, "on", 2)) {
7068                  __supported_pte_mask |= _PAGE_NX; 
7069 -               do_not_nx = 0; 
7070         } else if (!strncmp(str, "off", 3)) {
7071 -               do_not_nx = 1;
7072                 __supported_pte_mask &= ~_PAGE_NX;
7073          }
7074         return 1;
7075  } 
7076  __setup("noexec=", nonx_setup);        /* parsed early actually */
7077  
7078 -int force_personality32 = 0; 
7079 +int force_personality32;
7080  
7081  /* noexec32=on|off
7082  Control non executable heap for 32bit processes.
7083 @@ -173,7 +170,7 @@ void __cpuinit check_efer(void)
7084         unsigned long efer;
7085  
7086         rdmsrl(MSR_EFER, efer); 
7087 -        if (!(efer & EFER_NX) || do_not_nx) { 
7088 +        if (!(efer & EFER_NX)) { 
7089                  __supported_pte_mask &= ~_PAGE_NX; 
7090          }       
7091  }
7092 diff -urNp linux-2.6.17.7/arch/x86_64/kernel/sys_x86_64.c linux-2.6.17.7/arch/x86_64/kernel/sys_x86_64.c
7093 --- linux-2.6.17.7/arch/x86_64/kernel/sys_x86_64.c      2006-07-24 23:36:01.000000000 -0400
7094 +++ linux-2.6.17.7/arch/x86_64/kernel/sys_x86_64.c      2006-08-01 20:29:46.000000000 -0400
7095 @@ -65,8 +65,8 @@ out:
7096         return error;
7097  }
7098  
7099 -static void find_start_end(unsigned long flags, unsigned long *begin,
7100 -                          unsigned long *end)
7101 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
7102 +                          unsigned long *begin, unsigned long *end)
7103  {
7104         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
7105                 /* This is usually used needed to map code in small
7106 @@ -79,7 +79,7 @@ static void find_start_end(unsigned long
7107                 *begin = 0x40000000; 
7108                 *end = 0x80000000;              
7109         } else {
7110 -               *begin = TASK_UNMAPPED_BASE;
7111 +               *begin = mm->mmap_base;
7112                 *end = TASK_SIZE; 
7113         }
7114  } 
7115 @@ -93,11 +93,15 @@ arch_get_unmapped_area(struct file *filp
7116         unsigned long start_addr;
7117         unsigned long begin, end;
7118         
7119 -       find_start_end(flags, &begin, &end); 
7120 +       find_start_end(mm, flags, &begin, &end); 
7121  
7122         if (len > end)
7123                 return -ENOMEM;
7124  
7125 +#ifdef CONFIG_PAX_RANDMMAP
7126 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7127 +#endif
7128 +
7129         if (addr) {
7130                 addr = PAGE_ALIGN(addr);
7131                 vma = find_vma(mm, addr);
7132 diff -urNp linux-2.6.17.7/arch/x86_64/mm/fault.c linux-2.6.17.7/arch/x86_64/mm/fault.c
7133 --- linux-2.6.17.7/arch/x86_64/mm/fault.c       2006-07-24 23:36:01.000000000 -0400
7134 +++ linux-2.6.17.7/arch/x86_64/mm/fault.c       2006-08-01 20:29:46.000000000 -0400
7135 @@ -24,6 +24,7 @@
7136  #include <linux/compiler.h>
7137  #include <linux/module.h>
7138  #include <linux/kprobes.h>
7139 +#include <linux/binfmts.h>
7140  
7141  #include <asm/system.h>
7142  #include <asm/uaccess.h>
7143 @@ -294,6 +295,33 @@ static int vmalloc_fault(unsigned long a
7144         return 0;
7145  }
7146  
7147 +#ifdef CONFIG_PAX_PAGEEXEC
7148 +void pax_report_insns(void *pc, void *sp)
7149 +{
7150 +       long i;
7151 +
7152 +       printk(KERN_ERR "PAX: bytes at PC: ");
7153 +       for (i = 0; i < 20; i++) {
7154 +               unsigned char c;
7155 +               if (get_user(c, (unsigned char __user *)pc+i))
7156 +                       printk("?? ");
7157 +               else
7158 +                       printk("%02x ", c);
7159 +       }
7160 +       printk("\n");
7161 +
7162 +       printk(KERN_ERR "PAX: bytes at SP-8: ");
7163 +       for (i = -1; i < 10; i++) {
7164 +               unsigned long c;
7165 +               if (get_user(c, (unsigned long __user *)sp+i))
7166 +                       printk("???????????????? ");
7167 +               else
7168 +                       printk("%016lx ", c);
7169 +       }
7170 +       printk("\n");
7171 +}
7172 +#endif
7173 +
7174  int page_fault_trace = 0;
7175  int exception_trace = 1;
7176  
7177 @@ -423,6 +451,8 @@ asmlinkage void __kprobes do_page_fault(
7178  good_area:
7179         info.si_code = SEGV_ACCERR;
7180         write = 0;
7181 +       if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
7182 +               goto bad_area;
7183         switch (error_code & (PF_PROT|PF_WRITE)) {
7184                 default:        /* 3: write, present */
7185                         /* fall through */
7186 @@ -489,7 +519,14 @@ bad_area_nosemaphore:
7187                                         tsk->comm, tsk->pid, address, regs->rip,
7188                                         regs->rsp, error_code);
7189                 }
7190 -       
7191 +
7192 +#ifdef CONFIG_PAX_PAGEEXEC
7193 +               if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
7194 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
7195 +                       do_exit(SIGKILL);
7196 +               }
7197 +#endif
7198 +
7199                 tsk->thread.cr2 = address;
7200                 /* Kernel addresses are always protection faults */
7201                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
7202 diff -urNp linux-2.6.17.7/arch/x86_64/mm/mmap.c linux-2.6.17.7/arch/x86_64/mm/mmap.c
7203 --- linux-2.6.17.7/arch/x86_64/mm/mmap.c        2006-07-24 23:36:01.000000000 -0400
7204 +++ linux-2.6.17.7/arch/x86_64/mm/mmap.c        2006-08-01 20:29:46.000000000 -0400
7205 @@ -24,6 +24,12 @@ void arch_pick_mmap_layout(struct mm_str
7206                 unsigned rnd = get_random_int() & 0xfffffff;
7207                 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
7208         }
7209 +
7210 +#ifdef CONFIG_PAX_RANDMMAP
7211 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
7212 +               mm->mmap_base += mm->delta_mmap;
7213 +#endif
7214 +
7215         mm->get_unmapped_area = arch_get_unmapped_area;
7216         mm->unmap_area = arch_unmap_area;
7217  }
7218 diff -urNp linux-2.6.17.7/drivers/char/agp/frontend.c linux-2.6.17.7/drivers/char/agp/frontend.c
7219 --- linux-2.6.17.7/drivers/char/agp/frontend.c  2006-07-24 23:36:01.000000000 -0400
7220 +++ linux-2.6.17.7/drivers/char/agp/frontend.c  2006-08-01 20:29:46.000000000 -0400
7221 @@ -841,7 +841,7 @@ static int agpioc_reserve_wrap(struct ag
7222         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
7223                 return -EFAULT;
7224  
7225 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
7226 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
7227                 return -EFAULT;
7228  
7229         client = agp_find_client_by_pid(reserve.pid);
7230 diff -urNp linux-2.6.17.7/drivers/char/keyboard.c linux-2.6.17.7/drivers/char/keyboard.c
7231 --- linux-2.6.17.7/drivers/char/keyboard.c      2006-07-24 23:36:01.000000000 -0400
7232 +++ linux-2.6.17.7/drivers/char/keyboard.c      2006-08-01 20:29:46.000000000 -0400
7233 @@ -618,6 +618,16 @@ static void k_spec(struct vc_data *vc, u
7234              kbd->kbdmode == VC_MEDIUMRAW) &&
7235              value != KVAL(K_SAK))
7236                 return;         /* SAK is allowed even in raw mode */
7237 +
7238 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
7239 +       {
7240 +               void *func = fn_handler[value];
7241 +               if (func == fn_show_state || func == fn_show_ptregs ||
7242 +                   func == fn_show_mem)
7243 +                       return;
7244 +       }
7245 +#endif
7246 +
7247         fn_handler[value](vc, regs);
7248  }
7249  
7250 diff -urNp linux-2.6.17.7/drivers/char/mem.c linux-2.6.17.7/drivers/char/mem.c
7251 --- linux-2.6.17.7/drivers/char/mem.c   2006-07-24 23:36:01.000000000 -0400
7252 +++ linux-2.6.17.7/drivers/char/mem.c   2006-08-01 20:29:46.000000000 -0400
7253 @@ -28,6 +28,7 @@
7254  #include <linux/backing-dev.h>
7255  #include <linux/bootmem.h>
7256  #include <linux/pipe_fs_i.h>
7257 +#include <linux/grsecurity.h>
7258  
7259  #include <asm/uaccess.h>
7260  #include <asm/io.h>
7261 @@ -36,6 +37,10 @@
7262  # include <linux/efi.h>
7263  #endif
7264  
7265 +#ifdef CONFIG_GRKERNSEC
7266 +extern struct file_operations grsec_fops;
7267 +#endif
7268 +
7269  /*
7270   * Architectures vary in how they handle caching for addresses
7271   * outside of main memory.
7272 @@ -175,6 +180,11 @@ static ssize_t write_mem(struct file * f
7273         if (!valid_phys_addr_range(p, count))
7274                 return -EFAULT;
7275  
7276 +#ifdef CONFIG_GRKERNSEC_KMEM
7277 +       gr_handle_mem_write();
7278 +       return -EPERM;
7279 +#endif
7280 +
7281         written = 0;
7282  
7283  #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
7284 @@ -251,6 +261,11 @@ static int mmap_mem(struct file * file, 
7285                                                  size,
7286                                                  vma->vm_page_prot);
7287  
7288 +#ifdef CONFIG_GRKERNSEC_KMEM
7289 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
7290 +               return -EPERM;
7291 +#endif
7292 +
7293         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
7294         if (remap_pfn_range(vma,
7295                             vma->vm_start,
7296 @@ -478,6 +493,11 @@ static ssize_t write_kmem(struct file * 
7297         ssize_t written;
7298         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
7299  
7300 +#ifdef CONFIG_GRKERNSEC_KMEM
7301 +       gr_handle_kmem_write();
7302 +       return -EPERM;
7303 +#endif
7304 +
7305         if (p < (unsigned long) high_memory) {
7306  
7307                 wrote = count;
7308 @@ -618,7 +638,23 @@ static inline size_t read_zero_pagealign
7309                         count = size;
7310  
7311                 zap_page_range(vma, addr, count, NULL);
7312 -               zeromap_page_range(vma, addr, count, PAGE_COPY);
7313 +               zeromap_page_range(vma, addr, count, vma->vm_page_prot);
7314 +
7315 +#ifdef CONFIG_PAX_SEGMEXEC
7316 +               if (vma->vm_flags & VM_MIRROR) {
7317 +                       unsigned long addr_m;
7318 +                       struct vm_area_struct * vma_m;
7319 +
7320 +                       addr_m = vma->vm_start + vma->vm_mirror;
7321 +                       vma_m = find_vma(mm, addr_m);
7322 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
7323 +                               addr_m = addr + vma->vm_mirror;
7324 +                               zap_page_range(vma_m, addr_m, count, NULL);
7325 +                       } else
7326 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
7327 +                                      addr, vma->vm_start);
7328 +               }
7329 +#endif
7330  
7331                 size -= count;
7332                 buf += count;
7333 @@ -767,6 +803,16 @@ static loff_t memory_lseek(struct file *
7334  
7335  static int open_port(struct inode * inode, struct file * filp)
7336  {
7337 +#ifdef CONFIG_GRKERNSEC_KMEM
7338 +       gr_handle_open_port();
7339 +       return -EPERM;
7340 +#endif
7341 +
7342 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
7343 +}
7344 +
7345 +static int open_mem(struct inode * inode, struct file * filp)
7346 +{
7347         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
7348  }
7349  
7350 @@ -774,7 +820,6 @@ static int open_port(struct inode * inod
7351  #define full_lseek      null_lseek
7352  #define write_zero     write_null
7353  #define read_full       read_zero
7354 -#define open_mem       open_port
7355  #define open_kmem      open_mem
7356  #define open_oldmem    open_mem
7357  
7358 @@ -897,6 +942,11 @@ static int memory_open(struct inode * in
7359                         filp->f_op = &oldmem_fops;
7360                         break;
7361  #endif
7362 +#ifdef CONFIG_GRKERNSEC
7363 +               case 13:
7364 +                       filp->f_op = &grsec_fops;
7365 +                       break;
7366 +#endif
7367                 default:
7368                         return -ENXIO;
7369         }
7370 @@ -929,6 +979,9 @@ static const struct {
7371  #ifdef CONFIG_CRASH_DUMP
7372         {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
7373  #endif
7374 +#ifdef CONFIG_GRKERNSEC
7375 +       {13,"grsec",    S_IRUSR | S_IWUGO,          &grsec_fops},
7376 +#endif
7377  };
7378  
7379  static struct class *mem_class;
7380 diff -urNp linux-2.6.17.7/drivers/char/random.c linux-2.6.17.7/drivers/char/random.c
7381 --- linux-2.6.17.7/drivers/char/random.c        2006-07-24 23:36:01.000000000 -0400
7382 +++ linux-2.6.17.7/drivers/char/random.c        2006-08-01 20:29:46.000000000 -0400
7383 @@ -249,8 +249,13 @@
7384  /*
7385   * Configuration information
7386   */
7387 +#ifdef CONFIG_GRKERNSEC_RANDNET
7388 +#define INPUT_POOL_WORDS 512
7389 +#define OUTPUT_POOL_WORDS 128
7390 +#else
7391  #define INPUT_POOL_WORDS 128
7392  #define OUTPUT_POOL_WORDS 32
7393 +#endif
7394  #define SEC_XFER_SIZE 512
7395  
7396  /*
7397 @@ -287,10 +292,17 @@ static struct poolinfo {
7398         int poolwords;
7399         int tap1, tap2, tap3, tap4, tap5;
7400  } poolinfo_table[] = {
7401 +#ifdef CONFIG_GRKERNSEC_RANDNET
7402 +       /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
7403 +       { 512,  411,    308,    208,    104,    1 },
7404 +       /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
7405 +       { 128,  103,    76,     51,     25,     1 },
7406 +#else
7407         /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
7408         { 128,  103,    76,     51,     25,     1 },
7409         /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
7410         { 32,   26,     20,     14,     7,      1 },
7411 +#endif
7412  #if 0
7413         /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
7414         { 2048, 1638,   1231,   819,    411,    1 },
7415 @@ -1658,3 +1670,25 @@ randomize_range(unsigned long start, uns
7416                 return 0;
7417         return PAGE_ALIGN(get_random_int() % range + start);
7418  }
7419 +
7420 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
7421 +unsigned long pax_get_random_long(void)
7422 +{
7423 +       static time_t   rekey_time;
7424 +       static __u32    secret[12];
7425 +       time_t          t;
7426 +
7427 +       /*
7428 +        * Pick a random secret every REKEY_INTERVAL seconds.
7429 +        */
7430 +       t = get_seconds();
7431 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
7432 +               rekey_time = t;
7433 +               get_random_bytes(secret, sizeof(secret));
7434 +       }
7435 +
7436 +       secret[1] = half_md4_transform(secret+8, secret);
7437 +       secret[0] = half_md4_transform(secret+8, secret);
7438 +       return *(unsigned long *)secret;
7439 +}
7440 +#endif
7441 diff -urNp linux-2.6.17.7/drivers/char/vt_ioctl.c linux-2.6.17.7/drivers/char/vt_ioctl.c
7442 --- linux-2.6.17.7/drivers/char/vt_ioctl.c      2006-07-24 23:36:01.000000000 -0400
7443 +++ linux-2.6.17.7/drivers/char/vt_ioctl.c      2006-08-01 20:29:46.000000000 -0400
7444 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
7445         case KDSKBENT:
7446                 if (!perm)
7447                         return -EPERM;
7448 +
7449 +#ifdef CONFIG_GRKERNSEC
7450 +               if (!capable(CAP_SYS_TTY_CONFIG))
7451 +                       return -EPERM;
7452 +#endif
7453 +
7454                 if (!i && v == K_NOSUCHMAP) {
7455                         /* disallocate map */
7456                         key_map = key_maps[s];
7457 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
7458                         goto reterr;
7459                 }
7460  
7461 +#ifdef CONFIG_GRKERNSEC
7462 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
7463 +                       ret = -EPERM;
7464 +                       goto reterr;
7465 +               }
7466 +#endif
7467 +
7468                 q = func_table[i];
7469                 first_free = funcbufptr + (funcbufsize - funcbufleft);
7470                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
7471 diff -urNp linux-2.6.17.7/drivers/ieee1394/hosts.c linux-2.6.17.7/drivers/ieee1394/hosts.c
7472 --- linux-2.6.17.7/drivers/ieee1394/hosts.c     2006-07-24 23:36:01.000000000 -0400
7473 +++ linux-2.6.17.7/drivers/ieee1394/hosts.c     2006-08-01 20:29:46.000000000 -0400
7474 @@ -75,6 +75,7 @@ static int dummy_isoctl(struct hpsb_iso 
7475  }
7476  
7477  static struct hpsb_host_driver dummy_driver = {
7478 +       .name =            "dummy",
7479         .transmit_packet = dummy_transmit_packet,
7480         .devctl =          dummy_devctl,
7481         .isoctl =          dummy_isoctl
7482 diff -urNp linux-2.6.17.7/drivers/ieee1394/ohci1394.c linux-2.6.17.7/drivers/ieee1394/ohci1394.c
7483 --- linux-2.6.17.7/drivers/ieee1394/ohci1394.c  2006-07-24 23:36:01.000000000 -0400
7484 +++ linux-2.6.17.7/drivers/ieee1394/ohci1394.c  2006-08-01 20:29:46.000000000 -0400
7485 @@ -162,9 +162,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
7486  printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
7487  
7488  /* Module Parameters */
7489 -static int phys_dma = 1;
7490 +static int phys_dma = 0;
7491  module_param(phys_dma, int, 0644);
7492 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
7493 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
7494  
7495  static void dma_trm_tasklet(unsigned long data);
7496  static void dma_trm_reset(struct dma_trm_ctx *d);
7497 diff -urNp linux-2.6.17.7/drivers/mtd/devices/doc2001.c linux-2.6.17.7/drivers/mtd/devices/doc2001.c
7498 --- linux-2.6.17.7/drivers/mtd/devices/doc2001.c        2006-07-24 23:36:01.000000000 -0400
7499 +++ linux-2.6.17.7/drivers/mtd/devices/doc2001.c        2006-08-01 20:29:46.000000000 -0400
7500 @@ -423,6 +423,8 @@ static int doc_read_ecc (struct mtd_info
7501         /* Don't allow read past end of device */
7502         if (from >= this->totlen)
7503                 return -EINVAL;
7504 +       if (!len)
7505 +               return -EINVAL;
7506  
7507         /* Don't allow a single read to cross a 512-byte block boundary */
7508         if (from + len > ((from | 0x1ff) + 1))
7509 diff -urNp linux-2.6.17.7/drivers/net/pcnet32.c linux-2.6.17.7/drivers/net/pcnet32.c
7510 --- linux-2.6.17.7/drivers/net/pcnet32.c        2006-07-24 23:36:01.000000000 -0400
7511 +++ linux-2.6.17.7/drivers/net/pcnet32.c        2006-08-01 20:29:46.000000000 -0400
7512 @@ -81,7 +81,7 @@ static int cards_found;
7513  /*
7514   * VLB I/O addresses
7515   */
7516 -static unsigned int pcnet32_portlist[] __initdata =
7517 +static unsigned int pcnet32_portlist[] __devinitdata =
7518      { 0x300, 0x320, 0x340, 0x360, 0 };
7519  
7520  static int pcnet32_debug = 0;
7521 diff -urNp linux-2.6.17.7/drivers/pci/proc.c linux-2.6.17.7/drivers/pci/proc.c
7522 --- linux-2.6.17.7/drivers/pci/proc.c   2006-07-24 23:36:01.000000000 -0400
7523 +++ linux-2.6.17.7/drivers/pci/proc.c   2006-08-01 20:29:46.000000000 -0400
7524 @@ -473,7 +473,15 @@ static int __init pci_proc_init(void)
7525  {
7526         struct proc_dir_entry *entry;
7527         struct pci_dev *dev = NULL;
7528 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7529 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7530 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
7531 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7532 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
7533 +#endif
7534 +#else
7535         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
7536 +#endif
7537         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
7538         if (entry)
7539                 entry->proc_fops = &proc_bus_pci_dev_operations;
7540 diff -urNp linux-2.6.17.7/drivers/pnp/pnpbios/bioscalls.c linux-2.6.17.7/drivers/pnp/pnpbios/bioscalls.c
7541 --- linux-2.6.17.7/drivers/pnp/pnpbios/bioscalls.c      2006-07-24 23:36:01.000000000 -0400
7542 +++ linux-2.6.17.7/drivers/pnp/pnpbios/bioscalls.c      2006-08-01 20:29:46.000000000 -0400
7543 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
7544  set_limit(gdt[(selname) >> 3], size); \
7545  } while(0)
7546  
7547 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
7548 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
7549  
7550  /*
7551   * At some point we want to use this stack frame pointer to unwind
7552 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
7553         struct desc_struct save_desc_40;
7554         int cpu;
7555  
7556 +#ifdef CONFIG_PAX_KERNEXEC
7557 +       unsigned long cr0;
7558 +#endif
7559 +
7560         /*
7561          * PnP BIOSes are generally not terribly re-entrant.
7562          * Also, don't rely on them to save everything correctly.
7563 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
7564         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
7565         spin_lock_irqsave(&pnp_bios_lock, flags);
7566  
7567 +#ifdef CONFIG_PAX_KERNEXEC
7568 +       pax_open_kernel(cr0);
7569 +#endif
7570 +
7571         /* The lock prevents us bouncing CPU here */
7572         if (ts1_size)
7573                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
7574 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
7575                   "i" (0)
7576                 : "memory"
7577         );
7578 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
7579  
7580         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
7581 +
7582 +#ifdef CONFIG_PAX_KERNEXEC
7583 +       pax_close_kernel(cr0);
7584 +#endif
7585 +
7586 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
7587         put_cpu();
7588  
7589         /* If we get here and this is set then the PnP BIOS faulted on us. */
7590 diff -urNp linux-2.6.17.7/drivers/video/i810/i810_main.c linux-2.6.17.7/drivers/video/i810/i810_main.c
7591 --- linux-2.6.17.7/drivers/video/i810/i810_main.c       2006-07-24 23:36:01.000000000 -0400
7592 +++ linux-2.6.17.7/drivers/video/i810/i810_main.c       2006-08-01 20:29:46.000000000 -0400
7593 @@ -1508,7 +1508,7 @@ static int i810fb_cursor(struct fb_info 
7594                 int size = ((cursor->image.width + 7) >> 3) *
7595                         cursor->image.height;
7596                 int i;
7597 -               u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
7598 +               u8 *data = kmalloc(64 * 8, GFP_KERNEL);
7599  
7600                 if (data == NULL)
7601                         return -ENOMEM;
7602 diff -urNp linux-2.6.17.7/drivers/video/vesafb.c linux-2.6.17.7/drivers/video/vesafb.c
7603 --- linux-2.6.17.7/drivers/video/vesafb.c       2006-07-24 23:36:01.000000000 -0400
7604 +++ linux-2.6.17.7/drivers/video/vesafb.c       2006-08-01 20:29:46.000000000 -0400
7605 @@ -259,7 +259,7 @@ static int __init vesafb_probe(struct pl
7606                 size_remap = size_total;
7607         vesafb_fix.smem_len = size_remap;
7608  
7609 -#ifndef __i386__
7610 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
7611         screen_info.vesapm_seg = 0;
7612  #endif
7613  
7614 diff -urNp linux-2.6.17.7/fs/Kconfig linux-2.6.17.7/fs/Kconfig
7615 --- linux-2.6.17.7/fs/Kconfig   2006-07-24 23:36:01.000000000 -0400
7616 +++ linux-2.6.17.7/fs/Kconfig   2006-08-01 20:29:46.000000000 -0400
7617 @@ -794,7 +794,7 @@ config PROC_FS
7618  
7619  config PROC_KCORE
7620         bool "/proc/kcore support" if !ARM
7621 -       depends on PROC_FS && MMU
7622 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
7623  
7624  config PROC_VMCORE
7625          bool "/proc/vmcore support (EXPERIMENTAL)"
7626 diff -urNp linux-2.6.17.7/fs/binfmt_aout.c linux-2.6.17.7/fs/binfmt_aout.c
7627 --- linux-2.6.17.7/fs/binfmt_aout.c     2006-07-24 23:36:01.000000000 -0400
7628 +++ linux-2.6.17.7/fs/binfmt_aout.c     2006-08-01 20:29:46.000000000 -0400
7629 @@ -24,6 +24,7 @@
7630  #include <linux/personality.h>
7631  #include <linux/init.h>
7632  #include <linux/vs_memory.h>
7633 +#include <linux/grsecurity.h>
7634  
7635  #include <asm/system.h>
7636  #include <asm/uaccess.h>
7637 @@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
7638  /* If the size of the dump file exceeds the rlimit, then see what would happen
7639     if we wrote the stack, but not the data area.  */
7640  #ifdef __sparc__
7641 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
7642         if ((dump.u_dsize+dump.u_ssize) >
7643             current->signal->rlim[RLIMIT_CORE].rlim_cur)
7644                 dump.u_dsize = 0;
7645  #else
7646 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
7647         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
7648             current->signal->rlim[RLIMIT_CORE].rlim_cur)
7649                 dump.u_dsize = 0;
7650 @@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
7651  
7652  /* Make sure we have enough room to write the stack and data areas. */
7653  #ifdef __sparc__
7654 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
7655         if ((dump.u_ssize) >
7656             current->signal->rlim[RLIMIT_CORE].rlim_cur)
7657                 dump.u_ssize = 0;
7658  #else
7659 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
7660         if ((dump.u_ssize+1) * PAGE_SIZE >
7661             current->signal->rlim[RLIMIT_CORE].rlim_cur)
7662                 dump.u_ssize = 0;
7663 @@ -287,6 +292,8 @@ static int load_aout_binary(struct linux
7664         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
7665         if (rlim >= RLIM_INFINITY)
7666                 rlim = ~0;
7667 +
7668 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
7669         if (ex.a_data + ex.a_bss > rlim)
7670                 return -ENOMEM;
7671  
7672 @@ -319,6 +326,28 @@ static int load_aout_binary(struct linux
7673         current->mm->mmap = NULL;
7674         compute_creds(bprm);
7675         current->flags &= ~PF_FORKNOEXEC;
7676 +
7677 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
7678 +       current->mm->pax_flags = 0UL;
7679 +#endif
7680 +
7681 +#ifdef CONFIG_PAX_PAGEEXEC
7682 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
7683 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
7684 +
7685 +#ifdef CONFIG_PAX_EMUTRAMP
7686 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
7687 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
7688 +#endif
7689 +
7690 +#ifdef CONFIG_PAX_MPROTECT
7691 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
7692 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
7693 +#endif
7694 +
7695 +       }
7696 +#endif
7697 +
7698  #ifdef __sparc__
7699         if (N_MAGIC(ex) == NMAGIC) {
7700                 loff_t pos = fd_offset;
7701 @@ -414,7 +443,7 @@ static int load_aout_binary(struct linux
7702  
7703                 down_write(&current->mm->mmap_sem);
7704                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
7705 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
7706 +                               PROT_READ | PROT_WRITE,
7707                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
7708                                 fd_offset + ex.a_text);
7709                 up_write(&current->mm->mmap_sem);
7710 diff -urNp linux-2.6.17.7/fs/binfmt_elf.c linux-2.6.17.7/fs/binfmt_elf.c
7711 --- linux-2.6.17.7/fs/binfmt_elf.c      2006-07-24 23:36:01.000000000 -0400
7712 +++ linux-2.6.17.7/fs/binfmt_elf.c      2006-08-01 20:29:46.000000000 -0400
7713 @@ -38,11 +38,16 @@
7714  #include <linux/random.h>
7715  #include <linux/vs_memory.h>
7716  #include <linux/vs_cvirt.h>
7717 +#include <linux/grsecurity.h>
7718  
7719  #include <asm/uaccess.h>
7720  #include <asm/param.h>
7721  #include <asm/page.h>
7722  
7723 +#ifdef CONFIG_PAX_SEGMEXEC
7724 +#include <asm/desc.h>
7725 +#endif
7726 +
7727  #include <linux/elf.h>
7728  
7729  static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
7730 @@ -90,6 +95,8 @@ static struct linux_binfmt elf_format = 
7731  
7732  static int set_brk(unsigned long start, unsigned long end)
7733  {
7734 +       unsigned long e = end;
7735 +
7736         start = ELF_PAGEALIGN(start);
7737         end = ELF_PAGEALIGN(end);
7738         if (end > start) {
7739 @@ -100,7 +107,7 @@ static int set_brk(unsigned long start, 
7740                 if (BAD_ADDR(addr))
7741                         return addr;
7742         }
7743 -       current->mm->start_brk = current->mm->brk = end;
7744 +       current->mm->start_brk = current->mm->brk = e;
7745         return 0;
7746  }
7747  
7748 @@ -316,10 +323,9 @@ static unsigned long load_elf_interp(str
7749  {
7750         struct elf_phdr *elf_phdata;
7751         struct elf_phdr *eppnt;
7752 -       unsigned long load_addr = 0;
7753 -       int load_addr_set = 0;
7754 +       unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
7755         unsigned long last_bss = 0, elf_bss = 0;
7756 -       unsigned long error = ~0UL;
7757 +       unsigned long error = -EINVAL;
7758         int retval, i, size;
7759  
7760         /* First of all, some simple consistency checks */
7761 @@ -358,59 +364,80 @@ static unsigned long load_elf_interp(str
7762                 goto out_close;
7763         }
7764  
7765 +#ifdef CONFIG_PAX_SEGMEXEC
7766 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
7767 +               task_size = SEGMEXEC_TASK_SIZE;
7768 +#endif
7769 +
7770         eppnt = elf_phdata;
7771 +       min_addr = task_size;
7772 +       max_addr = 0;
7773 +       error = -ENOMEM;
7774 +
7775         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
7776 -         if (eppnt->p_type == PT_LOAD) {
7777 -           int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
7778 -           int elf_prot = 0;
7779 -           unsigned long vaddr = 0;
7780 -           unsigned long k, map_addr;
7781 -
7782 -           if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
7783 -           if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
7784 -           if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
7785 -           vaddr = eppnt->p_vaddr;
7786 -           if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
7787 -               elf_type |= MAP_FIXED;
7788 -
7789 -           map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
7790 -           error = map_addr;
7791 -           if (BAD_ADDR(map_addr))
7792 -               goto out_close;
7793 -
7794 -           if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
7795 -               load_addr = map_addr - ELF_PAGESTART(vaddr);
7796 -               load_addr_set = 1;
7797 -           }
7798 -
7799 -           /*
7800 -            * Check to see if the section's size will overflow the
7801 -            * allowed task size. Note that p_filesz must always be
7802 -            * <= p_memsize so it is only necessary to check p_memsz.
7803 -            */
7804 -           k = load_addr + eppnt->p_vaddr;
7805 -           if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz ||
7806 -               eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
7807 -               error = -ENOMEM;
7808 +               if (eppnt->p_type != PT_LOAD)
7809 +                       continue;
7810 +
7811 +               /*
7812 +                * Check to see if the section's size will overflow the
7813 +                * allowed task size. Note that p_filesz must always be
7814 +                * <= p_memsize so it is only necessary to check p_memsz.
7815 +                */
7816 +               if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
7817 +                       goto out_close;
7818 +
7819 +               if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
7820 +                       min_addr = ELF_PAGESTART(eppnt->p_vaddr);
7821 +               if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
7822 +                       max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
7823 +       }
7824 +       if (min_addr >= max_addr)
7825                 goto out_close;
7826 -           }
7827  
7828 -           /*
7829 -            * Find the end of the file mapping for this phdr, and keep
7830 -            * track of the largest address we see for this.
7831 -            */
7832 -           k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
7833 -           if (k > elf_bss)
7834 -               elf_bss = k;
7835 -
7836 -           /*
7837 -            * Do the same thing for the memory mapping - between
7838 -            * elf_bss and last_bss is the bss section.
7839 -            */
7840 -           k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
7841 -           if (k > last_bss)
7842 -               last_bss = k;
7843 -         }
7844 +       eppnt = elf_phdata;
7845 +       for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
7846 +               int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
7847 +               int elf_prot = 0;
7848 +               unsigned long vaddr;
7849 +               unsigned long k, map_addr;
7850 +
7851 +               if (eppnt->p_type != PT_LOAD)
7852 +                       continue;
7853 +
7854 +               if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
7855 +               if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
7856 +               if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
7857 +               vaddr = eppnt->p_vaddr;
7858 +
7859 +               if (!load_addr && interp_elf_ex->e_type == ET_DYN) {
7860 +                       load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
7861 +
7862 +                       if (load_addr > task_size)
7863 +                               goto out_close;
7864 +
7865 +                       load_addr -= min_addr;
7866 +               }
7867 +
7868 +               map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
7869 +               error = map_addr;
7870 +               if (BAD_ADDR(map_addr))
7871 +                       goto out_close;
7872 +
7873 +               /*
7874 +                * Find the end of the file mapping for this phdr, and keep
7875 +                * track of the largest address we see for this.
7876 +                */
7877 +               k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
7878 +               if (k > elf_bss)
7879 +                       elf_bss = k;
7880 +
7881 +               /*
7882 +                * Do the same thing for the memory mapping - between
7883 +                * elf_bss and last_bss is the bss section.
7884 +                */
7885 +               k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
7886 +               if (k > last_bss)
7887 +                       last_bss = k;
7888         }
7889  
7890         /*
7891 @@ -447,7 +474,7 @@ out:
7892  static unsigned long load_aout_interp(struct exec * interp_ex,
7893                              struct file * interpreter)
7894  {
7895 -       unsigned long text_data, elf_entry = ~0UL;
7896 +       unsigned long text_data, elf_entry = -EINVAL;
7897         char __user * addr;
7898         loff_t offset;
7899  
7900 @@ -491,6 +518,180 @@ out:
7901         return elf_entry;
7902  }
7903  
7904 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
7905 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
7906 +{
7907 +       unsigned long pax_flags = 0UL;
7908 +
7909 +#ifdef CONFIG_PAX_PAGEEXEC
7910 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
7911 +               pax_flags |= MF_PAX_PAGEEXEC;
7912 +#endif
7913 +
7914 +#ifdef CONFIG_PAX_SEGMEXEC
7915 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
7916 +               pax_flags |= MF_PAX_SEGMEXEC;
7917 +#endif
7918 +
7919 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
7920 +       if (pax_flags & MF_PAX_PAGEEXEC)
7921 +               pax_flags &= ~MF_PAX_SEGMEXEC;
7922 +#endif
7923 +
7924 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
7925 +       if (pax_flags & MF_PAX_SEGMEXEC)
7926 +               pax_flags &= ~MF_PAX_PAGEEXEC;
7927 +#endif
7928 +
7929 +#ifdef CONFIG_PAX_EMUTRAMP
7930 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
7931 +               pax_flags |= MF_PAX_EMUTRAMP;
7932 +#endif
7933 +
7934 +#ifdef CONFIG_PAX_MPROTECT
7935 +       if (elf_phdata->p_flags & PF_MPROTECT)
7936 +               pax_flags |= MF_PAX_MPROTECT;
7937 +#endif
7938 +
7939 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
7940 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
7941 +               pax_flags |= MF_PAX_RANDMMAP;
7942 +#endif
7943 +
7944 +       return pax_flags;
7945 +}
7946 +#endif
7947 +
7948 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
7949 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
7950 +{
7951 +       unsigned long pax_flags = 0UL;
7952 +
7953 +#ifdef CONFIG_PAX_PAGEEXEC
7954 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
7955 +               pax_flags |= MF_PAX_PAGEEXEC;
7956 +#endif
7957 +
7958 +#ifdef CONFIG_PAX_SEGMEXEC
7959 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
7960 +               pax_flags |= MF_PAX_SEGMEXEC;
7961 +#endif
7962 +
7963 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
7964 +       if (pax_flags & MF_PAX_PAGEEXEC)
7965 +               pax_flags &= ~MF_PAX_SEGMEXEC;
7966 +#endif
7967 +
7968 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
7969 +       if (pax_flags & MF_PAX_SEGMEXEC)
7970 +               pax_flags &= ~MF_PAX_PAGEEXEC;
7971 +#endif
7972 +
7973 +#ifdef CONFIG_PAX_EMUTRAMP
7974 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
7975 +               pax_flags |= MF_PAX_EMUTRAMP;
7976 +#endif
7977 +
7978 +#ifdef CONFIG_PAX_MPROTECT
7979 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
7980 +               pax_flags |= MF_PAX_MPROTECT;
7981 +#endif
7982 +
7983 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
7984 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
7985 +               pax_flags |= MF_PAX_RANDMMAP;
7986 +#endif
7987 +
7988 +       return pax_flags;
7989 +}
7990 +#endif
7991 +
7992 +#ifdef CONFIG_PAX_EI_PAX
7993 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
7994 +{
7995 +       unsigned long pax_flags = 0UL;
7996 +
7997 +#ifdef CONFIG_PAX_PAGEEXEC
7998 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
7999 +               pax_flags |= MF_PAX_PAGEEXEC;
8000 +#endif
8001 +
8002 +#ifdef CONFIG_PAX_SEGMEXEC
8003 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
8004 +               pax_flags |= MF_PAX_SEGMEXEC;
8005 +#endif
8006 +
8007 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
8008 +       if (pax_flags & MF_PAX_PAGEEXEC)
8009 +               pax_flags &= ~MF_PAX_SEGMEXEC;
8010 +#endif
8011 +
8012 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
8013 +       if (pax_flags & MF_PAX_SEGMEXEC)
8014 +               pax_flags &= ~MF_PAX_PAGEEXEC;
8015 +#endif
8016 +
8017 +#ifdef CONFIG_PAX_EMUTRAMP
8018 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
8019 +               pax_flags |= MF_PAX_EMUTRAMP;
8020 +#endif
8021 +
8022 +#ifdef CONFIG_PAX_MPROTECT
8023 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
8024 +               pax_flags |= MF_PAX_MPROTECT;
8025 +#endif
8026 +
8027 +#ifdef CONFIG_PAX_ASLR
8028 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
8029 +               pax_flags |= MF_PAX_RANDMMAP;
8030 +#endif
8031 +
8032 +       return pax_flags;
8033 +}
8034 +#endif
8035 +
8036 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
8037 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
8038 +{
8039 +       unsigned long pax_flags = 0UL;
8040 +
8041 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
8042 +       unsigned long i;
8043 +#endif
8044 +
8045 +#ifdef CONFIG_PAX_EI_PAX
8046 +       pax_flags = pax_parse_ei_pax(elf_ex);
8047 +#endif
8048 +
8049 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
8050 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
8051 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
8052 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
8053 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
8054 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
8055 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
8056 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
8057 +                               return -EINVAL;
8058 +
8059 +#ifdef CONFIG_PAX_SOFTMODE
8060 +                       if (pax_softmode)
8061 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
8062 +                       else
8063 +#endif
8064 +
8065 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
8066 +                       break;
8067 +               }
8068 +#endif
8069 +
8070 +       if (0 > pax_check_flags(&pax_flags))
8071 +               return -EINVAL;
8072 +
8073 +       current->mm->pax_flags = pax_flags;
8074 +       return 0;
8075 +}
8076 +#endif
8077 +
8078  /*
8079   * These are the functions used to load ELF style executables and shared
8080   * libraries.  There is no binary dependent code anywhere else.
8081 @@ -527,7 +728,7 @@ static int load_elf_binary(struct linux_
8082         char * elf_interpreter = NULL;
8083         unsigned int interpreter_type = INTERPRETER_NONE;
8084         unsigned char ibcs2_interpreter = 0;
8085 -       unsigned long error;
8086 +       unsigned long error = 0;
8087         struct elf_phdr * elf_ppnt, *elf_phdata;
8088         unsigned long elf_bss, elf_brk;
8089         int elf_exec_fileno;
8090 @@ -545,6 +746,7 @@ static int load_elf_binary(struct linux_
8091                 struct elfhdr interp_elf_ex;
8092                 struct exec interp_ex;
8093         } *loc;
8094 +       unsigned long task_size = TASK_SIZE;
8095  
8096         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
8097         if (!loc) {
8098 @@ -770,14 +972,88 @@ static int load_elf_binary(struct linux_
8099         current->mm->end_code = 0;
8100         current->mm->mmap = NULL;
8101         current->flags &= ~PF_FORKNOEXEC;
8102 +
8103 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
8104 +       current->mm->pax_flags = 0UL;
8105 +#endif
8106 +
8107 +#ifdef CONFIG_PAX_DLRESOLVE
8108 +       current->mm->call_dl_resolve = 0UL;
8109 +#endif
8110 +
8111 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
8112 +       current->mm->call_syscall = 0UL;
8113 +#endif
8114 +
8115 +#ifdef CONFIG_PAX_ASLR
8116 +       current->mm->delta_mmap = 0UL;
8117 +       current->mm->delta_exec = 0UL;
8118 +       current->mm->delta_stack = 0UL;
8119 +#endif
8120 +
8121         current->mm->def_flags = def_flags;
8122  
8123 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
8124 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
8125 +               send_sig(SIGKILL, current, 0);
8126 +               goto out_free_dentry;
8127 +       }
8128 +#endif
8129 +
8130 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
8131 +       pax_set_initial_flags(bprm);
8132 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
8133 +       if (pax_set_initial_flags_func)
8134 +               (pax_set_initial_flags_func)(bprm);
8135 +#endif
8136 +
8137 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8138 +       if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
8139 +               current->mm->context.user_cs_limit = PAGE_SIZE;
8140 +#endif
8141 +
8142 +#ifdef CONFIG_PAX_SEGMEXEC
8143 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
8144 +               int cpu = get_cpu();
8145 +
8146 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
8147 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
8148 +               set_user_cs(current->mm, cpu);
8149 +               put_cpu();
8150 +               task_size = SEGMEXEC_TASK_SIZE;
8151 +       }
8152 +#endif
8153 +
8154 +#ifdef CONFIG_PAX_ASLR
8155 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
8156 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
8157 +
8158 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
8159 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
8160 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
8161 +       }
8162 +#endif
8163 +
8164 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8165 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8166 +               executable_stack = EXSTACK_DEFAULT;
8167 +#endif
8168 +
8169         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
8170            may depend on the personality.  */
8171         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
8172 +
8173 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8174 +       if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
8175 +#endif
8176 +
8177         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
8178                 current->personality |= READ_IMPLIES_EXEC;
8179  
8180 +#ifdef CONFIG_PAX_ASLR
8181 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
8182 +#endif
8183 +
8184         if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8185                 current->flags |= PF_RANDOMIZE;
8186         arch_pick_mmap_layout(current->mm);
8187 @@ -849,6 +1125,15 @@ static int load_elf_binary(struct linux_
8188                            base, as well as whatever program they might try to exec.  This
8189                            is because the brk will follow the loader, and is not movable.  */
8190                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
8191 +
8192 +#ifdef CONFIG_PAX_RANDMMAP
8193 +                       /* PaX: randomize base address at the default exe base if requested */
8194 +                       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
8195 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
8196 +                               elf_flags |= MAP_FIXED;
8197 +                       }
8198 +#endif
8199 +
8200                 }
8201  
8202                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
8203 @@ -876,9 +1161,9 @@ static int load_elf_binary(struct linux_
8204                  * allowed task size. Note that p_filesz must always be
8205                  * <= p_memsz so it is only necessary to check p_memsz.
8206                  */
8207 -               if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
8208 -                   elf_ppnt->p_memsz > TASK_SIZE ||
8209 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
8210 +               if (k > task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
8211 +                   elf_ppnt->p_memsz > task_size ||
8212 +                   task_size - elf_ppnt->p_memsz < k) {
8213                         /* set_brk can never work.  Avoid overflows.  */
8214                         send_sig(SIGKILL, current, 0);
8215                         goto out_free_dentry;
8216 @@ -905,6 +1190,12 @@ static int load_elf_binary(struct linux_
8217         start_data += load_bias;
8218         end_data += load_bias;
8219  
8220 +#ifdef CONFIG_PAX_RANDMMAP
8221 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP)
8222 +               elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
8223 +#undef pax_delta_mask
8224 +#endif
8225 +
8226         /* Calling set_brk effectively mmaps the pages that we need
8227          * for the bss and break sections.  We must do this before
8228          * mapping in the interpreter, to make sure it doesn't wind
8229 @@ -933,7 +1224,7 @@ static int load_elf_binary(struct linux_
8230                         printk(KERN_ERR "Unable to load interpreter %.128s\n",
8231                                 elf_interpreter);
8232                         force_sig(SIGSEGV, current);
8233 -                       retval = -ENOEXEC; /* Nobody gets to see this, but.. */
8234 +                       retval = elf_entry; /* Nobody gets to see this, but.. */
8235                         goto out_free_dentry;
8236                 }
8237                 reloc_func_desc = interp_load_addr;
8238 @@ -1157,7 +1448,7 @@ static int dump_seek(struct file *file, 
8239   *
8240   * I think we should skip something. But I am not sure how. H.J.
8241   */
8242 -static int maydump(struct vm_area_struct *vma)
8243 +static int maydump(struct vm_area_struct *vma, long signr)
8244  {
8245         /* Do not dump I/O mapped devices or special mappings */
8246         if (vma->vm_flags & (VM_IO | VM_RESERVED))
8247 @@ -1168,7 +1459,7 @@ static int maydump(struct vm_area_struct
8248                 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
8249  
8250         /* If it hasn't been written to, don't write it out */
8251 -       if (!vma->anon_vma)
8252 +       if (signr != SIGKILL && !vma->anon_vma)
8253                 return 0;
8254  
8255         return 1;
8256 @@ -1222,8 +1513,11 @@ static int writenote(struct memelfnote *
8257  #undef DUMP_SEEK
8258  
8259  #define DUMP_WRITE(addr, nr)   \
8260 +       do { \
8261 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
8262         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
8263 -               goto end_coredump;
8264 +               goto end_coredump; \
8265 +       } while (0);
8266  #define DUMP_SEEK(off) \
8267         if (!dump_seek(file, (off))) \
8268                 goto end_coredump;
8269 @@ -1573,7 +1867,7 @@ static int elf_core_dump(long signr, str
8270                 phdr.p_offset = offset;
8271                 phdr.p_vaddr = vma->vm_start;
8272                 phdr.p_paddr = 0;
8273 -               phdr.p_filesz = maydump(vma) ? sz : 0;
8274 +               phdr.p_filesz = maydump(vma, signr) ? sz : 0;
8275                 phdr.p_memsz = sz;
8276                 offset += phdr.p_filesz;
8277                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
8278 @@ -1606,7 +1900,7 @@ static int elf_core_dump(long signr, str
8279         for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
8280                 unsigned long addr;
8281  
8282 -               if (!maydump(vma))
8283 +               if (!maydump(vma, signr))
8284                         continue;
8285  
8286                 for (addr = vma->vm_start;
8287 @@ -1625,6 +1919,7 @@ static int elf_core_dump(long signr, str
8288                                         void *kaddr;
8289                                         flush_cache_page(vma, addr, page_to_pfn(page));
8290                                         kaddr = kmap(page);
8291 +                                       gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
8292                                         if ((size += PAGE_SIZE) > limit ||
8293                                             !dump_write(file, kaddr,
8294                                             PAGE_SIZE)) {
8295 diff -urNp linux-2.6.17.7/fs/binfmt_flat.c linux-2.6.17.7/fs/binfmt_flat.c
8296 --- linux-2.6.17.7/fs/binfmt_flat.c     2006-07-24 23:36:01.000000000 -0400
8297 +++ linux-2.6.17.7/fs/binfmt_flat.c     2006-08-01 20:29:46.000000000 -0400
8298 @@ -552,7 +552,9 @@ static int load_flat_file(struct linux_b
8299                                 realdatastart = (unsigned long) -ENOMEM;
8300                         printk("Unable to allocate RAM for process data, errno %d\n",
8301                                         (int)-datapos);
8302 +                       down_write(&current->mm->mmap_sem);
8303                         do_munmap(current->mm, textpos, text_len);
8304 +                       up_write(&current->mm->mmap_sem);
8305                         ret = realdatastart;
8306                         goto err;
8307                 }
8308 @@ -574,8 +576,10 @@ static int load_flat_file(struct linux_b
8309                 }
8310                 if (result >= (unsigned long)-4096) {
8311                         printk("Unable to read data+bss, errno %d\n", (int)-result);
8312 +                       down_write(&current->mm->mmap_sem);
8313                         do_munmap(current->mm, textpos, text_len);
8314                         do_munmap(current->mm, realdatastart, data_len + extra);
8315 +                       up_write(&current->mm->mmap_sem);
8316                         ret = result;
8317                         goto err;
8318                 }
8319 @@ -639,8 +643,10 @@ static int load_flat_file(struct linux_b
8320                 }
8321                 if (result >= (unsigned long)-4096) {
8322                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
8323 +                       down_write(&current->mm->mmap_sem);
8324                         do_munmap(current->mm, textpos, text_len + data_len + extra +
8325                                 MAX_SHARED_LIBS * sizeof(unsigned long));
8326 +                       up_write(&current->mm->mmap_sem);
8327                         ret = result;
8328                         goto err;
8329                 }
8330 diff -urNp linux-2.6.17.7/fs/binfmt_misc.c linux-2.6.17.7/fs/binfmt_misc.c
8331 --- linux-2.6.17.7/fs/binfmt_misc.c     2006-07-24 23:36:01.000000000 -0400
8332 +++ linux-2.6.17.7/fs/binfmt_misc.c     2006-08-01 20:29:46.000000000 -0400
8333 @@ -112,9 +112,11 @@ static int load_misc_binary(struct linux
8334         struct files_struct *files = NULL;
8335  
8336         retval = -ENOEXEC;
8337 -       if (!enabled)
8338 +       if (!enabled || bprm->misc)
8339                 goto _ret;
8340  
8341 +       bprm->misc++;
8342 +
8343         /* to keep locking time low, we copy the interpreter string */
8344         read_lock(&entries_lock);
8345         fmt = check_file(bprm);
8346 diff -urNp linux-2.6.17.7/fs/buffer.c linux-2.6.17.7/fs/buffer.c
8347 --- linux-2.6.17.7/fs/buffer.c  2006-07-24 23:36:01.000000000 -0400
8348 +++ linux-2.6.17.7/fs/buffer.c  2006-08-01 20:29:46.000000000 -0400
8349 @@ -42,6 +42,7 @@
8350  #include <linux/bitops.h>
8351  #include <linux/mpage.h>
8352  #include <linux/bit_spinlock.h>
8353 +#include <linux/grsecurity.h>
8354  
8355  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
8356  static void invalidate_bh_lrus(void);
8357 @@ -2162,6 +2163,7 @@ static int __generic_cont_expand(struct 
8358  
8359         err = -EFBIG;
8360          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
8361 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
8362         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
8363                 send_sig(SIGXFSZ, current, 0);
8364                 goto out;
8365 diff -urNp linux-2.6.17.7/fs/compat.c linux-2.6.17.7/fs/compat.c
8366 --- linux-2.6.17.7/fs/compat.c  2006-07-24 23:36:01.000000000 -0400
8367 +++ linux-2.6.17.7/fs/compat.c  2006-08-01 20:29:46.000000000 -0400
8368 @@ -46,6 +46,7 @@
8369  #include <linux/rwsem.h>
8370  #include <linux/acct.h>
8371  #include <linux/mm.h>
8372 +#include <linux/grsecurity.h>
8373  
8374  #include <net/sock.h>          /* siocdevprivate_ioctl */
8375  
8376 @@ -1498,6 +1499,11 @@ int compat_do_execve(char * filename,
8377         struct file *file;
8378         int retval;
8379         int i;
8380 +#ifdef CONFIG_GRKERNSEC
8381 +       struct file *old_exec_file;
8382 +       struct acl_subject_label *old_acl;
8383 +       struct rlimit old_rlim[RLIM_NLIMITS];
8384 +#endif
8385  
8386         retval = -ENOMEM;
8387         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
8388 @@ -1515,6 +1521,15 @@ int compat_do_execve(char * filename,
8389         bprm->file = file;
8390         bprm->filename = filename;
8391         bprm->interp = filename;
8392 +
8393 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
8394 +       retval = -EAGAIN;
8395 +       if (gr_handle_nproc())
8396 +               goto out_file;
8397 +       retval = -EACCES;
8398 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
8399 +               goto out_file;
8400 +
8401         bprm->mm = mm_alloc();
8402         retval = -ENOMEM;
8403         if (!bprm->mm)
8404 @@ -1553,10 +1568,39 @@ int compat_do_execve(char * filename,
8405         if (retval < 0)
8406                 goto out;
8407  
8408 +       if (!gr_tpe_allow(file)) {
8409 +               retval = -EACCES;
8410 +               goto out;
8411 +       }
8412 +
8413 +       if (gr_check_crash_exec(file)) {
8414 +               retval = -EACCES;
8415 +               goto out;
8416 +       }
8417 +
8418 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
8419 +
8420 +       gr_handle_exec_args(bprm, (char __user * __user *)argv);
8421 +
8422 +#ifdef CONFIG_GRKERNSEC
8423 +       old_acl = current->acl;
8424 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
8425 +       old_exec_file = current->exec_file;
8426 +       get_file(file);
8427 +       current->exec_file = file;
8428 +#endif
8429 +
8430 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
8431 +
8432         retval = search_binary_handler(bprm, regs);
8433         if (retval >= 0) {
8434                 free_arg_pages(bprm);
8435  
8436 +#ifdef CONFIG_GRKERNSEC
8437 +               if (old_exec_file)
8438 +                       fput(old_exec_file);
8439 +#endif
8440 +
8441                 /* execve success */
8442                 security_bprm_free(bprm);
8443                 acct_update_integrals(current);
8444 @@ -1564,6 +1608,13 @@ int compat_do_execve(char * filename,
8445                 return retval;
8446         }
8447  
8448 +#ifdef CONFIG_GRKERNSEC
8449 +       current->acl = old_acl;
8450 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
8451 +       fput(current->exec_file);
8452 +       current->exec_file = old_exec_file;
8453 +#endif
8454 +
8455  out:
8456         /* Something went wrong, return the inode and free the argument pages*/
8457         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8458 diff -urNp linux-2.6.17.7/fs/dcache.c linux-2.6.17.7/fs/dcache.c
8459 --- linux-2.6.17.7/fs/dcache.c  2006-07-24 23:36:01.000000000 -0400
8460 +++ linux-2.6.17.7/fs/dcache.c  2006-08-01 20:29:46.000000000 -0400
8461 @@ -1389,7 +1389,7 @@ already_unhashed:
8462   *
8463   * "buflen" should be positive. Caller holds the dcache_lock.
8464   */
8465 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
8466 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
8467                         struct dentry *root, struct vfsmount *rootmnt,
8468                         char *buffer, int buflen)
8469  {
8470 diff -urNp linux-2.6.17.7/fs/exec.c linux-2.6.17.7/fs/exec.c
8471 --- linux-2.6.17.7/fs/exec.c    2006-07-24 23:36:01.000000000 -0400
8472 +++ linux-2.6.17.7/fs/exec.c    2006-08-01 20:29:46.000000000 -0400
8473 @@ -49,6 +49,8 @@
8474  #include <linux/cn_proc.h>
8475  #include <linux/vs_cvirt.h>
8476  #include <linux/vs_memory.h>
8477 +#include <linux/random.h>
8478 +#include <linux/grsecurity.h>
8479  
8480  #include <asm/uaccess.h>
8481  #include <asm/mmu_context.h>
8482 @@ -67,6 +69,15 @@ EXPORT_SYMBOL(suid_dumpable);
8483  static struct linux_binfmt *formats;
8484  static DEFINE_RWLOCK(binfmt_lock);
8485  
8486 +#ifdef CONFIG_PAX_SOFTMODE
8487 +unsigned int pax_softmode;
8488 +#endif
8489 +
8490 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
8491 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
8492 +EXPORT_SYMBOL(pax_set_initial_flags_func);
8493 +#endif
8494 +
8495  int register_binfmt(struct linux_binfmt * fmt)
8496  {
8497         struct linux_binfmt ** tmp = &formats;
8498 @@ -312,6 +323,10 @@ void install_arg_page(struct vm_area_str
8499         if (unlikely(anon_vma_prepare(vma)))
8500                 goto out;
8501  
8502 +#ifdef CONFIG_PAX_SEGMEXEC
8503 +       if (page_count(page) == 1)
8504 +#endif
8505 +
8506         flush_dcache_page(page);
8507         pte = get_locked_pte(mm, address, &ptl);
8508         if (!pte)
8509 @@ -321,9 +336,21 @@ void install_arg_page(struct vm_area_str
8510                 goto out;
8511         }
8512         inc_mm_counter(mm, anon_rss);
8513 +
8514 +#ifdef CONFIG_PAX_SEGMEXEC
8515 +       if (page_count(page) == 1)
8516 +#endif
8517 +
8518         lru_cache_add_active(page);
8519         set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
8520                                         page, vma->vm_page_prot))));
8521 +
8522 +#ifdef CONFIG_PAX_SEGMEXEC
8523 +       if (page_count(page) != 1)
8524 +               page_add_anon_rmap(page, vma, address);
8525 +       else
8526 +#endif
8527 +
8528         page_add_new_anon_rmap(page, vma, address);
8529         pte_unmap_unlock(pte, ptl);
8530  
8531 @@ -346,6 +373,10 @@ int setup_arg_pages(struct linux_binprm 
8532         int i, ret;
8533         long arg_size;
8534  
8535 +#ifdef CONFIG_PAX_SEGMEXEC
8536 +       struct vm_area_struct *mpnt_m = NULL;
8537 +#endif
8538 +
8539  #ifdef CONFIG_STACK_GROWSUP
8540         /* Move the argument and environment strings to the bottom of the
8541          * stack space.
8542 @@ -410,6 +441,18 @@ int setup_arg_pages(struct linux_binprm 
8543  
8544         memset(mpnt, 0, sizeof(*mpnt));
8545  
8546 +#ifdef CONFIG_PAX_SEGMEXEC
8547 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
8548 +               mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8549 +               if (!mpnt_m) {
8550 +                       kmem_cache_free(vm_area_cachep, mpnt);
8551 +                       return -ENOMEM;
8552 +               }
8553 +
8554 +               memset(mpnt_m, 0, sizeof(*mpnt_m));
8555 +       }
8556 +#endif
8557 +
8558         down_write(&mm->mmap_sem);
8559         {
8560                 mpnt->vm_mm = mm;
8561 @@ -430,14 +473,51 @@ int setup_arg_pages(struct linux_binprm 
8562                 else
8563                         mpnt->vm_flags = VM_STACK_FLAGS;
8564                 mpnt->vm_flags |= mm->def_flags;
8565 +
8566 +#ifdef CONFIG_PAX_PAGEEXEC
8567 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
8568 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & 0x7];
8569 +               else
8570 +#endif
8571 +
8572                 mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
8573                 if ((ret = insert_vm_struct(mm, mpnt))) {
8574                         up_write(&mm->mmap_sem);
8575                         kmem_cache_free(vm_area_cachep, mpnt);
8576 +
8577 +#ifdef CONFIG_PAX_SEGMEXEC
8578 +                       if (mpnt_m)
8579 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
8580 +#endif
8581 +
8582                         return ret;
8583                 }
8584                 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
8585                 mm->stack_vm = mm->total_vm;
8586 +
8587 +#ifdef CONFIG_PAX_SEGMEXEC
8588 +               if (mpnt_m) {
8589 +                       *mpnt_m = *mpnt;
8590 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
8591 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
8592 +                               mpnt_m->vm_page_prot = PAGE_NONE;
8593 +                       }
8594 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
8595 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
8596 +                       if ((ret = insert_vm_struct(mm, mpnt_m))) {
8597 +                               up_write(&mm->mmap_sem);
8598 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
8599 +                               return ret;
8600 +                       }
8601 +                       mpnt_m->vm_flags |= VM_MIRROR;
8602 +                       mpnt->vm_flags |= VM_MIRROR;
8603 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
8604 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
8605 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
8606 +                       mm->total_vm += vma_pages(mpnt_m);
8607 +               }
8608 +#endif
8609 +
8610         }
8611  
8612         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8613 @@ -444,6 +524,14 @@ int setup_arg_pages(struct linux_binprm 
8614                 if (page) {
8615                         bprm->page[i] = NULL;
8616                         install_arg_page(mpnt, page, stack_base);
8617 +
8618 +#ifdef CONFIG_PAX_SEGMEXEC
8619 +                       if (mpnt_m) {
8620 +                               page_cache_get(page);
8621 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
8622 +                       }
8623 +#endif
8624 +
8625                 }
8626                 stack_base += PAGE_SIZE;
8627         }
8628 @@ -1147,6 +1235,11 @@ int do_execve(char * filename,
8629         struct file *file;
8630         int retval;
8631         int i;
8632 +#ifdef CONFIG_GRKERNSEC
8633 +       struct file *old_exec_file;
8634 +       struct acl_subject_label *old_acl;
8635 +       struct rlimit old_rlim[RLIM_NLIMITS];
8636 +#endif
8637  
8638         retval = -ENOMEM;
8639         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
8640 @@ -1158,10 +1251,29 @@ int do_execve(char * filename,
8641         if (IS_ERR(file))
8642                 goto out_kfree;
8643  
8644 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
8645 +
8646 +       if (gr_handle_nproc()) {
8647 +               allow_write_access(file);
8648 +               fput(file);
8649 +               return -EAGAIN;
8650 +       }
8651 +
8652 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
8653 +               allow_write_access(file);
8654 +               fput(file);
8655 +               return -EACCES;
8656 +       }
8657 +
8658         sched_exec();
8659  
8660         bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
8661  
8662 +#ifdef CONFIG_PAX_RANDUSTACK
8663 +       if (randomize_va_space)
8664 +               bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
8665 +#endif
8666 +
8667         bprm->file = file;
8668         bprm->filename = filename;
8669         bprm->interp = filename;
8670 @@ -1203,8 +1315,38 @@ int do_execve(char * filename,
8671         if (retval < 0)
8672                 goto out;
8673  
8674 +       if (!gr_tpe_allow(file)) {
8675 +               retval = -EACCES;
8676 +               goto out;
8677 +       }
8678 +
8679 +       if (gr_check_crash_exec(file)) {
8680 +               retval = -EACCES;
8681 +               goto out;
8682 +       }
8683 +
8684 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
8685 +
8686 +       gr_handle_exec_args(bprm, argv);
8687 +
8688 +#ifdef CONFIG_GRKERNSEC
8689 +       old_acl = current->acl;
8690 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
8691 +       old_exec_file = current->exec_file;
8692 +       get_file(file);
8693 +       current->exec_file = file;
8694 +#endif
8695 +
8696 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
8697 +       if (retval < 0)
8698 +               goto out_fail;
8699 +
8700         retval = search_binary_handler(bprm,regs);
8701         if (retval >= 0) {
8702 +#ifdef CONFIG_GRKERNSEC
8703 +               if (old_exec_file)
8704 +                       fput(old_exec_file);
8705 +#endif
8706                 free_arg_pages(bprm);
8707  
8708                 /* execve success */
8709 @@ -1214,6 +1356,14 @@ int do_execve(char * filename,
8710                 return retval;
8711         }
8712  
8713 +out_fail:
8714 +#ifdef CONFIG_GRKERNSEC
8715 +       current->acl = old_acl;
8716 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
8717 +       fput(current->exec_file);
8718 +       current->exec_file = old_exec_file;
8719 +#endif
8720 +
8721  out:
8722         /* Something went wrong, return the inode and free the argument pages*/
8723         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8724 @@ -1374,6 +1524,114 @@ static void format_corename(char *corena
8725         *out_ptr = 0;
8726  }
8727  
8728 +int pax_check_flags(unsigned long * flags)
8729 +{
8730 +       int retval = 0;
8731 +
8732 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
8733 +       if (*flags & MF_PAX_SEGMEXEC)
8734 +       {
8735 +               *flags &= ~MF_PAX_SEGMEXEC;
8736 +               retval = -EINVAL;
8737 +       }
8738 +#endif
8739 +
8740 +       if ((*flags & MF_PAX_PAGEEXEC)
8741 +
8742 +#ifdef CONFIG_PAX_PAGEEXEC
8743 +           &&  (*flags & MF_PAX_SEGMEXEC)
8744 +#endif
8745 +
8746 +          )
8747 +       {
8748 +               *flags &= ~MF_PAX_PAGEEXEC;
8749 +               retval = -EINVAL;
8750 +       }
8751 +
8752 +       if ((*flags & MF_PAX_MPROTECT)
8753 +
8754 +#ifdef CONFIG_PAX_MPROTECT
8755 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8756 +#endif
8757 +
8758 +          )
8759 +       {
8760 +               *flags &= ~MF_PAX_MPROTECT;
8761 +               retval = -EINVAL;
8762 +       }
8763 +
8764 +       if ((*flags & MF_PAX_EMUTRAMP)
8765 +
8766 +#ifdef CONFIG_PAX_EMUTRAMP
8767 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
8768 +#endif
8769 +
8770 +          )
8771 +       {
8772 +               *flags &= ~MF_PAX_EMUTRAMP;
8773 +               retval = -EINVAL;
8774 +       }
8775 +
8776 +       return retval;
8777 +}
8778 +
8779 +EXPORT_SYMBOL(pax_check_flags);
8780 +
8781 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8782 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
8783 +{
8784 +       struct task_struct *tsk = current;
8785 +       struct mm_struct *mm = current->mm;
8786 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
8787 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
8788 +       char* path_exec=NULL;
8789 +       char* path_fault=NULL;
8790 +       unsigned long start=0UL, end=0UL, offset=0UL;
8791 +
8792 +       if (buffer_exec && buffer_fault) {
8793 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
8794 +
8795 +               down_read(&mm->mmap_sem);
8796 +               vma = mm->mmap;
8797 +               while (vma && (!vma_exec || !vma_fault)) {
8798 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
8799 +                               vma_exec = vma;
8800 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
8801 +                               vma_fault = vma;
8802 +                       vma = vma->vm_next;
8803 +               }
8804 +               if (vma_exec) {
8805 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
8806 +                       if (IS_ERR(path_exec))
8807 +                               path_exec = "<path too long>";
8808 +               }
8809 +               if (vma_fault) {
8810 +                       start = vma_fault->vm_start;
8811 +                       end = vma_fault->vm_end;
8812 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
8813 +                       if (vma_fault->vm_file) {
8814 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
8815 +                               if (IS_ERR(path_fault))
8816 +                                       path_fault = "<path too long>";
8817 +                       } else
8818 +                               path_fault = "<anonymous mapping>";
8819 +               }
8820 +               up_read(&mm->mmap_sem);
8821 +       }
8822 +       if (tsk->signal->curr_ip)
8823 +               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);
8824 +       else
8825 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
8826 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
8827 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
8828 +                       tsk->uid, tsk->euid, pc, sp);
8829 +       free_page((unsigned long)buffer_exec);
8830 +       free_page((unsigned long)buffer_fault);
8831 +       pax_report_insns(pc, sp);
8832 +       do_coredump(SIGKILL, SIGKILL, regs);
8833 +}
8834 +#endif
8835 +
8836  static void zap_threads (struct mm_struct *mm)
8837  {
8838         struct task_struct *g, *p;
8839 @@ -1491,6 +1749,10 @@ int do_coredump(long signr, int exit_cod
8840          */
8841         clear_thread_flag(TIF_SIGPENDING);
8842  
8843 +       if (signr == SIGKILL || signr == SIGILL)
8844 +               gr_handle_brute_attach(current);
8845 +
8846 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
8847         if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
8848                 goto fail_unlock;
8849  
8850 diff -urNp linux-2.6.17.7/fs/fcntl.c linux-2.6.17.7/fs/fcntl.c
8851 --- linux-2.6.17.7/fs/fcntl.c   2006-07-24 23:36:01.000000000 -0400
8852 +++ linux-2.6.17.7/fs/fcntl.c   2006-08-01 20:29:46.000000000 -0400
8853 @@ -18,6 +18,7 @@
8854  #include <linux/signal.h>
8855  #include <linux/rcupdate.h>
8856  #include <linux/vs_limit.h>
8857 +#include <linux/grsecurity.h>
8858  
8859  #include <asm/poll.h>
8860  #include <asm/siginfo.h>
8861 @@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
8862         struct fdtable *fdt;
8863  
8864         error = -EINVAL;
8865 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
8866         if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
8867                 goto out;
8868  
8869 @@ -83,6 +85,7 @@ repeat:
8870         }
8871         
8872         error = -EMFILE;
8873 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
8874         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
8875                 goto out;
8876  
8877 @@ -141,6 +144,8 @@ asmlinkage long sys_dup2(unsigned int ol
8878         struct files_struct * files = current->files;
8879         struct fdtable *fdt;
8880  
8881 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
8882 +
8883         spin_lock(&files->file_lock);
8884         if (!(file = fcheck(oldfd)))
8885                 goto out_unlock;
8886 @@ -427,7 +432,8 @@ static inline int sigio_perm(struct task
8887         return (((fown->euid == 0) ||
8888                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
8889                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
8890 -               !security_file_send_sigiotask(p, fown, sig));
8891 +               !security_file_send_sigiotask(p, fown, sig) &&
8892 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
8893  }
8894  
8895  static void send_sigio_to_task(struct task_struct *p,
8896 diff -urNp linux-2.6.17.7/fs/namei.c linux-2.6.17.7/fs/namei.c
8897 --- linux-2.6.17.7/fs/namei.c   2006-07-24 23:36:01.000000000 -0400
8898 +++ linux-2.6.17.7/fs/namei.c   2006-08-01 20:29:46.000000000 -0400
8899 @@ -32,6 +32,7 @@
8900  #include <linux/vserver/inode.h>
8901  #include <linux/vs_tag.h>
8902  #include <linux/vserver/debug.h>
8903 +#include <linux/grsecurity.h>
8904  #include <asm/namei.h>
8905  #include <asm/uaccess.h>
8906  
8907 @@ -611,6 +612,13 @@ static inline int do_follow_link(struct 
8908         err = security_inode_follow_link(path->dentry, nd);
8909         if (err)
8910                 goto loop;
8911 +
8912 +       if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
8913 +                                 path->dentry->d_inode, path->dentry, nd->mnt)) {
8914 +               err = -EACCES;
8915 +               goto loop;
8916 +       }
8917 +
8918         current->link_count++;
8919         current->total_link_count++;
8920         nd->depth++;
8921 @@ -954,11 +962,18 @@ return_reval:
8922                                 break;
8923                 }
8924  return_base:
8925 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
8926 +                       path_release(nd);
8927 +                       return -ENOENT;
8928 +               }
8929                 return 0;
8930  out_dput:
8931                 dput_path(&next, nd);
8932                 break;
8933         }
8934 +       if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
8935 +               err = -ENOENT;
8936 +
8937         path_release(nd);
8938  return_err:
8939         return err;
8940 @@ -1601,6 +1616,17 @@ int open_namei(int dfd, const char *path
8941                                          nd, flag);
8942                 if (error)
8943                         return error;
8944 +
8945 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
8946 +                       error = -EPERM;
8947 +                       goto exit;
8948 +               }
8949 +
8950 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
8951 +                       error = -EACCES;
8952 +                       goto exit;
8953 +               }
8954 +
8955                 goto ok;
8956         }
8957  
8958 @@ -1641,9 +1667,16 @@ do_last:
8959  
8960         /* Negative dentry, just create the file */
8961         if (!path.dentry->d_inode) {
8962 +               if (!gr_acl_handle_creat(path.dentry, nd->dentry, nd->mnt, flag, mode)) {
8963 +                       error = -EACCES;
8964 +                       mutex_unlock(&dir->d_inode->i_mutex);
8965 +                       goto exit_dput;
8966 +               }
8967                 if (!IS_POSIXACL(dir->d_inode))
8968                         mode &= ~current->fs->umask;
8969                 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
8970 +               if (!error)
8971 +                       gr_handle_create(path.dentry, nd->mnt);
8972                 mutex_unlock(&dir->d_inode->i_mutex);
8973                 dput(nd->dentry);
8974                 nd->dentry = path.dentry;
8975 @@ -1658,6 +1691,23 @@ do_last:
8976         /*
8977          * It already exists.
8978          */
8979 +
8980 +       if (gr_handle_rawio(path.dentry->d_inode)) {
8981 +               mutex_unlock(&dir->d_inode->i_mutex);
8982 +               error = -EPERM;
8983 +               goto exit_dput;
8984 +       }
8985 +       if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
8986 +               mutex_unlock(&dir->d_inode->i_mutex);
8987 +               error = -EACCES;
8988 +               goto exit_dput;
8989 +       }
8990 +       if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
8991 +               mutex_unlock(&dir->d_inode->i_mutex);
8992 +               error = -EACCES;
8993 +               goto exit_dput;
8994 +       }
8995 +
8996         mutex_unlock(&dir->d_inode->i_mutex);
8997  
8998         error = -EEXIST;
8999 @@ -1711,6 +1761,13 @@ do_link:
9000         error = security_inode_follow_link(path.dentry, nd);
9001         if (error)
9002                 goto exit_dput;
9003 +
9004 +       if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
9005 +                                 path.dentry, nd->mnt)) {
9006 +               error = -EACCES;
9007 +               goto exit_dput;
9008 +       }
9009 +
9010         error = __do_follow_link(&path, nd);
9011         if (error) {
9012                 /* Does someone understand code flow here? Or it is only
9013 @@ -1837,6 +1894,22 @@ asmlinkage long sys_mknodat(int dfd, con
9014         if (!IS_POSIXACL(nd.dentry->d_inode))
9015                 mode &= ~current->fs->umask;
9016         if (!IS_ERR(dentry)) {
9017 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
9018 +                       error = -EPERM;
9019 +                       dput(dentry);
9020 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
9021 +                       path_release(&nd);
9022 +                       goto out;
9023 +               }
9024 +
9025 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
9026 +                       error = -EACCES;
9027 +                       dput(dentry);
9028 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
9029 +                       path_release(&nd);
9030 +                       goto out;
9031 +               }
9032 +
9033                 switch (mode & S_IFMT) {
9034                 case 0: case S_IFREG:
9035                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
9036 @@ -1854,6 +1927,10 @@ asmlinkage long sys_mknodat(int dfd, con
9037                 default:
9038                         error = -EINVAL;
9039                 }
9040 +
9041 +               if (!error)
9042 +                       gr_handle_create(dentry, nd.mnt);
9043 +
9044                 dput(dentry);
9045         }
9046         mutex_unlock(&nd.dentry->d_inode->i_mutex);
9047 @@ -1908,10 +1985,19 @@ asmlinkage long sys_mkdirat(int dfd, con
9048                 dentry = lookup_create(&nd, 1);
9049                 error = PTR_ERR(dentry);
9050                 if (!IS_ERR(dentry)) {
9051 +                       error = 0;
9052                         if (!IS_POSIXACL(nd.dentry->d_inode))
9053                                 mode &= ~current->fs->umask;
9054 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
9055 -                               mode, &nd);
9056 +
9057 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
9058 +                               error = -EACCES;
9059 +
9060 +                       if (!error)
9061 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry,
9062 +                                       mode, &nd);
9063 +                       if (!error)
9064 +                               gr_handle_create(dentry, nd.mnt);
9065 +
9066                         dput(dentry);
9067                 }
9068                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9069 @@ -1994,6 +2081,8 @@ static long do_rmdir(int dfd, const char
9070         char * name;
9071         struct dentry *dentry;
9072         struct nameidata nd;
9073 +       ino_t saved_ino = 0;
9074 +       dev_t saved_dev = 0;
9075  
9076         name = getname(pathname);
9077         if(IS_ERR(name))
9078 @@ -2018,7 +2107,21 @@ static long do_rmdir(int dfd, const char
9079         dentry = lookup_hash(&nd);
9080         error = PTR_ERR(dentry);
9081         if (!IS_ERR(dentry)) {
9082 -               error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
9083 +               error = 0;
9084 +               if (dentry->d_inode) {
9085 +                       if (dentry->d_inode->i_nlink <= 1) {
9086 +                               saved_ino = dentry->d_inode->i_ino;
9087 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
9088 +                       }
9089 +
9090 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
9091 +                               error = -EACCES;
9092 +               }
9093 +
9094 +               if (!error)
9095 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
9096 +               if (!error && (saved_dev || saved_ino))
9097 +                       gr_handle_delete(saved_ino, saved_dev);
9098                 dput(dentry);
9099         }
9100         mutex_unlock(&nd.dentry->d_inode->i_mutex);
9101 @@ -2077,6 +2180,8 @@ static long do_unlinkat(int dfd, const c
9102         struct dentry *dentry;
9103         struct nameidata nd;
9104         struct inode *inode = NULL;
9105 +       ino_t saved_ino = 0;
9106 +       dev_t saved_dev = 0;
9107  
9108         name = getname(pathname);
9109         if(IS_ERR(name))
9110 @@ -2092,13 +2197,26 @@ static long do_unlinkat(int dfd, const c
9111         dentry = lookup_hash(&nd);
9112         error = PTR_ERR(dentry);
9113         if (!IS_ERR(dentry)) {
9114 +               error = 0;
9115                 /* Why not before? Because we want correct error value */
9116                 if (nd.last.name[nd.last.len])
9117                         goto slashes;
9118                 inode = dentry->d_inode;
9119 -               if (inode)
9120 +               if (inode) {
9121 +                       if (inode->i_nlink <= 1) {
9122 +                               saved_ino = inode->i_ino;
9123 +                               saved_dev = inode->i_sb->s_dev;
9124 +                       }
9125 +
9126 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
9127 +                               error = -EACCES;
9128 +
9129                         atomic_inc(&inode->i_count);
9130 -               error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
9131 +               }
9132 +               if (!error)
9133 +                       error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
9134 +               if (!error && (saved_ino || saved_dev))
9135 +                       gr_handle_delete(saved_ino, saved_dev);
9136         exit2:
9137                 dput(dentry);
9138         }
9139 @@ -2176,8 +2294,15 @@ asmlinkage long sys_symlinkat(const char
9140                 dentry = lookup_create(&nd, 0);
9141                 error = PTR_ERR(dentry);
9142                 if (!IS_ERR(dentry)) {
9143 -                       error = vfs_symlink(nd.dentry->d_inode, dentry,
9144 -                               from, S_IALLUGO, &nd);
9145 +                       error = 0;
9146 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
9147 +                               error = -EACCES;
9148 +
9149 +                       if (!error)
9150 +                               error = vfs_symlink(nd.dentry->d_inode, dentry,
9151 +                                       from, S_IALLUGO, &nd);
9152 +                       if (!error)
9153 +                               gr_handle_create(dentry, nd.mnt);
9154                         dput(dentry);
9155                 }
9156                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
9157 @@ -2268,8 +2394,20 @@ asmlinkage long sys_linkat(int olddfd, c
9158         new_dentry = lookup_create(&nd, 0);
9159         error = PTR_ERR(new_dentry);
9160         if (!IS_ERR(new_dentry)) {
9161 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode,
9162 -                       new_dentry, &nd);
9163 +               error = 0;
9164 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
9165 +                                      old_nd.dentry->d_inode,
9166 +                                      old_nd.dentry->d_inode->i_mode, to))
9167 +                       error = -EPERM;
9168 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
9169 +                                       old_nd.dentry, old_nd.mnt, to))
9170 +                       error = -EACCES;
9171 +               if (!error)
9172 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry,
9173 +                               &nd);
9174 +               if (!error)
9175 +                       gr_handle_create(new_dentry, nd.mnt);
9176 +
9177                 dput(new_dentry);
9178         }
9179         mutex_unlock(&nd.dentry->d_inode->i_mutex);
9180 @@ -2494,8 +2633,16 @@ static int do_rename(int olddfd, const c
9181         if (new_dentry == trap)
9182                 goto exit5;
9183  
9184 -       error = vfs_rename(old_dir->d_inode, old_dentry,
9185 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
9186 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
9187 +                                    newname);
9188 +
9189 +       if (!error)
9190 +               error = vfs_rename(old_dir->d_inode, old_dentry,
9191                                    new_dir->d_inode, new_dentry);
9192 +       if (!error)
9193 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
9194 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
9195  exit5:
9196         dput(new_dentry);
9197  exit4:
9198 diff -urNp linux-2.6.17.7/fs/namespace.c linux-2.6.17.7/fs/namespace.c
9199 --- linux-2.6.17.7/fs/namespace.c       2006-07-24 23:36:01.000000000 -0400
9200 +++ linux-2.6.17.7/fs/namespace.c       2006-08-01 20:29:46.000000000 -0400
9201 @@ -23,6 +23,8 @@
9202  #include <linux/mount.h>
9203  #include <linux/vserver/namespace.h>
9204  #include <linux/vserver/tag.h>
9205 +#include <linux/sched.h>
9206 +#include <linux/grsecurity.h>
9207  #include <asm/uaccess.h>
9208  #include <asm/unistd.h>
9209  #include "pnode.h"
9210 @@ -600,6 +602,8 @@ static int do_umount(struct vfsmount *mn
9211                         DQUOT_OFF(sb);
9212                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
9213                         unlock_kernel();
9214 +
9215 +                       gr_log_remount(mnt->mnt_devname, retval);
9216                 }
9217                 up_write(&sb->s_umount);
9218                 return retval;
9219 @@ -620,6 +624,9 @@ static int do_umount(struct vfsmount *mn
9220                 security_sb_umount_busy(mnt);
9221         up_write(&namespace_sem);
9222         release_mounts(&umount_list);
9223 +
9224 +       gr_log_unmount(mnt->mnt_devname, retval);
9225 +
9226         return retval;
9227  }
9228  
9229 @@ -1346,6 +1353,11 @@ long do_mount(char *dev_name, char *dir_
9230         if (retval)
9231                 goto dput_out;
9232  
9233 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
9234 +               retval = -EPERM;
9235 +               goto dput_out;
9236 +       }
9237 +
9238         if (flags & MS_REMOUNT)
9239                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
9240                                     data_page);
9241 @@ -1360,6 +1372,9 @@ long do_mount(char *dev_name, char *dir_
9242                                       dev_name, data_page);
9243  dput_out:
9244         path_release(&nd);
9245 +
9246 +       gr_log_mount(dev_name, dir_name, retval);
9247 +
9248         return retval;
9249  }
9250  
9251 @@ -1612,6 +1627,9 @@ asmlinkage long sys_pivot_root(const cha
9252         if (!capable(CAP_SYS_ADMIN))
9253                 return -EPERM;
9254  
9255 +       if (gr_handle_chroot_pivot())
9256 +               return -EPERM;
9257 +
9258         lock_kernel();
9259  
9260         error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
9261 diff -urNp linux-2.6.17.7/fs/open.c linux-2.6.17.7/fs/open.c
9262 --- linux-2.6.17.7/fs/open.c    2006-07-24 23:36:01.000000000 -0400
9263 +++ linux-2.6.17.7/fs/open.c    2006-08-01 20:29:46.000000000 -0400
9264 @@ -28,6 +28,7 @@
9265  #include <linux/vs_limit.h>
9266  #include <linux/vs_dlimit.h>
9267  #include <linux/vserver/tag.h>
9268 +#include <linux/grsecurity.h>
9269  
9270  #include <asm/unistd.h>
9271  
9272 @@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
9273         if (length < 0)
9274                 return -EINVAL;
9275  
9276 +       if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
9277 +               return -EACCES;
9278 +
9279         newattrs.ia_size = length;
9280         newattrs.ia_valid = ATTR_SIZE | time_attrs;
9281         if (filp) {
9282 @@ -407,6 +411,12 @@ asmlinkage long sys_utime(char __user * 
9283                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
9284                         goto dput_and_out;
9285         }
9286 +
9287 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
9288 +               error = -EACCES;
9289 +               goto dput_and_out;
9290 +       }
9291 +
9292         mutex_lock(&inode->i_mutex);
9293         error = notify_change(nd.dentry, &newattrs);
9294         mutex_unlock(&inode->i_mutex);
9295 @@ -460,6 +470,12 @@ long do_utimes(int dfd, char __user *fil
9296                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
9297                         goto dput_and_out;
9298         }
9299 +
9300 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
9301 +               error = -EACCES;
9302 +               goto dput_and_out;
9303 +       }
9304 +
9305         mutex_lock(&inode->i_mutex);
9306         error = notify_change(nd.dentry, &newattrs);
9307         mutex_unlock(&inode->i_mutex);
9308 @@ -526,6 +542,10 @@ asmlinkage long sys_faccessat(int dfd, c
9309                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
9310                    && !special_file(nd.dentry->d_inode->i_mode))
9311                         res = -EROFS;
9312 +
9313 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
9314 +                       res = -EACCES;
9315 +
9316                 path_release(&nd);
9317         }
9318  
9319 @@ -554,6 +574,8 @@ asmlinkage long sys_chdir(const char __u
9320         if (error)
9321                 goto dput_and_out;
9322  
9323 +       gr_log_chdir(nd.dentry, nd.mnt);
9324 +
9325         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
9326  
9327  dput_and_out:
9328 @@ -584,6 +606,13 @@ asmlinkage long sys_fchdir(unsigned int 
9329                 goto out_putf;
9330  
9331         error = file_permission(file, MAY_EXEC);
9332 +
9333 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
9334 +               error = -EPERM;
9335 +
9336 +       if (!error)
9337 +               gr_log_chdir(dentry, mnt);
9338 +
9339         if (!error)
9340                 set_fs_pwd(current->fs, mnt, dentry);
9341  out_putf:
9342 @@ -609,8 +638,16 @@ asmlinkage long sys_chroot(const char __
9343         if (!capable(CAP_SYS_CHROOT))
9344                 goto dput_and_out;
9345  
9346 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
9347 +               goto dput_and_out;
9348 +
9349         set_fs_root(current->fs, nd.mnt, nd.dentry);
9350         set_fs_altroot();
9351 +
9352 +       gr_handle_chroot_caps(current);
9353 +
9354 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
9355 +
9356         error = 0;
9357  dput_and_out:
9358         path_release(&nd);
9359 @@ -641,9 +678,22 @@ asmlinkage long sys_fchmod(unsigned int 
9360         err = -EPERM;
9361         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9362                 goto out_putf;
9363 +
9364 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
9365 +               err = -EACCES;
9366 +               goto out_putf;
9367 +       }
9368 +
9369         mutex_lock(&inode->i_mutex);
9370         if (mode == (mode_t) -1)
9371                 mode = inode->i_mode;
9372 +
9373 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
9374 +               err = -EPERM;
9375 +               mutex_unlock(&inode->i_mutex);
9376 +               goto out_putf;
9377 +       }
9378 +
9379         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
9380         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
9381         err = notify_change(dentry, &newattrs);
9382 @@ -676,9 +726,21 @@ asmlinkage long sys_fchmodat(int dfd, co
9383         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9384                 goto dput_and_out;
9385  
9386 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
9387 +               error = -EACCES;
9388 +               goto dput_and_out;
9389 +       };
9390 +
9391         mutex_lock(&inode->i_mutex);
9392         if (mode == (mode_t) -1)
9393                 mode = inode->i_mode;
9394 +
9395 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
9396 +               error = -EACCES;
9397 +               mutex_unlock(&inode->i_mutex);
9398 +               goto dput_and_out;
9399 +       }
9400 +
9401         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
9402         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
9403         error = notify_change(nd.dentry, &newattrs);
9404 @@ -712,6 +774,12 @@ static int chown_common(struct dentry * 
9405         error = -EPERM;
9406         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9407                 goto out;
9408 +
9409 +       if (!gr_acl_handle_chown(dentry, mnt)) {
9410 +               error = -EACCES;
9411 +               goto out;
9412 +       }
9413 +
9414         newattrs.ia_valid =  ATTR_CTIME;
9415         if (user != (uid_t) -1) {
9416                 newattrs.ia_valid |= ATTR_UID;
9417 @@ -995,6 +1063,7 @@ repeat:
9418          * N.B. For clone tasks sharing a files structure, this test
9419          * will limit the total number of files that can be opened.
9420          */
9421 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
9422         if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
9423                 goto out;
9424  
9425 diff -urNp linux-2.6.17.7/fs/pipe.c linux-2.6.17.7/fs/pipe.c
9426 --- linux-2.6.17.7/fs/pipe.c    2006-07-24 23:36:01.000000000 -0400
9427 +++ linux-2.6.17.7/fs/pipe.c    2006-08-01 20:29:46.000000000 -0400
9428 @@ -842,7 +842,7 @@ void free_pipe_info(struct inode *inode)
9429         inode->i_pipe = NULL;
9430  }
9431  
9432 -static struct vfsmount *pipe_mnt __read_mostly;
9433 +struct vfsmount *pipe_mnt __read_mostly;
9434  static int pipefs_delete_dentry(struct dentry *dentry)
9435  {
9436         return 1;
9437 diff -urNp linux-2.6.17.7/fs/proc/array.c linux-2.6.17.7/fs/proc/array.c
9438 --- linux-2.6.17.7/fs/proc/array.c      2006-07-24 23:36:01.000000000 -0400
9439 +++ linux-2.6.17.7/fs/proc/array.c      2006-08-01 20:29:46.000000000 -0400
9440 @@ -293,6 +293,21 @@ static inline char *task_cap(struct task
9441                             cap_t(p->cap_effective));
9442  }
9443  
9444 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9445 +static inline char *task_pax(struct task_struct *p, char *buffer)
9446 +{
9447 +       if (p->mm)
9448 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
9449 +                               p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
9450 +                               p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
9451 +                               p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
9452 +                               p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
9453 +                               p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
9454 +       else
9455 +               return buffer + sprintf(buffer, "PaX:\t-----\n");
9456 +}
9457 +#endif
9458 +
9459  int proc_pid_status(struct task_struct *task, char * buffer)
9460  {
9461         char * orig = buffer;
9462 @@ -311,9 +326,20 @@ int proc_pid_status(struct task_struct *
9463  #if defined(CONFIG_S390)
9464         buffer = task_show_regs(task, buffer);
9465  #endif
9466 +
9467 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9468 +       buffer = task_pax(task, buffer);
9469 +#endif
9470 +
9471         return buffer - orig;
9472  }
9473  
9474 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9475 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
9476 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
9477 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
9478 +#endif
9479 +
9480  static int do_task_stat(struct task_struct *task, char * buffer, int whole)
9481  {
9482         unsigned long vsize, eip, esp, wchan = ~0UL;
9483 @@ -398,6 +424,19 @@ static int do_task_stat(struct task_stru
9484                 stime = task->stime;
9485         }
9486  
9487 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9488 +       if (PAX_RAND_FLAGS(mm)) {
9489 +               eip = 0;
9490 +               esp = 0;
9491 +               wchan = 0;
9492 +       }
9493 +#endif
9494 +#ifdef CONFIG_GRKERNSEC_HIDESYM
9495 +       wchan = 0;
9496 +       eip =0;
9497 +       esp =0;
9498 +#endif
9499 +
9500         /* scale priority and nice values from timeslices to -20..20 */
9501         /* to make it look like a "normal" Unix priority/nice value  */
9502         priority = task_prio(task);
9503 @@ -437,9 +476,15 @@ static int do_task_stat(struct task_stru
9504                 vsize,
9505                 mm ? get_mm_rss(mm) : 0,
9506                 rsslim,
9507 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9508 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
9509 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
9510 +               PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
9511 +#else
9512                 mm ? mm->start_code : 0,
9513                 mm ? mm->end_code : 0,
9514                 mm ? mm->start_stack : 0,
9515 +#endif
9516                 esp,
9517                 eip,
9518                 /* The signal information here is obsolete.
9519 @@ -485,3 +530,14 @@ int proc_pid_statm(struct task_struct *t
9520         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
9521                        size, resident, shared, text, lib, data, 0);
9522  }
9523 +
9524 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9525 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
9526 +{
9527 +       int len;
9528 +
9529 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
9530 +       return len;
9531 +}
9532 +#endif
9533 +
9534 diff -urNp linux-2.6.17.7/fs/proc/base.c linux-2.6.17.7/fs/proc/base.c
9535 --- linux-2.6.17.7/fs/proc/base.c       2006-07-24 23:36:01.000000000 -0400
9536 +++ linux-2.6.17.7/fs/proc/base.c       2006-08-01 20:29:46.000000000 -0400
9537 @@ -72,6 +72,7 @@
9538  #include <linux/poll.h>
9539  #include <linux/vs_network.h>
9540  #include <linux/vs_pid.h>
9541 +#include <linux/grsecurity.h>
9542  #include "internal.h"
9543  
9544  /*
9545 @@ -125,6 +126,9 @@ enum pid_directory_inos {
9546  #ifdef CONFIG_AUDITSYSCALL
9547         PROC_TGID_LOGINUID,
9548  #endif
9549 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9550 +       PROC_TGID_IPADDR,
9551 +#endif
9552         PROC_TGID_OOM_SCORE,
9553         PROC_TGID_OOM_ADJUST,
9554         PROC_TID_INO,
9555 @@ -204,6 +208,9 @@ static struct pid_entry tgid_base_stuff[
9556         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
9557         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
9558         E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
9559 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9560 +       E(PROC_TGID_IPADDR,     "ipaddr", S_IFREG|S_IRUSR),
9561 +#endif
9562  #ifdef CONFIG_MMU
9563         E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
9564  #endif
9565 @@ -410,7 +417,7 @@ static int proc_task_root_link(struct in
9566         (task->parent == current && \
9567         (task->ptrace & PT_PTRACED) && \
9568          (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
9569 -        security_ptrace(current,task) == 0))
9570 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
9571  
9572  static int proc_pid_environ(struct task_struct *task, char * buffer)
9573  {
9574 @@ -591,9 +598,25 @@ static int proc_check_root(struct inode 
9575  
9576  static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
9577  {
9578 +       int ret = -EACCES;
9579 +       struct task_struct *task;
9580 +
9581         if (generic_permission(inode, mask, NULL) != 0)
9582 -               return -EACCES;
9583 -       return proc_check_root(inode);
9584 +               goto out;
9585 +
9586 +       ret = proc_check_root(inode);
9587 +       if (ret)
9588 +               goto out;
9589 +
9590 +       task = proc_task(inode);
9591 +
9592 +       if (!task)
9593 +               goto out;
9594 +
9595 +       ret = gr_acl_handle_procpidmem(task);
9596 +
9597 +out:
9598 +       return ret;
9599  }
9600  
9601  static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd)
9602 @@ -1372,6 +1395,9 @@ static struct inode *proc_pid_make_inode
9603         }
9604         /* procfs is xid tagged */
9605         inode->i_tag = (tag_t)vx_task_xid(task);
9606 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9607 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9608 +#endif
9609         security_task_to_inode(task, inode);
9610  
9611  out:
9612 @@ -1400,7 +1426,9 @@ static int pid_revalidate(struct dentry 
9613         if (pid_alive(task)) {
9614                 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
9615                         inode->i_uid = task->euid;
9616 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
9617                         inode->i_gid = task->egid;
9618 +#endif
9619                 } else {
9620                         inode->i_uid = 0;
9621                         inode->i_gid = 0;
9622 @@ -1730,6 +1758,12 @@ static struct dentry *proc_pident_lookup
9623                         inode->i_fop = &proc_info_file_operations;
9624                         ei->op.proc_read = proc_pid_status;
9625                         break;
9626 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9627 +               case PROC_TGID_IPADDR:
9628 +                       inode->i_fop = &proc_info_file_operations;
9629 +                       ei->op.proc_read = proc_pid_ipaddr;
9630 +                       break;
9631 +#endif
9632                 case PROC_TID_STAT:
9633                         inode->i_fop = &proc_info_file_operations;
9634                         ei->op.proc_read = proc_tid_stat;
9635 @@ -2140,11 +2173,34 @@ struct dentry *proc_pid_lookup(struct in
9636         if (!proc_pid_visible(task, tgid))
9637                 goto out_drop_task;
9638  
9639 +       if (gr_check_hidden_task(task)) {
9640 +               put_task_struct(task);
9641 +               goto out;
9642 +       }
9643 +
9644 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9645 +       if (current->uid && (task->uid != current->uid)
9646 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9647 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
9648 +#endif
9649 +       ) {
9650 +               put_task_struct(task);
9651 +               goto out;
9652 +       }
9653 +#endif
9654 +
9655         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
9656         if (!inode)
9657                 goto out_drop_task;
9658  
9659 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9660 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
9661 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9662 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
9663 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9664 +#else
9665         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
9666 +#endif
9667         inode->i_op = &proc_tgid_base_inode_operations;
9668         inode->i_fop = &proc_tgid_base_operations;
9669         inode->i_flags|=S_IMMUTABLE;
9670 @@ -2137,6 +2195,9 @@ out:
9671  static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
9672  {
9673         struct task_struct *p;
9674 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9675 +       struct task_struct *tmp = current;
9676 +#endif
9677         int nr_tgids = 0;
9678  
9679         index--;
9680 @@ -2157,6 +2218,18 @@ static int get_tgid_list(int index, unsi
9681                 int tgid = p->pid;
9682                 if (!pid_alive(p))
9683                         continue;
9684 +               if (gr_pid_is_chrooted(p))
9685 +                       continue;
9686 +               if (gr_check_hidden_task(p))
9687 +                       continue;
9688 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9689 +               if (tmp->uid && (p->uid != tmp->uid)
9690 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9691 +                   && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
9692 +#endif
9693 +               )
9694 +                       continue;
9695 +#endif
9696                 if (--index >= 0)
9697                         continue;
9698                 tgids[nr_tgids] = tgid;
9699 diff -urNp linux-2.6.17.7/fs/proc/inode.c linux-2.6.17.7/fs/proc/inode.c
9700 --- linux-2.6.17.7/fs/proc/inode.c      2006-07-24 23:36:01.000000000 -0400
9701 +++ linux-2.6.17.7/fs/proc/inode.c      2006-08-01 20:29:46.000000000 -0400
9702 @@ -169,7 +169,11 @@ struct inode *proc_get_inode(struct supe
9703                 if (de->mode) {
9704                         inode->i_mode = de->mode;
9705                         inode->i_uid = de->uid;
9706 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
9707 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
9708 +#else
9709                         inode->i_gid = de->gid;
9710 +#endif
9711                 }
9712                 if (de->size)
9713                         inode->i_size = de->size;
9714 diff -urNp linux-2.6.17.7/fs/proc/internal.h linux-2.6.17.7/fs/proc/internal.h
9715 --- linux-2.6.17.7/fs/proc/internal.h   2006-07-24 23:36:01.000000000 -0400
9716 +++ linux-2.6.17.7/fs/proc/internal.h   2006-08-01 20:29:46.000000000 -0400
9717 @@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
9718  extern int proc_tgid_stat(struct task_struct *, char *);
9719  extern int proc_pid_status(struct task_struct *, char *);
9720  extern int proc_pid_statm(struct task_struct *, char *);
9721 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
9722 +extern int proc_pid_ipaddr(struct task_struct*,char*);
9723 +#endif
9724  
9725  void free_proc_entry(struct proc_dir_entry *de);
9726  
9727 diff -urNp linux-2.6.17.7/fs/proc/proc_misc.c linux-2.6.17.7/fs/proc/proc_misc.c
9728 --- linux-2.6.17.7/fs/proc/proc_misc.c  2006-07-24 23:36:01.000000000 -0400
9729 +++ linux-2.6.17.7/fs/proc/proc_misc.c  2006-08-01 20:29:46.000000000 -0400
9730 @@ -651,6 +651,8 @@ void create_seq_entry(char *name, mode_t
9731  void __init proc_misc_init(void)
9732  {
9733         struct proc_dir_entry *entry;
9734 +       int gr_mode = 0;
9735 +
9736         static struct {
9737                 char *name;
9738                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
9739 @@ -666,7 +668,9 @@ void __init proc_misc_init(void)
9740                 {"stram",       stram_read_proc},
9741  #endif
9742                 {"filesystems", filesystems_read_proc},
9743 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
9744                 {"cmdline",     cmdline_read_proc},
9745 +#endif
9746                 {"locks",       locks_read_proc},
9747                 {"execdomains", execdomains_read_proc},
9748                 {NULL,}
9749 @@ -674,19 +678,36 @@ void __init proc_misc_init(void)
9750         for (p = simple_ones; p->name; p++)
9751                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
9752  
9753 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9754 +       gr_mode = S_IRUSR;
9755 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9756 +       gr_mode = S_IRUSR | S_IRGRP;
9757 +#endif
9758 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9759 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
9760 +#endif
9761 +
9762         proc_symlink("mounts", NULL, "self/mounts");
9763  
9764         /* And now for trickier ones */
9765         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
9766         if (entry)
9767                 entry->proc_fops = &proc_kmsg_operations;
9768 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9769 +       create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
9770 +#else
9771         create_seq_entry("devices", 0, &proc_devinfo_operations);
9772 +#endif
9773         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
9774         create_seq_entry("partitions", 0, &proc_partitions_operations);
9775         create_seq_entry("stat", 0, &proc_stat_operations);
9776         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
9777  #ifdef CONFIG_SLAB
9778 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9779 +       create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
9780 +#else
9781         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
9782 +#endif
9783  #ifdef CONFIG_DEBUG_SLAB_LEAK
9784         create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
9785  #endif
9786 @@ -701,7 +722,7 @@ void __init proc_misc_init(void)
9787  #ifdef CONFIG_SCHEDSTATS
9788         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
9789  #endif
9790 -#ifdef CONFIG_PROC_KCORE
9791 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
9792         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
9793         if (proc_root_kcore) {
9794                 proc_root_kcore->proc_fops = &proc_kcore_operations;
9795 diff -urNp linux-2.6.17.7/fs/proc/root.c linux-2.6.17.7/fs/proc/root.c
9796 --- linux-2.6.17.7/fs/proc/root.c       2006-07-24 23:36:01.000000000 -0400
9797 +++ linux-2.6.17.7/fs/proc/root.c       2006-08-01 20:29:46.000000000 -0400
9798 @@ -53,7 +53,13 @@ void __init proc_root_init(void)
9799                 return;
9800         }
9801         proc_misc_init();
9802 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9803 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
9804 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9805 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
9806 +#else
9807         proc_net = proc_mkdir("net", NULL);
9808 +#endif
9809         proc_net_stat = proc_mkdir("net/stat", NULL);
9810  
9811  #ifdef CONFIG_SYSVIPC
9812 @@ -77,7 +83,15 @@ void __init proc_root_init(void)
9813  #ifdef CONFIG_PROC_DEVICETREE
9814         proc_device_tree_init();
9815  #endif
9816 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
9817 +#ifdef CONFIG_GRKERNSEC_PROC_USER
9818 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
9819 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
9820 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
9821 +#endif
9822 +#else
9823         proc_bus = proc_mkdir("bus", NULL);
9824 +#endif
9825         proc_vx_init();
9826  }
9827  
9828 diff -urNp linux-2.6.17.7/fs/proc/task_mmu.c linux-2.6.17.7/fs/proc/task_mmu.c
9829 --- linux-2.6.17.7/fs/proc/task_mmu.c   2006-07-24 23:36:01.000000000 -0400
9830 +++ linux-2.6.17.7/fs/proc/task_mmu.c   2006-08-01 20:29:46.000000000 -0400
9831 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
9832                 "VmStk:\t%8lu kB\n"
9833                 "VmExe:\t%8lu kB\n"
9834                 "VmLib:\t%8lu kB\n"
9835 -               "VmPTE:\t%8lu kB\n",
9836 -               hiwater_vm << (PAGE_SHIFT-10),
9837 +               "VmPTE:\t%8lu kB\n"
9838 +
9839 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
9840 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
9841 +#endif
9842 +
9843 +               ,hiwater_vm << (PAGE_SHIFT-10),
9844                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
9845                 mm->locked_vm << (PAGE_SHIFT-10),
9846                 hiwater_rss << (PAGE_SHIFT-10),
9847                 total_rss << (PAGE_SHIFT-10),
9848                 data << (PAGE_SHIFT-10),
9849                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
9850 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
9851 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
9852 +
9853 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
9854 +               , mm->context.user_cs_base, mm->context.user_cs_limit
9855 +#endif
9856 +
9857 +       );
9858 +
9859         return buffer;
9860  }
9861  
9862 @@ -118,6 +130,12 @@ struct mem_size_stats
9863         unsigned long private_dirty;
9864  };
9865  
9866 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9867 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
9868 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
9869 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
9870 +#endif
9871 +
9872  static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
9873  {
9874         struct task_struct *task = m->private;
9875 @@ -136,13 +154,30 @@ static int show_map_internal(struct seq_
9876         }
9877  
9878         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
9879 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9880 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
9881 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
9882 +#else
9883                         vma->vm_start,
9884                         vma->vm_end,
9885 +#endif
9886 +
9887 +#if 0
9888 +                       flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
9889 +                       flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
9890 +                       flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
9891 +#else
9892                         flags & VM_READ ? 'r' : '-',
9893                         flags & VM_WRITE ? 'w' : '-',
9894                         flags & VM_EXEC ? 'x' : '-',
9895 +#endif
9896 +
9897                         flags & VM_MAYSHARE ? 's' : 'p',
9898 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9899 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
9900 +#else
9901                         vma->vm_pgoff << PAGE_SHIFT,
9902 +#endif
9903                         MAJOR(dev), MINOR(dev), ino, &len);
9904  
9905         /*
9906 @@ -154,13 +189,13 @@ static int show_map_internal(struct seq_
9907                 seq_path(m, file->f_vfsmnt, file->f_dentry, "\n");
9908         } else {
9909                 if (mm) {
9910 -                       if (vma->vm_start <= mm->start_brk &&
9911 -                                               vma->vm_end >= mm->brk) {
9912 +                       if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
9913                                 pad_len_spaces(m, len);
9914                                 seq_puts(m, "[heap]");
9915                         } else {
9916 -                               if (vma->vm_start <= mm->start_stack &&
9917 -                                       vma->vm_end >= mm->start_stack) {
9918 +                               if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
9919 +                                   (vma->vm_start <= mm->start_stack &&
9920 +                                       vma->vm_end >= mm->start_stack)) {
9921  
9922                                         pad_len_spaces(m, len);
9923                                         seq_puts(m, "[stack]");
9924 @@ -173,7 +208,25 @@ static int show_map_internal(struct seq_
9925         }
9926         seq_putc(m, '\n');
9927  
9928 -       if (mss)
9929 +       
9930 +       if (mss) {
9931 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
9932 +           if (PAX_RAND_FLAGS(mm))
9933 +               seq_printf(m,
9934 +                          "Size:          %8lu kB\n"
9935 +                          "Rss:           %8lu kB\n"
9936 +                          "Shared_Clean:  %8lu kB\n"
9937 +                          "Shared_Dirty:  %8lu kB\n"
9938 +                          "Private_Clean: %8lu kB\n"
9939 +                          "Private_Dirty: %8lu kB\n",
9940 +                          0UL,
9941 +                          0UL,
9942 +                          0UL,
9943 +                          0UL,
9944 +                          0UL,
9945 +                          0UL);
9946 +           else
9947 +#endif
9948                 seq_printf(m,
9949                            "Size:          %8lu kB\n"
9950                            "Rss:           %8lu kB\n"
9951 @@ -187,6 +240,7 @@ static int show_map_internal(struct seq_
9952                            mss->shared_dirty  >> 10,
9953                            mss->private_clean >> 10,
9954                            mss->private_dirty >> 10);
9955 +       }
9956  
9957         if (m->count < m->size)  /* vma is copied successfully */
9958                 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
9959 diff -urNp linux-2.6.17.7/fs/readdir.c linux-2.6.17.7/fs/readdir.c
9960 --- linux-2.6.17.7/fs/readdir.c 2006-07-24 23:36:01.000000000 -0400
9961 +++ linux-2.6.17.7/fs/readdir.c 2006-08-01 20:29:46.000000000 -0400
9962 @@ -16,6 +16,8 @@
9963  #include <linux/security.h>
9964  #include <linux/syscalls.h>
9965  #include <linux/unistd.h>
9966 +#include <linux/namei.h>
9967 +#include <linux/grsecurity.h>
9968  
9969  #include <asm/uaccess.h>
9970  
9971 @@ -65,6 +67,7 @@ struct old_linux_dirent {
9972  
9973  struct readdir_callback {
9974         struct old_linux_dirent __user * dirent;
9975 +       struct file * file;
9976         int result;
9977  };
9978  
9979 @@ -76,6 +79,10 @@ static int fillonedir(void * __buf, cons
9980  
9981         if (buf->result)
9982                 return -EINVAL;
9983 +
9984 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
9985 +               return 0;
9986 +
9987         buf->result++;
9988         dirent = buf->dirent;
9989         if (!access_ok(VERIFY_WRITE, dirent,
9990 @@ -107,6 +114,7 @@ asmlinkage long old_readdir(unsigned int
9991  
9992         buf.result = 0;
9993         buf.dirent = dirent;
9994 +       buf.file = file;
9995  
9996         error = vfs_readdir(file, fillonedir, &buf);
9997         if (error >= 0)
9998 @@ -133,6 +141,7 @@ struct linux_dirent {
9999  struct getdents_callback {
10000         struct linux_dirent __user * current_dir;
10001         struct linux_dirent __user * previous;
10002 +       struct file * file;
10003         int count;
10004         int error;
10005  };
10006 @@ -147,6 +156,10 @@ static int filldir(void * __buf, const c
10007         buf->error = -EINVAL;   /* only used if we fail.. */
10008         if (reclen > buf->count)
10009                 return -EINVAL;
10010 +
10011 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
10012 +               return 0;
10013 +
10014         dirent = buf->previous;
10015         if (dirent) {
10016                 if (__put_user(offset, &dirent->d_off))
10017 @@ -191,6 +204,7 @@ asmlinkage long sys_getdents(unsigned in
10018  
10019         buf.current_dir = dirent;
10020         buf.previous = NULL;
10021 +       buf.file = file;
10022         buf.count = count;
10023         buf.error = 0;
10024  
10025 @@ -217,6 +231,7 @@ out:
10026  struct getdents_callback64 {
10027         struct linux_dirent64 __user * current_dir;
10028         struct linux_dirent64 __user * previous;
10029 +       struct file * file;
10030         int count;
10031         int error;
10032  };
10033 @@ -231,6 +246,10 @@ static int filldir64(void * __buf, const
10034         buf->error = -EINVAL;   /* only used if we fail.. */
10035         if (reclen > buf->count)
10036                 return -EINVAL;
10037 +
10038 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
10039 +               return 0;
10040 +
10041         dirent = buf->previous;
10042         if (dirent) {
10043                 if (__put_user(offset, &dirent->d_off))
10044 @@ -277,6 +296,7 @@ asmlinkage long sys_getdents64(unsigned 
10045  
10046         buf.current_dir = dirent;
10047         buf.previous = NULL;
10048 +       buf.file = file;
10049         buf.count = count;
10050         buf.error = 0;
10051  
10052 diff -urNp linux-2.6.17.7/fs/xfs/linux-2.6/xfs_file.c linux-2.6.17.7/fs/xfs/linux-2.6/xfs_file.c
10053 --- linux-2.6.17.7/fs/xfs/linux-2.6/xfs_file.c  2006-07-24 23:36:01.000000000 -0400
10054 +++ linux-2.6.17.7/fs/xfs/linux-2.6/xfs_file.c  2006-08-01 20:29:46.000000000 -0400
10055 @@ -461,6 +461,11 @@ xfs_file_mmap(
10056         vattr_t         vattr;
10057         int             error;
10058  
10059 +#ifdef CONFIG_PAX_PAGEEXEC
10060 +       if (vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC)
10061 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
10062 +#endif
10063 +
10064         vma->vm_ops = &xfs_file_vm_ops;
10065  
10066  #ifdef CONFIG_XFS_DMAPI
10067 diff -urNp linux-2.6.17.7/grsecurity/Kconfig linux-2.6.17.7/grsecurity/Kconfig
10068 --- linux-2.6.17.7/grsecurity/Kconfig   1969-12-31 19:00:00.000000000 -0500
10069 +++ linux-2.6.17.7/grsecurity/Kconfig   2006-08-01 20:29:47.000000000 -0400
10070 @@ -0,0 +1,890 @@
10071 +#
10072 +# grecurity configuration
10073 +#
10074 +
10075 +menu "Grsecurity"
10076 +
10077 +config GRKERNSEC
10078 +       bool "Grsecurity"
10079 +       select CRYPTO
10080 +       select CRYPTO_SHA256
10081 +       help
10082 +         If you say Y here, you will be able to configure many features
10083 +         that will enhance the security of your system.  It is highly
10084 +         recommended that you say Y here and read through the help
10085 +         for each option so that you fully understand the features and
10086 +         can evaluate their usefulness for your machine.
10087 +
10088 +choice
10089 +       prompt "Security Level"
10090 +       depends GRKERNSEC
10091 +       default GRKERNSEC_CUSTOM
10092 +
10093 +config GRKERNSEC_LOW
10094 +       bool "Low"
10095 +       select GRKERNSEC_LINK
10096 +       select GRKERNSEC_FIFO
10097 +       select GRKERNSEC_RANDPID
10098 +       select GRKERNSEC_EXECVE
10099 +       select GRKERNSEC_RANDNET
10100 +       select GRKERNSEC_DMESG
10101 +       select GRKERNSEC_CHROOT_CHDIR
10102 +       select GRKERNSEC_MODSTOP if (MODULES)
10103 +
10104 +       help
10105 +         If you choose this option, several of the grsecurity options will
10106 +         be enabled that will give you greater protection against a number
10107 +         of attacks, while assuring that none of your software will have any
10108 +         conflicts with the additional security measures.  If you run a lot
10109 +         of unusual software, or you are having problems with the higher
10110 +         security levels, you should say Y here.  With this option, the
10111 +         following features are enabled:
10112 +
10113 +         - Linking restrictions
10114 +         - FIFO restrictions
10115 +         - Randomized PIDs
10116 +         - Enforcing RLIMIT_NPROC on execve
10117 +         - Restricted dmesg
10118 +         - Enforced chdir("/") on chroot
10119 +         - Runtime module disabling
10120 +
10121 +config GRKERNSEC_MEDIUM
10122 +       bool "Medium"
10123 +       select PAX
10124 +       select PAX_EI_PAX
10125 +       select PAX_PT_PAX_FLAGS
10126 +       select PAX_HAVE_ACL_FLAGS
10127 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
10128 +       select GRKERNSEC_CHROOT_SYSCTL
10129 +       select GRKERNSEC_LINK
10130 +       select GRKERNSEC_FIFO
10131 +       select GRKERNSEC_RANDPID
10132 +       select GRKERNSEC_EXECVE
10133 +       select GRKERNSEC_DMESG
10134 +       select GRKERNSEC_RANDNET
10135 +       select GRKERNSEC_FORKFAIL
10136 +       select GRKERNSEC_TIME
10137 +       select GRKERNSEC_SIGNAL
10138 +       select GRKERNSEC_CHROOT
10139 +       select GRKERNSEC_CHROOT_UNIX
10140 +       select GRKERNSEC_CHROOT_MOUNT
10141 +       select GRKERNSEC_CHROOT_PIVOT
10142 +       select GRKERNSEC_CHROOT_DOUBLE
10143 +       select GRKERNSEC_CHROOT_CHDIR
10144 +       select GRKERNSEC_CHROOT_MKNOD
10145 +       select GRKERNSEC_PROC
10146 +       select GRKERNSEC_PROC_USERGROUP
10147 +       select GRKERNSEC_MODSTOP if (MODULES)
10148 +       select PAX_RANDUSTACK
10149 +       select PAX_ASLR
10150 +       select PAX_RANDMMAP
10151 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
10152 +
10153 +       help
10154 +         If you say Y here, several features in addition to those included
10155 +         in the low additional security level will be enabled.  These
10156 +         features provide even more security to your system, though in rare
10157 +         cases they may be incompatible with very old or poorly written
10158 +         software.  If you enable this option, make sure that your auth
10159 +         service (identd) is running as gid 1001.  With this option, 
10160 +         the following features (in addition to those provided in the 
10161 +         low additional security level) will be enabled:
10162 +
10163 +         - Randomized TCP source ports
10164 +         - Failed fork logging
10165 +         - Time change logging
10166 +         - Signal logging
10167 +         - Deny mounts in chroot
10168 +         - Deny double chrooting
10169 +         - Deny sysctl writes in chroot
10170 +         - Deny mknod in chroot
10171 +         - Deny access to abstract AF_UNIX sockets out of chroot
10172 +         - Deny pivot_root in chroot
10173 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
10174 +         - /proc restrictions with special GID set to 10 (usually wheel)
10175 +         - Address Space Layout Randomization (ASLR)
10176 +
10177 +config GRKERNSEC_HIGH
10178 +       bool "High"
10179 +       select GRKERNSEC_LINK
10180 +       select GRKERNSEC_FIFO
10181 +       select GRKERNSEC_RANDPID
10182 +       select GRKERNSEC_EXECVE
10183 +       select GRKERNSEC_DMESG
10184 +       select GRKERNSEC_FORKFAIL
10185 +       select GRKERNSEC_TIME
10186 +       select GRKERNSEC_SIGNAL
10187 +       select GRKERNSEC_CHROOT_SHMAT
10188 +       select GRKERNSEC_CHROOT_UNIX
10189 +       select GRKERNSEC_CHROOT_MOUNT
10190 +       select GRKERNSEC_CHROOT_FCHDIR
10191 +       select GRKERNSEC_CHROOT_PIVOT
10192 +       select GRKERNSEC_CHROOT_DOUBLE
10193 +       select GRKERNSEC_CHROOT_CHDIR
10194 +       select GRKERNSEC_CHROOT_MKNOD
10195 +       select GRKERNSEC_CHROOT_CAPS
10196 +       select GRKERNSEC_CHROOT_SYSCTL
10197 +       select GRKERNSEC_CHROOT_FINDTASK
10198 +       select GRKERNSEC_PROC
10199 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
10200 +       select GRKERNSEC_HIDESYM
10201 +       select GRKERNSEC_BRUTE
10202 +       select GRKERNSEC_SHM if (SYSVIPC)
10203 +       select GRKERNSEC_PROC_USERGROUP
10204 +       select GRKERNSEC_KMEM
10205 +       select GRKERNSEC_RESLOG
10206 +       select GRKERNSEC_RANDNET
10207 +       select GRKERNSEC_PROC_ADD
10208 +       select GRKERNSEC_CHROOT_CHMOD
10209 +       select GRKERNSEC_CHROOT_NICE
10210 +       select GRKERNSEC_AUDIT_MOUNT
10211 +       select GRKERNSEC_MODSTOP if (MODULES)
10212 +       select PAX
10213 +       select PAX_RANDUSTACK
10214 +       select PAX_ASLR
10215 +       select PAX_RANDMMAP
10216 +       select PAX_NOEXEC
10217 +       select PAX_MPROTECT
10218 +       select PAX_EI_PAX
10219 +       select PAX_PT_PAX_FLAGS
10220 +       select PAX_HAVE_ACL_FLAGS
10221 +       select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
10222 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
10223 +       select PAX_SEGMEXEC if (X86 && !X86_64)
10224 +       select PAX_PAGEEXEC if (!X86)
10225 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
10226 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
10227 +       select PAX_SYSCALL if (PPC32)
10228 +       select PAX_EMUTRAMP if (PARISC)
10229 +       select PAX_EMUSIGRT if (PARISC)
10230 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
10231 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
10232 +       help
10233 +         If you say Y here, many of the features of grsecurity will be
10234 +         enabled, which will protect you against many kinds of attacks
10235 +         against your system.  The heightened security comes at a cost
10236 +         of an increased chance of incompatibilities with rare software
10237 +         on your machine.  Since this security level enables PaX, you should
10238 +         view <http://pax.grsecurity.net> and read about the PaX
10239 +         project.  While you are there, download chpax and run it on
10240 +         binaries that cause problems with PaX.  Also remember that
10241 +         since the /proc restrictions are enabled, you must run your
10242 +         identd as gid 1001.  This security level enables the following 
10243 +         features in addition to those listed in the low and medium 
10244 +         security levels:
10245 +
10246 +         - Additional /proc restrictions
10247 +         - Chmod restrictions in chroot
10248 +         - No signals, ptrace, or viewing of processes outside of chroot
10249 +         - Capability restrictions in chroot
10250 +         - Deny fchdir out of chroot
10251 +         - Priority restrictions in chroot
10252 +         - Segmentation-based implementation of PaX
10253 +         - Mprotect restrictions
10254 +         - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
10255 +         - Kernel stack randomization
10256 +         - Mount/unmount/remount logging
10257 +         - Kernel symbol hiding
10258 +         - Destroy unused shared memory        
10259 +         - Prevention of memory exhaustion-based exploits
10260 +config GRKERNSEC_CUSTOM
10261 +       bool "Custom"
10262 +       help
10263 +         If you say Y here, you will be able to configure every grsecurity
10264 +         option, which allows you to enable many more features that aren't
10265 +         covered in the basic security levels.  These additional features
10266 +         include TPE, socket restrictions, and the sysctl system for
10267 +         grsecurity.  It is advised that you read through the help for
10268 +         each option to determine its usefulness in your situation.
10269 +
10270 +endchoice
10271 +
10272 +menu "Address Space Protection"
10273 +depends on GRKERNSEC
10274 +
10275 +config GRKERNSEC_KMEM
10276 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
10277 +       help
10278 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
10279 +         be written to via mmap or otherwise to modify the running kernel.
10280 +         /dev/port will also not be allowed to be opened. If you have module
10281 +         support disabled, enabling this will close up four ways that are
10282 +         currently used  to insert malicious code into the running kernel.
10283 +         Even with all these features enabled, we still highly recommend that
10284 +         you use the RBAC system, as it is still possible for an attacker to
10285 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
10286 +         If you are not using XFree86, you may be able to stop this additional
10287 +         case by enabling the 'Disable privileged I/O' option. Though nothing
10288 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
10289 +         but only to video memory, which is the only writing we allow in this
10290 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
10291 +         not be allowed to mprotect it with PROT_WRITE later.
10292 +         It is highly recommended that you say Y here if you meet all the
10293 +         conditions above.
10294 +
10295 +config GRKERNSEC_IO
10296 +       bool "Disable privileged I/O"
10297 +       depends on X86
10298 +       select RTC
10299 +       help
10300 +         If you say Y here, all ioperm and iopl calls will return an error.
10301 +         Ioperm and iopl can be used to modify the running kernel.
10302 +         Unfortunately, some programs need this access to operate properly,
10303 +         the most notable of which are XFree86 and hwclock.  hwclock can be
10304 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
10305 +         enabled if this option is enabled, to ensure that hwclock operates
10306 +         correctly.  XFree86 still will not operate correctly with this option
10307 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
10308 +         and you still want to protect your kernel against modification,
10309 +         use the RBAC system.
10310 +
10311 +config GRKERNSEC_PROC_MEMMAP
10312 +       bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
10313 +       depends on PAX_NOEXEC || PAX_ASLR
10314 +       help
10315 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
10316 +         give no information about the addresses of its mappings if
10317 +         PaX features that rely on random addresses are enabled on the task.
10318 +         If you use PaX it is greatly recommended that you say Y here as it
10319 +         closes up a hole that makes the full ASLR useless for suid
10320 +         binaries.
10321 +
10322 +config GRKERNSEC_BRUTE
10323 +       bool "Deter exploit bruteforcing"
10324 +       help
10325 +         If you say Y here, attempts to bruteforce exploits against forking
10326 +         daemons such as apache or sshd will be deterred.  When a child of a
10327 +         forking daemon is killed by PaX or crashes due to an illegal
10328 +         instruction, the parent process will be delayed 30 seconds upon every
10329 +         subsequent fork until the administrator is able to assess the
10330 +         situation and restart the daemon.  It is recommended that you also
10331 +         enable signal logging in the auditing section so that logs are
10332 +         generated when a process performs an illegal instruction.
10333 +
10334 +config GRKERNSEC_MODSTOP
10335 +       bool "Runtime module disabling"
10336 +       depends on MODULES
10337 +       help
10338 +         If you say Y here, you will be able to disable the ability to (un)load
10339 +         modules at runtime.  This feature is useful if you need the ability
10340 +         to load kernel modules at boot time, but do not want to allow an
10341 +         attacker to load a rootkit kernel module into the system, or to remove
10342 +         a loaded kernel module important to system functioning.  You should
10343 +         enable the /dev/mem protection feature as well, since rootkits can be
10344 +         inserted into the kernel via other methods than kernel modules.  Since
10345 +         an untrusted module could still be loaded by modifying init scripts and
10346 +         rebooting the system, it is also recommended that you enable the RBAC
10347 +         system.  If you enable this option, a sysctl option with name
10348 +         "disable_modules" will be created.  Setting this option to "1" disables
10349 +         module loading.  After this option is set, no further writes to it are
10350 +         allowed until the system is rebooted.
10351 +
10352 +config GRKERNSEC_HIDESYM
10353 +       bool "Hide kernel symbols"
10354 +       help
10355 +         If you say Y here, getting information on loaded modules, and
10356 +         displaying all kernel symbols through a syscall will be restricted
10357 +         to users with CAP_SYS_MODULE.  This option is only effective
10358 +         provided the following conditions are met:
10359 +         1) The kernel using grsecurity is not precompiled by some distribution
10360 +         2) You are using the RBAC system and hiding other files such as your
10361 +            kernel image and System.map
10362 +         3) You have the additional /proc restrictions enabled, which removes
10363 +            /proc/kcore
10364 +         If the above conditions are met, this option will aid to provide a
10365 +         useful protection against local and remote kernel exploitation of
10366 +         overflows and arbitrary read/write vulnerabilities.
10367 +
10368 +endmenu
10369 +menu "Role Based Access Control Options"
10370 +depends on GRKERNSEC
10371 +
10372 +config GRKERNSEC_ACL_HIDEKERN
10373 +       bool "Hide kernel processes"
10374 +       help
10375 +         If you say Y here, all kernel threads will be hidden to all
10376 +         processes but those whose subject has the "view hidden processes"
10377 +         flag.
10378 +
10379 +config GRKERNSEC_ACL_MAXTRIES
10380 +       int "Maximum tries before password lockout"
10381 +       default 3
10382 +       help
10383 +         This option enforces the maximum number of times a user can attempt
10384 +         to authorize themselves with the grsecurity RBAC system before being
10385 +         denied the ability to attempt authorization again for a specified time.
10386 +         The lower the number, the harder it will be to brute-force a password.
10387 +
10388 +config GRKERNSEC_ACL_TIMEOUT
10389 +       int "Time to wait after max password tries, in seconds"
10390 +       default 30
10391 +       help
10392 +         This option specifies the time the user must wait after attempting to
10393 +         authorize to the RBAC system with the maximum number of invalid
10394 +         passwords.  The higher the number, the harder it will be to brute-force
10395 +         a password.
10396 +
10397 +endmenu
10398 +menu "Filesystem Protections"
10399 +depends on GRKERNSEC
10400 +
10401 +config GRKERNSEC_PROC
10402 +       bool "Proc restrictions"
10403 +       help
10404 +         If you say Y here, the permissions of the /proc filesystem
10405 +         will be altered to enhance system security and privacy.  You MUST
10406 +         choose either a user only restriction or a user and group restriction.
10407 +         Depending upon the option you choose, you can either restrict users to
10408 +         see only the processes they themselves run, or choose a group that can
10409 +         view all processes and files normally restricted to root if you choose
10410 +         the "restrict to user only" option.  NOTE: If you're running identd as
10411 +         a non-root user, you will have to run it as the group you specify here.
10412 +
10413 +config GRKERNSEC_PROC_USER
10414 +       bool "Restrict /proc to user only"
10415 +       depends on GRKERNSEC_PROC
10416 +       help
10417 +         If you say Y here, non-root users will only be able to view their own
10418 +         processes, and restricts them from viewing network-related information,
10419 +         and viewing kernel symbol and module information.
10420 +
10421 +config GRKERNSEC_PROC_USERGROUP
10422 +       bool "Allow special group"
10423 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
10424 +       help
10425 +         If you say Y here, you will be able to select a group that will be
10426 +         able to view all processes, network-related information, and
10427 +         kernel and symbol information.  This option is useful if you want
10428 +         to run identd as a non-root user.
10429 +
10430 +config GRKERNSEC_PROC_GID
10431 +       int "GID for special group"
10432 +       depends on GRKERNSEC_PROC_USERGROUP
10433 +       default 1001
10434 +
10435 +config GRKERNSEC_PROC_ADD
10436 +       bool "Additional restrictions"
10437 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
10438 +       help
10439 +         If you say Y here, additional restrictions will be placed on
10440 +         /proc that keep normal users from viewing device information and 
10441 +         slabinfo information that could be useful for exploits.
10442 +
10443 +config GRKERNSEC_LINK
10444 +       bool "Linking restrictions"
10445 +       help
10446 +         If you say Y here, /tmp race exploits will be prevented, since users
10447 +         will no longer be able to follow symlinks owned by other users in
10448 +         world-writable +t directories (i.e. /tmp), unless the owner of the
10449 +         symlink is the owner of the directory. users will also not be
10450 +         able to hardlink to files they do not own.  If the sysctl option is
10451 +         enabled, a sysctl option with name "linking_restrictions" is created.
10452 +
10453 +config GRKERNSEC_FIFO
10454 +       bool "FIFO restrictions"
10455 +       help
10456 +         If you say Y here, users will not be able to write to FIFOs they don't
10457 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
10458 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
10459 +         option is enabled, a sysctl option with name "fifo_restrictions" is
10460 +         created.
10461 +
10462 +config GRKERNSEC_CHROOT
10463 +       bool "Chroot jail restrictions"
10464 +       help
10465 +         If you say Y here, you will be able to choose several options that will
10466 +         make breaking out of a chrooted jail much more difficult.  If you
10467 +         encounter no software incompatibilities with the following options, it
10468 +         is recommended that you enable each one.
10469 +
10470 +config GRKERNSEC_CHROOT_MOUNT
10471 +       bool "Deny mounts"
10472 +       depends on GRKERNSEC_CHROOT
10473 +       help
10474 +         If you say Y here, processes inside a chroot will not be able to
10475 +         mount or remount filesystems.  If the sysctl option is enabled, a
10476 +         sysctl option with name "chroot_deny_mount" is created.
10477 +
10478 +config GRKERNSEC_CHROOT_DOUBLE
10479 +       bool "Deny double-chroots"
10480 +       depends on GRKERNSEC_CHROOT
10481 +       help
10482 +         If you say Y here, processes inside a chroot will not be able to chroot
10483 +         again outside the chroot.  This is a widely used method of breaking
10484 +         out of a chroot jail and should not be allowed.  If the sysctl 
10485 +         option is enabled, a sysctl option with name 
10486 +         "chroot_deny_chroot" is created.
10487 +
10488 +config GRKERNSEC_CHROOT_PIVOT
10489 +       bool "Deny pivot_root in chroot"
10490 +       depends on GRKERNSEC_CHROOT
10491 +       help
10492 +         If you say Y here, processes inside a chroot will not be able to use
10493 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
10494 +         works similar to chroot in that it changes the root filesystem.  This
10495 +         function could be misused in a chrooted process to attempt to break out
10496 +         of the chroot, and therefore should not be allowed.  If the sysctl
10497 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
10498 +         created.
10499 +
10500 +config GRKERNSEC_CHROOT_CHDIR
10501 +       bool "Enforce chdir(\"/\") on all chroots"
10502 +       depends on GRKERNSEC_CHROOT
10503 +       help
10504 +         If you say Y here, the current working directory of all newly-chrooted
10505 +         applications will be set to the the root directory of the chroot.
10506 +         The man page on chroot(2) states:
10507 +         Note that this call does not change  the  current  working
10508 +         directory,  so  that `.' can be outside the tree rooted at
10509 +         `/'.  In particular, the  super-user  can  escape  from  a
10510 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
10511 +
10512 +         It is recommended that you say Y here, since it's not known to break
10513 +         any software.  If the sysctl option is enabled, a sysctl option with
10514 +         name "chroot_enforce_chdir" is created.
10515 +
10516 +config GRKERNSEC_CHROOT_CHMOD
10517 +       bool "Deny (f)chmod +s"
10518 +       depends on GRKERNSEC_CHROOT
10519 +       help
10520 +         If you say Y here, processes inside a chroot will not be able to chmod
10521 +         or fchmod files to make them have suid or sgid bits.  This protects
10522 +         against another published method of breaking a chroot.  If the sysctl
10523 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
10524 +         created.
10525 +
10526 +config GRKERNSEC_CHROOT_FCHDIR
10527 +       bool "Deny fchdir out of chroot"
10528 +       depends on GRKERNSEC_CHROOT
10529 +       help
10530 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
10531 +         to a file descriptor of the chrooting process that points to a directory
10532 +         outside the filesystem will be stopped.  If the sysctl option
10533 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
10534 +
10535 +config GRKERNSEC_CHROOT_MKNOD
10536 +       bool "Deny mknod"
10537 +       depends on GRKERNSEC_CHROOT
10538 +       help
10539 +         If you say Y here, processes inside a chroot will not be allowed to
10540 +         mknod.  The problem with using mknod inside a chroot is that it
10541 +         would allow an attacker to create a device entry that is the same
10542 +         as one on the physical root of your system, which could range from
10543 +         anything from the console device to a device for your harddrive (which
10544 +         they could then use to wipe the drive or steal data).  It is recommended
10545 +         that you say Y here, unless you run into software incompatibilities.
10546 +         If the sysctl option is enabled, a sysctl option with name
10547 +         "chroot_deny_mknod" is created.
10548 +
10549 +config GRKERNSEC_CHROOT_SHMAT
10550 +       bool "Deny shmat() out of chroot"
10551 +       depends on GRKERNSEC_CHROOT
10552 +       help
10553 +         If you say Y here, processes inside a chroot will not be able to attach
10554 +         to shared memory segments that were created outside of the chroot jail.
10555 +         It is recommended that you say Y here.  If the sysctl option is enabled,
10556 +         a sysctl option with name "chroot_deny_shmat" is created.
10557 +
10558 +config GRKERNSEC_CHROOT_UNIX
10559 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
10560 +       depends on GRKERNSEC_CHROOT
10561 +       help
10562 +         If you say Y here, processes inside a chroot will not be able to
10563 +         connect to abstract (meaning not belonging to a filesystem) Unix
10564 +         domain sockets that were bound outside of a chroot.  It is recommended
10565 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
10566 +         with name "chroot_deny_unix" is created.
10567 +
10568 +config GRKERNSEC_CHROOT_FINDTASK
10569 +       bool "Protect outside processes"
10570 +       depends on GRKERNSEC_CHROOT
10571 +       help
10572 +         If you say Y here, processes inside a chroot will not be able to
10573 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
10574 +         getsid, or view any process outside of the chroot.  If the sysctl
10575 +         option is enabled, a sysctl option with name "chroot_findtask" is
10576 +         created.
10577 +
10578 +config GRKERNSEC_CHROOT_NICE
10579 +       bool "Restrict priority changes"
10580 +       depends on GRKERNSEC_CHROOT
10581 +       help
10582 +         If you say Y here, processes inside a chroot will not be able to raise
10583 +         the priority of processes in the chroot, or alter the priority of
10584 +         processes outside the chroot.  This provides more security than simply
10585 +         removing CAP_SYS_NICE from the process' capability set.  If the
10586 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
10587 +         is created.
10588 +
10589 +config GRKERNSEC_CHROOT_SYSCTL
10590 +       bool "Deny sysctl writes"
10591 +       depends on GRKERNSEC_CHROOT
10592 +       help
10593 +         If you say Y here, an attacker in a chroot will not be able to
10594 +         write to sysctl entries, either by sysctl(2) or through a /proc
10595 +         interface.  It is strongly recommended that you say Y here. If the
10596 +         sysctl option is enabled, a sysctl option with name
10597 +         "chroot_deny_sysctl" is created.
10598 +
10599 +config GRKERNSEC_CHROOT_CAPS
10600 +       bool "Capability restrictions"
10601 +       depends on GRKERNSEC_CHROOT
10602 +       help
10603 +         If you say Y here, the capabilities on all root processes within a
10604 +         chroot jail will be lowered to stop module insertion, raw i/o,
10605 +         system and net admin tasks, rebooting the system, modifying immutable
10606 +         files, modifying IPC owned by another, and changing the system time.
10607 +         This is left an option because it can break some apps.  Disable this
10608 +         if your chrooted apps are having problems performing those kinds of
10609 +         tasks.  If the sysctl option is enabled, a sysctl option with
10610 +         name "chroot_caps" is created.
10611 +
10612 +endmenu
10613 +menu "Kernel Auditing"
10614 +depends on GRKERNSEC
10615 +
10616 +config GRKERNSEC_AUDIT_GROUP
10617 +       bool "Single group for auditing"
10618 +       help
10619 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
10620 +         will only operate on a group you specify.  This option is recommended
10621 +         if you only want to watch certain users instead of having a large
10622 +         amount of logs from the entire system.  If the sysctl option is enabled,
10623 +         a sysctl option with name "audit_group" is created.
10624 +
10625 +config GRKERNSEC_AUDIT_GID
10626 +       int "GID for auditing"
10627 +       depends on GRKERNSEC_AUDIT_GROUP
10628 +       default 1007
10629 +
10630 +config GRKERNSEC_EXECLOG
10631 +       bool "Exec logging"
10632 +       help
10633 +         If you say Y here, all execve() calls will be logged (since the
10634 +         other exec*() calls are frontends to execve(), all execution
10635 +         will be logged).  Useful for shell-servers that like to keep track
10636 +         of their users.  If the sysctl option is enabled, a sysctl option with
10637 +         name "exec_logging" is created.
10638 +         WARNING: This option when enabled will produce a LOT of logs, especially
10639 +         on an active system.
10640 +
10641 +config GRKERNSEC_RESLOG
10642 +       bool "Resource logging"
10643 +       help
10644 +         If you say Y here, all attempts to overstep resource limits will
10645 +         be logged with the resource name, the requested size, and the current
10646 +         limit.  It is highly recommended that you say Y here.  If the sysctl
10647 +         option is enabled, a sysctl option with name "resource_logging" is
10648 +         created.  If the RBAC system is enabled, the sysctl value is ignored.
10649 +
10650 +config GRKERNSEC_CHROOT_EXECLOG
10651 +       bool "Log execs within chroot"
10652 +       help
10653 +         If you say Y here, all executions inside a chroot jail will be logged
10654 +         to syslog.  This can cause a large amount of logs if certain
10655 +         applications (eg. djb's daemontools) are installed on the system, and
10656 +         is therefore left as an option.  If the sysctl option is enabled, a
10657 +         sysctl option with name "chroot_execlog" is created.
10658 +
10659 +config GRKERNSEC_AUDIT_CHDIR
10660 +       bool "Chdir logging"
10661 +       help
10662 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
10663 +         option is enabled, a sysctl option with name "audit_chdir" is created.
10664 +
10665 +config GRKERNSEC_AUDIT_MOUNT
10666 +       bool "(Un)Mount logging"
10667 +       help
10668 +         If you say Y here, all mounts and unmounts will be logged.  If the
10669 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
10670 +         created.
10671 +
10672 +config GRKERNSEC_AUDIT_IPC
10673 +       bool "IPC logging"
10674 +       help
10675 +         If you say Y here, creation and removal of message queues, semaphores,
10676 +         and shared memory will be logged.  If the sysctl option is enabled, a
10677 +         sysctl option with name "audit_ipc" is created.
10678 +
10679 +config GRKERNSEC_SIGNAL
10680 +       bool "Signal logging"
10681 +       help
10682 +         If you say Y here, certain important signals will be logged, such as
10683 +         SIGSEGV, which will as a result inform you of when a error in a program
10684 +         occurred, which in some cases could mean a possible exploit attempt.
10685 +         If the sysctl option is enabled, a sysctl option with name
10686 +         "signal_logging" is created.
10687 +
10688 +config GRKERNSEC_FORKFAIL
10689 +       bool "Fork failure logging"
10690 +       help
10691 +         If you say Y here, all failed fork() attempts will be logged.
10692 +         This could suggest a fork bomb, or someone attempting to overstep
10693 +         their process limit.  If the sysctl option is enabled, a sysctl option
10694 +         with name "forkfail_logging" is created.
10695 +
10696 +config GRKERNSEC_TIME
10697 +       bool "Time change logging"
10698 +       help
10699 +         If you say Y here, any changes of the system clock will be logged.
10700 +         If the sysctl option is enabled, a sysctl option with name
10701 +         "timechange_logging" is created.
10702 +
10703 +config GRKERNSEC_PROC_IPADDR
10704 +       bool "/proc/<pid>/ipaddr support"
10705 +       help
10706 +         If you say Y here, a new entry will be added to each /proc/<pid>
10707 +         directory that contains the IP address of the person using the task.
10708 +         The IP is carried across local TCP and AF_UNIX stream sockets.
10709 +         This information can be useful for IDS/IPSes to perform remote response
10710 +         to a local attack.  The entry is readable by only the owner of the
10711 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
10712 +         the RBAC system), and thus does not create privacy concerns.
10713 +
10714 +config GRKERNSEC_AUDIT_TEXTREL
10715 +       bool 'ELF text relocations logging (READ HELP)'
10716 +       depends on PAX_MPROTECT
10717 +       help
10718 +         If you say Y here, text relocations will be logged with the filename
10719 +         of the offending library or binary.  The purpose of the feature is
10720 +         to help Linux distribution developers get rid of libraries and
10721 +         binaries that need text relocations which hinder the future progress
10722 +         of PaX.  Only Linux distribution developers should say Y here, and
10723 +         never on a production machine, as this option creates an information
10724 +         leak that could aid an attacker in defeating the randomization of
10725 +         a single memory region.  If the sysctl option is enabled, a sysctl
10726 +         option with name "audit_textrel" is created.
10727 +
10728 +endmenu
10729 +
10730 +menu "Executable Protections"
10731 +depends on GRKERNSEC
10732 +
10733 +config GRKERNSEC_EXECVE
10734 +       bool "Enforce RLIMIT_NPROC on execs"
10735 +       help
10736 +         If you say Y here, users with a resource limit on processes will
10737 +         have the value checked during execve() calls.  The current system
10738 +         only checks the system limit during fork() calls.  If the sysctl option
10739 +         is enabled, a sysctl option with name "execve_limiting" is created.
10740 +
10741 +config GRKERNSEC_SHM
10742 +       bool "Destroy unused shared memory"
10743 +       depends on SYSVIPC
10744 +       help
10745 +         If you say Y here, shared memory will be destroyed when no one is
10746 +         attached to it.  Otherwise, resources involved with the shared
10747 +         memory can be used up and not be associated with any process (as the
10748 +         shared memory still exists, and the creating process has exited).  If
10749 +         the sysctl option is enabled, a sysctl option with name
10750 +         "destroy_unused_shm" is created.
10751 +
10752 +config GRKERNSEC_DMESG
10753 +       bool "Dmesg(8) restriction"
10754 +       help
10755 +         If you say Y here, non-root users will not be able to use dmesg(8)
10756 +         to view up to the last 4kb of messages in the kernel's log buffer.
10757 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
10758 +         created.
10759 +
10760 +config GRKERNSEC_RANDPID
10761 +       bool "Randomized PIDs"
10762 +       help
10763 +         If you say Y here, all PIDs created on the system will be
10764 +         pseudo-randomly generated.  This is extremely effective along
10765 +         with the /proc restrictions to disallow an attacker from guessing
10766 +         pids of daemons, etc.  PIDs are also used in some cases as part
10767 +         of a naming system for temporary files, so this option would keep
10768 +         those filenames from being predicted as well.  We also use code
10769 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
10770 +         option is enabled, a sysctl option with name "rand_pids" is created.
10771 +
10772 +config GRKERNSEC_TPE
10773 +       bool "Trusted Path Execution (TPE)"
10774 +       help
10775 +         If you say Y here, you will be able to choose a gid to add to the
10776 +         supplementary groups of users you want to mark as "untrusted."
10777 +         These users will not be able to execute any files that are not in
10778 +         root-owned directories writable only by root.  If the sysctl option
10779 +         is enabled, a sysctl option with name "tpe" is created.
10780 +
10781 +config GRKERNSEC_TPE_ALL
10782 +       bool "Partially restrict non-root users"
10783 +       depends on GRKERNSEC_TPE
10784 +       help
10785 +         If you say Y here, All non-root users other than the ones in the
10786 +         group specified in the main TPE option will only be allowed to
10787 +         execute files in directories they own that are not group or
10788 +         world-writable, or in directories owned by root and writable only by
10789 +         root.  If the sysctl option is enabled, a sysctl option with name
10790 +         "tpe_restrict_all" is created.
10791 +
10792 +config GRKERNSEC_TPE_INVERT
10793 +       bool "Invert GID option"
10794 +       depends on GRKERNSEC_TPE
10795 +       help
10796 +         If you say Y here, the group you specify in the TPE configuration will
10797 +         decide what group TPE restrictions will be *disabled* for.  This
10798 +         option is useful if you want TPE restrictions to be applied to most
10799 +         users on the system.
10800 +
10801 +config GRKERNSEC_TPE_GID
10802 +       int "GID for untrusted users"
10803 +       depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
10804 +       default 1005
10805 +       help
10806 +         If you have selected the "Invert GID option" above, setting this
10807 +         GID determines what group TPE restrictions will be *disabled* for.
10808 +         If you have not selected the "Invert GID option" above, setting this
10809 +         GID determines what group TPE restrictions will be *enabled* for.
10810 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
10811 +         is created.
10812 +
10813 +config GRKERNSEC_TPE_GID
10814 +       int "GID for trusted users"
10815 +       depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
10816 +       default 1005
10817 +       help
10818 +         If you have selected the "Invert GID option" above, setting this
10819 +         GID determines what group TPE restrictions will be *disabled* for.
10820 +         If you have not selected the "Invert GID option" above, setting this
10821 +         GID determines what group TPE restrictions will be *enabled* for.
10822 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
10823 +         is created.
10824 +
10825 +endmenu
10826 +menu "Network Protections"
10827 +depends on GRKERNSEC
10828 +
10829 +config GRKERNSEC_RANDNET
10830 +       bool "Larger entropy pools"
10831 +       help
10832 +         If you say Y here, the entropy pools used for many features of Linux
10833 +         and grsecurity will be doubled in size.  Since several grsecurity
10834 +         features use additional randomness, it is recommended that you say Y
10835 +         here.  Saying Y here has a similar effect as modifying
10836 +         /proc/sys/kernel/random/poolsize.
10837 +
10838 +config GRKERNSEC_SOCKET
10839 +       bool "Socket restrictions"
10840 +       help
10841 +         If you say Y here, you will be able to choose from several options.
10842 +         If you assign a GID on your system and add it to the supplementary
10843 +         groups of users you want to restrict socket access to, this patch
10844 +         will perform up to three things, based on the option(s) you choose.
10845 +
10846 +config GRKERNSEC_SOCKET_ALL
10847 +       bool "Deny any sockets to group"
10848 +       depends on GRKERNSEC_SOCKET
10849 +       help
10850 +         If you say Y here, you will be able to choose a GID of whose users will
10851 +         be unable to connect to other hosts from your machine or run server
10852 +         applications from your machine.  If the sysctl option is enabled, a
10853 +         sysctl option with name "socket_all" is created.
10854 +
10855 +config GRKERNSEC_SOCKET_ALL_GID
10856 +       int "GID to deny all sockets for"
10857 +       depends on GRKERNSEC_SOCKET_ALL
10858 +       default 1004
10859 +       help
10860 +         Here you can choose the GID to disable socket access for. Remember to
10861 +         add the users you want socket access disabled for to the GID
10862 +         specified here.  If the sysctl option is enabled, a sysctl option
10863 +         with name "socket_all_gid" is created.
10864 +
10865 +config GRKERNSEC_SOCKET_CLIENT
10866 +       bool "Deny client sockets to group"
10867 +       depends on GRKERNSEC_SOCKET
10868 +       help
10869 +         If you say Y here, you will be able to choose a GID of whose users will
10870 +         be unable to connect to other hosts from your machine, but will be
10871 +         able to run servers.  If this option is enabled, all users in the group
10872 +         you specify will have to use passive mode when initiating ftp transfers
10873 +         from the shell on your machine.  If the sysctl option is enabled, a
10874 +         sysctl option with name "socket_client" is created.
10875 +
10876 +config GRKERNSEC_SOCKET_CLIENT_GID
10877 +       int "GID to deny client sockets for"
10878 +       depends on GRKERNSEC_SOCKET_CLIENT
10879 +       default 1003
10880 +       help
10881 +         Here you can choose the GID to disable client socket access for.
10882 +         Remember to add the users you want client socket access disabled for to
10883 +         the GID specified here.  If the sysctl option is enabled, a sysctl
10884 +         option with name "socket_client_gid" is created.
10885 +
10886 +config GRKERNSEC_SOCKET_SERVER
10887 +       bool "Deny server sockets to group"
10888 +       depends on GRKERNSEC_SOCKET
10889 +       help
10890 +         If you say Y here, you will be able to choose a GID of whose users will
10891 +         be unable to run server applications from your machine.  If the sysctl
10892 +         option is enabled, a sysctl option with name "socket_server" is created.
10893 +
10894 +config GRKERNSEC_SOCKET_SERVER_GID
10895 +       int "GID to deny server sockets for"
10896 +       depends on GRKERNSEC_SOCKET_SERVER
10897 +       default 1002
10898 +       help
10899 +         Here you can choose the GID to disable server socket access for.
10900 +         Remember to add the users you want server socket access disabled for to
10901 +         the GID specified here.  If the sysctl option is enabled, a sysctl
10902 +         option with name "socket_server_gid" is created.
10903 +
10904 +endmenu
10905 +menu "Sysctl support"
10906 +depends on GRKERNSEC && SYSCTL
10907 +
10908 +config GRKERNSEC_SYSCTL
10909 +       bool "Sysctl support"
10910 +       help
10911 +         If you say Y here, you will be able to change the options that
10912 +         grsecurity runs with at bootup, without having to recompile your
10913 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
10914 +         to enable (1) or disable (0) various features.  All the sysctl entries
10915 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
10916 +         All features enabled in the kernel configuration are disabled at boot
10917 +         if you do not say Y to the "Turn on features by default" option.
10918 +         All options should be set at startup, and the grsec_lock entry should
10919 +         be set to a non-zero value after all the options are set.
10920 +         *THIS IS EXTREMELY IMPORTANT*
10921 +
10922 +config GRKERNSEC_SYSCTL_ON
10923 +       bool "Turn on features by default"
10924 +       depends on GRKERNSEC_SYSCTL
10925 +       help
10926 +         If you say Y here, instead of having all features enabled in the
10927 +         kernel configuration disabled at boot time, the features will be
10928 +         enabled at boot time.  It is recommended you say Y here unless
10929 +         there is some reason you would want all sysctl-tunable features to
10930 +         be disabled by default.  As mentioned elsewhere, it is important
10931 +         to enable the grsec_lock entry once you have finished modifying
10932 +         the sysctl entries.
10933 +
10934 +endmenu
10935 +menu "Logging Options"
10936 +depends on GRKERNSEC
10937 +
10938 +config GRKERNSEC_FLOODTIME
10939 +       int "Seconds in between log messages (minimum)"
10940 +       default 10
10941 +       help
10942 +         This option allows you to enforce the number of seconds between
10943 +         grsecurity log messages.  The default should be suitable for most
10944 +         people, however, if you choose to change it, choose a value small enough
10945 +         to allow informative logs to be produced, but large enough to
10946 +         prevent flooding.
10947 +
10948 +config GRKERNSEC_FLOODBURST
10949 +       int "Number of messages in a burst (maximum)"
10950 +       default 4
10951 +       help
10952 +         This option allows you to choose the maximum number of messages allowed
10953 +         within the flood time interval you chose in a separate option.  The
10954 +         default should be suitable for most people, however if you find that
10955 +         many of your logs are being interpreted as flooding, you may want to
10956 +         raise this value.
10957 +
10958 +endmenu
10959 +
10960 +endmenu
10961 diff -urNp linux-2.6.17.7/grsecurity/Makefile linux-2.6.17.7/grsecurity/Makefile
10962 --- linux-2.6.17.7/grsecurity/Makefile  1969-12-31 19:00:00.000000000 -0500
10963 +++ linux-2.6.17.7/grsecurity/Makefile  2006-08-01 20:29:47.000000000 -0400
10964 @@ -0,0 +1,20 @@
10965 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
10966 +# during 2001-2005 it has been completely redesigned by Brad Spengler
10967 +# into an RBAC system
10968 +#
10969 +# All code in this directory and various hooks inserted throughout the kernel
10970 +# are copyright Brad Spengler, and released under the GPL v2 or higher
10971 +
10972 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
10973 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
10974 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
10975 +
10976 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
10977 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
10978 +       gracl_learn.o grsec_log.o
10979 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
10980 +
10981 +ifndef CONFIG_GRKERNSEC
10982 +obj-y += grsec_disabled.o
10983 +endif
10984 +
10985 diff -urNp linux-2.6.17.7/grsecurity/gracl.c linux-2.6.17.7/grsecurity/gracl.c
10986 --- linux-2.6.17.7/grsecurity/gracl.c   1969-12-31 19:00:00.000000000 -0500
10987 +++ linux-2.6.17.7/grsecurity/gracl.c   2006-08-01 20:29:47.000000000 -0400
10988 @@ -0,0 +1,3547 @@
10989 +#include <linux/kernel.h>
10990 +#include <linux/module.h>
10991 +#include <linux/sched.h>
10992 +#include <linux/mm.h>
10993 +#include <linux/file.h>
10994 +#include <linux/fs.h>
10995 +#include <linux/namei.h>
10996 +#include <linux/mount.h>
10997 +#include <linux/tty.h>
10998 +#include <linux/proc_fs.h>
10999 +#include <linux/smp_lock.h>
11000 +#include <linux/slab.h>
11001 +#include <linux/vmalloc.h>
11002 +#include <linux/types.h>
11003 +#include <linux/capability.h>
11004 +#include <linux/sysctl.h>
11005 +#include <linux/netdevice.h>
11006 +#include <linux/ptrace.h>
11007 +#include <linux/gracl.h>
11008 +#include <linux/gralloc.h>
11009 +#include <linux/grsecurity.h>
11010 +#include <linux/grinternal.h>
11011 +#include <linux/percpu.h>
11012 +
11013 +#include <asm/uaccess.h>
11014 +#include <asm/errno.h>
11015 +#include <asm/mman.h>
11016 +
11017 +static struct acl_role_db acl_role_set;
11018 +static struct name_db name_set;
11019 +static struct inodev_db inodev_set;
11020 +
11021 +/* for keeping track of userspace pointers used for subjects, so we
11022 +   can share references in the kernel as well
11023 +*/
11024 +
11025 +static struct dentry *real_root;
11026 +static struct vfsmount *real_root_mnt;
11027 +
11028 +static struct acl_subj_map_db subj_map_set;
11029 +
11030 +static struct acl_role_label *default_role;
11031 +
11032 +static u16 acl_sp_role_value;
11033 +
11034 +extern char *gr_shared_page[4];
11035 +static DECLARE_MUTEX(gr_dev_sem);
11036 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
11037 +
11038 +struct gr_arg *gr_usermode;
11039 +
11040 +static unsigned int gr_status = GR_STATUS_INIT;
11041 +
11042 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
11043 +extern void gr_clear_learn_entries(void);
11044 +
11045 +#ifdef CONFIG_GRKERNSEC_RESLOG
11046 +extern void gr_log_resource(const struct task_struct *task,
11047 +                           const int res, const unsigned long wanted, const int gt);
11048 +#endif
11049 +
11050 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
11051 +                        struct dentry *root, struct vfsmount *rootmnt,
11052 +                        char *buffer, int buflen);
11053 +
11054 +unsigned char *gr_system_salt;
11055 +unsigned char *gr_system_sum;
11056 +
11057 +static struct sprole_pw **acl_special_roles = NULL;
11058 +static __u16 num_sprole_pws = 0;
11059 +
11060 +static struct acl_role_label *kernel_role = NULL;
11061 +
11062 +static unsigned int gr_auth_attempts = 0;
11063 +static unsigned long gr_auth_expires = 0UL;
11064 +
11065 +extern struct vfsmount *sock_mnt;
11066 +extern struct vfsmount *pipe_mnt;
11067 +extern struct vfsmount *shm_mnt;
11068 +static struct acl_object_label *fakefs_obj;
11069 +
11070 +extern int gr_init_uidset(void);
11071 +extern void gr_free_uidset(void);
11072 +extern void gr_remove_uid(uid_t uid);
11073 +extern int gr_find_uid(uid_t uid);
11074 +
11075 +__inline__ int
11076 +gr_acl_is_enabled(void)
11077 +{
11078 +       return (gr_status & GR_READY);
11079 +}
11080 +
11081 +char gr_roletype_to_char(void)
11082 +{
11083 +       switch (current->role->roletype &
11084 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
11085 +                GR_ROLE_SPECIAL)) {
11086 +       case GR_ROLE_DEFAULT:
11087 +               return 'D';
11088 +       case GR_ROLE_USER:
11089 +               return 'U';
11090 +       case GR_ROLE_GROUP:
11091 +               return 'G';
11092 +       case GR_ROLE_SPECIAL:
11093 +               return 'S';
11094 +       }
11095 +
11096 +       return 'X';
11097 +}
11098 +
11099 +__inline__ int
11100 +gr_acl_tpe_check(void)
11101 +{
11102 +       if (unlikely(!(gr_status & GR_READY)))
11103 +               return 0;
11104 +       if (current->role->roletype & GR_ROLE_TPE)
11105 +               return 1;
11106 +       else
11107 +               return 0;
11108 +}
11109 +
11110 +int
11111 +gr_handle_rawio(const struct inode *inode)
11112 +{
11113 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11114 +       if (inode && S_ISBLK(inode->i_mode) &&
11115 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
11116 +           !capable(CAP_SYS_RAWIO))
11117 +               return 1;
11118 +#endif
11119 +       return 0;
11120 +}
11121 +
11122 +static int
11123 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
11124 +{
11125 +       int i;
11126 +       unsigned long *l1;
11127 +       unsigned long *l2;
11128 +       unsigned char *c1;
11129 +       unsigned char *c2;
11130 +       int num_longs;
11131 +
11132 +       if (likely(lena != lenb))
11133 +               return 0;
11134 +
11135 +       l1 = (unsigned long *)a;
11136 +       l2 = (unsigned long *)b;
11137 +
11138 +       num_longs = lena / sizeof(unsigned long);
11139 +
11140 +       for (i = num_longs; i--; l1++, l2++) {
11141 +               if (unlikely(*l1 != *l2))
11142 +                       return 0;
11143 +       }
11144 +
11145 +       c1 = (unsigned char *) l1;
11146 +       c2 = (unsigned char *) l2;
11147 +
11148 +       i = lena - (num_longs * sizeof(unsigned long)); 
11149 +
11150 +       for (; i--; c1++, c2++) {
11151 +               if (unlikely(*c1 != *c2))
11152 +                       return 0;
11153 +       }
11154 +
11155 +       return 1;
11156 +}
11157 +               
11158 +static char *
11159 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
11160 +              struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
11161 +{
11162 +       char *end = buf + buflen;
11163 +       char *retval;
11164 +       int namelen = 0;
11165 +
11166 +       *--end = '\0';
11167 +
11168 +       retval = end - 1;
11169 +       *retval = '/';
11170 +
11171 +       if (dentry == root && vfsmnt == rootmnt)
11172 +               return retval;
11173 +       if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
11174 +               namelen = strlen(dentry->d_name.name);
11175 +               buflen -= namelen;
11176 +               if (buflen < 2)
11177 +                       goto err;
11178 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
11179 +                       buflen--;
11180 +       }
11181 +
11182 +       retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
11183 +       if (unlikely(IS_ERR(retval)))
11184 +err:
11185 +               retval = strcpy(buf, "<path too long>");
11186 +       else if (namelen != 0) {
11187 +               end = buf + buflen - 1; // accounts for null termination
11188 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
11189 +                       *end++ = '/'; // accounted for above with buflen--
11190 +               memcpy(end, dentry->d_name.name, namelen);
11191 +       }
11192 +
11193 +       return retval;
11194 +}
11195 +
11196 +static char *
11197 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
11198 +               char *buf, int buflen)
11199 +{
11200 +       char *res;
11201 +
11202 +       /* we can use real_root, real_root_mnt, because this is only called
11203 +          by the RBAC system */
11204 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
11205 +
11206 +       return res;
11207 +}
11208 +
11209 +static char *
11210 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
11211 +           char *buf, int buflen)
11212 +{
11213 +       char *res;
11214 +       struct dentry *root;
11215 +       struct vfsmount *rootmnt;
11216 +
11217 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
11218 +       read_lock(&child_reaper->fs->lock);
11219 +       root = dget(child_reaper->fs->root);
11220 +       rootmnt = mntget(child_reaper->fs->rootmnt);
11221 +       read_unlock(&child_reaper->fs->lock);
11222 +
11223 +       spin_lock(&dcache_lock);
11224 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
11225 +       spin_unlock(&dcache_lock);
11226 +
11227 +       dput(root);
11228 +       mntput(rootmnt);
11229 +       return res;
11230 +}
11231 +
11232 +static char *
11233 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
11234 +{
11235 +       char *ret;
11236 +       spin_lock(&dcache_lock);
11237 +       ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
11238 +                            PAGE_SIZE);
11239 +       spin_unlock(&dcache_lock);
11240 +       return ret;
11241 +}
11242 +
11243 +char *
11244 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
11245 +{
11246 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
11247 +                            PAGE_SIZE);
11248 +}
11249 +
11250 +char *
11251 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
11252 +{
11253 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
11254 +                          PAGE_SIZE);
11255 +}
11256 +
11257 +char *
11258 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
11259 +{
11260 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
11261 +                          PAGE_SIZE);
11262 +}
11263 +
11264 +char *
11265 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
11266 +{
11267 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
11268 +                          PAGE_SIZE);
11269 +}
11270 +
11271 +char *
11272 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
11273 +{
11274 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
11275 +                          PAGE_SIZE);
11276 +}
11277 +
11278 +__inline__ __u32
11279 +to_gr_audit(const __u32 reqmode)
11280 +{
11281 +       /* masks off auditable permission flags, then shifts them to create
11282 +          auditing flags, and adds the special case of append auditing if
11283 +          we're requesting write */
11284 +       return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
11285 +}
11286 +
11287 +struct acl_subject_label *
11288 +lookup_subject_map(const struct acl_subject_label *userp)
11289 +{
11290 +       unsigned int index = shash(userp, subj_map_set.s_size);
11291 +       struct subject_map *match;
11292 +
11293 +       match = subj_map_set.s_hash[index];
11294 +
11295 +       while (match && match->user != userp)
11296 +               match = match->next;
11297 +
11298 +       if (match != NULL)
11299 +               return match->kernel;
11300 +       else
11301 +               return NULL;
11302 +}
11303 +
11304 +static void
11305 +insert_subj_map_entry(struct subject_map *subjmap)
11306 +{
11307 +       unsigned int index = shash(subjmap->user, subj_map_set.s_size);
11308 +       struct subject_map **curr;
11309 +
11310 +       subjmap->prev = NULL;
11311 +
11312 +       curr = &subj_map_set.s_hash[index];
11313 +       if (*curr != NULL)
11314 +               (*curr)->prev = subjmap;
11315 +
11316 +       subjmap->next = *curr;
11317 +       *curr = subjmap;
11318 +
11319 +       return;
11320 +}
11321 +
11322 +static struct acl_role_label *
11323 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
11324 +                     const gid_t gid)
11325 +{
11326 +       unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
11327 +       struct acl_role_label *match;
11328 +       struct role_allowed_ip *ipp;
11329 +       unsigned int x;
11330 +
11331 +       match = acl_role_set.r_hash[index];
11332 +
11333 +       while (match) {
11334 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
11335 +                       for (x = 0; x < match->domain_child_num; x++) {
11336 +                               if (match->domain_children[x] == uid)
11337 +                                       goto found;
11338 +                       }
11339 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
11340 +                       break;
11341 +               match = match->next;
11342 +       }
11343 +found:
11344 +       if (match == NULL) {
11345 +             try_group:
11346 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
11347 +               match = acl_role_set.r_hash[index];
11348 +
11349 +               while (match) {
11350 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
11351 +                               for (x = 0; x < match->domain_child_num; x++) {
11352 +                                       if (match->domain_children[x] == gid)
11353 +                                               goto found2;
11354 +                               }
11355 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
11356 +                               break;
11357 +                       match = match->next;
11358 +               }
11359 +found2:
11360 +               if (match == NULL)
11361 +                       match = default_role;
11362 +               if (match->allowed_ips == NULL)
11363 +                       return match;
11364 +               else {
11365 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
11366 +                               if (likely
11367 +                                   ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
11368 +                                    (ntohl(ipp->addr) & ipp->netmask)))
11369 +                                       return match;
11370 +                       }
11371 +                       match = default_role;
11372 +               }
11373 +       } else if (match->allowed_ips == NULL) {
11374 +               return match;
11375 +       } else {
11376 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
11377 +                       if (likely
11378 +                           ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
11379 +                            (ntohl(ipp->addr) & ipp->netmask)))
11380 +                               return match;
11381 +               }
11382 +               goto try_group;
11383 +       }
11384 +
11385 +       return match;
11386 +}
11387 +
11388 +struct acl_subject_label *
11389 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
11390 +                     const struct acl_role_label *role)
11391 +{
11392 +       unsigned int index = fhash(ino, dev, role->subj_hash_size);
11393 +       struct acl_subject_label *match;
11394 +
11395 +       match = role->subj_hash[index];
11396 +
11397 +       while (match && (match->inode != ino || match->device != dev ||
11398 +              (match->mode & GR_DELETED))) {
11399 +               match = match->next;
11400 +       }
11401 +
11402 +       if (match && !(match->mode & GR_DELETED))
11403 +               return match;
11404 +       else
11405 +               return NULL;
11406 +}
11407 +
11408 +static struct acl_object_label *
11409 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
11410 +                    const struct acl_subject_label *subj)
11411 +{
11412 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
11413 +       struct acl_object_label *match;
11414 +
11415 +       match = subj->obj_hash[index];
11416 +
11417 +       while (match && (match->inode != ino || match->device != dev ||
11418 +              (match->mode & GR_DELETED))) {
11419 +               match = match->next;
11420 +       }
11421 +
11422 +       if (match && !(match->mode & GR_DELETED))
11423 +               return match;
11424 +       else
11425 +               return NULL;
11426 +}
11427 +
11428 +static struct acl_object_label *
11429 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
11430 +                    const struct acl_subject_label *subj)
11431 +{
11432 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
11433 +       struct acl_object_label *match;
11434 +
11435 +       match = subj->obj_hash[index];
11436 +
11437 +       while (match && (match->inode != ino || match->device != dev ||
11438 +              !(match->mode & GR_DELETED))) {
11439 +               match = match->next;
11440 +       }
11441 +
11442 +       if (match && (match->mode & GR_DELETED))
11443 +               return match;
11444 +
11445 +       match = subj->obj_hash[index];
11446 +
11447 +       while (match && (match->inode != ino || match->device != dev ||
11448 +              (match->mode & GR_DELETED))) {
11449 +               match = match->next;
11450 +       }
11451 +
11452 +       if (match && !(match->mode & GR_DELETED))
11453 +               return match;
11454 +       else
11455 +               return NULL;
11456 +}
11457 +
11458 +static struct name_entry *
11459 +lookup_name_entry(const char *name)
11460 +{
11461 +       unsigned int len = strlen(name);
11462 +       unsigned int key = full_name_hash(name, len);
11463 +       unsigned int index = key % name_set.n_size;
11464 +       struct name_entry *match;
11465 +
11466 +       match = name_set.n_hash[index];
11467 +
11468 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
11469 +               match = match->next;
11470 +
11471 +       return match;
11472 +}
11473 +
11474 +static struct inodev_entry *
11475 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
11476 +{
11477 +       unsigned int index = fhash(ino, dev, inodev_set.i_size);
11478 +       struct inodev_entry *match;
11479 +
11480 +       match = inodev_set.i_hash[index];
11481 +
11482 +       while (match && (match->nentry->inode != ino || match->nentry->device != dev))
11483 +               match = match->next;
11484 +
11485 +       return match;
11486 +}
11487 +
11488 +static void
11489 +insert_inodev_entry(struct inodev_entry *entry)
11490 +{
11491 +       unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
11492 +                                   inodev_set.i_size);
11493 +       struct inodev_entry **curr;
11494 +
11495 +       entry->prev = NULL;
11496 +
11497 +       curr = &inodev_set.i_hash[index];
11498 +       if (*curr != NULL)
11499 +               (*curr)->prev = entry;
11500 +       
11501 +       entry->next = *curr;
11502 +       *curr = entry;
11503 +
11504 +       return;
11505 +}
11506 +
11507 +static void
11508 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
11509 +{
11510 +       unsigned int index =
11511 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
11512 +       struct acl_role_label **curr;
11513 +
11514 +       role->prev = NULL;
11515 +
11516 +       curr = &acl_role_set.r_hash[index];
11517 +       if (*curr != NULL)
11518 +               (*curr)->prev = role;
11519 +
11520 +       role->next = *curr;
11521 +       *curr = role;
11522 +
11523 +       return;
11524 +}
11525 +
11526 +static void
11527 +insert_acl_role_label(struct acl_role_label *role)
11528 +{
11529 +       int i;
11530 +
11531 +       if (role->roletype & GR_ROLE_DOMAIN) {
11532 +               for (i = 0; i < role->domain_child_num; i++)
11533 +                       __insert_acl_role_label(role, role->domain_children[i]);
11534 +       } else
11535 +               __insert_acl_role_label(role, role->uidgid);
11536 +}
11537 +                                       
11538 +static int
11539 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
11540 +{
11541 +       struct name_entry **curr, *nentry;
11542 +       struct inodev_entry *ientry;
11543 +       unsigned int len = strlen(name);
11544 +       unsigned int key = full_name_hash(name, len);
11545 +       unsigned int index = key % name_set.n_size;
11546 +
11547 +       curr = &name_set.n_hash[index];
11548 +
11549 +       while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
11550 +               curr = &((*curr)->next);
11551 +
11552 +       if (*curr != NULL)
11553 +               return 1;
11554 +
11555 +       nentry = acl_alloc(sizeof (struct name_entry));
11556 +       if (nentry == NULL)
11557 +               return 0;
11558 +       ientry = acl_alloc(sizeof (struct inodev_entry));
11559 +       if (ientry == NULL)
11560 +               return 0;
11561 +       ientry->nentry = nentry;
11562 +
11563 +       nentry->key = key;
11564 +       nentry->name = name;
11565 +       nentry->inode = inode;
11566 +       nentry->device = device;
11567 +       nentry->len = len;
11568 +
11569 +       nentry->prev = NULL;
11570 +       curr = &name_set.n_hash[index];
11571 +       if (*curr != NULL)
11572 +               (*curr)->prev = nentry;
11573 +       nentry->next = *curr;
11574 +       *curr = nentry;
11575 +
11576 +       /* insert us into the table searchable by inode/dev */
11577 +       insert_inodev_entry(ientry);
11578 +
11579 +       return 1;
11580 +}
11581 +
11582 +static void
11583 +insert_acl_obj_label(struct acl_object_label *obj,
11584 +                    struct acl_subject_label *subj)
11585 +{
11586 +       unsigned int index =
11587 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
11588 +       struct acl_object_label **curr;
11589 +
11590 +       
11591 +       obj->prev = NULL;
11592 +
11593 +       curr = &subj->obj_hash[index];
11594 +       if (*curr != NULL)
11595 +               (*curr)->prev = obj;
11596 +
11597 +       obj->next = *curr;
11598 +       *curr = obj;
11599 +
11600 +       return;
11601 +}
11602 +
11603 +static void
11604 +insert_acl_subj_label(struct acl_subject_label *obj,
11605 +                     struct acl_role_label *role)
11606 +{
11607 +       unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
11608 +       struct acl_subject_label **curr;
11609 +
11610 +       obj->prev = NULL;
11611 +
11612 +       curr = &role->subj_hash[index];
11613 +       if (*curr != NULL)
11614 +               (*curr)->prev = obj;
11615 +
11616 +       obj->next = *curr;
11617 +       *curr = obj;
11618 +
11619 +       return;
11620 +}
11621 +
11622 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
11623 +
11624 +static void *
11625 +create_table(__u32 * len, int elementsize)
11626 +{
11627 +       unsigned int table_sizes[] = {
11628 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
11629 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
11630 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
11631 +               268435399, 536870909, 1073741789, 2147483647
11632 +       };
11633 +       void *newtable = NULL;
11634 +       unsigned int pwr = 0;
11635 +
11636 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
11637 +              table_sizes[pwr] <= *len)
11638 +               pwr++;
11639 +
11640 +       if (table_sizes[pwr] <= *len)
11641 +               return newtable;
11642 +
11643 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
11644 +               newtable =
11645 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
11646 +       else
11647 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
11648 +
11649 +       *len = table_sizes[pwr];
11650 +
11651 +       return newtable;
11652 +}
11653 +
11654 +static int
11655 +init_variables(const struct gr_arg *arg)
11656 +{
11657 +       unsigned int stacksize;
11658 +
11659 +       subj_map_set.s_size = arg->role_db.num_subjects;
11660 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
11661 +       name_set.n_size = arg->role_db.num_objects;
11662 +       inodev_set.i_size = arg->role_db.num_objects;
11663 +
11664 +       if (!subj_map_set.s_size || !acl_role_set.r_size ||
11665 +           !name_set.n_size || !inodev_set.i_size)
11666 +               return 1;
11667 +
11668 +       if (!gr_init_uidset())
11669 +               return 1;
11670 +
11671 +       /* set up the stack that holds allocation info */
11672 +
11673 +       stacksize = arg->role_db.num_pointers + 5;
11674 +
11675 +       if (!acl_alloc_stack_init(stacksize))
11676 +               return 1;
11677 +
11678 +       /* grab reference for the real root dentry and vfsmount */
11679 +       read_lock(&child_reaper->fs->lock);
11680 +       real_root_mnt = mntget(child_reaper->fs->rootmnt);
11681 +       real_root = dget(child_reaper->fs->root);
11682 +       read_unlock(&child_reaper->fs->lock);
11683 +       
11684 +       fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
11685 +       if (fakefs_obj == NULL)
11686 +               return 1;
11687 +       fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
11688 +
11689 +       subj_map_set.s_hash =
11690 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
11691 +       acl_role_set.r_hash =
11692 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
11693 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
11694 +       inodev_set.i_hash =
11695 +           (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
11696 +
11697 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
11698 +           !name_set.n_hash || !inodev_set.i_hash)
11699 +               return 1;
11700 +
11701 +       memset(subj_map_set.s_hash, 0,
11702 +              sizeof(struct subject_map *) * subj_map_set.s_size);
11703 +       memset(acl_role_set.r_hash, 0,
11704 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
11705 +       memset(name_set.n_hash, 0,
11706 +              sizeof (struct name_entry *) * name_set.n_size);
11707 +       memset(inodev_set.i_hash, 0,
11708 +              sizeof (struct inodev_entry *) * inodev_set.i_size);
11709 +
11710 +       return 0;
11711 +}
11712 +
11713 +/* free information not needed after startup
11714 +   currently contains user->kernel pointer mappings for subjects
11715 +*/
11716 +
11717 +static void
11718 +free_init_variables(void)
11719 +{
11720 +       __u32 i;
11721 +
11722 +       if (subj_map_set.s_hash) {
11723 +               for (i = 0; i < subj_map_set.s_size; i++) {
11724 +                       if (subj_map_set.s_hash[i]) {
11725 +                               kfree(subj_map_set.s_hash[i]);
11726 +                               subj_map_set.s_hash[i] = NULL;
11727 +                       }
11728 +               }
11729 +
11730 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
11731 +                   PAGE_SIZE)
11732 +                       kfree(subj_map_set.s_hash);
11733 +               else
11734 +                       vfree(subj_map_set.s_hash);
11735 +       }
11736 +
11737 +       return;
11738 +}
11739 +
11740 +static void
11741 +free_variables(void)
11742 +{
11743 +       struct acl_subject_label *s;
11744 +       struct acl_role_label *r;
11745 +       struct task_struct *task, *task2;
11746 +       unsigned int i, x;
11747 +
11748 +       gr_clear_learn_entries();
11749 +
11750 +       read_lock(&tasklist_lock);
11751 +       do_each_thread(task2, task) {
11752 +               task->acl_sp_role = 0;
11753 +               task->acl_role_id = 0;
11754 +               task->acl = NULL;
11755 +               task->role = NULL;
11756 +       } while_each_thread(task2, task);
11757 +       read_unlock(&tasklist_lock);
11758 +
11759 +       /* release the reference to the real root dentry and vfsmount */
11760 +       if (real_root)
11761 +               dput(real_root);
11762 +       real_root = NULL;
11763 +       if (real_root_mnt)
11764 +               mntput(real_root_mnt);
11765 +       real_root_mnt = NULL;
11766 +
11767 +       /* free all object hash tables */
11768 +
11769 +       FOR_EACH_ROLE_START(r, i)
11770 +               if (r->subj_hash == NULL)
11771 +                       break;
11772 +               FOR_EACH_SUBJECT_START(r, s, x)
11773 +                       if (s->obj_hash == NULL)
11774 +                               break;
11775 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
11776 +                               kfree(s->obj_hash);
11777 +                       else
11778 +                               vfree(s->obj_hash);
11779 +               FOR_EACH_SUBJECT_END(s, x)
11780 +               FOR_EACH_NESTED_SUBJECT_START(r, s)
11781 +                       if (s->obj_hash == NULL)
11782 +                               break;
11783 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
11784 +                               kfree(s->obj_hash);
11785 +                       else
11786 +                               vfree(s->obj_hash);
11787 +               FOR_EACH_NESTED_SUBJECT_END(s)
11788 +               if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
11789 +                       kfree(r->subj_hash);
11790 +               else
11791 +                       vfree(r->subj_hash);
11792 +               r->subj_hash = NULL;
11793 +       FOR_EACH_ROLE_END(r,i)
11794 +
11795 +       acl_free_all();
11796 +
11797 +       if (acl_role_set.r_hash) {
11798 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
11799 +                   PAGE_SIZE)
11800 +                       kfree(acl_role_set.r_hash);
11801 +               else
11802 +                       vfree(acl_role_set.r_hash);
11803 +       }
11804 +       if (name_set.n_hash) {
11805 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
11806 +                   PAGE_SIZE)
11807 +                       kfree(name_set.n_hash);
11808 +               else
11809 +                       vfree(name_set.n_hash);
11810 +       }
11811 +
11812 +       if (inodev_set.i_hash) {
11813 +               if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
11814 +                   PAGE_SIZE)
11815 +                       kfree(inodev_set.i_hash);
11816 +               else
11817 +                       vfree(inodev_set.i_hash);
11818 +       }
11819 +
11820 +       gr_free_uidset();
11821 +
11822 +       memset(&name_set, 0, sizeof (struct name_db));
11823 +       memset(&inodev_set, 0, sizeof (struct inodev_db));
11824 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
11825 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
11826 +
11827 +       default_role = NULL;
11828 +
11829 +       return;
11830 +}
11831 +
11832 +static __u32
11833 +count_user_objs(struct acl_object_label *userp)
11834 +{
11835 +       struct acl_object_label o_tmp;
11836 +       __u32 num = 0;
11837 +
11838 +       while (userp) {
11839 +               if (copy_from_user(&o_tmp, userp,
11840 +                                  sizeof (struct acl_object_label)))
11841 +                       break;
11842 +
11843 +               userp = o_tmp.prev;
11844 +               num++;
11845 +       }
11846 +
11847 +       return num;
11848 +}
11849 +
11850 +static struct acl_subject_label *
11851 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
11852 +
11853 +static int
11854 +copy_user_glob(struct acl_object_label *obj)
11855 +{
11856 +       struct acl_object_label *g_tmp, **guser;
11857 +       unsigned int len;
11858 +       char *tmp;
11859 +
11860 +       if (obj->globbed == NULL)
11861 +               return 0;
11862 +
11863 +       guser = &obj->globbed;
11864 +       while (*guser) {
11865 +               g_tmp = (struct acl_object_label *)
11866 +                       acl_alloc(sizeof (struct acl_object_label));
11867 +               if (g_tmp == NULL)
11868 +                       return -ENOMEM;
11869 +
11870 +               if (copy_from_user(g_tmp, *guser,
11871 +                                  sizeof (struct acl_object_label)))
11872 +                       return -EFAULT;
11873 +
11874 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
11875 +
11876 +               if (!len || len >= PATH_MAX)
11877 +                       return -EINVAL;
11878 +
11879 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
11880 +                       return -ENOMEM;
11881 +
11882 +               if (copy_from_user(tmp, g_tmp->filename, len))
11883 +                       return -EFAULT;
11884 +
11885 +               g_tmp->filename = tmp;
11886 +
11887 +               *guser = g_tmp;
11888 +               guser = &(g_tmp->next);
11889 +       }
11890 +
11891 +       return 0;
11892 +}
11893 +
11894 +static int
11895 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
11896 +              struct acl_role_label *role)
11897 +{
11898 +       struct acl_object_label *o_tmp;
11899 +       unsigned int len;
11900 +       int ret;
11901 +       char *tmp;
11902 +
11903 +       while (userp) {
11904 +               if ((o_tmp = (struct acl_object_label *)
11905 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
11906 +                       return -ENOMEM;
11907 +
11908 +               if (copy_from_user(o_tmp, userp,
11909 +                                  sizeof (struct acl_object_label)))
11910 +                       return -EFAULT;
11911 +
11912 +               userp = o_tmp->prev;
11913 +
11914 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
11915 +
11916 +               if (!len || len >= PATH_MAX)
11917 +                       return -EINVAL;
11918 +
11919 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
11920 +                       return -ENOMEM;
11921 +
11922 +               if (copy_from_user(tmp, o_tmp->filename, len))
11923 +                       return -EFAULT;
11924 +
11925 +               o_tmp->filename = tmp;
11926 +
11927 +               insert_acl_obj_label(o_tmp, subj);
11928 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
11929 +                                      o_tmp->device))
11930 +                       return -ENOMEM;
11931 +
11932 +               ret = copy_user_glob(o_tmp);
11933 +               if (ret)
11934 +                       return ret;
11935 +
11936 +               if (o_tmp->nested) {
11937 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
11938 +                       if (IS_ERR(o_tmp->nested))
11939 +                               return PTR_ERR(o_tmp->nested);
11940 +
11941 +                       /* insert into nested subject list */
11942 +                       o_tmp->nested->next = role->hash->first;
11943 +                       role->hash->first = o_tmp->nested;
11944 +               }
11945 +       }
11946 +
11947 +       return 0;
11948 +}
11949 +
11950 +static __u32
11951 +count_user_subjs(struct acl_subject_label *userp)
11952 +{
11953 +       struct acl_subject_label s_tmp;
11954 +       __u32 num = 0;
11955 +
11956 +       while (userp) {
11957 +               if (copy_from_user(&s_tmp, userp,
11958 +                                  sizeof (struct acl_subject_label)))
11959 +                       break;
11960 +
11961 +               userp = s_tmp.prev;
11962 +               /* do not count nested subjects against this count, since
11963 +                  they are not included in the hash table, but are
11964 +                  attached to objects.  We have already counted
11965 +                  the subjects in userspace for the allocation 
11966 +                  stack
11967 +               */
11968 +               if (!(s_tmp.mode & GR_NESTED))
11969 +                       num++;
11970 +       }
11971 +
11972 +       return num;
11973 +}
11974 +
11975 +static int
11976 +copy_user_allowedips(struct acl_role_label *rolep)
11977 +{
11978 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
11979 +
11980 +       ruserip = rolep->allowed_ips;
11981 +
11982 +       while (ruserip) {
11983 +               rlast = rtmp;
11984 +
11985 +               if ((rtmp = (struct role_allowed_ip *)
11986 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
11987 +                       return -ENOMEM;
11988 +
11989 +               if (copy_from_user(rtmp, ruserip,
11990 +                                  sizeof (struct role_allowed_ip)))
11991 +                       return -EFAULT;
11992 +
11993 +               ruserip = rtmp->prev;
11994 +
11995 +               if (!rlast) {
11996 +                       rtmp->prev = NULL;
11997 +                       rolep->allowed_ips = rtmp;
11998 +               } else {
11999 +                       rlast->next = rtmp;
12000 +                       rtmp->prev = rlast;
12001 +               }
12002 +
12003 +               if (!ruserip)
12004 +                       rtmp->next = NULL;
12005 +       }
12006 +
12007 +       return 0;
12008 +}
12009 +
12010 +static int
12011 +copy_user_transitions(struct acl_role_label *rolep)
12012 +{
12013 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
12014 +       
12015 +       unsigned int len;
12016 +       char *tmp;
12017 +
12018 +       rusertp = rolep->transitions;
12019 +
12020 +       while (rusertp) {
12021 +               rlast = rtmp;
12022 +
12023 +               if ((rtmp = (struct role_transition *)
12024 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
12025 +                       return -ENOMEM;
12026 +
12027 +               if (copy_from_user(rtmp, rusertp,
12028 +                                  sizeof (struct role_transition)))
12029 +                       return -EFAULT;
12030 +
12031 +               rusertp = rtmp->prev;
12032 +
12033 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
12034 +
12035 +               if (!len || len >= GR_SPROLE_LEN)
12036 +                       return -EINVAL;
12037 +
12038 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
12039 +                       return -ENOMEM;
12040 +
12041 +               if (copy_from_user(tmp, rtmp->rolename, len))
12042 +                       return -EFAULT;
12043 +
12044 +               rtmp->rolename = tmp;
12045 +
12046 +               if (!rlast) {
12047 +                       rtmp->prev = NULL;
12048 +                       rolep->transitions = rtmp;
12049 +               } else {
12050 +                       rlast->next = rtmp;
12051 +                       rtmp->prev = rlast;
12052 +               }
12053 +
12054 +               if (!rusertp)
12055 +                       rtmp->next = NULL;
12056 +       }
12057 +
12058 +       return 0;
12059 +}
12060 +
12061 +static struct acl_subject_label *
12062 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
12063 +{
12064 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
12065 +       unsigned int len;
12066 +       char *tmp;
12067 +       __u32 num_objs;
12068 +       struct acl_ip_label **i_tmp, *i_utmp2;
12069 +       struct gr_hash_struct ghash;
12070 +       struct subject_map *subjmap;
12071 +       unsigned int i_num;
12072 +       int err;
12073 +
12074 +       s_tmp = lookup_subject_map(userp);
12075 +
12076 +       /* we've already copied this subject into the kernel, just return
12077 +          the reference to it, and don't copy it over again
12078 +       */
12079 +       if (s_tmp)
12080 +               return(s_tmp);
12081 +
12082 +       if ((s_tmp = (struct acl_subject_label *)
12083 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
12084 +               return ERR_PTR(-ENOMEM);
12085 +
12086 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
12087 +       if (subjmap == NULL)
12088 +               return ERR_PTR(-ENOMEM);
12089 +
12090 +       subjmap->user = userp;
12091 +       subjmap->kernel = s_tmp;
12092 +       insert_subj_map_entry(subjmap);
12093 +
12094 +       if (copy_from_user(s_tmp, userp,
12095 +                          sizeof (struct acl_subject_label)))
12096 +               return ERR_PTR(-EFAULT);
12097 +
12098 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
12099 +
12100 +       if (!len || len >= PATH_MAX)
12101 +               return ERR_PTR(-EINVAL);
12102 +
12103 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
12104 +               return ERR_PTR(-ENOMEM);
12105 +
12106 +       if (copy_from_user(tmp, s_tmp->filename, len))
12107 +               return ERR_PTR(-EFAULT);
12108 +
12109 +       s_tmp->filename = tmp;
12110 +
12111 +       if (!strcmp(s_tmp->filename, "/"))
12112 +               role->root_label = s_tmp;
12113 +
12114 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
12115 +               return ERR_PTR(-EFAULT);
12116 +
12117 +       /* copy user and group transition tables */
12118 +
12119 +       if (s_tmp->user_trans_num) {
12120 +               uid_t *uidlist;
12121 +
12122 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
12123 +               if (uidlist == NULL)
12124 +                       return ERR_PTR(-ENOMEM);
12125 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
12126 +                       return ERR_PTR(-EFAULT);
12127 +
12128 +               s_tmp->user_transitions = uidlist;
12129 +       }
12130 +
12131 +       if (s_tmp->group_trans_num) {
12132 +               gid_t *gidlist;
12133 +
12134 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
12135 +               if (gidlist == NULL)
12136 +                       return ERR_PTR(-ENOMEM);
12137 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
12138 +                       return ERR_PTR(-EFAULT);
12139 +
12140 +               s_tmp->group_transitions = gidlist;
12141 +       }
12142 +
12143 +       /* set up object hash table */
12144 +       num_objs = count_user_objs(ghash.first);
12145 +
12146 +       s_tmp->obj_hash_size = num_objs;
12147 +       s_tmp->obj_hash =
12148 +           (struct acl_object_label **)
12149 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
12150 +
12151 +       if (!s_tmp->obj_hash)
12152 +               return ERR_PTR(-ENOMEM);
12153 +
12154 +       memset(s_tmp->obj_hash, 0,
12155 +              s_tmp->obj_hash_size *
12156 +              sizeof (struct acl_object_label *));
12157 +
12158 +       /* add in objects */
12159 +       err = copy_user_objs(ghash.first, s_tmp, role);
12160 +
12161 +       if (err)
12162 +               return ERR_PTR(err);
12163 +
12164 +       /* set pointer for parent subject */
12165 +       if (s_tmp->parent_subject) {
12166 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
12167 +
12168 +               if (IS_ERR(s_tmp2))
12169 +                       return s_tmp2;
12170 +
12171 +               s_tmp->parent_subject = s_tmp2;
12172 +       }
12173 +
12174 +       /* add in ip acls */
12175 +
12176 +       if (!s_tmp->ip_num) {
12177 +               s_tmp->ips = NULL;
12178 +               goto insert;
12179 +       }
12180 +
12181 +       i_tmp =
12182 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
12183 +                                              sizeof (struct
12184 +                                                      acl_ip_label *));
12185 +
12186 +       if (!i_tmp)
12187 +               return ERR_PTR(-ENOMEM);
12188 +
12189 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
12190 +               *(i_tmp + i_num) =
12191 +                   (struct acl_ip_label *)
12192 +                   acl_alloc(sizeof (struct acl_ip_label));
12193 +               if (!*(i_tmp + i_num))
12194 +                       return ERR_PTR(-ENOMEM);
12195 +
12196 +               if (copy_from_user
12197 +                   (&i_utmp2, s_tmp->ips + i_num,
12198 +                    sizeof (struct acl_ip_label *)))
12199 +                       return ERR_PTR(-EFAULT);
12200 +
12201 +               if (copy_from_user
12202 +                   (*(i_tmp + i_num), i_utmp2,
12203 +                    sizeof (struct acl_ip_label)))
12204 +                       return ERR_PTR(-EFAULT);
12205 +               
12206 +               if ((*(i_tmp + i_num))->iface == NULL)
12207 +                       continue;
12208 +
12209 +               len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
12210 +               if (!len || len >= IFNAMSIZ)
12211 +                       return ERR_PTR(-EINVAL);
12212 +               tmp = acl_alloc(len);
12213 +               if (tmp == NULL)
12214 +                       return ERR_PTR(-ENOMEM);
12215 +               if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
12216 +                       return ERR_PTR(-EFAULT);
12217 +               (*(i_tmp + i_num))->iface = tmp;
12218 +       }
12219 +
12220 +       s_tmp->ips = i_tmp;
12221 +
12222 +insert:
12223 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
12224 +                              s_tmp->device))
12225 +               return ERR_PTR(-ENOMEM);
12226 +
12227 +       return s_tmp;
12228 +}
12229 +
12230 +static int
12231 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
12232 +{
12233 +       struct acl_subject_label s_pre;
12234 +       struct acl_subject_label * ret;
12235 +       int err;
12236 +
12237 +       while (userp) {
12238 +               if (copy_from_user(&s_pre, userp,
12239 +                                  sizeof (struct acl_subject_label)))
12240 +                       return -EFAULT;
12241 +               
12242 +               /* do not add nested subjects here, add
12243 +                  while parsing objects
12244 +               */
12245 +
12246 +               if (s_pre.mode & GR_NESTED) {
12247 +                       userp = s_pre.prev;
12248 +                       continue;
12249 +               }
12250 +
12251 +               ret = do_copy_user_subj(userp, role);
12252 +
12253 +               err = PTR_ERR(ret);
12254 +               if (IS_ERR(ret))
12255 +                       return err;
12256 +
12257 +               insert_acl_subj_label(ret, role);
12258 +
12259 +               userp = s_pre.prev;
12260 +       }
12261 +
12262 +       return 0;
12263 +}
12264 +
12265 +static int
12266 +copy_user_acl(struct gr_arg *arg)
12267 +{
12268 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
12269 +       struct sprole_pw *sptmp;
12270 +       struct gr_hash_struct *ghash;
12271 +       uid_t *domainlist;
12272 +       unsigned int r_num;
12273 +       unsigned int len;
12274 +       char *tmp;
12275 +       int err = 0;
12276 +       __u16 i;
12277 +       __u32 num_subjs;
12278 +
12279 +       /* we need a default and kernel role */
12280 +       if (arg->role_db.num_roles < 2)
12281 +               return -EINVAL;
12282 +
12283 +       /* copy special role authentication info from userspace */
12284 +
12285 +       num_sprole_pws = arg->num_sprole_pws;
12286 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
12287 +
12288 +       if (!acl_special_roles) {
12289 +               err = -ENOMEM;
12290 +               goto cleanup;
12291 +       }
12292 +
12293 +       for (i = 0; i < num_sprole_pws; i++) {
12294 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
12295 +               if (!sptmp) {
12296 +                       err = -ENOMEM;
12297 +                       goto cleanup;
12298 +               }
12299 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
12300 +                                  sizeof (struct sprole_pw))) {
12301 +                       err = -EFAULT;
12302 +                       goto cleanup;
12303 +               }
12304 +
12305 +               len =
12306 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
12307 +
12308 +               if (!len || len >= GR_SPROLE_LEN) {
12309 +                       err = -EINVAL;
12310 +                       goto cleanup;
12311 +               }
12312 +
12313 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
12314 +                       err = -ENOMEM;
12315 +                       goto cleanup;
12316 +               }
12317 +
12318 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
12319 +                       err = -EFAULT;
12320 +                       goto cleanup;
12321 +               }
12322 +
12323 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
12324 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
12325 +#endif
12326 +               sptmp->rolename = tmp;
12327 +               acl_special_roles[i] = sptmp;
12328 +       }
12329 +
12330 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
12331 +
12332 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
12333 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
12334 +
12335 +               if (!r_tmp) {
12336 +                       err = -ENOMEM;
12337 +                       goto cleanup;
12338 +               }
12339 +
12340 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
12341 +                                  sizeof (struct acl_role_label *))) {
12342 +                       err = -EFAULT;
12343 +                       goto cleanup;
12344 +               }
12345 +
12346 +               if (copy_from_user(r_tmp, r_utmp2,
12347 +                                  sizeof (struct acl_role_label))) {
12348 +                       err = -EFAULT;
12349 +                       goto cleanup;
12350 +               }
12351 +
12352 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
12353 +
12354 +               if (!len || len >= PATH_MAX) {
12355 +                       err = -EINVAL;
12356 +                       goto cleanup;
12357 +               }
12358 +
12359 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
12360 +                       err = -ENOMEM;
12361 +                       goto cleanup;
12362 +               }
12363 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
12364 +                       err = -EFAULT;
12365 +                       goto cleanup;
12366 +               }
12367 +               r_tmp->rolename = tmp;
12368 +
12369 +               if (!strcmp(r_tmp->rolename, "default")
12370 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
12371 +                       default_role = r_tmp;
12372 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
12373 +                       kernel_role = r_tmp;
12374 +               }
12375 +
12376 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
12377 +                       err = -ENOMEM;
12378 +                       goto cleanup;
12379 +               }
12380 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
12381 +                       err = -EFAULT;
12382 +                       goto cleanup;
12383 +               }
12384 +
12385 +               r_tmp->hash = ghash;
12386 +
12387 +               num_subjs = count_user_subjs(r_tmp->hash->first);
12388 +
12389 +               r_tmp->subj_hash_size = num_subjs;
12390 +               r_tmp->subj_hash =
12391 +                   (struct acl_subject_label **)
12392 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
12393 +
12394 +               if (!r_tmp->subj_hash) {
12395 +                       err = -ENOMEM;
12396 +                       goto cleanup;
12397 +               }
12398 +
12399 +               err = copy_user_allowedips(r_tmp);
12400 +               if (err)
12401 +                       goto cleanup;
12402 +
12403 +               /* copy domain info */
12404 +               if (r_tmp->domain_children != NULL) {
12405 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
12406 +                       if (domainlist == NULL) {
12407 +                               err = -ENOMEM;
12408 +                               goto cleanup;
12409 +                       }
12410 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
12411 +                               err = -EFAULT;
12412 +                               goto cleanup;
12413 +                       }
12414 +                       r_tmp->domain_children = domainlist;
12415 +               }
12416 +
12417 +               err = copy_user_transitions(r_tmp);
12418 +               if (err)
12419 +                       goto cleanup;
12420 +
12421 +               memset(r_tmp->subj_hash, 0,
12422 +                      r_tmp->subj_hash_size *
12423 +                      sizeof (struct acl_subject_label *));
12424 +
12425 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
12426 +
12427 +               if (err)
12428 +                       goto cleanup;
12429 +
12430 +               /* set nested subject list to null */
12431 +               r_tmp->hash->first = NULL;
12432 +
12433 +               insert_acl_role_label(r_tmp);
12434 +       }
12435 +
12436 +       goto return_err;
12437 +      cleanup:
12438 +       free_variables();
12439 +      return_err:
12440 +       return err;
12441 +
12442 +}
12443 +
12444 +static int
12445 +gracl_init(struct gr_arg *args)
12446 +{
12447 +       int error = 0;
12448 +
12449 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
12450 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
12451 +
12452 +       if (init_variables(args)) {
12453 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
12454 +               error = -ENOMEM;
12455 +               free_variables();
12456 +               goto out;
12457 +       }
12458 +
12459 +       error = copy_user_acl(args);
12460 +       free_init_variables();
12461 +       if (error) {
12462 +               free_variables();
12463 +               goto out;
12464 +       }
12465 +
12466 +       if ((error = gr_set_acls(0))) {
12467 +               free_variables();
12468 +               goto out;
12469 +       }
12470 +
12471 +       gr_status |= GR_READY;
12472 +      out:
12473 +       return error;
12474 +}
12475 +
12476 +/* derived from glibc fnmatch() 0: match, 1: no match*/
12477 +
12478 +static int
12479 +glob_match(const char *p, const char *n)
12480 +{
12481 +       char c;
12482 +
12483 +       while ((c = *p++) != '\0') {
12484 +       switch (c) {
12485 +               case '?':
12486 +                       if (*n == '\0')
12487 +                               return 1;
12488 +                       else if (*n == '/')
12489 +                               return 1;
12490 +                       break;
12491 +               case '\\':
12492 +                       if (*n != c)
12493 +                               return 1;
12494 +                       break;
12495 +               case '*':
12496 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
12497 +                               if (*n == '/')
12498 +                                       return 1;
12499 +                               else if (c == '?') {
12500 +                                       if (*n == '\0')
12501 +                                               return 1;
12502 +                                       else
12503 +                                               ++n;
12504 +                               }
12505 +                       }
12506 +                       if (c == '\0') {
12507 +                               return 0;
12508 +                       } else {
12509 +                               const char *endp;
12510 +
12511 +                               if ((endp = strchr(n, '/')) == NULL)
12512 +                                       endp = n + strlen(n);
12513 +
12514 +                               if (c == '[') {
12515 +                                       for (--p; n < endp; ++n)
12516 +                                               if (!glob_match(p, n))
12517 +                                                       return 0;
12518 +                               } else if (c == '/') {
12519 +                                       while (*n != '\0' && *n != '/')
12520 +                                               ++n;
12521 +                                       if (*n == '/' && !glob_match(p, n + 1))
12522 +                                               return 0;
12523 +                               } else {
12524 +                                       for (--p; n < endp; ++n)
12525 +                                               if (*n == c && !glob_match(p, n))
12526 +                                                       return 0;
12527 +                               }
12528 +
12529 +                               return 1;
12530 +                       }
12531 +               case '[':
12532 +                       {
12533 +                       int not;
12534 +                       char cold;
12535 +
12536 +                       if (*n == '\0' || *n == '/')
12537 +                               return 1;
12538 +
12539 +                       not = (*p == '!' || *p == '^');
12540 +                       if (not)
12541 +                               ++p;
12542 +
12543 +                       c = *p++;
12544 +                       for (;;) {
12545 +                               unsigned char fn = (unsigned char)*n;
12546 +
12547 +                               if (c == '\0')
12548 +                                       return 1;
12549 +                               else {
12550 +                                       if (c == fn)
12551 +                                               goto matched;
12552 +                                       cold = c;
12553 +                                       c = *p++;
12554 +
12555 +                                       if (c == '-' && *p != ']') {
12556 +                                               unsigned char cend = *p++;
12557 +
12558 +                                               if (cend == '\0')
12559 +                                                       return 1;
12560 +
12561 +                                               if (cold <= fn && fn <= cend)
12562 +                                                       goto matched;
12563 +
12564 +                                               c = *p++;
12565 +                                       }
12566 +                               }
12567 +
12568 +                               if (c == ']')
12569 +                                       break;
12570 +                       }
12571 +                       if (!not)
12572 +                               return 1;
12573 +                       break;
12574 +               matched:
12575 +                       while (c != ']') {
12576 +                               if (c == '\0')
12577 +                                       return 1;
12578 +
12579 +                               c = *p++;
12580 +                       }
12581 +                       if (not)
12582 +                               return 1;
12583 +               }
12584 +               break;
12585 +       default:
12586 +               if (c != *n)
12587 +                       return 1;
12588 +       }
12589 +
12590 +       ++n;
12591 +       }
12592 +
12593 +       if (*n == '\0')
12594 +               return 0;
12595 +
12596 +       if (*n == '/')
12597 +               return 0;
12598 +
12599 +       return 1;
12600 +}
12601 +
12602 +static struct acl_object_label *
12603 +chk_glob_label(struct acl_object_label *globbed,
12604 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
12605 +{
12606 +       struct acl_object_label *tmp;
12607 +
12608 +       if (*path == NULL)
12609 +               *path = gr_to_filename_nolock(dentry, mnt);
12610 +
12611 +       tmp = globbed;
12612 +
12613 +       while (tmp) {
12614 +               if (!glob_match(tmp->filename, *path))
12615 +                       return tmp;
12616 +               tmp = tmp->next;
12617 +       }
12618 +
12619 +       return NULL;
12620 +}
12621 +
12622 +static struct acl_object_label *
12623 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
12624 +           const ino_t curr_ino, const dev_t curr_dev,
12625 +           const struct acl_subject_label *subj, char **path)
12626 +{
12627 +       struct acl_subject_label *tmpsubj;
12628 +       struct acl_object_label *retval;
12629 +       struct acl_object_label *retval2;
12630 +
12631 +       tmpsubj = (struct acl_subject_label *) subj;
12632 +       read_lock(&gr_inode_lock);
12633 +       do {
12634 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
12635 +               if (retval) {
12636 +                       if (retval->globbed) {
12637 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
12638 +                                               (struct vfsmount *)orig_mnt, path);
12639 +                               if (retval2)
12640 +                                       retval = retval2;
12641 +                       }
12642 +                       break;
12643 +               }
12644 +       } while ((tmpsubj = tmpsubj->parent_subject));
12645 +       read_unlock(&gr_inode_lock);
12646 +
12647 +       return retval;
12648 +}
12649 +
12650 +static __inline__ struct acl_object_label *
12651 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
12652 +           const struct dentry *curr_dentry,
12653 +           const struct acl_subject_label *subj, char **path)
12654 +{
12655 +       return __full_lookup(orig_dentry, orig_mnt,
12656 +                            curr_dentry->d_inode->i_ino, 
12657 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
12658 +}
12659 +
12660 +static struct acl_object_label *
12661 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12662 +             const struct acl_subject_label *subj, char *path)
12663 +{
12664 +       struct dentry *dentry = (struct dentry *) l_dentry;
12665 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
12666 +       struct acl_object_label *retval;
12667 +
12668 +       spin_lock(&dcache_lock);
12669 +
12670 +       if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt)) {
12671 +               retval = fakefs_obj;
12672 +               goto out;
12673 +       }
12674 +
12675 +       for (;;) {
12676 +               if (dentry == real_root && mnt == real_root_mnt)
12677 +                       break;
12678 +
12679 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
12680 +                       if (mnt->mnt_parent == mnt)
12681 +                               break;
12682 +
12683 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12684 +                       if (retval != NULL)
12685 +                               goto out;
12686 +
12687 +                       dentry = mnt->mnt_mountpoint;
12688 +                       mnt = mnt->mnt_parent;
12689 +                       continue;
12690 +               }
12691 +
12692 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12693 +               if (retval != NULL)
12694 +                       goto out;
12695 +
12696 +               dentry = dentry->d_parent;
12697 +       }
12698 +
12699 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
12700 +
12701 +       if (retval == NULL)
12702 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
12703 +out:
12704 +       spin_unlock(&dcache_lock);
12705 +       return retval;
12706 +}
12707 +
12708 +static __inline__ struct acl_object_label *
12709 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12710 +             const struct acl_subject_label *subj)
12711 +{
12712 +       char *path = NULL;
12713 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
12714 +}
12715 +
12716 +static __inline__ struct acl_object_label *
12717 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12718 +                    const struct acl_subject_label *subj, char *path)
12719 +{
12720 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
12721 +}
12722 +
12723 +static struct acl_subject_label *
12724 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
12725 +              const struct acl_role_label *role)
12726 +{
12727 +       struct dentry *dentry = (struct dentry *) l_dentry;
12728 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
12729 +       struct acl_subject_label *retval;
12730 +
12731 +       spin_lock(&dcache_lock);
12732 +
12733 +       for (;;) {
12734 +               if (dentry == real_root && mnt == real_root_mnt)
12735 +                       break;
12736 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
12737 +                       if (mnt->mnt_parent == mnt)
12738 +                               break;
12739 +
12740 +                       read_lock(&gr_inode_lock);
12741 +                       retval =
12742 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
12743 +                                               dentry->d_inode->i_sb->s_dev, role);
12744 +                       read_unlock(&gr_inode_lock);
12745 +                       if (retval != NULL)
12746 +                               goto out;
12747 +
12748 +                       dentry = mnt->mnt_mountpoint;
12749 +                       mnt = mnt->mnt_parent;
12750 +                       continue;
12751 +               }
12752 +
12753 +               read_lock(&gr_inode_lock);
12754 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
12755 +                                         dentry->d_inode->i_sb->s_dev, role);
12756 +               read_unlock(&gr_inode_lock);
12757 +               if (retval != NULL)
12758 +                       goto out;
12759 +
12760 +               dentry = dentry->d_parent;
12761 +       }
12762 +
12763 +       read_lock(&gr_inode_lock);
12764 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
12765 +                                 dentry->d_inode->i_sb->s_dev, role);
12766 +       read_unlock(&gr_inode_lock);
12767 +
12768 +       if (unlikely(retval == NULL)) {
12769 +               read_lock(&gr_inode_lock);
12770 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
12771 +                                         real_root->d_inode->i_sb->s_dev, role);
12772 +               read_unlock(&gr_inode_lock);
12773 +       }
12774 +out:
12775 +       spin_unlock(&dcache_lock);
12776 +
12777 +       return retval;
12778 +}
12779 +
12780 +static void
12781 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
12782 +{
12783 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
12784 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
12785 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
12786 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
12787 +
12788 +       return;
12789 +}
12790 +
12791 +static void
12792 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
12793 +                      const unsigned int effective, const unsigned int fs)
12794 +{
12795 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
12796 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
12797 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
12798 +                      type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
12799 +
12800 +       return;
12801 +}
12802 +
12803 +__u32
12804 +gr_check_link(const struct dentry * new_dentry,
12805 +             const struct dentry * parent_dentry,
12806 +             const struct vfsmount * parent_mnt,
12807 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
12808 +{
12809 +       struct acl_object_label *obj;
12810 +       __u32 oldmode, newmode;
12811 +       __u32 needmode;
12812 +
12813 +       if (unlikely(!(gr_status & GR_READY)))
12814 +               return (GR_CREATE | GR_LINK);
12815 +
12816 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
12817 +       oldmode = obj->mode;
12818 +
12819 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
12820 +               oldmode |= (GR_CREATE | GR_LINK);
12821 +
12822 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
12823 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
12824 +               needmode |= GR_SETID | GR_AUDIT_SETID;
12825 +
12826 +       newmode =
12827 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
12828 +                           oldmode | needmode);
12829 +
12830 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
12831 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
12832 +                             GR_INHERIT | GR_AUDIT_INHERIT);
12833 +
12834 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
12835 +               goto bad;
12836 +
12837 +       if ((oldmode & needmode) != needmode)
12838 +               goto bad;
12839 +
12840 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
12841 +       if ((newmode & needmode) != needmode)
12842 +               goto bad;
12843 +
12844 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
12845 +               return newmode;
12846 +bad:
12847 +       needmode = oldmode;
12848 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
12849 +               needmode |= GR_SETID;
12850 +       
12851 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
12852 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
12853 +               return (GR_CREATE | GR_LINK);
12854 +       } else if (newmode & GR_SUPPRESS)
12855 +               return GR_SUPPRESS;
12856 +       else
12857 +               return 0;
12858 +}
12859 +
12860 +__u32
12861 +gr_search_file(const struct dentry * dentry, const __u32 mode,
12862 +              const struct vfsmount * mnt)
12863 +{
12864 +       __u32 retval = mode;
12865 +       struct acl_subject_label *curracl;
12866 +       struct acl_object_label *currobj;
12867 +
12868 +       if (unlikely(!(gr_status & GR_READY)))
12869 +               return (mode & ~GR_AUDITS);
12870 +
12871 +       curracl = current->acl;
12872 +
12873 +       currobj = chk_obj_label(dentry, mnt, curracl);
12874 +       retval = currobj->mode & mode;
12875 +
12876 +       if (unlikely
12877 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
12878 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
12879 +               __u32 new_mode = mode;
12880 +
12881 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12882 +
12883 +               retval = new_mode;
12884 +
12885 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
12886 +                       new_mode |= GR_INHERIT;
12887 +
12888 +               if (!(mode & GR_NOLEARN))
12889 +                       gr_log_learn(current, dentry, mnt, new_mode);
12890 +       }
12891 +
12892 +       return retval;
12893 +}
12894 +
12895 +__u32
12896 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
12897 +               const struct vfsmount * mnt, const __u32 mode)
12898 +{
12899 +       struct name_entry *match;
12900 +       struct acl_object_label *matchpo;
12901 +       struct acl_subject_label *curracl;
12902 +       char *path;
12903 +       __u32 retval;
12904 +
12905 +       if (unlikely(!(gr_status & GR_READY)))
12906 +               return (mode & ~GR_AUDITS);
12907 +
12908 +       preempt_disable();
12909 +       path = gr_to_filename_rbac(new_dentry, mnt);
12910 +       match = lookup_name_entry(path);
12911 +
12912 +       if (!match)
12913 +               goto check_parent;
12914 +
12915 +       curracl = current->acl;
12916 +
12917 +       read_lock(&gr_inode_lock);
12918 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
12919 +       read_unlock(&gr_inode_lock);
12920 +
12921 +       if (matchpo) {
12922 +               if ((matchpo->mode & mode) !=
12923 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
12924 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
12925 +                       __u32 new_mode = mode;
12926 +
12927 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12928 +
12929 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
12930 +
12931 +                       preempt_enable();
12932 +                       return new_mode;
12933 +               }
12934 +               preempt_enable();
12935 +               return (matchpo->mode & mode);
12936 +       }
12937 +
12938 +      check_parent:
12939 +       curracl = current->acl;
12940 +
12941 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
12942 +       retval = matchpo->mode & mode;
12943 +
12944 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
12945 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
12946 +               __u32 new_mode = mode;
12947 +
12948 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12949 +
12950 +               gr_log_learn(current, new_dentry, mnt, new_mode);
12951 +               preempt_enable();
12952 +               return new_mode;
12953 +       }
12954 +
12955 +       preempt_enable();
12956 +       return retval;
12957 +}
12958 +
12959 +int
12960 +gr_check_hidden_task(const struct task_struct *task)
12961 +{
12962 +       if (unlikely(!(gr_status & GR_READY)))
12963 +               return 0;
12964 +
12965 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
12966 +               return 1;
12967 +
12968 +       return 0;
12969 +}
12970 +
12971 +int
12972 +gr_check_protected_task(const struct task_struct *task)
12973 +{
12974 +       if (unlikely(!(gr_status & GR_READY) || !task))
12975 +               return 0;
12976 +
12977 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
12978 +           task->acl != current->acl)
12979 +               return 1;
12980 +
12981 +       return 0;
12982 +}
12983 +
12984 +void
12985 +gr_copy_label(struct task_struct *tsk)
12986 +{
12987 +       tsk->signal->used_accept = 0;
12988 +       tsk->acl_sp_role = 0;
12989 +       tsk->acl_role_id = current->acl_role_id;
12990 +       tsk->acl = current->acl;
12991 +       tsk->role = current->role;
12992 +       tsk->signal->curr_ip = current->signal->curr_ip;
12993 +       if (current->exec_file)
12994 +               get_file(current->exec_file);
12995 +       tsk->exec_file = current->exec_file;
12996 +       tsk->is_writable = current->is_writable;
12997 +       if (unlikely(current->signal->used_accept))
12998 +               current->signal->curr_ip = 0;
12999 +
13000 +       return;
13001 +}
13002 +
13003 +static void
13004 +gr_set_proc_res(struct task_struct *task)
13005 +{
13006 +       struct acl_subject_label *proc;
13007 +       unsigned short i;
13008 +
13009 +       proc = task->acl;
13010 +
13011 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
13012 +               return;
13013 +
13014 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
13015 +               if (!(proc->resmask & (1 << i)))
13016 +                       continue;
13017 +
13018 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
13019 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
13020 +       }
13021 +
13022 +       return;
13023 +}
13024 +
13025 +int
13026 +gr_check_user_change(int real, int effective, int fs)
13027 +{
13028 +       unsigned int i;
13029 +       __u16 num;
13030 +       uid_t *uidlist;
13031 +       int curuid;
13032 +       int realok = 0;
13033 +       int effectiveok = 0;
13034 +       int fsok = 0;
13035 +
13036 +       if (unlikely(!(gr_status & GR_READY)))
13037 +               return 0;
13038 +
13039 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
13040 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
13041 +
13042 +       num = current->acl->user_trans_num;
13043 +       uidlist = current->acl->user_transitions;
13044 +
13045 +       if (uidlist == NULL)
13046 +               return 0;
13047 +
13048 +       if (real == -1)
13049 +               realok = 1;
13050 +       if (effective == -1)
13051 +               effectiveok = 1;
13052 +       if (fs == -1)
13053 +               fsok = 1;
13054 +
13055 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
13056 +               for (i = 0; i < num; i++) {
13057 +                       curuid = (int)uidlist[i];
13058 +                       if (real == curuid)
13059 +                               realok = 1;
13060 +                       if (effective == curuid)
13061 +                               effectiveok = 1;
13062 +                       if (fs == curuid)
13063 +                               fsok = 1;
13064 +               }
13065 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
13066 +               for (i = 0; i < num; i++) {
13067 +                       curuid = (int)uidlist[i];
13068 +                       if (real == curuid)
13069 +                               break;
13070 +                       if (effective == curuid)
13071 +                               break;
13072 +                       if (fs == curuid)
13073 +                               break;
13074 +               }
13075 +               /* not in deny list */
13076 +               if (i == num) {
13077 +                       realok = 1;
13078 +                       effectiveok = 1;
13079 +                       fsok = 1;
13080 +               }
13081 +       }
13082 +
13083 +       if (realok && effectiveok && fsok)
13084 +               return 0;
13085 +       else {
13086 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
13087 +               return 1;
13088 +       }
13089 +}
13090 +
13091 +int
13092 +gr_check_group_change(int real, int effective, int fs)
13093 +{
13094 +       unsigned int i;
13095 +       __u16 num;
13096 +       gid_t *gidlist;
13097 +       int curgid;
13098 +       int realok = 0;
13099 +       int effectiveok = 0;
13100 +       int fsok = 0;
13101 +
13102 +       if (unlikely(!(gr_status & GR_READY)))
13103 +               return 0;
13104 +
13105 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
13106 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
13107 +
13108 +       num = current->acl->group_trans_num;
13109 +       gidlist = current->acl->group_transitions;
13110 +
13111 +       if (gidlist == NULL)
13112 +               return 0;
13113 +
13114 +       if (real == -1)
13115 +               realok = 1;
13116 +       if (effective == -1)
13117 +               effectiveok = 1;
13118 +       if (fs == -1)
13119 +               fsok = 1;
13120 +
13121 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
13122 +               for (i = 0; i < num; i++) {
13123 +                       curgid = (int)gidlist[i];
13124 +                       if (real == curgid)
13125 +                               realok = 1;
13126 +                       if (effective == curgid)
13127 +                               effectiveok = 1;
13128 +                       if (fs == curgid)
13129 +                               fsok = 1;
13130 +               }
13131 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
13132 +               for (i = 0; i < num; i++) {
13133 +                       curgid = (int)gidlist[i];
13134 +                       if (real == curgid)
13135 +                               break;
13136 +                       if (effective == curgid)
13137 +                               break;
13138 +                       if (fs == curgid)
13139 +                               break;
13140 +               }
13141 +               /* not in deny list */
13142 +               if (i == num) {
13143 +                       realok = 1;
13144 +                       effectiveok = 1;
13145 +                       fsok = 1;
13146 +               }
13147 +       }
13148 +
13149 +       if (realok && effectiveok && fsok)
13150 +               return 0;
13151 +       else {
13152 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
13153 +               return 1;
13154 +       }
13155 +}
13156 +
13157 +void
13158 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
13159 +{
13160 +       struct acl_role_label *role = task->role;
13161 +       struct acl_subject_label *subj = NULL;
13162 +       struct acl_object_label *obj;
13163 +       struct file *filp;
13164 +
13165 +       if (unlikely(!(gr_status & GR_READY)))
13166 +               return;
13167 +
13168 +       filp = task->exec_file;
13169 +
13170 +       /* kernel process, we'll give them the kernel role */
13171 +       if (unlikely(!filp)) {
13172 +               task->role = kernel_role;
13173 +               task->acl = kernel_role->root_label;
13174 +               return;
13175 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
13176 +               role = lookup_acl_role_label(task, uid, gid);
13177 +
13178 +       /* perform subject lookup in possibly new role
13179 +          we can use this result below in the case where role == task->role
13180 +       */
13181 +       subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
13182 +
13183 +       /* if we changed uid/gid, but result in the same role
13184 +          and are using inheritance, don't lose the inherited subject
13185 +          if current subject is other than what normal lookup
13186 +          would result in, we arrived via inheritance, don't
13187 +          lose subject
13188 +       */
13189 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
13190 +                                  (subj == task->acl)))
13191 +               task->acl = subj;
13192 +
13193 +       task->role = role;
13194 +
13195 +       task->is_writable = 0;
13196 +
13197 +       /* ignore additional mmap checks for processes that are writable 
13198 +          by the default ACL */
13199 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13200 +       if (unlikely(obj->mode & GR_WRITE))
13201 +               task->is_writable = 1;
13202 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
13203 +       if (unlikely(obj->mode & GR_WRITE))
13204 +               task->is_writable = 1;
13205 +
13206 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13207 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13208 +#endif
13209 +
13210 +       gr_set_proc_res(task);
13211 +
13212 +       return;
13213 +}
13214 +
13215 +int
13216 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
13217 +{
13218 +       struct task_struct *task = current;
13219 +       struct acl_subject_label *newacl;
13220 +       struct acl_object_label *obj;
13221 +       __u32 retmode;
13222 +
13223 +       if (unlikely(!(gr_status & GR_READY)))
13224 +               return 0;
13225 +
13226 +       newacl = chk_subj_label(dentry, mnt, task->role);
13227 +
13228 +       task_lock(task);
13229 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
13230 +            GR_POVERRIDE) && (task->acl != newacl) &&
13231 +            !(task->role->roletype & GR_ROLE_GOD) &&
13232 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
13233 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
13234 +           (atomic_read(&task->fs->count) > 1 ||
13235 +            atomic_read(&task->files->count) > 1 ||
13236 +            atomic_read(&task->sighand->count) > 1)) {
13237 +                task_unlock(task);
13238 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
13239 +               return -EACCES;
13240 +       }
13241 +       task_unlock(task);
13242 +
13243 +       obj = chk_obj_label(dentry, mnt, task->acl);
13244 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
13245 +
13246 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
13247 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
13248 +               if (obj->nested)
13249 +                       task->acl = obj->nested;
13250 +               else
13251 +                       task->acl = newacl;
13252 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
13253 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
13254 +
13255 +       task->is_writable = 0;
13256 +
13257 +       /* ignore additional mmap checks for processes that are writable 
13258 +          by the default ACL */
13259 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
13260 +       if (unlikely(obj->mode & GR_WRITE))
13261 +               task->is_writable = 1;
13262 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
13263 +       if (unlikely(obj->mode & GR_WRITE))
13264 +               task->is_writable = 1;
13265 +
13266 +       gr_set_proc_res(task);
13267 +
13268 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13269 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13270 +#endif
13271 +       return 0;
13272 +}
13273 +
13274 +static void
13275 +do_handle_delete(const ino_t ino, const dev_t dev)
13276 +{
13277 +       struct acl_object_label *matchpo;
13278 +       struct acl_subject_label *matchps;
13279 +       struct acl_subject_label *subj;
13280 +       struct acl_role_label *role;
13281 +       unsigned int i, x;
13282 +
13283 +       FOR_EACH_ROLE_START(role, i)
13284 +               FOR_EACH_SUBJECT_START(role, subj, x)
13285 +                       if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
13286 +                               matchpo->mode |= GR_DELETED;
13287 +               FOR_EACH_SUBJECT_END(subj,x)
13288 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
13289 +                       if (subj->inode == ino && subj->device == dev)
13290 +                               subj->mode |= GR_DELETED;
13291 +               FOR_EACH_NESTED_SUBJECT_END(subj)
13292 +               if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
13293 +                       matchps->mode |= GR_DELETED;
13294 +       FOR_EACH_ROLE_END(role,i)
13295 +
13296 +       return;
13297 +}
13298 +
13299 +void
13300 +gr_handle_delete(const ino_t ino, const dev_t dev)
13301 +{
13302 +       if (unlikely(!(gr_status & GR_READY)))
13303 +               return;
13304 +
13305 +       write_lock(&gr_inode_lock);
13306 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
13307 +               do_handle_delete(ino, dev);
13308 +       write_unlock(&gr_inode_lock);
13309 +
13310 +       return;
13311 +}
13312 +
13313 +static void
13314 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
13315 +                    const ino_t newinode, const dev_t newdevice,
13316 +                    struct acl_subject_label *subj)
13317 +{
13318 +       unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
13319 +       struct acl_object_label *match;
13320 +
13321 +       match = subj->obj_hash[index];
13322 +
13323 +       while (match && (match->inode != oldinode ||
13324 +              match->device != olddevice ||
13325 +              !(match->mode & GR_DELETED)))
13326 +               match = match->next;
13327 +
13328 +       if (match && (match->inode == oldinode)
13329 +           && (match->device == olddevice)
13330 +           && (match->mode & GR_DELETED)) {
13331 +               if (match->prev == NULL) {
13332 +                       subj->obj_hash[index] = match->next;
13333 +                       if (match->next != NULL)
13334 +                               match->next->prev = NULL;
13335 +               } else {
13336 +                       match->prev->next = match->next;
13337 +                       if (match->next != NULL)
13338 +                               match->next->prev = match->prev;
13339 +               }
13340 +               match->prev = NULL;
13341 +               match->next = NULL;
13342 +               match->inode = newinode;
13343 +               match->device = newdevice;
13344 +               match->mode &= ~GR_DELETED;
13345 +
13346 +               insert_acl_obj_label(match, subj);
13347 +       }
13348 +
13349 +       return;
13350 +}
13351 +
13352 +static void
13353 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
13354 +                     const ino_t newinode, const dev_t newdevice,
13355 +                     struct acl_role_label *role)
13356 +{
13357 +       unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
13358 +       struct acl_subject_label *match;
13359 +
13360 +       match = role->subj_hash[index];
13361 +
13362 +       while (match && (match->inode != oldinode ||
13363 +              match->device != olddevice ||
13364 +              !(match->mode & GR_DELETED)))
13365 +               match = match->next;
13366 +
13367 +       if (match && (match->inode == oldinode)
13368 +           && (match->device == olddevice)
13369 +           && (match->mode & GR_DELETED)) {
13370 +               if (match->prev == NULL) {
13371 +                       role->subj_hash[index] = match->next;
13372 +                       if (match->next != NULL)
13373 +                               match->next->prev = NULL;
13374 +               } else {
13375 +                       match->prev->next = match->next;
13376 +                       if (match->next != NULL)
13377 +                               match->next->prev = match->prev;
13378 +               }
13379 +               match->prev = NULL;
13380 +               match->next = NULL;
13381 +               match->inode = newinode;
13382 +               match->device = newdevice;
13383 +               match->mode &= ~GR_DELETED;
13384 +
13385 +               insert_acl_subj_label(match, role);
13386 +       }
13387 +
13388 +       return;
13389 +}
13390 +
13391 +static void
13392 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
13393 +                   const ino_t newinode, const dev_t newdevice)
13394 +{
13395 +       unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
13396 +       struct inodev_entry *match;
13397 +
13398 +       match = inodev_set.i_hash[index];
13399 +
13400 +       while (match && (match->nentry->inode != oldinode ||
13401 +              match->nentry->device != olddevice))
13402 +               match = match->next;
13403 +
13404 +       if (match && (match->nentry->inode == oldinode)
13405 +           && (match->nentry->device == olddevice)) {
13406 +               if (match->prev == NULL) {
13407 +                       inodev_set.i_hash[index] = match->next;
13408 +                       if (match->next != NULL)
13409 +                               match->next->prev = NULL;
13410 +               } else {
13411 +                       match->prev->next = match->next;
13412 +                       if (match->next != NULL)
13413 +                               match->next->prev = match->prev;
13414 +               }
13415 +               match->prev = NULL;
13416 +               match->next = NULL;
13417 +               match->nentry->inode = newinode;
13418 +               match->nentry->device = newdevice;
13419 +
13420 +               insert_inodev_entry(match);
13421 +       }
13422 +
13423 +       return;
13424 +}
13425 +
13426 +static void
13427 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
13428 +                const struct vfsmount *mnt)
13429 +{
13430 +       struct acl_subject_label *subj;
13431 +       struct acl_role_label *role;
13432 +       unsigned int i, x;
13433 +
13434 +       FOR_EACH_ROLE_START(role, i)
13435 +               update_acl_subj_label(matchn->inode, matchn->device,
13436 +                                     dentry->d_inode->i_ino,
13437 +                                     dentry->d_inode->i_sb->s_dev, role);
13438 +
13439 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
13440 +                       if ((subj->inode == dentry->d_inode->i_ino) &&
13441 +                           (subj->device == dentry->d_inode->i_sb->s_dev)) {
13442 +                               subj->inode = dentry->d_inode->i_ino;
13443 +                               subj->device = dentry->d_inode->i_sb->s_dev;
13444 +                       }
13445 +               FOR_EACH_NESTED_SUBJECT_END(subj)
13446 +               FOR_EACH_SUBJECT_START(role, subj, x)
13447 +                       update_acl_obj_label(matchn->inode, matchn->device,
13448 +                                            dentry->d_inode->i_ino,
13449 +                                            dentry->d_inode->i_sb->s_dev, subj);
13450 +               FOR_EACH_SUBJECT_END(subj,x)
13451 +       FOR_EACH_ROLE_END(role,i)
13452 +
13453 +       update_inodev_entry(matchn->inode, matchn->device,
13454 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
13455 +
13456 +       return;
13457 +}
13458 +
13459 +void
13460 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
13461 +{
13462 +       struct name_entry *matchn;
13463 +
13464 +       if (unlikely(!(gr_status & GR_READY)))
13465 +               return;
13466 +
13467 +       preempt_disable();
13468 +       matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
13469 +
13470 +       if (unlikely((unsigned long)matchn)) {
13471 +               write_lock(&gr_inode_lock);
13472 +               do_handle_create(matchn, dentry, mnt);
13473 +               write_unlock(&gr_inode_lock);
13474 +       }
13475 +       preempt_enable();
13476 +
13477 +       return;
13478 +}
13479 +
13480 +void
13481 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
13482 +                struct dentry *old_dentry,
13483 +                struct dentry *new_dentry,
13484 +                struct vfsmount *mnt, const __u8 replace)
13485 +{
13486 +       struct name_entry *matchn;
13487 +
13488 +       if (unlikely(!(gr_status & GR_READY)))
13489 +               return;
13490 +
13491 +       preempt_disable();
13492 +       matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
13493 +
13494 +       /* we wouldn't have to check d_inode if it weren't for
13495 +          NFS silly-renaming
13496 +        */
13497 +
13498 +       write_lock(&gr_inode_lock);
13499 +       if (unlikely(replace && new_dentry->d_inode)) {
13500 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
13501 +                                       new_dentry->d_inode->i_sb->s_dev) &&
13502 +                   (old_dentry->d_inode->i_nlink <= 1)))
13503 +                       do_handle_delete(new_dentry->d_inode->i_ino,
13504 +                                        new_dentry->d_inode->i_sb->s_dev);
13505 +       }
13506 +
13507 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
13508 +                               old_dentry->d_inode->i_sb->s_dev) &&
13509 +           (old_dentry->d_inode->i_nlink <= 1)))
13510 +               do_handle_delete(old_dentry->d_inode->i_ino,
13511 +                                old_dentry->d_inode->i_sb->s_dev);
13512 +
13513 +       if (unlikely((unsigned long)matchn))
13514 +               do_handle_create(matchn, old_dentry, mnt);
13515 +
13516 +       write_unlock(&gr_inode_lock);
13517 +       preempt_enable();
13518 +
13519 +       return;
13520 +}
13521 +
13522 +static int
13523 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
13524 +                        unsigned char **sum)
13525 +{
13526 +       struct acl_role_label *r;
13527 +       struct role_allowed_ip *ipp;
13528 +       struct role_transition *trans;
13529 +       unsigned int i;
13530 +       int found = 0;
13531 +
13532 +       /* check transition table */
13533 +
13534 +       for (trans = current->role->transitions; trans; trans = trans->next) {
13535 +               if (!strcmp(rolename, trans->rolename)) {
13536 +                       found = 1;
13537 +                       break;
13538 +               }
13539 +       }
13540 +
13541 +       if (!found)
13542 +               return 0;
13543 +
13544 +       /* handle special roles that do not require authentication
13545 +          and check ip */
13546 +
13547 +       FOR_EACH_ROLE_START(r, i)
13548 +               if (!strcmp(rolename, r->rolename) &&
13549 +                   (r->roletype & GR_ROLE_SPECIAL)) {
13550 +                       found = 0;
13551 +                       if (r->allowed_ips != NULL) {
13552 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
13553 +                                       if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
13554 +                                            (ntohl(ipp->addr) & ipp->netmask))
13555 +                                               found = 1;
13556 +                               }
13557 +                       } else
13558 +                               found = 2;
13559 +                       if (!found)
13560 +                               return 0;
13561 +
13562 +                       if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
13563 +                           ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
13564 +                               *salt = NULL;
13565 +                               *sum = NULL;
13566 +                               return 1;
13567 +                       }
13568 +               }
13569 +       FOR_EACH_ROLE_END(r,i)
13570 +
13571 +       for (i = 0; i < num_sprole_pws; i++) {
13572 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
13573 +                       *salt = acl_special_roles[i]->salt;
13574 +                       *sum = acl_special_roles[i]->sum;
13575 +                       return 1;
13576 +               }
13577 +       }
13578 +
13579 +       return 0;
13580 +}
13581 +
13582 +static void
13583 +assign_special_role(char *rolename)
13584 +{
13585 +       struct acl_object_label *obj;
13586 +       struct acl_role_label *r;
13587 +       struct acl_role_label *assigned = NULL;
13588 +       struct task_struct *tsk;
13589 +       struct file *filp;
13590 +       unsigned int i;
13591 +
13592 +       FOR_EACH_ROLE_START(r, i)
13593 +               if (!strcmp(rolename, r->rolename) &&
13594 +                   (r->roletype & GR_ROLE_SPECIAL))
13595 +                       assigned = r;
13596 +       FOR_EACH_ROLE_END(r,i)
13597 +
13598 +       if (!assigned)
13599 +               return;
13600 +
13601 +       read_lock(&tasklist_lock);
13602 +       read_lock(&grsec_exec_file_lock);
13603 +
13604 +       tsk = current->parent;
13605 +       if (tsk == NULL)
13606 +               goto out_unlock;
13607 +
13608 +       filp = tsk->exec_file;
13609 +       if (filp == NULL)
13610 +               goto out_unlock;
13611 +
13612 +       tsk->is_writable = 0;
13613 +
13614 +       tsk->acl_sp_role = 1;
13615 +       tsk->acl_role_id = ++acl_sp_role_value;
13616 +       tsk->role = assigned;
13617 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
13618 +
13619 +       /* ignore additional mmap checks for processes that are writable 
13620 +          by the default ACL */
13621 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13622 +       if (unlikely(obj->mode & GR_WRITE))
13623 +               tsk->is_writable = 1;
13624 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
13625 +       if (unlikely(obj->mode & GR_WRITE))
13626 +               tsk->is_writable = 1;
13627 +
13628 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13629 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
13630 +#endif
13631 +
13632 +out_unlock:
13633 +       read_unlock(&grsec_exec_file_lock);
13634 +       read_unlock(&tasklist_lock);
13635 +       return;
13636 +}
13637 +
13638 +int gr_check_secure_terminal(struct task_struct *task)
13639 +{
13640 +       struct task_struct *p, *p2, *p3;
13641 +       struct files_struct *files;
13642 +       struct fdtable *fdt;
13643 +       struct file *our_file = NULL, *file;
13644 +       int i;
13645 +
13646 +       if (task->signal->tty == NULL)
13647 +               return 1;
13648 +
13649 +       files = get_files_struct(task);
13650 +       if (files != NULL) {
13651 +               rcu_read_lock();
13652 +               fdt = files_fdtable(files);
13653 +               for (i=0; i < fdt->max_fds; i++) {
13654 +                       file = fcheck_files(files, i);
13655 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
13656 +                               get_file(file);
13657 +                               our_file = file;
13658 +                       }
13659 +               }
13660 +               rcu_read_unlock();
13661 +               put_files_struct(files);
13662 +       }
13663 +
13664 +       if (our_file == NULL)
13665 +               return 1;
13666 +
13667 +       read_lock(&tasklist_lock);
13668 +       do_each_thread(p2, p) {
13669 +               files = get_files_struct(p);
13670 +               if (files == NULL ||
13671 +                   (p->signal && p->signal->tty == task->signal->tty)) {
13672 +                       if (files != NULL)
13673 +                               put_files_struct(files);
13674 +                       continue;
13675 +               }
13676 +               rcu_read_lock();
13677 +               fdt = files_fdtable(files);
13678 +               for (i=0; i < fdt->max_fds; i++) {
13679 +                       file = fcheck_files(files, i);
13680 +                       if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
13681 +                           file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
13682 +                               p3 = task;
13683 +                               while (p3->pid > 0) {
13684 +                                       if (p3 == p)
13685 +                                               break;
13686 +                                       p3 = p3->parent;
13687 +                               }
13688 +                               if (p3 == p)
13689 +                                       break;
13690 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
13691 +                               gr_handle_alertkill(p);
13692 +                               rcu_read_unlock();
13693 +                               put_files_struct(files);
13694 +                               read_unlock(&tasklist_lock);
13695 +                               fput(our_file);
13696 +                               return 0;
13697 +                       }
13698 +               }
13699 +               rcu_read_unlock();
13700 +               put_files_struct(files);
13701 +       } while_each_thread(p2, p);
13702 +       read_unlock(&tasklist_lock);
13703 +
13704 +       fput(our_file);
13705 +       return 1;
13706 +}
13707 +
13708 +ssize_t
13709 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
13710 +{
13711 +       struct gr_arg_wrapper uwrap;
13712 +       unsigned char *sprole_salt;
13713 +       unsigned char *sprole_sum;
13714 +       int error = sizeof (struct gr_arg_wrapper);
13715 +       int error2 = 0;
13716 +
13717 +       down(&gr_dev_sem);
13718 +
13719 +       if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
13720 +               error = -EPERM;
13721 +               goto out;
13722 +       }
13723 +
13724 +       if (count != sizeof (struct gr_arg_wrapper)) {
13725 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
13726 +               error = -EINVAL;
13727 +               goto out;
13728 +       }
13729 +
13730 +       
13731 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
13732 +               gr_auth_expires = 0;
13733 +               gr_auth_attempts = 0;
13734 +       }
13735 +
13736 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
13737 +               error = -EFAULT;
13738 +               goto out;
13739 +       }
13740 +
13741 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
13742 +               error = -EINVAL;
13743 +               goto out;
13744 +       }
13745 +
13746 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
13747 +               error = -EFAULT;
13748 +               goto out;
13749 +       }
13750 +
13751 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
13752 +           gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
13753 +           time_after(gr_auth_expires, get_seconds())) {
13754 +               error = -EBUSY;
13755 +               goto out;
13756 +       }
13757 +
13758 +       /* if non-root trying to do anything other than use a special role,
13759 +          do not attempt authentication, do not count towards authentication
13760 +          locking
13761 +        */
13762 +
13763 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
13764 +           gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
13765 +           current->uid) {
13766 +               error = -EPERM;
13767 +               goto out;
13768 +       }
13769 +
13770 +       /* ensure pw and special role name are null terminated */
13771 +
13772 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
13773 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
13774 +
13775 +       /* Okay. 
13776 +        * We have our enough of the argument structure..(we have yet
13777 +        * to copy_from_user the tables themselves) . Copy the tables
13778 +        * only if we need them, i.e. for loading operations. */
13779 +
13780 +       switch (gr_usermode->mode) {
13781 +       case STATUS:
13782 +                       if (gr_status & GR_READY) {
13783 +                               error = 1;
13784 +                               if (!gr_check_secure_terminal(current))
13785 +                                       error = 3;
13786 +                       } else
13787 +                               error = 2;
13788 +                       goto out;
13789 +       case SHUTDOWN:
13790 +               if ((gr_status & GR_READY)
13791 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13792 +                       gr_status &= ~GR_READY;
13793 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
13794 +                       free_variables();
13795 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
13796 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
13797 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
13798 +               } else if (gr_status & GR_READY) {
13799 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
13800 +                       error = -EPERM;
13801 +               } else {
13802 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
13803 +                       error = -EAGAIN;
13804 +               }
13805 +               break;
13806 +       case ENABLE:
13807 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
13808 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
13809 +               else {
13810 +                       if (gr_status & GR_READY)
13811 +                               error = -EAGAIN;
13812 +                       else
13813 +                               error = error2;
13814 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
13815 +               }
13816 +               break;
13817 +       case RELOAD:
13818 +               if (!(gr_status & GR_READY)) {
13819 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
13820 +                       error = -EAGAIN;
13821 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13822 +                       lock_kernel();
13823 +                       gr_status &= ~GR_READY;
13824 +                       free_variables();
13825 +                       if (!(error2 = gracl_init(gr_usermode))) {
13826 +                               unlock_kernel();
13827 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
13828 +                       } else {
13829 +                               unlock_kernel();
13830 +                               error = error2;
13831 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
13832 +                       }
13833 +               } else {
13834 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
13835 +                       error = -EPERM;
13836 +               }
13837 +               break;
13838 +       case SEGVMOD:
13839 +               if (unlikely(!(gr_status & GR_READY))) {
13840 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
13841 +                       error = -EAGAIN;
13842 +                       break;
13843 +               }
13844 +
13845 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
13846 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
13847 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
13848 +                               struct acl_subject_label *segvacl;
13849 +                               segvacl =
13850 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
13851 +                                                         gr_usermode->segv_device,
13852 +                                                         current->role);
13853 +                               if (segvacl) {
13854 +                                       segvacl->crashes = 0;
13855 +                                       segvacl->expires = 0;
13856 +                               }
13857 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
13858 +                               gr_remove_uid(gr_usermode->segv_uid);
13859 +                       }
13860 +               } else {
13861 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
13862 +                       error = -EPERM;
13863 +               }
13864 +               break;
13865 +       case SPROLE:
13866 +       case SPROLEPAM:
13867 +               if (unlikely(!(gr_status & GR_READY))) {
13868 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
13869 +                       error = -EAGAIN;
13870 +                       break;
13871 +               }
13872 +
13873 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
13874 +                       current->role->expires = 0;
13875 +                       current->role->auth_attempts = 0;
13876 +               }
13877 +
13878 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
13879 +                   time_after(current->role->expires, get_seconds())) {
13880 +                       error = -EBUSY;
13881 +                       goto out;
13882 +               }
13883 +
13884 +               if (lookup_special_role_auth
13885 +                   (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
13886 +                   && ((!sprole_salt && !sprole_sum)
13887 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
13888 +                       char *p = "";
13889 +                       assign_special_role(gr_usermode->sp_role);
13890 +                       read_lock(&tasklist_lock);
13891 +                       if (current->parent)
13892 +                               p = current->parent->role->rolename;
13893 +                       read_unlock(&tasklist_lock);
13894 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
13895 +                                       p, acl_sp_role_value);
13896 +               } else {
13897 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
13898 +                       error = -EPERM;
13899 +                       if(!(current->role->auth_attempts++))
13900 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
13901 +
13902 +                       goto out;
13903 +               }
13904 +               break;
13905 +       case UNSPROLE:
13906 +               if (unlikely(!(gr_status & GR_READY))) {
13907 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
13908 +                       error = -EAGAIN;
13909 +                       break;
13910 +               }
13911 +
13912 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
13913 +                       char *p = "";
13914 +                       int i = 0;
13915 +
13916 +                       read_lock(&tasklist_lock);
13917 +                       if (current->parent) {
13918 +                               p = current->parent->role->rolename;
13919 +                               i = current->parent->acl_role_id;
13920 +                       }
13921 +                       read_unlock(&tasklist_lock);
13922 +
13923 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
13924 +                       gr_set_acls(1);
13925 +               } else {
13926 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
13927 +                       error = -EPERM;
13928 +                       goto out;
13929 +               }
13930 +               break;
13931 +       default:
13932 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
13933 +               error = -EINVAL;
13934 +               break;
13935 +       }
13936 +
13937 +       if (error != -EPERM)
13938 +               goto out;
13939 +
13940 +       if(!(gr_auth_attempts++))
13941 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
13942 +
13943 +      out:
13944 +       up(&gr_dev_sem);
13945 +       return error;
13946 +}
13947 +
13948 +int
13949 +gr_set_acls(const int type)
13950 +{
13951 +       struct acl_object_label *obj;
13952 +       struct task_struct *task, *task2;
13953 +       struct file *filp;
13954 +       struct acl_role_label *role = current->role;
13955 +       __u16 acl_role_id = current->acl_role_id;
13956 +
13957 +       read_lock(&tasklist_lock);
13958 +       read_lock(&grsec_exec_file_lock);
13959 +       do_each_thread(task2, task) {
13960 +               /* check to see if we're called from the exit handler,
13961 +                  if so, only replace ACLs that have inherited the admin
13962 +                  ACL */
13963 +
13964 +               if (type && (task->role != role ||
13965 +                            task->acl_role_id != acl_role_id))
13966 +                       continue;
13967 +
13968 +               task->acl_role_id = 0;
13969 +               task->acl_sp_role = 0;
13970 +
13971 +               if ((filp = task->exec_file)) {
13972 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
13973 +
13974 +                       task->acl =
13975 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
13976 +                                          task->role);
13977 +                       if (task->acl) {
13978 +                               struct acl_subject_label *curr;
13979 +                               curr = task->acl;
13980 +
13981 +                               task->is_writable = 0;
13982 +                               /* ignore additional mmap checks for processes that are writable 
13983 +                                  by the default ACL */
13984 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
13985 +                               if (unlikely(obj->mode & GR_WRITE))
13986 +                                       task->is_writable = 1;
13987 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
13988 +                               if (unlikely(obj->mode & GR_WRITE))
13989 +                                       task->is_writable = 1;
13990 +
13991 +                               gr_set_proc_res(task);
13992 +
13993 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13994 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
13995 +#endif
13996 +                       } else {
13997 +                               read_unlock(&grsec_exec_file_lock);
13998 +                               read_unlock(&tasklist_lock);
13999 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
14000 +                               return 1;
14001 +                       }
14002 +               } else {
14003 +                       // it's a kernel process
14004 +                       task->role = kernel_role;
14005 +                       task->acl = kernel_role->root_label;
14006 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
14007 +                       task->acl->mode &= ~GR_PROCFIND;
14008 +#endif
14009 +               }
14010 +       } while_each_thread(task2, task);
14011 +       read_unlock(&grsec_exec_file_lock);
14012 +       read_unlock(&tasklist_lock);
14013 +       return 0;
14014 +}
14015 +
14016 +void
14017 +gr_learn_resource(const struct task_struct *task,
14018 +                 const int res, const unsigned long wanted, const int gt)
14019 +{
14020 +       struct acl_subject_label *acl;
14021 +
14022 +       if (unlikely((gr_status & GR_READY) &&
14023 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
14024 +               goto skip_reslog;
14025 +
14026 +#ifdef CONFIG_GRKERNSEC_RESLOG
14027 +       gr_log_resource(task, res, wanted, gt);
14028 +#endif
14029 +      skip_reslog:
14030 +
14031 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
14032 +               return;
14033 +
14034 +       acl = task->acl;
14035 +
14036 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
14037 +                  !(acl->resmask & (1 << (unsigned short) res))))
14038 +               return;
14039 +
14040 +       if (wanted >= acl->res[res].rlim_cur) {
14041 +               unsigned long res_add;
14042 +
14043 +               res_add = wanted;
14044 +               switch (res) {
14045 +               case RLIMIT_CPU:
14046 +                       res_add += GR_RLIM_CPU_BUMP;
14047 +                       break;
14048 +               case RLIMIT_FSIZE:
14049 +                       res_add += GR_RLIM_FSIZE_BUMP;
14050 +                       break;
14051 +               case RLIMIT_DATA:
14052 +                       res_add += GR_RLIM_DATA_BUMP;
14053 +                       break;
14054 +               case RLIMIT_STACK:
14055 +                       res_add += GR_RLIM_STACK_BUMP;
14056 +                       break;
14057 +               case RLIMIT_CORE:
14058 +                       res_add += GR_RLIM_CORE_BUMP;
14059 +                       break;
14060 +               case RLIMIT_RSS:
14061 +                       res_add += GR_RLIM_RSS_BUMP;
14062 +                       break;
14063 +               case RLIMIT_NPROC:
14064 +                       res_add += GR_RLIM_NPROC_BUMP;
14065 +                       break;
14066 +               case RLIMIT_NOFILE:
14067 +                       res_add += GR_RLIM_NOFILE_BUMP;
14068 +                       break;
14069 +               case RLIMIT_MEMLOCK:
14070 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
14071 +                       break;
14072 +               case RLIMIT_AS:
14073 +                       res_add += GR_RLIM_AS_BUMP;
14074 +                       break;
14075 +               case RLIMIT_LOCKS:
14076 +                       res_add += GR_RLIM_LOCKS_BUMP;
14077 +                       break;
14078 +               }
14079 +
14080 +               acl->res[res].rlim_cur = res_add;
14081 +
14082 +               if (wanted > acl->res[res].rlim_max)
14083 +                       acl->res[res].rlim_max = res_add;
14084 +
14085 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
14086 +                              task->role->roletype, acl->filename,
14087 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
14088 +                              "", (unsigned long) res);
14089 +       }
14090 +
14091 +       return;
14092 +}
14093 +
14094 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14095 +void
14096 +pax_set_initial_flags(struct linux_binprm *bprm)
14097 +{
14098 +       struct task_struct *task = current;
14099 +        struct acl_subject_label *proc;
14100 +       unsigned long flags;
14101 +
14102 +        if (unlikely(!(gr_status & GR_READY)))
14103 +                return;
14104 +
14105 +       flags = pax_get_flags(task);
14106 +
14107 +        proc = task->acl;
14108 +
14109 +       if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
14110 +               flags &= ~MF_PAX_PAGEEXEC;
14111 +       if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
14112 +               flags &= ~MF_PAX_SEGMEXEC;
14113 +       if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
14114 +               flags &= ~MF_PAX_RANDMMAP;
14115 +       if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
14116 +               flags &= ~MF_PAX_EMUTRAMP;
14117 +       if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
14118 +               flags &= ~MF_PAX_MPROTECT;
14119 +
14120 +       if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
14121 +               flags |= MF_PAX_PAGEEXEC;
14122 +       if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
14123 +               flags |= MF_PAX_SEGMEXEC;
14124 +       if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
14125 +               flags |= MF_PAX_RANDMMAP;
14126 +       if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
14127 +               flags |= MF_PAX_EMUTRAMP;
14128 +       if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
14129 +               flags |= MF_PAX_MPROTECT;
14130 +
14131 +       pax_set_flags(task, flags);
14132 +
14133 +        return;
14134 +}
14135 +#endif
14136 +
14137 +#ifdef CONFIG_SYSCTL
14138 +extern struct proc_dir_entry *proc_sys_root;
14139 +
14140 +/* the following function is called under the BKL */
14141 +
14142 +__u32
14143 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
14144 +                const void *newval)
14145 +{
14146 +       struct proc_dir_entry *tmp;
14147 +       struct nameidata nd;
14148 +       const char *proc_sys = "/proc/sys";
14149 +       char *path;
14150 +       struct acl_object_label *obj;
14151 +       unsigned short len = 0, pos = 0, depth = 0, i;
14152 +       __u32 err = 0;
14153 +       __u32 mode = 0;
14154 +
14155 +       if (unlikely(!(gr_status & GR_READY)))
14156 +               return 1;
14157 +
14158 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
14159 +
14160 +       if (oldval)
14161 +               mode |= GR_READ;
14162 +       if (newval)
14163 +               mode |= GR_WRITE;
14164 +
14165 +       /* convert the requested sysctl entry into a pathname */
14166 +
14167 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
14168 +               len += strlen(tmp->name);
14169 +               len++;
14170 +               depth++;
14171 +       }
14172 +
14173 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
14174 +               return 0;       /* deny */
14175 +
14176 +       memset(path, 0, PAGE_SIZE);
14177 +
14178 +       memcpy(path, proc_sys, strlen(proc_sys));
14179 +
14180 +       pos += strlen(proc_sys);
14181 +
14182 +       for (; depth > 0; depth--) {
14183 +               path[pos] = '/';
14184 +               pos++;
14185 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
14186 +                    tmp = tmp->parent) {
14187 +                       if (depth == i) {
14188 +                               memcpy(path + pos, tmp->name,
14189 +                                      strlen(tmp->name));
14190 +                               pos += strlen(tmp->name);
14191 +                       }
14192 +                       i++;
14193 +               }
14194 +       }
14195 +
14196 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
14197 +
14198 +       if (err)
14199 +               goto out;
14200 +
14201 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
14202 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
14203 +
14204 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
14205 +                    ((err & mode) != mode))) {
14206 +               __u32 new_mode = mode;
14207 +
14208 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14209 +
14210 +               err = new_mode;
14211 +               gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
14212 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
14213 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
14214 +                              path, (mode & GR_READ) ? " reading" : "",
14215 +                              (mode & GR_WRITE) ? " writing" : "");
14216 +               err = 0;
14217 +       } else if ((err & mode) != mode) {
14218 +               err = 0;
14219 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
14220 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
14221 +                              path, (mode & GR_READ) ? " reading" : "",
14222 +                              (mode & GR_WRITE) ? " writing" : "");
14223 +       }
14224 +
14225 +       path_release(&nd);
14226 +
14227 +      out:
14228 +       return err;
14229 +}
14230 +#endif
14231 +
14232 +int
14233 +gr_handle_proc_ptrace(struct task_struct *task)
14234 +{
14235 +       struct file *filp;
14236 +       struct task_struct *tmp = task;
14237 +       struct task_struct *curtemp = current;
14238 +       __u32 retmode;
14239 +
14240 +       if (unlikely(!(gr_status & GR_READY)))
14241 +               return 0;
14242 +
14243 +       read_lock(&tasklist_lock);
14244 +       read_lock(&grsec_exec_file_lock);
14245 +       filp = task->exec_file;
14246 +
14247 +       while (tmp->pid > 0) {
14248 +               if (tmp == curtemp)
14249 +                       break;
14250 +               tmp = tmp->parent;
14251 +       }
14252 +
14253 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
14254 +               read_unlock(&grsec_exec_file_lock);
14255 +               read_unlock(&tasklist_lock);
14256 +               return 1;
14257 +       }
14258 +
14259 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
14260 +       read_unlock(&grsec_exec_file_lock);
14261 +       read_unlock(&tasklist_lock);
14262 +
14263 +       if (retmode & GR_NOPTRACE)
14264 +               return 1;
14265 +
14266 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
14267 +           && (current->acl != task->acl || (current->acl != current->role->root_label
14268 +           && current->pid != task->pid)))
14269 +               return 1;
14270 +
14271 +       return 0;
14272 +}
14273 +
14274 +int
14275 +gr_handle_ptrace(struct task_struct *task, const long request)
14276 +{
14277 +       struct task_struct *tmp = task;
14278 +       struct task_struct *curtemp = current;
14279 +       __u32 retmode;
14280 +
14281 +       if (unlikely(!(gr_status & GR_READY)))
14282 +               return 0;
14283 +
14284 +       read_lock(&tasklist_lock);
14285 +       while (tmp->pid > 0) {
14286 +               if (tmp == curtemp)
14287 +                       break;
14288 +               tmp = tmp->parent;
14289 +       }
14290 +
14291 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
14292 +               read_unlock(&tasklist_lock);
14293 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
14294 +               return 1;
14295 +       }
14296 +       read_unlock(&tasklist_lock);
14297 +
14298 +       read_lock(&grsec_exec_file_lock);
14299 +       if (unlikely(!task->exec_file)) {
14300 +               read_unlock(&grsec_exec_file_lock);
14301 +               return 0;
14302 +       }
14303 +
14304 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
14305 +       read_unlock(&grsec_exec_file_lock);
14306 +
14307 +       if (retmode & GR_NOPTRACE) {
14308 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
14309 +               return 1;
14310 +       }
14311 +               
14312 +       if (retmode & GR_PTRACERD) {
14313 +               switch (request) {
14314 +               case PTRACE_POKETEXT:
14315 +               case PTRACE_POKEDATA:
14316 +               case PTRACE_POKEUSR:
14317 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
14318 +               case PTRACE_SETREGS:
14319 +               case PTRACE_SETFPREGS:
14320 +#endif
14321 +#ifdef CONFIG_X86
14322 +               case PTRACE_SETFPXREGS:
14323 +#endif
14324 +#ifdef CONFIG_ALTIVEC
14325 +               case PTRACE_SETVRREGS:
14326 +#endif
14327 +                       return 1;
14328 +               default:
14329 +                       return 0;
14330 +               }
14331 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
14332 +                  !(current->role->roletype & GR_ROLE_GOD) &&
14333 +                  (current->acl != task->acl)) {
14334 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
14335 +               return 1;
14336 +       }
14337 +
14338 +       return 0;
14339 +}
14340 +
14341 +static int is_writable_mmap(const struct file *filp)
14342 +{
14343 +       struct task_struct *task = current;
14344 +       struct acl_object_label *obj, *obj2;
14345 +
14346 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
14347 +           !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
14348 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
14349 +               obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
14350 +                                    task->role->root_label);
14351 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
14352 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
14353 +                       return 1;
14354 +               }
14355 +       }
14356 +       return 0;
14357 +}
14358 +
14359 +int
14360 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
14361 +{
14362 +       __u32 mode;
14363 +
14364 +       if (unlikely(!file || !(prot & PROT_EXEC)))
14365 +               return 1;
14366 +
14367 +       if (is_writable_mmap(file))
14368 +               return 0;
14369 +
14370 +       mode =
14371 +           gr_search_file(file->f_dentry,
14372 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
14373 +                          file->f_vfsmnt);
14374 +
14375 +       if (!gr_tpe_allow(file))
14376 +               return 0;
14377 +
14378 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
14379 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
14380 +               return 0;
14381 +       } else if (unlikely(!(mode & GR_EXEC))) {
14382 +               return 0;
14383 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
14384 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
14385 +               return 1;
14386 +       }
14387 +
14388 +       return 1;
14389 +}
14390 +
14391 +int
14392 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
14393 +{
14394 +       __u32 mode;
14395 +
14396 +       if (unlikely(!file || !(prot & PROT_EXEC)))
14397 +               return 1;
14398 +
14399 +       if (is_writable_mmap(file))
14400 +               return 0;
14401 +
14402 +       mode =
14403 +           gr_search_file(file->f_dentry,
14404 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
14405 +                          file->f_vfsmnt);
14406 +
14407 +       if (!gr_tpe_allow(file))
14408 +               return 0;
14409 +
14410 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
14411 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
14412 +               return 0;
14413 +       } else if (unlikely(!(mode & GR_EXEC))) {
14414 +               return 0;
14415 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
14416 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
14417 +               return 1;
14418 +       }
14419 +
14420 +       return 1;
14421 +}
14422 +
14423 +void
14424 +gr_acl_handle_psacct(struct task_struct *task, const long code)
14425 +{
14426 +       unsigned long runtime;
14427 +       unsigned long cputime;
14428 +       unsigned int wday, cday;
14429 +       __u8 whr, chr;
14430 +       __u8 wmin, cmin;
14431 +       __u8 wsec, csec;
14432 +
14433 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
14434 +                    !(task->acl->mode & GR_PROCACCT)))
14435 +               return;
14436 +
14437 +       runtime = xtime.tv_sec - task->start_time.tv_sec;
14438 +       wday = runtime / (3600 * 24);
14439 +       runtime -= wday * (3600 * 24);
14440 +       whr = runtime / 3600;
14441 +       runtime -= whr * 3600;
14442 +       wmin = runtime / 60;
14443 +       runtime -= wmin * 60;
14444 +       wsec = runtime;
14445 +
14446 +       cputime = (task->utime + task->stime) / HZ;
14447 +       cday = cputime / (3600 * 24);
14448 +       cputime -= cday * (3600 * 24);
14449 +       chr = cputime / 3600;
14450 +       cputime -= chr * 3600;
14451 +       cmin = cputime / 60;
14452 +       cputime -= cmin * 60;
14453 +       csec = cputime;
14454 +
14455 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
14456 +
14457 +       return;
14458 +}
14459 +
14460 +void gr_set_kernel_label(struct task_struct *task)
14461 +{
14462 +       if (gr_status & GR_READY) {
14463 +               task->role = kernel_role;
14464 +               task->acl = kernel_role->root_label;
14465 +       }
14466 +       return;
14467 +}
14468 +
14469 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
14470 +{
14471 +       struct task_struct *task = current;
14472 +       struct dentry *dentry = file->f_dentry;
14473 +       struct vfsmount *mnt = file->f_vfsmnt;
14474 +       struct acl_object_label *obj, *tmp;
14475 +       struct acl_subject_label *subj;
14476 +       unsigned int bufsize;
14477 +       int is_not_root;
14478 +       char *path;
14479 +
14480 +       if (unlikely(!(gr_status & GR_READY)))
14481 +               return 1;
14482 +
14483 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
14484 +               return 1;
14485 +
14486 +       subj = task->acl;
14487 +       do {
14488 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
14489 +               if (obj != NULL)
14490 +                       return (obj->mode & GR_FIND) ? 1 : 0;
14491 +       } while ((subj = subj->parent_subject));
14492 +       
14493 +       obj = chk_obj_label(dentry, mnt, task->acl);
14494 +       if (obj->globbed == NULL)
14495 +               return (obj->mode & GR_FIND) ? 1 : 0;
14496 +
14497 +       is_not_root = ((obj->filename[0] == '/') &&
14498 +                  (obj->filename[1] == '\0')) ? 0 : 1;
14499 +       bufsize = PAGE_SIZE - namelen - is_not_root;
14500 +
14501 +       /* check bufsize > PAGE_SIZE || bufsize == 0 */
14502 +       if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
14503 +               return 1;
14504 +
14505 +       preempt_disable();
14506 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
14507 +                          bufsize);
14508 +
14509 +       bufsize = strlen(path);
14510 +
14511 +       /* if base is "/", don't append an additional slash */
14512 +       if (is_not_root)
14513 +               *(path + bufsize) = '/';
14514 +       memcpy(path + bufsize + is_not_root, name, namelen);
14515 +       *(path + bufsize + namelen + is_not_root) = '\0';
14516 +
14517 +       tmp = obj->globbed;
14518 +       while (tmp) {
14519 +               if (!glob_match(tmp->filename, path)) {
14520 +                       preempt_enable();
14521 +                       return (tmp->mode & GR_FIND) ? 1 : 0;
14522 +               }
14523 +               tmp = tmp->next;
14524 +       }
14525 +       preempt_enable();
14526 +       return (obj->mode & GR_FIND) ? 1 : 0;
14527 +}
14528 +
14529 +EXPORT_SYMBOL(gr_learn_resource);
14530 +EXPORT_SYMBOL(gr_set_kernel_label);
14531 +#ifdef CONFIG_SECURITY
14532 +EXPORT_SYMBOL(gr_check_user_change);
14533 +EXPORT_SYMBOL(gr_check_group_change);
14534 +#endif
14535 +
14536 diff -urNp linux-2.6.17.7/grsecurity/gracl_alloc.c linux-2.6.17.7/grsecurity/gracl_alloc.c
14537 --- linux-2.6.17.7/grsecurity/gracl_alloc.c     1969-12-31 19:00:00.000000000 -0500
14538 +++ linux-2.6.17.7/grsecurity/gracl_alloc.c     2006-08-01 20:29:46.000000000 -0400
14539 @@ -0,0 +1,91 @@
14540 +#include <linux/kernel.h>
14541 +#include <linux/mm.h>
14542 +#include <linux/slab.h>
14543 +#include <linux/vmalloc.h>
14544 +#include <linux/gracl.h>
14545 +#include <linux/grsecurity.h>
14546 +
14547 +static unsigned long alloc_stack_next = 1;
14548 +static unsigned long alloc_stack_size = 1;
14549 +static void **alloc_stack;
14550 +
14551 +static __inline__ int
14552 +alloc_pop(void)
14553 +{
14554 +       if (alloc_stack_next == 1)
14555 +               return 0;
14556 +
14557 +       kfree(alloc_stack[alloc_stack_next - 2]);
14558 +
14559 +       alloc_stack_next--;
14560 +
14561 +       return 1;
14562 +}
14563 +
14564 +static __inline__ void
14565 +alloc_push(void *buf)
14566 +{
14567 +       if (alloc_stack_next >= alloc_stack_size)
14568 +               BUG();
14569 +
14570 +       alloc_stack[alloc_stack_next - 1] = buf;
14571 +
14572 +       alloc_stack_next++;
14573 +
14574 +       return;
14575 +}
14576 +
14577 +void *
14578 +acl_alloc(unsigned long len)
14579 +{
14580 +       void *ret;
14581 +
14582 +       if (len > PAGE_SIZE)
14583 +               BUG();
14584 +
14585 +       ret = kmalloc(len, GFP_KERNEL);
14586 +
14587 +       if (ret)
14588 +               alloc_push(ret);
14589 +
14590 +       return ret;
14591 +}
14592 +
14593 +void
14594 +acl_free_all(void)
14595 +{
14596 +       if (gr_acl_is_enabled() || !alloc_stack)
14597 +               return;
14598 +
14599 +       while (alloc_pop()) ;
14600 +
14601 +       if (alloc_stack) {
14602 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
14603 +                       kfree(alloc_stack);
14604 +               else
14605 +                       vfree(alloc_stack);
14606 +       }
14607 +
14608 +       alloc_stack = NULL;
14609 +       alloc_stack_size = 1;
14610 +       alloc_stack_next = 1;
14611 +
14612 +       return;
14613 +}
14614 +
14615 +int
14616 +acl_alloc_stack_init(unsigned long size)
14617 +{
14618 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
14619 +               alloc_stack =
14620 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
14621 +       else
14622 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
14623 +
14624 +       alloc_stack_size = size;
14625 +
14626 +       if (!alloc_stack)
14627 +               return 0;
14628 +       else
14629 +               return 1;
14630 +}
14631 diff -urNp linux-2.6.17.7/grsecurity/gracl_cap.c linux-2.6.17.7/grsecurity/gracl_cap.c
14632 --- linux-2.6.17.7/grsecurity/gracl_cap.c       1969-12-31 19:00:00.000000000 -0500
14633 +++ linux-2.6.17.7/grsecurity/gracl_cap.c       2006-08-01 20:29:47.000000000 -0400
14634 @@ -0,0 +1,110 @@
14635 +#include <linux/kernel.h>
14636 +#include <linux/module.h>
14637 +#include <linux/sched.h>
14638 +#include <linux/capability.h>
14639 +#include <linux/gracl.h>
14640 +#include <linux/grsecurity.h>
14641 +#include <linux/grinternal.h>
14642 +
14643 +static const char *captab_log[] = {
14644 +       "CAP_CHOWN",
14645 +       "CAP_DAC_OVERRIDE",
14646 +       "CAP_DAC_READ_SEARCH",
14647 +       "CAP_FOWNER",
14648 +       "CAP_FSETID",
14649 +       "CAP_KILL",
14650 +       "CAP_SETGID",
14651 +       "CAP_SETUID",
14652 +       "CAP_SETPCAP",
14653 +       "CAP_LINUX_IMMUTABLE",
14654 +       "CAP_NET_BIND_SERVICE",
14655 +       "CAP_NET_BROADCAST",
14656 +       "CAP_NET_ADMIN",
14657 +       "CAP_NET_RAW",
14658 +       "CAP_IPC_LOCK",
14659 +       "CAP_IPC_OWNER",
14660 +       "CAP_SYS_MODULE",
14661 +       "CAP_SYS_RAWIO",
14662 +       "CAP_SYS_CHROOT",
14663 +       "CAP_SYS_PTRACE",
14664 +       "CAP_SYS_PACCT",
14665 +       "CAP_SYS_ADMIN",
14666 +       "CAP_SYS_BOOT",
14667 +       "CAP_SYS_NICE",
14668 +       "CAP_SYS_RESOURCE",
14669 +       "CAP_SYS_TIME",
14670 +       "CAP_SYS_TTY_CONFIG",
14671 +       "CAP_MKNOD",
14672 +       "CAP_LEASE"
14673 +};
14674 +
14675 +EXPORT_SYMBOL(gr_task_is_capable);
14676 +
14677 +int
14678 +gr_task_is_capable(struct task_struct *task, const int cap)
14679 +{
14680 +       struct acl_subject_label *curracl;
14681 +       __u32 cap_drop = 0, cap_mask = 0;
14682 +
14683 +       if (!gr_acl_is_enabled())
14684 +               return 1;
14685 +
14686 +       curracl = task->acl;
14687 +
14688 +       cap_drop = curracl->cap_lower;
14689 +       cap_mask = curracl->cap_mask;
14690 +
14691 +       while ((curracl = curracl->parent_subject)) {
14692 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
14693 +                       cap_drop |= curracl->cap_lower & (1 << cap);
14694 +               cap_mask |= curracl->cap_mask;
14695 +       }
14696 +
14697 +       if (!cap_raised(cap_drop, cap))
14698 +               return 1;
14699 +
14700 +       curracl = task->acl;
14701 +
14702 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
14703 +           && cap_raised(task->cap_effective, cap)) {
14704 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
14705 +                              task->role->roletype, task->uid,
14706 +                              task->gid, task->exec_file ?
14707 +                              gr_to_filename(task->exec_file->f_dentry,
14708 +                              task->exec_file->f_vfsmnt) : curracl->filename,
14709 +                              curracl->filename, 0UL,
14710 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
14711 +               return 1;
14712 +       }
14713 +
14714 +       if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
14715 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
14716 +
14717 +       return 0;
14718 +}
14719 +
14720 +int
14721 +gr_is_capable_nolog(const int cap)
14722 +{
14723 +       struct acl_subject_label *curracl;
14724 +       __u32 cap_drop = 0, cap_mask = 0;
14725 +
14726 +       if (!gr_acl_is_enabled())
14727 +               return 1;
14728 +
14729 +       curracl = current->acl;
14730 +
14731 +       cap_drop = curracl->cap_lower;
14732 +       cap_mask = curracl->cap_mask;
14733 +
14734 +       while ((curracl = curracl->parent_subject)) {
14735 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
14736 +               cap_mask |= curracl->cap_mask;
14737 +       }
14738 +
14739 +       if (!cap_raised(cap_drop, cap))
14740 +               return 1;
14741 +
14742 +       return 0;
14743 +}
14744 +
14745 diff -urNp linux-2.6.17.7/grsecurity/gracl_fs.c linux-2.6.17.7/grsecurity/gracl_fs.c
14746 --- linux-2.6.17.7/grsecurity/gracl_fs.c        1969-12-31 19:00:00.000000000 -0500
14747 +++ linux-2.6.17.7/grsecurity/gracl_fs.c        2006-08-01 20:29:47.000000000 -0400
14748 @@ -0,0 +1,423 @@
14749 +#include <linux/kernel.h>
14750 +#include <linux/sched.h>
14751 +#include <linux/types.h>
14752 +#include <linux/fs.h>
14753 +#include <linux/file.h>
14754 +#include <linux/stat.h>
14755 +#include <linux/grsecurity.h>
14756 +#include <linux/grinternal.h>
14757 +#include <linux/gracl.h>
14758 +
14759 +__u32
14760 +gr_acl_handle_hidden_file(const struct dentry * dentry,
14761 +                         const struct vfsmount * mnt)
14762 +{
14763 +       __u32 mode;
14764 +
14765 +       if (unlikely(!dentry->d_inode))
14766 +               return GR_FIND;
14767 +
14768 +       mode =
14769 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
14770 +
14771 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
14772 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
14773 +               return mode;
14774 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
14775 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
14776 +               return 0;
14777 +       } else if (unlikely(!(mode & GR_FIND)))
14778 +               return 0;
14779 +
14780 +       return GR_FIND;
14781 +}
14782 +
14783 +__u32
14784 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
14785 +                  const int fmode)
14786 +{
14787 +       __u32 reqmode = GR_FIND;
14788 +       __u32 mode;
14789 +
14790 +       if (unlikely(!dentry->d_inode))
14791 +               return reqmode;
14792 +
14793 +       if (unlikely(fmode & O_APPEND))
14794 +               reqmode |= GR_APPEND;
14795 +       else if (unlikely(fmode & FMODE_WRITE))
14796 +               reqmode |= GR_WRITE;
14797 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
14798 +               reqmode |= GR_READ;
14799 +
14800 +       mode =
14801 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
14802 +                          mnt);
14803 +
14804 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14805 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
14806 +                              reqmode & GR_READ ? " reading" : "",
14807 +                              reqmode & GR_WRITE ? " writing" : reqmode &
14808 +                              GR_APPEND ? " appending" : "");
14809 +               return reqmode;
14810 +       } else
14811 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14812 +       {
14813 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
14814 +                              reqmode & GR_READ ? " reading" : "",
14815 +                              reqmode & GR_WRITE ? " writing" : reqmode &
14816 +                              GR_APPEND ? " appending" : "");
14817 +               return 0;
14818 +       } else if (unlikely((mode & reqmode) != reqmode))
14819 +               return 0;
14820 +
14821 +       return reqmode;
14822 +}
14823 +
14824 +__u32
14825 +gr_acl_handle_creat(const struct dentry * dentry,
14826 +                   const struct dentry * p_dentry,
14827 +                   const struct vfsmount * p_mnt, const int fmode,
14828 +                   const int imode)
14829 +{
14830 +       __u32 reqmode = GR_WRITE | GR_CREATE;
14831 +       __u32 mode;
14832 +
14833 +       if (unlikely(fmode & O_APPEND))
14834 +               reqmode |= GR_APPEND;
14835 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
14836 +               reqmode |= GR_READ;
14837 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
14838 +               reqmode |= GR_SETID;
14839 +
14840 +       mode =
14841 +           gr_check_create(dentry, p_dentry, p_mnt,
14842 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
14843 +
14844 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14845 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
14846 +                              reqmode & GR_READ ? " reading" : "",
14847 +                              reqmode & GR_WRITE ? " writing" : reqmode &
14848 +                              GR_APPEND ? " appending" : "");
14849 +               return reqmode;
14850 +       } else
14851 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14852 +       {
14853 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
14854 +                              reqmode & GR_READ ? " reading" : "",
14855 +                              reqmode & GR_WRITE ? " writing" : reqmode &
14856 +                              GR_APPEND ? " appending" : "");
14857 +               return 0;
14858 +       } else if (unlikely((mode & reqmode) != reqmode))
14859 +               return 0;
14860 +
14861 +       return reqmode;
14862 +}
14863 +
14864 +__u32
14865 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
14866 +                    const int fmode)
14867 +{
14868 +       __u32 mode, reqmode = GR_FIND;
14869 +
14870 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
14871 +               reqmode |= GR_EXEC;
14872 +       if (fmode & S_IWOTH)
14873 +               reqmode |= GR_WRITE;
14874 +       if (fmode & S_IROTH)
14875 +               reqmode |= GR_READ;
14876 +
14877 +       mode =
14878 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
14879 +                          mnt);
14880 +
14881 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
14882 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
14883 +                              reqmode & GR_READ ? " reading" : "",
14884 +                              reqmode & GR_WRITE ? " writing" : "",
14885 +                              reqmode & GR_EXEC ? " executing" : "");
14886 +               return reqmode;
14887 +       } else
14888 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
14889 +       {
14890 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
14891 +                              reqmode & GR_READ ? " reading" : "",
14892 +                              reqmode & GR_WRITE ? " writing" : "",
14893 +                              reqmode & GR_EXEC ? " executing" : "");
14894 +               return 0;
14895 +       } else if (unlikely((mode & reqmode) != reqmode))
14896 +               return 0;
14897 +
14898 +       return reqmode;
14899 +}
14900 +
14901 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
14902 +{
14903 +       __u32 mode;
14904 +
14905 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
14906 +
14907 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
14908 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
14909 +               return mode;
14910 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
14911 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
14912 +               return 0;
14913 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
14914 +               return 0;
14915 +
14916 +       return (reqmode);
14917 +}
14918 +
14919 +__u32
14920 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
14921 +{
14922 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
14923 +}
14924 +
14925 +__u32
14926 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
14927 +{
14928 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
14929 +}
14930 +
14931 +__u32
14932 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
14933 +{
14934 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
14935 +}
14936 +
14937 +__u32
14938 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
14939 +{
14940 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
14941 +}
14942 +
14943 +__u32
14944 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
14945 +                    mode_t mode)
14946 +{
14947 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
14948 +               return 1;
14949 +
14950 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
14951 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
14952 +                                  GR_FCHMOD_ACL_MSG);
14953 +       } else {
14954 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
14955 +       }
14956 +}
14957 +
14958 +__u32
14959 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
14960 +                   mode_t mode)
14961 +{
14962 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
14963 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
14964 +                                  GR_CHMOD_ACL_MSG);
14965 +       } else {
14966 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
14967 +       }
14968 +}
14969 +
14970 +__u32
14971 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
14972 +{
14973 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
14974 +}
14975 +
14976 +__u32
14977 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
14978 +{
14979 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
14980 +}
14981 +
14982 +__u32
14983 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
14984 +{
14985 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
14986 +                          GR_UNIXCONNECT_ACL_MSG);
14987 +}
14988 +
14989 +/* hardlinks require at minimum create permission,
14990 +   any additional privilege required is based on the
14991 +   privilege of the file being linked to
14992 +*/
14993 +__u32
14994 +gr_acl_handle_link(const struct dentry * new_dentry,
14995 +                  const struct dentry * parent_dentry,
14996 +                  const struct vfsmount * parent_mnt,
14997 +                  const struct dentry * old_dentry,
14998 +                  const struct vfsmount * old_mnt, const char *to)
14999 +{
15000 +       __u32 mode;
15001 +       __u32 needmode = GR_CREATE | GR_LINK;
15002 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
15003 +
15004 +       mode =
15005 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
15006 +                         old_mnt);
15007 +
15008 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
15009 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
15010 +               return mode;
15011 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
15012 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
15013 +               return 0;
15014 +       } else if (unlikely((mode & needmode) != needmode))
15015 +               return 0;
15016 +
15017 +       return 1;
15018 +}
15019 +
15020 +__u32
15021 +gr_acl_handle_symlink(const struct dentry * new_dentry,
15022 +                     const struct dentry * parent_dentry,
15023 +                     const struct vfsmount * parent_mnt, const char *from)
15024 +{
15025 +       __u32 needmode = GR_WRITE | GR_CREATE;
15026 +       __u32 mode;
15027 +
15028 +       mode =
15029 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
15030 +                           GR_CREATE | GR_AUDIT_CREATE |
15031 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
15032 +
15033 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
15034 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
15035 +               return mode;
15036 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
15037 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
15038 +               return 0;
15039 +       } else if (unlikely((mode & needmode) != needmode))
15040 +               return 0;
15041 +
15042 +       return (GR_WRITE | GR_CREATE);
15043 +}
15044 +
15045 +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)
15046 +{
15047 +       __u32 mode;
15048 +
15049 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
15050 +
15051 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
15052 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
15053 +               return mode;
15054 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
15055 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
15056 +               return 0;
15057 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
15058 +               return 0;
15059 +
15060 +       return (reqmode);
15061 +}
15062 +
15063 +__u32
15064 +gr_acl_handle_mknod(const struct dentry * new_dentry,
15065 +                   const struct dentry * parent_dentry,
15066 +                   const struct vfsmount * parent_mnt,
15067 +                   const int mode)
15068 +{
15069 +       __u32 reqmode = GR_WRITE | GR_CREATE;
15070 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
15071 +               reqmode |= GR_SETID;
15072 +
15073 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
15074 +                                 reqmode, GR_MKNOD_ACL_MSG);
15075 +}
15076 +
15077 +__u32
15078 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
15079 +                   const struct dentry *parent_dentry,
15080 +                   const struct vfsmount *parent_mnt)
15081 +{
15082 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
15083 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
15084 +}
15085 +
15086 +#define RENAME_CHECK_SUCCESS(old, new) \
15087 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
15088 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
15089 +
15090 +int
15091 +gr_acl_handle_rename(struct dentry *new_dentry,
15092 +                    struct dentry *parent_dentry,
15093 +                    const struct vfsmount *parent_mnt,
15094 +                    struct dentry *old_dentry,
15095 +                    struct inode *old_parent_inode,
15096 +                    struct vfsmount *old_mnt, const char *newname)
15097 +{
15098 +       __u32 comp1, comp2;
15099 +       int error = 0;
15100 +
15101 +       if (unlikely(!gr_acl_is_enabled()))
15102 +               return 0;
15103 +
15104 +       if (!new_dentry->d_inode) {
15105 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
15106 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
15107 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
15108 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
15109 +                                      GR_DELETE | GR_AUDIT_DELETE |
15110 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
15111 +                                      GR_SUPPRESS, old_mnt);
15112 +       } else {
15113 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
15114 +                                      GR_CREATE | GR_DELETE |
15115 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
15116 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
15117 +                                      GR_SUPPRESS, parent_mnt);
15118 +               comp2 =
15119 +                   gr_search_file(old_dentry,
15120 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
15121 +                                  GR_DELETE | GR_AUDIT_DELETE |
15122 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
15123 +       }
15124 +
15125 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
15126 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
15127 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
15128 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
15129 +                && !(comp2 & GR_SUPPRESS)) {
15130 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
15131 +               error = -EACCES;
15132 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
15133 +               error = -EACCES;
15134 +
15135 +       return error;
15136 +}
15137 +
15138 +void
15139 +gr_acl_handle_exit(void)
15140 +{
15141 +       u16 id;
15142 +       char *rolename;
15143 +       struct file *exec_file;
15144 +
15145 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
15146 +               id = current->acl_role_id;
15147 +               rolename = current->role->rolename;
15148 +               gr_set_acls(1);
15149 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
15150 +       }
15151 +
15152 +       write_lock(&grsec_exec_file_lock);
15153 +       exec_file = current->exec_file;
15154 +       current->exec_file = NULL;
15155 +       write_unlock(&grsec_exec_file_lock);
15156 +
15157 +       if (exec_file)
15158 +               fput(exec_file);
15159 +}
15160 +
15161 +int
15162 +gr_acl_handle_procpidmem(const struct task_struct *task)
15163 +{
15164 +       if (unlikely(!gr_acl_is_enabled()))
15165 +               return 0;
15166 +
15167 +       if (task->acl->mode & GR_PROTPROCFD)
15168 +               return -EACCES;
15169 +
15170 +       return 0;
15171 +}
15172 diff -urNp linux-2.6.17.7/grsecurity/gracl_ip.c linux-2.6.17.7/grsecurity/gracl_ip.c
15173 --- linux-2.6.17.7/grsecurity/gracl_ip.c        1969-12-31 19:00:00.000000000 -0500
15174 +++ linux-2.6.17.7/grsecurity/gracl_ip.c        2006-08-01 20:29:47.000000000 -0400
15175 @@ -0,0 +1,313 @@
15176 +#include <linux/kernel.h>
15177 +#include <asm/uaccess.h>
15178 +#include <asm/errno.h>
15179 +#include <net/sock.h>
15180 +#include <linux/file.h>
15181 +#include <linux/fs.h>
15182 +#include <linux/net.h>
15183 +#include <linux/in.h>
15184 +#include <linux/skbuff.h>
15185 +#include <linux/ip.h>
15186 +#include <linux/udp.h>
15187 +#include <linux/smp_lock.h>
15188 +#include <linux/types.h>
15189 +#include <linux/sched.h>
15190 +#include <linux/netdevice.h>
15191 +#include <linux/inetdevice.h>
15192 +#include <linux/gracl.h>
15193 +#include <linux/grsecurity.h>
15194 +#include <linux/grinternal.h>
15195 +
15196 +#define GR_BIND        0x01
15197 +#define GR_CONNECT     0x02
15198 +#define GR_INVERT      0x04
15199 +
15200 +static const char * gr_protocols[256] = {
15201 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
15202 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
15203 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
15204 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
15205 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
15206 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
15207 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
15208 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
15209 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
15210 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
15211 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
15212 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
15213 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
15214 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
15215 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
15216 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
15217 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
15218 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
15219 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
15220 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
15221 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
15222 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
15223 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
15224 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
15225 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
15226 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
15227 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
15228 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
15229 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
15230 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
15231 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
15232 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
15233 +       };
15234 +
15235 +static const char * gr_socktypes[11] = {
15236 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
15237 +       "unknown:7", "unknown:8", "unknown:9", "packet"
15238 +       };
15239 +
15240 +const char *
15241 +gr_proto_to_name(unsigned char proto)
15242 +{
15243 +       return gr_protocols[proto];
15244 +}
15245 +
15246 +const char *
15247 +gr_socktype_to_name(unsigned char type)
15248 +{
15249 +       return gr_socktypes[type];
15250 +}
15251 +
15252 +int
15253 +gr_search_socket(const int domain, const int type, const int protocol)
15254 +{
15255 +       struct acl_subject_label *curr;
15256 +
15257 +       if (unlikely(!gr_acl_is_enabled()))
15258 +               goto exit;
15259 +
15260 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
15261 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
15262 +               goto exit;      // let the kernel handle it
15263 +
15264 +       curr = current->acl;
15265 +
15266 +       if (!curr->ips)
15267 +               goto exit;
15268 +
15269 +       if ((curr->ip_type & (1 << type)) &&
15270 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
15271 +               goto exit;
15272 +
15273 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
15274 +               /* we don't place acls on raw sockets , and sometimes
15275 +                  dgram/ip sockets are opened for ioctl and not
15276 +                  bind/connect, so we'll fake a bind learn log */
15277 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
15278 +                       __u32 fakeip = 0;
15279 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15280 +                                      current->role->roletype, current->uid,
15281 +                                      current->gid, current->exec_file ?
15282 +                                      gr_to_filename(current->exec_file->f_dentry,
15283 +                                      current->exec_file->f_vfsmnt) :
15284 +                                      curr->filename, curr->filename,
15285 +                                      NIPQUAD(fakeip), 0, type,
15286 +                                      protocol, GR_CONNECT, 
15287 +NIPQUAD(current->signal->curr_ip));
15288 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
15289 +                       __u32 fakeip = 0;
15290 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15291 +                                      current->role->roletype, current->uid,
15292 +                                      current->gid, current->exec_file ?
15293 +                                      gr_to_filename(current->exec_file->f_dentry,
15294 +                                      current->exec_file->f_vfsmnt) :
15295 +                                      curr->filename, curr->filename,
15296 +                                      NIPQUAD(fakeip), 0, type,
15297 +                                      protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
15298 +               }
15299 +               /* we'll log when they use connect or bind */
15300 +               goto exit;
15301 +       }
15302 +
15303 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
15304 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
15305 +
15306 +       return 0;
15307 +      exit:
15308 +       return 1;
15309 +}
15310 +
15311 +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)
15312 +{
15313 +       if ((ip->mode & mode) &&
15314 +           (ip_port >= ip->low) &&
15315 +           (ip_port <= ip->high) &&
15316 +           ((ntohl(ip_addr) & our_netmask) ==
15317 +            (ntohl(our_addr) & our_netmask))
15318 +           && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
15319 +           && (ip->type & (1 << type))) {
15320 +               if (ip->mode & GR_INVERT)
15321 +                       return 2; // specifically denied
15322 +               else
15323 +                       return 1; // allowed
15324 +       }
15325 +
15326 +       return 0; // not specifically allowed, may continue parsing
15327 +}
15328 +
15329 +static int
15330 +gr_search_connectbind(const int mode, const struct sock *sk,
15331 +                     const struct sockaddr_in *addr, const int type)
15332 +{
15333 +       char iface[IFNAMSIZ] = {0};
15334 +       struct acl_subject_label *curr;
15335 +       struct acl_ip_label *ip;
15336 +       struct net_device *dev;
15337 +       struct in_device *idev;
15338 +       unsigned long i;
15339 +       int ret;
15340 +       __u32 ip_addr = 0;
15341 +       __u32 our_addr;
15342 +       __u32 our_netmask;
15343 +       char *p;
15344 +       __u16 ip_port = 0;
15345 +
15346 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
15347 +               return 1;
15348 +
15349 +       curr = current->acl;
15350 +
15351 +       if (!curr->ips)
15352 +               return 1;
15353 +
15354 +       ip_addr = addr->sin_addr.s_addr;
15355 +       ip_port = ntohs(addr->sin_port);
15356 +
15357 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
15358 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
15359 +                              current->role->roletype, current->uid,
15360 +                              current->gid, current->exec_file ?
15361 +                              gr_to_filename(current->exec_file->f_dentry,
15362 +                              current->exec_file->f_vfsmnt) :
15363 +                              curr->filename, curr->filename,
15364 +                              NIPQUAD(ip_addr), ip_port, type,
15365 +                              sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
15366 +               return 1;
15367 +       }
15368 +
15369 +       for (i = 0; i < curr->ip_num; i++) {
15370 +               ip = *(curr->ips + i);
15371 +               if (ip->iface != NULL) {
15372 +                       strncpy(iface, ip->iface, IFNAMSIZ - 1);
15373 +                       p = strchr(iface, ':');
15374 +                       if (p != NULL)
15375 +                               *p = '\0';
15376 +                       dev = dev_get_by_name(iface);
15377 +                       if (dev == NULL)
15378 +                               continue;
15379 +                       idev = in_dev_get(dev);
15380 +                       if (idev == NULL) {
15381 +                               dev_put(dev);
15382 +                               continue;
15383 +                       }
15384 +                       rcu_read_lock();
15385 +                       for_ifa(idev) {
15386 +                               if (!strcmp(ip->iface, ifa->ifa_label)) {
15387 +                                       our_addr = ifa->ifa_address;
15388 +                                       our_netmask = 0xffffffff;
15389 +                                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
15390 +                                       if (ret == 1) {
15391 +                                               rcu_read_unlock();
15392 +                                               in_dev_put(idev);
15393 +                                               dev_put(dev);
15394 +                                               return 1;
15395 +                                       } else if (ret == 2) {
15396 +                                               rcu_read_unlock();
15397 +                                               in_dev_put(idev);
15398 +                                               dev_put(dev);
15399 +                                               goto denied;
15400 +                                       }
15401 +                               }
15402 +                       } endfor_ifa(idev);
15403 +                       rcu_read_unlock();
15404 +                       in_dev_put(idev);
15405 +                       dev_put(dev);
15406 +               } else {
15407 +                       our_addr = ip->addr;
15408 +                       our_netmask = ip->netmask;
15409 +                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
15410 +                       if (ret == 1)
15411 +                               return 1;
15412 +                       else if (ret == 2)
15413 +                               goto denied;
15414 +               }
15415 +       }
15416 +
15417 +denied:
15418 +       if (mode == GR_BIND)
15419 +               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));
15420 +       else if (mode == GR_CONNECT)
15421 +               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));
15422 +
15423 +       return 0;
15424 +}
15425 +
15426 +int
15427 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
15428 +{
15429 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
15430 +}
15431 +
15432 +int
15433 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
15434 +{
15435 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
15436 +}
15437 +
15438 +int gr_search_listen(const struct socket *sock)
15439 +{
15440 +       struct sock *sk = sock->sk;
15441 +       struct sockaddr_in addr;
15442 +
15443 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
15444 +       addr.sin_port = inet_sk(sk)->sport;
15445 +
15446 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
15447 +}
15448 +
15449 +int gr_search_accept(const struct socket *sock)
15450 +{
15451 +       struct sock *sk = sock->sk;
15452 +       struct sockaddr_in addr;
15453 +
15454 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
15455 +       addr.sin_port = inet_sk(sk)->sport;
15456 +
15457 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
15458 +}
15459 +
15460 +int
15461 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
15462 +{
15463 +       if (addr)
15464 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
15465 +       else {
15466 +               struct sockaddr_in sin;
15467 +               const struct inet_sock *inet = inet_sk(sk);
15468 +
15469 +               sin.sin_addr.s_addr = inet->daddr;
15470 +               sin.sin_port = inet->dport;
15471 +
15472 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
15473 +       }
15474 +}
15475 +
15476 +int
15477 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
15478 +{
15479 +       struct sockaddr_in sin;
15480 +
15481 +       if (unlikely(skb->len < sizeof (struct udphdr)))
15482 +               return 1;       // skip this packet
15483 +
15484 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
15485 +       sin.sin_port = skb->h.uh->source;
15486 +
15487 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
15488 +}
15489 diff -urNp linux-2.6.17.7/grsecurity/gracl_learn.c linux-2.6.17.7/grsecurity/gracl_learn.c
15490 --- linux-2.6.17.7/grsecurity/gracl_learn.c     1969-12-31 19:00:00.000000000 -0500
15491 +++ linux-2.6.17.7/grsecurity/gracl_learn.c     2006-08-01 20:29:47.000000000 -0400
15492 @@ -0,0 +1,204 @@
15493 +#include <linux/kernel.h>
15494 +#include <linux/mm.h>
15495 +#include <linux/sched.h>
15496 +#include <linux/poll.h>
15497 +#include <linux/smp_lock.h>
15498 +#include <linux/string.h>
15499 +#include <linux/file.h>
15500 +#include <linux/types.h>
15501 +#include <linux/vmalloc.h>
15502 +#include <linux/grinternal.h>
15503 +
15504 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
15505 +                                  size_t count, loff_t *ppos);
15506 +extern int gr_acl_is_enabled(void);
15507 +
15508 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
15509 +static int gr_learn_attached;
15510 +
15511 +/* use a 512k buffer */
15512 +#define LEARN_BUFFER_SIZE (512 * 1024)
15513 +
15514 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
15515 +static DECLARE_MUTEX(gr_learn_user_sem);
15516 +
15517 +/* we need to maintain two buffers, so that the kernel context of grlearn
15518 +   uses a semaphore around the userspace copying, and the other kernel contexts
15519 +   use a spinlock when copying into the buffer, since they cannot sleep
15520 +*/
15521 +static char *learn_buffer;
15522 +static char *learn_buffer_user;
15523 +static int learn_buffer_len;
15524 +static int learn_buffer_user_len;
15525 +
15526 +static ssize_t
15527 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
15528 +{
15529 +       DECLARE_WAITQUEUE(wait, current);
15530 +       ssize_t retval = 0;
15531 +
15532 +       add_wait_queue(&learn_wait, &wait);
15533 +       set_current_state(TASK_INTERRUPTIBLE);
15534 +       do {
15535 +               down(&gr_learn_user_sem);
15536 +               spin_lock(&gr_learn_lock);
15537 +               if (learn_buffer_len)
15538 +                       break;
15539 +               spin_unlock(&gr_learn_lock);
15540 +               up(&gr_learn_user_sem);
15541 +               if (file->f_flags & O_NONBLOCK) {
15542 +                       retval = -EAGAIN;
15543 +                       goto out;
15544 +               }
15545 +               if (signal_pending(current)) {
15546 +                       retval = -ERESTARTSYS;
15547 +                       goto out;
15548 +               }
15549 +
15550 +               schedule();
15551 +       } while (1);
15552 +
15553 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
15554 +       learn_buffer_user_len = learn_buffer_len;
15555 +       retval = learn_buffer_len;
15556 +       learn_buffer_len = 0;
15557 +
15558 +       spin_unlock(&gr_learn_lock);
15559 +
15560 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
15561 +               retval = -EFAULT;
15562 +
15563 +       up(&gr_learn_user_sem);
15564 +out:
15565 +       set_current_state(TASK_RUNNING);
15566 +       remove_wait_queue(&learn_wait, &wait);
15567 +       return retval;
15568 +}
15569 +
15570 +static unsigned int
15571 +poll_learn(struct file * file, poll_table * wait)
15572 +{
15573 +       poll_wait(file, &learn_wait, wait);
15574 +
15575 +       if (learn_buffer_len)
15576 +               return (POLLIN | POLLRDNORM);
15577 +
15578 +       return 0;
15579 +}
15580 +
15581 +void
15582 +gr_clear_learn_entries(void)
15583 +{
15584 +       char *tmp;
15585 +
15586 +       down(&gr_learn_user_sem);
15587 +       if (learn_buffer != NULL) {
15588 +               spin_lock(&gr_learn_lock);
15589 +               tmp = learn_buffer;
15590 +               learn_buffer = NULL;
15591 +               spin_unlock(&gr_learn_lock);
15592 +               vfree(learn_buffer);
15593 +       }
15594 +       if (learn_buffer_user != NULL) {
15595 +               vfree(learn_buffer_user);
15596 +               learn_buffer_user = NULL;
15597 +       }
15598 +       learn_buffer_len = 0;
15599 +       up(&gr_learn_user_sem);
15600 +
15601 +       return;
15602 +}
15603 +
15604 +void
15605 +gr_add_learn_entry(const char *fmt, ...)
15606 +{
15607 +       va_list args;
15608 +       unsigned int len;
15609 +
15610 +       if (!gr_learn_attached)
15611 +               return;
15612 +
15613 +       spin_lock(&gr_learn_lock);
15614 +
15615 +       /* leave a gap at the end so we know when it's "full" but don't have to
15616 +          compute the exact length of the string we're trying to append
15617 +       */
15618 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
15619 +               spin_unlock(&gr_learn_lock);
15620 +               wake_up_interruptible(&learn_wait);
15621 +               return;
15622 +       }
15623 +       if (learn_buffer == NULL) {
15624 +               spin_unlock(&gr_learn_lock);
15625 +               return;
15626 +       }
15627 +
15628 +       va_start(args, fmt);
15629 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
15630 +       va_end(args);
15631 +
15632 +       learn_buffer_len += len + 1;
15633 +
15634 +       spin_unlock(&gr_learn_lock);
15635 +       wake_up_interruptible(&learn_wait);
15636 +
15637 +       return;
15638 +}
15639 +
15640 +static int
15641 +open_learn(struct inode *inode, struct file *file)
15642 +{
15643 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
15644 +               return -EBUSY;
15645 +       if (file->f_mode & FMODE_READ) {
15646 +               down(&gr_learn_user_sem);
15647 +               if (learn_buffer == NULL)
15648 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
15649 +               if (learn_buffer_user == NULL)
15650 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
15651 +               if (learn_buffer == NULL)
15652 +                       return -ENOMEM;
15653 +               if (learn_buffer_user == NULL)
15654 +                       return -ENOMEM;
15655 +               learn_buffer_len = 0;
15656 +               learn_buffer_user_len = 0;
15657 +               gr_learn_attached = 1;
15658 +               up(&gr_learn_user_sem);
15659 +       }
15660 +       return 0;
15661 +}
15662 +
15663 +static int
15664 +close_learn(struct inode *inode, struct file *file)
15665 +{
15666 +       char *tmp;
15667 +
15668 +       if (file->f_mode & FMODE_READ) {
15669 +               down(&gr_learn_user_sem);
15670 +               if (learn_buffer != NULL) {
15671 +                       spin_lock(&gr_learn_lock);
15672 +                       tmp = learn_buffer;
15673 +                       learn_buffer = NULL;
15674 +                       spin_unlock(&gr_learn_lock);
15675 +                       vfree(tmp);
15676 +               }
15677 +               if (learn_buffer_user != NULL) {
15678 +                       vfree(learn_buffer_user);
15679 +                       learn_buffer_user = NULL;
15680 +               }
15681 +               learn_buffer_len = 0;
15682 +               learn_buffer_user_len = 0;
15683 +               gr_learn_attached = 0;
15684 +               up(&gr_learn_user_sem);
15685 +       }
15686 +
15687 +       return 0;
15688 +}
15689 +               
15690 +struct file_operations grsec_fops = {
15691 +       .read           = read_learn,
15692 +       .write          = write_grsec_handler,
15693 +       .open           = open_learn,
15694 +       .release        = close_learn,
15695 +       .poll           = poll_learn,
15696 +};
15697 diff -urNp linux-2.6.17.7/grsecurity/gracl_res.c linux-2.6.17.7/grsecurity/gracl_res.c
15698 --- linux-2.6.17.7/grsecurity/gracl_res.c       1969-12-31 19:00:00.000000000 -0500
15699 +++ linux-2.6.17.7/grsecurity/gracl_res.c       2006-08-01 20:29:47.000000000 -0400
15700 @@ -0,0 +1,45 @@
15701 +#include <linux/kernel.h>
15702 +#include <linux/sched.h>
15703 +#include <linux/gracl.h>
15704 +#include <linux/grinternal.h>
15705 +
15706 +static const char *restab_log[] = {
15707 +       [RLIMIT_CPU] = "RLIMIT_CPU",
15708 +       [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
15709 +       [RLIMIT_DATA] = "RLIMIT_DATA",
15710 +       [RLIMIT_STACK] = "RLIMIT_STACK",
15711 +       [RLIMIT_CORE] = "RLIMIT_CORE",
15712 +       [RLIMIT_RSS] = "RLIMIT_RSS",
15713 +       [RLIMIT_NPROC] = "RLIMIT_NPROC",
15714 +       [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
15715 +       [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
15716 +       [RLIMIT_AS] = "RLIMIT_AS",
15717 +       [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
15718 +       [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
15719 +};
15720 +
15721 +void
15722 +gr_log_resource(const struct task_struct *task,
15723 +               const int res, const unsigned long wanted, const int gt)
15724 +{
15725 +       if (res == RLIMIT_NPROC && 
15726 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
15727 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
15728 +               return;
15729 +       else if (res == RLIMIT_MEMLOCK &&
15730 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
15731 +               return;
15732 +
15733 +       if (!gr_acl_is_enabled() && !grsec_resource_logging)
15734 +               return;
15735 +
15736 +       preempt_disable();
15737 +
15738 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
15739 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
15740 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
15741 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
15742 +       preempt_enable_no_resched();
15743 +
15744 +       return;
15745 +}
15746 diff -urNp linux-2.6.17.7/grsecurity/gracl_segv.c linux-2.6.17.7/grsecurity/gracl_segv.c
15747 --- linux-2.6.17.7/grsecurity/gracl_segv.c      1969-12-31 19:00:00.000000000 -0500
15748 +++ linux-2.6.17.7/grsecurity/gracl_segv.c      2006-08-01 20:29:47.000000000 -0400
15749 @@ -0,0 +1,295 @@
15750 +#include <linux/kernel.h>
15751 +#include <linux/mm.h>
15752 +#include <asm/uaccess.h>
15753 +#include <asm/errno.h>
15754 +#include <asm/mman.h>
15755 +#include <net/sock.h>
15756 +#include <linux/file.h>
15757 +#include <linux/fs.h>
15758 +#include <linux/net.h>
15759 +#include <linux/in.h>
15760 +#include <linux/smp_lock.h>
15761 +#include <linux/slab.h>
15762 +#include <linux/types.h>
15763 +#include <linux/sched.h>
15764 +#include <linux/timer.h>
15765 +#include <linux/gracl.h>
15766 +#include <linux/grsecurity.h>
15767 +#include <linux/grinternal.h>
15768 +
15769 +static struct crash_uid *uid_set;
15770 +static unsigned short uid_used;
15771 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
15772 +extern rwlock_t gr_inode_lock;
15773 +extern struct acl_subject_label *
15774 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
15775 +                             struct acl_role_label *role);
15776 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
15777 +
15778 +int
15779 +gr_init_uidset(void)
15780 +{
15781 +       uid_set =
15782 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
15783 +       uid_used = 0;
15784 +
15785 +       return uid_set ? 1 : 0;
15786 +}
15787 +
15788 +void
15789 +gr_free_uidset(void)
15790 +{
15791 +       if (uid_set)
15792 +               kfree(uid_set);
15793 +
15794 +       return;
15795 +}
15796 +
15797 +int
15798 +gr_find_uid(const uid_t uid)
15799 +{
15800 +       struct crash_uid *tmp = uid_set;
15801 +       uid_t buid;
15802 +       int low = 0, high = uid_used - 1, mid;
15803 +
15804 +       while (high >= low) {
15805 +               mid = (low + high) >> 1;
15806 +               buid = tmp[mid].uid;
15807 +               if (buid == uid)
15808 +                       return mid;
15809 +               if (buid > uid)
15810 +                       high = mid - 1;
15811 +               if (buid < uid)
15812 +                       low = mid + 1;
15813 +       }
15814 +
15815 +       return -1;
15816 +}
15817 +
15818 +static __inline__ void
15819 +gr_insertsort(void)
15820 +{
15821 +       unsigned short i, j;
15822 +       struct crash_uid index;
15823 +
15824 +       for (i = 1; i < uid_used; i++) {
15825 +               index = uid_set[i];
15826 +               j = i;
15827 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
15828 +                       uid_set[j] = uid_set[j - 1];
15829 +                       j--;
15830 +               }
15831 +               uid_set[j] = index;
15832 +       }
15833 +
15834 +       return;
15835 +}
15836 +
15837 +static __inline__ void
15838 +gr_insert_uid(const uid_t uid, const unsigned long expires)
15839 +{
15840 +       int loc;
15841 +
15842 +       if (uid_used == GR_UIDTABLE_MAX)
15843 +               return;
15844 +
15845 +       loc = gr_find_uid(uid);
15846 +
15847 +       if (loc >= 0) {
15848 +               uid_set[loc].expires = expires;
15849 +               return;
15850 +       }
15851 +
15852 +       uid_set[uid_used].uid = uid;
15853 +       uid_set[uid_used].expires = expires;
15854 +       uid_used++;
15855 +
15856 +       gr_insertsort();
15857 +
15858 +       return;
15859 +}
15860 +
15861 +void
15862 +gr_remove_uid(const unsigned short loc)
15863 +{
15864 +       unsigned short i;
15865 +
15866 +       for (i = loc + 1; i < uid_used; i++)
15867 +               uid_set[i - 1] = uid_set[i];
15868 +
15869 +       uid_used--;
15870 +
15871 +       return;
15872 +}
15873 +
15874 +int
15875 +gr_check_crash_uid(const uid_t uid)
15876 +{
15877 +       int loc;
15878 +       int ret = 0;
15879 +
15880 +       if (unlikely(!gr_acl_is_enabled()))
15881 +               return 0;
15882 +
15883 +       spin_lock(&gr_uid_lock);
15884 +       loc = gr_find_uid(uid);
15885 +
15886 +       if (loc < 0)
15887 +               goto out_unlock;
15888 +
15889 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
15890 +               gr_remove_uid(loc);
15891 +       else
15892 +               ret = 1;
15893 +
15894 +out_unlock:
15895 +       spin_unlock(&gr_uid_lock);
15896 +       return ret;
15897 +}
15898 +
15899 +static __inline__ int
15900 +proc_is_setxid(const struct task_struct *task)
15901 +{
15902 +       if (task->uid != task->euid || task->uid != task->suid ||
15903 +           task->uid != task->fsuid)
15904 +               return 1;
15905 +       if (task->gid != task->egid || task->gid != task->sgid ||
15906 +           task->gid != task->fsgid)
15907 +               return 1;
15908 +
15909 +       return 0;
15910 +}
15911 +static __inline__ int
15912 +gr_fake_force_sig(int sig, struct task_struct *t)
15913 +{
15914 +       unsigned long int flags;
15915 +       int ret;
15916 +
15917 +       spin_lock_irqsave(&t->sighand->siglock, flags);
15918 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
15919 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
15920 +               sigdelset(&t->blocked, sig);
15921 +               recalc_sigpending_tsk(t);
15922 +       }
15923 +       ret = specific_send_sig_info(sig, (void*)1L, t);
15924 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
15925 +
15926 +       return ret;
15927 +}
15928 +
15929 +void
15930 +gr_handle_crash(struct task_struct *task, const int sig)
15931 +{
15932 +       struct acl_subject_label *curr;
15933 +       struct acl_subject_label *curr2;
15934 +       struct task_struct *tsk, *tsk2;
15935 +
15936 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
15937 +               return;
15938 +
15939 +       if (unlikely(!gr_acl_is_enabled()))
15940 +               return;
15941 +
15942 +       curr = task->acl;
15943 +
15944 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
15945 +               return;
15946 +
15947 +       if (time_before_eq(curr->expires, get_seconds())) {
15948 +               curr->expires = 0;
15949 +               curr->crashes = 0;
15950 +       }
15951 +
15952 +       curr->crashes++;
15953 +
15954 +       if (!curr->expires)
15955 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
15956 +
15957 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
15958 +           time_after(curr->expires, get_seconds())) {
15959 +               if (task->uid && proc_is_setxid(task)) {
15960 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
15961 +                       spin_lock(&gr_uid_lock);
15962 +                       gr_insert_uid(task->uid, curr->expires);
15963 +                       spin_unlock(&gr_uid_lock);
15964 +                       curr->expires = 0;
15965 +                       curr->crashes = 0;
15966 +                       read_lock(&tasklist_lock);
15967 +                       do_each_thread(tsk2, tsk) {
15968 +                               if (tsk != task && tsk->uid == task->uid)
15969 +                                       gr_fake_force_sig(SIGKILL, tsk);
15970 +                       } while_each_thread(tsk2, tsk);
15971 +                       read_unlock(&tasklist_lock);
15972 +               } else {
15973 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
15974 +                       read_lock(&tasklist_lock);
15975 +                       do_each_thread(tsk2, tsk) {
15976 +                               if (likely(tsk != task)) {
15977 +                                       curr2 = tsk->acl;
15978 +
15979 +                                       if (curr2->device == curr->device &&
15980 +                                           curr2->inode == curr->inode)
15981 +                                               gr_fake_force_sig(SIGKILL, tsk);
15982 +                               }
15983 +                       } while_each_thread(tsk2, tsk);
15984 +                       read_unlock(&tasklist_lock);
15985 +               }
15986 +       }
15987 +
15988 +       return;
15989 +}
15990 +
15991 +int
15992 +gr_check_crash_exec(const struct file *filp)
15993 +{
15994 +       struct acl_subject_label *curr;
15995 +
15996 +       if (unlikely(!gr_acl_is_enabled()))
15997 +               return 0;
15998 +
15999 +       read_lock(&gr_inode_lock);
16000 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
16001 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
16002 +                                    current->role);
16003 +       read_unlock(&gr_inode_lock);
16004 +
16005 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
16006 +           (!curr->crashes && !curr->expires))
16007 +               return 0;
16008 +
16009 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
16010 +           time_after(curr->expires, get_seconds()))
16011 +               return 1;
16012 +       else if (time_before_eq(curr->expires, get_seconds())) {
16013 +               curr->crashes = 0;
16014 +               curr->expires = 0;
16015 +       }
16016 +
16017 +       return 0;
16018 +}
16019 +
16020 +void
16021 +gr_handle_alertkill(struct task_struct *task)
16022 +{
16023 +       struct acl_subject_label *curracl;
16024 +       __u32 curr_ip;
16025 +       struct task_struct *p, *p2;
16026 +
16027 +       if (unlikely(!gr_acl_is_enabled()))
16028 +               return;
16029 +
16030 +       curracl = task->acl;
16031 +       curr_ip = task->signal->curr_ip;
16032 +
16033 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
16034 +               read_lock(&tasklist_lock);
16035 +               do_each_thread(p2, p) {
16036 +                       if (p->signal->curr_ip == curr_ip)
16037 +                               gr_fake_force_sig(SIGKILL, p);
16038 +               } while_each_thread(p2, p);
16039 +               read_unlock(&tasklist_lock);
16040 +       } else if (curracl->mode & GR_KILLPROC)
16041 +               gr_fake_force_sig(SIGKILL, task);
16042 +
16043 +       return;
16044 +}
16045 diff -urNp linux-2.6.17.7/grsecurity/gracl_shm.c linux-2.6.17.7/grsecurity/gracl_shm.c
16046 --- linux-2.6.17.7/grsecurity/gracl_shm.c       1969-12-31 19:00:00.000000000 -0500
16047 +++ linux-2.6.17.7/grsecurity/gracl_shm.c       2006-08-01 20:29:47.000000000 -0400
16048 @@ -0,0 +1,34 @@
16049 +#include <linux/kernel.h>
16050 +#include <linux/mm.h>
16051 +#include <linux/sched.h>
16052 +#include <linux/file.h>
16053 +#include <linux/ipc.h>
16054 +#include <linux/gracl.h>
16055 +#include <linux/grsecurity.h>
16056 +#include <linux/grinternal.h>
16057 +#include <linux/vs_pid.h>
16058 +
16059 +int
16060 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16061 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
16062 +{
16063 +       struct task_struct *task;
16064 +
16065 +       if (!gr_acl_is_enabled())
16066 +               return 1;
16067 +
16068 +       task = find_task_by_pid(shm_cprid);
16069 +
16070 +       if (unlikely(!task))
16071 +               task = find_task_by_pid(shm_lapid);
16072 +
16073 +       if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
16074 +                             (task->pid == shm_lapid)) &&
16075 +                    (task->acl->mode & GR_PROTSHM) &&
16076 +                    (task->acl != current->acl))) {
16077 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
16078 +               return 0;
16079 +       }
16080 +
16081 +       return 1;
16082 +}
16083 diff -urNp linux-2.6.17.7/grsecurity/grsec_chdir.c linux-2.6.17.7/grsecurity/grsec_chdir.c
16084 --- linux-2.6.17.7/grsecurity/grsec_chdir.c     1969-12-31 19:00:00.000000000 -0500
16085 +++ linux-2.6.17.7/grsecurity/grsec_chdir.c     2006-08-01 20:29:47.000000000 -0400
16086 @@ -0,0 +1,19 @@
16087 +#include <linux/kernel.h>
16088 +#include <linux/sched.h>
16089 +#include <linux/fs.h>
16090 +#include <linux/file.h>
16091 +#include <linux/grsecurity.h>
16092 +#include <linux/grinternal.h>
16093 +
16094 +void
16095 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
16096 +{
16097 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16098 +       if ((grsec_enable_chdir && grsec_enable_group &&
16099 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
16100 +                                             !grsec_enable_group)) {
16101 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
16102 +       }
16103 +#endif
16104 +       return;
16105 +}
16106 diff -urNp linux-2.6.17.7/grsecurity/grsec_chroot.c linux-2.6.17.7/grsecurity/grsec_chroot.c
16107 --- linux-2.6.17.7/grsecurity/grsec_chroot.c    1969-12-31 19:00:00.000000000 -0500
16108 +++ linux-2.6.17.7/grsecurity/grsec_chroot.c    2006-08-01 20:29:47.000000000 -0400
16109 @@ -0,0 +1,332 @@
16110 +#include <linux/kernel.h>
16111 +#include <linux/module.h>
16112 +#include <linux/sched.h>
16113 +#include <linux/file.h>
16114 +#include <linux/fs.h>
16115 +#include <linux/mount.h>
16116 +#include <linux/types.h>
16117 +#include <linux/grinternal.h>
16118 +
16119 +int
16120 +gr_handle_chroot_unix(const pid_t pid)
16121 +{
16122 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16123 +       struct pid *spid = NULL;
16124 +
16125 +       if (unlikely(!grsec_enable_chroot_unix))
16126 +               return 1;
16127 +
16128 +       if (likely(!proc_is_chrooted(current)))
16129 +               return 1;
16130 +
16131 +       read_lock(&tasklist_lock);
16132 +
16133 +       spid = find_pid(pid);
16134 +       if (spid) {
16135 +               struct task_struct *p;
16136 +               p = pid_task(spid, PIDTYPE_PID);
16137 +               task_lock(p);
16138 +               if (unlikely(!have_same_root(current, p))) {
16139 +                       task_unlock(p);
16140 +                       read_unlock(&tasklist_lock);
16141 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
16142 +                       return 0;
16143 +               }
16144 +               task_unlock(p);
16145 +       }
16146 +       read_unlock(&tasklist_lock);
16147 +#endif
16148 +       return 1;
16149 +}
16150 +
16151 +int
16152 +gr_handle_chroot_nice(void)
16153 +{
16154 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16155 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
16156 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
16157 +               return -EPERM;
16158 +       }
16159 +#endif
16160 +       return 0;
16161 +}
16162 +
16163 +int
16164 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
16165 +{
16166 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16167 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
16168 +                       && proc_is_chrooted(current)) {
16169 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
16170 +               return -EACCES;
16171 +       }
16172 +#endif
16173 +       return 0;
16174 +}
16175 +
16176 +int
16177 +gr_handle_chroot_rawio(const struct inode *inode)
16178 +{
16179 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16180 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
16181 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
16182 +               return 1;
16183 +#endif
16184 +       return 0;
16185 +}
16186 +
16187 +int
16188 +gr_pid_is_chrooted(struct task_struct *p)
16189 +{
16190 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16191 +       if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !p)
16192 +               return 0;
16193 +
16194 +       task_lock(p);
16195 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
16196 +           !have_same_root(current, p)) {
16197 +               task_unlock(p);
16198 +               return 1;
16199 +       }
16200 +       task_unlock(p);
16201 +#endif
16202 +       return 0;
16203 +}
16204 +
16205 +EXPORT_SYMBOL(gr_pid_is_chrooted);
16206 +
16207 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
16208 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
16209 +{
16210 +       struct dentry *dentry = (struct dentry *)u_dentry;
16211 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
16212 +       struct dentry *realroot;
16213 +       struct vfsmount *realrootmnt;
16214 +       struct dentry *currentroot;
16215 +       struct vfsmount *currentmnt;
16216 +       int ret = 1;
16217 +
16218 +       read_lock(&child_reaper->fs->lock);
16219 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
16220 +       realroot = dget(child_reaper->fs->root);
16221 +       read_unlock(&child_reaper->fs->lock);
16222 +
16223 +       read_lock(&current->fs->lock);
16224 +       currentmnt = mntget(current->fs->rootmnt);
16225 +       currentroot = dget(current->fs->root);
16226 +       read_unlock(&current->fs->lock);
16227 +
16228 +       spin_lock(&dcache_lock);
16229 +       for (;;) {
16230 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
16231 +                    || (dentry == currentroot && mnt == currentmnt)))
16232 +                       break;
16233 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
16234 +                       if (mnt->mnt_parent == mnt)
16235 +                               break;
16236 +                       dentry = mnt->mnt_mountpoint;
16237 +                       mnt = mnt->mnt_parent;
16238 +                       continue;
16239 +               }
16240 +               dentry = dentry->d_parent;
16241 +       }
16242 +       spin_unlock(&dcache_lock);
16243 +
16244 +       dput(currentroot);
16245 +       mntput(currentmnt);
16246 +
16247 +       /* access is outside of chroot */
16248 +       if (dentry == realroot && mnt == realrootmnt)
16249 +               ret = 0;
16250 +
16251 +       dput(realroot);
16252 +       mntput(realrootmnt);
16253 +       return ret;
16254 +}
16255 +#endif
16256 +
16257 +int
16258 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
16259 +{
16260 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16261 +       if (!grsec_enable_chroot_fchdir)
16262 +               return 1;
16263 +
16264 +       if (!proc_is_chrooted(current))
16265 +               return 1;
16266 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
16267 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
16268 +               return 0;
16269 +       }
16270 +#endif
16271 +       return 1;
16272 +}
16273 +
16274 +int
16275 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16276 +               const time_t shm_createtime)
16277 +{
16278 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16279 +       struct pid *pid = NULL;
16280 +       time_t starttime;
16281 +
16282 +       if (unlikely(!grsec_enable_chroot_shmat))
16283 +               return 1;
16284 +
16285 +       if (likely(!proc_is_chrooted(current)))
16286 +               return 1;
16287 +
16288 +       read_lock(&tasklist_lock);
16289 +
16290 +       pid = find_pid(shm_cprid);
16291 +       if (pid) {
16292 +               struct task_struct *p;
16293 +               p = pid_task(pid, PIDTYPE_PID);
16294 +               task_lock(p);
16295 +               starttime = p->start_time.tv_sec;
16296 +               if (unlikely(!have_same_root(current, p) &&
16297 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
16298 +                       task_unlock(p);
16299 +                       read_unlock(&tasklist_lock);
16300 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
16301 +                       return 0;
16302 +               }
16303 +               task_unlock(p);
16304 +       } else {
16305 +               pid = find_pid(shm_lapid);
16306 +               if (pid) {
16307 +                       struct task_struct *p;
16308 +                       p = pid_task(pid, PIDTYPE_PID);
16309 +                       task_lock(p);
16310 +                       if (unlikely(!have_same_root(current, p))) {
16311 +                               task_unlock(p);
16312 +                               read_unlock(&tasklist_lock);
16313 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
16314 +                               return 0;
16315 +                       }
16316 +                       task_unlock(p);
16317 +               }
16318 +       }
16319 +
16320 +       read_unlock(&tasklist_lock);
16321 +#endif
16322 +       return 1;
16323 +}
16324 +
16325 +void
16326 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
16327 +{
16328 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16329 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
16330 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
16331 +#endif
16332 +       return;
16333 +}
16334 +
16335 +int
16336 +gr_handle_chroot_mknod(const struct dentry *dentry,
16337 +                      const struct vfsmount *mnt, const int mode)
16338 +{
16339 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16340 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
16341 +           proc_is_chrooted(current)) {
16342 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
16343 +               return -EPERM;
16344 +       }
16345 +#endif
16346 +       return 0;
16347 +}
16348 +
16349 +int
16350 +gr_handle_chroot_mount(const struct dentry *dentry,
16351 +                      const struct vfsmount *mnt, const char *dev_name)
16352 +{
16353 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16354 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
16355 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
16356 +               return -EPERM;
16357 +       }
16358 +#endif
16359 +       return 0;
16360 +}
16361 +
16362 +int
16363 +gr_handle_chroot_pivot(void)
16364 +{
16365 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16366 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
16367 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
16368 +               return -EPERM;
16369 +       }
16370 +#endif
16371 +       return 0;
16372 +}
16373 +
16374 +int
16375 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
16376 +{
16377 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
16378 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
16379 +           !gr_is_outside_chroot(dentry, mnt)) {
16380 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
16381 +               return -EPERM;
16382 +       }
16383 +#endif
16384 +       return 0;
16385 +}
16386 +
16387 +void
16388 +gr_handle_chroot_caps(struct task_struct *task)
16389 +{
16390 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16391 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
16392 +               task->cap_permitted =
16393 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
16394 +               task->cap_inheritable =
16395 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
16396 +               task->cap_effective =
16397 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
16398 +       }
16399 +#endif
16400 +       return;
16401 +}
16402 +
16403 +int
16404 +gr_handle_chroot_sysctl(const int op)
16405 +{
16406 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
16407 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
16408 +           && (op & 002))
16409 +               return -EACCES;
16410 +#endif
16411 +       return 0;
16412 +}
16413 +
16414 +void
16415 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
16416 +{
16417 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
16418 +       if (grsec_enable_chroot_chdir)
16419 +               set_fs_pwd(current->fs, mnt, dentry);
16420 +#endif
16421 +       return;
16422 +}
16423 +
16424 +int
16425 +gr_handle_chroot_chmod(const struct dentry *dentry,
16426 +                      const struct vfsmount *mnt, const int mode)
16427 +{
16428 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
16429 +       if (grsec_enable_chroot_chmod &&
16430 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
16431 +           proc_is_chrooted(current)) {
16432 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
16433 +               return -EPERM;
16434 +       }
16435 +#endif
16436 +       return 0;
16437 +}
16438 +
16439 +#ifdef CONFIG_SECURITY
16440 +EXPORT_SYMBOL(gr_handle_chroot_caps);
16441 +#endif
16442 diff -urNp linux-2.6.17.7/grsecurity/grsec_disabled.c linux-2.6.17.7/grsecurity/grsec_disabled.c
16443 --- linux-2.6.17.7/grsecurity/grsec_disabled.c  1969-12-31 19:00:00.000000000 -0500
16444 +++ linux-2.6.17.7/grsecurity/grsec_disabled.c  2006-08-01 20:29:47.000000000 -0400
16445 @@ -0,0 +1,418 @@
16446 +#include <linux/kernel.h>
16447 +#include <linux/module.h>
16448 +#include <linux/config.h>
16449 +#include <linux/sched.h>
16450 +#include <linux/file.h>
16451 +#include <linux/fs.h>
16452 +#include <linux/kdev_t.h>
16453 +#include <linux/net.h>
16454 +#include <linux/in.h>
16455 +#include <linux/ip.h>
16456 +#include <linux/skbuff.h>
16457 +#include <linux/sysctl.h>
16458 +
16459 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
16460 +void
16461 +pax_set_initial_flags(struct linux_binprm *bprm)
16462 +{
16463 +       return;
16464 +}
16465 +#endif
16466 +
16467 +#ifdef CONFIG_SYSCTL
16468 +__u32
16469 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
16470 +{
16471 +       return mode;
16472 +}
16473 +#endif
16474 +
16475 +int
16476 +gr_acl_is_enabled(void)
16477 +{
16478 +       return 0;
16479 +}
16480 +
16481 +int
16482 +gr_handle_rawio(const struct inode *inode)
16483 +{
16484 +       return 0;
16485 +}
16486 +
16487 +void
16488 +gr_acl_handle_psacct(struct task_struct *task, const long code)
16489 +{
16490 +       return;
16491 +}
16492 +
16493 +int
16494 +gr_handle_ptrace(struct task_struct *task, const long request)
16495 +{
16496 +       return 0;
16497 +}
16498 +
16499 +int
16500 +gr_handle_proc_ptrace(struct task_struct *task)
16501 +{
16502 +       return 0;
16503 +}
16504 +
16505 +void
16506 +gr_learn_resource(const struct task_struct *task,
16507 +                 const int res, const unsigned long wanted, const int gt)
16508 +{
16509 +       return;
16510 +}
16511 +
16512 +int
16513 +gr_set_acls(const int type)
16514 +{
16515 +       return 0;
16516 +}
16517 +
16518 +int
16519 +gr_check_hidden_task(const struct task_struct *tsk)
16520 +{
16521 +       return 0;
16522 +}
16523 +
16524 +int
16525 +gr_check_protected_task(const struct task_struct *task)
16526 +{
16527 +       return 0;
16528 +}
16529 +
16530 +void
16531 +gr_copy_label(struct task_struct *tsk)
16532 +{
16533 +       return;
16534 +}
16535 +
16536 +void
16537 +gr_set_pax_flags(struct task_struct *task)
16538 +{
16539 +       return;
16540 +}
16541 +
16542 +int
16543 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
16544 +{
16545 +       return 0;
16546 +}
16547 +
16548 +void
16549 +gr_handle_delete(const ino_t ino, const dev_t dev)
16550 +{
16551 +       return;
16552 +}
16553 +
16554 +void
16555 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
16556 +{
16557 +       return;
16558 +}
16559 +
16560 +void
16561 +gr_handle_crash(struct task_struct *task, const int sig)
16562 +{
16563 +       return;
16564 +}
16565 +
16566 +int
16567 +gr_check_crash_exec(const struct file *filp)
16568 +{
16569 +       return 0;
16570 +}
16571 +
16572 +int
16573 +gr_check_crash_uid(const uid_t uid)
16574 +{
16575 +       return 0;
16576 +}
16577 +
16578 +void
16579 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
16580 +                struct dentry *old_dentry,
16581 +                struct dentry *new_dentry,
16582 +                struct vfsmount *mnt, const __u8 replace)
16583 +{
16584 +       return;
16585 +}
16586 +
16587 +int
16588 +gr_search_socket(const int family, const int type, const int protocol)
16589 +{
16590 +       return 1;
16591 +}
16592 +
16593 +int
16594 +gr_search_connectbind(const int mode, const struct socket *sock,
16595 +                     const struct sockaddr_in *addr)
16596 +{
16597 +       return 1;
16598 +}
16599 +
16600 +int
16601 +gr_task_is_capable(struct task_struct *task, const int cap)
16602 +{
16603 +       return 1;
16604 +}
16605 +
16606 +int
16607 +gr_is_capable_nolog(const int cap)
16608 +{
16609 +       return 1;
16610 +}
16611 +
16612 +void
16613 +gr_handle_alertkill(struct task_struct *task)
16614 +{
16615 +       return;
16616 +}
16617 +
16618 +__u32
16619 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
16620 +{
16621 +       return 1;
16622 +}
16623 +
16624 +__u32
16625 +gr_acl_handle_hidden_file(const struct dentry * dentry,
16626 +                         const struct vfsmount * mnt)
16627 +{
16628 +       return 1;
16629 +}
16630 +
16631 +__u32
16632 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
16633 +                  const int fmode)
16634 +{
16635 +       return 1;
16636 +}
16637 +
16638 +__u32
16639 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
16640 +{
16641 +       return 1;
16642 +}
16643 +
16644 +__u32
16645 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
16646 +{
16647 +       return 1;
16648 +}
16649 +
16650 +int
16651 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
16652 +                  unsigned int *vm_flags)
16653 +{
16654 +       return 1;
16655 +}
16656 +
16657 +__u32
16658 +gr_acl_handle_truncate(const struct dentry * dentry,
16659 +                      const struct vfsmount * mnt)
16660 +{
16661 +       return 1;
16662 +}
16663 +
16664 +__u32
16665 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
16666 +{
16667 +       return 1;
16668 +}
16669 +
16670 +__u32
16671 +gr_acl_handle_access(const struct dentry * dentry,
16672 +                    const struct vfsmount * mnt, const int fmode)
16673 +{
16674 +       return 1;
16675 +}
16676 +
16677 +__u32
16678 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
16679 +                    mode_t mode)
16680 +{
16681 +       return 1;
16682 +}
16683 +
16684 +__u32
16685 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
16686 +                   mode_t mode)
16687 +{
16688 +       return 1;
16689 +}
16690 +
16691 +__u32
16692 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
16693 +{
16694 +       return 1;
16695 +}
16696 +
16697 +void
16698 +grsecurity_init(void)
16699 +{
16700 +       return;
16701 +}
16702 +
16703 +__u32
16704 +gr_acl_handle_mknod(const struct dentry * new_dentry,
16705 +                   const struct dentry * parent_dentry,
16706 +                   const struct vfsmount * parent_mnt,
16707 +                   const int mode)
16708 +{
16709 +       return 1;
16710 +}
16711 +
16712 +__u32
16713 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
16714 +                   const struct dentry * parent_dentry,
16715 +                   const struct vfsmount * parent_mnt)
16716 +{
16717 +       return 1;
16718 +}
16719 +
16720 +__u32
16721 +gr_acl_handle_symlink(const struct dentry * new_dentry,
16722 +                     const struct dentry * parent_dentry,
16723 +                     const struct vfsmount * parent_mnt, const char *from)
16724 +{
16725 +       return 1;
16726 +}
16727 +
16728 +__u32
16729 +gr_acl_handle_link(const struct dentry * new_dentry,
16730 +                  const struct dentry * parent_dentry,
16731 +                  const struct vfsmount * parent_mnt,
16732 +                  const struct dentry * old_dentry,
16733 +                  const struct vfsmount * old_mnt, const char *to)
16734 +{
16735 +       return 1;
16736 +}
16737 +
16738 +int
16739 +gr_acl_handle_rename(const struct dentry *new_dentry,
16740 +                    const struct dentry *parent_dentry,
16741 +                    const struct vfsmount *parent_mnt,
16742 +                    const struct dentry *old_dentry,
16743 +                    const struct inode *old_parent_inode,
16744 +                    const struct vfsmount *old_mnt, const char *newname)
16745 +{
16746 +       return 0;
16747 +}
16748 +
16749 +int
16750 +gr_acl_handle_filldir(const struct file *file, const char *name,
16751 +                     const int namelen, const ino_t ino)
16752 +{
16753 +       return 1;
16754 +}
16755 +
16756 +int
16757 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
16758 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
16759 +{
16760 +       return 1;
16761 +}
16762 +
16763 +int
16764 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
16765 +{
16766 +       return 1;
16767 +}
16768 +
16769 +int
16770 +gr_search_accept(const struct socket *sock)
16771 +{
16772 +       return 1;
16773 +}
16774 +
16775 +int
16776 +gr_search_listen(const struct socket *sock)
16777 +{
16778 +       return 1;
16779 +}
16780 +
16781 +int
16782 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
16783 +{
16784 +       return 1;
16785 +}
16786 +
16787 +__u32
16788 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
16789 +{
16790 +       return 1;
16791 +}
16792 +
16793 +__u32
16794 +gr_acl_handle_creat(const struct dentry * dentry,
16795 +                   const struct dentry * p_dentry,
16796 +                   const struct vfsmount * p_mnt, const int fmode,
16797 +                   const int imode)
16798 +{
16799 +       return 1;
16800 +}
16801 +
16802 +void
16803 +gr_acl_handle_exit(void)
16804 +{
16805 +       return;
16806 +}
16807 +
16808 +int
16809 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
16810 +{
16811 +       return 1;
16812 +}
16813 +
16814 +void
16815 +gr_set_role_label(const uid_t uid, const gid_t gid)
16816 +{
16817 +       return;
16818 +}
16819 +
16820 +int
16821 +gr_acl_handle_procpidmem(const struct task_struct *task)
16822 +{
16823 +       return 0;
16824 +}
16825 +
16826 +int
16827 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
16828 +{
16829 +       return 1;
16830 +}
16831 +
16832 +int
16833 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
16834 +{
16835 +       return 1;
16836 +}
16837 +
16838 +void
16839 +gr_set_kernel_label(struct task_struct *task)
16840 +{
16841 +       return;
16842 +}
16843 +
16844 +int
16845 +gr_check_user_change(int real, int effective, int fs)
16846 +{
16847 +       return 0;
16848 +}
16849 +
16850 +int
16851 +gr_check_group_change(int real, int effective, int fs)
16852 +{
16853 +       return 0;
16854 +}
16855 +
16856 +
16857 +EXPORT_SYMBOL(gr_task_is_capable);
16858 +EXPORT_SYMBOL(gr_learn_resource);
16859 +EXPORT_SYMBOL(gr_set_kernel_label);
16860 +#ifdef CONFIG_SECURITY
16861 +EXPORT_SYMBOL(gr_check_user_change);
16862 +EXPORT_SYMBOL(gr_check_group_change);
16863 +#endif
16864 diff -urNp linux-2.6.17.7/grsecurity/grsec_exec.c linux-2.6.17.7/grsecurity/grsec_exec.c
16865 --- linux-2.6.17.7/grsecurity/grsec_exec.c      1969-12-31 19:00:00.000000000 -0500
16866 +++ linux-2.6.17.7/grsecurity/grsec_exec.c      2006-08-01 20:29:47.000000000 -0400
16867 @@ -0,0 +1,88 @@
16868 +#include <linux/kernel.h>
16869 +#include <linux/sched.h>
16870 +#include <linux/file.h>
16871 +#include <linux/binfmts.h>
16872 +#include <linux/smp_lock.h>
16873 +#include <linux/fs.h>
16874 +#include <linux/types.h>
16875 +#include <linux/grdefs.h>
16876 +#include <linux/grinternal.h>
16877 +#include <linux/capability.h>
16878 +
16879 +#include <asm/uaccess.h>
16880 +
16881 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16882 +static char gr_exec_arg_buf[132];
16883 +static DECLARE_MUTEX(gr_exec_arg_sem);
16884 +#endif
16885 +
16886 +int
16887 +gr_handle_nproc(void)
16888 +{
16889 +#ifdef CONFIG_GRKERNSEC_EXECVE
16890 +       if (grsec_enable_execve && current->user &&
16891 +           (atomic_read(&current->user->processes) >
16892 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
16893 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
16894 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
16895 +               return -EAGAIN;
16896 +       }
16897 +#endif
16898 +       return 0;
16899 +}
16900 +
16901 +void
16902 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
16903 +{
16904 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16905 +       char *grarg = gr_exec_arg_buf;
16906 +       unsigned int i, x, execlen = 0;
16907 +       char c;
16908 +
16909 +       if (!((grsec_enable_execlog && grsec_enable_group &&
16910 +              in_group_p(grsec_audit_gid))
16911 +             || (grsec_enable_execlog && !grsec_enable_group)))
16912 +               return;
16913 +
16914 +       down(&gr_exec_arg_sem);
16915 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
16916 +
16917 +       if (unlikely(argv == NULL))
16918 +               goto log;
16919 +
16920 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
16921 +               const char __user *p;
16922 +               unsigned int len;
16923 +
16924 +               if (copy_from_user(&p, argv + i, sizeof(p)))
16925 +                       goto log;
16926 +               if (!p)
16927 +                       goto log;
16928 +               len = strnlen_user(p, 128 - execlen);
16929 +               if (len > 128 - execlen)
16930 +                       len = 128 - execlen;
16931 +               else if (len > 0)
16932 +                       len--;
16933 +               if (copy_from_user(grarg + execlen, p, len))
16934 +                       goto log;
16935 +
16936 +               /* rewrite unprintable characters */
16937 +               for (x = 0; x < len; x++) {
16938 +                       c = *(grarg + execlen + x);
16939 +                       if (c < 32 || c > 126)
16940 +                               *(grarg + execlen + x) = ' ';
16941 +               }
16942 +
16943 +               execlen += len;
16944 +               *(grarg + execlen) = ' ';
16945 +               *(grarg + execlen + 1) = '\0';
16946 +               execlen++;
16947 +       }
16948 +
16949 +      log:
16950 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
16951 +                       bprm->file->f_vfsmnt, grarg);
16952 +       up(&gr_exec_arg_sem);
16953 +#endif
16954 +       return;
16955 +}
16956 diff -urNp linux-2.6.17.7/grsecurity/grsec_fifo.c linux-2.6.17.7/grsecurity/grsec_fifo.c
16957 --- linux-2.6.17.7/grsecurity/grsec_fifo.c      1969-12-31 19:00:00.000000000 -0500
16958 +++ linux-2.6.17.7/grsecurity/grsec_fifo.c      2006-08-01 20:29:47.000000000 -0400
16959 @@ -0,0 +1,22 @@
16960 +#include <linux/kernel.h>
16961 +#include <linux/sched.h>
16962 +#include <linux/fs.h>
16963 +#include <linux/file.h>
16964 +#include <linux/grinternal.h>
16965 +
16966 +int
16967 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
16968 +              const struct dentry *dir, const int flag, const int acc_mode)
16969 +{
16970 +#ifdef CONFIG_GRKERNSEC_FIFO
16971 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
16972 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
16973 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
16974 +           (current->fsuid != dentry->d_inode->i_uid)) {
16975 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
16976 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
16977 +               return -EACCES;
16978 +       }
16979 +#endif
16980 +       return 0;
16981 +}
16982 diff -urNp linux-2.6.17.7/grsecurity/grsec_fork.c linux-2.6.17.7/grsecurity/grsec_fork.c
16983 --- linux-2.6.17.7/grsecurity/grsec_fork.c      1969-12-31 19:00:00.000000000 -0500
16984 +++ linux-2.6.17.7/grsecurity/grsec_fork.c      2006-08-01 20:49:45.000000000 -0400
16985 @@ -0,0 +1,15 @@
16986 +#include <linux/kernel.h>
16987 +#include <linux/sched.h>
16988 +#include <linux/grsecurity.h>
16989 +#include <linux/grinternal.h>
16990 +#include <linux/errno.h>
16991 +
16992 +void
16993 +gr_log_forkfail(const int retval)
16994 +{
16995 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
16996 +       if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
16997 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
16998 +#endif
16999 +       return;
17000 +}
17001 diff -urNp linux-2.6.17.7/grsecurity/grsec_init.c linux-2.6.17.7/grsecurity/grsec_init.c
17002 --- linux-2.6.17.7/grsecurity/grsec_init.c      1969-12-31 19:00:00.000000000 -0500
17003 +++ linux-2.6.17.7/grsecurity/grsec_init.c      2006-08-01 20:29:47.000000000 -0400
17004 @@ -0,0 +1,236 @@
17005 +#include <linux/kernel.h>
17006 +#include <linux/sched.h>
17007 +#include <linux/mm.h>
17008 +#include <linux/smp_lock.h>
17009 +#include <linux/gracl.h>
17010 +#include <linux/slab.h>
17011 +#include <linux/vmalloc.h>
17012 +#include <linux/percpu.h>
17013 +
17014 +int grsec_enable_shm;
17015 +int grsec_enable_link;
17016 +int grsec_enable_dmesg;
17017 +int grsec_enable_fifo;
17018 +int grsec_enable_execve;
17019 +int grsec_enable_execlog;
17020 +int grsec_enable_signal;
17021 +int grsec_enable_forkfail;
17022 +int grsec_enable_time;
17023 +int grsec_enable_audit_textrel;
17024 +int grsec_enable_group;
17025 +int grsec_audit_gid;
17026 +int grsec_enable_chdir;
17027 +int grsec_enable_audit_ipc;
17028 +int grsec_enable_mount;
17029 +int grsec_enable_chroot_findtask;
17030 +int grsec_enable_chroot_mount;
17031 +int grsec_enable_chroot_shmat;
17032 +int grsec_enable_chroot_fchdir;
17033 +int grsec_enable_chroot_double;
17034 +int grsec_enable_chroot_pivot;
17035 +int grsec_enable_chroot_chdir;
17036 +int grsec_enable_chroot_chmod;
17037 +int grsec_enable_chroot_mknod;
17038 +int grsec_enable_chroot_nice;
17039 +int grsec_enable_chroot_execlog;
17040 +int grsec_enable_chroot_caps;
17041 +int grsec_enable_chroot_sysctl;
17042 +int grsec_enable_chroot_unix;
17043 +int grsec_enable_tpe;
17044 +int grsec_tpe_gid;
17045 +int grsec_enable_tpe_all;
17046 +int grsec_enable_randpid;
17047 +int grsec_enable_socket_all;
17048 +int grsec_socket_all_gid;
17049 +int grsec_enable_socket_client;
17050 +int grsec_socket_client_gid;
17051 +int grsec_enable_socket_server;
17052 +int grsec_socket_server_gid;
17053 +int grsec_resource_logging;
17054 +int grsec_lock;
17055 +
17056 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
17057 +unsigned long grsec_alert_wtime = 0;
17058 +unsigned long grsec_alert_fyet = 0;
17059 +
17060 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
17061 +
17062 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
17063 +
17064 +char *gr_shared_page[4];
17065 +
17066 +char *gr_alert_log_fmt;
17067 +char *gr_audit_log_fmt;
17068 +char *gr_alert_log_buf;
17069 +char *gr_audit_log_buf;
17070 +
17071 +extern struct gr_arg *gr_usermode;
17072 +extern unsigned char *gr_system_salt;
17073 +extern unsigned char *gr_system_sum;
17074 +
17075 +void
17076 +grsecurity_init(void)
17077 +{
17078 +       int j;
17079 +       /* create the per-cpu shared pages */
17080 +
17081 +       preempt_disable();
17082 +       for (j = 0; j < 4; j++) {
17083 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
17084 +               if (gr_shared_page[j] == NULL) {
17085 +                       panic("Unable to allocate grsecurity shared page");
17086 +                       return;
17087 +               }
17088 +       }
17089 +       preempt_enable();
17090 +
17091 +       /* allocate log buffers */
17092 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
17093 +       if (!gr_alert_log_fmt) {
17094 +               panic("Unable to allocate grsecurity alert log format buffer");
17095 +               return;
17096 +       }
17097 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
17098 +       if (!gr_audit_log_fmt) {
17099 +               panic("Unable to allocate grsecurity audit log format buffer");
17100 +               return;
17101 +       }
17102 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
17103 +       if (!gr_alert_log_buf) {
17104 +               panic("Unable to allocate grsecurity alert log buffer");
17105 +               return;
17106 +       }
17107 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
17108 +       if (!gr_audit_log_buf) {
17109 +               panic("Unable to allocate grsecurity audit log buffer");
17110 +               return;
17111 +       }
17112 +
17113 +       /* allocate memory for authentication structure */
17114 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
17115 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
17116 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
17117 +
17118 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
17119 +               panic("Unable to allocate grsecurity authentication structure");
17120 +               return;
17121 +       }
17122 +
17123 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
17124 +#ifndef CONFIG_GRKERNSEC_SYSCTL
17125 +       grsec_lock = 1;
17126 +#endif
17127 +#ifdef CONFIG_GRKERNSEC_SHM
17128 +       grsec_enable_shm = 1;
17129 +#endif
17130 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
17131 +       grsec_enable_audit_textrel = 1;
17132 +#endif
17133 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
17134 +       grsec_enable_group = 1;
17135 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
17136 +#endif
17137 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
17138 +       grsec_enable_chdir = 1;
17139 +#endif
17140 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17141 +       grsec_enable_audit_ipc = 1;
17142 +#endif
17143 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17144 +       grsec_enable_mount = 1;
17145 +#endif
17146 +#ifdef CONFIG_GRKERNSEC_LINK
17147 +       grsec_enable_link = 1;
17148 +#endif
17149 +#ifdef CONFIG_GRKERNSEC_DMESG
17150 +       grsec_enable_dmesg = 1;
17151 +#endif
17152 +#ifdef CONFIG_GRKERNSEC_FIFO
17153 +       grsec_enable_fifo = 1;
17154 +#endif
17155 +#ifdef CONFIG_GRKERNSEC_EXECVE
17156 +       grsec_enable_execve = 1;
17157 +#endif
17158 +#ifdef CONFIG_GRKERNSEC_EXECLOG
17159 +       grsec_enable_execlog = 1;
17160 +#endif
17161 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17162 +       grsec_enable_signal = 1;
17163 +#endif
17164 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
17165 +       grsec_enable_forkfail = 1;
17166 +#endif
17167 +#ifdef CONFIG_GRKERNSEC_TIME
17168 +       grsec_enable_time = 1;
17169 +#endif
17170 +#ifdef CONFIG_GRKERNSEC_RESLOG
17171 +       grsec_resource_logging = 1;
17172 +#endif
17173 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
17174 +       grsec_enable_chroot_findtask = 1;
17175 +#endif
17176 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
17177 +       grsec_enable_chroot_unix = 1;
17178 +#endif
17179 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
17180 +       grsec_enable_chroot_mount = 1;
17181 +#endif
17182 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
17183 +       grsec_enable_chroot_fchdir = 1;
17184 +#endif
17185 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
17186 +       grsec_enable_chroot_shmat = 1;
17187 +#endif
17188 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17189 +       grsec_enable_chroot_double = 1;
17190 +#endif
17191 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
17192 +       grsec_enable_chroot_pivot = 1;
17193 +#endif
17194 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17195 +       grsec_enable_chroot_chdir = 1;
17196 +#endif
17197 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17198 +       grsec_enable_chroot_chmod = 1;
17199 +#endif
17200 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
17201 +       grsec_enable_chroot_mknod = 1;
17202 +#endif
17203 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17204 +       grsec_enable_chroot_nice = 1;
17205 +#endif
17206 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
17207 +       grsec_enable_chroot_execlog = 1;
17208 +#endif
17209 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17210 +       grsec_enable_chroot_caps = 1;
17211 +#endif
17212 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17213 +       grsec_enable_chroot_sysctl = 1;
17214 +#endif
17215 +#ifdef CONFIG_GRKERNSEC_TPE
17216 +       grsec_enable_tpe = 1;
17217 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
17218 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
17219 +       grsec_enable_tpe_all = 1;
17220 +#endif
17221 +#endif
17222 +#ifdef CONFIG_GRKERNSEC_RANDPID
17223 +       grsec_enable_randpid = 1;
17224 +#endif
17225 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
17226 +       grsec_enable_socket_all = 1;
17227 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
17228 +#endif
17229 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
17230 +       grsec_enable_socket_client = 1;
17231 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
17232 +#endif
17233 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
17234 +       grsec_enable_socket_server = 1;
17235 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
17236 +#endif
17237 +#endif
17238 +
17239 +       return;
17240 +}
17241 diff -urNp linux-2.6.17.7/grsecurity/grsec_ipc.c linux-2.6.17.7/grsecurity/grsec_ipc.c
17242 --- linux-2.6.17.7/grsecurity/grsec_ipc.c       1969-12-31 19:00:00.000000000 -0500
17243 +++ linux-2.6.17.7/grsecurity/grsec_ipc.c       2006-08-01 20:29:47.000000000 -0400
17244 @@ -0,0 +1,81 @@
17245 +#include <linux/kernel.h>
17246 +#include <linux/sched.h>
17247 +#include <linux/types.h>
17248 +#include <linux/ipc.h>
17249 +#include <linux/grsecurity.h>
17250 +#include <linux/grinternal.h>
17251 +
17252 +void
17253 +gr_log_msgget(const int ret, const int msgflg)
17254 +{
17255 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17256 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17257 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17258 +                                         !grsec_enable_group)) && (ret >= 0)
17259 +           && (msgflg & IPC_CREAT))
17260 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
17261 +#endif
17262 +       return;
17263 +}
17264 +
17265 +void
17266 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
17267 +{
17268 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17269 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17270 +            grsec_enable_audit_ipc) ||
17271 +           (grsec_enable_audit_ipc && !grsec_enable_group))
17272 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
17273 +#endif
17274 +       return;
17275 +}
17276 +
17277 +void
17278 +gr_log_semget(const int err, const int semflg)
17279 +{
17280 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17281 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17282 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17283 +                                         !grsec_enable_group)) && (err >= 0)
17284 +           && (semflg & IPC_CREAT))
17285 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
17286 +#endif
17287 +       return;
17288 +}
17289 +
17290 +void
17291 +gr_log_semrm(const uid_t uid, const uid_t cuid)
17292 +{
17293 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17294 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17295 +            grsec_enable_audit_ipc) ||
17296 +           (grsec_enable_audit_ipc && !grsec_enable_group))
17297 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
17298 +#endif
17299 +       return;
17300 +}
17301 +
17302 +void
17303 +gr_log_shmget(const int err, const int shmflg, const size_t size)
17304 +{
17305 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17306 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17307 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
17308 +                                         !grsec_enable_group)) && (err >= 0)
17309 +           && (shmflg & IPC_CREAT))
17310 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
17311 +#endif
17312 +       return;
17313 +}
17314 +
17315 +void
17316 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
17317 +{
17318 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
17319 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
17320 +            grsec_enable_audit_ipc) ||
17321 +           (grsec_enable_audit_ipc && !grsec_enable_group))
17322 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
17323 +#endif
17324 +       return;
17325 +}
17326 diff -urNp linux-2.6.17.7/grsecurity/grsec_link.c linux-2.6.17.7/grsecurity/grsec_link.c
17327 --- linux-2.6.17.7/grsecurity/grsec_link.c      1969-12-31 19:00:00.000000000 -0500
17328 +++ linux-2.6.17.7/grsecurity/grsec_link.c      2006-08-01 20:29:47.000000000 -0400
17329 @@ -0,0 +1,39 @@
17330 +#include <linux/kernel.h>
17331 +#include <linux/sched.h>
17332 +#include <linux/fs.h>
17333 +#include <linux/file.h>
17334 +#include <linux/grinternal.h>
17335 +
17336 +int
17337 +gr_handle_follow_link(const struct inode *parent,
17338 +                     const struct inode *inode,
17339 +                     const struct dentry *dentry, const struct vfsmount *mnt)
17340 +{
17341 +#ifdef CONFIG_GRKERNSEC_LINK
17342 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
17343 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
17344 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
17345 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
17346 +               return -EACCES;
17347 +       }
17348 +#endif
17349 +       return 0;
17350 +}
17351 +
17352 +int
17353 +gr_handle_hardlink(const struct dentry *dentry,
17354 +                  const struct vfsmount *mnt,
17355 +                  struct inode *inode, const int mode, const char *to)
17356 +{
17357 +#ifdef CONFIG_GRKERNSEC_LINK
17358 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
17359 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
17360 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
17361 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
17362 +           !capable(CAP_FOWNER) && current->uid) {
17363 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
17364 +               return -EPERM;
17365 +       }
17366 +#endif
17367 +       return 0;
17368 +}
17369 diff -urNp linux-2.6.17.7/grsecurity/grsec_log.c linux-2.6.17.7/grsecurity/grsec_log.c
17370 --- linux-2.6.17.7/grsecurity/grsec_log.c       1969-12-31 19:00:00.000000000 -0500
17371 +++ linux-2.6.17.7/grsecurity/grsec_log.c       2006-08-01 20:29:47.000000000 -0400
17372 @@ -0,0 +1,265 @@
17373 +#include <linux/kernel.h>
17374 +#include <linux/sched.h>
17375 +#include <linux/file.h>
17376 +#include <linux/tty.h>
17377 +#include <linux/fs.h>
17378 +#include <linux/grinternal.h>
17379 +
17380 +#define BEGIN_LOCKS(x) \
17381 +       read_lock(&tasklist_lock); \
17382 +       read_lock(&grsec_exec_file_lock); \
17383 +       if (x != GR_DO_AUDIT) \
17384 +               spin_lock(&grsec_alert_lock); \
17385 +       else \
17386 +               spin_lock(&grsec_audit_lock)
17387 +
17388 +#define END_LOCKS(x) \
17389 +       if (x != GR_DO_AUDIT) \
17390 +               spin_unlock(&grsec_alert_lock); \
17391 +       else \
17392 +               spin_unlock(&grsec_audit_lock); \
17393 +       read_unlock(&grsec_exec_file_lock); \
17394 +       read_unlock(&tasklist_lock); \
17395 +       if (x == GR_DONT_AUDIT) \
17396 +               gr_handle_alertkill(current)
17397 +
17398 +enum {
17399 +       FLOODING,
17400 +       NO_FLOODING
17401 +};
17402 +
17403 +extern char *gr_alert_log_fmt;
17404 +extern char *gr_audit_log_fmt;
17405 +extern char *gr_alert_log_buf;
17406 +extern char *gr_audit_log_buf;
17407 +
17408 +static int gr_log_start(int audit)
17409 +{
17410 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
17411 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
17412 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
17413 +
17414 +       if (audit == GR_DO_AUDIT)
17415 +               goto set_fmt;
17416 +
17417 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
17418 +               grsec_alert_wtime = jiffies;
17419 +               grsec_alert_fyet = 0;
17420 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
17421 +               grsec_alert_fyet++;
17422 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
17423 +               grsec_alert_wtime = jiffies;
17424 +               grsec_alert_fyet++;
17425 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
17426 +               return FLOODING;
17427 +       } else return FLOODING;
17428 +
17429 +set_fmt:
17430 +       memset(buf, 0, PAGE_SIZE);
17431 +       if (current->signal->curr_ip && gr_acl_is_enabled()) {
17432 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
17433 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
17434 +       } else if (current->signal->curr_ip) {
17435 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
17436 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
17437 +       } else if (gr_acl_is_enabled()) {
17438 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
17439 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
17440 +       } else {
17441 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
17442 +               strcpy(buf, fmt);
17443 +       }
17444 +
17445 +       return NO_FLOODING;
17446 +}
17447 +
17448 +static void gr_log_middle(int audit, const char *msg, va_list ap)
17449 +{
17450 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
17451 +       unsigned int len = strlen(buf);
17452 +
17453 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
17454 +
17455 +       return;
17456 +}
17457 +
17458 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
17459 +{
17460 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
17461 +       unsigned int len = strlen(buf);
17462 +       va_list ap;
17463 +
17464 +       va_start(ap, msg);
17465 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
17466 +       va_end(ap);
17467 +
17468 +       return;
17469 +}
17470 +
17471 +static void gr_log_end(int audit)
17472 +{
17473 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
17474 +       unsigned int len = strlen(buf);
17475 +
17476 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
17477 +       printk("%s\n", buf);
17478 +
17479 +       return;
17480 +}
17481 +
17482 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
17483 +{
17484 +       int logtype;
17485 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
17486 +       char *str1, *str2, *str3;
17487 +       int num1, num2;
17488 +       unsigned long ulong1, ulong2;
17489 +       struct dentry *dentry;
17490 +       struct vfsmount *mnt;
17491 +       struct file *file;
17492 +       struct task_struct *task;
17493 +       va_list ap;
17494 +
17495 +       BEGIN_LOCKS(audit);
17496 +       logtype = gr_log_start(audit);
17497 +       if (logtype == FLOODING) {
17498 +               END_LOCKS(audit);
17499 +               return;
17500 +       }
17501 +       va_start(ap, argtypes);
17502 +       switch (argtypes) {
17503 +       case GR_TTYSNIFF:
17504 +               task = va_arg(ap, struct task_struct *);
17505 +               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);
17506 +               break;
17507 +       case GR_RBAC:
17508 +               dentry = va_arg(ap, struct dentry *);
17509 +               mnt = va_arg(ap, struct vfsmount *);
17510 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
17511 +               break;
17512 +       case GR_RBAC_STR:
17513 +               dentry = va_arg(ap, struct dentry *);
17514 +               mnt = va_arg(ap, struct vfsmount *);
17515 +               str1 = va_arg(ap, char *);
17516 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
17517 +               break;
17518 +       case GR_STR_RBAC:
17519 +               str1 = va_arg(ap, char *);
17520 +               dentry = va_arg(ap, struct dentry *);
17521 +               mnt = va_arg(ap, struct vfsmount *);
17522 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
17523 +               break;
17524 +       case GR_RBAC_MODE2:
17525 +               dentry = va_arg(ap, struct dentry *);
17526 +               mnt = va_arg(ap, struct vfsmount *);
17527 +               str1 = va_arg(ap, char *);
17528 +               str2 = va_arg(ap, char *);
17529 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
17530 +               break;
17531 +       case GR_RBAC_MODE3:
17532 +               dentry = va_arg(ap, struct dentry *);
17533 +               mnt = va_arg(ap, struct vfsmount *);
17534 +               str1 = va_arg(ap, char *);
17535 +               str2 = va_arg(ap, char *);
17536 +               str3 = va_arg(ap, char *);
17537 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
17538 +               break;
17539 +       case GR_FILENAME:
17540 +               dentry = va_arg(ap, struct dentry *);
17541 +               mnt = va_arg(ap, struct vfsmount *);
17542 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
17543 +               break;
17544 +       case GR_STR_FILENAME:
17545 +               str1 = va_arg(ap, char *);
17546 +               dentry = va_arg(ap, struct dentry *);
17547 +               mnt = va_arg(ap, struct vfsmount *);
17548 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
17549 +               break;
17550 +       case GR_FILENAME_STR:
17551 +               dentry = va_arg(ap, struct dentry *);
17552 +               mnt = va_arg(ap, struct vfsmount *);
17553 +               str1 = va_arg(ap, char *);
17554 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
17555 +               break;
17556 +       case GR_FILENAME_TWO_INT:
17557 +               dentry = va_arg(ap, struct dentry *);
17558 +               mnt = va_arg(ap, struct vfsmount *);
17559 +               num1 = va_arg(ap, int);
17560 +               num2 = va_arg(ap, int);
17561 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
17562 +               break;
17563 +       case GR_FILENAME_TWO_INT_STR:
17564 +               dentry = va_arg(ap, struct dentry *);
17565 +               mnt = va_arg(ap, struct vfsmount *);
17566 +               num1 = va_arg(ap, int);
17567 +               num2 = va_arg(ap, int);
17568 +               str1 = va_arg(ap, char *);
17569 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
17570 +               break;
17571 +       case GR_TEXTREL:
17572 +               file = va_arg(ap, struct file *);
17573 +               ulong1 = va_arg(ap, unsigned long);
17574 +               ulong2 = va_arg(ap, unsigned long);
17575 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
17576 +               break;
17577 +       case GR_PTRACE:
17578 +               task = va_arg(ap, struct task_struct *);
17579 +               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);
17580 +               break;
17581 +       case GR_RESOURCE:
17582 +               task = va_arg(ap, struct task_struct *);
17583 +               ulong1 = va_arg(ap, unsigned long);
17584 +               str1 = va_arg(ap, char *);
17585 +               ulong2 = va_arg(ap, unsigned long);
17586 +               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);
17587 +               break;
17588 +       case GR_CAP:
17589 +               task = va_arg(ap, struct task_struct *);
17590 +               str1 = va_arg(ap, char *);
17591 +               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);
17592 +               break;
17593 +       case GR_SIG:
17594 +               task = va_arg(ap, struct task_struct *);
17595 +               num1 = va_arg(ap, int);
17596 +               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);
17597 +               break;
17598 +       case GR_CRASH1:
17599 +               task = va_arg(ap, struct task_struct *);
17600 +               ulong1 = va_arg(ap, unsigned long);
17601 +               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);
17602 +               break;
17603 +       case GR_CRASH2:
17604 +               task = va_arg(ap, struct task_struct *);
17605 +               ulong1 = va_arg(ap, unsigned long);
17606 +               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);
17607 +               break;
17608 +       case GR_PSACCT:
17609 +               {
17610 +                       unsigned int wday, cday;
17611 +                       __u8 whr, chr;
17612 +                       __u8 wmin, cmin;
17613 +                       __u8 wsec, csec;
17614 +                       char cur_tty[64] = { 0 };
17615 +                       char parent_tty[64] = { 0 };
17616 +
17617 +                       task = va_arg(ap, struct task_struct *);
17618 +                       wday = va_arg(ap, unsigned int);
17619 +                       cday = va_arg(ap, unsigned int);
17620 +                       whr = va_arg(ap, int);
17621 +                       chr = va_arg(ap, int);
17622 +                       wmin = va_arg(ap, int);
17623 +                       cmin = va_arg(ap, int);
17624 +                       wsec = va_arg(ap, int);
17625 +                       csec = va_arg(ap, int);
17626 +                       ulong1 = va_arg(ap, unsigned long);
17627 +
17628 +                       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);
17629 +               }
17630 +               break;
17631 +       default:
17632 +               gr_log_middle(audit, msg, ap);
17633 +       }
17634 +       va_end(ap);
17635 +       gr_log_end(audit);
17636 +       END_LOCKS(audit);
17637 +}
17638 diff -urNp linux-2.6.17.7/grsecurity/grsec_mem.c linux-2.6.17.7/grsecurity/grsec_mem.c
17639 --- linux-2.6.17.7/grsecurity/grsec_mem.c       1969-12-31 19:00:00.000000000 -0500
17640 +++ linux-2.6.17.7/grsecurity/grsec_mem.c       2006-08-01 20:29:47.000000000 -0400
17641 @@ -0,0 +1,71 @@
17642 +#include <linux/kernel.h>
17643 +#include <linux/sched.h>
17644 +#include <linux/mm.h>
17645 +#include <linux/mman.h>
17646 +#include <linux/grinternal.h>
17647 +
17648 +void
17649 +gr_handle_ioperm(void)
17650 +{
17651 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
17652 +       return;
17653 +}
17654 +
17655 +void
17656 +gr_handle_iopl(void)
17657 +{
17658 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
17659 +       return;
17660 +}
17661 +
17662 +void
17663 +gr_handle_mem_write(void)
17664 +{
17665 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
17666 +       return;
17667 +}
17668 +
17669 +void
17670 +gr_handle_kmem_write(void)
17671 +{
17672 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
17673 +       return;
17674 +}
17675 +
17676 +void
17677 +gr_handle_open_port(void)
17678 +{
17679 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
17680 +       return;
17681 +}
17682 +
17683 +int
17684 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
17685 +{
17686 +       unsigned long start, end;
17687 +
17688 +       start = offset;
17689 +       end = start + vma->vm_end - vma->vm_start;
17690 +
17691 +       if (start > end) {
17692 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
17693 +               return -EPERM;
17694 +       }
17695 +
17696 +       /* allowed ranges : ISA I/O BIOS */
17697 +       if ((start >= __pa(high_memory))
17698 +#ifdef CONFIG_X86
17699 +           || (start >= 0x000a0000 && end <= 0x00100000)
17700 +           || (start >= 0x00000000 && end <= 0x00001000)
17701 +#endif
17702 +       )
17703 +               return 0;
17704 +
17705 +       if (vma->vm_flags & VM_WRITE) {
17706 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
17707 +               return -EPERM;
17708 +       } else
17709 +               vma->vm_flags &= ~VM_MAYWRITE;
17710 +
17711 +       return 0;
17712 +}
17713 diff -urNp linux-2.6.17.7/grsecurity/grsec_mount.c linux-2.6.17.7/grsecurity/grsec_mount.c
17714 --- linux-2.6.17.7/grsecurity/grsec_mount.c     1969-12-31 19:00:00.000000000 -0500
17715 +++ linux-2.6.17.7/grsecurity/grsec_mount.c     2006-08-01 20:29:47.000000000 -0400
17716 @@ -0,0 +1,34 @@
17717 +#include <linux/kernel.h>
17718 +#include <linux/sched.h>
17719 +#include <linux/grsecurity.h>
17720 +#include <linux/grinternal.h>
17721 +
17722 +void
17723 +gr_log_remount(const char *devname, const int retval)
17724 +{
17725 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17726 +       if (grsec_enable_mount && (retval >= 0))
17727 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
17728 +#endif
17729 +       return;
17730 +}
17731 +
17732 +void
17733 +gr_log_unmount(const char *devname, const int retval)
17734 +{
17735 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17736 +       if (grsec_enable_mount && (retval >= 0))
17737 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
17738 +#endif
17739 +       return;
17740 +}
17741 +
17742 +void
17743 +gr_log_mount(const char *from, const char *to, const int retval)
17744 +{
17745 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
17746 +       if (grsec_enable_mount && (retval >= 0))
17747 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
17748 +#endif
17749 +       return;
17750 +}
17751 diff -urNp linux-2.6.17.7/grsecurity/grsec_rand.c linux-2.6.17.7/grsecurity/grsec_rand.c
17752 --- linux-2.6.17.7/grsecurity/grsec_rand.c      1969-12-31 19:00:00.000000000 -0500
17753 +++ linux-2.6.17.7/grsecurity/grsec_rand.c      2006-08-01 20:29:47.000000000 -0400
17754 @@ -0,0 +1,26 @@
17755 +#include <linux/kernel.h>
17756 +#include <linux/sched.h>
17757 +#include <linux/smp_lock.h>
17758 +#include <linux/grsecurity.h>
17759 +#include <linux/grinternal.h>
17760 +
17761 +extern int pid_max;
17762 +
17763 +int
17764 +gr_random_pid(void)
17765 +{
17766 +#ifdef CONFIG_GRKERNSEC_RANDPID
17767 +       int pid;
17768 +
17769 +       if (grsec_enable_randpid && current->fs->root) {
17770 +               /* return a pid in the range 1 ... pid_max - 1
17771 +                  optimize this so we don't have to do a real division
17772 +               */
17773 +               pid = 1 + (get_random_long() % pid_max);
17774 +               if (pid == pid_max)
17775 +                       pid = pid_max - 1;
17776 +               return pid;
17777 +       }
17778 +#endif
17779 +       return 0;
17780 +}
17781 diff -urNp linux-2.6.17.7/grsecurity/grsec_sig.c linux-2.6.17.7/grsecurity/grsec_sig.c
17782 --- linux-2.6.17.7/grsecurity/grsec_sig.c       1969-12-31 19:00:00.000000000 -0500
17783 +++ linux-2.6.17.7/grsecurity/grsec_sig.c       2006-08-01 20:29:47.000000000 -0400
17784 @@ -0,0 +1,59 @@
17785 +#include <linux/kernel.h>
17786 +#include <linux/sched.h>
17787 +#include <linux/grsecurity.h>
17788 +#include <linux/grinternal.h>
17789 +
17790 +void
17791 +gr_log_signal(const int sig, const struct task_struct *t)
17792 +{
17793 +#ifdef CONFIG_GRKERNSEC_SIGNAL
17794 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
17795 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
17796 +               if (t->pid == current->pid) {
17797 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
17798 +               } else {
17799 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
17800 +               }
17801 +       }
17802 +#endif
17803 +       return;
17804 +}
17805 +
17806 +int
17807 +gr_handle_signal(const struct task_struct *p, const int sig)
17808 +{
17809 +#ifdef CONFIG_GRKERNSEC
17810 +       if (current->pid > 1 && gr_check_protected_task(p)) {
17811 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
17812 +               return -EPERM;
17813 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
17814 +               return -EPERM;
17815 +       }
17816 +#endif
17817 +       return 0;
17818 +}
17819 +
17820 +void gr_handle_brute_attach(struct task_struct *p)
17821 +{
17822 +#ifdef CONFIG_GRKERNSEC_BRUTE
17823 +       read_lock(&tasklist_lock);
17824 +       read_lock(&grsec_exec_file_lock);
17825 +       if (p->parent && p->parent->exec_file == p->exec_file)
17826 +               p->parent->brute = 1;
17827 +       read_unlock(&grsec_exec_file_lock);
17828 +       read_unlock(&tasklist_lock);
17829 +#endif
17830 +       return;
17831 +}
17832 +
17833 +void gr_handle_brute_check(void)
17834 +{
17835 +#ifdef CONFIG_GRKERNSEC_BRUTE
17836 +       if (current->brute) {
17837 +               set_current_state(TASK_UNINTERRUPTIBLE);
17838 +               schedule_timeout(30 * HZ);
17839 +       }
17840 +#endif
17841 +       return;
17842 +}
17843 +
17844 diff -urNp linux-2.6.17.7/grsecurity/grsec_sock.c linux-2.6.17.7/grsecurity/grsec_sock.c
17845 --- linux-2.6.17.7/grsecurity/grsec_sock.c      1969-12-31 19:00:00.000000000 -0500
17846 +++ linux-2.6.17.7/grsecurity/grsec_sock.c      2006-08-01 20:29:47.000000000 -0400
17847 @@ -0,0 +1,263 @@
17848 +#include <linux/kernel.h>
17849 +#include <linux/module.h>
17850 +#include <linux/sched.h>
17851 +#include <linux/file.h>
17852 +#include <linux/net.h>
17853 +#include <linux/in.h>
17854 +#include <linux/ip.h>
17855 +#include <net/sock.h>
17856 +#include <net/inet_sock.h>
17857 +#include <linux/grsecurity.h>
17858 +#include <linux/grinternal.h>
17859 +#include <linux/gracl.h>
17860 +
17861 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
17862 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
17863 +EXPORT_SYMBOL(udp_v4_lookup);
17864 +#endif
17865 +
17866 +EXPORT_SYMBOL(gr_cap_rtnetlink);
17867 +
17868 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
17869 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
17870 +
17871 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
17872 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
17873 +
17874 +#ifdef CONFIG_UNIX_MODULE
17875 +EXPORT_SYMBOL(gr_acl_handle_unix);
17876 +EXPORT_SYMBOL(gr_acl_handle_mknod);
17877 +EXPORT_SYMBOL(gr_handle_chroot_unix);
17878 +EXPORT_SYMBOL(gr_handle_create);
17879 +#endif
17880 +
17881 +#ifdef CONFIG_GRKERNSEC
17882 +#define gr_conn_table_size 32749
17883 +struct conn_table_entry {
17884 +       struct conn_table_entry *next;
17885 +       struct signal_struct *sig;
17886 +};
17887 +
17888 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
17889 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
17890 +
17891 +extern const char * gr_socktype_to_name(unsigned char type);
17892 +extern const char * gr_proto_to_name(unsigned char proto);
17893 +
17894 +static __inline__ int 
17895 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
17896 +{
17897 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
17898 +}
17899 +
17900 +static __inline__ int
17901 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, 
17902 +          __u16 sport, __u16 dport)
17903 +{
17904 +       if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
17905 +                    sig->gr_sport == sport && sig->gr_dport == dport))
17906 +               return 1;
17907 +       else
17908 +               return 0;
17909 +}
17910 +
17911 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
17912 +{
17913 +       struct conn_table_entry **match;
17914 +       unsigned int index;
17915 +
17916 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
17917 +                         sig->gr_sport, sig->gr_dport, 
17918 +                         gr_conn_table_size);
17919 +
17920 +       newent->sig = sig;
17921 +       
17922 +       match = &gr_conn_table[index];
17923 +       newent->next = *match;
17924 +       *match = newent;
17925 +
17926 +       return;
17927 +}
17928 +
17929 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
17930 +{
17931 +       struct conn_table_entry *match, *last = NULL;
17932 +       unsigned int index;
17933 +
17934 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
17935 +                         sig->gr_sport, sig->gr_dport, 
17936 +                         gr_conn_table_size);
17937 +
17938 +       match = gr_conn_table[index];
17939 +       while (match && !conn_match(match->sig, 
17940 +               sig->gr_saddr, sig->gr_daddr, sig->gr_sport, 
17941 +               sig->gr_dport)) {
17942 +               last = match;
17943 +               match = match->next;
17944 +       }
17945 +
17946 +       if (match) {
17947 +               if (last)
17948 +                       last->next = match->next;
17949 +               else
17950 +                       gr_conn_table[index] = NULL;
17951 +               kfree(match);
17952 +       }
17953 +
17954 +       return;
17955 +}
17956 +
17957 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
17958 +                                            __u16 sport, __u16 dport)
17959 +{
17960 +       struct conn_table_entry *match;
17961 +       unsigned int index;
17962 +
17963 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
17964 +
17965 +       match = gr_conn_table[index];
17966 +       while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
17967 +               match = match->next;
17968 +
17969 +       if (match)
17970 +               return match->sig;
17971 +       else
17972 +               return NULL;
17973 +}
17974 +
17975 +#endif
17976 +
17977 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
17978 +{
17979 +#ifdef CONFIG_GRKERNSEC
17980 +       struct signal_struct *sig = task->signal;
17981 +       struct conn_table_entry *newent;
17982 +
17983 +       newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
17984 +       if (newent == NULL)
17985 +               return;
17986 +       /* no bh lock needed since we are called with bh disabled */
17987 +       spin_lock(&gr_conn_table_lock);
17988 +       gr_del_task_from_ip_table_nolock(sig);
17989 +       sig->gr_saddr = inet->rcv_saddr;
17990 +       sig->gr_daddr = inet->daddr;
17991 +       sig->gr_sport = inet->sport;
17992 +       sig->gr_dport = inet->dport;
17993 +       gr_add_to_task_ip_table_nolock(sig, newent);
17994 +       spin_unlock(&gr_conn_table_lock);
17995 +#endif
17996 +       return;
17997 +}
17998 +
17999 +void gr_del_task_from_ip_table(struct task_struct *task)
18000 +{
18001 +#ifdef CONFIG_GRKERNSEC
18002 +       spin_lock(&gr_conn_table_lock);
18003 +       gr_del_task_from_ip_table_nolock(task->signal);
18004 +       spin_unlock(&gr_conn_table_lock);
18005 +#endif
18006 +       return;
18007 +}
18008 +
18009 +void
18010 +gr_attach_curr_ip(const struct sock *sk)
18011 +{
18012 +#ifdef CONFIG_GRKERNSEC
18013 +       struct signal_struct *p, *set;
18014 +       const struct inet_sock *inet = inet_sk(sk);     
18015 +
18016 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
18017 +               return;
18018 +
18019 +       set = current->signal;
18020 +
18021 +       spin_lock_bh(&gr_conn_table_lock);
18022 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
18023 +                                   inet->dport, inet->sport);
18024 +       if (unlikely(p != NULL)) {
18025 +               set->curr_ip = p->curr_ip;
18026 +               set->used_accept = 1;
18027 +               gr_del_task_from_ip_table_nolock(p);
18028 +               spin_unlock_bh(&gr_conn_table_lock);
18029 +               return;
18030 +       }
18031 +       spin_unlock_bh(&gr_conn_table_lock);
18032 +
18033 +       set->curr_ip = inet->daddr;
18034 +       set->used_accept = 1;
18035 +#endif
18036 +       return;
18037 +}
18038 +
18039 +int
18040 +gr_handle_sock_all(const int family, const int type, const int protocol)
18041 +{
18042 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
18043 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
18044 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
18045 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
18046 +               return -EACCES;
18047 +       }
18048 +#endif
18049 +       return 0;
18050 +}
18051 +
18052 +int
18053 +gr_handle_sock_server(const struct sockaddr *sck)
18054 +{
18055 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18056 +       if (grsec_enable_socket_server &&
18057 +           in_group_p(grsec_socket_server_gid) &&
18058 +           sck && (sck->sa_family != AF_UNIX) &&
18059 +           (sck->sa_family != AF_LOCAL)) {
18060 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
18061 +               return -EACCES;
18062 +       }
18063 +#endif
18064 +       return 0;
18065 +}
18066 +
18067 +int
18068 +gr_handle_sock_server_other(const struct sock *sck)
18069 +{
18070 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18071 +       if (grsec_enable_socket_server &&
18072 +           in_group_p(grsec_socket_server_gid) &&
18073 +           sck && (sck->sk_family != AF_UNIX) &&
18074 +           (sck->sk_family != AF_LOCAL)) {
18075 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
18076 +               return -EACCES;
18077 +       }
18078 +#endif
18079 +       return 0;
18080 +}
18081 +
18082 +int
18083 +gr_handle_sock_client(const struct sockaddr *sck)
18084 +{
18085 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
18086 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
18087 +           sck && (sck->sa_family != AF_UNIX) &&
18088 +           (sck->sa_family != AF_LOCAL)) {
18089 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
18090 +               return -EACCES;
18091 +       }
18092 +#endif
18093 +       return 0;
18094 +}
18095 +
18096 +__u32
18097 +gr_cap_rtnetlink(void)
18098 +{
18099 +#ifdef CONFIG_GRKERNSEC
18100 +       if (!gr_acl_is_enabled())
18101 +               return current->cap_effective;
18102 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
18103 +                gr_task_is_capable(current, CAP_NET_ADMIN))
18104 +               return current->cap_effective;
18105 +       else
18106 +               return 0;
18107 +#else
18108 +       return current->cap_effective;
18109 +#endif
18110 +}
18111 diff -urNp linux-2.6.17.7/grsecurity/grsec_sysctl.c linux-2.6.17.7/grsecurity/grsec_sysctl.c
18112 --- linux-2.6.17.7/grsecurity/grsec_sysctl.c    1969-12-31 19:00:00.000000000 -0500
18113 +++ linux-2.6.17.7/grsecurity/grsec_sysctl.c    2006-08-01 20:29:47.000000000 -0400
18114 @@ -0,0 +1,466 @@
18115 +#include <linux/kernel.h>
18116 +#include <linux/sched.h>
18117 +#include <linux/sysctl.h>
18118 +#include <linux/grsecurity.h>
18119 +#include <linux/grinternal.h>
18120 +
18121 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18122 +int grsec_modstop;
18123 +#endif
18124 +
18125 +int
18126 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
18127 +{
18128 +#ifdef CONFIG_GRKERNSEC_SYSCTL
18129 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
18130 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
18131 +               return -EACCES;
18132 +       }
18133 +#endif
18134 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18135 +       if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
18136 +           grsec_modstop && (op & 002)) {
18137 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
18138 +               return -EACCES;
18139 +       }
18140 +#endif
18141 +       return 0;
18142 +}
18143 +
18144 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
18145 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
18146 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
18147 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
18148 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
18149 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
18150 +GS_RANDPID, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
18151 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, 
18152 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
18153 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
18154 +
18155 +
18156 +ctl_table grsecurity_table[] = {
18157 +#ifdef CONFIG_GRKERNSEC_SYSCTL
18158 +#ifdef CONFIG_GRKERNSEC_LINK
18159 +       {
18160 +               .ctl_name       = GS_LINK,
18161 +               .procname       = "linking_restrictions",
18162 +               .data           = &grsec_enable_link,
18163 +               .maxlen         = sizeof(int),
18164 +               .mode           = 0600,
18165 +               .proc_handler   = &proc_dointvec,
18166 +       },
18167 +#endif
18168 +#ifdef CONFIG_GRKERNSEC_FIFO
18169 +       {
18170 +               .ctl_name       = GS_FIFO,
18171 +               .procname       = "fifo_restrictions",
18172 +               .data           = &grsec_enable_fifo,
18173 +               .maxlen         = sizeof(int),
18174 +               .mode           = 0600,
18175 +               .proc_handler   = &proc_dointvec,
18176 +       },
18177 +#endif
18178 +#ifdef CONFIG_GRKERNSEC_EXECVE
18179 +       {
18180 +               .ctl_name       = GS_EXECVE,
18181 +               .procname       = "execve_limiting",
18182 +               .data           = &grsec_enable_execve,
18183 +               .maxlen         = sizeof(int),
18184 +               .mode           = 0600,
18185 +               .proc_handler   = &proc_dointvec,
18186 +       },
18187 +#endif
18188 +#ifdef CONFIG_GRKERNSEC_EXECLOG
18189 +       {
18190 +               .ctl_name       = GS_EXECLOG,
18191 +               .procname       = "exec_logging",
18192 +               .data           = &grsec_enable_execlog,
18193 +               .maxlen         = sizeof(int),
18194 +               .mode           = 0600,
18195 +               .proc_handler   = &proc_dointvec,
18196 +       },
18197 +#endif
18198 +#ifdef CONFIG_GRKERNSEC_SIGNAL
18199 +       {
18200 +               .ctl_name       = GS_SIGNAL,
18201 +               .procname       = "signal_logging",
18202 +               .data           = &grsec_enable_signal,
18203 +               .maxlen         = sizeof(int),
18204 +               .mode           = 0600,
18205 +               .proc_handler   = &proc_dointvec,
18206 +       },
18207 +#endif
18208 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
18209 +       {
18210 +               .ctl_name       = GS_FORKFAIL,
18211 +               .procname       = "forkfail_logging",
18212 +               .data           = &grsec_enable_forkfail,
18213 +               .maxlen         = sizeof(int),
18214 +               .mode           = 0600,
18215 +               .proc_handler   = &proc_dointvec,
18216 +       },
18217 +#endif
18218 +#ifdef CONFIG_GRKERNSEC_TIME
18219 +       {
18220 +               .ctl_name       = GS_TIME,
18221 +               .procname       = "timechange_logging",
18222 +               .data           = &grsec_enable_time,
18223 +               .maxlen         = sizeof(int),
18224 +               .mode           = 0600,
18225 +               .proc_handler   = &proc_dointvec,
18226 +       },
18227 +#endif
18228 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
18229 +       {
18230 +               .ctl_name       = GS_CHROOT_SHMAT,
18231 +               .procname       = "chroot_deny_shmat",
18232 +               .data           = &grsec_enable_chroot_shmat,
18233 +               .maxlen         = sizeof(int),
18234 +               .mode           = 0600,
18235 +               .proc_handler   = &proc_dointvec,
18236 +       },
18237 +#endif
18238 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
18239 +       {
18240 +               .ctl_name       = GS_CHROOT_UNIX,
18241 +               .procname       = "chroot_deny_unix",
18242 +               .data           = &grsec_enable_chroot_unix,
18243 +               .maxlen         = sizeof(int),
18244 +               .mode           = 0600,
18245 +               .proc_handler   = &proc_dointvec,
18246 +       },
18247 +#endif
18248 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
18249 +       {
18250 +               .ctl_name       = GS_CHROOT_MNT,
18251 +               .procname       = "chroot_deny_mount",
18252 +               .data           = &grsec_enable_chroot_mount,
18253 +               .maxlen         = sizeof(int),
18254 +               .mode           = 0600,
18255 +               .proc_handler   = &proc_dointvec,
18256 +       },
18257 +#endif
18258 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
18259 +       {
18260 +               .ctl_name       = GS_CHROOT_FCHDIR,
18261 +               .procname       = "chroot_deny_fchdir",
18262 +               .data           = &grsec_enable_chroot_fchdir,
18263 +               .maxlen         = sizeof(int),
18264 +               .mode           = 0600,
18265 +               .proc_handler   = &proc_dointvec,
18266 +       },
18267 +#endif
18268 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
18269 +       {
18270 +               .ctl_name       = GS_CHROOT_DBL,
18271 +               .procname       = "chroot_deny_chroot",
18272 +               .data           = &grsec_enable_chroot_double,
18273 +               .maxlen         = sizeof(int),
18274 +               .mode           = 0600,
18275 +               .proc_handler   = &proc_dointvec,
18276 +       },
18277 +#endif
18278 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
18279 +       {
18280 +               .ctl_name       = GS_CHROOT_PVT,
18281 +               .procname       = "chroot_deny_pivot",
18282 +               .data           = &grsec_enable_chroot_pivot,
18283 +               .maxlen         = sizeof(int),
18284 +               .mode           = 0600,
18285 +               .proc_handler   = &proc_dointvec,
18286 +       },
18287 +#endif
18288 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
18289 +       {
18290 +               .ctl_name       = GS_CHROOT_CD,
18291 +               .procname       = "chroot_enforce_chdir",
18292 +               .data           = &grsec_enable_chroot_chdir,
18293 +               .maxlen         = sizeof(int),
18294 +               .mode           = 0600,
18295 +               .proc_handler   = &proc_dointvec,
18296 +       },
18297 +#endif
18298 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
18299 +       {
18300 +               .ctl_name       = GS_CHROOT_CM,
18301 +               .procname       = "chroot_deny_chmod",
18302 +               .data           = &grsec_enable_chroot_chmod,
18303 +               .maxlen         = sizeof(int),
18304 +               .mode           = 0600,
18305 +               .proc_handler   = &proc_dointvec,
18306 +       },
18307 +#endif
18308 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
18309 +       {
18310 +               .ctl_name       = GS_CHROOT_MK,
18311 +               .procname       = "chroot_deny_mknod",
18312 +               .data           = &grsec_enable_chroot_mknod,
18313 +               .maxlen         = sizeof(int),
18314 +               .mode           = 0600,
18315 +               .proc_handler   = &proc_dointvec,
18316 +       },
18317 +#endif
18318 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
18319 +       {
18320 +               .ctl_name       = GS_CHROOT_NI,
18321 +               .procname       = "chroot_restrict_nice",
18322 +               .data           = &grsec_enable_chroot_nice,
18323 +               .maxlen         = sizeof(int),
18324 +               .mode           = 0600,
18325 +               .proc_handler   = &proc_dointvec,
18326 +       },
18327 +#endif
18328 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
18329 +       {
18330 +               .ctl_name       = GS_CHROOT_EXECLOG,
18331 +               .procname       = "chroot_execlog",
18332 +               .data           = &grsec_enable_chroot_execlog,
18333 +               .maxlen         = sizeof(int),
18334 +               .mode           = 0600,
18335 +               .proc_handler   = &proc_dointvec,
18336 +       },
18337 +#endif
18338 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
18339 +       {
18340 +               .ctl_name       = GS_CHROOT_CAPS,
18341 +               .procname       = "chroot_caps",
18342 +               .data           = &grsec_enable_chroot_caps,
18343 +               .maxlen         = sizeof(int),
18344 +               .mode           = 0600,
18345 +               .proc_handler   = &proc_dointvec,
18346 +       },
18347 +#endif
18348 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
18349 +       {
18350 +               .ctl_name       = GS_CHROOT_SYSCTL,
18351 +               .procname       = "chroot_deny_sysctl",
18352 +               .data           = &grsec_enable_chroot_sysctl,
18353 +               .maxlen         = sizeof(int),
18354 +               .mode           = 0600,
18355 +               .proc_handler   = &proc_dointvec,
18356 +       },
18357 +#endif
18358 +#ifdef CONFIG_GRKERNSEC_TPE
18359 +       {
18360 +               .ctl_name       = GS_TPE,
18361 +               .procname       = "tpe",
18362 +               .data           = &grsec_enable_tpe,
18363 +               .maxlen         = sizeof(int),
18364 +               .mode           = 0600,
18365 +               .proc_handler   = &proc_dointvec,
18366 +       },
18367 +       {
18368 +               .ctl_name       = GS_TPE_GID,
18369 +               .procname       = "tpe_gid",
18370 +               .data           = &grsec_tpe_gid,
18371 +               .maxlen         = sizeof(int),
18372 +               .mode           = 0600,
18373 +               .proc_handler   = &proc_dointvec,
18374 +       },
18375 +#endif
18376 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
18377 +       {
18378 +               .ctl_name       = GS_TPE_ALL,
18379 +               .procname       = "tpe_restrict_all",
18380 +               .data           = &grsec_enable_tpe_all,
18381 +               .maxlen         = sizeof(int),
18382 +               .mode           = 0600,
18383 +               .proc_handler   = &proc_dointvec,
18384 +       },
18385 +#endif
18386 +#ifdef CONFIG_GRKERNSEC_RANDPID
18387 +       {
18388 +               .ctl_name       = GS_RANDPID,
18389 +               .procname       = "rand_pids",
18390 +               .data           = &grsec_enable_randpid,
18391 +               .maxlen         = sizeof(int),
18392 +               .mode           = 0600,
18393 +               .proc_handler   = &proc_dointvec,
18394 +       },
18395 +#endif
18396 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
18397 +       {
18398 +               .ctl_name       = GS_SOCKET_ALL,
18399 +               .procname       = "socket_all",
18400 +               .data           = &grsec_enable_socket_all,
18401 +               .maxlen         = sizeof(int),
18402 +               .mode           = 0600,
18403 +               .proc_handler   = &proc_dointvec,
18404 +       },
18405 +       {
18406 +               .ctl_name       = GS_SOCKET_ALL_GID,
18407 +               .procname       = "socket_all_gid",
18408 +               .data           = &grsec_socket_all_gid,
18409 +               .maxlen         = sizeof(int),
18410 +               .mode           = 0600,
18411 +               .proc_handler   = &proc_dointvec,
18412 +       },
18413 +#endif
18414 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
18415 +       {
18416 +               .ctl_name       = GS_SOCKET_CLIENT,
18417 +               .procname       = "socket_client",
18418 +               .data           = &grsec_enable_socket_client,
18419 +               .maxlen         = sizeof(int),
18420 +               .mode           = 0600,
18421 +               .proc_handler   = &proc_dointvec,
18422 +       },
18423 +       {
18424 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
18425 +               .procname       = "socket_client_gid",
18426 +               .data           = &grsec_socket_client_gid,
18427 +               .maxlen         = sizeof(int),
18428 +               .mode           = 0600,
18429 +               .proc_handler   = &proc_dointvec,
18430 +       },
18431 +#endif
18432 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18433 +       {
18434 +               .ctl_name       = GS_SOCKET_SERVER,
18435 +               .procname       = "socket_server",
18436 +               .data           = &grsec_enable_socket_server,
18437 +               .maxlen         = sizeof(int),
18438 +               .mode           = 0600,
18439 +               .proc_handler   = &proc_dointvec,
18440 +       },
18441 +       {
18442 +               .ctl_name       = GS_SOCKET_SERVER_GID,
18443 +               .procname       = "socket_server_gid",
18444 +               .data           = &grsec_socket_server_gid,
18445 +               .maxlen         = sizeof(int),
18446 +               .mode           = 0600,
18447 +               .proc_handler   = &proc_dointvec,
18448 +       },
18449 +#endif
18450 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
18451 +       {
18452 +               .ctl_name       = GS_GROUP,
18453 +               .procname       = "audit_group",
18454 +               .data           = &grsec_enable_group,
18455 +               .maxlen         = sizeof(int),
18456 +               .mode           = 0600,
18457 +               .proc_handler   = &proc_dointvec,
18458 +       },
18459 +       {
18460 +               .ctl_name       = GS_GID,
18461 +               .procname       = "audit_gid",
18462 +               .data           = &grsec_audit_gid,
18463 +               .maxlen         = sizeof(int),
18464 +               .mode           = 0600,
18465 +               .proc_handler   = &proc_dointvec,
18466 +       },
18467 +#endif
18468 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
18469 +       {
18470 +               .ctl_name       = GS_ACHDIR,
18471 +               .procname       = "audit_chdir",
18472 +               .data           = &grsec_enable_chdir,
18473 +               .maxlen         = sizeof(int),
18474 +               .mode           = 0600,
18475 +               .proc_handler   = &proc_dointvec,
18476 +       },
18477 +#endif
18478 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18479 +       {
18480 +               .ctl_name       = GS_AMOUNT,
18481 +               .procname       = "audit_mount",
18482 +               .data           = &grsec_enable_mount,
18483 +               .maxlen         = sizeof(int),
18484 +               .mode           = 0600,
18485 +               .proc_handler   = &proc_dointvec,
18486 +       },
18487 +#endif
18488 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18489 +       {
18490 +               .ctl_name       = GS_AIPC,
18491 +               .procname       = "audit_ipc",
18492 +               .data           = &grsec_enable_audit_ipc,
18493 +               .maxlen         = sizeof(int),
18494 +               .mode           = 0600,
18495 +               .proc_handler   = &proc_dointvec,
18496 +       },
18497 +#endif
18498 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
18499 +       {
18500 +               .ctl_name       = GS_TEXTREL,
18501 +               .procname       = "audit_textrel",
18502 +               .data           = &grsec_enable_audit_textrel,
18503 +               .maxlen         = sizeof(int),
18504 +               .mode           = 0600,
18505 +               .proc_handler   = &proc_dointvec,
18506 +       },
18507 +#endif
18508 +#ifdef CONFIG_GRKERNSEC_DMESG
18509 +       {
18510 +               .ctl_name       = GS_DMSG,
18511 +               .procname       = "dmesg",
18512 +               .data           = &grsec_enable_dmesg,
18513 +               .maxlen         = sizeof(int),
18514 +               .mode           = 0600,
18515 +               .proc_handler   = &proc_dointvec,
18516 +       },
18517 +#endif
18518 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
18519 +       {
18520 +               .ctl_name       = GS_FINDTASK,
18521 +               .procname       = "chroot_findtask",
18522 +               .data           = &grsec_enable_chroot_findtask,
18523 +               .maxlen         = sizeof(int),
18524 +               .mode           = 0600,
18525 +               .proc_handler   = &proc_dointvec,
18526 +       },
18527 +#endif
18528 +#ifdef CONFIG_GRKERNSEC_SHM
18529 +       {
18530 +               .ctl_name       = GS_SHM,
18531 +               .procname       = "destroy_unused_shm",
18532 +               .data           = &grsec_enable_shm,
18533 +               .maxlen         = sizeof(int),
18534 +               .mode           = 0600,
18535 +               .proc_handler   = &proc_dointvec,
18536 +       },
18537 +#endif
18538 +#ifdef CONFIG_GRKERNSEC_RESLOG
18539 +       {
18540 +               .ctl_name       = GS_RESLOG,
18541 +               .procname       = "resource_logging",
18542 +               .data           = &grsec_resource_logging,
18543 +               .maxlen         = sizeof(int),
18544 +               .mode           = 0600,
18545 +               .proc_handler   = &proc_dointvec,
18546 +       },
18547 +#endif
18548 +       {
18549 +               .ctl_name       = GS_LOCK,
18550 +               .procname       = "grsec_lock",
18551 +               .data           = &grsec_lock,
18552 +               .maxlen         = sizeof(int),
18553 +               .mode           = 0600,
18554 +               .proc_handler   = &proc_dointvec,
18555 +       },
18556 +#endif
18557 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18558 +       {
18559 +               .ctl_name       = GS_MODSTOP,
18560 +               .procname       = "disable_modules",
18561 +               .data           = &grsec_modstop,
18562 +               .maxlen         = sizeof(int),
18563 +               .mode           = 0600,
18564 +               .proc_handler   = &proc_dointvec,
18565 +       },
18566 +#endif
18567 +       { .ctl_name = 0 }
18568 +};
18569 +#endif
18570 +
18571 +int gr_check_modstop(void)
18572 +{
18573 +#ifdef CONFIG_GRKERNSEC_MODSTOP
18574 +       if (grsec_modstop == 1) {
18575 +               gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
18576 +               return 1;
18577 +       }
18578 +#endif
18579 +       return 0;
18580 +}
18581 diff -urNp linux-2.6.17.7/grsecurity/grsec_textrel.c linux-2.6.17.7/grsecurity/grsec_textrel.c
18582 --- linux-2.6.17.7/grsecurity/grsec_textrel.c   1969-12-31 19:00:00.000000000 -0500
18583 +++ linux-2.6.17.7/grsecurity/grsec_textrel.c   2006-08-01 20:29:47.000000000 -0400
18584 @@ -0,0 +1,16 @@
18585 +#include <linux/kernel.h>
18586 +#include <linux/sched.h>
18587 +#include <linux/mm.h>
18588 +#include <linux/file.h>
18589 +#include <linux/grinternal.h>
18590 +#include <linux/grsecurity.h>
18591 +
18592 +void
18593 +gr_log_textrel(struct vm_area_struct * vma)
18594 +{
18595 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
18596 +       if (grsec_enable_audit_textrel)
18597 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
18598 +#endif
18599 +       return;
18600 +}
18601 diff -urNp linux-2.6.17.7/grsecurity/grsec_time.c linux-2.6.17.7/grsecurity/grsec_time.c
18602 --- linux-2.6.17.7/grsecurity/grsec_time.c      1969-12-31 19:00:00.000000000 -0500
18603 +++ linux-2.6.17.7/grsecurity/grsec_time.c      2006-08-01 20:29:47.000000000 -0400
18604 @@ -0,0 +1,13 @@
18605 +#include <linux/kernel.h>
18606 +#include <linux/sched.h>
18607 +#include <linux/grinternal.h>
18608 +
18609 +void
18610 +gr_log_timechange(void)
18611 +{
18612 +#ifdef CONFIG_GRKERNSEC_TIME
18613 +       if (grsec_enable_time)
18614 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
18615 +#endif
18616 +       return;
18617 +}
18618 diff -urNp linux-2.6.17.7/grsecurity/grsec_tpe.c linux-2.6.17.7/grsecurity/grsec_tpe.c
18619 --- linux-2.6.17.7/grsecurity/grsec_tpe.c       1969-12-31 19:00:00.000000000 -0500
18620 +++ linux-2.6.17.7/grsecurity/grsec_tpe.c       2006-08-01 20:29:47.000000000 -0400
18621 @@ -0,0 +1,37 @@
18622 +#include <linux/kernel.h>
18623 +#include <linux/sched.h>
18624 +#include <linux/file.h>
18625 +#include <linux/fs.h>
18626 +#include <linux/grinternal.h>
18627 +
18628 +extern int gr_acl_tpe_check(void);
18629 +
18630 +int
18631 +gr_tpe_allow(const struct file *file)
18632 +{
18633 +#ifdef CONFIG_GRKERNSEC
18634 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
18635 +
18636 +       if (current->uid && ((grsec_enable_tpe &&
18637 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
18638 +           !in_group_p(grsec_tpe_gid)
18639 +#else
18640 +           in_group_p(grsec_tpe_gid)
18641 +#endif
18642 +           ) || gr_acl_tpe_check()) &&
18643 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
18644 +                                               (inode->i_mode & S_IWOTH))))) {
18645 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
18646 +               return 0;
18647 +       }
18648 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
18649 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
18650 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
18651 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
18652 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
18653 +               return 0;
18654 +       }
18655 +#endif
18656 +#endif
18657 +       return 1;
18658 +}
18659 diff -urNp linux-2.6.17.7/grsecurity/grsum.c linux-2.6.17.7/grsecurity/grsum.c
18660 --- linux-2.6.17.7/grsecurity/grsum.c   1969-12-31 19:00:00.000000000 -0500
18661 +++ linux-2.6.17.7/grsecurity/grsum.c   2006-08-01 20:29:47.000000000 -0400
18662 @@ -0,0 +1,59 @@
18663 +#include <linux/kernel.h>
18664 +#include <linux/sched.h>
18665 +#include <linux/mm.h>
18666 +#include <asm/scatterlist.h>
18667 +#include <linux/crypto.h>
18668 +#include <linux/gracl.h>
18669 +
18670 +
18671 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
18672 +#error "crypto and sha256 must be built into the kernel"
18673 +#endif
18674 +
18675 +int
18676 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
18677 +{
18678 +       char *p;
18679 +       struct crypto_tfm *tfm;
18680 +       unsigned char temp_sum[GR_SHA_LEN];
18681 +       struct scatterlist sg[2];
18682 +       volatile int retval = 0;
18683 +       volatile int dummy = 0;
18684 +       unsigned int i;
18685 +
18686 +       tfm = crypto_alloc_tfm("sha256", 0);
18687 +       if (tfm == NULL) {
18688 +               /* should never happen, since sha256 should be built in */
18689 +               return 1;
18690 +       }
18691 +
18692 +       crypto_digest_init(tfm);
18693 +
18694 +       p = salt;
18695 +       sg[0].page = virt_to_page(p);
18696 +       sg[0].offset = ((long) p & ~PAGE_MASK);
18697 +       sg[0].length = GR_SALT_LEN;
18698 +       
18699 +       crypto_digest_update(tfm, sg, 1);
18700 +
18701 +       p = entry->pw;
18702 +       sg[0].page = virt_to_page(p);
18703 +       sg[0].offset = ((long) p & ~PAGE_MASK);
18704 +       sg[0].length = strlen(entry->pw);
18705 +
18706 +       crypto_digest_update(tfm, sg, 1);
18707 +
18708 +       crypto_digest_final(tfm, temp_sum);
18709 +
18710 +       memset(entry->pw, 0, GR_PW_LEN);
18711 +
18712 +       for (i = 0; i < GR_SHA_LEN; i++)
18713 +               if (sum[i] != temp_sum[i])
18714 +                       retval = 1;
18715 +               else
18716 +                       dummy = 1;      // waste a cycle
18717 +
18718 +       crypto_free_tfm(tfm);
18719 +
18720 +       return retval;
18721 +}
18722 diff -urNp linux-2.6.17.7/include/asm-alpha/a.out.h linux-2.6.17.7/include/asm-alpha/a.out.h
18723 --- linux-2.6.17.7/include/asm-alpha/a.out.h    2006-07-24 23:36:01.000000000 -0400
18724 +++ linux-2.6.17.7/include/asm-alpha/a.out.h    2006-08-01 20:29:47.000000000 -0400
18725 @@ -98,7 +98,7 @@ struct exec
18726         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
18727                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
18728  
18729 -#define STACK_TOP \
18730 +#define __STACK_TOP \
18731    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
18732  
18733  #endif
18734 diff -urNp linux-2.6.17.7/include/asm-alpha/elf.h linux-2.6.17.7/include/asm-alpha/elf.h
18735 --- linux-2.6.17.7/include/asm-alpha/elf.h      2006-07-24 23:36:01.000000000 -0400
18736 +++ linux-2.6.17.7/include/asm-alpha/elf.h      2006-08-01 20:29:47.000000000 -0400
18737 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
18738  
18739  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
18740  
18741 +#ifdef CONFIG_PAX_ASLR
18742 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
18743 +
18744 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18745 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
18746 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18747 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
18748 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18749 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
18750 +#endif
18751 +
18752  /* $0 is set by ld.so to a pointer to a function which might be 
18753     registered using atexit.  This provides a mean for the dynamic
18754     linker to call DT_FINI functions for shared libraries that have
18755 diff -urNp linux-2.6.17.7/include/asm-alpha/kmap_types.h linux-2.6.17.7/include/asm-alpha/kmap_types.h
18756 --- linux-2.6.17.7/include/asm-alpha/kmap_types.h       2006-07-24 23:36:01.000000000 -0400
18757 +++ linux-2.6.17.7/include/asm-alpha/kmap_types.h       2006-08-01 20:29:47.000000000 -0400
18758 @@ -25,7 +25,8 @@ D(9)  KM_IRQ0,
18759  D(10)  KM_IRQ1,
18760  D(11)  KM_SOFTIRQ0,
18761  D(12)  KM_SOFTIRQ1,
18762 -D(13)  KM_TYPE_NR
18763 +D(13)  KM_CLEARPAGE,
18764 +D(14)  KM_TYPE_NR
18765  };
18766  
18767  #undef D
18768 diff -urNp linux-2.6.17.7/include/asm-alpha/page.h linux-2.6.17.7/include/asm-alpha/page.h
18769 --- linux-2.6.17.7/include/asm-alpha/page.h     2006-07-24 23:36:01.000000000 -0400
18770 +++ linux-2.6.17.7/include/asm-alpha/page.h     2006-08-01 20:29:47.000000000 -0400
18771 @@ -93,6 +93,16 @@ typedef unsigned long pgprot_t;
18772  
18773  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
18774                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18775 +
18776 +#ifdef CONFIG_PAX_PAGEEXEC
18777 +#ifdef CONFIG_PAX_MPROTECT
18778 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18779 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18780 +#else
18781 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18782 +#endif
18783 +#endif
18784 +
18785  #endif /* __KERNEL__ */
18786  
18787  #include <asm-generic/memory_model.h>
18788 diff -urNp linux-2.6.17.7/include/asm-alpha/pgtable.h linux-2.6.17.7/include/asm-alpha/pgtable.h
18789 --- linux-2.6.17.7/include/asm-alpha/pgtable.h  2006-07-24 23:36:01.000000000 -0400
18790 +++ linux-2.6.17.7/include/asm-alpha/pgtable.h  2006-08-01 20:29:47.000000000 -0400
18791 @@ -102,6 +102,17 @@ struct vm_area_struct;
18792  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
18793  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
18794  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
18795 +
18796 +#ifdef CONFIG_PAX_PAGEEXEC
18797 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
18798 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
18799 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
18800 +#else
18801 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18802 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18803 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18804 +#endif
18805 +
18806  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
18807  
18808  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
18809 diff -urNp linux-2.6.17.7/include/asm-arm/a.out.h linux-2.6.17.7/include/asm-arm/a.out.h
18810 --- linux-2.6.17.7/include/asm-arm/a.out.h      2006-07-24 23:36:01.000000000 -0400
18811 +++ linux-2.6.17.7/include/asm-arm/a.out.h      2006-08-01 20:29:47.000000000 -0400
18812 @@ -28,7 +28,7 @@ struct exec
18813  #define M_ARM 103
18814  
18815  #ifdef __KERNEL__
18816 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
18817 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
18818                          TASK_SIZE : TASK_SIZE_26)
18819  #endif
18820  
18821 diff -urNp linux-2.6.17.7/include/asm-arm/elf.h linux-2.6.17.7/include/asm-arm/elf.h
18822 --- linux-2.6.17.7/include/asm-arm/elf.h        2006-07-24 23:36:01.000000000 -0400
18823 +++ linux-2.6.17.7/include/asm-arm/elf.h        2006-08-01 20:29:47.000000000 -0400
18824 @@ -56,6 +56,17 @@ typedef struct user_fp elf_fpregset_t;
18825  
18826  #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
18827  
18828 +#ifdef CONFIG_PAX_ASLR
18829 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x00008000UL
18830 +
18831 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18832 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
18833 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18834 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
18835 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18836 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
18837 +#endif
18838 +
18839  /* When the program starts, a1 contains a pointer to a function to be 
18840     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
18841     have no such handler.  */
18842 diff -urNp linux-2.6.17.7/include/asm-arm/kmap_types.h linux-2.6.17.7/include/asm-arm/kmap_types.h
18843 --- linux-2.6.17.7/include/asm-arm/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
18844 +++ linux-2.6.17.7/include/asm-arm/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
18845 @@ -18,6 +18,7 @@ enum km_type {
18846         KM_IRQ1,
18847         KM_SOFTIRQ0,
18848         KM_SOFTIRQ1,
18849 +       KM_CLEARPAGE,
18850         KM_TYPE_NR
18851  };
18852  
18853 diff -urNp linux-2.6.17.7/include/asm-arm26/kmap_types.h linux-2.6.17.7/include/asm-arm26/kmap_types.h
18854 --- linux-2.6.17.7/include/asm-arm26/kmap_types.h       2006-07-24 23:36:01.000000000 -0400
18855 +++ linux-2.6.17.7/include/asm-arm26/kmap_types.h       2006-08-01 20:29:47.000000000 -0400
18856 @@ -6,7 +6,8 @@
18857   */
18858  enum km_type {
18859          KM_IRQ0,
18860 -        KM_USER1
18861 +        KM_USER1,
18862 +        KM_CLEARPAGE
18863  };
18864  
18865  #endif
18866 diff -urNp linux-2.6.17.7/include/asm-cris/kmap_types.h linux-2.6.17.7/include/asm-cris/kmap_types.h
18867 --- linux-2.6.17.7/include/asm-cris/kmap_types.h        2006-07-24 23:36:01.000000000 -0400
18868 +++ linux-2.6.17.7/include/asm-cris/kmap_types.h        2006-08-01 20:29:47.000000000 -0400
18869 @@ -19,6 +19,7 @@ enum km_type {
18870         KM_IRQ1,
18871         KM_SOFTIRQ0,
18872         KM_SOFTIRQ1,
18873 +       KM_CLEARPAGE,
18874         KM_TYPE_NR
18875  };
18876  
18877 diff -urNp linux-2.6.17.7/include/asm-frv/kmap_types.h linux-2.6.17.7/include/asm-frv/kmap_types.h
18878 --- linux-2.6.17.7/include/asm-frv/kmap_types.h 2006-07-24 23:36:01.000000000 -0400
18879 +++ linux-2.6.17.7/include/asm-frv/kmap_types.h 2006-08-01 20:29:47.000000000 -0400
18880 @@ -23,6 +23,7 @@ enum km_type {
18881         KM_IRQ1,
18882         KM_SOFTIRQ0,
18883         KM_SOFTIRQ1,
18884 +       KM_CLEARPAGE,
18885         KM_TYPE_NR
18886  };
18887  
18888 diff -urNp linux-2.6.17.7/include/asm-h8300/kmap_types.h linux-2.6.17.7/include/asm-h8300/kmap_types.h
18889 --- linux-2.6.17.7/include/asm-h8300/kmap_types.h       2006-07-24 23:36:01.000000000 -0400
18890 +++ linux-2.6.17.7/include/asm-h8300/kmap_types.h       2006-08-01 20:29:47.000000000 -0400
18891 @@ -15,6 +15,7 @@ enum km_type {
18892         KM_IRQ1,
18893         KM_SOFTIRQ0,
18894         KM_SOFTIRQ1,
18895 +       KM_CLEARPAGE,
18896         KM_TYPE_NR
18897  };
18898  
18899 diff -urNp linux-2.6.17.7/include/asm-i386/a.out.h linux-2.6.17.7/include/asm-i386/a.out.h
18900 --- linux-2.6.17.7/include/asm-i386/a.out.h     2006-07-24 23:36:01.000000000 -0400
18901 +++ linux-2.6.17.7/include/asm-i386/a.out.h     2006-08-01 20:29:47.000000000 -0400
18902 @@ -19,7 +19,11 @@ struct exec
18903  
18904  #ifdef __KERNEL__
18905  
18906 -#define STACK_TOP      TASK_SIZE
18907 +#ifdef CONFIG_PAX_SEGMEXEC
18908 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
18909 +#else
18910 +#define __STACK_TOP TASK_SIZE
18911 +#endif
18912  
18913  #endif
18914  
18915 diff -urNp linux-2.6.17.7/include/asm-i386/alternative.h linux-2.6.17.7/include/asm-i386/alternative.h
18916 --- linux-2.6.17.7/include/asm-i386/alternative.h       2006-07-24 23:36:01.000000000 -0400
18917 +++ linux-2.6.17.7/include/asm-i386/alternative.h       2006-08-01 20:29:47.000000000 -0400
18918 @@ -47,7 +47,7 @@ extern void alternatives_smp_switch(int 
18919                       "  .byte 662b-661b\n"       /* sourcelen */       \
18920                       "  .byte 664f-663f\n"       /* replacementlen */  \
18921                       ".previous\n"                                     \
18922 -                     ".section .altinstr_replacement,\"ax\"\n"         \
18923 +                     ".section .altinstr_replacement,\"a\"\n"          \
18924                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
18925                       ".previous" :: "i" (feature) : "memory")
18926  
18927 @@ -71,7 +71,7 @@ extern void alternatives_smp_switch(int 
18928                       "  .byte 662b-661b\n"       /* sourcelen */       \
18929                       "  .byte 664f-663f\n"       /* replacementlen */  \
18930                       ".previous\n"                                     \
18931 -                     ".section .altinstr_replacement,\"ax\"\n"         \
18932 +                     ".section .altinstr_replacement,\"a\"\n"          \
18933                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
18934                       ".previous" :: "i" (feature), ##input)
18935  
18936 @@ -110,7 +110,7 @@ extern void alternatives_smp_switch(int 
18937                       "  .byte 662b-661b\n"       /* sourcelen */       \
18938                       "  .byte 664f-663f\n"       /* replacementlen */  \
18939                       ".previous\n"                                     \
18940 -                     ".section .smp_altinstr_replacement,\"awx\"\n"    \
18941 +                     ".section .smp_altinstr_replacement,\"aw\"\n"     \
18942                       "663:\n\t" upinstr "\n"     /* replacement */     \
18943                       "664:\n\t.fill 662b-661b,1,0x42\n" /* space for original */ \
18944                       ".previous" : args)
18945 diff -urNp linux-2.6.17.7/include/asm-i386/auxvec.h linux-2.6.17.7/include/asm-i386/auxvec.h
18946 --- linux-2.6.17.7/include/asm-i386/auxvec.h    2006-07-24 23:36:01.000000000 -0400
18947 +++ linux-2.6.17.7/include/asm-i386/auxvec.h    2006-08-01 20:29:47.000000000 -0400
18948 @@ -5,7 +5,9 @@
18949   * Architecture-neutral AT_ values in 0-17, leave some room
18950   * for more of them, start the x86-specific ones at 32.
18951   */
18952 +#ifndef CONFIG_PAX_NOVSYSCALL
18953  #define AT_SYSINFO             32
18954  #define AT_SYSINFO_EHDR                33
18955 +#endif
18956  
18957  #endif
18958 diff -urNp linux-2.6.17.7/include/asm-i386/checksum.h linux-2.6.17.7/include/asm-i386/checksum.h
18959 --- linux-2.6.17.7/include/asm-i386/checksum.h  2006-07-24 23:36:01.000000000 -0400
18960 +++ linux-2.6.17.7/include/asm-i386/checksum.h  2006-08-01 20:29:47.000000000 -0400
18961 @@ -30,6 +30,12 @@ asmlinkage unsigned int csum_partial(con
18962  asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned char *dst,
18963                                                   int len, int sum, int *src_err_ptr, int *dst_err_ptr);
18964  
18965 +asmlinkage unsigned int csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
18966 +                                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
18967 +
18968 +asmlinkage unsigned int csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
18969 +                                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
18970 +
18971  /*
18972   *     Note: when you get a NULL pointer exception here this means someone
18973   *     passed in an incorrect kernel address to one of these functions.
18974 @@ -49,7 +55,7 @@ unsigned int csum_partial_copy_from_user
18975                                                 int len, int sum, int *err_ptr)
18976  {
18977         might_sleep();
18978 -       return csum_partial_copy_generic((__force unsigned char *)src, dst,
18979 +       return csum_partial_copy_generic_from_user((__force unsigned char *)src, dst,
18980                                         len, sum, err_ptr, NULL);
18981  }
18982  
18983 @@ -183,7 +189,7 @@ static __inline__ unsigned int csum_and_
18984  {
18985         might_sleep();
18986         if (access_ok(VERIFY_WRITE, dst, len))
18987 -               return csum_partial_copy_generic(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
18988 +               return csum_partial_copy_generic_to_user(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
18989  
18990         if (len)
18991                 *err_ptr = -EFAULT;
18992 diff -urNp linux-2.6.17.7/include/asm-i386/desc.h linux-2.6.17.7/include/asm-i386/desc.h
18993 --- linux-2.6.17.7/include/asm-i386/desc.h      2006-07-24 23:36:01.000000000 -0400
18994 +++ linux-2.6.17.7/include/asm-i386/desc.h      2006-08-01 20:29:47.000000000 -0400
18995 @@ -10,11 +10,13 @@
18996  
18997  #include <linux/preempt.h>
18998  #include <linux/smp.h>
18999 -#include <linux/percpu.h>
19000 +#include <linux/sched.h>
19001  
19002  #include <asm/mmu.h>
19003 +#include <asm/pgtable.h>
19004 +#include <asm/tlbflush.h>
19005  
19006 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
19007 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
19008  
19009  DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
19010  
19011 @@ -24,13 +26,53 @@ struct Xgt_desc_struct {
19012         unsigned short pad;
19013  } __attribute__ ((packed));
19014  
19015 -extern struct Xgt_desc_struct idt_descr;
19016 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
19017 -
19018 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
19019  
19020  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
19021  {
19022 -       return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
19023 +       return cpu_gdt_table[cpu];
19024 +}
19025 +
19026 +#define pax_open_kernel(cr0)           \
19027 +do {                                   \
19028 +       typecheck(unsigned long,cr0);   \
19029 +       preempt_disable();              \
19030 +       cr0 = read_cr0();               \
19031 +       write_cr0(cr0 & ~0x10000UL);    \
19032 +} while(0)
19033 +
19034 +#define pax_close_kernel(cr0)          \
19035 +do {                                   \
19036 +       typecheck(unsigned long,cr0);   \
19037 +       write_cr0(cr0);                 \
19038 +       preempt_enable_no_resched();    \
19039 +} while(0)
19040 +
19041 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
19042 +{
19043 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19044 +       unsigned long base = mm->context.user_cs_base;
19045 +       unsigned long limit = mm->context.user_cs_limit;
19046 +
19047 +#ifdef CONFIG_PAX_KERNEXEC
19048 +       unsigned long cr0;
19049 +
19050 +       pax_open_kernel(cr0);
19051 +#endif
19052 +
19053 +       if (likely(limit)) {
19054 +               limit -= 1UL;
19055 +               limit >>= 12;
19056 +       }
19057 +
19058 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
19059 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
19060 +
19061 +#ifdef CONFIG_PAX_KERNEXEC
19062 +       pax_close_kernel(cr0);
19063 +#endif
19064 +
19065 +#endif
19066  }
19067  
19068  #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
19069 @@ -50,7 +92,7 @@ static inline struct desc_struct *get_cp
19070   * This is the ldt that every process will get unless we need
19071   * something other than this.
19072   */
19073 -extern struct desc_struct default_ldt[];
19074 +extern const struct desc_struct default_ldt[];
19075  extern void set_intr_gate(unsigned int irq, void * addr);
19076  
19077  #define _set_tssldt_desc(n,addr,limit,type) \
19078 @@ -64,7 +106,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
19079         "rorl $16,%1" \
19080         : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
19081  
19082 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
19083 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
19084  {
19085         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
19086                 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
19087 @@ -72,11 +114,28 @@ static inline void __set_tss_desc(unsign
19088  
19089  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
19090  
19091 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
19092 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
19093  {
19094         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
19095  }
19096  
19097 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
19098 +{
19099 +
19100 +#ifdef CONFIG_PAX_KERNEXEC
19101 +       unsigned long cr0;
19102 +
19103 +       pax_open_kernel(cr0);
19104 +#endif
19105 +
19106 +       _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
19107 +
19108 +#ifdef CONFIG_PAX_KERNEXEC
19109 +       pax_close_kernel(cr0);
19110 +#endif
19111 +
19112 +}
19113 +
19114  #define LDT_entry_a(info) \
19115         ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
19116  
19117 @@ -90,7 +149,7 @@ static inline void set_ldt_desc(unsigned
19118         ((info)->seg_32bit << 22) | \
19119         ((info)->limit_in_pages << 23) | \
19120         ((info)->useable << 20) | \
19121 -       0x7000)
19122 +       0x7100)
19123  
19124  #define LDT_empty(info) (\
19125         (info)->base_addr       == 0    && \
19126 @@ -134,7 +193,7 @@ static inline void clear_LDT(void)
19127   */
19128  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
19129  {
19130 -       void *segments = pc->ldt;
19131 +       const void *segments = pc->ldt;
19132         int count = pc->size;
19133  
19134         if (likely(!count)) {
19135 @@ -162,6 +221,22 @@ static inline unsigned long get_desc_bas
19136         return base;
19137  }
19138  
19139 +static inline void _load_LDT(mm_context_t *pc)
19140 +{
19141 +       int cpu = get_cpu();
19142 +       const void *segments = pc->ldt;
19143 +       int count = pc->size;
19144 +
19145 +       if (likely(!count)) {
19146 +               segments = &default_ldt[0];
19147 +               count = 5;
19148 +       }
19149 +               
19150 +       __set_ldt_desc(cpu, segments, count);
19151 +       load_LDT_desc();
19152 +       put_cpu();
19153 +}
19154 +
19155  #endif /* !__ASSEMBLY__ */
19156  
19157  #endif
19158 diff -urNp linux-2.6.17.7/include/asm-i386/elf.h linux-2.6.17.7/include/asm-i386/elf.h
19159 --- linux-2.6.17.7/include/asm-i386/elf.h       2006-07-24 23:36:01.000000000 -0400
19160 +++ linux-2.6.17.7/include/asm-i386/elf.h       2006-08-01 20:29:47.000000000 -0400
19161 @@ -71,6 +71,17 @@ typedef struct user_fxsr_struct elf_fpxr
19162  
19163  #define ELF_ET_DYN_BASE         ((TASK_UNMAPPED_BASE) * 2)
19164  
19165 +#ifdef CONFIG_PAX_ASLR
19166 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
19167 +
19168 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
19169 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
19170 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
19171 +#define PAX_DELTA_EXEC_LEN(tsk)                15
19172 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
19173 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
19174 +#endif
19175 +
19176  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
19177     now struct_user_regs, they are different) */
19178  
19179 @@ -131,7 +146,14 @@ extern int dump_task_extended_fpu (struc
19180  
19181  #define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
19182  #define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
19183 +
19184 +#ifndef CONFIG_PAX_NOVSYSCALL
19185 +#ifdef CONFIG_PAX_SEGMEXEC
19186 +#define VSYSCALL_ENTRY ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
19187 +#else
19188  #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
19189 +#endif
19190 +
19191  extern void __kernel_vsyscall;
19192  
19193  #define ARCH_DLINFO                                            \
19194 @@ -187,3 +209,5 @@ do {                                                                              \
19195  #endif
19196  
19197  #endif
19198 +
19199 +#endif
19200 diff -urNp linux-2.6.17.7/include/asm-i386/kmap_types.h linux-2.6.17.7/include/asm-i386/kmap_types.h
19201 --- linux-2.6.17.7/include/asm-i386/kmap_types.h        2006-07-24 23:36:01.000000000 -0400
19202 +++ linux-2.6.17.7/include/asm-i386/kmap_types.h        2006-08-01 20:29:47.000000000 -0400
19203 @@ -23,7 +23,8 @@ D(9)  KM_IRQ0,
19204  D(10)  KM_IRQ1,
19205  D(11)  KM_SOFTIRQ0,
19206  D(12)  KM_SOFTIRQ1,
19207 -D(13)  KM_TYPE_NR
19208 +D(13)  KM_CLEARPAGE,
19209 +D(14)  KM_TYPE_NR
19210  };
19211  
19212  #undef D
19213 diff -urNp linux-2.6.17.7/include/asm-i386/mach-default/apm.h linux-2.6.17.7/include/asm-i386/mach-default/apm.h
19214 --- linux-2.6.17.7/include/asm-i386/mach-default/apm.h  2006-07-24 23:36:01.000000000 -0400
19215 +++ linux-2.6.17.7/include/asm-i386/mach-default/apm.h  2006-08-01 20:29:47.000000000 -0400
19216 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
19217         __asm__ __volatile__(APM_DO_ZERO_SEGS
19218                 "pushl %%edi\n\t"
19219                 "pushl %%ebp\n\t"
19220 -               "lcall *%%cs:apm_bios_entry\n\t"
19221 +               "lcall *%%ss:apm_bios_entry\n\t"
19222                 "setc %%al\n\t"
19223                 "popl %%ebp\n\t"
19224                 "popl %%edi\n\t"
19225 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
19226         __asm__ __volatile__(APM_DO_ZERO_SEGS
19227                 "pushl %%edi\n\t"
19228                 "pushl %%ebp\n\t"
19229 -               "lcall *%%cs:apm_bios_entry\n\t"
19230 +               "lcall *%%ss:apm_bios_entry\n\t"
19231                 "setc %%bl\n\t"
19232                 "popl %%ebp\n\t"
19233                 "popl %%edi\n\t"
19234 diff -urNp linux-2.6.17.7/include/asm-i386/mach-default/do_timer.h linux-2.6.17.7/include/asm-i386/mach-default/do_timer.h
19235 --- linux-2.6.17.7/include/asm-i386/mach-default/do_timer.h     2006-07-24 23:36:01.000000000 -0400
19236 +++ linux-2.6.17.7/include/asm-i386/mach-default/do_timer.h     2006-08-01 20:29:47.000000000 -0400
19237 @@ -18,7 +18,7 @@ static inline void do_timer_interrupt_ho
19238  {
19239         do_timer(regs);
19240  #ifndef CONFIG_SMP
19241 -       update_process_times(user_mode_vm(regs));
19242 +       update_process_times(user_mode(regs));
19243  #endif
19244  /*
19245   * In the SMP case we use the local APIC timer interrupt to do the
19246 diff -urNp linux-2.6.17.7/include/asm-i386/mach-visws/do_timer.h linux-2.6.17.7/include/asm-i386/mach-visws/do_timer.h
19247 --- linux-2.6.17.7/include/asm-i386/mach-visws/do_timer.h       2006-07-24 23:36:01.000000000 -0400
19248 +++ linux-2.6.17.7/include/asm-i386/mach-visws/do_timer.h       2006-08-01 20:29:47.000000000 -0400
19249 @@ -11,7 +11,7 @@ static inline void do_timer_interrupt_ho
19250  
19251         do_timer(regs);
19252  #ifndef CONFIG_SMP
19253 -       update_process_times(user_mode_vm(regs));
19254 +       update_process_times(user_mode(regs));
19255  #endif
19256  /*
19257   * In the SMP case we use the local APIC timer interrupt to do the
19258 diff -urNp linux-2.6.17.7/include/asm-i386/mach-voyager/do_timer.h linux-2.6.17.7/include/asm-i386/mach-voyager/do_timer.h
19259 --- linux-2.6.17.7/include/asm-i386/mach-voyager/do_timer.h     2006-07-24 23:36:01.000000000 -0400
19260 +++ linux-2.6.17.7/include/asm-i386/mach-voyager/do_timer.h     2006-08-01 20:29:47.000000000 -0400
19261 @@ -5,7 +5,7 @@ static inline void do_timer_interrupt_ho
19262  {
19263         do_timer(regs);
19264  #ifndef CONFIG_SMP
19265 -       update_process_times(user_mode_vm(regs));
19266 +       update_process_times(user_mode(regs));
19267  #endif
19268  
19269         voyager_timer_interrupt(regs);
19270 diff -urNp linux-2.6.17.7/include/asm-i386/mman.h linux-2.6.17.7/include/asm-i386/mman.h
19271 --- linux-2.6.17.7/include/asm-i386/mman.h      2006-07-24 23:36:01.000000000 -0400
19272 +++ linux-2.6.17.7/include/asm-i386/mman.h      2006-08-01 20:29:47.000000000 -0400
19273 @@ -11,6 +11,10 @@
19274  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
19275  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
19276  
19277 +#ifdef CONFIG_PAX_SEGMEXEC
19278 +#define MAP_MIRROR     0x20000
19279 +#endif
19280 +
19281  #define MCL_CURRENT    1               /* lock all current mappings */
19282  #define MCL_FUTURE     2               /* lock all future mappings */
19283  
19284 diff -urNp linux-2.6.17.7/include/asm-i386/mmu.h linux-2.6.17.7/include/asm-i386/mmu.h
19285 --- linux-2.6.17.7/include/asm-i386/mmu.h       2006-07-24 23:36:01.000000000 -0400
19286 +++ linux-2.6.17.7/include/asm-i386/mmu.h       2006-08-01 20:29:47.000000000 -0400
19287 @@ -12,6 +12,17 @@ typedef struct { 
19288         int size;
19289         struct semaphore sem;
19290         void *ldt;
19291 +
19292 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19293 +       unsigned long user_cs_base;
19294 +       unsigned long user_cs_limit;
19295 +
19296 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
19297 +       cpumask_t cpu_user_cs_mask;
19298 +#endif
19299 +
19300 +#endif
19301 +
19302  } mm_context_t;
19303  
19304  #endif
19305 diff -urNp linux-2.6.17.7/include/asm-i386/mmu_context.h linux-2.6.17.7/include/asm-i386/mmu_context.h
19306 --- linux-2.6.17.7/include/asm-i386/mmu_context.h       2006-07-24 23:36:01.000000000 -0400
19307 +++ linux-2.6.17.7/include/asm-i386/mmu_context.h       2006-08-01 20:29:47.000000000 -0400
19308 @@ -46,6 +46,18 @@ static inline void switch_mm(struct mm_s
19309                  */
19310                 if (unlikely(prev->context.ldt != next->context.ldt))
19311                         load_LDT_nolock(&next->context, cpu);
19312 +
19313 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
19314 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
19315 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
19316 +#endif
19317 +
19318 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19319 +               if (prev->context.user_cs_base != next->context.user_cs_base ||
19320 +                   prev->context.user_cs_limit != next->context.user_cs_limit)
19321 +#endif
19322 +
19323 +                       set_user_cs(next, cpu);
19324         }
19325  #ifdef CONFIG_SMP
19326         else {
19327 @@ -58,6 +70,12 @@ static inline void switch_mm(struct mm_s
19328                          */
19329                         load_cr3(next->pgd);
19330                         load_LDT_nolock(&next->context, cpu);
19331 +
19332 +#ifdef CONFIG_PAX_PAGEEXEC
19333 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
19334 +#endif
19335 +
19336 +                       set_user_cs(next, cpu);
19337                 }
19338         }
19339  #endif
19340 diff -urNp linux-2.6.17.7/include/asm-i386/module.h linux-2.6.17.7/include/asm-i386/module.h
19341 --- linux-2.6.17.7/include/asm-i386/module.h    2006-07-24 23:36:01.000000000 -0400
19342 +++ linux-2.6.17.7/include/asm-i386/module.h    2006-08-01 20:29:47.000000000 -0400
19343 @@ -72,6 +72,12 @@ struct mod_arch_specific
19344  #define MODULE_STACKSIZE ""
19345  #endif
19346  
19347 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
19348 +#ifdef CONFIG_GRKERNSEC
19349 +#define MODULE_GRSEC "GRSECURITY "
19350 +#else
19351 +#define MODULE_GRSEC ""
19352 +#endif
19353 +
19354 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
19355  
19356  #endif /* _ASM_I386_MODULE_H */
19357 diff -urNp linux-2.6.17.7/include/asm-i386/page.h linux-2.6.17.7/include/asm-i386/page.h
19358 --- linux-2.6.17.7/include/asm-i386/page.h      2006-07-24 23:36:01.000000000 -0400
19359 +++ linux-2.6.17.7/include/asm-i386/page.h      2006-08-01 20:29:47.000000000 -0400
19360 @@ -57,7 +57,6 @@ typedef struct { unsigned long long pgpr
19361  typedef struct { unsigned long pte_low; } pte_t;
19362  typedef struct { unsigned long pgd; } pgd_t;
19363  typedef struct { unsigned long pgprot; } pgprot_t;
19364 -#define boot_pte_t pte_t /* or would you rather have a typedef */
19365  #define pte_val(x)     ((x).pte_low)
19366  #define HPAGE_SHIFT    22
19367  #endif
19368 @@ -118,6 +117,15 @@ extern int page_is_ram(unsigned long pag
19369  #endif
19370  #define __KERNEL_START         (__PAGE_OFFSET + __PHYSICAL_START)
19371  
19372 +#ifdef CONFIG_PAX_KERNEXEC
19373 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + ((__PHYSICAL_START + ~(4*1024*1024)) & (4*1024*1024)))
19374 +#ifndef __ASSEMBLY__
19375 +extern unsigned char MODULES_VADDR[];
19376 +extern unsigned char MODULES_END[];
19377 +#endif
19378 +#else
19379 +#define __KERNEL_TEXT_OFFSET   (0)
19380 +#endif
19381  
19382  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
19383  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
19384 @@ -137,6 +145,19 @@ extern int page_is_ram(unsigned long pag
19385         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
19386                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
19387  
19388 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19389 +#ifdef CONFIG_PAX_MPROTECT
19390 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
19391 +                         ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
19392 +#else
19393 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
19394 +#endif
19395 +#endif
19396 +
19397 +#ifdef CONFIG_PAX_PAGEEXEC
19398 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
19399 +#endif
19400 +
19401  #endif /* __KERNEL__ */
19402  
19403  #include <asm-generic/memory_model.h>
19404 diff -urNp linux-2.6.17.7/include/asm-i386/pgalloc.h linux-2.6.17.7/include/asm-i386/pgalloc.h
19405 --- linux-2.6.17.7/include/asm-i386/pgalloc.h   2006-07-24 23:36:01.000000000 -0400
19406 +++ linux-2.6.17.7/include/asm-i386/pgalloc.h   2006-08-01 20:29:47.000000000 -0400
19407 @@ -3,11 +3,17 @@
19408  
19409  #include <linux/config.h>
19410  #include <asm/fixmap.h>
19411 +#include <asm/desc.h>
19412  #include <linux/threads.h>
19413  #include <linux/mm.h>          /* for struct page */
19414  
19415 +#ifdef CONFIG_PAX_NOVSYSCALL
19416 +#define pmd_populate_kernel(mm, pmd, pte) \
19417 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
19418 +#else
19419  #define pmd_populate_kernel(mm, pmd, pte) \
19420                 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
19421 +#endif
19422  
19423  #define pmd_populate(mm, pmd, pte)                             \
19424         set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
19425 diff -urNp linux-2.6.17.7/include/asm-i386/pgtable.h linux-2.6.17.7/include/asm-i386/pgtable.h
19426 --- linux-2.6.17.7/include/asm-i386/pgtable.h   2006-07-24 23:36:01.000000000 -0400
19427 +++ linux-2.6.17.7/include/asm-i386/pgtable.h   2006-08-01 20:29:47.000000000 -0400
19428 @@ -34,7 +34,6 @@ struct vm_area_struct;
19429   */
19430  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
19431  extern unsigned long empty_zero_page[1024];
19432 -extern pgd_t swapper_pg_dir[1024];
19433  extern kmem_cache_t *pgd_cache;
19434  extern kmem_cache_t *pmd_cache;
19435  extern spinlock_t pgd_lock;
19436 @@ -59,6 +58,11 @@ void paging_init(void);
19437  # include <asm/pgtable-2level-defs.h>
19438  #endif
19439  
19440 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
19441 +#ifdef CONFIG_X86_PAE
19442 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
19443 +#endif
19444 +
19445  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
19446  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
19447  
19448 @@ -68,9 +72,11 @@ void paging_init(void);
19449  #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
19450  #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
19451  
19452 +#ifndef CONFIG_X86_PAE
19453  #define TWOLEVEL_PGDIR_SHIFT   22
19454  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
19455  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
19456 +#endif
19457  
19458  /* Just any arbitrary offset to the start of the vmalloc VM area: the
19459   * current 8MB value just means that there will be a 8MB "hole" after the
19460 @@ -141,17 +147,26 @@ void paging_init(void);
19461  
19462  #define PAGE_SHARED_EXEC \
19463         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
19464 -#define PAGE_COPY_NOEXEC \
19465 -       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19466  #define PAGE_COPY_EXEC \
19467         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
19468 -#define PAGE_COPY \
19469 -       PAGE_COPY_NOEXEC
19470  #define PAGE_READONLY \
19471         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19472  #define PAGE_READONLY_EXEC \
19473         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
19474  
19475 +#ifdef CONFIG_PAX_PAGEEXEC
19476 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
19477 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
19478 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
19479 +#else
19480 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
19481 +# define PAGE_COPY_NOEXEC \
19482 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
19483 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
19484 +#endif
19485 +
19486 +#define PAGE_COPY \
19487 +       PAGE_COPY_NOEXEC
19488  #define _PAGE_KERNEL \
19489         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
19490  #define _PAGE_KERNEL_EXEC \
19491 @@ -176,18 +191,18 @@ extern unsigned long long __PAGE_KERNEL,
19492   * This is the closest we can get..
19493   */
19494  #define __P000 PAGE_NONE
19495 -#define __P001 PAGE_READONLY
19496 -#define __P010 PAGE_COPY
19497 -#define __P011 PAGE_COPY
19498 +#define __P001 PAGE_READONLY_NOEXEC
19499 +#define __P010 PAGE_COPY_NOEXEC
19500 +#define __P011 PAGE_COPY_NOEXEC
19501  #define __P100 PAGE_READONLY_EXEC
19502  #define __P101 PAGE_READONLY_EXEC
19503  #define __P110 PAGE_COPY_EXEC
19504  #define __P111 PAGE_COPY_EXEC
19505  
19506  #define __S000 PAGE_NONE
19507 -#define __S001 PAGE_READONLY
19508 -#define __S010 PAGE_SHARED
19509 -#define __S011 PAGE_SHARED
19510 +#define __S001 PAGE_READONLY_NOEXEC
19511 +#define __S010 PAGE_SHARED_NOEXEC
19512 +#define __S011 PAGE_SHARED_NOEXEC
19513  #define __S100 PAGE_READONLY_EXEC
19514  #define __S101 PAGE_READONLY_EXEC
19515  #define __S110 PAGE_SHARED_EXEC
19516 @@ -431,6 +446,9 @@ extern void noexec_setup(const char *str
19517  
19518  #endif /* !__ASSEMBLY__ */
19519  
19520 +#define HAVE_ARCH_UNMAPPED_AREA
19521 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
19522 +
19523  #ifdef CONFIG_FLATMEM
19524  #define kern_addr_valid(addr)  (1)
19525  #endif /* CONFIG_FLATMEM */
19526 diff -urNp linux-2.6.17.7/include/asm-i386/processor.h linux-2.6.17.7/include/asm-i386/processor.h
19527 --- linux-2.6.17.7/include/asm-i386/processor.h 2006-07-24 23:36:01.000000000 -0400
19528 +++ linux-2.6.17.7/include/asm-i386/processor.h 2006-08-01 20:29:47.000000000 -0400
19529 @@ -19,7 +19,6 @@
19530  #include <linux/cache.h>
19531  #include <linux/config.h>
19532  #include <linux/threads.h>
19533 -#include <asm/percpu.h>
19534  #include <linux/cpumask.h>
19535  
19536  /* flag for disabling the tsc */
19537 @@ -94,8 +93,6 @@ struct cpuinfo_x86 {
19538  
19539  extern struct cpuinfo_x86 boot_cpu_data;
19540  extern struct cpuinfo_x86 new_cpu_data;
19541 -extern struct tss_struct doublefault_tss;
19542 -DECLARE_PER_CPU(struct tss_struct, init_tss);
19543  
19544  #ifdef CONFIG_SMP
19545  extern struct cpuinfo_x86 cpu_data[];
19546 @@ -325,10 +322,19 @@ extern int bootloader_type;
19547   */
19548  #define TASK_SIZE      (PAGE_OFFSET)
19549  
19550 +#ifdef CONFIG_PAX_SEGMEXEC
19551 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
19552 +#endif
19553 +
19554  /* This decides where the kernel will search for a free chunk of vm
19555   * space during mmap's.
19556   */
19557 +
19558 +#ifdef CONFIG_PAX_SEGMEXEC
19559 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
19560 +#else
19561  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
19562 +#endif
19563  
19564  #define HAVE_ARCH_PICK_MMAP_LAYOUT
19565  
19566 @@ -444,6 +450,9 @@ struct tss_struct {
19567  
19568  #define ARCH_MIN_TASKALIGN     16
19569  
19570 +extern struct tss_struct doublefault_tss;
19571 +extern struct tss_struct init_tss[NR_CPUS];
19572 +
19573  struct thread_struct {
19574  /* cached TLS descriptors. */
19575         struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
19576 @@ -472,6 +481,7 @@ struct thread_struct {
19577  };
19578  
19579  #define INIT_THREAD  {                                                 \
19580 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
19581         .vm86_info = NULL,                                              \
19582         .sysenter_cs = __KERNEL_CS,                                     \
19583         .io_bitmap_ptr = NULL,                                          \
19584 @@ -484,7 +494,7 @@ struct thread_struct {
19585   * be within the limit.
19586   */
19587  #define INIT_TSS  {                                                    \
19588 -       .esp0           = sizeof(init_stack) + (long)&init_stack,       \
19589 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
19590         .ss0            = __KERNEL_DS,                                  \
19591         .ss1            = __KERNEL_CS,                                  \
19592         .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,                     \
19593 @@ -560,11 +570,7 @@ void show_trace(struct task_struct *task
19594  unsigned long get_wchan(struct task_struct *p);
19595  
19596  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
19597 -#define KSTK_TOP(info)                                                 \
19598 -({                                                                     \
19599 -       unsigned long *__ptr = (unsigned long *)(info);                 \
19600 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
19601 -})
19602 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
19603  
19604  /*
19605   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
19606 @@ -579,7 +585,7 @@ unsigned long get_wchan(struct task_stru
19607  #define task_pt_regs(task)                                             \
19608  ({                                                                     \
19609         struct pt_regs *__regs__;                                       \
19610 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
19611 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
19612         __regs__ - 1;                                                   \
19613  })
19614  
19615 diff -urNp linux-2.6.17.7/include/asm-i386/ptrace.h linux-2.6.17.7/include/asm-i386/ptrace.h
19616 --- linux-2.6.17.7/include/asm-i386/ptrace.h    2006-07-24 23:36:01.000000000 -0400
19617 +++ linux-2.6.17.7/include/asm-i386/ptrace.h    2006-08-01 20:29:47.000000000 -0400
19618 @@ -65,17 +65,18 @@ struct task_struct;
19619  extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
19620  
19621  /*
19622 - * user_mode_vm(regs) determines whether a register set came from user mode.
19623 + * user_mode(regs) determines whether a register set came from user mode.
19624   * This is true if V8086 mode was enabled OR if the register set was from
19625   * protected mode with RPL-3 CS value.  This tricky test checks that with
19626   * one comparison.  Many places in the kernel can bypass this full check
19627 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
19628 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
19629 + * be used.
19630   */
19631 -static inline int user_mode(struct pt_regs *regs)
19632 +static inline int user_mode_novm(struct pt_regs *regs)
19633  {
19634         return (regs->xcs & 3) != 0;
19635  }
19636 -static inline int user_mode_vm(struct pt_regs *regs)
19637 +static inline int user_mode(struct pt_regs *regs)
19638  {
19639         return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
19640  }
19641 diff -urNp linux-2.6.17.7/include/asm-i386/system.h linux-2.6.17.7/include/asm-i386/system.h
19642 --- linux-2.6.17.7/include/asm-i386/system.h    2006-07-24 23:36:01.000000000 -0400
19643 +++ linux-2.6.17.7/include/asm-i386/system.h    2006-08-01 20:29:47.000000000 -0400
19644 @@ -5,6 +5,7 @@
19645  #include <linux/kernel.h>
19646  #include <asm/segment.h>
19647  #include <asm/cpufeature.h>
19648 +#include <asm/page.h>
19649  #include <linux/bitops.h> /* for LOCK_PREFIX */
19650  
19651  #ifdef __KERNEL__
19652 @@ -151,7 +152,7 @@ static inline unsigned long get_limit(un
19653         unsigned long __limit;
19654         __asm__("lsll %1,%0"
19655                 :"=r" (__limit):"r" (segment));
19656 -       return __limit+1;
19657 +       return __limit;
19658  }
19659  
19660  #define nop() __asm__ __volatile__ ("nop")
19661 @@ -496,7 +497,7 @@ static inline void sched_cacheflush(void
19662         wbinvd();
19663  }
19664  
19665 -extern unsigned long arch_align_stack(unsigned long sp);
19666 +#define arch_align_stack(x) (x)
19667  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
19668  
19669  void default_idle(void);
19670 diff -urNp linux-2.6.17.7/include/asm-i386/uaccess.h linux-2.6.17.7/include/asm-i386/uaccess.h
19671 --- linux-2.6.17.7/include/asm-i386/uaccess.h   2006-07-24 23:36:01.000000000 -0400
19672 +++ linux-2.6.17.7/include/asm-i386/uaccess.h   2006-08-01 20:29:47.000000000 -0400
19673 @@ -10,6 +10,8 @@
19674  #include <linux/prefetch.h>
19675  #include <linux/string.h>
19676  #include <asm/page.h>
19677 +#include <asm/segment.h>
19678 +#include <asm/desc.h>
19679  
19680  #define VERIFY_READ 0
19681  #define VERIFY_WRITE 1
19682 @@ -30,7 +32,8 @@
19683  
19684  #define get_ds()       (KERNEL_DS)
19685  #define get_fs()       (current_thread_info()->addr_limit)
19686 -#define set_fs(x)      (current_thread_info()->addr_limit = (x))
19687 +void __set_fs(mm_segment_t x, int cpu);
19688 +void set_fs(mm_segment_t x);
19689  
19690  #define segment_eq(a,b)        ((a).seg == (b).seg)
19691  
19692 @@ -281,9 +284,12 @@ extern void __put_user_8(void);
19693  
19694  #define __put_user_u64(x, addr, err)                           \
19695         __asm__ __volatile__(                                   \
19696 -               "1:     movl %%eax,0(%2)\n"                     \
19697 -               "2:     movl %%edx,4(%2)\n"                     \
19698 +               "       movw %w5,%%ds\n"                        \
19699 +               "1:     movl %%eax,%%ds:0(%2)\n"                \
19700 +               "2:     movl %%edx,%%ds:4(%2)\n"                \
19701                 "3:\n"                                          \
19702 +               "       pushl %%ss\n"                           \
19703 +               "       popl %%ds\n"                            \
19704                 ".section .fixup,\"ax\"\n"                      \
19705                 "4:     movl %3,%0\n"                           \
19706                 "       jmp 3b\n"                               \
19707 @@ -294,7 +300,8 @@ extern void __put_user_8(void);
19708                 "       .long 2b,4b\n"                          \
19709                 ".previous"                                     \
19710                 : "=r"(err)                                     \
19711 -               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
19712 +               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err),  \
19713 +                 "r"(__USER_DS))
19714  
19715  #ifdef CONFIG_X86_WP_WORKS_OK
19716  
19717 @@ -333,8 +340,11 @@ struct __large_struct { unsigned long bu
19718   */
19719  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
19720         __asm__ __volatile__(                                           \
19721 -               "1:     mov"itype" %"rtype"1,%2\n"                      \
19722 +               "       movw %w5,%%ds\n"                                \
19723 +               "1:     mov"itype" %"rtype"1,%%ds:%2\n"                 \
19724                 "2:\n"                                                  \
19725 +               "       pushl %%ss\n"                                   \
19726 +               "       popl %%ds\n"                                    \
19727                 ".section .fixup,\"ax\"\n"                              \
19728                 "3:     movl %3,%0\n"                                   \
19729                 "       jmp 2b\n"                                       \
19730 @@ -344,7 +354,8 @@ struct __large_struct { unsigned long bu
19731                 "       .long 1b,3b\n"                                  \
19732                 ".previous"                                             \
19733                 : "=r"(err)                                             \
19734 -               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
19735 +               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err),     \
19736 +                 "r"(__USER_DS))
19737  
19738  
19739  #define __get_user_nocheck(x,ptr,size)                         \
19740 @@ -372,8 +383,11 @@ do {                                                                       \
19741  
19742  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
19743         __asm__ __volatile__(                                           \
19744 -               "1:     mov"itype" %2,%"rtype"1\n"                      \
19745 +               "       movw %w5,%%ds\n"                                \
19746 +               "1:     mov"itype" %%ds:%2,%"rtype"1\n"                 \
19747                 "2:\n"                                                  \
19748 +               "       pushl %%ss\n"                                   \
19749 +               "       popl %%ds\n"                                    \
19750                 ".section .fixup,\"ax\"\n"                              \
19751                 "3:     movl %3,%0\n"                                   \
19752                 "       xor"itype" %"rtype"1,%"rtype"1\n"               \
19753 @@ -384,7 +398,7 @@ do {                                                                        \
19754                 "       .long 1b,3b\n"                                  \
19755                 ".previous"                                             \
19756                 : "=r"(err), ltype (x)                                  \
19757 -               : "m"(__m(addr)), "i"(errret), "0"(err))
19758 +               : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
19759  
19760  
19761  unsigned long __must_check __copy_to_user_ll(void __user *to,
19762 diff -urNp linux-2.6.17.7/include/asm-ia64/elf.h linux-2.6.17.7/include/asm-ia64/elf.h
19763 --- linux-2.6.17.7/include/asm-ia64/elf.h       2006-07-24 23:36:01.000000000 -0400
19764 +++ linux-2.6.17.7/include/asm-ia64/elf.h       2006-08-01 20:29:47.000000000 -0400
19765 @@ -163,6 +163,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
19766  typedef struct ia64_fpreg elf_fpreg_t;
19767  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
19768  
19769 +#ifdef CONFIG_PAX_ASLR
19770 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
19771 +
19772 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
19773 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19774 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
19775 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19776 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
19777 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
19778 +#endif
19779  
19780  
19781  struct pt_regs;        /* forward declaration... */
19782 diff -urNp linux-2.6.17.7/include/asm-ia64/kmap_types.h linux-2.6.17.7/include/asm-ia64/kmap_types.h
19783 --- linux-2.6.17.7/include/asm-ia64/kmap_types.h        2006-07-24 23:36:01.000000000 -0400
19784 +++ linux-2.6.17.7/include/asm-ia64/kmap_types.h        2006-08-01 20:29:47.000000000 -0400
19785 @@ -23,7 +23,8 @@ D(9)  KM_IRQ0,
19786  D(10)  KM_IRQ1,
19787  D(11)  KM_SOFTIRQ0,
19788  D(12)  KM_SOFTIRQ1,
19789 -D(13)  KM_TYPE_NR
19790 +D(13)  KM_CLEARPAGE,
19791 +D(14)  KM_TYPE_NR
19792  };
19793  
19794  #undef D
19795 diff -urNp linux-2.6.17.7/include/asm-ia64/page.h linux-2.6.17.7/include/asm-ia64/page.h
19796 --- linux-2.6.17.7/include/asm-ia64/page.h      2006-07-24 23:36:01.000000000 -0400
19797 +++ linux-2.6.17.7/include/asm-ia64/page.h      2006-08-01 20:29:47.000000000 -0400
19798 @@ -229,4 +229,13 @@ get_order (unsigned long size)
19799                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
19800                                           ? VM_EXEC : 0))
19801  
19802 +#ifdef CONFIG_PAX_PAGEEXEC
19803 +#ifdef CONFIG_PAX_MPROTECT
19804 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
19805 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
19806 +#else
19807 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
19808 +#endif
19809 +#endif
19810 +
19811  #endif /* _ASM_IA64_PAGE_H */
19812 diff -urNp linux-2.6.17.7/include/asm-ia64/pgtable.h linux-2.6.17.7/include/asm-ia64/pgtable.h
19813 --- linux-2.6.17.7/include/asm-ia64/pgtable.h   2006-07-24 23:36:01.000000000 -0400
19814 +++ linux-2.6.17.7/include/asm-ia64/pgtable.h   2006-08-01 20:29:47.000000000 -0400
19815 @@ -144,6 +144,17 @@
19816  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
19817  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
19818  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
19819 +
19820 +#ifdef CONFIG_PAX_PAGEEXEC
19821 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
19822 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
19823 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
19824 +#else
19825 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
19826 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
19827 +# define PAGE_COPY_NOEXEC      PAGE_COPY
19828 +#endif
19829 +
19830  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
19831  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
19832  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
19833 diff -urNp linux-2.6.17.7/include/asm-ia64/processor.h linux-2.6.17.7/include/asm-ia64/processor.h
19834 --- linux-2.6.17.7/include/asm-ia64/processor.h 2006-07-24 23:36:01.000000000 -0400
19835 +++ linux-2.6.17.7/include/asm-ia64/processor.h 2006-08-01 20:29:47.000000000 -0400
19836 @@ -284,7 +284,7 @@ struct thread_struct {
19837         .on_ustack =    0,                                      \
19838         .ksp =          0,                                      \
19839         .map_base =     DEFAULT_MAP_BASE,                       \
19840 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
19841 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
19842         .task_size =    DEFAULT_TASK_SIZE,                      \
19843         .last_fph_cpu =  -1,                                    \
19844         INIT_THREAD_IA32                                        \
19845 diff -urNp linux-2.6.17.7/include/asm-ia64/ustack.h linux-2.6.17.7/include/asm-ia64/ustack.h
19846 --- linux-2.6.17.7/include/asm-ia64/ustack.h    2006-07-24 23:36:01.000000000 -0400
19847 +++ linux-2.6.17.7/include/asm-ia64/ustack.h    2006-08-01 20:29:47.000000000 -0400
19848 @@ -11,6 +11,6 @@
19849  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
19850  /* Make a default stack size of 2GB */
19851  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
19852 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
19853 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
19854  
19855  #endif /* _ASM_IA64_USTACK_H */
19856 diff -urNp linux-2.6.17.7/include/asm-m32r/kmap_types.h linux-2.6.17.7/include/asm-m32r/kmap_types.h
19857 --- linux-2.6.17.7/include/asm-m32r/kmap_types.h        2006-07-24 23:36:01.000000000 -0400
19858 +++ linux-2.6.17.7/include/asm-m32r/kmap_types.h        2006-08-01 20:29:47.000000000 -0400
19859 @@ -25,7 +25,8 @@ D(9)  KM_IRQ0,
19860  D(10)  KM_IRQ1,
19861  D(11)  KM_SOFTIRQ0,
19862  D(12)  KM_SOFTIRQ1,
19863 -D(13)  KM_TYPE_NR
19864 +D(13)  KM_CLEARPAGE,
19865 +D(14)  KM_TYPE_NR
19866  };
19867  
19868  #undef D
19869 diff -urNp linux-2.6.17.7/include/asm-m68k/kmap_types.h linux-2.6.17.7/include/asm-m68k/kmap_types.h
19870 --- linux-2.6.17.7/include/asm-m68k/kmap_types.h        2006-07-24 23:36:01.000000000 -0400
19871 +++ linux-2.6.17.7/include/asm-m68k/kmap_types.h        2006-08-01 20:29:47.000000000 -0400
19872 @@ -15,6 +15,7 @@ enum km_type {
19873         KM_IRQ1,
19874         KM_SOFTIRQ0,
19875         KM_SOFTIRQ1,
19876 +       KM_CLEARPAGE,
19877         KM_TYPE_NR
19878  };
19879  
19880 diff -urNp linux-2.6.17.7/include/asm-m68knommu/kmap_types.h linux-2.6.17.7/include/asm-m68knommu/kmap_types.h
19881 --- linux-2.6.17.7/include/asm-m68knommu/kmap_types.h   2006-07-24 23:36:01.000000000 -0400
19882 +++ linux-2.6.17.7/include/asm-m68knommu/kmap_types.h   2006-08-01 20:29:47.000000000 -0400
19883 @@ -15,6 +15,7 @@ enum km_type {
19884         KM_IRQ1,
19885         KM_SOFTIRQ0,
19886         KM_SOFTIRQ1,
19887 +       KM_CLEARPAGE,
19888         KM_TYPE_NR
19889  };
19890  
19891 diff -urNp linux-2.6.17.7/include/asm-mips/a.out.h linux-2.6.17.7/include/asm-mips/a.out.h
19892 --- linux-2.6.17.7/include/asm-mips/a.out.h     2006-07-24 23:36:01.000000000 -0400
19893 +++ linux-2.6.17.7/include/asm-mips/a.out.h     2006-08-01 20:29:47.000000000 -0400
19894 @@ -36,10 +36,10 @@ struct exec
19895  #ifdef __KERNEL__
19896  
19897  #ifdef CONFIG_32BIT
19898 -#define STACK_TOP      TASK_SIZE
19899 +#define __STACK_TOP    TASK_SIZE
19900  #endif
19901  #ifdef CONFIG_64BIT
19902 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
19903 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
19904  #endif
19905  
19906  #endif
19907 diff -urNp linux-2.6.17.7/include/asm-mips/elf.h linux-2.6.17.7/include/asm-mips/elf.h
19908 --- linux-2.6.17.7/include/asm-mips/elf.h       2006-07-24 23:36:01.000000000 -0400
19909 +++ linux-2.6.17.7/include/asm-mips/elf.h       2006-08-01 20:29:47.000000000 -0400
19910 @@ -372,4 +372,15 @@ extern int dump_task_fpu(struct task_str
19911  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
19912  #endif
19913  
19914 +#ifdef CONFIG_PAX_ASLR
19915 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
19916 +
19917 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
19918 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
19919 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
19920 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
19921 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
19922 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
19923 +#endif
19924 +
19925  #endif /* _ASM_ELF_H */
19926 diff -urNp linux-2.6.17.7/include/asm-mips/kmap_types.h linux-2.6.17.7/include/asm-mips/kmap_types.h
19927 --- linux-2.6.17.7/include/asm-mips/kmap_types.h        2006-07-24 23:36:01.000000000 -0400
19928 +++ linux-2.6.17.7/include/asm-mips/kmap_types.h        2006-08-01 20:29:47.000000000 -0400
19929 @@ -23,7 +23,8 @@ D(9)  KM_IRQ0,
19930  D(10)  KM_IRQ1,
19931  D(11)  KM_SOFTIRQ0,
19932  D(12)  KM_SOFTIRQ1,
19933 -D(13)  KM_TYPE_NR
19934 +D(13)  KM_CLEARPAGE,
19935 +D(14)  KM_TYPE_NR
19936  };
19937  
19938  #undef D
19939 diff -urNp linux-2.6.17.7/include/asm-mips/page.h linux-2.6.17.7/include/asm-mips/page.h
19940 --- linux-2.6.17.7/include/asm-mips/page.h      2006-07-24 23:36:01.000000000 -0400
19941 +++ linux-2.6.17.7/include/asm-mips/page.h      2006-08-01 20:29:47.000000000 -0400
19942 @@ -151,6 +151,15 @@ typedef struct { unsigned long pgprot; }
19943  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
19944                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
19945  
19946 +#ifdef CONFIG_PAX_PAGEEXEC
19947 +#ifdef CONFIG_PAX_MPROTECT
19948 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
19949 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
19950 +#else
19951 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
19952 +#endif
19953 +#endif
19954 +
19955  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
19956  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
19957  
19958 diff -urNp linux-2.6.17.7/include/asm-parisc/a.out.h linux-2.6.17.7/include/asm-parisc/a.out.h
19959 --- linux-2.6.17.7/include/asm-parisc/a.out.h   2006-07-24 23:36:01.000000000 -0400
19960 +++ linux-2.6.17.7/include/asm-parisc/a.out.h   2006-08-01 20:29:47.000000000 -0400
19961 @@ -22,7 +22,7 @@ struct exec
19962  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
19963   * prumpf */
19964  
19965 -#define STACK_TOP      TASK_SIZE
19966 +#define __STACK_TOP    TASK_SIZE
19967  
19968  #endif
19969  
19970 diff -urNp linux-2.6.17.7/include/asm-parisc/elf.h linux-2.6.17.7/include/asm-parisc/elf.h
19971 --- linux-2.6.17.7/include/asm-parisc/elf.h     2006-07-24 23:36:01.000000000 -0400
19972 +++ linux-2.6.17.7/include/asm-parisc/elf.h     2006-08-01 20:29:47.000000000 -0400
19973 @@ -337,6 +337,17 @@ struct pt_regs;    /* forward declaration..
19974  
19975  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
19976  
19977 +#ifdef CONFIG_PAX_ASLR
19978 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
19979 +
19980 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
19981 +#define PAX_DELTA_MMAP_LEN(tsk)                16
19982 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
19983 +#define PAX_DELTA_EXEC_LEN(tsk)                16
19984 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
19985 +#define PAX_DELTA_STACK_LEN(tsk)       16
19986 +#endif
19987 +
19988  /* This yields a mask that user programs can use to figure out what
19989     instruction set this CPU supports.  This could be done in user space,
19990     but it's not easy, and we've already done it here.  */
19991 diff -urNp linux-2.6.17.7/include/asm-parisc/kmap_types.h linux-2.6.17.7/include/asm-parisc/kmap_types.h
19992 --- linux-2.6.17.7/include/asm-parisc/kmap_types.h      2006-07-24 23:36:01.000000000 -0400
19993 +++ linux-2.6.17.7/include/asm-parisc/kmap_types.h      2006-08-01 20:29:47.000000000 -0400
19994 @@ -23,7 +23,8 @@ D(9)  KM_IRQ0,
19995  D(10)  KM_IRQ1,
19996  D(11)  KM_SOFTIRQ0,
19997  D(12)  KM_SOFTIRQ1,
19998 -D(13)  KM_TYPE_NR
19999 +D(13)  KM_CLEARPAGE,
20000 +D(14)  KM_TYPE_NR
20001  };
20002  
20003  #undef D
20004 diff -urNp linux-2.6.17.7/include/asm-parisc/page.h linux-2.6.17.7/include/asm-parisc/page.h
20005 --- linux-2.6.17.7/include/asm-parisc/page.h    2006-07-24 23:36:01.000000000 -0400
20006 +++ linux-2.6.17.7/include/asm-parisc/page.h    2006-08-01 20:29:47.000000000 -0400
20007 @@ -189,6 +189,15 @@ extern int npmem_ranges;
20008  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
20009                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20010  
20011 +#ifdef CONFIG_PAX_PAGEEXEC
20012 +#ifdef CONFIG_PAX_MPROTECT
20013 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20014 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20015 +#else
20016 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20017 +#endif
20018 +#endif
20019 +
20020  #endif /* __KERNEL__ */
20021  
20022  #include <asm-generic/memory_model.h>
20023 diff -urNp linux-2.6.17.7/include/asm-parisc/pgtable.h linux-2.6.17.7/include/asm-parisc/pgtable.h
20024 --- linux-2.6.17.7/include/asm-parisc/pgtable.h 2006-07-24 23:36:01.000000000 -0400
20025 +++ linux-2.6.17.7/include/asm-parisc/pgtable.h 2006-08-01 20:29:47.000000000 -0400
20026 @@ -220,6 +220,17 @@ extern  void *vmalloc_start;
20027  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
20028  #define PAGE_COPY       PAGE_EXECREAD
20029  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
20030 +
20031 +#ifdef CONFIG_PAX_PAGEEXEC
20032 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
20033 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
20034 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
20035 +#else
20036 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20037 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20038 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20039 +#endif
20040 +
20041  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
20042  #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
20043  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
20044 diff -urNp linux-2.6.17.7/include/asm-powerpc/a.out.h linux-2.6.17.7/include/asm-powerpc/a.out.h
20045 --- linux-2.6.17.7/include/asm-powerpc/a.out.h  2006-07-24 23:36:01.000000000 -0400
20046 +++ linux-2.6.17.7/include/asm-powerpc/a.out.h  2006-08-01 20:29:47.000000000 -0400
20047 @@ -23,12 +23,12 @@ struct exec
20048  #define STACK_TOP_USER64 TASK_SIZE_USER64
20049  #define STACK_TOP_USER32 TASK_SIZE_USER32
20050  
20051 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20052 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20053                    STACK_TOP_USER32 : STACK_TOP_USER64)
20054  
20055  #else /* __powerpc64__ */
20056  
20057 -#define STACK_TOP TASK_SIZE
20058 +#define __STACK_TOP TASK_SIZE
20059  
20060  #endif /* __powerpc64__ */
20061  #endif /* __KERNEL__ */
20062 diff -urNp linux-2.6.17.7/include/asm-powerpc/elf.h linux-2.6.17.7/include/asm-powerpc/elf.h
20063 --- linux-2.6.17.7/include/asm-powerpc/elf.h    2006-07-24 23:36:01.000000000 -0400
20064 +++ linux-2.6.17.7/include/asm-powerpc/elf.h    2006-08-01 20:29:47.000000000 -0400
20065 @@ -176,6 +176,26 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF
20066  
20067  #define ELF_ET_DYN_BASE         (0x08000000)
20068  
20069 +#ifdef CONFIG_PAX_ASLR
20070 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
20071 +
20072 +#ifdef __powerpc64__
20073 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20074 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
20075 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20076 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
20077 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20078 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 16 : 28)
20079 +#else
20080 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20081 +#define PAX_DELTA_MMAP_LEN(tsk)                15
20082 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20083 +#define PAX_DELTA_EXEC_LEN(tsk)                15
20084 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20085 +#define PAX_DELTA_STACK_LEN(tsk)       15
20086 +#endif
20087 +#endif
20088 +
20089  #ifdef __KERNEL__
20090  
20091  /* Common routine for both 32-bit and 64-bit processes */
20092 diff -urNp linux-2.6.17.7/include/asm-powerpc/kmap_types.h linux-2.6.17.7/include/asm-powerpc/kmap_types.h
20093 --- linux-2.6.17.7/include/asm-powerpc/kmap_types.h     2006-07-24 23:36:01.000000000 -0400
20094 +++ linux-2.6.17.7/include/asm-powerpc/kmap_types.h     2006-08-01 20:29:47.000000000 -0400
20095 @@ -26,6 +26,7 @@ enum km_type {
20096         KM_SOFTIRQ1,
20097         KM_PPC_SYNC_PAGE,
20098         KM_PPC_SYNC_ICACHE,
20099 +       KM_CLEARPAGE,
20100         KM_TYPE_NR
20101  };
20102  
20103 diff -urNp linux-2.6.17.7/include/asm-powerpc/page_64.h linux-2.6.17.7/include/asm-powerpc/page_64.h
20104 --- linux-2.6.17.7/include/asm-powerpc/page_64.h        2006-07-24 23:36:01.000000000 -0400
20105 +++ linux-2.6.17.7/include/asm-powerpc/page_64.h        2006-08-01 20:29:47.000000000 -0400
20106 @@ -170,6 +170,15 @@ extern unsigned int HPAGE_SHIFT;
20107         (test_thread_flag(TIF_32BIT) ? \
20108          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
20109  
20110 +#ifdef CONFIG_PAX_PAGEEXEC
20111 +#ifdef CONFIG_PAX_MPROTECT
20112 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20113 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20114 +#else
20115 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20116 +#endif
20117 +#endif
20118 +
20119  #include <asm-generic/page.h>
20120  
20121  #endif /* __KERNEL__ */
20122 diff -urNp linux-2.6.17.7/include/asm-ppc/page.h linux-2.6.17.7/include/asm-ppc/page.h
20123 --- linux-2.6.17.7/include/asm-ppc/page.h       2006-07-24 23:36:01.000000000 -0400
20124 +++ linux-2.6.17.7/include/asm-ppc/page.h       2006-08-01 20:29:47.000000000 -0400
20125 @@ -175,6 +175,15 @@ extern __inline__ int get_order(unsigned
20126  /* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
20127  #define __HAVE_ARCH_GATE_AREA          1
20128  
20129 +#ifdef CONFIG_PAX_PAGEEXEC
20130 +#ifdef CONFIG_PAX_MPROTECT
20131 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20132 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20133 +#else
20134 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20135 +#endif
20136 +#endif
20137 +
20138  #include <asm-generic/memory_model.h>
20139  #endif /* __KERNEL__ */
20140  #endif /* _PPC_PAGE_H */
20141 diff -urNp linux-2.6.17.7/include/asm-ppc/pgtable.h linux-2.6.17.7/include/asm-ppc/pgtable.h
20142 --- linux-2.6.17.7/include/asm-ppc/pgtable.h    2006-07-24 23:36:01.000000000 -0400
20143 +++ linux-2.6.17.7/include/asm-ppc/pgtable.h    2006-08-01 20:29:47.000000000 -0400
20144 @@ -441,11 +441,21 @@ extern unsigned long ioremap_bot, iorema
20145  
20146  #define PAGE_NONE      __pgprot(_PAGE_BASE)
20147  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
20148 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
20149 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
20150  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
20151 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
20152 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
20153  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
20154 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
20155 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
20156 +
20157 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
20158 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
20159 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
20160 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
20161 +#else
20162 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20163 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20164 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20165 +#endif
20166  
20167  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
20168  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
20169 @@ -457,21 +467,21 @@ extern unsigned long ioremap_bot, iorema
20170   * This is the closest we can get..
20171   */
20172  #define __P000 PAGE_NONE
20173 -#define __P001 PAGE_READONLY_X
20174 -#define __P010 PAGE_COPY
20175 -#define __P011 PAGE_COPY_X
20176 -#define __P100 PAGE_READONLY
20177 +#define __P001 PAGE_READONLY_NOEXEC
20178 +#define __P010 PAGE_COPY_NOEXEC
20179 +#define __P011 PAGE_COPY_NOEXEC
20180 +#define __P100 PAGE_READONLY_X
20181  #define __P101 PAGE_READONLY_X
20182 -#define __P110 PAGE_COPY
20183 +#define __P110 PAGE_COPY_X
20184  #define __P111 PAGE_COPY_X
20185  
20186  #define __S000 PAGE_NONE
20187 -#define __S001 PAGE_READONLY_X
20188 -#define __S010 PAGE_SHARED
20189 -#define __S011 PAGE_SHARED_X
20190 -#define __S100 PAGE_READONLY
20191 +#define __S001 PAGE_READONLY_NOEXEC
20192 +#define __S010 PAGE_SHARED_NOEXEC
20193 +#define __S011 PAGE_SHARED_NOEXEC
20194 +#define __S100 PAGE_READONLY_X
20195  #define __S101 PAGE_READONLY_X
20196 -#define __S110 PAGE_SHARED
20197 +#define __S110 PAGE_SHARED_X
20198  #define __S111 PAGE_SHARED_X
20199  
20200  #ifndef __ASSEMBLY__
20201 diff -urNp linux-2.6.17.7/include/asm-s390/kmap_types.h linux-2.6.17.7/include/asm-s390/kmap_types.h
20202 --- linux-2.6.17.7/include/asm-s390/kmap_types.h        2006-07-24 23:36:01.000000000 -0400
20203 +++ linux-2.6.17.7/include/asm-s390/kmap_types.h        2006-08-01 20:29:47.000000000 -0400
20204 @@ -16,6 +16,7 @@ enum km_type {
20205         KM_IRQ1,
20206         KM_SOFTIRQ0,
20207         KM_SOFTIRQ1,    
20208 +       KM_CLEARPAGE,
20209         KM_TYPE_NR
20210  };
20211  
20212 diff -urNp linux-2.6.17.7/include/asm-sh/kmap_types.h linux-2.6.17.7/include/asm-sh/kmap_types.h
20213 --- linux-2.6.17.7/include/asm-sh/kmap_types.h  2006-07-24 23:36:01.000000000 -0400
20214 +++ linux-2.6.17.7/include/asm-sh/kmap_types.h  2006-08-01 20:29:47.000000000 -0400
20215 @@ -25,7 +25,8 @@ D(9)  KM_IRQ0,
20216  D(10)  KM_IRQ1,
20217  D(11)  KM_SOFTIRQ0,
20218  D(12)  KM_SOFTIRQ1,
20219 -D(13)  KM_TYPE_NR
20220 +D(13)  KM_CLEARPAGE,
20221 +D(14)  KM_TYPE_NR
20222  };
20223  
20224  #undef D
20225 diff -urNp linux-2.6.17.7/include/asm-sparc/a.out.h linux-2.6.17.7/include/asm-sparc/a.out.h
20226 --- linux-2.6.17.7/include/asm-sparc/a.out.h    2006-07-24 23:36:01.000000000 -0400
20227 +++ linux-2.6.17.7/include/asm-sparc/a.out.h    2006-08-01 20:29:47.000000000 -0400
20228 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
20229  
20230  #include <asm/page.h>
20231  
20232 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
20233 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
20234  
20235  #endif /* __KERNEL__ */
20236  
20237 diff -urNp linux-2.6.17.7/include/asm-sparc/elf.h linux-2.6.17.7/include/asm-sparc/elf.h
20238 --- linux-2.6.17.7/include/asm-sparc/elf.h      2006-07-24 23:36:01.000000000 -0400
20239 +++ linux-2.6.17.7/include/asm-sparc/elf.h      2006-08-01 20:29:47.000000000 -0400
20240 @@ -145,6 +145,17 @@ typedef struct {
20241  
20242  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
20243  
20244 +#ifdef CONFIG_PAX_ASLR
20245 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
20246 +
20247 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20248 +#define PAX_DELTA_MMAP_LEN(tsk)                16
20249 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20250 +#define PAX_DELTA_EXEC_LEN(tsk)                16
20251 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20252 +#define PAX_DELTA_STACK_LEN(tsk)       16
20253 +#endif
20254 +
20255  /* This yields a mask that user programs can use to figure out what
20256     instruction set this cpu supports.  This can NOT be done in userspace
20257     on Sparc.  */
20258 diff -urNp linux-2.6.17.7/include/asm-sparc/kmap_types.h linux-2.6.17.7/include/asm-sparc/kmap_types.h
20259 --- linux-2.6.17.7/include/asm-sparc/kmap_types.h       2006-07-24 23:36:01.000000000 -0400
20260 +++ linux-2.6.17.7/include/asm-sparc/kmap_types.h       2006-08-01 20:29:47.000000000 -0400
20261 @@ -15,6 +15,7 @@ enum km_type {
20262         KM_IRQ1,
20263         KM_SOFTIRQ0,
20264         KM_SOFTIRQ1,
20265 +       KM_CLEARPAGE,
20266         KM_TYPE_NR
20267  };
20268  
20269 diff -urNp linux-2.6.17.7/include/asm-sparc/page.h linux-2.6.17.7/include/asm-sparc/page.h
20270 --- linux-2.6.17.7/include/asm-sparc/page.h     2006-07-24 23:36:01.000000000 -0400
20271 +++ linux-2.6.17.7/include/asm-sparc/page.h     2006-08-01 20:29:47.000000000 -0400
20272 @@ -161,6 +161,15 @@ extern unsigned long pfn_base;
20273  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
20274                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20275  
20276 +#ifdef CONFIG_PAX_PAGEEXEC
20277 +#ifdef CONFIG_PAX_MPROTECT
20278 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20279 +                        ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20280 +#else
20281 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20282 +#endif
20283 +#endif
20284 +
20285  #endif /* __KERNEL__ */
20286  
20287  #include <asm-generic/memory_model.h>
20288 diff -urNp linux-2.6.17.7/include/asm-sparc/pgtable.h linux-2.6.17.7/include/asm-sparc/pgtable.h
20289 --- linux-2.6.17.7/include/asm-sparc/pgtable.h  2006-07-24 23:36:01.000000000 -0400
20290 +++ linux-2.6.17.7/include/asm-sparc/pgtable.h  2006-08-01 20:29:47.000000000 -0400
20291 @@ -50,6 +50,13 @@ BTFIXUPDEF_INT(page_none)
20292  BTFIXUPDEF_INT(page_shared)
20293  BTFIXUPDEF_INT(page_copy)
20294  BTFIXUPDEF_INT(page_readonly)
20295 +
20296 +#ifdef CONFIG_PAX_PAGEEXEC
20297 +BTFIXUPDEF_INT(page_shared_noexec)
20298 +BTFIXUPDEF_INT(page_copy_noexec)
20299 +BTFIXUPDEF_INT(page_readonly_noexec)
20300 +#endif
20301 +
20302  BTFIXUPDEF_INT(page_kernel)
20303  
20304  #define PMD_SHIFT              SUN4C_PMD_SHIFT
20305 @@ -71,6 +78,16 @@ BTFIXUPDEF_INT(page_kernel)
20306  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
20307  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
20308  
20309 +#ifdef CONFIG_PAX_PAGEEXEC
20310 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
20311 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
20312 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
20313 +#else
20314 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
20315 +# define PAGE_COPY_NOEXEC      PAGE_COPY
20316 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
20317 +#endif
20318 +
20319  extern unsigned long page_kernel;
20320  
20321  #ifdef MODULE
20322 diff -urNp linux-2.6.17.7/include/asm-sparc/pgtsrmmu.h linux-2.6.17.7/include/asm-sparc/pgtsrmmu.h
20323 --- linux-2.6.17.7/include/asm-sparc/pgtsrmmu.h 2006-07-24 23:36:01.000000000 -0400
20324 +++ linux-2.6.17.7/include/asm-sparc/pgtsrmmu.h 2006-08-01 20:29:47.000000000 -0400
20325 @@ -115,6 +115,16 @@
20326                                     SRMMU_EXEC | SRMMU_REF)
20327  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20328                                     SRMMU_EXEC | SRMMU_REF)
20329 +
20330 +#ifdef CONFIG_PAX_PAGEEXEC
20331 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20332 +                                          SRMMU_WRITE | SRMMU_REF)
20333 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20334 +                                          SRMMU_REF)
20335 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
20336 +                                          SRMMU_REF)
20337 +#endif
20338 +
20339  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
20340                                     SRMMU_DIRTY | SRMMU_REF)
20341  
20342 diff -urNp linux-2.6.17.7/include/asm-sparc/uaccess.h linux-2.6.17.7/include/asm-sparc/uaccess.h
20343 --- linux-2.6.17.7/include/asm-sparc/uaccess.h  2006-07-24 23:36:01.000000000 -0400
20344 +++ linux-2.6.17.7/include/asm-sparc/uaccess.h  2006-08-01 20:29:47.000000000 -0400
20345 @@ -41,7 +41,7 @@
20346   * No one can read/write anything from userland in the kernel space by setting
20347   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
20348   */
20349 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
20350 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
20351  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
20352  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
20353  #define access_ok(type, addr, size)                                    \
20354 diff -urNp linux-2.6.17.7/include/asm-sparc64/a.out.h linux-2.6.17.7/include/asm-sparc64/a.out.h
20355 --- linux-2.6.17.7/include/asm-sparc64/a.out.h  2006-07-24 23:36:01.000000000 -0400
20356 +++ linux-2.6.17.7/include/asm-sparc64/a.out.h  2006-08-01 20:29:47.000000000 -0400
20357 @@ -98,7 +98,7 @@ struct relocation_info /* used when head
20358  #define STACK_TOP32    ((1UL << 32UL) - PAGE_SIZE)
20359  #define STACK_TOP64    (0x0000080000000000UL - (1UL << 32UL))
20360  
20361 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20362 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
20363                    STACK_TOP32 : STACK_TOP64)
20364  
20365  #endif
20366 diff -urNp linux-2.6.17.7/include/asm-sparc64/elf.h linux-2.6.17.7/include/asm-sparc64/elf.h
20367 --- linux-2.6.17.7/include/asm-sparc64/elf.h    2006-07-24 23:36:01.000000000 -0400
20368 +++ linux-2.6.17.7/include/asm-sparc64/elf.h    2006-08-01 20:29:47.000000000 -0400
20369 @@ -142,6 +142,16 @@ typedef struct {
20370  #define ELF_ET_DYN_BASE         0x0000010000000000UL
20371  #endif
20372  
20373 +#ifdef CONFIG_PAX_ASLR
20374 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
20375 +
20376 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
20377 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
20378 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
20379 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
20380 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20381 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
20382 +#endif
20383  
20384  /* This yields a mask that user programs can use to figure out what
20385     instruction set this cpu supports.  */
20386 diff -urNp linux-2.6.17.7/include/asm-sparc64/kmap_types.h linux-2.6.17.7/include/asm-sparc64/kmap_types.h
20387 --- linux-2.6.17.7/include/asm-sparc64/kmap_types.h     2006-07-24 23:36:01.000000000 -0400
20388 +++ linux-2.6.17.7/include/asm-sparc64/kmap_types.h     2006-08-01 20:29:47.000000000 -0400
20389 @@ -19,6 +19,7 @@ enum km_type {
20390         KM_IRQ1,
20391         KM_SOFTIRQ0,
20392         KM_SOFTIRQ1,
20393 +       KM_CLEARPAGE,
20394         KM_TYPE_NR
20395  };
20396  
20397 diff -urNp linux-2.6.17.7/include/asm-sparc64/page.h linux-2.6.17.7/include/asm-sparc64/page.h
20398 --- linux-2.6.17.7/include/asm-sparc64/page.h   2006-07-24 23:36:01.000000000 -0400
20399 +++ linux-2.6.17.7/include/asm-sparc64/page.h   2006-08-01 20:29:47.000000000 -0400
20400 @@ -142,6 +142,15 @@ typedef unsigned long pgprot_t;
20401  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
20402                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20403  
20404 +#ifdef CONFIG_PAX_PAGEEXEC
20405 +#ifdef CONFIG_PAX_MPROTECT
20406 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20407 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20408 +#else
20409 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20410 +#endif
20411 +#endif
20412 +
20413  #endif /* !(__KERNEL__) */
20414  
20415  #include <asm-generic/page.h>
20416 diff -urNp linux-2.6.17.7/include/asm-v850/kmap_types.h linux-2.6.17.7/include/asm-v850/kmap_types.h
20417 --- linux-2.6.17.7/include/asm-v850/kmap_types.h        2006-07-24 23:36:01.000000000 -0400
20418 +++ linux-2.6.17.7/include/asm-v850/kmap_types.h        2006-08-01 20:29:48.000000000 -0400
20419 @@ -13,6 +13,7 @@ enum km_type {
20420         KM_PTE1,
20421         KM_IRQ0,
20422         KM_IRQ1,
20423 +       KM_CLEARPAGE,
20424         KM_TYPE_NR
20425  };
20426  
20427 diff -urNp linux-2.6.17.7/include/asm-x86_64/a.out.h linux-2.6.17.7/include/asm-x86_64/a.out.h
20428 --- linux-2.6.17.7/include/asm-x86_64/a.out.h   2006-07-24 23:36:01.000000000 -0400
20429 +++ linux-2.6.17.7/include/asm-x86_64/a.out.h   2006-08-01 20:29:48.000000000 -0400
20430 @@ -21,7 +21,7 @@ struct exec
20431  
20432  #ifdef __KERNEL__
20433  #include <linux/thread_info.h>
20434 -#define STACK_TOP TASK_SIZE
20435 +#define __STACK_TOP TASK_SIZE
20436  #endif
20437  
20438  #endif /* __A_OUT_GNU_H__ */
20439 diff -urNp linux-2.6.17.7/include/asm-x86_64/elf.h linux-2.6.17.7/include/asm-x86_64/elf.h
20440 --- linux-2.6.17.7/include/asm-x86_64/elf.h     2006-07-24 23:36:01.000000000 -0400
20441 +++ linux-2.6.17.7/include/asm-x86_64/elf.h     2006-08-01 20:29:48.000000000 -0400
20442 @@ -90,6 +90,17 @@ typedef struct user_i387_struct elf_fpre
20443  
20444  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
20445  
20446 +#ifdef CONFIG_PAX_ASLR
20447 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
20448 +
20449 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
20450 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
20451 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
20452 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
20453 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
20454 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 32)
20455 +#endif
20456 +
20457  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
20458     now struct_user_regs, they are different). Assumes current is the process
20459     getting dumped. */
20460 diff -urNp linux-2.6.17.7/include/asm-x86_64/ia32.h linux-2.6.17.7/include/asm-x86_64/ia32.h
20461 --- linux-2.6.17.7/include/asm-x86_64/ia32.h    2006-07-24 23:36:01.000000000 -0400
20462 +++ linux-2.6.17.7/include/asm-x86_64/ia32.h    2006-08-01 20:29:48.000000000 -0400
20463 @@ -157,7 +157,13 @@ struct ustat32 {
20464         char                    f_fpack[6];
20465  };
20466  
20467 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
20468 +#ifdef CONFIG_PAX_RANDUSTACK
20469 +#define IA32_DELTA_STACK (current->mm->delta_stack)
20470 +#else
20471 +#define IA32_DELTA_STACK 0UL
20472 +#endif
20473 +
20474 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
20475  
20476  #ifdef __KERNEL__
20477  struct user_desc;
20478 diff -urNp linux-2.6.17.7/include/asm-x86_64/kmap_types.h linux-2.6.17.7/include/asm-x86_64/kmap_types.h
20479 --- linux-2.6.17.7/include/asm-x86_64/kmap_types.h      2006-07-24 23:36:01.000000000 -0400
20480 +++ linux-2.6.17.7/include/asm-x86_64/kmap_types.h      2006-08-01 20:29:48.000000000 -0400
20481 @@ -13,6 +13,7 @@ enum km_type {
20482         KM_IRQ1,
20483         KM_SOFTIRQ0,
20484         KM_SOFTIRQ1,
20485 +       KM_CLEARPAGE,
20486         KM_TYPE_NR
20487  };
20488  
20489 diff -urNp linux-2.6.17.7/include/asm-x86_64/page.h linux-2.6.17.7/include/asm-x86_64/page.h
20490 --- linux-2.6.17.7/include/asm-x86_64/page.h    2006-07-24 23:36:01.000000000 -0400
20491 +++ linux-2.6.17.7/include/asm-x86_64/page.h    2006-08-01 20:29:48.000000000 -0400
20492 @@ -134,6 +134,15 @@ typedef struct { unsigned long pgprot; }
20493         (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
20494          VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
20495  
20496 +#ifdef CONFIG_PAX_PAGEEXEC
20497 +#ifdef CONFIG_PAX_MPROTECT
20498 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
20499 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20500 +#else
20501 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
20502 +#endif
20503 +#endif
20504 +
20505  #define __HAVE_ARCH_GATE_AREA 1        
20506  
20507  #endif /* __KERNEL__ */
20508 diff -urNp linux-2.6.17.7/include/asm-x86_64/pgalloc.h linux-2.6.17.7/include/asm-x86_64/pgalloc.h
20509 --- linux-2.6.17.7/include/asm-x86_64/pgalloc.h 2006-07-24 23:36:01.000000000 -0400
20510 +++ linux-2.6.17.7/include/asm-x86_64/pgalloc.h 2006-08-01 20:29:48.000000000 -0400
20511 @@ -7,7 +7,7 @@
20512  #include <linux/mm.h>
20513  
20514  #define pmd_populate_kernel(mm, pmd, pte) \
20515 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
20516 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
20517  #define pud_populate(mm, pud, pmd) \
20518                 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
20519  #define pgd_populate(mm, pgd, pud) \
20520 diff -urNp linux-2.6.17.7/include/asm-x86_64/pgtable.h linux-2.6.17.7/include/asm-x86_64/pgtable.h
20521 --- linux-2.6.17.7/include/asm-x86_64/pgtable.h 2006-07-24 23:36:01.000000000 -0400
20522 +++ linux-2.6.17.7/include/asm-x86_64/pgtable.h 2006-08-01 20:29:48.000000000 -0400
20523 @@ -180,6 +180,10 @@ static inline pte_t ptep_get_and_clear_f
20524  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
20525  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
20526  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
20527 +
20528 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
20529 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
20530 +
20531  #define __PAGE_KERNEL \
20532         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
20533  #define __PAGE_KERNEL_EXEC \
20534 @@ -268,7 +272,13 @@ static inline pte_t pfn_pte(unsigned lon
20535  #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
20536  static inline int pte_user(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
20537  static inline int pte_read(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
20538 -static inline int pte_exec(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
20539 +extern inline int pte_exec(pte_t pte)
20540 +{
20541 +       if (__supported_pte_mask & _PAGE_NX)
20542 +               return pte_val(pte) & _PAGE_NX;
20543 +       else
20544 +               return pte_val(pte) & _PAGE_USER;
20545 +}
20546  static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
20547  static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
20548  static inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_RW; }
20549 @@ -276,12 +286,26 @@ static inline int pte_file(pte_t pte)             {
20550  static inline int pte_huge(pte_t pte)          { return pte_val(pte) & _PAGE_PSE; }
20551  
20552  static inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
20553 -static inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
20554 +extern inline pte_t pte_exprotect(pte_t pte)
20555 +{
20556 +       if (__supported_pte_mask & _PAGE_NX)
20557 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
20558 +       else
20559 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
20560 +       return pte;
20561 +}
20562  static inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
20563  static inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
20564  static inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
20565  static inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
20566 -static inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
20567 +extern inline pte_t pte_mkexec(pte_t pte)
20568 +{
20569 +       if (__supported_pte_mask & _PAGE_NX)
20570 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
20571 +       else
20572 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
20573 +       return pte;
20574 +}
20575  static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
20576  static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
20577  static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
20578 diff -urNp linux-2.6.17.7/include/asm-x86_64/system.h linux-2.6.17.7/include/asm-x86_64/system.h
20579 --- linux-2.6.17.7/include/asm-x86_64/system.h  2006-07-24 23:36:01.000000000 -0400
20580 +++ linux-2.6.17.7/include/asm-x86_64/system.h  2006-08-01 20:29:48.000000000 -0400
20581 @@ -366,6 +366,6 @@ static inline unsigned long __cmpxchg(vo
20582  
20583  void cpu_idle_wait(void);
20584  
20585 -extern unsigned long arch_align_stack(unsigned long sp);
20586 +#define arch_align_stack(x) (x)
20587  
20588  #endif
20589 diff -urNp linux-2.6.17.7/include/asm-xtensa/kmap_types.h linux-2.6.17.7/include/asm-xtensa/kmap_types.h
20590 --- linux-2.6.17.7/include/asm-xtensa/kmap_types.h      2006-07-24 23:36:01.000000000 -0400
20591 +++ linux-2.6.17.7/include/asm-xtensa/kmap_types.h      2006-08-01 20:29:48.000000000 -0400
20592 @@ -25,6 +25,7 @@ enum km_type {
20593    KM_IRQ1,
20594    KM_SOFTIRQ0,
20595    KM_SOFTIRQ1,
20596 +  KM_CLEARPAGE,
20597    KM_TYPE_NR
20598  };
20599  
20600 diff -urNp linux-2.6.17.7/include/linux/a.out.h linux-2.6.17.7/include/linux/a.out.h
20601 --- linux-2.6.17.7/include/linux/a.out.h        2006-07-24 23:36:01.000000000 -0400
20602 +++ linux-2.6.17.7/include/linux/a.out.h        2006-08-01 20:29:48.000000000 -0400
20603 @@ -7,6 +7,16 @@
20604  
20605  #include <asm/a.out.h>
20606  
20607 +#ifdef CONFIG_PAX_RANDUSTACK
20608 +#define __DELTA_STACK (current->mm->delta_stack)
20609 +#else
20610 +#define __DELTA_STACK 0UL
20611 +#endif
20612 +
20613 +#ifndef STACK_TOP
20614 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
20615 +#endif
20616 +
20617  #endif /* __STRUCT_EXEC_OVERRIDE__ */
20618  
20619  /* these go in the N_MACHTYPE field */
20620 @@ -37,6 +47,14 @@ enum machine_type {
20621    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
20622  };
20623  
20624 +/* Constants for the N_FLAGS field */
20625 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
20626 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
20627 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
20628 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
20629 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
20630 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
20631 +
20632  #if !defined (N_MAGIC)
20633  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
20634  #endif
20635 diff -urNp linux-2.6.17.7/include/linux/binfmts.h linux-2.6.17.7/include/linux/binfmts.h
20636 --- linux-2.6.17.7/include/linux/binfmts.h      2006-07-24 23:36:01.000000000 -0400
20637 +++ linux-2.6.17.7/include/linux/binfmts.h      2006-08-01 20:29:48.000000000 -0400
20638 @@ -7,10 +7,10 @@ struct pt_regs;
20639  
20640  /*
20641   * MAX_ARG_PAGES defines the number of pages allocated for arguments
20642 - * and envelope for the new program. 32 should suffice, this gives
20643 - * a maximum env+arg of 128kB w/4KB pages!
20644 + * and envelope for the new program. 33 should suffice, this gives
20645 + * a maximum env+arg of 132kB w/4KB pages!
20646   */
20647 -#define MAX_ARG_PAGES 32
20648 +#define MAX_ARG_PAGES 33
20649  
20650  /* sizeof(linux_binprm->buf) */
20651  #define BINPRM_BUF_SIZE 128
20652 @@ -38,6 +38,7 @@ struct linux_binprm{
20653         unsigned interp_flags;
20654         unsigned interp_data;
20655         unsigned long loader, exec;
20656 +       int misc;
20657  };
20658  
20659  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
20660 @@ -87,5 +88,8 @@ extern void compute_creds(struct linux_b
20661  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
20662  extern int set_binfmt(struct linux_binfmt *new);
20663  
20664 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
20665 +void pax_report_insns(void *pc, void *sp);
20666 +
20667  #endif /* __KERNEL__ */
20668  #endif /* _LINUX_BINFMTS_H */
20669 diff -urNp linux-2.6.17.7/include/linux/capability.h linux-2.6.17.7/include/linux/capability.h
20670 --- linux-2.6.17.7/include/linux/capability.h   2006-07-24 23:36:01.000000000 -0400
20671 +++ linux-2.6.17.7/include/linux/capability.h   2006-08-01 20:29:48.000000000 -0400
20672 @@ -358,6 +358,7 @@ static inline kernel_cap_t cap_invert(ke
20673  #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
20674  
20675  int capable(int cap);
20676 +int capable_nolog(int cap);
20677  int __capable(struct task_struct *t, int cap);
20678  
20679  #endif /* __KERNEL__ */
20680 diff -urNp linux-2.6.17.7/include/linux/elf.h linux-2.6.17.7/include/linux/elf.h
20681 --- linux-2.6.17.7/include/linux/elf.h  2006-07-24 23:36:01.000000000 -0400
20682 +++ linux-2.6.17.7/include/linux/elf.h  2006-08-01 20:29:48.000000000 -0400
20683 @@ -5,6 +5,10 @@
20684  #include <linux/auxvec.h>
20685  #include <asm/elf.h>
20686  
20687 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20688 +#undef elf_read_implies_exec
20689 +#endif
20690 +
20691  #ifndef elf_read_implies_exec
20692    /* Executables for which elf_read_implies_exec() returns TRUE will
20693       have the READ_IMPLIES_EXEC personality flag set automatically.
20694 @@ -46,6 +50,16 @@ typedef __s64        Elf64_Sxword;
20695  
20696  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
20697  
20698 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
20699 +
20700 +/* Constants for the e_flags field */
20701 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
20702 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
20703 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
20704 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
20705 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
20706 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
20707 +
20708  /* These constants define the different elf file types */
20709  #define ET_NONE   0
20710  #define ET_REL    1
20711 @@ -138,6 +152,8 @@ typedef __s64       Elf64_Sxword;
20712  #define DT_DEBUG       21
20713  #define DT_TEXTREL     22
20714  #define DT_JMPREL      23
20715 +#define DT_FLAGS       30
20716 +  #define DF_TEXTREL   0x00000004
20717  #define DT_LOPROC      0x70000000
20718  #define DT_HIPROC      0x7fffffff
20719  
20720 @@ -267,6 +283,19 @@ typedef struct elf64_hdr {
20721  #define PF_W           0x2
20722  #define PF_X           0x1
20723  
20724 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
20725 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
20726 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
20727 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
20728 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
20729 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
20730 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
20731 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
20732 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
20733 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
20734 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
20735 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
20736 +
20737  typedef struct elf32_phdr{
20738    Elf32_Word   p_type;
20739    Elf32_Off    p_offset;
20740 @@ -359,6 +388,8 @@ typedef struct elf64_shdr {
20741  #define        EI_OSABI        7
20742  #define        EI_PAD          8
20743  
20744 +#define        EI_PAX          14
20745 +
20746  #define        ELFMAG0         0x7f            /* EI_MAG */
20747  #define        ELFMAG1         'E'
20748  #define        ELFMAG2         'L'
20749 @@ -415,6 +446,7 @@ extern Elf32_Dyn _DYNAMIC [];
20750  #define elfhdr         elf32_hdr
20751  #define elf_phdr       elf32_phdr
20752  #define elf_note       elf32_note
20753 +#define elf_dyn                Elf32_Dyn
20754  
20755  #else
20756  
20757 @@ -422,6 +454,7 @@ extern Elf64_Dyn _DYNAMIC [];
20758  #define elfhdr         elf64_hdr
20759  #define elf_phdr       elf64_phdr
20760  #define elf_note       elf64_note
20761 +#define elf_dyn                Elf64_Dyn
20762  
20763  #endif
20764  
20765 diff -urNp linux-2.6.17.7/include/linux/gracl.h linux-2.6.17.7/include/linux/gracl.h
20766 --- linux-2.6.17.7/include/linux/gracl.h        1969-12-31 19:00:00.000000000 -0500
20767 +++ linux-2.6.17.7/include/linux/gracl.h        2006-08-01 20:29:48.000000000 -0400
20768 @@ -0,0 +1,316 @@
20769 +#ifndef GR_ACL_H
20770 +#define GR_ACL_H
20771 +
20772 +#include <linux/grdefs.h>
20773 +#include <linux/resource.h>
20774 +#include <linux/dcache.h>
20775 +#include <asm/resource.h>
20776 +
20777 +/* Major status information */
20778 +
20779 +#define GR_VERSION  "grsecurity 2.1.9"
20780 +#define GRSECURITY_VERSION 0x219
20781 +
20782 +enum {
20783 +
20784 +       SHUTDOWN = 0,
20785 +       ENABLE = 1,
20786 +       SPROLE = 2,
20787 +       RELOAD = 3,
20788 +       SEGVMOD = 4,
20789 +       STATUS = 5,
20790 +       UNSPROLE = 6,
20791 +       PASSSET = 7,
20792 +       SPROLEPAM = 8
20793 +};
20794 +
20795 +/* Password setup definitions
20796 + * kernel/grhash.c */
20797 +enum {
20798 +       GR_PW_LEN = 128,
20799 +       GR_SALT_LEN = 16,
20800 +       GR_SHA_LEN = 32,
20801 +};
20802 +
20803 +enum {
20804 +       GR_SPROLE_LEN = 64,
20805 +};
20806 +
20807 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
20808 +
20809 +/* Begin Data Structures */
20810 +
20811 +struct sprole_pw {
20812 +       unsigned char *rolename;
20813 +       unsigned char salt[GR_SALT_LEN];
20814 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
20815 +};
20816 +
20817 +struct name_entry {
20818 +       __u32 key;
20819 +       ino_t inode;
20820 +       dev_t device;
20821 +       char *name;
20822 +       __u16 len;
20823 +       struct name_entry *prev;
20824 +       struct name_entry *next;
20825 +};
20826 +
20827 +struct inodev_entry {
20828 +       struct name_entry *nentry;
20829 +       struct inodev_entry *prev;
20830 +       struct inodev_entry *next;
20831 +};
20832 +
20833 +struct acl_role_db {
20834 +       struct acl_role_label **r_hash;
20835 +       __u32 r_size;
20836 +};
20837 +
20838 +struct inodev_db {
20839 +       struct inodev_entry **i_hash;
20840 +       __u32 i_size;
20841 +};
20842 +
20843 +struct name_db {
20844 +       struct name_entry **n_hash;
20845 +       __u32 n_size;
20846 +};
20847 +
20848 +struct crash_uid {
20849 +       uid_t uid;
20850 +       unsigned long expires;
20851 +};
20852 +
20853 +struct gr_hash_struct {
20854 +       void **table;
20855 +       void **nametable;
20856 +       void *first;
20857 +       __u32 table_size;
20858 +       __u32 used_size;
20859 +       int type;
20860 +};
20861 +
20862 +/* Userspace Grsecurity ACL data structures */
20863 +
20864 +struct acl_subject_label {
20865 +       char *filename;
20866 +       ino_t inode;
20867 +       dev_t device;
20868 +       __u32 mode;
20869 +       __u32 cap_mask;
20870 +       __u32 cap_lower;
20871 +
20872 +       struct rlimit res[GR_NLIMITS];
20873 +       __u16 resmask;
20874 +
20875 +       __u8 user_trans_type;
20876 +       __u8 group_trans_type;
20877 +       uid_t *user_transitions;
20878 +       gid_t *group_transitions;
20879 +       __u16 user_trans_num;
20880 +       __u16 group_trans_num;
20881 +
20882 +       __u32 ip_proto[8];
20883 +       __u32 ip_type;
20884 +       struct acl_ip_label **ips;
20885 +       __u32 ip_num;
20886 +
20887 +       __u32 crashes;
20888 +       unsigned long expires;
20889 +
20890 +       struct acl_subject_label *parent_subject;
20891 +       struct gr_hash_struct *hash;
20892 +       struct acl_subject_label *prev;
20893 +       struct acl_subject_label *next;
20894 +
20895 +       struct acl_object_label **obj_hash;
20896 +       __u32 obj_hash_size;
20897 +       __u16 pax_flags;
20898 +};
20899 +
20900 +struct role_allowed_ip {
20901 +       __u32 addr;
20902 +       __u32 netmask;
20903 +
20904 +       struct role_allowed_ip *prev;
20905 +       struct role_allowed_ip *next;
20906 +};
20907 +
20908 +struct role_transition {
20909 +       char *rolename;
20910 +
20911 +       struct role_transition *prev;
20912 +       struct role_transition *next;
20913 +};
20914 +
20915 +struct acl_role_label {
20916 +       char *rolename;
20917 +       uid_t uidgid;
20918 +       __u16 roletype;
20919 +
20920 +       __u16 auth_attempts;
20921 +       unsigned long expires;
20922 +
20923 +       struct acl_subject_label *root_label;
20924 +       struct gr_hash_struct *hash;
20925 +
20926 +       struct acl_role_label *prev;
20927 +       struct acl_role_label *next;
20928 +
20929 +       struct role_transition *transitions;
20930 +       struct role_allowed_ip *allowed_ips;
20931 +       uid_t *domain_children;
20932 +       __u16 domain_child_num;
20933 +
20934 +       struct acl_subject_label **subj_hash;
20935 +       __u32 subj_hash_size;
20936 +};
20937 +
20938 +struct user_acl_role_db {
20939 +       struct acl_role_label **r_table;
20940 +       __u32 num_pointers;             /* Number of allocations to track */
20941 +       __u32 num_roles;                /* Number of roles */
20942 +       __u32 num_domain_children;      /* Number of domain children */
20943 +       __u32 num_subjects;             /* Number of subjects */
20944 +       __u32 num_objects;              /* Number of objects */
20945 +};
20946 +
20947 +struct acl_object_label {
20948 +       char *filename;
20949 +       ino_t inode;
20950 +       dev_t device;
20951 +       __u32 mode;
20952 +
20953 +       struct acl_subject_label *nested;
20954 +       struct acl_object_label *globbed;
20955 +
20956 +       /* next two structures not used */
20957 +
20958 +       struct acl_object_label *prev;
20959 +       struct acl_object_label *next;
20960 +};
20961 +
20962 +struct acl_ip_label {
20963 +       char *iface;
20964 +       __u32 addr;
20965 +       __u32 netmask;
20966 +       __u16 low, high;
20967 +       __u8 mode;
20968 +       __u32 type;
20969 +       __u32 proto[8];
20970 +
20971 +       /* next two structures not used */
20972 +
20973 +       struct acl_ip_label *prev;
20974 +       struct acl_ip_label *next;
20975 +};
20976 +
20977 +struct gr_arg {
20978 +       struct user_acl_role_db role_db;
20979 +       unsigned char pw[GR_PW_LEN];
20980 +       unsigned char salt[GR_SALT_LEN];
20981 +       unsigned char sum[GR_SHA_LEN];
20982 +       unsigned char sp_role[GR_SPROLE_LEN];
20983 +       struct sprole_pw *sprole_pws;
20984 +       dev_t segv_device;
20985 +       ino_t segv_inode;
20986 +       uid_t segv_uid;
20987 +       __u16 num_sprole_pws;
20988 +       __u16 mode;
20989 +};
20990 +
20991 +struct gr_arg_wrapper {
20992 +       struct gr_arg *arg;
20993 +       __u32 version;
20994 +       __u32 size;
20995 +};
20996 +
20997 +struct subject_map {
20998 +       struct acl_subject_label *user;
20999 +       struct acl_subject_label *kernel;
21000 +       struct subject_map *prev;
21001 +       struct subject_map *next;
21002 +};
21003 +
21004 +struct acl_subj_map_db {
21005 +       struct subject_map **s_hash;
21006 +       __u32 s_size;
21007 +};
21008 +
21009 +/* End Data Structures Section */
21010 +
21011 +/* Hash functions generated by empirical testing by Brad Spengler
21012 +   Makes good use of the low bits of the inode.  Generally 0-1 times
21013 +   in loop for successful match.  0-3 for unsuccessful match.
21014 +   Shift/add algorithm with modulus of table size and an XOR*/
21015 +
21016 +static __inline__ unsigned int
21017 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
21018 +{
21019 +       return (((uid << type) + (uid ^ type)) % sz);
21020 +}
21021 +
21022 + static __inline__ unsigned int
21023 +shash(const struct acl_subject_label *userp, const unsigned int sz)
21024 +{
21025 +       return ((const unsigned long)userp % sz);
21026 +}
21027 +
21028 +static __inline__ unsigned int
21029 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
21030 +{
21031 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
21032 +}
21033 +
21034 +static __inline__ unsigned int
21035 +nhash(const char *name, const __u16 len, const unsigned int sz)
21036 +{
21037 +       return full_name_hash(name, len) % sz;
21038 +}
21039 +
21040 +#define FOR_EACH_ROLE_START(role,iter) \
21041 +       role = NULL; \
21042 +       iter = 0; \
21043 +       while (iter < acl_role_set.r_size) { \
21044 +               if (role == NULL) \
21045 +                       role = acl_role_set.r_hash[iter]; \
21046 +               if (role == NULL) { \
21047 +                       iter++; \
21048 +                       continue; \
21049 +               }
21050 +
21051 +#define FOR_EACH_ROLE_END(role,iter) \
21052 +               role = role->next; \
21053 +               if (role == NULL) \
21054 +                       iter++; \
21055 +       }
21056 +
21057 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
21058 +       subj = NULL; \
21059 +       iter = 0; \
21060 +       while (iter < role->subj_hash_size) { \
21061 +               if (subj == NULL) \
21062 +                       subj = role->subj_hash[iter]; \
21063 +               if (subj == NULL) { \
21064 +                       iter++; \
21065 +                       continue; \
21066 +               }
21067 +
21068 +#define FOR_EACH_SUBJECT_END(subj,iter) \
21069 +               subj = subj->next; \
21070 +               if (subj == NULL) \
21071 +                       iter++; \
21072 +       }
21073 +
21074 +
21075 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
21076 +       subj = role->hash->first; \
21077 +       while (subj != NULL) {
21078 +
21079 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
21080 +               subj = subj->next; \
21081 +       }
21082 +
21083 +#endif
21084 +
21085 diff -urNp linux-2.6.17.7/include/linux/gralloc.h linux-2.6.17.7/include/linux/gralloc.h
21086 --- linux-2.6.17.7/include/linux/gralloc.h      1969-12-31 19:00:00.000000000 -0500
21087 +++ linux-2.6.17.7/include/linux/gralloc.h      2006-08-01 20:29:48.000000000 -0400
21088 @@ -0,0 +1,8 @@
21089 +#ifndef __GRALLOC_H
21090 +#define __GRALLOC_H
21091 +
21092 +void acl_free_all(void);
21093 +int acl_alloc_stack_init(unsigned long size);
21094 +void *acl_alloc(unsigned long len);
21095 +
21096 +#endif
21097 diff -urNp linux-2.6.17.7/include/linux/grdefs.h linux-2.6.17.7/include/linux/grdefs.h
21098 --- linux-2.6.17.7/include/linux/grdefs.h       1969-12-31 19:00:00.000000000 -0500
21099 +++ linux-2.6.17.7/include/linux/grdefs.h       2006-08-01 20:29:48.000000000 -0400
21100 @@ -0,0 +1,131 @@
21101 +#ifndef GRDEFS_H
21102 +#define GRDEFS_H
21103 +
21104 +/* Begin grsecurity status declarations */
21105 +
21106 +enum {
21107 +       GR_READY = 0x01,
21108 +       GR_STATUS_INIT = 0x00   // disabled state
21109 +};
21110 +
21111 +/* Begin  ACL declarations */
21112 +
21113 +/* Role flags */
21114 +
21115 +enum {
21116 +       GR_ROLE_USER = 0x0001,
21117 +       GR_ROLE_GROUP = 0x0002,
21118 +       GR_ROLE_DEFAULT = 0x0004,
21119 +       GR_ROLE_SPECIAL = 0x0008,
21120 +       GR_ROLE_AUTH = 0x0010,
21121 +       GR_ROLE_NOPW = 0x0020,
21122 +       GR_ROLE_GOD = 0x0040,
21123 +       GR_ROLE_LEARN = 0x0080,
21124 +       GR_ROLE_TPE = 0x0100,
21125 +       GR_ROLE_DOMAIN = 0x0200,
21126 +       GR_ROLE_PAM = 0x0400
21127 +};
21128 +
21129 +/* ACL Subject and Object mode flags */
21130 +enum {
21131 +       GR_DELETED = 0x80000000
21132 +};
21133 +
21134 +/* ACL Object-only mode flags */
21135 +enum {
21136 +       GR_READ         = 0x00000001,
21137 +       GR_APPEND       = 0x00000002,
21138 +       GR_WRITE        = 0x00000004,
21139 +       GR_EXEC         = 0x00000008,
21140 +       GR_FIND         = 0x00000010,
21141 +       GR_INHERIT      = 0x00000020,
21142 +       GR_SETID        = 0x00000040,
21143 +       GR_CREATE       = 0x00000080,
21144 +       GR_DELETE       = 0x00000100,
21145 +       GR_LINK         = 0x00000200,
21146 +       GR_AUDIT_READ   = 0x00000400,
21147 +       GR_AUDIT_APPEND = 0x00000800,
21148 +       GR_AUDIT_WRITE  = 0x00001000,
21149 +       GR_AUDIT_EXEC   = 0x00002000,
21150 +       GR_AUDIT_FIND   = 0x00004000,
21151 +       GR_AUDIT_INHERIT= 0x00008000,
21152 +       GR_AUDIT_SETID  = 0x00010000,
21153 +       GR_AUDIT_CREATE = 0x00020000,
21154 +       GR_AUDIT_DELETE = 0x00040000,
21155 +       GR_AUDIT_LINK   = 0x00080000,
21156 +       GR_PTRACERD     = 0x00100000,
21157 +       GR_NOPTRACE     = 0x00200000,
21158 +       GR_SUPPRESS     = 0x00400000,
21159 +       GR_NOLEARN      = 0x00800000
21160 +};
21161 +
21162 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
21163 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
21164 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
21165 +
21166 +/* ACL subject-only mode flags */
21167 +enum {
21168 +       GR_KILL         = 0x00000001,
21169 +       GR_VIEW         = 0x00000002,
21170 +       GR_PROTECTED    = 0x00000004,
21171 +       GR_LEARN        = 0x00000008,
21172 +       GR_OVERRIDE     = 0x00000010,
21173 +       /* just a placeholder, this mode is only used in userspace */
21174 +       GR_DUMMY        = 0x00000020,
21175 +       GR_PROTSHM      = 0x00000040,
21176 +       GR_KILLPROC     = 0x00000080,
21177 +       GR_KILLIPPROC   = 0x00000100,
21178 +       /* just a placeholder, this mode is only used in userspace */
21179 +       GR_NOTROJAN     = 0x00000200,
21180 +       GR_PROTPROCFD   = 0x00000400,
21181 +       GR_PROCACCT     = 0x00000800,
21182 +       GR_RELAXPTRACE  = 0x00001000,
21183 +       GR_NESTED       = 0x00002000,
21184 +       GR_INHERITLEARN = 0x00004000,
21185 +       GR_PROCFIND     = 0x00008000,
21186 +       GR_POVERRIDE    = 0x00010000,
21187 +       GR_KERNELAUTH   = 0x00020000,
21188 +};
21189 +
21190 +enum {
21191 +       GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
21192 +       GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
21193 +       GR_PAX_ENABLE_MPROTECT  = 0x0004,
21194 +       GR_PAX_ENABLE_RANDMMAP  = 0x0008,
21195 +       GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
21196 +       GR_PAX_DISABLE_SEGMEXEC = 0x8001,
21197 +       GR_PAX_DISABLE_PAGEEXEC = 0x8002,
21198 +       GR_PAX_DISABLE_MPROTECT = 0x8004,
21199 +       GR_PAX_DISABLE_RANDMMAP = 0x8008,
21200 +       GR_PAX_DISABLE_EMUTRAMP = 0x8010,
21201 +};
21202 +
21203 +enum {
21204 +       GR_ID_USER      = 0x01,
21205 +       GR_ID_GROUP     = 0x02,
21206 +};
21207 +
21208 +enum {
21209 +       GR_ID_ALLOW     = 0x01,
21210 +       GR_ID_DENY      = 0x02,
21211 +};
21212 +
21213 +#define GR_CRASH_RES   11
21214 +#define GR_UIDTABLE_MAX 500
21215 +
21216 +/* begin resource learning section */
21217 +enum {
21218 +       GR_RLIM_CPU_BUMP = 60,
21219 +       GR_RLIM_FSIZE_BUMP = 50000,
21220 +       GR_RLIM_DATA_BUMP = 10000,
21221 +       GR_RLIM_STACK_BUMP = 1000,
21222 +       GR_RLIM_CORE_BUMP = 10000,
21223 +       GR_RLIM_RSS_BUMP = 500000,
21224 +       GR_RLIM_NPROC_BUMP = 1,
21225 +       GR_RLIM_NOFILE_BUMP = 5,
21226 +       GR_RLIM_MEMLOCK_BUMP = 50000,
21227 +       GR_RLIM_AS_BUMP = 500000,
21228 +       GR_RLIM_LOCKS_BUMP = 2
21229 +};
21230 +
21231 +#endif
21232 diff -urNp linux-2.6.17.7/include/linux/grinternal.h linux-2.6.17.7/include/linux/grinternal.h
21233 --- linux-2.6.17.7/include/linux/grinternal.h   1969-12-31 19:00:00.000000000 -0500
21234 +++ linux-2.6.17.7/include/linux/grinternal.h   2006-08-01 20:29:48.000000000 -0400
21235 @@ -0,0 +1,211 @@
21236 +#ifndef __GRINTERNAL_H
21237 +#define __GRINTERNAL_H
21238 +
21239 +#ifdef CONFIG_GRKERNSEC
21240 +
21241 +#include <linux/fs.h>
21242 +#include <linux/gracl.h>
21243 +#include <linux/grdefs.h>
21244 +#include <linux/grmsg.h>
21245 +
21246 +extern void gr_add_learn_entry(const char *fmt, ...);
21247 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
21248 +                           const struct vfsmount *mnt);
21249 +extern __u32 gr_check_create(const struct dentry *new_dentry,
21250 +                            const struct dentry *parent,
21251 +                            const struct vfsmount *mnt, const __u32 mode);
21252 +extern int gr_check_protected_task(const struct task_struct *task);
21253 +extern __u32 to_gr_audit(const __u32 reqmode);
21254 +extern int gr_set_acls(const int type);
21255 +
21256 +extern int gr_acl_is_enabled(void);
21257 +extern char gr_roletype_to_char(void);
21258 +
21259 +extern void gr_handle_alertkill(struct task_struct *task);
21260 +extern char *gr_to_filename(const struct dentry *dentry,
21261 +                           const struct vfsmount *mnt);
21262 +extern char *gr_to_filename1(const struct dentry *dentry,
21263 +                           const struct vfsmount *mnt);
21264 +extern char *gr_to_filename2(const struct dentry *dentry,
21265 +                           const struct vfsmount *mnt);
21266 +extern char *gr_to_filename3(const struct dentry *dentry,
21267 +                           const struct vfsmount *mnt);
21268 +
21269 +extern int grsec_enable_link;
21270 +extern int grsec_enable_fifo;
21271 +extern int grsec_enable_execve;
21272 +extern int grsec_enable_shm;
21273 +extern int grsec_enable_execlog;
21274 +extern int grsec_enable_signal;
21275 +extern int grsec_enable_forkfail;
21276 +extern int grsec_enable_time;
21277 +extern int grsec_enable_chroot_shmat;
21278 +extern int grsec_enable_chroot_findtask;
21279 +extern int grsec_enable_chroot_mount;
21280 +extern int grsec_enable_chroot_double;
21281 +extern int grsec_enable_chroot_pivot;
21282 +extern int grsec_enable_chroot_chdir;
21283 +extern int grsec_enable_chroot_chmod;
21284 +extern int grsec_enable_chroot_mknod;
21285 +extern int grsec_enable_chroot_fchdir;
21286 +extern int grsec_enable_chroot_nice;
21287 +extern int grsec_enable_chroot_execlog;
21288 +extern int grsec_enable_chroot_caps;
21289 +extern int grsec_enable_chroot_sysctl;
21290 +extern int grsec_enable_chroot_unix;
21291 +extern int grsec_enable_tpe;
21292 +extern int grsec_tpe_gid;
21293 +extern int grsec_enable_tpe_all;
21294 +extern int grsec_enable_sidcaps;
21295 +extern int grsec_enable_randpid;
21296 +extern int grsec_enable_socket_all;
21297 +extern int grsec_socket_all_gid;
21298 +extern int grsec_enable_socket_client;
21299 +extern int grsec_socket_client_gid;
21300 +extern int grsec_enable_socket_server;
21301 +extern int grsec_socket_server_gid;
21302 +extern int grsec_audit_gid;
21303 +extern int grsec_enable_group;
21304 +extern int grsec_enable_audit_ipc;
21305 +extern int grsec_enable_audit_textrel;
21306 +extern int grsec_enable_mount;
21307 +extern int grsec_enable_chdir;
21308 +extern int grsec_resource_logging;
21309 +extern int grsec_lock;
21310 +
21311 +extern struct task_struct *child_reaper;
21312 +
21313 +extern spinlock_t grsec_alert_lock;
21314 +extern unsigned long grsec_alert_wtime;
21315 +extern unsigned long grsec_alert_fyet;
21316 +
21317 +extern spinlock_t grsec_audit_lock;
21318 +
21319 +extern rwlock_t grsec_exec_file_lock;
21320 +
21321 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
21322 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
21323 +                       tsk->exec_file->f_vfsmnt) : "/")
21324 +
21325 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
21326 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
21327 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
21328 +
21329 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
21330 +                       gr_to_filename(tsk->exec_file->f_dentry, \
21331 +                       tsk->exec_file->f_vfsmnt) : "/")
21332 +
21333 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
21334 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
21335 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
21336 +
21337 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
21338 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
21339 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
21340 +                         (tsk_a->fs->root->d_inode->i_ino != \
21341 +                         child_reaper->fs->root->d_inode->i_ino)))
21342 +
21343 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
21344 +                         (tsk_a->fs->root->d_inode->i_sb->s_dev == \
21345 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
21346 +                         (tsk_a->fs->root->d_inode->i_ino == \
21347 +                         tsk_b->fs->root->d_inode->i_ino))
21348 +
21349 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
21350 +                      task->pid, task->uid, \
21351 +                      task->euid, task->gid, task->egid, \
21352 +                      gr_parent_task_fullpath(task), \
21353 +                      task->parent->comm, task->parent->pid, \
21354 +                      task->parent->uid, task->parent->euid, \
21355 +                      task->parent->gid, task->parent->egid
21356 +
21357 +#define GR_CHROOT_CAPS ( \
21358 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
21359 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
21360 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
21361 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
21362 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
21363 +       CAP_TO_MASK(CAP_IPC_OWNER))
21364 +
21365 +#define security_learn(normal_msg,args...) \
21366 +({ \
21367 +       read_lock(&grsec_exec_file_lock); \
21368 +       gr_add_learn_entry(normal_msg "\n", ## args); \
21369 +       read_unlock(&grsec_exec_file_lock); \
21370 +})
21371 +
21372 +enum {
21373 +       GR_DO_AUDIT,
21374 +       GR_DONT_AUDIT,
21375 +       GR_DONT_AUDIT_GOOD
21376 +};
21377 +
21378 +enum {
21379 +       GR_TTYSNIFF,
21380 +       GR_RBAC,
21381 +       GR_RBAC_STR,
21382 +       GR_STR_RBAC,
21383 +       GR_RBAC_MODE2,
21384 +       GR_RBAC_MODE3,
21385 +       GR_FILENAME,
21386 +       GR_NOARGS,
21387 +       GR_ONE_INT,
21388 +       GR_ONE_INT_TWO_STR,
21389 +       GR_ONE_STR,
21390 +       GR_STR_INT,
21391 +       GR_TWO_INT,
21392 +       GR_THREE_INT,
21393 +       GR_FIVE_INT_TWO_STR,
21394 +       GR_TWO_STR,
21395 +       GR_THREE_STR,
21396 +       GR_FOUR_STR,
21397 +       GR_STR_FILENAME,
21398 +       GR_FILENAME_STR,
21399 +       GR_FILENAME_TWO_INT,
21400 +       GR_FILENAME_TWO_INT_STR,
21401 +       GR_TEXTREL,
21402 +       GR_PTRACE,
21403 +       GR_RESOURCE,
21404 +       GR_CAP,
21405 +       GR_SIG,
21406 +       GR_CRASH1,
21407 +       GR_CRASH2,
21408 +       GR_PSACCT
21409 +};
21410 +
21411 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
21412 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
21413 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
21414 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
21415 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
21416 +#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)
21417 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
21418 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
21419 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
21420 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
21421 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
21422 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
21423 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
21424 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
21425 +#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)
21426 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
21427 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
21428 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
21429 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
21430 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
21431 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
21432 +#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)
21433 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
21434 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
21435 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
21436 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
21437 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
21438 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
21439 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
21440 +#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)
21441 +
21442 +extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
21443 +
21444 +#endif
21445 +
21446 +#endif
21447 diff -urNp linux-2.6.17.7/include/linux/grmsg.h linux-2.6.17.7/include/linux/grmsg.h
21448 --- linux-2.6.17.7/include/linux/grmsg.h        1969-12-31 19:00:00.000000000 -0500
21449 +++ linux-2.6.17.7/include/linux/grmsg.h        2006-08-01 20:29:48.000000000 -0400
21450 @@ -0,0 +1,108 @@
21451 +#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"
21452 +#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"
21453 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
21454 +#define GR_STOPMOD_MSG "denied modification of module state by "
21455 +#define GR_IOPERM_MSG "denied use of ioperm() by "
21456 +#define GR_IOPL_MSG "denied use of iopl() by "
21457 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
21458 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
21459 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
21460 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
21461 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
21462 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
21463 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
21464 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
21465 +#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"
21466 +#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"
21467 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
21468 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
21469 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
21470 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
21471 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
21472 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
21473 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
21474 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
21475 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
21476 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
21477 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
21478 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
21479 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
21480 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
21481 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
21482 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
21483 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
21484 +#define GR_NPROC_MSG "denied overstep of process limit by "
21485 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
21486 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
21487 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
21488 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
21489 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
21490 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
21491 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
21492 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
21493 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
21494 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
21495 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
21496 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
21497 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
21498 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
21499 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
21500 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
21501 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
21502 +#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"
21503 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
21504 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
21505 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
21506 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
21507 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
21508 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
21509 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
21510 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
21511 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
21512 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
21513 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
21514 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
21515 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
21516 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
21517 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
21518 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
21519 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
21520 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
21521 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
21522 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
21523 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
21524 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
21525 +#define GR_NICE_CHROOT_MSG "denied priority change by "
21526 +#define GR_UNISIGLOG_MSG "signal %d sent to "
21527 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
21528 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
21529 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
21530 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
21531 +#define GR_TIME_MSG "time set by "
21532 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
21533 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
21534 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
21535 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
21536 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
21537 +#define GR_BIND_MSG "denied bind() by "
21538 +#define GR_CONNECT_MSG "denied connect() by "
21539 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
21540 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
21541 +#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"
21542 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
21543 +#define GR_CAP_ACL_MSG "use of %s denied for "
21544 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
21545 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
21546 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
21547 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
21548 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
21549 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
21550 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
21551 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
21552 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
21553 +#define GR_SEM_AUDIT_MSG "semaphore created by "
21554 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
21555 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
21556 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
21557 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
21558 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
21559 diff -urNp linux-2.6.17.7/include/linux/grsecurity.h linux-2.6.17.7/include/linux/grsecurity.h
21560 --- linux-2.6.17.7/include/linux/grsecurity.h   1969-12-31 19:00:00.000000000 -0500
21561 +++ linux-2.6.17.7/include/linux/grsecurity.h   2006-08-01 20:29:48.000000000 -0400
21562 @@ -0,0 +1,196 @@
21563 +#ifndef GR_SECURITY_H
21564 +#define GR_SECURITY_H
21565 +#include <linux/fs.h>
21566 +#include <linux/binfmts.h>
21567 +#include <linux/gracl.h>
21568 +
21569 +extern void gr_handle_brute_attach(struct task_struct *p);
21570 +extern void gr_handle_brute_check(void);
21571 +
21572 +extern char gr_roletype_to_char(void);
21573 +
21574 +extern int gr_check_user_change(int real, int effective, int fs);
21575 +extern int gr_check_group_change(int real, int effective, int fs);
21576 +
21577 +extern void gr_del_task_from_ip_table(struct task_struct *p);
21578 +
21579 +extern int gr_pid_is_chrooted(struct task_struct *p);
21580 +extern int gr_handle_chroot_nice(void);
21581 +extern int gr_handle_chroot_sysctl(const int op);
21582 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
21583 +                                       const int niceval);
21584 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
21585 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
21586 +                                  const struct vfsmount *mnt);
21587 +extern void gr_handle_chroot_caps(struct task_struct *task);
21588 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
21589 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
21590 +                                 const struct vfsmount *mnt, const int mode);
21591 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
21592 +                                 const struct vfsmount *mnt, const int mode);
21593 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
21594 +                                 const struct vfsmount *mnt,
21595 +                                 const char *dev_name);
21596 +extern int gr_handle_chroot_pivot(void);
21597 +extern int gr_handle_chroot_unix(const pid_t pid);
21598 +
21599 +extern int gr_handle_rawio(const struct inode *inode);
21600 +extern int gr_handle_nproc(void);
21601 +
21602 +extern void gr_handle_ioperm(void);
21603 +extern void gr_handle_iopl(void);
21604 +
21605 +extern int gr_tpe_allow(const struct file *file);
21606 +
21607 +extern int gr_random_pid(void);
21608 +
21609 +extern void gr_log_forkfail(const int retval);
21610 +extern void gr_log_timechange(void);
21611 +extern void gr_log_signal(const int sig, const struct task_struct *t);
21612 +extern void gr_log_chdir(const struct dentry *dentry,
21613 +                        const struct vfsmount *mnt);
21614 +extern void gr_log_chroot_exec(const struct dentry *dentry,
21615 +                              const struct vfsmount *mnt);
21616 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
21617 +extern void gr_log_remount(const char *devname, const int retval);
21618 +extern void gr_log_unmount(const char *devname, const int retval);
21619 +extern void gr_log_mount(const char *from, const char *to, const int retval);
21620 +extern void gr_log_msgget(const int ret, const int msgflg);
21621 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
21622 +extern void gr_log_semget(const int err, const int semflg);
21623 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
21624 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
21625 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
21626 +extern void gr_log_textrel(struct vm_area_struct *vma);
21627 +
21628 +extern int gr_handle_follow_link(const struct inode *parent,
21629 +                                const struct inode *inode,
21630 +                                const struct dentry *dentry,
21631 +                                const struct vfsmount *mnt);
21632 +extern int gr_handle_fifo(const struct dentry *dentry,
21633 +                         const struct vfsmount *mnt,
21634 +                         const struct dentry *dir, const int flag,
21635 +                         const int acc_mode);
21636 +extern int gr_handle_hardlink(const struct dentry *dentry,
21637 +                             const struct vfsmount *mnt,
21638 +                             struct inode *inode,
21639 +                             const int mode, const char *to);
21640 +
21641 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
21642 +extern int gr_is_capable_nolog(const int cap);
21643 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
21644 +                             const unsigned long wanted, const int gt);
21645 +extern void gr_copy_label(struct task_struct *tsk);
21646 +extern void gr_handle_crash(struct task_struct *task, const int sig);
21647 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
21648 +extern int gr_check_crash_uid(const uid_t uid);
21649 +extern int gr_check_protected_task(const struct task_struct *task);
21650 +extern int gr_acl_handle_mmap(const struct file *file,
21651 +                             const unsigned long prot);
21652 +extern int gr_acl_handle_mprotect(const struct file *file,
21653 +                                 const unsigned long prot);
21654 +extern int gr_check_hidden_task(const struct task_struct *tsk);
21655 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
21656 +                                   const struct vfsmount *mnt);
21657 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
21658 +                                const struct vfsmount *mnt);
21659 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
21660 +                                 const struct vfsmount *mnt, const int fmode);
21661 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
21662 +                                 const struct vfsmount *mnt, mode_t mode);
21663 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
21664 +                                const struct vfsmount *mnt, mode_t mode);
21665 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
21666 +                                const struct vfsmount *mnt);
21667 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
21668 +extern int gr_handle_proc_ptrace(struct task_struct *task);
21669 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
21670 +                                 const struct vfsmount *mnt);
21671 +extern int gr_check_crash_exec(const struct file *filp);
21672 +extern int gr_acl_is_enabled(void);
21673 +extern void gr_set_kernel_label(struct task_struct *task);
21674 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
21675 +                             const gid_t gid);
21676 +extern int gr_set_proc_label(const struct dentry *dentry,
21677 +                             const struct vfsmount *mnt);
21678 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
21679 +                                      const struct vfsmount *mnt);
21680 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
21681 +                               const struct vfsmount *mnt, const int fmode);
21682 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
21683 +                                const struct dentry *p_dentry,
21684 +                                const struct vfsmount *p_mnt, const int fmode,
21685 +                                const int imode);
21686 +extern void gr_handle_create(const struct dentry *dentry,
21687 +                            const struct vfsmount *mnt);
21688 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
21689 +                                const struct dentry *parent_dentry,
21690 +                                const struct vfsmount *parent_mnt,
21691 +                                const int mode);
21692 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
21693 +                                const struct dentry *parent_dentry,
21694 +                                const struct vfsmount *parent_mnt);
21695 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
21696 +                                const struct vfsmount *mnt);
21697 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
21698 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
21699 +                                 const struct vfsmount *mnt);
21700 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
21701 +                                  const struct dentry *parent_dentry,
21702 +                                  const struct vfsmount *parent_mnt,
21703 +                                  const char *from);
21704 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
21705 +                               const struct dentry *parent_dentry,
21706 +                               const struct vfsmount *parent_mnt,
21707 +                               const struct dentry *old_dentry,
21708 +                               const struct vfsmount *old_mnt, const char *to);
21709 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
21710 +                               struct dentry *parent_dentry,
21711 +                               const struct vfsmount *parent_mnt,
21712 +                               struct dentry *old_dentry,
21713 +                               struct inode *old_parent_inode,
21714 +                               struct vfsmount *old_mnt, const char *newname);
21715 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
21716 +                               struct dentry *old_dentry,
21717 +                               struct dentry *new_dentry,
21718 +                               struct vfsmount *mnt, const __u8 replace);
21719 +extern __u32 gr_check_link(const struct dentry *new_dentry,
21720 +                          const struct dentry *parent_dentry,
21721 +                          const struct vfsmount *parent_mnt,
21722 +                          const struct dentry *old_dentry,
21723 +                          const struct vfsmount *old_mnt);
21724 +extern int gr_acl_handle_filldir(const struct file *file, const char *name,
21725 +                                const unsigned int namelen, const ino_t ino);
21726 +
21727 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
21728 +                               const struct vfsmount *mnt);
21729 +extern void gr_acl_handle_exit(void);
21730 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
21731 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
21732 +extern __u32 gr_cap_rtnetlink(void);
21733 +
21734 +#ifdef CONFIG_SYSVIPC
21735 +extern void gr_shm_exit(struct task_struct *task);
21736 +#else
21737 +static inline void gr_shm_exit(struct task_struct *task)
21738 +{
21739 +       return;
21740 +}
21741 +#endif
21742 +
21743 +#ifdef CONFIG_GRKERNSEC
21744 +extern void gr_handle_mem_write(void);
21745 +extern void gr_handle_kmem_write(void);
21746 +extern void gr_handle_open_port(void);
21747 +extern int gr_handle_mem_mmap(const unsigned long offset,
21748 +                             struct vm_area_struct *vma);
21749 +
21750 +extern unsigned long pax_get_random_long(void);
21751 +#define get_random_long() pax_get_random_long()
21752 +
21753 +extern int grsec_enable_dmesg;
21754 +extern int grsec_enable_randsrc;
21755 +extern int grsec_enable_shm;
21756 +#endif
21757 +
21758 +#endif
21759 diff -urNp linux-2.6.17.7/include/linux/highmem.h linux-2.6.17.7/include/linux/highmem.h
21760 --- linux-2.6.17.7/include/linux/highmem.h      2006-07-24 23:36:01.000000000 -0400
21761 +++ linux-2.6.17.7/include/linux/highmem.h      2006-08-01 20:29:48.000000000 -0400
21762 @@ -70,9 +70,9 @@ alloc_zeroed_user_highpage(struct vm_are
21763  
21764  static inline void clear_highpage(struct page *page)
21765  {
21766 -       void *kaddr = kmap_atomic(page, KM_USER0);
21767 +       void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
21768         clear_page(kaddr);
21769 -       kunmap_atomic(kaddr, KM_USER0);
21770 +       kunmap_atomic(kaddr, KM_CLEARPAGE);
21771  }
21772  
21773  /*
21774 diff -urNp linux-2.6.17.7/include/linux/mm.h linux-2.6.17.7/include/linux/mm.h
21775 --- linux-2.6.17.7/include/linux/mm.h   2006-07-24 23:36:01.000000000 -0400
21776 +++ linux-2.6.17.7/include/linux/mm.h   2006-08-01 20:29:48.000000000 -0400
21777 @@ -38,6 +38,7 @@ extern int sysctl_legacy_va_layout;
21778  #include <asm/pgtable.h>
21779  #include <asm/processor.h>
21780  #include <asm/atomic.h>
21781 +#include <asm/mman.h>
21782  
21783  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
21784  
21785 @@ -111,8 +112,43 @@ struct vm_area_struct {
21786  #ifdef CONFIG_NUMA
21787         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
21788  #endif
21789 +
21790 +       unsigned long vm_mirror;        /* PaX: mirror distance */
21791  };
21792  
21793 +#ifdef CONFIG_PAX_SOFTMODE
21794 +extern unsigned int pax_softmode;
21795 +#endif
21796 +
21797 +extern int pax_check_flags(unsigned long *);
21798 +
21799 +/* if tsk != current then task_lock must be held on it */
21800 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21801 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
21802 +{
21803 +       if (likely(tsk->mm))
21804 +               return tsk->mm->pax_flags;
21805 +       else
21806 +               return 0UL;
21807 +}
21808 +
21809 +/* if tsk != current then task_lock must be held on it */
21810 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
21811 +{
21812 +       if (likely(tsk->mm)) {
21813 +               tsk->mm->pax_flags = flags;
21814 +               return 0;
21815 +       }
21816 +       return -EINVAL;
21817 +}
21818 +#endif
21819 +
21820 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
21821 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
21822 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
21823 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
21824 +#endif
21825 +
21826  /*
21827   * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
21828   * disabled, then there's a single shared list of VMAs maintained by the
21829 @@ -167,6 +203,18 @@ extern unsigned int kobjsize(const void 
21830  #define VM_MAPPED_COPY 0x01000000      /* T if mapped copy of data (nommu mmap) */
21831  #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
21832  
21833 +#ifdef CONFIG_PAX_SEGMEXEC
21834 +#define VM_MIRROR      0x04000000      /* vma is mirroring another */
21835 +#endif
21836 +
21837 +#ifdef CONFIG_PAX_MPROTECT
21838 +#define VM_MAYNOTWRITE 0x08000000      /* vma cannot be granted VM_WRITE any more */
21839 +#endif
21840 +
21841 +#ifdef __VM_STACK_FLAGS
21842 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
21843 +#endif
21844 +
21845  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
21846  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
21847  #endif
21848 @@ -1058,5 +1106,11 @@ void drop_slab(void);
21849  extern int randomize_va_space;
21850  #endif
21851  
21852 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
21853 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
21854 +#else
21855 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
21856 +#endif
21857 +
21858  #endif /* __KERNEL__ */
21859  #endif /* _LINUX_MM_H */
21860 diff -urNp linux-2.6.17.7/include/linux/mman.h linux-2.6.17.7/include/linux/mman.h
21861 --- linux-2.6.17.7/include/linux/mman.h 2006-07-24 23:36:01.000000000 -0400
21862 +++ linux-2.6.17.7/include/linux/mman.h 2006-08-01 20:29:48.000000000 -0400
21863 @@ -59,6 +59,11 @@ static inline unsigned long
21864  calc_vm_flag_bits(unsigned long flags)
21865  {
21866         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
21867 +
21868 +#ifdef CONFIG_PAX_SEGMEXEC
21869 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
21870 +#endif
21871 +
21872                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
21873                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
21874                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
21875 diff -urNp linux-2.6.17.7/include/linux/module.h linux-2.6.17.7/include/linux/module.h
21876 --- linux-2.6.17.7/include/linux/module.h       2006-07-24 23:36:01.000000000 -0400
21877 +++ linux-2.6.17.7/include/linux/module.h       2006-08-01 20:29:48.000000000 -0400
21878 @@ -273,16 +273,16 @@ struct module
21879         int (*init)(void);
21880  
21881         /* If this is non-NULL, vfree after init() returns */
21882 -       void *module_init;
21883 +       void *module_init_rx, *module_init_rw;
21884  
21885         /* Here is the actual code + data, vfree'd on unload. */
21886 -       void *module_core;
21887 +       void *module_core_rx, *module_core_rw;
21888  
21889         /* Here are the sizes of the init and core sections */
21890 -       unsigned long init_size, core_size;
21891 +       unsigned long init_size_rw, core_size_rw;
21892  
21893         /* The size of the executable code in each section.  */
21894 -       unsigned long init_text_size, core_text_size;
21895 +       unsigned long init_size_rx, core_size_rx;
21896  
21897         /* Arch-specific module values */
21898         struct mod_arch_specific arch;
21899 diff -urNp linux-2.6.17.7/include/linux/moduleloader.h linux-2.6.17.7/include/linux/moduleloader.h
21900 --- linux-2.6.17.7/include/linux/moduleloader.h 2006-07-24 23:36:01.000000000 -0400
21901 +++ linux-2.6.17.7/include/linux/moduleloader.h 2006-08-01 20:29:48.000000000 -0400
21902 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
21903     sections.  Returns NULL on failure. */
21904  void *module_alloc(unsigned long size);
21905  
21906 +#ifdef CONFIG_PAX_KERNEXEC
21907 +void *module_alloc_exec(unsigned long size);
21908 +#else
21909 +#define module_alloc_exec(x) module_alloc(x)
21910 +#endif
21911 +
21912  /* Free memory returned from module_alloc. */
21913  void module_free(struct module *mod, void *module_region);
21914  
21915 +#ifdef CONFIG_PAX_KERNEXEC
21916 +void module_free_exec(struct module *mod, void *module_region);
21917 +#else
21918 +#define module_free_exec(x, y) module_free(x, y)
21919 +#endif
21920 +
21921  /* Apply the given relocation to the (simplified) ELF.  Return -error
21922     or 0. */
21923  int apply_relocate(Elf_Shdr *sechdrs,
21924 diff -urNp linux-2.6.17.7/include/linux/random.h linux-2.6.17.7/include/linux/random.h
21925 --- linux-2.6.17.7/include/linux/random.h       2006-07-24 23:36:01.000000000 -0400
21926 +++ linux-2.6.17.7/include/linux/random.h       2006-08-01 20:29:48.000000000 -0400
21927 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
21928  extern u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
21929                                        __u16 sport, __u16 dport);
21930  
21931 +extern unsigned long pax_get_random_long(void);
21932 +
21933  #ifndef MODULE
21934  extern struct file_operations random_fops, urandom_fops;
21935  #endif
21936 diff -urNp linux-2.6.17.7/include/linux/sched.h linux-2.6.17.7/include/linux/sched.h
21937 --- linux-2.6.17.7/include/linux/sched.h        2006-07-24 23:36:01.000000000 -0400
21938 +++ linux-2.6.17.7/include/linux/sched.h        2006-08-01 20:29:48.000000000 -0400
21939 @@ -40,6 +40,7 @@
21940  #include <linux/auxvec.h>      /* For AT_VECTOR_SIZE */
21941  
21942  struct exec_domain;
21943 +struct linux_binprm;
21944  
21945  /*
21946   * cloning flags:
21947 @@ -350,8 +351,34 @@ struct mm_struct {
21948         /* aio bits */
21949         rwlock_t                ioctx_list_lock;
21950         struct kioctx           *ioctx_list;
21951 +
21952 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21953 +       unsigned long pax_flags;
21954 +#endif
21955 +
21956 +#ifdef CONFIG_PAX_DLRESOLVE
21957 +       unsigned long call_dl_resolve;
21958 +#endif
21959 +
21960 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
21961 +       unsigned long call_syscall;
21962 +#endif
21963 +
21964 +#ifdef CONFIG_PAX_ASLR
21965 +       unsigned long delta_mmap;               /* randomized offset */
21966 +       unsigned long delta_exec;               /* randomized offset */
21967 +       unsigned long delta_stack;              /* randomized offset */
21968 +#endif
21969 +
21970  };
21971  
21972 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
21973 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
21974 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
21975 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
21976 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
21977 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
21978 +
21979  struct sighand_struct {
21980         atomic_t                count;
21981         struct k_sigaction      action[_NSIG];
21982 @@ -449,6 +476,15 @@ struct signal_struct {
21983         struct key *session_keyring;    /* keyring inherited over fork */
21984         struct key *process_keyring;    /* keyring private to this process */
21985  #endif
21986 +
21987 +#ifdef CONFIG_GRKERNSEC
21988 +       u32 curr_ip;
21989 +       u32 gr_saddr;
21990 +       u32 gr_daddr;
21991 +       u16 gr_sport;
21992 +       u16 gr_dport;
21993 +       u8 used_accept:1;
21994 +#endif
21995  };
21996  
21997  /* Context switch must be unlocked if interrupts are to be enabled */
21998 @@ -881,6 +917,17 @@ struct task_struct {
21999         struct compat_robust_list_head __user *compat_robust_list;
22000  #endif
22001  
22002 +#ifdef CONFIG_GRKERNSEC
22003 +       /* grsecurity */
22004 +       struct acl_subject_label *acl;
22005 +       struct acl_role_label *role;
22006 +       struct file *exec_file;
22007 +       u16 acl_role_id;
22008 +       u8 acl_sp_role:1;
22009 +       u8 is_writable:1;
22010 +       u8 brute:1;
22011 +#endif
22012 +
22013         atomic_t fs_excl;       /* holding fs exclusive resources */
22014         struct rcu_head rcu;
22015  
22016 @@ -1393,6 +1440,12 @@ extern void arch_pick_mmap_layout(struct
22017  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
22018  {
22019         mm->mmap_base = TASK_UNMAPPED_BASE;
22020 +
22021 +#ifdef CONFIG_PAX_RANDMMAP
22022 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
22023 +               mm->mmap_base += mm->delta_mmap;
22024 +#endif
22025 +
22026         mm->get_unmapped_area = arch_get_unmapped_area;
22027         mm->unmap_area = arch_unmap_area;
22028  }
22029 diff -urNp linux-2.6.17.7/include/linux/shm.h linux-2.6.17.7/include/linux/shm.h
22030 --- linux-2.6.17.7/include/linux/shm.h  2006-07-24 23:36:01.000000000 -0400
22031 +++ linux-2.6.17.7/include/linux/shm.h  2006-08-01 20:29:48.000000000 -0400
22032 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
22033         pid_t                   shm_cprid;
22034         pid_t                   shm_lprid;
22035         struct user_struct      *mlock_user;
22036 +#ifdef CONFIG_GRKERNSEC
22037 +       time_t                  shm_createtime;
22038 +       pid_t                   shm_lapid;
22039 +#endif
22040  };
22041  
22042  /* shm_mode upper byte flags */
22043 diff -urNp linux-2.6.17.7/include/linux/sysctl.h linux-2.6.17.7/include/linux/sysctl.h
22044 --- linux-2.6.17.7/include/linux/sysctl.h       2006-07-24 23:36:01.000000000 -0400
22045 +++ linux-2.6.17.7/include/linux/sysctl.h       2006-08-01 20:29:48.000000000 -0400
22046 @@ -78,9 +78,22 @@
22047         INOTIFY_MAX_QUEUED_EVENTS=3     /* max queued events per instance */
22048  };
22049  
22050 +#ifdef CONFIG_PAX_SOFTMODE
22051 +enum {
22052 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
22053 +};
22054 +#endif
22055 +
22056  /* CTL_KERN names: */
22057  enum
22058  {
22059 +#ifdef CONFIG_GRKERNSEC
22060 +       KERN_GRSECURITY=98,     /* grsecurity */
22061 +#endif
22062 +
22063 +#ifdef CONFIG_PAX_SOFTMODE
22064 +       KERN_PAX=99,            /* PaX control */
22065 +#endif
22066         KERN_OSTYPE=1,          /* string: system version */
22067         KERN_OSRELEASE=2,       /* string: system release */
22068         KERN_OSREV=3,           /* int: system revision */
22069 diff -urNp linux-2.6.17.7/init/Kconfig linux-2.6.17.7/init/Kconfig
22070 --- linux-2.6.17.7/init/Kconfig 2006-07-24 23:36:01.000000000 -0400
22071 +++ linux-2.6.17.7/init/Kconfig 2006-08-01 20:29:48.000000000 -0400
22072 @@ -268,6 +268,7 @@ menuconfig EMBEDDED
22073  config KALLSYMS
22074          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
22075          default y
22076 +        depends on !GRKERNSEC_HIDESYM
22077          help
22078            Say Y here to let the kernel print out symbolic crash information and
22079            symbolic stack backtraces. This increases the size of the kernel
22080 diff -urNp linux-2.6.17.7/init/main.c linux-2.6.17.7/init/main.c
22081 --- linux-2.6.17.7/init/main.c  2006-07-24 23:36:01.000000000 -0400
22082 +++ linux-2.6.17.7/init/main.c  2006-08-01 20:29:48.000000000 -0400
22083 @@ -100,6 +100,7 @@ static inline void mark_rodata_ro(void) 
22084  #ifdef CONFIG_TC
22085  extern void tc_init(void);
22086  #endif
22087 +extern void grsecurity_init(void);
22088  
22089  enum system_states system_state;
22090  EXPORT_SYMBOL(system_state);
22091 @@ -150,6 +151,15 @@ static int __init maxcpus(char *str)
22092  
22093  __setup("maxcpus=", maxcpus);
22094  
22095 +#ifdef CONFIG_PAX_SOFTMODE
22096 +static int __init setup_pax_softmode(char *str)
22097 +{
22098 +       get_option(&str, &pax_softmode);
22099 +       return 1;
22100 +}
22101 +__setup("pax_softmode=", setup_pax_softmode);
22102 +#endif
22103 +
22104  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
22105  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
22106  static const char *panic_later, *panic_param;
22107 @@ -692,6 +702,8 @@ static int init(void * unused)
22108                 prepare_namespace();
22109         }
22110  
22111 +       grsecurity_init();
22112 +
22113         /*
22114          * Ok, we have completed the initial bootup, and
22115          * we're essentially up and running. Get rid of the
22116 diff -urNp linux-2.6.17.7/ipc/msg.c linux-2.6.17.7/ipc/msg.c
22117 --- linux-2.6.17.7/ipc/msg.c    2006-07-24 23:36:01.000000000 -0400
22118 +++ linux-2.6.17.7/ipc/msg.c    2006-08-01 20:29:48.000000000 -0400
22119 @@ -32,6 +32,7 @@
22120  #include <linux/audit.h>
22121  #include <linux/seq_file.h>
22122  #include <linux/mutex.h>
22123 +#include <linux/grsecurity.h>
22124  
22125  #include <asm/current.h>
22126  #include <asm/uaccess.h>
22127 @@ -237,6 +238,9 @@ asmlinkage long sys_msgget (key_t key, i
22128                 msg_unlock(msq);
22129         }
22130         mutex_unlock(&msg_ids.mutex);
22131 +
22132 +       gr_log_msgget(ret, msgflg);
22133 +
22134         return ret;
22135  }
22136  
22137 @@ -495,6 +499,8 @@ asmlinkage long sys_msgctl (int msqid, i
22138                 break;
22139         }
22140         case IPC_RMID:
22141 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
22142 +
22143                 freeque (msq, msqid); 
22144                 break;
22145         }
22146 diff -urNp linux-2.6.17.7/ipc/sem.c linux-2.6.17.7/ipc/sem.c
22147 --- linux-2.6.17.7/ipc/sem.c    2006-07-24 23:36:01.000000000 -0400
22148 +++ linux-2.6.17.7/ipc/sem.c    2006-08-01 20:29:48.000000000 -0400
22149 @@ -79,6 +79,7 @@
22150  #include <linux/seq_file.h>
22151  #include <linux/mutex.h>
22152  #include <linux/vs_limit.h>
22153 +#include <linux/grsecurity.h>
22154  
22155  #include <asm/uaccess.h>
22156  #include "util.h"
22157 @@ -247,6 +248,9 @@ asmlinkage long sys_semget (key_t key, i
22158         }
22159  
22160         mutex_unlock(&sem_ids.mutex);
22161 +
22162 +       gr_log_semget(err, semflg);
22163 +
22164         return err;
22165  }
22166  
22167 @@ -840,6 +844,8 @@ static int semctl_down(int semid, int se
22168  
22169         switch(cmd){
22170         case IPC_RMID:
22171 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
22172 +
22173                 freeary(sma, semid);
22174                 err = 0;
22175                 break;
22176 diff -urNp linux-2.6.17.7/ipc/shm.c linux-2.6.17.7/ipc/shm.c
22177 --- linux-2.6.17.7/ipc/shm.c    2006-07-24 23:36:01.000000000 -0400
22178 +++ linux-2.6.17.7/ipc/shm.c    2006-08-01 20:29:48.000000000 -0400
22179 @@ -33,6 +33,7 @@
22180  #include <linux/mutex.h>
22181  #include <linux/vs_context.h>
22182  #include <linux/vs_limit.h>
22183 +#include <linux/grsecurity.h>
22184  
22185  #include <asm/uaccess.h>
22186  
22187 @@ -56,6 +57,14 @@ static void shm_close (struct vm_area_st
22188  static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
22189  #endif
22190  
22191 +#ifdef CONFIG_GRKERNSEC
22192 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22193 +                          const time_t shm_createtime, const uid_t cuid,
22194 +                          const int shmid);
22195 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22196 +                          const time_t shm_createtime);
22197 +#endif
22198 +
22199  size_t shm_ctlmax = SHMMAX;
22200  size_t         shm_ctlall = SHMALL;
22201  int    shm_ctlmni = SHMMNI;
22202 @@ -149,6 +158,17 @@ static void shm_close (struct vm_area_st
22203         shp->shm_lprid = current->tgid;
22204         shp->shm_dtim = get_seconds();
22205         shp->shm_nattch--;
22206 +#ifdef CONFIG_GRKERNSEC_SHM
22207 +       if (grsec_enable_shm) {
22208 +               if (shp->shm_nattch == 0) {
22209 +                       shp->shm_perm.mode |= SHM_DEST;
22210 +                       shm_destroy(shp);
22211 +               } else
22212 +                       shm_unlock(shp);
22213 +               mutex_unlock(&shm_ids.mutex);
22214 +               return;
22215 +       }
22216 +#endif
22217         if(shp->shm_nattch == 0 &&
22218            shp->shm_perm.mode & SHM_DEST)
22219                 shm_destroy (shp);
22220 @@ -248,6 +268,9 @@ static int newseg (key_t key, int shmflg
22221         shp->shm_lprid = 0;
22222         shp->shm_atim = shp->shm_dtim = 0;
22223         shp->shm_ctim = get_seconds();
22224 +#ifdef CONFIG_GRKERNSEC
22225 +       shp->shm_createtime = get_seconds();
22226 +#endif
22227         shp->shm_segsz = size;
22228         shp->shm_nattch = 0;
22229         shp->id = shm_buildid(id,shp->shm_perm.seq);
22230 @@ -302,6 +325,8 @@ asmlinkage long sys_shmget (key_t key, s
22231         }
22232         mutex_unlock(&shm_ids.mutex);
22233  
22234 +       gr_log_shmget(err, shmflg, size);
22235 +
22236         return err;
22237  }
22238  
22239 @@ -615,6 +640,8 @@ asmlinkage long sys_shmctl (int shmid, i
22240                 if (err)
22241                         goto out_unlock_up;
22242  
22243 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
22244 +
22245                 if (shp->shm_nattch){
22246                         shp->shm_perm.mode |= SHM_DEST;
22247                         /* Do not find it any more */
22248 @@ -763,9 +790,27 @@ long do_shmat(int shmid, char __user *sh
22249                 return err;
22250         }
22251                 
22252 +#ifdef CONFIG_GRKERNSEC
22253 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
22254 +                            shp->shm_perm.cuid, shmid)) {
22255 +               shm_unlock(shp);
22256 +               return -EACCES;
22257 +       }
22258 +
22259 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
22260 +               shm_unlock(shp);
22261 +               return -EACCES;
22262 +       }
22263 +#endif
22264 +
22265         file = shp->shm_file;
22266         size = i_size_read(file->f_dentry->d_inode);
22267         shp->shm_nattch++;
22268 +
22269 +#ifdef CONFIG_GRKERNSEC
22270 +       shp->shm_lapid = current->pid;
22271 +#endif
22272 +
22273         shm_unlock(shp);
22274  
22275         down_write(&current->mm->mmap_sem);
22276 @@ -935,3 +980,24 @@ static int sysvipc_shm_proc_show(struct 
22277                           shp->shm_ctim);
22278  }
22279  #endif
22280 +
22281 +void gr_shm_exit(struct task_struct *task)
22282 +{
22283 +#ifdef CONFIG_GRKERNSEC_SHM
22284 +       int i;
22285 +       struct shmid_kernel *shp;
22286 +
22287 +       if (!grsec_enable_shm)
22288 +               return;
22289 +
22290 +       for (i = 0; i <= shm_ids.max_id; i++) {
22291 +               shp = shm_get(i);
22292 +               if (shp && (shp->shm_cprid == task->pid) &&
22293 +                   (shp->shm_nattch <= 0)) {
22294 +                       shp->shm_perm.mode |= SHM_DEST;
22295 +                       shm_destroy(shp);
22296 +               }
22297 +       }
22298 +#endif
22299 +       return;
22300 +}
22301 diff -urNp linux-2.6.17.7/kernel/capability.c linux-2.6.17.7/kernel/capability.c
22302 --- linux-2.6.17.7/kernel/capability.c  2006-07-24 23:36:01.000000000 -0400
22303 +++ linux-2.6.17.7/kernel/capability.c  2006-08-01 20:29:48.000000000 -0400
22304 @@ -12,6 +12,7 @@
22305  #include <linux/security.h>
22306  #include <linux/syscalls.h>
22307  #include <linux/vs_pid.h>
22308 +#include <linux/grsecurity.h>
22309  #include <asm/uaccess.h>
22310  
22311  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
22312 @@ -234,14 +235,25 @@ out:
22313       return ret;
22314  }
22315  
22316 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
22317 +extern int gr_is_capable_nolog(const int cap);
22318 +
22319  int __capable(struct task_struct *t, int cap)
22320  {
22321 -       if (security_capable(t, cap) == 0) {
22322 +       if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
22323                 t->flags |= PF_SUPERPRIV;
22324                 return 1;
22325         }
22326         return 0;
22327  }
22328 +int capable_nolog(int cap)
22329 +{
22330 +       if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
22331 +               current->flags |= PF_SUPERPRIV;
22332 +               return 1;
22333 +       }
22334 +       return 0;
22335 +}
22336  EXPORT_SYMBOL(__capable);
22337  
22338  int capable(int cap)
22339 @@ -249,4 +261,5 @@ int capable(int cap)
22340         return __capable(current, cap);
22341  }
22342  EXPORT_SYMBOL(capable);
22343 +EXPORT_SYMBOL(capable_nolog);
22344  
22345 diff -urNp linux-2.6.17.7/kernel/configs.c linux-2.6.17.7/kernel/configs.c
22346 --- linux-2.6.17.7/kernel/configs.c     2006-07-24 23:36:01.000000000 -0400
22347 +++ linux-2.6.17.7/kernel/configs.c     2006-08-01 20:29:48.000000000 -0400
22348 @@ -89,8 +89,16 @@ static int __init ikconfig_init(void)
22349         struct proc_dir_entry *entry;
22350  
22351         /* create the current config file */
22352 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
22353 +#ifdef CONFIG_GRKERNSEC_PROC_USER
22354 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
22355 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22356 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
22357 +#endif
22358 +#else
22359         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
22360                                   &proc_root);
22361 +#endif
22362         if (!entry)
22363                 return -ENOMEM;
22364  
22365 diff -urNp linux-2.6.17.7/kernel/exit.c linux-2.6.17.7/kernel/exit.c
22366 --- linux-2.6.17.7/kernel/exit.c        2006-07-24 23:36:01.000000000 -0400
22367 +++ linux-2.6.17.7/kernel/exit.c        2006-08-01 20:29:48.000000000 -0400
22368 @@ -41,5 +41,10 @@
22369  #include <linux/vs_network.h>
22370  #include <linux/vs_pid.h>
22371 +#include <linux/grsecurity.h>
22372 +
22373 +#ifdef CONFIG_GRKERNSEC
22374 +extern rwlock_t grsec_exec_file_lock;
22375 +#endif
22376  
22377  #include <asm/uaccess.h>
22378  #include <asm/unistd.h>
22379 @@ -115,6 +120,7 @@ static void __exit_signal(struct task_st
22380  
22381         __unhash_process(tsk);
22382  
22383 +       gr_del_task_from_ip_table(tsk);
22384         tsk->signal = NULL;
22385         tsk->sighand = NULL;
22386         spin_unlock(&sighand->siglock);
22387 @@ -287,6 +293,15 @@ static void reparent_to_init(void)
22388  {
22389         write_lock_irq(&tasklist_lock);
22390  
22391 +#ifdef CONFIG_GRKERNSEC
22392 +       write_lock(&grsec_exec_file_lock);
22393 +       if (current->exec_file) {
22394 +               fput(current->exec_file);
22395 +               current->exec_file = NULL;
22396 +       }
22397 +       write_unlock(&grsec_exec_file_lock);
22398 +#endif
22399 +
22400         ptrace_unlink(current);
22401         /* Reparent to init */
22402         remove_parent(current);
22403 @@ -294,6 +309,8 @@ static void reparent_to_init(void)
22404         current->real_parent = child_reaper;
22405         add_parent(current);
22406  
22407 +       gr_set_kernel_label(current);
22408 +
22409         /* Set the exit signal to SIGCHLD so we signal init on exit */
22410         current->exit_signal = SIGCHLD;
22411  
22412 @@ -390,6 +407,17 @@ void daemonize(const char *name, ...)
22413         vsnprintf(current->comm, sizeof(current->comm), name, args);
22414         va_end(args);
22415  
22416 +#ifdef CONFIG_GRKERNSEC
22417 +       write_lock(&grsec_exec_file_lock);
22418 +       if (current->exec_file) {
22419 +               fput(current->exec_file);
22420 +               current->exec_file = NULL;
22421 +       }
22422 +       write_unlock(&grsec_exec_file_lock);
22423 +#endif
22424 +
22425 +       gr_set_kernel_label(current);
22426 +
22427         /*
22428          * If we were started as result of loading a module, close all of the
22429          * user space pages.  We don't need them, and if we didn't close them
22430 @@ -905,9 +933,14 @@ fastcall NORET_TYPE void do_exit(long co
22431  #endif
22432         if (unlikely(tsk->audit_context))
22433                 audit_free(tsk);
22434 +
22435 +       gr_acl_handle_psacct(tsk, code);
22436 +       gr_acl_handle_exit();
22437 +
22438         exit_mm(tsk);
22439  
22440         exit_sem(tsk);
22441 +       gr_shm_exit(tsk);
22442         __exit_files(tsk);
22443         __exit_fs(tsk);
22444         exit_namespace(tsk);
22445 diff -urNp linux-2.6.17.7/kernel/fork.c linux-2.6.17.7/kernel/fork.c
22446 --- linux-2.6.17.7/kernel/fork.c        2006-07-24 23:36:01.000000000 -0400
22447 +++ linux-2.6.17.7/kernel/fork.c        2006-08-01 20:29:48.000000000 -0400
22448 @@ -44,6 +44,7 @@
22449  #include <linux/vs_network.h>
22450  #include <linux/vs_limit.h>
22451  #include <linux/vs_memory.h>
22452 +#include <linux/grsecurity.h>
22453  
22454  #include <asm/pgtable.h>
22455  #include <asm/pgalloc.h>
22456 @@ -198,8 +199,8 @@ static inline int dup_mmap(struct mm_str
22457         mm->locked_vm = 0;
22458         mm->mmap = NULL;
22459         mm->mmap_cache = NULL;
22460 -       mm->free_area_cache = oldmm->mmap_base;
22461 -       mm->cached_hole_size = ~0UL;
22462 +       mm->free_area_cache = oldmm->free_area_cache;
22463 +       mm->cached_hole_size = oldmm->cached_hole_size;
22464         mm->map_count = 0;
22465         cpus_clear(mm->cpu_vm_mask);
22466         mm->mm_rb = RB_ROOT;
22467 @@ -324,7 +325,7 @@ static struct mm_struct * mm_init(struct
22468         spin_lock_init(&mm->page_table_lock);
22469         rwlock_init(&mm->ioctx_list_lock);
22470         mm->ioctx_list = NULL;
22471 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
22472 +       mm->free_area_cache = ~0UL;
22473         mm->cached_hole_size = ~0UL;
22474  
22475         if (likely(!mm_alloc_pgd(mm))) {
22476 @@ -956,6 +957,8 @@ static task_t *copy_process(unsigned lon
22477         if (!vx_nproc_avail(1))
22478                 goto bad_fork_cleanup_vm;
22479  
22480 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
22481 +
22482         if (atomic_read(&p->user->processes) >=
22483                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
22484                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
22485 @@ -1066,6 +1070,8 @@ static task_t *copy_process(unsigned lon
22486         if (retval)
22487                 goto bad_fork_cleanup_namespace;
22488  
22489 +       gr_copy_label(p);
22490 +
22491         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
22492         /*
22493          * Clear TID on mm_release()?
22494 @@ -1255,6 +1261,8 @@ bad_fork_cleanup_count:
22495  bad_fork_free:
22496         free_task(p);
22497  fork_out:
22498 +       gr_log_forkfail(retval);
22499 +
22500         return ERR_PTR(retval);
22501  }
22502  
22503 @@ -1328,6 +1336,8 @@ long do_fork(unsigned long clone_flags,
22504         if (!IS_ERR(p)) {
22505                 struct completion vfork;
22506  
22507 +               gr_handle_brute_check();
22508 +
22509                 if (clone_flags & CLONE_VFORK) {
22510                         p->vfork_done = &vfork;
22511                         init_completion(&vfork);
22512 diff -urNp linux-2.6.17.7/kernel/futex.c linux-2.6.17.7/kernel/futex.c
22513 --- linux-2.6.17.7/kernel/futex.c       2006-07-24 23:36:01.000000000 -0400
22514 +++ linux-2.6.17.7/kernel/futex.c       2006-08-01 20:29:48.000000000 -0400
22515 @@ -151,6 +151,11 @@ static int get_futex_key(unsigned long u
22516         struct page *page;
22517         int err;
22518  
22519 +#ifdef CONFIG_PAX_SEGMEXEC
22520 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (uaddr >= SEGMEXEC_TASK_SIZE))
22521 +               return -EFAULT;
22522 +#endif
22523 +
22524         /*
22525          * The futex address must be "naturally" aligned.
22526          */
22527 diff -urNp linux-2.6.17.7/kernel/kallsyms.c linux-2.6.17.7/kernel/kallsyms.c
22528 --- linux-2.6.17.7/kernel/kallsyms.c    2006-07-24 23:36:01.000000000 -0400
22529 +++ linux-2.6.17.7/kernel/kallsyms.c    2006-08-01 20:29:48.000000000 -0400
22530 @@ -301,7 +301,6 @@ static unsigned long get_ksymbol_core(st
22531  
22532  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
22533  {
22534 -       iter->name[0] = '\0';
22535         iter->nameoff = get_symbol_offset(new_pos);
22536         iter->pos = new_pos;
22537  }
22538 @@ -380,7 +379,7 @@ static int kallsyms_open(struct inode *i
22539         struct kallsym_iter *iter;
22540         int ret;
22541  
22542 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
22543 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
22544         if (!iter)
22545                 return -ENOMEM;
22546         reset_iter(iter, 0);
22547 @@ -411,7 +410,15 @@ static int __init kallsyms_init(void)
22548  {
22549         struct proc_dir_entry *entry;
22550  
22551 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
22552 +#ifdef CONFIG_GRKERNSEC_PROC_USER
22553 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
22554 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22555 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
22556 +#endif
22557 +#else
22558         entry = create_proc_entry("kallsyms", 0444, NULL);
22559 +#endif
22560         if (entry)
22561                 entry->proc_fops = &kallsyms_operations;
22562         return 0;
22563 diff -urNp linux-2.6.17.7/kernel/kprobes.c linux-2.6.17.7/kernel/kprobes.c
22564 --- linux-2.6.17.7/kernel/kprobes.c     2006-07-24 23:36:01.000000000 -0400
22565 +++ linux-2.6.17.7/kernel/kprobes.c     2006-08-01 20:29:48.000000000 -0400
22566 @@ -106,7 +106,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
22567          * kernel image and loaded module images reside. This is required
22568          * so x86_64 can correctly handle the %rip-relative fixups.
22569          */
22570 -       kip->insns = module_alloc(PAGE_SIZE);
22571 +       kip->insns = module_alloc_exec(PAGE_SIZE);
22572         if (!kip->insns) {
22573                 kfree(kip);
22574                 return NULL;
22575 diff -urNp linux-2.6.17.7/kernel/module.c linux-2.6.17.7/kernel/module.c
22576 --- linux-2.6.17.7/kernel/module.c      2006-07-24 23:36:01.000000000 -0400
22577 +++ linux-2.6.17.7/kernel/module.c      2006-08-01 20:29:48.000000000 -0400
22578 @@ -40,10 +40,15 @@
22579  #include <linux/string.h>
22580  #include <linux/sched.h>
22581  #include <linux/mutex.h>
22582 +#include <linux/kallsyms.h>
22583  #include <asm/uaccess.h>
22584  #include <asm/semaphore.h>
22585  #include <asm/cacheflush.h>
22586  
22587 +#ifdef CONFIG_PAX_KERNEXEC
22588 +#include <asm/desc.h>
22589 +#endif
22590 +
22591  #if 0
22592  #define DEBUGP printk
22593  #else
22594 @@ -66,6 +71,8 @@ static LIST_HEAD(modules);
22595  
22596  static BLOCKING_NOTIFIER_HEAD(module_notify_list);
22597  
22598 +extern int gr_check_modstop(void);
22599 +
22600  int register_module_notifier(struct notifier_block * nb)
22601  {
22602         return blocking_notifier_chain_register(&module_notify_list, nb);
22603 @@ -594,6 +601,9 @@ sys_delete_module(const char __user *nam
22604         char name[MODULE_NAME_LEN];
22605         int ret, forced = 0;
22606  
22607 +       if (gr_check_modstop())
22608 +               return -EPERM;
22609 +
22610         if (!capable(CAP_SYS_MODULE))
22611                 return -EPERM;
22612  
22613 @@ -1058,13 +1068,15 @@ static void free_module(struct module *m
22614         module_unload_free(mod);
22615  
22616         /* This may be NULL, but that's OK */
22617 -       module_free(mod, mod->module_init);
22618 +       module_free(mod, mod->module_init_rw);
22619 +       module_free_exec(mod, mod->module_init_rx);
22620         kfree(mod->args);
22621         if (mod->percpu)
22622                 percpu_modfree(mod->percpu);
22623  
22624         /* Finally, free the core (containing the module structure) */
22625 -       module_free(mod, mod->module_core);
22626 +       module_free_exec(mod, mod->module_core_rx);
22627 +       module_free(mod, mod->module_core_rw);
22628  }
22629  
22630  void *__symbol_get(const char *symbol)
22631 @@ -1221,11 +1233,14 @@ static void layout_sections(struct modul
22632                             || strncmp(secstrings + s->sh_name,
22633                                        ".init", 5) == 0)
22634                                 continue;
22635 -                       s->sh_entsize = get_offset(&mod->core_size, s);
22636 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
22637 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
22638 +                       else
22639 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
22640                         DEBUGP("\t%s\n", secstrings + s->sh_name);
22641                 }
22642                 if (m == 0)
22643 -                       mod->core_text_size = mod->core_size;
22644 +                       mod->core_size_rx = mod->core_size_rx;
22645         }
22646  
22647         DEBUGP("Init section allocation order:\n");
22648 @@ -1239,12 +1254,15 @@ static void layout_sections(struct modul
22649                             || strncmp(secstrings + s->sh_name,
22650                                        ".init", 5) != 0)
22651                                 continue;
22652 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
22653 -                                        | INIT_OFFSET_MASK);
22654 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
22655 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
22656 +                       else
22657 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
22658 +                       s->sh_entsize |= INIT_OFFSET_MASK;
22659                         DEBUGP("\t%s\n", secstrings + s->sh_name);
22660                 }
22661                 if (m == 0)
22662 -                       mod->init_text_size = mod->init_size;
22663 +                       mod->init_size_rx = mod->init_size_rx;
22664         }
22665  }
22666  
22667 @@ -1419,6 +1437,10 @@ static struct module *load_module(void _
22668         struct exception_table_entry *extable;
22669         mm_segment_t old_fs;
22670  
22671 +#ifdef CONFIG_PAX_KERNEXEC
22672 +       unsigned long cr0;
22673 +#endif
22674 +
22675         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
22676                umod, len, uargs);
22677         if (len < sizeof(*hdr))
22678 @@ -1568,21 +1590,57 @@ static struct module *load_module(void _
22679         layout_sections(mod, hdr, sechdrs, secstrings);
22680  
22681         /* Do the allocs. */
22682 -       ptr = module_alloc(mod->core_size);
22683 +       ptr = module_alloc(mod->core_size_rw);
22684         if (!ptr) {
22685                 err = -ENOMEM;
22686                 goto free_percpu;
22687         }
22688 -       memset(ptr, 0, mod->core_size);
22689 -       mod->module_core = ptr;
22690 +       memset(ptr, 0, mod->core_size_rw);
22691 +       mod->module_core_rw = ptr;
22692 +
22693 +       ptr = module_alloc(mod->init_size_rw);
22694 +       if (!ptr && mod->init_size_rw) {
22695 +               err = -ENOMEM;
22696 +               goto free_core_rw;
22697 +       }
22698 +       memset(ptr, 0, mod->init_size_rw);
22699 +       mod->module_init_rw = ptr;
22700 +
22701 +       ptr = module_alloc_exec(mod->core_size_rx);
22702 +       if (!ptr) {
22703 +               err = -ENOMEM;
22704 +               goto free_init_rw;
22705 +       }
22706 +
22707 +#ifdef CONFIG_PAX_KERNEXEC
22708 +       pax_open_kernel(cr0);
22709 +#endif
22710 +
22711 +       memset(ptr, 0, mod->core_size_rx);
22712 +
22713 +#ifdef CONFIG_PAX_KERNEXEC
22714 +       pax_close_kernel(cr0);
22715 +#endif
22716 +
22717 +       mod->module_core_rx = ptr;
22718  
22719 -       ptr = module_alloc(mod->init_size);
22720 -       if (!ptr && mod->init_size) {
22721 +       ptr = module_alloc_exec(mod->init_size_rx);
22722 +       if (!ptr && mod->init_size_rx) {
22723                 err = -ENOMEM;
22724 -               goto free_core;
22725 +               goto free_core_rx;
22726         }
22727 -       memset(ptr, 0, mod->init_size);
22728 -       mod->module_init = ptr;
22729 +
22730 +#ifdef CONFIG_PAX_KERNEXEC
22731 +       pax_open_kernel(cr0);
22732 +#endif
22733 +
22734 +       memset(ptr, 0, mod->init_size_rx);
22735 +
22736 +#ifdef CONFIG_PAX_KERNEXEC
22737 +       pax_close_kernel(cr0);
22738 +#endif
22739 +
22740 +       mod->module_init_rx = ptr;
22741  
22742         /* Transfer each section which specifies SHF_ALLOC */
22743         DEBUGP("final section addresses:\n");
22744 @@ -1592,17 +1650,44 @@ static struct module *load_module(void _
22745                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
22746                         continue;
22747  
22748 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
22749 -                       dest = mod->module_init
22750 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22751 -               else
22752 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
22753 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
22754 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
22755 +                               dest = mod->module_init_rw
22756 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22757 +                       else
22758 +                               dest = mod->module_init_rx
22759 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
22760 +               } else {
22761 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
22762 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
22763 +                       else
22764 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
22765 +               }
22766 +
22767 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
22768 +
22769 +#ifdef CONFIG_PAX_KERNEXEC
22770 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
22771 +                               pax_open_kernel(cr0);
22772 +#endif
22773 +
22774 +                       memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
22775  
22776 -               if (sechdrs[i].sh_type != SHT_NOBITS)
22777 -                       memcpy(dest, (void *)sechdrs[i].sh_addr,
22778 -                              sechdrs[i].sh_size);
22779 +#ifdef CONFIG_PAX_KERNEXEC
22780 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
22781 +                               pax_close_kernel(cr0);
22782 +#endif
22783 +
22784 +               }
22785                 /* Update sh_addr to point to copy in image. */
22786 -               sechdrs[i].sh_addr = (unsigned long)dest;
22787 +
22788 +#ifdef CONFIG_PAX_KERNEXEC
22789 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
22790 +                       sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
22791 +               else
22792 +#endif
22793 +
22794 +                       sechdrs[i].sh_addr = (unsigned long)dest;
22795                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
22796         }
22797         /* Module has been moved. */
22798 @@ -1623,8 +1708,18 @@ static struct module *load_module(void _
22799         setup_modinfo(mod, sechdrs, infoindex);
22800  
22801         /* Fix up syms, so that st_value is a pointer to location. */
22802 +
22803 +#ifdef CONFIG_PAX_KERNEXEC
22804 +       pax_open_kernel(cr0);
22805 +#endif
22806 +
22807         err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
22808                                mod);
22809 +
22810 +#ifdef CONFIG_PAX_KERNEXEC
22811 +       pax_close_kernel(cr0);
22812 +#endif
22813 +
22814         if (err < 0)
22815                 goto cleanup;
22816  
22817 @@ -1666,11 +1761,20 @@ static struct module *load_module(void _
22818                 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
22819                         continue;
22820  
22821 +#ifdef CONFIG_PAX_KERNEXEC
22822 +       pax_open_kernel(cr0);
22823 +#endif
22824 +
22825                 if (sechdrs[i].sh_type == SHT_REL)
22826                         err = apply_relocate(sechdrs, strtab, symindex, i,mod);
22827                 else if (sechdrs[i].sh_type == SHT_RELA)
22828                         err = apply_relocate_add(sechdrs, strtab, symindex, i,
22829                                                  mod);
22830 +
22831 +#ifdef CONFIG_PAX_KERNEXEC
22832 +       pax_close_kernel(cr0);
22833 +#endif
22834 +
22835                 if (err < 0)
22836                         goto cleanup;
22837         }
22838 @@ -1684,14 +1788,31 @@ static struct module *load_module(void _
22839         /* Set up and sort exception table */
22840         mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
22841         mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
22842 +
22843 +#ifdef CONFIG_PAX_KERNEXEC
22844 +       pax_open_kernel(cr0);
22845 +#endif
22846 +
22847         sort_extable(extable, extable + mod->num_exentries);
22848  
22849 +#ifdef CONFIG_PAX_KERNEXEC
22850 +       pax_close_kernel(cr0);
22851 +#endif
22852 +
22853         /* Finally, copy percpu area over. */
22854         percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
22855                        sechdrs[pcpuindex].sh_size);
22856  
22857 +#ifdef CONFIG_PAX_KERNEXEC
22858 +       pax_open_kernel(cr0);
22859 +#endif
22860 +
22861         add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
22862  
22863 +#ifdef CONFIG_PAX_KERNEXEC
22864 +       pax_close_kernel(cr0);
22865 +#endif
22866 +
22867         err = module_finalize(hdr, sechdrs, mod);
22868         if (err < 0)
22869                 goto cleanup;
22870 @@ -1705,12 +1826,12 @@ static struct module *load_module(void _
22871          * Do it before processing of module parameters, so the module
22872          * can provide parameter accessor functions of its own.
22873          */
22874 -       if (mod->module_init)
22875 -               flush_icache_range((unsigned long)mod->module_init,
22876 -                                  (unsigned long)mod->module_init
22877 -                                  + mod->init_size);
22878 -       flush_icache_range((unsigned long)mod->module_core,
22879 -                          (unsigned long)mod->module_core + mod->core_size);
22880 +       if (mod->module_init_rx)
22881 +               flush_icache_range((unsigned long)mod->module_init_rx,
22882 +                                  (unsigned long)mod->module_init_rx
22883 +                                  + mod->init_size_rx);
22884 +       flush_icache_range((unsigned long)mod->module_core_rx,
22885 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
22886  
22887         set_fs(old_fs);
22888  
22889 @@ -1748,9 +1869,13 @@ static struct module *load_module(void _
22890         module_arch_cleanup(mod);
22891   cleanup:
22892         module_unload_free(mod);
22893 -       module_free(mod, mod->module_init);
22894 - free_core:
22895 -       module_free(mod, mod->module_core);
22896 +       module_free_exec(mod, mod->module_init_rx);
22897 + free_core_rx:
22898 +       module_free_exec(mod, mod->module_core_rx);
22899 + free_init_rw:
22900 +       module_free(mod, mod->module_init_rw);
22901 + free_core_rw:
22902 +       module_free(mod, mod->module_core_rw);
22903   free_percpu:
22904         if (percpu)
22905                 percpu_modfree(percpu);
22906 @@ -1786,6 +1911,9 @@ sys_init_module(void __user *umod,
22907         struct module *mod;
22908         int ret = 0;
22909  
22910 +       if (gr_check_modstop())
22911 +               return -EPERM;
22912 +
22913         /* Must have permission */
22914         if (!capable(CAP_SYS_MODULE))
22915                 return -EPERM;
22916 @@ -1836,10 +1964,12 @@ sys_init_module(void __user *umod,
22917         mod->state = MODULE_STATE_LIVE;
22918         /* Drop initial reference. */
22919         module_put(mod);
22920 -       module_free(mod, mod->module_init);
22921 -       mod->module_init = NULL;
22922 -       mod->init_size = 0;
22923 -       mod->init_text_size = 0;
22924 +       module_free(mod, mod->module_init_rw);
22925 +       module_free_exec(mod, mod->module_init_rx);
22926 +       mod->module_init_rw = NULL;
22927 +       mod->module_init_rx = NULL;
22928 +       mod->init_size_rw = 0;
22929 +       mod->init_size_rx = 0;
22930         mutex_unlock(&module_mutex);
22931  
22932         return 0;
22933 @@ -1870,10 +2000,14 @@ static const char *get_ksymbol(struct mo
22934         unsigned long nextval;
22935  
22936         /* At worse, next value is at end of module */
22937 -       if (within(addr, mod->module_init, mod->init_size))
22938 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
22939 -       else 
22940 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
22941 +       if (within(addr, mod->module_init_rx, mod->init_size_rx))
22942 +               nextval = (unsigned long)mod->module_init_rw;
22943 +       else if (within(addr, mod->module_init_rw, mod->init_size_rw))
22944 +               nextval = (unsigned long)mod->module_core_rx;
22945 +       else if (within(addr, mod->module_core_rx, mod->core_size_rx))
22946 +               nextval = (unsigned long)mod->module_core_rw;
22947 +       else
22948 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
22949  
22950         /* Scan for closest preceeding symbol, and next symbol. (ELF
22951             starts real symbols at 1). */
22952 @@ -1914,8 +2048,10 @@ const char *module_address_lookup(unsign
22953         struct module *mod;
22954  
22955         list_for_each_entry(mod, &modules, list) {
22956 -               if (within(addr, mod->module_init, mod->init_size)
22957 -                   || within(addr, mod->module_core, mod->core_size)) {
22958 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
22959 +                   || within(addr, mod->module_init_rw, mod->init_size_rw)
22960 +                   || within(addr, mod->module_core_rx, mod->core_size_rx)
22961 +                   || within(addr, mod->module_core_rw, mod->core_size_rw)) {
22962                         *modname = mod->name;
22963                         return get_ksymbol(mod, addr, size, offset);
22964                 }
22965 @@ -1926,7 +2062,7 @@ const char *module_address_lookup(unsign
22966  struct module *module_get_kallsym(unsigned int symnum,
22967                                   unsigned long *value,
22968                                   char *type,
22969 -                                 char namebuf[128])
22970 +                                 char namebuf[KSYM_NAME_LEN+1])
22971  {
22972         struct module *mod;
22973  
22974 @@ -1937,7 +2073,7 @@ struct module *module_get_kallsym(unsign
22975                         *type = mod->symtab[symnum].st_info;
22976                         strncpy(namebuf,
22977                                 mod->strtab + mod->symtab[symnum].st_name,
22978 -                               127);
22979 +                               KSYM_NAME_LEN);
22980                         mutex_unlock(&module_mutex);
22981                         return mod;
22982                 }
22983 @@ -2014,7 +2150,7 @@ static int m_show(struct seq_file *m, vo
22984  {
22985         struct module *mod = list_entry(p, struct module, list);
22986         seq_printf(m, "%s %lu",
22987 -                  mod->name, mod->init_size + mod->core_size);
22988 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
22989         print_unload_info(m, mod);
22990  
22991         /* Informative for users. */
22992 @@ -2023,7 +2159,7 @@ static int m_show(struct seq_file *m, vo
22993                    mod->state == MODULE_STATE_COMING ? "Loading":
22994                    "Live");
22995         /* Used by oprofile and other similar tools. */
22996 -       seq_printf(m, " 0x%p", mod->module_core);
22997 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
22998  
22999         seq_printf(m, "\n");
23000         return 0;
23001 @@ -2071,9 +2207,13 @@ struct module *__module_text_address(uns
23002  {
23003         struct module *mod;
23004  
23005 +#ifdef CONFIG_PAX_KERNEXEC
23006 +       addr += __KERNEL_TEXT_OFFSET;
23007 +#endif
23008 +
23009         list_for_each_entry(mod, &modules, list)
23010 -               if (within(addr, mod->module_init, mod->init_text_size)
23011 -                   || within(addr, mod->module_core, mod->core_text_size))
23012 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
23013 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
23014                         return mod;
23015         return NULL;
23016  }
23017 diff -urNp linux-2.6.17.7/kernel/pid.c linux-2.6.17.7/kernel/pid.c
23018 --- linux-2.6.17.7/kernel/pid.c 2006-07-24 23:36:01.000000000 -0400
23019 +++ linux-2.6.17.7/kernel/pid.c 2006-08-01 20:29:48.000000000 -0400
23020 @@ -26,6 +26,7 @@
23021  #include <linux/init.h>
23022  #include <linux/bootmem.h>
23023  #include <linux/hash.h>
23024 +#include <linux/grsecurity.h>
23025  
23026  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
23027  static struct hlist_head *pid_hash;
23028 @@ -90,7 +91,9 @@ static int alloc_pidmap(void)
23029         int i, offset, max_scan, pid, last = last_pid;
23030         pidmap_t *map;
23031  
23032 -       pid = last + 1;
23033 +       pid = gr_random_pid();
23034 +       if (!pid)
23035 +               pid = last_pid + 1;
23036         if (pid >= pid_max)
23037                 pid = RESERVED_PIDS;
23038         offset = pid & BITS_PER_PAGE_MASK;
23039 @@ -269,7 +272,14 @@ struct task_struct * fastcall pid_task(s
23040   */
23041  task_t *find_task_by_pid_type(int type, int nr)
23042  {
23043 -       return pid_task(find_pid(nr), type);
23044 +       task_t *task;
23045 +       
23046 +       task = pid_task(find_pid(nr), type);
23047 +
23048 +       if (gr_pid_is_chrooted(task))
23049 +               return NULL;
23050 +
23051 +       return task;
23052  }
23053  
23054  EXPORT_SYMBOL(find_task_by_pid_type);
23055 diff -urNp linux-2.6.17.7/kernel/posix-cpu-timers.c linux-2.6.17.7/kernel/posix-cpu-timers.c
23056 --- linux-2.6.17.7/kernel/posix-cpu-timers.c    2006-07-24 23:36:01.000000000 -0400
23057 +++ linux-2.6.17.7/kernel/posix-cpu-timers.c    2006-08-01 20:29:48.000000000 -0400
23058 @@ -6,6 +6,7 @@
23059  #include <asm/uaccess.h>
23060  #include <linux/errno.h>
23061  #include <linux/vs_pid.h>
23062 +#include <linux/grsecurity.h>
23063  
23064  static int check_clock(const clockid_t which_clock)
23065  {
23066 @@ -1125,6 +1126,7 @@ static void check_process_timers(struct 
23067                         __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
23068                         return;
23069                 }
23070 +               gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
23071                 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
23072                         /*
23073                          * At the soft limit, send a SIGXCPU every second.
23074 diff -urNp linux-2.6.17.7/kernel/printk.c linux-2.6.17.7/kernel/printk.c
23075 --- linux-2.6.17.7/kernel/printk.c      2006-07-24 23:36:01.000000000 -0400
23076 +++ linux-2.6.17.7/kernel/printk.c      2006-08-01 20:29:48.000000000 -0400
23077 @@ -31,7 +31,8 @@
23078  #include <linux/bootmem.h>
23079  #include <linux/syscalls.h>
23080  #include <linux/vs_context.h>
23081  #include <linux/vserver/cvirt.h>
23082 +#include <linux/grsecurity.h>
23083  
23084  #include <asm/uaccess.h>
23085  
23086 @@ -185,6 +186,11 @@ int do_syslog(int type, char __user *buf
23087         char c;
23088         int error = 0;
23089  
23090 +#ifdef CONFIG_GRKERNSEC_DMESG
23091 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
23092 +               return -EPERM;
23093 +#endif
23094 +
23095         error = security_syslog(type);
23096         if (error)
23097                 return error;
23098 diff -urNp linux-2.6.17.7/kernel/ptrace.c linux-2.6.17.7/kernel/ptrace.c
23099 --- linux-2.6.17.7/kernel/ptrace.c      2006-07-24 23:36:01.000000000 -0400
23100 +++ linux-2.6.17.7/kernel/ptrace.c      2006-08-01 20:29:48.000000000 -0400
23101 @@ -18,6 +18,7 @@
23102  #include <linux/security.h>
23103  #include <linux/signal.h>
23104  #include <linux/vs_pid.h>
23105 +#include <linux/grsecurity.h>
23106  
23107  #include <asm/pgtable.h>
23108  #include <asm/uaccess.h>
23109 @@ -127,10 +128,10 @@ static int may_attach(struct task_struct
23110              (current->uid != task->uid) ||
23111              (current->gid != task->egid) ||
23112              (current->gid != task->sgid) ||
23113 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
23114 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
23115                 return -EPERM;
23116         smp_rmb();
23117 -       if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
23118 +       if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
23119                 return -EPERM;
23120  
23121         return security_ptrace(current, task);
23122 @@ -515,6 +516,11 @@ asmlinkage long sys_ptrace(long request,
23123         if (ret < 0)
23124                 goto out_put_task_struct;
23125  
23126 +       if (gr_handle_ptrace(child, request)) {
23127 +               ret = -EPERM;
23128 +               goto out_put_task_struct;
23129 +       }
23130 +
23131         ret = arch_ptrace(child, request, addr, data);
23132         if (ret < 0)
23133                 goto out_put_task_struct;
23134 diff -urNp linux-2.6.17.7/kernel/resource.c linux-2.6.17.7/kernel/resource.c
23135 --- linux-2.6.17.7/kernel/resource.c    2006-07-24 23:36:01.000000000 -0400
23136 +++ linux-2.6.17.7/kernel/resource.c    2006-08-01 20:29:48.000000000 -0400
23137 @@ -136,10 +136,27 @@ static int __init ioresources_init(void)
23138  {
23139         struct proc_dir_entry *entry;
23140  
23141 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
23142 +#ifdef CONFIG_GRKERNSEC_PROC_USER
23143 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
23144 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
23145 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
23146 +#endif
23147 +#else
23148         entry = create_proc_entry("ioports", 0, NULL);
23149 +#endif
23150         if (entry)
23151                 entry->proc_fops = &proc_ioports_operations;
23152 +
23153 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
23154 +#ifdef CONFIG_GRKERNSEC_PROC_USER
23155 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
23156 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
23157 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
23158 +#endif
23159 +#else
23160         entry = create_proc_entry("iomem", 0, NULL);
23161 +#endif
23162         if (entry)
23163                 entry->proc_fops = &proc_iomem_operations;
23164         return 0;
23165 diff -urNp linux-2.6.17.7/kernel/sched.c linux-2.6.17.7/kernel/sched.c
23166 --- linux-2.6.17.7/kernel/sched.c       2006-07-24 23:36:01.000000000 -0400
23167 +++ linux-2.6.17.7/kernel/sched.c       2006-08-01 20:29:48.000000000 -0400
23168 @@ -50,6 +50,7 @@
23169  #include <linux/times.h>
23170  #include <linux/acct.h>
23171  #include <linux/kprobes.h>
23172 +#include <linux/grsecurity.h>
23173  #include <asm/tlb.h>
23174  
23175  #include <asm/unistd.h>
23176 @@ -3565,7 +3566,8 @@ asmlinkage long sys_nice(int increment)
23177         if (nice > 19)
23178                 nice = 19;
23179  
23180 -       if (increment < 0 && !can_nice(current, nice))
23181 +       if (increment < 0 && (!can_nice(current, nice) ||
23182 +                             gr_handle_chroot_nice()))
23183                 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
23184  
23185         retval = security_task_setnice(current, nice);
23186 diff -urNp linux-2.6.17.7/kernel/signal.c linux-2.6.17.7/kernel/signal.c
23187 --- linux-2.6.17.7/kernel/signal.c      2006-07-24 23:36:01.000000000 -0400
23188 +++ linux-2.6.17.7/kernel/signal.c      2006-08-01 20:29:48.000000000 -0400
23189 @@ -25,6 +25,7 @@
23190  #include <linux/audit.h>
23191  #include <linux/capability.h>
23192  #include <linux/vs_pid.h>
23193 +#include <linux/grsecurity.h>
23194  #include <asm/param.h>
23195  #include <asm/uaccess.h>
23196  #include <asm/unistd.h>
23197 @@ -583,11 +583,11 @@ static int check_kill_permission(int sig
23198                 (!is_si_special(info) && SI_FROMUSER(info)));
23199  
23200         error = -EPERM;
23201 -       if (user && ((sig != SIGCONT) ||
23202 +       if (user && ((((sig != SIGCONT) ||
23203                 (current->signal->session != t->signal->session))
23204             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
23205             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
23206 -           && !capable(CAP_KILL))
23207 +           && !capable(CAP_KILL)) || gr_handle_signal(t, sig)))
23208                 return error;
23209  
23210         error = -ESRCH;
23211 @@ -595,8 +595,10 @@ static int check_kill_permission(int sig
23212                 return error;
23213  
23214         error = security_task_kill(t, info, sig);
23215 -       if (!error)
23216 +       if (!error) {
23217                 audit_signal_info(sig, t); /* Let audit system see the signal */
23218 +               gr_log_signal(sig, t);
23219 +       }
23220         return error;
23221  }
23222  
23223 @@ -764,7 +767,7 @@ out_set:
23224         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
23225  
23226  
23227 -static int
23228 +int
23229  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
23230  {
23231         int ret = 0;
23232 @@ -809,6 +812,10 @@ force_sig_info(int sig, struct siginfo *
23233         }
23234         recalc_sigpending_tsk(t);
23235         ret = specific_send_sig_info(sig, info, t);
23236 +
23237 +       gr_log_signal(sig, t);
23238 +       gr_handle_crash(t, sig);
23239 +
23240         spin_unlock_irqrestore(&t->sighand->siglock, flags);
23241  
23242         return ret;
23243 diff -urNp linux-2.6.17.7/kernel/sys.c linux-2.6.17.7/kernel/sys.c
23244 --- linux-2.6.17.7/kernel/sys.c 2006-07-24 23:36:01.000000000 -0400
23245 +++ linux-2.6.17.7/kernel/sys.c 2006-08-01 20:29:48.000000000 -0400
23246 @@ -30,6 +30,7 @@
23247  #include <linux/cn_proc.h>
23248  #include <linux/vs_cvirt.h>
23249  #include <linux/vs_pid.h>
23250 +#include <linux/grsecurity.h>
23251  
23252  #include <linux/compat.h>
23253  #include <linux/syscalls.h>
23254 @@ -442,6 +443,12 @@ static int set_one_prio(struct task_stru
23255                 error = -EACCES;
23256                 goto out;
23257         }
23258 +
23259 +       if (gr_handle_chroot_setpriority(p, niceval)) {
23260 +               error = -EACCES;
23261 +               goto out;
23262 +       }
23263 +
23264         no_nice = security_task_setnice(p, niceval);
23265         if (no_nice) {
23266                 error = no_nice;
23267 @@ -831,6 +838,9 @@ asmlinkage long sys_setregid(gid_t rgid,
23268         if (rgid != (gid_t) -1 ||
23269             (egid != (gid_t) -1 && egid != old_rgid))
23270                 current->sgid = new_egid;
23271 +
23272 +       gr_set_role_label(current, current->uid, new_rgid);
23273 +
23274         current->fsgid = new_egid;
23275         current->egid = new_egid;
23276         current->gid = new_rgid;
23277 @@ -860,6 +870,9 @@ asmlinkage long sys_setgid(gid_t gid)
23278                         current->mm->dumpable = suid_dumpable;
23279                         smp_wmb();
23280                 }
23281 +
23282 +               gr_set_role_label(current, current->uid, gid);
23283 +
23284                 current->gid = current->egid = current->sgid = current->fsgid = gid;
23285         }
23286         else if ((gid == current->gid) || (gid == current->sgid))
23287 @@ -901,6 +914,9 @@ static int set_user(uid_t new_ruid, int 
23288                 current->mm->dumpable = suid_dumpable;
23289                 smp_wmb();
23290         }
23291 +
23292 +       gr_set_role_label(current, new_ruid, current->gid);
23293 +
23294         current->uid = new_ruid;
23295         return 0;
23296  }
23297 @@ -1004,6 +1020,9 @@ asmlinkage long sys_setuid(uid_t uid)
23298         } else if ((uid != current->uid) && (uid != new_suid))
23299                 return -EPERM;
23300  
23301 +       if (gr_check_crash_uid(uid))
23302 +               return -EPERM;
23303 +
23304         if (old_euid != uid)
23305         {
23306                 current->mm->dumpable = suid_dumpable;
23307 @@ -1109,8 +1128,10 @@ asmlinkage long sys_setresgid(gid_t rgid
23308                 current->egid = egid;
23309         }
23310         current->fsgid = current->egid;
23311 -       if (rgid != (gid_t) -1)
23312 +       if (rgid != (gid_t) -1) {
23313 +               gr_set_role_label(current, current->uid, rgid);
23314                 current->gid = rgid;
23315 +       }
23316         if (sgid != (gid_t) -1)
23317                 current->sgid = sgid;
23318  
23319 diff -urNp linux-2.6.17.7/kernel/sysctl.c linux-2.6.17.7/kernel/sysctl.c
23320 --- linux-2.6.17.7/kernel/sysctl.c      2006-07-24 23:36:01.000000000 -0400
23321 +++ linux-2.6.17.7/kernel/sysctl.c      2006-08-01 20:29:48.000000000 -0400
23322 @@ -54,6 +54,14 @@ extern int proc_nr_files(ctl_table *tabl
23323                       void __user *buffer, size_t *lenp, loff_t *ppos);
23324  
23325  #if defined(CONFIG_SYSCTL)
23326 +#include <linux/grsecurity.h>
23327 +#include <linux/grinternal.h>
23328 +
23329 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
23330 +                             const void *newval);
23331 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
23332 +                               const int op);
23333 +extern int gr_handle_chroot_sysctl(const int op);
23334  
23335  /* External variables not in a header file. */
23336  extern int C_A_D;
23337 @@ -157,6 +165,22 @@ extern ctl_table inotify_table[];
23338  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
23339  int sysctl_legacy_va_layout;
23340  #endif
23341 +extern ctl_table grsecurity_table[];
23342 +
23343 +#ifdef CONFIG_PAX_SOFTMODE
23344 +static ctl_table pax_table[] = {
23345 +       {
23346 +               .ctl_name       = PAX_SOFTMODE,
23347 +               .procname       = "softmode",
23348 +               .data           = &pax_softmode,
23349 +               .maxlen         = sizeof(unsigned int),
23350 +               .mode           = 0600,
23351 +               .proc_handler   = &proc_dointvec,
23352 +       },
23353 +
23354 +       { .ctl_name = 0 }
23355 +};
23356 +#endif
23357  
23358  /* /proc declarations: */
23359  
23360 @@ -683,6 +707,24 @@ static ctl_table kern_table[] = {
23361                 .proc_handler   = &proc_dointvec,
23362         },
23363  #endif
23364 +
23365 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
23366 +       {
23367 +               .ctl_name       = KERN_GRSECURITY,
23368 +               .procname       = "grsecurity",
23369 +               .mode           = 0500,
23370 +               .child          = grsecurity_table,
23371 +       },
23372 +#endif
23373 +
23374 +#ifdef CONFIG_PAX_SOFTMODE
23375 +       {
23376 +               .ctl_name       = KERN_PAX,
23377 +               .procname       = "pax",
23378 +               .mode           = 0500,
23379 +               .child          = pax_table,
23380 +       },
23381 +#endif
23382         { .ctl_name = 0 }
23383  };
23384  
23385 @@ -1180,6 +1222,10 @@ static int test_perm(int mode, int op)
23386  static inline int ctl_perm(ctl_table *table, int op)
23387  {
23388         int error;
23389 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
23390 +               return -EACCES;
23391 +       if (gr_handle_chroot_sysctl(op))
23392 +               return -EACCES;
23393         error = security_sysctl(table, op);
23394         if (error)
23395                 return error;
23396 @@ -1216,6 +1262,10 @@ repeat:
23397                                 table = table->child;
23398                                 goto repeat;
23399                         }
23400 +
23401 +                       if (!gr_handle_sysctl(table, oldval, newval))
23402 +                               return -EACCES;
23403 +
23404                         error = do_sysctl_strategy(table, name, nlen,
23405                                                    oldval, oldlenp,
23406                                                    newval, newlen, context);
23407 diff -urNp linux-2.6.17.7/kernel/time.c linux-2.6.17.7/kernel/time.c
23408 --- linux-2.6.17.7/kernel/time.c        2006-07-24 23:36:01.000000000 -0400
23409 +++ linux-2.6.17.7/kernel/time.c        2006-08-01 20:29:48.000000000 -0400
23410 @@ -36,6 +36,7 @@
23411  #include <linux/security.h>
23412  #include <linux/fs.h>
23413  #include <linux/module.h>
23414 +#include <linux/grsecurity.h>
23415  
23416  #include <asm/uaccess.h>
23417  #include <asm/unistd.h>
23418 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user 
23419                 return err;
23420  
23421         vx_settimeofday(&tv);
23422 +
23423 +       gr_log_timechange();
23424 +
23425         return 0;
23426  }
23427  
23428 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct 
23429                         return -EFAULT;
23430         }
23431  
23432 +       gr_log_timechange();
23433 +
23434         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
23435  }
23436  
23437 diff -urNp linux-2.6.17.7/mm/filemap.c linux-2.6.17.7/mm/filemap.c
23438 --- linux-2.6.17.7/mm/filemap.c 2006-07-24 23:36:01.000000000 -0400
23439 +++ linux-2.6.17.7/mm/filemap.c 2006-08-01 20:29:48.000000000 -0400
23440 @@ -30,6 +30,7 @@
23441  #include <linux/security.h>
23442  #include <linux/syscalls.h>
23443  #include <linux/cpuset.h>
23444 +#include <linux/grsecurity.h>
23445  #include "filemap.h"
23446  #include "internal.h"
23447  
23448 @@ -1650,7 +1651,13 @@ int generic_file_mmap(struct file * file
23449         struct address_space *mapping = file->f_mapping;
23450  
23451         if (!mapping->a_ops->readpage)
23452 -               return -ENOEXEC;
23453 +               return -ENODEV;
23454 +
23455 +#ifdef CONFIG_PAX_PAGEEXEC
23456 +       if (vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC)
23457 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
23458 +#endif
23459 +
23460         file_accessed(file);
23461         vma->vm_ops = &generic_file_vm_ops;
23462         return 0;
23463 @@ -1872,6 +1879,7 @@ inline int generic_write_checks(struct f
23464                          *pos = i_size_read(inode);
23465  
23466                 if (limit != RLIM_INFINITY) {
23467 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
23468                         if (*pos >= limit) {
23469                                 send_sig(SIGXFSZ, current, 0);
23470                                 return -EFBIG;
23471 diff -urNp linux-2.6.17.7/mm/madvise.c linux-2.6.17.7/mm/madvise.c
23472 --- linux-2.6.17.7/mm/madvise.c 2006-07-24 23:36:01.000000000 -0400
23473 +++ linux-2.6.17.7/mm/madvise.c 2006-08-01 20:29:48.000000000 -0400
23474 @@ -15,9 +15,46 @@
23475   * We can potentially split a vm area into separate
23476   * areas, each area with its own behavior.
23477   */
23478 +
23479 +#ifdef CONFIG_PAX_SEGMEXEC
23480 +static long __madvise_behavior(struct vm_area_struct * vma,
23481 +                    struct vm_area_struct **prev,
23482 +                    unsigned long start, unsigned long end, int behavior);
23483 +
23484 +static long madvise_behavior(struct vm_area_struct * vma,
23485 +                    struct vm_area_struct **prev,
23486 +                    unsigned long start, unsigned long end, int behavior)
23487 +{
23488 +       if (vma->vm_flags & VM_MIRROR) {
23489 +               struct vm_area_struct * vma_m, * prev_m;
23490 +               unsigned long start_m, end_m;
23491 +               int error;
23492 +
23493 +               start_m = vma->vm_start + vma->vm_mirror;
23494 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
23495 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
23496 +                       start_m = start + vma->vm_mirror;
23497 +                       end_m = end + vma->vm_mirror;
23498 +                       error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
23499 +                       if (error)
23500 +                               return error;
23501 +               } else {
23502 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
23503 +                       return -ENOMEM;
23504 +               }
23505 +       }
23506 +
23507 +       return __madvise_behavior(vma, prev, start, end, behavior);
23508 +}
23509 +
23510 +static long __madvise_behavior(struct vm_area_struct * vma,
23511 +                    struct vm_area_struct **prev,
23512 +                    unsigned long start, unsigned long end, int behavior)
23513 +#else
23514  static long madvise_behavior(struct vm_area_struct * vma,
23515                      struct vm_area_struct **prev,
23516                      unsigned long start, unsigned long end, int behavior)
23517 +#endif
23518  {
23519         struct mm_struct * mm = vma->vm_mm;
23520         int error = 0;
23521 diff -urNp linux-2.6.17.7/mm/memory.c linux-2.6.17.7/mm/memory.c
23522 --- linux-2.6.17.7/mm/memory.c  2006-07-24 23:36:01.000000000 -0400
23523 +++ linux-2.6.17.7/mm/memory.c  2006-08-01 20:29:48.000000000 -0400
23524 @@ -48,6 +48,7 @@
23525  #include <linux/rmap.h>
23526  #include <linux/module.h>
23527  #include <linux/init.h>
23528 +#include <linux/grsecurity.h>
23529  
23530  #include <asm/pgalloc.h>
23531  #include <asm/uaccess.h>
23532 @@ -320,6 +321,11 @@ int __pte_alloc(struct mm_struct *mm, pm
23533  
23534  int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
23535  {
23536 +
23537 +#ifdef CONFIG_PAX_KERNEXEC
23538 +       unsigned long cr0;
23539 +#endif
23540 +
23541         pte_t *new = pte_alloc_one_kernel(&init_mm, address);
23542         if (!new)
23543                 return -ENOMEM;
23544 @@ -327,8 +333,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
23545         spin_lock(&init_mm.page_table_lock);
23546         if (pmd_present(*pmd))          /* Another has populated it */
23547                 pte_free_kernel(new);
23548 -       else
23549 +       else {
23550 +
23551 +#ifdef CONFIG_PAX_KERNEXEC
23552 +               pax_open_kernel(cr0);
23553 +#endif
23554 +
23555                 pmd_populate_kernel(&init_mm, pmd, new);
23556 +
23557 +#ifdef CONFIG_PAX_KERNEXEC
23558 +               pax_close_kernel(cr0);
23559 +#endif
23560 +
23561 +       }
23562         spin_unlock(&init_mm.page_table_lock);
23563         return 0;
23564  }
23565 @@ -1421,6 +1438,88 @@ static inline void cow_user_page(struct 
23566         copy_user_highpage(dst, src, va);
23567  }
23568  
23569 +#ifdef CONFIG_PAX_SEGMEXEC
23570 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
23571 + *
23572 + * the ptl of the lower mapped page is held on entry and is not released on exit
23573 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
23574 + */
23575 +static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
23576 +{
23577 +       struct mm_struct *mm = vma->vm_mm;
23578 +       unsigned long address_m, pfn_m;
23579 +       struct vm_area_struct * vma_m = NULL;
23580 +       pte_t * pte_m, entry_m;
23581 +       struct page * page_m = NULL;
23582 +
23583 +       address_m = vma->vm_start + vma->vm_mirror;
23584 +       vma_m = find_vma(mm, address_m);
23585 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
23586 +
23587 +       address_m = address + vma->vm_mirror;
23588 +       pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
23589 +
23590 +       if (pte_same(*pte, *pte_m)) {
23591 +               pte_unmap_nested(pte_m);
23592 +               return;
23593 +       }
23594 +
23595 +       pfn_m = pte_pfn(*pte);
23596 +       if (pte_present(*pte_m)) {
23597 +               page_m = vm_normal_page(vma_m, address_m, *pte_m);
23598 +               if (page_m) {
23599 +                       flush_cache_page(vma_m, address_m, pfn_m);
23600 +                       flush_icache_page(vma_m, page_m);
23601 +               }
23602 +       }
23603 +
23604 +       if (pte_present(*pte_m))
23605 +               entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
23606 +       else
23607 +               entry_m = ptep_get_and_clear(mm, address_m, pte_m);
23608 +
23609 +       if (pte_none(entry_m)) {
23610 +       } else if (pte_present(entry_m)) {
23611 +               if (page_m) {
23612 +                       page_remove_rmap(page_m);
23613 +                       if (PageAnon(page_m))
23614 +                               dec_mm_counter(mm, anon_rss);
23615 +                       else
23616 +                               dec_mm_counter(mm, file_rss);
23617 +                       page_cache_release(page_m);
23618 +               }
23619 +       } else if (!pte_file(entry_m)) {
23620 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
23621 +       } else {
23622 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
23623 +                               address, vma->vm_start, address_m, vma_m->vm_start);
23624 +       }
23625 +
23626 +       page_m = vm_normal_page(vma, address, *pte);
23627 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
23628 +       if (pte_write(*pte))
23629 +               entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
23630 +       if (page_m) {
23631 +               page_cache_get(page_m);
23632 +               /*
23633 +                * we can test PAGE_MAPPING_ANON without holding page_map_lock because
23634 +                * we hold the page table lock and have a reference to page_m
23635 +                */
23636 +               if (PageAnon(page_m)) {
23637 +                       page_add_anon_rmap(page_m, vma_m, address_m);
23638 +                       inc_mm_counter(mm, anon_rss);
23639 +               } else {
23640 +                       page_add_file_rmap(page_m);
23641 +                       inc_mm_counter(mm, file_rss);
23642 +               }
23643 +       }
23644 +       set_pte_at(mm, address_m, pte_m, entry_m);
23645 +       update_mmu_cache(vma_m, address_m, entry_m);
23646 +       lazy_mmu_prot_update(entry_m);
23647 +       pte_unmap_nested(pte_m);
23648 +}
23649 +#endif
23650 +
23651  /*
23652   * This routine handles present pages, when users try to write
23653   * to a shared page. It is done by copying the page to a new address
23654 @@ -1511,6 +1610,12 @@ gotten:
23655                 /* Free the old page.. */
23656                 new_page = old_page;
23657                 ret |= VM_FAULT_WRITE;
23658 +
23659 +#ifdef CONFIG_PAX_SEGMEXEC
23660 +               if (vma->vm_flags & VM_MIRROR)
23661 +                       pax_mirror_fault(vma, address, page_table);
23662 +#endif
23663 +
23664         }
23665         if (new_page)
23666                 page_cache_release(new_page);
23667 @@ -1761,6 +1866,7 @@ int vmtruncate(struct inode * inode, lof
23668  
23669  do_expand:
23670         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
23671 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
23672         if (limit != RLIM_INFINITY && offset > limit)
23673                 goto out_sig;
23674         if (offset > inode->i_sb->s_maxbytes)
23675 @@ -1950,6 +2056,12 @@ again:
23676         /* No need to invalidate - it was non-present before */
23677         update_mmu_cache(vma, address, pte);
23678         lazy_mmu_prot_update(pte);
23679 +
23680 +#ifdef CONFIG_PAX_SEGMEXEC
23681 +       if (vma->vm_flags & VM_MIRROR)
23682 +               pax_mirror_fault(vma, address, page_table);
23683 +#endif
23684 +
23685  unlock:
23686         pte_unmap_unlock(page_table, ptl);
23687  out:
23688 @@ -2012,6 +2124,12 @@ static int do_anonymous_page(struct mm_s
23689         /* No need to invalidate - it was non-present before */
23690         update_mmu_cache(vma, address, entry);
23691         lazy_mmu_prot_update(entry);
23692 +
23693 +#ifdef CONFIG_PAX_SEGMEXEC
23694 +       if (vma->vm_flags & VM_MIRROR)
23695 +               pax_mirror_fault(vma, address, page_table);
23696 +#endif
23697 +
23698  unlock:
23699         pte_unmap_unlock(page_table, ptl);
23700         return VM_FAULT_MINOR;
23701 @@ -2137,6 +2255,12 @@ retry:
23702         /* no need to invalidate: a not-present page shouldn't be cached */
23703         update_mmu_cache(vma, address, entry);
23704         lazy_mmu_prot_update(entry);
23705 +
23706 +#ifdef CONFIG_PAX_SEGMEXEC
23707 +       if (vma->vm_flags & VM_MIRROR)
23708 +               pax_mirror_fault(vma, address, page_table);
23709 +#endif
23710 +
23711  unlock:
23712         pte_unmap_unlock(page_table, ptl);
23713         return ret;
23714 @@ -2246,6 +2370,12 @@ static inline int handle_pte_fault(struc
23715                         flush_tlb_page(vma, address);
23716         }
23717  unlock:
23718 +
23719 +#ifdef CONFIG_PAX_SEGMEXEC
23720 +       if (vma->vm_flags & VM_MIRROR)
23721 +               pax_mirror_fault(vma, address, pte);
23722 +#endif
23723 +
23724         pte_unmap_unlock(pte, ptl);
23725         return VM_FAULT_MINOR;
23726  }
23727 @@ -2268,6 +2398,49 @@ int __handle_mm_fault(struct mm_struct *
23728         if (unlikely(is_vm_hugetlb_page(vma)))
23729                 return hugetlb_fault(mm, vma, address, write_access);
23730  
23731 +#ifdef CONFIG_PAX_SEGMEXEC
23732 +       if (vma->vm_flags & VM_MIRROR) {
23733 +               unsigned long address_m;
23734 +               struct vm_area_struct * vma_m;
23735 +               pgd_t *pgd_m;
23736 +               pud_t *pud_m;
23737 +               pmd_t *pmd_m;
23738 +
23739 +               address_m = vma->vm_start + vma->vm_mirror;
23740 +               vma_m = find_vma(mm, address_m);
23741 +
23742 +               /* PaX: sanity checks */
23743 +               if (!vma_m) {
23744 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
23745 +                              address, vma, address_m, vma_m);
23746 +                       return VM_FAULT_SIGBUS;
23747 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
23748 +                       vma_m->vm_start != address_m ||
23749 +                       vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
23750 +               {
23751 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
23752 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
23753 +                       return VM_FAULT_SIGBUS;
23754 +               }
23755 +
23756 +               if (address_m < address) {
23757 +                       address += vma->vm_mirror;
23758 +                       vma = vma_m;
23759 +               }
23760 +
23761 +               address_m = address + vma->vm_mirror;
23762 +               pgd_m = pgd_offset(mm, address_m);
23763 +               pud_m = pud_alloc(mm, pgd_m, address_m);
23764 +               if (!pud_m)
23765 +                       return VM_FAULT_OOM;
23766 +               pmd_m = pmd_alloc(mm, pud_m, address_m);
23767 +               if (!pmd_m)
23768 +                       return VM_FAULT_OOM;
23769 +               if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
23770 +                       return VM_FAULT_OOM;
23771 +       }
23772 +#endif
23773 +
23774         pgd = pgd_offset(mm, address);
23775         pud = pud_alloc(mm, pgd, address);
23776         if (!pud)
23777 diff -urNp linux-2.6.17.7/mm/mempolicy.c linux-2.6.17.7/mm/mempolicy.c
23778 --- linux-2.6.17.7/mm/mempolicy.c       2006-07-24 23:36:01.000000000 -0400
23779 +++ linux-2.6.17.7/mm/mempolicy.c       2006-08-01 20:29:48.000000000 -0400
23780 @@ -346,6 +346,12 @@ check_range(struct mm_struct *mm, unsign
23781                         if (prev && prev->vm_end < vma->vm_start)
23782                                 return ERR_PTR(-EFAULT);
23783                 }
23784 +
23785 +#ifdef CONFIG_PAX_SEGMEXEC
23786 +               if (vma->vm_flags & VM_MIRROR)
23787 +                       return ERR_PTR(-EFAULT);
23788 +#endif
23789 +
23790                 if (!is_vm_hugetlb_page(vma) &&
23791                     ((flags & MPOL_MF_STRICT) ||
23792                      ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
23793 diff -urNp linux-2.6.17.7/mm/mlock.c linux-2.6.17.7/mm/mlock.c
23794 --- linux-2.6.17.7/mm/mlock.c   2006-07-24 23:36:01.000000000 -0400
23795 +++ linux-2.6.17.7/mm/mlock.c   2006-08-01 20:29:48.000000000 -0400
23796 @@ -10,14 +10,85 @@
23797  #include <linux/mempolicy.h>
23798  #include <linux/syscalls.h>
23799  #include <linux/vs_memory.h>
23800 +#include <linux/grsecurity.h>
23801  
23802 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
23803 +       unsigned long start, unsigned long end, unsigned int newflags);
23804  
23805  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
23806         unsigned long start, unsigned long end, unsigned int newflags)
23807  {
23808         struct mm_struct * mm = vma->vm_mm;
23809 -       pgoff_t pgoff;
23810         int pages;
23811 +       int ret;
23812 +
23813 +#ifdef CONFIG_PAX_SEGMEXEC
23814 +       struct vm_area_struct * vma_m = NULL, *prev_m;
23815 +       unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
23816 +
23817 +       if (vma->vm_flags & VM_MIRROR) {
23818 +               start_m = vma->vm_start + vma->vm_mirror;
23819 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
23820 +               if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
23821 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
23822 +                       return -ENOMEM;
23823 +               }
23824 +
23825 +               start_m = start + vma->vm_mirror;
23826 +               end_m = end + vma->vm_mirror;
23827 +               if (newflags & VM_LOCKED)
23828 +                       newflags_m = vma_m->vm_flags | VM_LOCKED;
23829 +               else
23830 +                       newflags_m = vma_m->vm_flags & ~VM_LOCKED;
23831 +               ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
23832 +               if (ret)
23833 +                       return ret;
23834 +       }
23835 +#endif
23836 +
23837 +       ret = __mlock_fixup(vma, prev, start, end, newflags);
23838 +       if (ret)
23839 +               return ret;
23840 +
23841 +       /*
23842 +        * vm_flags is protected by the mmap_sem held in write mode.
23843 +        * It's okay if try_to_unmap_one unmaps a page just after we
23844 +        * set VM_LOCKED, make_pages_present below will bring it back.
23845 +        */
23846 +       vma->vm_flags = newflags;
23847 +
23848 +#ifdef CONFIG_PAX_SEGMEXEC
23849 +       if (vma->vm_flags & VM_MIRROR)
23850 +               vma_m->vm_flags = newflags_m;
23851 +#endif
23852 +
23853 +       /*
23854 +        * Keep track of amount of locked VM.
23855 +        */
23856 +       pages = (end - start) >> PAGE_SHIFT;
23857 +       if (newflags & VM_LOCKED) {
23858 +               pages = -pages;
23859 +               if (!(newflags & VM_IO))
23860 +                       ret = make_pages_present(start, end);
23861 +       }
23862 +
23863 +       mm->locked_vm -= pages;
23864 +
23865 +#ifdef CONFIG_PAX_SEGMEXEC
23866 +       if (vma->vm_flags & VM_MIRROR)
23867 +               mm->locked_vm -= pages;
23868 +#endif
23869 +
23870 +       if (ret == -ENOMEM)
23871 +               ret = -EAGAIN;
23872 +       return ret;
23873 +}
23874 +
23875 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
23876 +       unsigned long start, unsigned long end, unsigned int newflags)
23877 +{
23878 +       struct mm_struct * mm = vma->vm_mm;
23879 +       pgoff_t pgoff;
23880         int ret = 0;
23881  
23882         if (newflags == vma->vm_flags) {
23883 @@ -30,7 +101,7 @@ static int mlock_fixup(struct vm_area_st
23884                           vma->vm_file, pgoff, vma_policy(vma));
23885         if (*prev) {
23886                 vma = *prev;
23887 -               goto success;
23888 +               goto out;
23889         }
23890  
23891         *prev = vma;
23892 @@ -41,31 +112,9 @@ static int mlock_fixup(struct vm_area_st
23893                         goto out;
23894         }
23895  
23896 -       if (end != vma->vm_end) {
23897 +       if (end != vma->vm_end)
23898                 ret = split_vma(mm, vma, end, 0);
23899 -               if (ret)
23900 -                       goto out;
23901 -       }
23902  
23903 -success:
23904 -       /*
23905 -        * vm_flags is protected by the mmap_sem held in write mode.
23906 -        * It's okay if try_to_unmap_one unmaps a page just after we
23907 -        * set VM_LOCKED, make_pages_present below will bring it back.
23908 -        */
23909 -       vma->vm_flags = newflags;
23910 -
23911 -       /*
23912 -        * Keep track of amount of locked VM.
23913 -        */
23914 -       pages = (end - start) >> PAGE_SHIFT;
23915 -       if (newflags & VM_LOCKED) {
23916 -               pages = -pages;
23917 -               if (!(newflags & VM_IO))
23918 -                       ret = make_pages_present(start, end);
23919 -       }
23920 -
23921 -       vx_vmlocked_sub(vma->vm_mm, pages);
23922  out:
23923         if (ret == -ENOMEM)
23924                 ret = -EAGAIN;
23925 @@ -84,6 +133,17 @@ static int do_mlock(unsigned long start,
23926                 return -EINVAL;
23927         if (end == start)
23928                 return 0;
23929 +
23930 +#ifdef CONFIG_PAX_SEGMEXEC
23931 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
23932 +               if (end > SEGMEXEC_TASK_SIZE)
23933 +                       return -EINVAL;
23934 +       } else
23935 +#endif
23936 +
23937 +       if (end > TASK_SIZE)
23938 +               return -EINVAL;
23939 +
23940         vma = find_vma_prev(current->mm, start, &prev);
23941         if (!vma || vma->vm_start > start)
23942                 return -ENOMEM;
23943 @@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long 
23944         lock_limit >>= PAGE_SHIFT;
23945  
23946         /* check against resource limits */
23947 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
23948         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
23949                 error = do_mlock(start, len, 1);
23950  out:
23951 @@ -173,6 +234,16 @@ static int do_mlockall(int flags)
23952         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
23953                 unsigned int newflags;
23954  
23955 +#ifdef CONFIG_PAX_SEGMEXEC
23956 +               if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
23957 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
23958 +                               break;
23959 +               } else
23960 +#endif
23961 +
23962 +               if (vma->vm_end > TASK_SIZE)
23963 +                       break;
23964 +
23965                 newflags = vma->vm_flags | VM_LOCKED;
23966                 if (!(flags & MCL_CURRENT))
23967                         newflags &= ~VM_LOCKED;
23968 @@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
23969         ret = -ENOMEM;
23970         if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
23971                 goto out;
23972 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
23973         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
23974             capable(CAP_IPC_LOCK))
23975                 ret = do_mlockall(flags);
23976 diff -urNp linux-2.6.17.7/mm/mmap.c linux-2.6.17.7/mm/mmap.c
23977 --- linux-2.6.17.7/mm/mmap.c    2006-07-24 23:36:01.000000000 -0400
23978 +++ linux-2.6.17.7/mm/mmap.c    2006-08-01 20:29:48.000000000 -0400
23979 @@ -25,6 +25,7 @@
23980  #include <linux/mount.h>
23981  #include <linux/mempolicy.h>
23982  #include <linux/rmap.h>
23983 +#include <linux/grsecurity.h>
23984  
23985  #include <asm/uaccess.h>
23986  #include <asm/cacheflush.h>
23987 @@ -60,6 +61,8 @@ pgprot_t protection_map[16] = {
23988         __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
23989  };
23990  
23991 +EXPORT_SYMBOL(protection_map);
23992 +
23993  int sysctl_overcommit_memory = OVERCOMMIT_GUESS;  /* heuristic overcommit */
23994  int sysctl_overcommit_ratio = 50;      /* default is 50% */
23995  int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
23996 @@ -240,6 +243,7 @@ asmlinkage unsigned long sys_brk(unsigne
23997          * not page aligned -Ram Gupta
23998          */
23999         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
24000 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
24001         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
24002                 goto out;
24003  
24004 @@ -628,11 +632,17 @@ again:                    remove_next = 1 + (end > next->
24005   * If the vma has a ->close operation then the driver probably needs to release
24006   * per-vma resources, so we don't attempt to merge those.
24007   */
24008 +#ifdef CONFIG_PAX_SEGMEXEC
24009 +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
24010 +#else
24011  #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
24012 +#endif
24013  
24014  static inline int is_mergeable_vma(struct vm_area_struct *vma,
24015                         struct file *file, unsigned long vm_flags)
24016  {
24017 +       if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
24018 +               return 0;
24019         if (vma->vm_flags != vm_flags)
24020                 return 0;
24021         if (vma->vm_file != file)
24022 @@ -857,14 +867,11 @@ none:
24023  void vm_stat_account(struct mm_struct *mm, unsigned long flags,
24024                                                 struct file *file, long pages)
24025  {
24026 -       const unsigned long stack_flags
24027 -               = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
24028 -
24029         if (file) {
24030                 mm->shared_vm += pages;
24031                 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
24032                         mm->exec_vm += pages;
24033 -       } else if (flags & stack_flags)
24034 +       } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
24035                 mm->stack_vm += pages;
24036         if (flags & (VM_RESERVED|VM_IO))
24037                 mm->reserved_vm += pages;
24038 @@ -875,10 +882,55 @@ void vm_stat_account(struct mm_struct *m
24039   * The caller must hold down_write(current->mm->mmap_sem).
24040   */
24041  
24042 +#ifdef CONFIG_PAX_SEGMEXEC
24043 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
24044 +                       unsigned long len, unsigned long prot,
24045 +                       unsigned long flags, unsigned long pgoff);
24046 +
24047  unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
24048                         unsigned long len, unsigned long prot,
24049                         unsigned long flags, unsigned long pgoff)
24050  {
24051 +       unsigned long ret = -EINVAL;
24052 +
24053 +       if (flags & MAP_MIRROR)
24054 +               return ret;
24055 +
24056 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
24057 +           (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
24058 +               return ret;
24059 +
24060 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
24061 +
24062 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
24063 +
24064 +#ifdef CONFIG_PAX_MPROTECT
24065 +           && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
24066 +#endif
24067 +
24068 +          )
24069 +       {
24070 +               unsigned long ret_m;
24071 +               prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
24072 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
24073 +               if (ret_m >= TASK_SIZE) {
24074 +                       do_munmap(current->mm, ret, len);
24075 +                       ret = ret_m;
24076 +               }
24077 +       }
24078 +
24079 +       return ret;
24080 +}
24081 +
24082 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
24083 +                       unsigned long len, unsigned long prot,
24084 +                       unsigned long flags, unsigned long pgoff)
24085 +#else
24086 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
24087 +                       unsigned long len, unsigned long prot,
24088 +                       unsigned long flags, unsigned long pgoff)
24089 +#endif
24090 +{
24091         struct mm_struct * mm = current->mm;
24092         struct vm_area_struct * vma, * prev;
24093         struct inode *inode;
24094 @@ -889,6 +941,28 @@ unsigned long do_mmap_pgoff(struct file 
24095         int accountable = 1;
24096         unsigned long charged = 0, reqprot = prot;
24097  
24098 +#ifdef CONFIG_PAX_SEGMEXEC
24099 +       struct vm_area_struct * vma_m = NULL;
24100 +
24101 +       if (flags & MAP_MIRROR) {
24102 +               /* PaX: sanity checks, to be removed when proved to be stable */
24103 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
24104 +                       return -EINVAL;
24105 +
24106 +               vma_m = find_vma(mm, pgoff);
24107 +
24108 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
24109 +                   vma_m->vm_start != pgoff ||
24110 +                   (vma_m->vm_flags & VM_SPECIAL) ||
24111 +                   (prot & PROT_WRITE))
24112 +                       return -EINVAL;
24113 +
24114 +               file = vma_m->vm_file;
24115 +               pgoff = vma_m->vm_pgoff;
24116 +               len = vma_m->vm_end - vma_m->vm_start;
24117 +       }
24118 +#endif
24119 +
24120         if (file) {
24121                 if (is_file_hugepages(file))
24122                         accountable = 0;
24123 @@ -929,7 +1003,7 @@ unsigned long do_mmap_pgoff(struct file 
24124         /* Obtain the address to map to. we verify (or select) it and ensure
24125          * that it represents a valid section of the address space.
24126          */
24127 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
24128 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
24129         if (addr & ~PAGE_MASK)
24130                 return addr;
24131  
24132 @@ -940,6 +1014,24 @@ unsigned long do_mmap_pgoff(struct file 
24133         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
24134                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
24135  
24136 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
24137 +               vm_flags &= ~VM_MAYEXEC;
24138 +
24139 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
24140 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
24141 +
24142 +#ifdef CONFIG_PAX_MPROTECT
24143 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
24144 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
24145 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
24146 +                       else
24147 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
24148 +               }
24149 +#endif
24150 +
24151 +       }
24152 +#endif
24153 +
24154         if (flags & MAP_LOCKED) {
24155                 if (!can_do_mlock())
24156                         return -EPERM;
24157 @@ -952,6 +1044,7 @@ unsigned long do_mmap_pgoff(struct file 
24158                 locked += mm->locked_vm;
24159                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
24160                 lock_limit >>= PAGE_SHIFT;
24161 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24162                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
24163                         return -EAGAIN;
24164         }
24165 @@ -999,6 +1092,11 @@ unsigned long do_mmap_pgoff(struct file 
24166                         /*
24167                          * Set pgoff according to addr for anon_vma.
24168                          */
24169 +
24170 +#ifdef CONFIG_PAX_SEGMEXEC
24171 +                       if (!(flags & MAP_MIRROR))
24172 +#endif
24173 +
24174                         pgoff = addr >> PAGE_SHIFT;
24175                         break;
24176                 default:
24177 @@ -1010,14 +1108,17 @@ unsigned long do_mmap_pgoff(struct file 
24178         if (error)
24179                 return error;
24180                 
24181 +       if (!gr_acl_handle_mmap(file, prot))
24182 +               return -EACCES;
24183 +
24184         /* Clear old maps */
24185         error = -ENOMEM;
24186 -munmap_back:
24187         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24188         if (vma && vma->vm_start < addr + len) {
24189                 if (do_munmap(mm, addr, len))
24190                         return -ENOMEM;
24191 -               goto munmap_back;
24192 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24193 +               BUG_ON(vma && vma->vm_start < addr + len);
24194         }
24195  
24196         /* Check against address space limit. */
24197 @@ -1065,6 +1166,13 @@ munmap_back:
24198         vma->vm_start = addr;
24199         vma->vm_end = addr + len;
24200         vma->vm_flags = vm_flags;
24201 +
24202 +#ifdef CONFIG_PAX_PAGEEXEC
24203 +       if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
24204 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
24205 +       else
24206 +#endif
24207 +
24208         vma->vm_page_prot = protection_map[vm_flags & 0x0f];
24209         vma->vm_pgoff = pgoff;
24210  
24211 @@ -1089,6 +1197,14 @@ munmap_back:
24212                         goto free_vma;
24213         }
24214  
24215 +#ifdef CONFIG_PAX_SEGMEXEC
24216 +       if (flags & MAP_MIRROR) {
24217 +               vma_m->vm_flags |= VM_MIRROR;
24218 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
24219 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
24220 +       }
24221 +#endif
24222 +
24223         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
24224          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
24225          * that memory reservation must be checked; but that reservation
24226 @@ -1124,6 +1240,7 @@ munmap_back:
24227  out:   
24228         mm->total_vm += len >> PAGE_SHIFT;
24229         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
24230 +       track_exec_limit(mm, addr, addr + len, vm_flags);
24231         if (vm_flags & VM_LOCKED) {
24232                 mm->locked_vm += len >> PAGE_SHIFT;
24233                 make_pages_present(addr, addr + len);
24234 @@ -1178,6 +1295,10 @@ arch_get_unmapped_area(struct file *filp
24235         if (len > TASK_SIZE)
24236                 return -ENOMEM;
24237  
24238 +#ifdef CONFIG_PAX_RANDMMAP
24239 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
24240 +#endif
24241 +
24242         if (addr) {
24243                 addr = PAGE_ALIGN(addr);
24244                 vma = find_vma(mm, addr);
24245 @@ -1188,7 +1309,7 @@ arch_get_unmapped_area(struct file *filp
24246         if (len > mm->cached_hole_size) {
24247                 start_addr = addr = mm->free_area_cache;
24248         } else {
24249 -               start_addr = addr = TASK_UNMAPPED_BASE;
24250 +               start_addr = addr = mm->mmap_base;
24251                 mm->cached_hole_size = 0;
24252         }
24253  
24254 @@ -1200,9 +1321,8 @@ full_search:
24255                          * Start a new search - just in case we missed
24256                          * some holes.
24257                          */
24258 -                       if (start_addr != TASK_UNMAPPED_BASE) {
24259 -                               addr = TASK_UNMAPPED_BASE;
24260 -                               start_addr = addr;
24261 +                       if (start_addr != mm->mmap_base) {
24262 +                               start_addr = addr = mm->mmap_base;
24263                                 mm->cached_hole_size = 0;
24264                                 goto full_search;
24265                         }
24266 @@ -1227,7 +1347,7 @@ void arch_unmap_area(struct mm_struct *m
24267         /*
24268          * Is this a new hole at the lowest possible address?
24269          */
24270 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
24271 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
24272                 mm->free_area_cache = addr;
24273                 mm->cached_hole_size = ~0UL;
24274         }
24275 @@ -1245,12 +1365,16 @@ arch_get_unmapped_area_topdown(struct fi
24276  {
24277         struct vm_area_struct *vma;
24278         struct mm_struct *mm = current->mm;
24279 -       unsigned long addr = addr0;
24280 +       unsigned long base = mm->mmap_base, addr = addr0;
24281  
24282         /* requested length too big for entire address space */
24283         if (len > TASK_SIZE)
24284                 return -ENOMEM;
24285  
24286 +#ifdef CONFIG_PAX_RANDMMAP
24287 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
24288 +#endif
24289 +
24290         /* requesting a specific address */
24291         if (addr) {
24292                 addr = PAGE_ALIGN(addr);
24293 @@ -1308,13 +1432,21 @@ bottomup:
24294          * can happen with large stack limits and large mmap()
24295          * allocations.
24296          */
24297 +       mm->mmap_base = TASK_UNMAPPED_BASE;
24298 +
24299 +#ifdef CONFIG_PAX_RANDMMAP
24300 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
24301 +               mm->mmap_base += mm->delta_mmap;
24302 +#endif
24303 +
24304 +       mm->free_area_cache = mm->mmap_base;
24305         mm->cached_hole_size = ~0UL;
24306 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
24307         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
24308         /*
24309          * Restore the topdown base:
24310          */
24311 -       mm->free_area_cache = mm->mmap_base;
24312 +       mm->mmap_base = base;
24313 +       mm->free_area_cache = base;
24314         mm->cached_hole_size = ~0UL;
24315  
24316         return addr;
24317 @@ -1330,8 +1462,10 @@ void arch_unmap_area_topdown(struct mm_s
24318                 mm->free_area_cache = addr;
24319  
24320         /* dont allow allocations above current base */
24321 -       if (mm->free_area_cache > mm->mmap_base)
24322 +       if (mm->free_area_cache > mm->mmap_base) {
24323                 mm->free_area_cache = mm->mmap_base;
24324 +               mm->cached_hole_size = ~0UL;
24325 +       }
24326  }
24327  
24328  unsigned long
24329 @@ -1464,6 +1598,7 @@ static int acct_stack_growth(struct vm_a
24330                 return -ENOMEM;
24331  
24332         /* Stack limit test */
24333 +       gr_learn_resource(current, RLIMIT_STACK, size, 1);
24334         if (size > rlim[RLIMIT_STACK].rlim_cur)
24335                 return -ENOMEM;
24336  
24337 @@ -1473,6 +1608,7 @@ static int acct_stack_growth(struct vm_a
24338                 unsigned long limit;
24339                 locked = mm->locked_vm + grow;
24340                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
24341 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24342                 if (locked > limit && !capable(CAP_IPC_LOCK))
24343                         return -ENOMEM;
24344         }
24345 @@ -1590,13 +1726,49 @@ int expand_stack(struct vm_area_struct *
24346         if (address < vma->vm_start) {
24347                 unsigned long size, grow;
24348  
24349 +#ifdef CONFIG_PAX_SEGMEXEC
24350 +               struct vm_area_struct *vma_m = NULL;
24351 +               unsigned long address_m = 0UL;
24352 +
24353 +               if (vma->vm_flags & VM_MIRROR) {
24354 +                       address_m = vma->vm_start + vma->vm_mirror;
24355 +                       vma_m = find_vma(vma->vm_mm, address_m);
24356 +                       if (!vma_m || vma_m->vm_start != address_m ||
24357 +                           !(vma_m->vm_flags & VM_MIRROR) ||
24358 +                           vma->vm_end - vma->vm_start !=
24359 +                           vma_m->vm_end - vma_m->vm_start ||
24360 +                           vma->anon_vma != vma_m->anon_vma) {
24361 +                               printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
24362 +                                      address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
24363 +                               anon_vma_unlock(vma);
24364 +                               return -EFAULT;
24365 +                       }
24366 +                       address_m = address + vma->vm_mirror;
24367 +               }
24368 +#endif
24369 +
24370                 size = vma->vm_end - address;
24371                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
24372  
24373 +#ifdef CONFIG_PAX_SEGMEXEC
24374 +               if (vma_m)
24375 +                       error = acct_stack_growth(vma, size, 2*grow);
24376 +               else
24377 +#endif
24378 +
24379                 error = acct_stack_growth(vma, size, grow);
24380                 if (!error) {
24381                         vma->vm_start = address;
24382                         vma->vm_pgoff -= grow;
24383 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
24384 +
24385 +#ifdef CONFIG_PAX_SEGMEXEC
24386 +                       if (vma_m) {
24387 +                               vma_m->vm_start = address_m;
24388 +                               vma_m->vm_pgoff -= grow;
24389 +                       }
24390 +#endif
24391 +
24392                 }
24393         }
24394         anon_vma_unlock(vma);
24395 @@ -1758,7 +1930,24 @@ int split_vma(struct mm_struct * mm, str
24396   * work.  This now handles partial unmappings.
24397   * Jeremy Fitzhardinge <jeremy@goop.org>
24398   */
24399 +#ifdef CONFIG_PAX_SEGMEXEC
24400 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
24401 +
24402 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24403 +{
24404 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
24405 +               int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
24406 +               if (ret)
24407 +                       return ret;
24408 +       }
24409 +
24410 +       return __do_munmap(mm, start, len);
24411 +}
24412 +
24413 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24414 +#else
24415  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
24416 +#endif
24417  {
24418         unsigned long end;
24419         struct vm_area_struct *vma, *prev, *last;
24420 @@ -1812,6 +2001,8 @@ int do_munmap(struct mm_struct *mm, unsi
24421         /* Fix up all other VM information */
24422         remove_vma_list(mm, vma);
24423  
24424 +       track_exec_limit(mm, start, end, 0UL);
24425 +
24426         return 0;
24427  }
24428  
24429 @@ -1824,6 +2015,12 @@ asmlinkage long sys_munmap(unsigned long
24430  
24431         profile_munmap(addr);
24432  
24433 +#ifdef CONFIG_PAX_SEGMEXEC
24434 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
24435 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
24436 +               return -EINVAL;
24437 +#endif
24438 +
24439         down_write(&mm->mmap_sem);
24440         ret = do_munmap(mm, addr, len);
24441         up_write(&mm->mmap_sem);
24442 @@ -1845,11 +2042,35 @@ static inline void verify_mm_writelocked
24443   *  anonymous maps.  eventually we may be able to do some
24444   *  brk-specific accounting here.
24445   */
24446 +#ifdef CONFIG_PAX_SEGMEXEC
24447 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
24448 +
24449  unsigned long do_brk(unsigned long addr, unsigned long len)
24450  {
24451 +       unsigned long ret;
24452 +
24453 +       ret = __do_brk(addr, len);
24454 +       if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
24455 +               unsigned long ret_m;
24456 +
24457 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
24458 +               if (ret_m > TASK_SIZE) {
24459 +                       do_munmap(current->mm, addr, len);
24460 +                       ret = ret_m;
24461 +               }
24462 +       }
24463 +
24464 +       return ret;
24465 +}
24466 +
24467 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
24468 +#else
24469 +unsigned long do_brk(unsigned long addr, unsigned long len)
24470 +#endif
24471 +{
24472         struct mm_struct * mm = current->mm;
24473         struct vm_area_struct * vma, * prev;
24474 -       unsigned long flags;
24475 +       unsigned long flags, task_size = TASK_SIZE;
24476         struct rb_node ** rb_link, * rb_parent;
24477         pgoff_t pgoff = addr >> PAGE_SHIFT;
24478  
24479 @@ -1857,7 +2078,12 @@ unsigned long do_brk(unsigned long addr,
24480         if (!len)
24481                 return addr;
24482  
24483 -       if ((addr + len) > TASK_SIZE || (addr + len) < addr)
24484 +#ifdef CONFIG_PAX_SEGMEXEC
24485 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
24486 +               task_size = SEGMEXEC_TASK_SIZE;
24487 +#endif
24488 +
24489 +       if ((addr + len) > task_size || (addr + len) < addr)
24490                 return -EINVAL;
24491  
24492         /*
24493 @@ -1869,6 +2095,7 @@ unsigned long do_brk(unsigned long addr,
24494                 locked += mm->locked_vm;
24495                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
24496                 lock_limit >>= PAGE_SHIFT;
24497 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
24498                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
24499                         return -EAGAIN;
24500         }
24501 @@ -1882,12 +2109,12 @@ unsigned long do_brk(unsigned long addr,
24502         /*
24503          * Clear old maps.  this also does some error checking for us
24504          */
24505 - munmap_back:
24506         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24507         if (vma && vma->vm_start < addr + len) {
24508                 if (do_munmap(mm, addr, len))
24509                         return -ENOMEM;
24510 -               goto munmap_back;
24511 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
24512 +               BUG_ON(vma && vma->vm_start < addr + len);
24513         }
24514  
24515         /* Check against address space limits *after* clearing old maps... */
24516 @@ -1902,6 +2129,18 @@ unsigned long do_brk(unsigned long addr,
24517  
24518         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
24519  
24520 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
24521 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
24522 +               flags &= ~VM_EXEC;
24523 +
24524 +#ifdef CONFIG_PAX_MPROTECT
24525 +               if (mm->pax_flags & MF_PAX_MPROTECT)
24526 +                       flags &= ~VM_MAYEXEC;
24527 +#endif
24528 +
24529 +       }
24530 +#endif
24531 +
24532         /* Can we just expand an old private anonymous mapping? */
24533         if (vma_merge(mm, prev, addr, addr + len, flags,
24534                                         NULL, NULL, pgoff, NULL))
24535 @@ -1921,6 +2160,13 @@ unsigned long do_brk(unsigned long addr,
24536         vma->vm_end = addr + len;
24537         vma->vm_pgoff = pgoff;
24538         vma->vm_flags = flags;
24539 +
24540 +#ifdef CONFIG_PAX_PAGEEXEC
24541 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
24542 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
24543 +       else
24544 +#endif
24545 +
24546         vma->vm_page_prot = protection_map[flags & 0x0f];
24547         vma_link(mm, vma, prev, rb_link, rb_parent);
24548  out:
24549 @@ -1929,6 +2175,7 @@ out:
24550                 mm->locked_vm += len >> PAGE_SHIFT;
24551                 make_pages_present(addr, addr + len);
24552         }
24553 +       track_exec_limit(mm, addr, addr + len, flags);
24554         return addr;
24555  }
24556  
24557 @@ -2061,7 +2308,7 @@ int may_expand_vm(struct mm_struct *mm, 
24558         unsigned long lim;
24559  
24560         lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
24561 -
24562 +       gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
24563         if (cur + npages > lim)
24564                 return 0;
24565         return 1;
24566 diff -urNp linux-2.6.17.7/mm/mprotect.c linux-2.6.17.7/mm/mprotect.c
24567 --- linux-2.6.17.7/mm/mprotect.c        2006-07-24 23:36:01.000000000 -0400
24568 +++ linux-2.6.17.7/mm/mprotect.c        2006-08-01 20:29:48.000000000 -0400
24569 @@ -19,11 +19,18 @@
24570  #include <linux/mempolicy.h>
24571  #include <linux/personality.h>
24572  #include <linux/syscalls.h>
24573 +#include <linux/grsecurity.h>
24574 +
24575 +#ifdef CONFIG_PAX_MPROTECT
24576 +#include <linux/elf.h>
24577 +#include <linux/fs.h>
24578 +#endif
24579  
24580  #include <asm/uaccess.h>
24581  #include <asm/pgtable.h>
24582  #include <asm/cacheflush.h>
24583  #include <asm/tlbflush.h>
24584 +#include <asm/mmu_context.h>
24585  
24586  static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
24587                 unsigned long addr, unsigned long end, pgprot_t newprot)
24588 @@ -98,6 +105,94 @@ static void change_protection(struct vm_
24589         flush_tlb_range(vma, start, end);
24590  }
24591  
24592 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24593 +/* called while holding the mmap semaphor for writing */
24594 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
24595 +{
24596 +       struct vm_area_struct *vma = find_vma(mm, start);
24597 +
24598 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
24599 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
24600 +
24601 +}
24602 +
24603 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
24604 +{
24605 +       unsigned long oldlimit, newlimit = 0UL;
24606 +
24607 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
24608 +               return;
24609 +
24610 +       spin_lock(&mm->page_table_lock);
24611 +       oldlimit = mm->context.user_cs_limit;
24612 +       if ((prot & VM_EXEC) && oldlimit < end)
24613 +               /* USER_CS limit moved up */
24614 +               newlimit = end;
24615 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
24616 +               /* USER_CS limit moved down */
24617 +               newlimit = start;
24618 +
24619 +       if (newlimit) {
24620 +               mm->context.user_cs_limit = newlimit;
24621 +
24622 +#ifdef CONFIG_SMP
24623 +               wmb();
24624 +               cpus_clear(mm->context.cpu_user_cs_mask);
24625 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
24626 +#endif
24627 +
24628 +               set_user_cs(mm, smp_processor_id());
24629 +       }
24630 +       spin_unlock(&mm->page_table_lock);
24631 +       if (newlimit == end)
24632 +               establish_user_cs_limit(mm, oldlimit, end);
24633 +}
24634 +#endif
24635 +
24636 +#ifdef CONFIG_PAX_SEGMEXEC
24637 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24638 +       unsigned long start, unsigned long end, unsigned int newflags);
24639 +
24640 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24641 +       unsigned long start, unsigned long end, unsigned int newflags)
24642 +{
24643 +       if (vma->vm_flags & VM_MIRROR) {
24644 +               struct vm_area_struct * vma_m, * prev_m;
24645 +               unsigned long start_m, end_m;
24646 +               int error;
24647 +
24648 +               start_m = vma->vm_start + vma->vm_mirror;
24649 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
24650 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
24651 +                       start_m = start + vma->vm_mirror;
24652 +                       end_m = end + vma->vm_mirror;
24653 +
24654 +                       if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
24655 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
24656 +                       else
24657 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
24658 +                       if (error)
24659 +                               return error;
24660 +               } else {
24661 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
24662 +                       return -ENOMEM;
24663 +               }
24664 +       }
24665 +
24666 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
24667 +}
24668 +
24669 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24670 +       unsigned long start, unsigned long end, unsigned int newflags)
24671 +{
24672 +       struct mm_struct * mm = vma->vm_mm;
24673 +       unsigned long oldflags = vma->vm_flags;
24674 +       long nrpages = (end - start) >> PAGE_SHIFT;
24675 +       unsigned long charged = 0;
24676 +       pgprot_t newprot;
24677 +       pgoff_t pgoff;
24678 +       int error;
24679 +#else
24680  static int
24681  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
24682         unsigned long start, unsigned long end, unsigned long newflags)
24683 @@ -114,6 +209,7 @@ mprotect_fixup(struct vm_area_struct *vm
24684                 *pprev = vma;
24685                 return 0;
24686         }
24687 +#endif
24688  
24689         /*
24690          * If we make a private mapping writable we increase our commit;
24691 @@ -132,6 +228,12 @@ mprotect_fixup(struct vm_area_struct *vm
24692                 }
24693         }
24694  
24695 +#ifdef CONFIG_PAX_PAGEEXEC
24696 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
24697 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
24698 +       else
24699 +#endif
24700 +
24701         newprot = protection_map[newflags & 0xf];
24702  
24703         /*
24704 @@ -179,6 +281,69 @@ fail:
24705         return error;
24706  }
24707  
24708 +#ifdef CONFIG_PAX_MPROTECT
24709 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
24710 + * therefore we'll grant them VM_MAYWRITE once during their life.
24711 + *
24712 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
24713 + * basis because we want to allow the common case and not the special ones.
24714 + */
24715 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
24716 +{
24717 +       struct elfhdr elf_h;
24718 +       struct elf_phdr elf_p, p_dyn;
24719 +       elf_dyn dyn;
24720 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
24721 +
24722 +#ifndef CONFIG_PAX_NOELFRELOCS
24723 +       if ((vma->vm_start != start) ||
24724 +           !vma->vm_file ||
24725 +           !(vma->vm_flags & VM_MAYEXEC) ||
24726 +           (vma->vm_flags & VM_MAYNOTWRITE))
24727 +#endif
24728 +
24729 +               return;
24730 +
24731 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
24732 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
24733 +
24734 +#ifdef CONFIG_PAX_ETEXECRELOCS
24735 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
24736 +#else
24737 +           elf_h.e_type != ET_DYN ||
24738 +#endif
24739 +
24740 +           !elf_check_arch(&elf_h) ||
24741 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
24742 +           elf_h.e_phnum > j)
24743 +               return;
24744 +
24745 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
24746 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
24747 +                       return;
24748 +               if (elf_p.p_type == PT_DYNAMIC) {
24749 +                       p_dyn = elf_p;
24750 +                       j = i;
24751 +               }
24752 +       }
24753 +       if (elf_h.e_phnum <= j)
24754 +               return;
24755 +
24756 +       i = 0UL;
24757 +       do {
24758 +               if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
24759 +                       return;
24760 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
24761 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
24762 +                       gr_log_textrel(vma);
24763 +                       return;
24764 +               }
24765 +               i++;
24766 +       } while (dyn.d_tag != DT_NULL);
24767 +       return;
24768 +}
24769 +#endif
24770 +
24771  asmlinkage long
24772  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
24773  {
24774 @@ -198,6 +363,17 @@ sys_mprotect(unsigned long start, size_t
24775         end = start + len;
24776         if (end <= start)
24777                 return -ENOMEM;
24778 +
24779 +#ifdef CONFIG_PAX_SEGMEXEC
24780 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
24781 +               if (end > SEGMEXEC_TASK_SIZE)
24782 +                       return -EINVAL;
24783 +       } else
24784 +#endif
24785 +
24786 +       if (end > TASK_SIZE)
24787 +               return -EINVAL;
24788 +
24789         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
24790                 return -EINVAL;
24791  
24792 @@ -238,6 +414,16 @@ sys_mprotect(unsigned long start, size_t
24793         if (start > vma->vm_start)
24794                 prev = vma;
24795  
24796 +#ifdef CONFIG_PAX_MPROTECT
24797 +       if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
24798 +               pax_handle_maywrite(vma, start);
24799 +#endif
24800 +
24801 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
24802 +               error = -EACCES;
24803 +               goto out;
24804 +       }
24805 +
24806         for (nstart = start ; ; ) {
24807                 unsigned long newflags;
24808  
24809 @@ -251,6 +437,12 @@ sys_mprotect(unsigned long start, size_t
24810                         goto out;
24811                 }
24812  
24813 +#ifdef CONFIG_PAX_MPROTECT
24814 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
24815 +               if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
24816 +                       newflags &= ~VM_MAYWRITE;
24817 +#endif
24818 +
24819                 error = security_file_mprotect(vma, reqprot, prot);
24820                 if (error)
24821                         goto out;
24822 @@ -274,6 +466,9 @@ sys_mprotect(unsigned long start, size_t
24823                         goto out;
24824                 }
24825         }
24826 +
24827 +       track_exec_limit(current->mm, start, end, vm_flags);
24828 +
24829  out:
24830         up_write(&current->mm->mmap_sem);
24831         return error;
24832 diff -urNp linux-2.6.17.7/mm/mremap.c linux-2.6.17.7/mm/mremap.c
24833 --- linux-2.6.17.7/mm/mremap.c  2006-07-24 23:36:01.000000000 -0400
24834 +++ linux-2.6.17.7/mm/mremap.c  2006-08-01 20:29:48.000000000 -0400
24835 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
24836                 pte = ptep_clear_flush(vma, old_addr, old_pte);
24837                 /* ZERO_PAGE can be dependant on virtual addr */
24838                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
24839 +
24840 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24841 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
24842 +                       pte_exprotect(pte);
24843 +#endif
24844 +
24845                 set_pte_at(mm, new_addr, new_pte, pte);
24846         }
24847  
24848 @@ -253,6 +259,7 @@ unsigned long do_mremap(unsigned long ad
24849         struct vm_area_struct *vma;
24850         unsigned long ret = -EINVAL;
24851         unsigned long charged = 0;
24852 +       unsigned long task_size = TASK_SIZE;
24853  
24854         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
24855                 goto out;
24856 @@ -271,6 +278,15 @@ unsigned long do_mremap(unsigned long ad
24857         if (!new_len)
24858                 goto out;
24859  
24860 +#ifdef CONFIG_PAX_SEGMEXEC
24861 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
24862 +               task_size = SEGMEXEC_TASK_SIZE;
24863 +#endif
24864 +
24865 +       if (new_len > task_size || addr > task_size-new_len ||
24866 +           old_len > task_size || addr > task_size-old_len)
24867 +               goto out;
24868 +
24869         /* new_addr is only valid if MREMAP_FIXED is specified */
24870         if (flags & MREMAP_FIXED) {
24871                 if (new_addr & ~PAGE_MASK)
24872 @@ -278,16 +294,13 @@ unsigned long do_mremap(unsigned long ad
24873                 if (!(flags & MREMAP_MAYMOVE))
24874                         goto out;
24875  
24876 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
24877 +               if (new_addr > task_size - new_len)
24878                         goto out;
24879  
24880                 /* Check if the location we're moving into overlaps the
24881                  * old location at all, and fail if it does.
24882                  */
24883 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
24884 -                       goto out;
24885 -
24886 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
24887 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
24888                         goto out;
24889  
24890                 ret = do_munmap(mm, new_addr, new_len);
24891 @@ -321,6 +334,14 @@ unsigned long do_mremap(unsigned long ad
24892                 ret = -EINVAL;
24893                 goto out;
24894         }
24895 +
24896 +#ifdef CONFIG_PAX_SEGMEXEC
24897 +       if (vma->vm_flags & VM_MIRROR) {
24898 +               ret = -EINVAL;
24899 +               goto out;
24900 +       }
24901 +#endif
24902 +
24903         /* We can't remap across vm area boundaries */
24904         if (old_len > vma->vm_end - addr)
24905                 goto out;
24906 @@ -354,7 +375,7 @@ unsigned long do_mremap(unsigned long ad
24907         if (old_len == vma->vm_end - addr &&
24908             !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
24909             (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
24910 -               unsigned long max_addr = TASK_SIZE;
24911 +               unsigned long max_addr = task_size;
24912                 if (vma->vm_next)
24913                         max_addr = vma->vm_next->vm_start;
24914                 /* can we just expand the current mapping? */
24915 @@ -372,6 +393,7 @@ unsigned long do_mremap(unsigned long ad
24916                                                    addr + new_len);
24917                         }
24918                         ret = addr;
24919 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
24920                         goto out;
24921                 }
24922         }
24923 @@ -382,8 +404,8 @@ unsigned long do_mremap(unsigned long ad
24924          */
24925         ret = -ENOMEM;
24926         if (flags & MREMAP_MAYMOVE) {
24927 +               unsigned long map_flags = 0;
24928                 if (!(flags & MREMAP_FIXED)) {
24929 -                       unsigned long map_flags = 0;
24930                         if (vma->vm_flags & VM_MAYSHARE)
24931                                 map_flags |= MAP_SHARED;
24932  
24933 @@ -393,7 +415,12 @@ unsigned long do_mremap(unsigned long ad
24934                         if (new_addr & ~PAGE_MASK)
24935                                 goto out;
24936                 }
24937 +               map_flags = vma->vm_flags;
24938                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
24939 +               if (!(ret & ~PAGE_MASK)) {
24940 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
24941 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
24942 +               }
24943         }
24944  out:
24945         if (ret & ~PAGE_MASK)
24946 diff -urNp linux-2.6.17.7/mm/page_alloc.c linux-2.6.17.7/mm/page_alloc.c
24947 --- linux-2.6.17.7/mm/page_alloc.c      2006-07-24 23:36:01.000000000 -0400
24948 +++ linux-2.6.17.7/mm/page_alloc.c      2006-08-01 20:29:48.000000000 -0400
24949 @@ -334,7 +334,7 @@ static inline int page_is_buddy(struct p
24950  static inline void __free_one_page(struct page *page,
24951                 struct zone *zone, unsigned int order)
24952  {
24953 -       unsigned long page_idx;
24954 +       unsigned long page_idx, index;
24955         int order_size = 1 << order;
24956  
24957         if (unlikely(PageCompound(page)))
24958 @@ -345,6 +345,11 @@ static inline void __free_one_page(struc
24959         BUG_ON(page_idx & (order_size - 1));
24960         BUG_ON(bad_range(zone, page));
24961  
24962 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
24963 +       for (index = order_size; index; --index)
24964 +               clear_highpage(page + index - 1);
24965 +#endif
24966 +
24967         zone->free_pages += order_size;
24968         while (order < MAX_ORDER-1) {
24969                 unsigned long combined_idx;
24970 diff -urNp linux-2.6.17.7/mm/rmap.c linux-2.6.17.7/mm/rmap.c
24971 --- linux-2.6.17.7/mm/rmap.c    2006-07-24 23:36:01.000000000 -0400
24972 +++ linux-2.6.17.7/mm/rmap.c    2006-08-01 20:29:48.000000000 -0400
24973 @@ -106,6 +106,19 @@ int anon_vma_prepare(struct vm_area_stru
24974                         list_add(&vma->anon_vma_node, &anon_vma->head);
24975                         allocated = NULL;
24976                 }
24977 +
24978 +#ifdef CONFIG_PAX_SEGMEXEC
24979 +               if (vma->vm_flags & VM_MIRROR) {
24980 +                       struct vm_area_struct *vma_m;
24981 +
24982 +                       vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
24983 +                       BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
24984 +                       BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
24985 +                       vma_m->anon_vma = anon_vma;
24986 +                       __anon_vma_link(vma_m);
24987 +               }
24988 +#endif
24989 +
24990                 spin_unlock(&mm->page_table_lock);
24991  
24992                 if (locked)
24993 diff -urNp linux-2.6.17.7/mm/shmem.c linux-2.6.17.7/mm/shmem.c
24994 --- linux-2.6.17.7/mm/shmem.c   2006-07-24 23:36:01.000000000 -0400
24995 +++ linux-2.6.17.7/mm/shmem.c   2006-08-01 20:29:48.000000000 -0400
24996 @@ -2245,7 +2245,7 @@ static struct file_system_type tmpfs_fs_
24997         .get_sb         = shmem_get_sb,
24998         .kill_sb        = kill_litter_super,
24999  };
25000 -static struct vfsmount *shm_mnt;
25001 +struct vfsmount *shm_mnt;
25002  
25003  static int __init init_tmpfs(void)
25004  {
25005 diff -urNp linux-2.6.17.7/mm/tiny-shmem.c linux-2.6.17.7/mm/tiny-shmem.c
25006 --- linux-2.6.17.7/mm/tiny-shmem.c      2006-07-24 23:36:01.000000000 -0400
25007 +++ linux-2.6.17.7/mm/tiny-shmem.c      2006-08-01 20:29:48.000000000 -0400
25008 @@ -27,7 +27,7 @@ static struct file_system_type tmpfs_fs_
25009         .kill_sb        = kill_litter_super,
25010  };
25011  
25012 -static struct vfsmount *shm_mnt;
25013 +struct vfsmount *shm_mnt;
25014  
25015  static int __init init_tmpfs(void)
25016  {
25017 diff -urNp linux-2.6.17.7/mm/vmalloc.c linux-2.6.17.7/mm/vmalloc.c
25018 --- linux-2.6.17.7/mm/vmalloc.c 2006-07-24 23:36:01.000000000 -0400
25019 +++ linux-2.6.17.7/mm/vmalloc.c 2006-08-01 20:29:48.000000000 -0400
25020 @@ -193,6 +193,8 @@ struct vm_struct *__get_vm_area_node(uns
25021  
25022         write_lock(&vmlist_lock);
25023         for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
25024 +               if (addr > end - size)
25025 +                       goto out;
25026                 if ((unsigned long)tmp->addr < addr) {
25027                         if((unsigned long)tmp->addr + tmp->size >= addr)
25028                                 addr = ALIGN(tmp->size + 
25029 @@ -204,8 +206,6 @@ struct vm_struct *__get_vm_area_node(uns
25030                 if (size + addr <= (unsigned long)tmp->addr)
25031                         goto found;
25032                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
25033 -               if (addr > end - size)
25034 -                       goto out;
25035         }
25036  
25037  found:
25038 diff -urNp linux-2.6.17.7/net/ipv4/inet_connection_sock.c linux-2.6.17.7/net/ipv4/inet_connection_sock.c
25039 --- linux-2.6.17.7/net/ipv4/inet_connection_sock.c      2006-07-24 23:36:01.000000000 -0400
25040 +++ linux-2.6.17.7/net/ipv4/inet_connection_sock.c      2006-08-01 20:29:48.000000000 -0400
25041 @@ -16,6 +16,7 @@
25042  #include <linux/config.h>
25043  #include <linux/module.h>
25044  #include <linux/jhash.h>
25045 +#include <linux/grsecurity.h>
25046  
25047  #include <net/inet_connection_sock.h>
25048  #include <net/inet_hashtables.h>
25049 diff -urNp linux-2.6.17.7/net/ipv4/inet_hashtables.c linux-2.6.17.7/net/ipv4/inet_hashtables.c
25050 --- linux-2.6.17.7/net/ipv4/inet_hashtables.c   2006-07-24 23:36:01.000000000 -0400
25051 +++ linux-2.6.17.7/net/ipv4/inet_hashtables.c   2006-08-01 20:29:48.000000000 -0400
25052 @@ -19,11 +19,14 @@
25053  #include <linux/sched.h>
25054  #include <linux/slab.h>
25055  #include <linux/wait.h>
25056 +#include <linux/grsecurity.h>
25057  
25058  #include <net/inet_connection_sock.h>
25059  #include <net/inet_hashtables.h>
25060  #include <net/ip.h>
25061  
25062 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
25063 +
25064  /*
25065   * Allocate and initialize a new local port bind bucket.
25066   * The bindhash mutex for snum's hash chain must be held here.
25067 @@ -310,6 +313,8 @@ ok:
25068                 }
25069                 spin_unlock(&head->lock);
25070  
25071 +               gr_update_task_in_ip_table(current, inet_sk(sk));
25072 +
25073                 if (tw) {
25074                         inet_twsk_deschedule(tw, death_row);
25075                         inet_twsk_put(tw);
25076 diff -urNp linux-2.6.17.7/net/ipv4/netfilter/Kconfig linux-2.6.17.7/net/ipv4/netfilter/Kconfig
25077 --- linux-2.6.17.7/net/ipv4/netfilter/Kconfig   2006-07-24 23:36:01.000000000 -0400
25078 +++ linux-2.6.17.7/net/ipv4/netfilter/Kconfig   2006-08-01 20:29:48.000000000 -0400
25079 @@ -314,6 +314,21 @@ config IP_NF_MATCH_HASHLIMIT
25080           destination IP' or `500pps from any given source IP'  with a single
25081           IPtables rule.
25082  
25083 +config IP_NF_MATCH_STEALTH
25084 +       tristate "stealth match support"
25085 +       depends on IP_NF_IPTABLES
25086 +       help
25087 +         Enabling this option will drop all syn packets coming to unserved tcp
25088 +         ports as well as all packets coming to unserved udp ports.  If you
25089 +         are using your system to route any type of packets (ie. via NAT)
25090 +         you should put this module at the end of your ruleset, since it will
25091 +         drop packets that aren't going to ports that are listening on your
25092 +         machine itself, it doesn't take into account that the packet might be
25093 +         destined for someone on your internal network if you're using NAT for
25094 +         instance.
25095 +
25096 +         To compile it as a module, choose M here.  If unsure, say N.
25097 +
25098  # `filter', generic and specific targets
25099  config IP_NF_FILTER
25100         tristate "Packet filtering"
25101 @@ -614,4 +629,3 @@ config IP_NF_ARP_MANGLE
25102           hardware and network addresses.
25103  
25104  endmenu
25105 -
25106 diff -urNp linux-2.6.17.7/net/ipv4/netfilter/Makefile linux-2.6.17.7/net/ipv4/netfilter/Makefile
25107 --- linux-2.6.17.7/net/ipv4/netfilter/Makefile  2006-07-24 23:36:01.000000000 -0400
25108 +++ linux-2.6.17.7/net/ipv4/netfilter/Makefile  2006-08-01 20:29:48.000000000 -0400
25109 @@ -61,6 +61,7 @@ obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_ds
25110  obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
25111  obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
25112  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
25113 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
25114  
25115  # targets
25116  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
25117 diff -urNp linux-2.6.17.7/net/ipv4/netfilter/ipt_stealth.c linux-2.6.17.7/net/ipv4/netfilter/ipt_stealth.c
25118 --- linux-2.6.17.7/net/ipv4/netfilter/ipt_stealth.c     1969-12-31 19:00:00.000000000 -0500
25119 +++ linux-2.6.17.7/net/ipv4/netfilter/ipt_stealth.c     2006-08-01 20:29:48.000000000 -0400
25120 @@ -0,0 +1,112 @@
25121 +/* Kernel module to add stealth support.
25122 + *
25123 + * Copyright (C) 2002,2005 Brad Spengler  <spender@grsecurity.net>
25124 + *
25125 + */
25126 +
25127 +#include <linux/kernel.h>
25128 +#include <linux/module.h>
25129 +#include <linux/skbuff.h>
25130 +#include <linux/net.h>
25131 +#include <linux/sched.h>
25132 +#include <linux/inet.h>
25133 +#include <linux/stddef.h>
25134 +
25135 +#include <net/ip.h>
25136 +#include <net/sock.h>
25137 +#include <net/tcp.h>
25138 +#include <net/udp.h>
25139 +#include <net/route.h>
25140 +#include <net/inet_common.h>
25141 +
25142 +#include <linux/netfilter_ipv4/ip_tables.h>
25143 +
25144 +MODULE_LICENSE("GPL");
25145 +
25146 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
25147 +
25148 +static int
25149 +match(const struct sk_buff *skb,
25150 +      const struct net_device *in,
25151 +      const struct net_device *out,
25152 +      const void *matchinfo,
25153 +      int offset,
25154 +      int *hotdrop)
25155 +{
25156 +       struct iphdr *ip = skb->nh.iph;
25157 +       struct tcphdr th;
25158 +       struct udphdr uh;
25159 +       struct sock *sk = NULL;
25160 +
25161 +       if (!ip || offset) return 0;
25162 +
25163 +       switch(ip->protocol) {
25164 +       case IPPROTO_TCP:
25165 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
25166 +                       *hotdrop = 1;
25167 +                       return 0;
25168 +               }
25169 +               if (!(th.syn && !th.ack)) return 0;
25170 +               sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);        
25171 +               break;
25172 +       case IPPROTO_UDP:
25173 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
25174 +                       *hotdrop = 1;
25175 +                       return 0;
25176 +               }
25177 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
25178 +               break;
25179 +       default:
25180 +               return 0;
25181 +       }
25182 +
25183 +       if(!sk) // port is being listened on, match this
25184 +               return 1;
25185 +       else {
25186 +               sock_put(sk);
25187 +               return 0;
25188 +       }
25189 +}
25190 +
25191 +/* Called when user tries to insert an entry of this type. */
25192 +static int
25193 +checkentry(const char *tablename,
25194 +           const struct ipt_ip *ip,
25195 +           void *matchinfo,
25196 +           unsigned int matchsize,
25197 +           unsigned int hook_mask)
25198 +{
25199 +        if (matchsize != IPT_ALIGN(0))
25200 +                return 0;
25201 +
25202 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
25203 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
25204 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
25205 +                       return 1;
25206 +
25207 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
25208 +
25209 +        return 0;
25210 +}
25211 +
25212 +
25213 +static struct ipt_match stealth_match = {
25214 +       .name = "stealth",
25215 +       .match = &match,
25216 +       .checkentry = &checkentry,
25217 +       .destroy = NULL,
25218 +       .me = THIS_MODULE
25219 +};
25220 +
25221 +static int __init init(void)
25222 +{
25223 +       return ipt_register_match(&stealth_match);
25224 +}
25225 +
25226 +static void __exit fini(void)
25227 +{
25228 +       ipt_unregister_match(&stealth_match);
25229 +}
25230 +
25231 +module_init(init);
25232 +module_exit(fini);
25233 diff -urNp linux-2.6.17.7/net/ipv4/tcp_ipv4.c linux-2.6.17.7/net/ipv4/tcp_ipv4.c
25234 --- linux-2.6.17.7/net/ipv4/tcp_ipv4.c  2006-07-24 23:36:01.000000000 -0400
25235 +++ linux-2.6.17.7/net/ipv4/tcp_ipv4.c  2006-08-01 20:29:48.000000000 -0400
25236 @@ -62,6 +62,7 @@
25237  #include <linux/jhash.h>
25238  #include <linux/init.h>
25239  #include <linux/times.h>
25240 +#include <linux/grsecurity.h>
25241  
25242  #include <net/icmp.h>
25243  #include <net/inet_hashtables.h>
25244 diff -urNp linux-2.6.17.7/net/ipv4/udp.c linux-2.6.17.7/net/ipv4/udp.c
25245 --- linux-2.6.17.7/net/ipv4/udp.c       2006-07-24 23:36:01.000000000 -0400
25246 +++ linux-2.6.17.7/net/ipv4/udp.c       2006-08-01 20:29:48.000000000 -0400
25247 @@ -102,6 +102,7 @@
25248  #include <linux/skbuff.h>
25249  #include <linux/proc_fs.h>
25250  #include <linux/seq_file.h>
25251 +#include <linux/grsecurity.h>
25252  #include <net/sock.h>
25253  #include <net/udp.h>
25254  #include <net/icmp.h>
25255 @@ -110,6 +111,12 @@
25256  #include <net/checksum.h>
25257  #include <net/xfrm.h>
25258  
25259 +extern int gr_search_udp_recvmsg(const struct sock *sk,
25260 +                                const struct sk_buff *skb);
25261 +extern int gr_search_udp_sendmsg(const struct sock *sk,
25262 +                                const struct sockaddr_in *addr);
25263 +
25264 +
25265  /*
25266   *     Snmp MIB for the UDP layer
25267   */
25268 @@ -266,8 +273,7 @@ static struct sock *udp_v4_lookup_longwa
25269         return result;
25270  }
25271  
25272 -static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
25273 -                                            u32 daddr, u16 dport, int dif)
25274 +struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
25275  {
25276         struct sock *sk;
25277  
25278 @@ -542,9 +548,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
25279                 dport = usin->sin_port;
25280                 if (dport == 0)
25281                         return -EINVAL;
25282 +
25283 +               if (!gr_search_udp_sendmsg(sk, usin))
25284 +                       return -EPERM;
25285         } else {
25286                 if (sk->sk_state != TCP_ESTABLISHED)
25287                         return -EDESTADDRREQ;
25288 +
25289 +               if (!gr_search_udp_sendmsg(sk, NULL))
25290 +                       return -EPERM;
25291 +
25292                 daddr = inet->daddr;
25293                 dport = inet->dport;
25294                 /* Open fast path for connected socket.
25295 @@ -798,6 +811,11 @@ try_again:
25296         if (!skb)
25297                 goto out;
25298    
25299 +       if (!gr_search_udp_recvmsg(sk, skb)) {
25300 +               err = -EPERM;
25301 +               goto out_free;
25302 +       }
25303 +
25304         copied = skb->len - sizeof(struct udphdr);
25305         if (copied > len) {
25306                 copied = len;
25307 diff -urNp linux-2.6.17.7/net/socket.c linux-2.6.17.7/net/socket.c
25308 --- linux-2.6.17.7/net/socket.c 2006-07-24 23:36:01.000000000 -0400
25309 +++ linux-2.6.17.7/net/socket.c 2006-08-01 20:29:48.000000000 -0400
25310 @@ -86,6 +86,7 @@
25311  #include <linux/kmod.h>
25312  #include <linux/audit.h>
25313  #include <linux/wireless.h>
25314 +#include <linux/in.h>
25315  
25316  #include <asm/uaccess.h>
25317  #include <asm/unistd.h>
25318 @@ -95,6 +96,21 @@
25319  #include <net/sock.h>
25320  #include <linux/netfilter.h>
25321  
25322 +extern void gr_attach_curr_ip(const struct sock *sk);
25323 +extern int gr_handle_sock_all(const int family, const int type,
25324 +                             const int protocol);
25325 +extern int gr_handle_sock_server(const struct sockaddr *sck);
25326 +extern int gr_handle_sock_server_other(const struct socket *sck);
25327 +extern int gr_handle_sock_client(const struct sockaddr *sck);
25328 +extern int gr_search_connect(const struct socket * sock,
25329 +                            const struct sockaddr_in * addr);
25330 +extern int gr_search_bind(const struct socket * sock,
25331 +                          const struct sockaddr_in * addr);
25332 +extern int gr_search_listen(const struct socket * sock);
25333 +extern int gr_search_accept(const struct socket * sock);
25334 +extern int gr_search_socket(const int domain, const int type,
25335 +                           const int protocol);
25336 +
25337  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
25338  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
25339                          size_t size, loff_t pos);
25340 @@ -341,7 +357,7 @@ static struct super_block *sockfs_get_sb
25341         return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
25342  }
25343  
25344 -static struct vfsmount *sock_mnt __read_mostly;
25345 +struct vfsmount *sock_mnt __read_mostly;
25346  
25347  static struct file_system_type sock_fs_type = {
25348         .name =         "sockfs",
25349 @@ -1240,6 +1256,16 @@ asmlinkage long sys_socket(int family, i
25350         int retval;
25351         struct socket *sock;
25352  
25353 +       if(!gr_search_socket(family, type, protocol)) {
25354 +               retval = -EACCES;
25355 +               goto out;
25356 +       }
25357 +
25358 +       if (gr_handle_sock_all(family, type, protocol)) {
25359 +               retval = -EACCES;
25360 +               goto out;
25361 +       }
25362 +
25363         retval = sock_create(family, type, protocol, &sock);
25364         if (retval < 0)
25365                 goto out;
25366 @@ -1335,16 +1361,25 @@ asmlinkage long sys_bind(int fd, struct 
25367  {
25368         struct socket *sock;
25369         char address[MAX_SOCK_ADDR];
25370 +       struct sockaddr *sck;
25371         int err, fput_needed;
25372  
25373         if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
25374         {
25375                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
25376 +                       sck = (struct sockaddr *)address;
25377 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck) ||
25378 +                           gr_handle_sock_server(sck)) {
25379 +                               err = -EACCES;
25380 +                               goto error;
25381 +                       }
25382 +
25383                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
25384                         if (!err)
25385                                 err = sock->ops->bind(sock,
25386                                         (struct sockaddr *)address, addrlen);
25387                 }
25388 +error:
25389                 fput_light(sock->file, fput_needed);
25390         }                       
25391         return err;
25392 @@ -1368,10 +1403,17 @@ asmlinkage long sys_listen(int fd, int b
25393                 if ((unsigned) backlog > sysctl_somaxconn)
25394                         backlog = sysctl_somaxconn;
25395  
25396 +               if (gr_handle_sock_server_other(sock) ||
25397 +                   !gr_search_listen(sock)) {
25398 +                       err = -EPERM;
25399 +                       goto error;
25400 +               }
25401 +
25402                 err = security_socket_listen(sock, backlog);
25403                 if (!err)
25404                         err = sock->ops->listen(sock, backlog);
25405  
25406 +error:
25407                 fput_light(sock->file, fput_needed);
25408         }
25409         return err;
25410 @@ -1408,6 +1450,13 @@ asmlinkage long sys_accept(int fd, struc
25411         newsock->type = sock->type;
25412         newsock->ops = sock->ops;
25413  
25414 +       if (gr_handle_sock_server_other(sock) ||
25415 +           !gr_search_accept(sock)) {
25416 +               err = -EPERM;
25417 +               sock_release(newsock);
25418 +               goto out_put;
25419 +       }
25420 +
25421         /*
25422          * We don't need try_module_get here, as the listening socket (sock)
25423          * has the protocol module (sock->ops->owner) held.
25424 @@ -1449,6 +1498,7 @@ asmlinkage long sys_accept(int fd, struc
25425         err = newfd;
25426  
25427         security_socket_post_accept(sock, newsock);
25428 +       gr_attach_curr_ip(newsock->sk);
25429  
25430  out_put:
25431         fput_light(sock->file, fput_needed);
25432 @@ -1477,6 +1527,7 @@ asmlinkage long sys_connect(int fd, stru
25433  {
25434         struct socket *sock;
25435         char address[MAX_SOCK_ADDR];
25436 +       struct sockaddr *sck;
25437         int err, fput_needed;
25438  
25439         sock = sockfd_lookup_light(fd, &err, &fput_needed);
25440 @@ -1486,6 +1537,13 @@ asmlinkage long sys_connect(int fd, stru
25441         if (err < 0)
25442                 goto out_put;
25443  
25444 +       sck = (struct sockaddr *)address;
25445 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
25446 +           gr_handle_sock_client(sck)) {
25447 +               err = -EACCES;
25448 +               goto out_put;
25449 +       }
25450 +
25451         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
25452         if (err)
25453                 goto out_put;
25454 @@ -1740,6 +1798,7 @@ asmlinkage long sys_shutdown(int fd, int
25455                         err = sock->ops->shutdown(sock, how);
25456                 fput_light(sock->file, fput_needed);
25457         }
25458 +
25459         return err;
25460  }
25461  
25462 diff -urNp linux-2.6.17.7/net/unix/af_unix.c linux-2.6.17.7/net/unix/af_unix.c
25463 --- linux-2.6.17.7/net/unix/af_unix.c   2006-07-24 23:36:01.000000000 -0400
25464 +++ linux-2.6.17.7/net/unix/af_unix.c   2006-08-01 20:29:48.000000000 -0400
25465 @@ -117,6 +117,7 @@
25466  #include <linux/vs_context.h>
25467  #include <linux/vs_network.h>
25468  #include <linux/vs_limit.h>
25469 +#include <linux/grsecurity.h>
25470  
25471  int sysctl_unix_max_dgram_qlen = 10;
25472  
25473 @@ -680,6 +681,11 @@ static struct sock *unix_find_other(stru
25474                 if (err)
25475                         goto put_fail;
25476  
25477 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
25478 +                       err = -EACCES;
25479 +                       goto put_fail;
25480 +               }
25481 +
25482                 err = -ECONNREFUSED;
25483                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
25484                         goto put_fail;
25485 @@ -703,6 +709,13 @@ static struct sock *unix_find_other(stru
25486                 if (u) {
25487                         struct dentry *dentry;
25488                         dentry = unix_sk(u)->dentry;
25489 +
25490 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
25491 +                               err = -EPERM;
25492 +                               sock_put(u);
25493 +                               goto fail;
25494 +                       }
25495 +
25496                         if (dentry)
25497                                 touch_atime(unix_sk(u)->mnt, dentry);
25498                 } else
25499 @@ -781,9 +794,18 @@ static int unix_bind(struct socket *sock
25500                  */
25501                 mode = S_IFSOCK |
25502                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
25503 +
25504 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
25505 +                       err = -EACCES;
25506 +                       goto out_mknod_dput;
25507 +               }
25508 +
25509                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
25510                 if (err)
25511                         goto out_mknod_dput;
25512 +
25513 +               gr_handle_create(dentry, nd.mnt);
25514 +
25515                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
25516                 dput(nd.dentry);
25517                 nd.dentry = dentry;
25518 @@ -801,6 +823,10 @@ static int unix_bind(struct socket *sock
25519                         goto out_unlock;
25520                 }
25521  
25522 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25523 +               sk->sk_peercred.pid = current->pid;
25524 +#endif
25525 +
25526                 list = &unix_socket_table[addr->hash];
25527         } else {
25528                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
25529 diff -urNp linux-2.6.17.7/security/Kconfig linux-2.6.17.7/security/Kconfig
25530 --- linux-2.6.17.7/security/Kconfig     2006-07-24 23:36:01.000000000 -0400
25531 +++ linux-2.6.17.7/security/Kconfig     2006-08-01 20:29:48.000000000 -0400
25532 @@ -4,6 +4,453 @@
25533  
25534  menu "Security options"
25535  
25536 +menu "PaX"
25537 +
25538 +config PAX
25539 +       bool "Enable various PaX features"
25540 +       depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
25541 +       help
25542 +         This allows you to enable various PaX features.  PaX adds
25543 +         intrusion prevention mechanisms to the kernel that reduce
25544 +         the risks posed by exploitable memory corruption bugs.
25545 +
25546 +menu "PaX Control"
25547 +       depends on PAX
25548 +
25549 +config PAX_SOFTMODE
25550 +       bool 'Support soft mode'
25551 +       help
25552 +         Enabling this option will allow you to run PaX in soft mode, that
25553 +         is, PaX features will not be enforced by default, only on executables
25554 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
25555 +         is the only way to mark executables for soft mode use.
25556 +
25557 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
25558 +         line option on boot.  Furthermore you can control various PaX features
25559 +         at runtime via the entries in /proc/sys/kernel/pax.
25560 +
25561 +config PAX_EI_PAX
25562 +       bool 'Use legacy ELF header marking'
25563 +       help
25564 +         Enabling this option will allow you to control PaX features on
25565 +         a per executable basis via the 'chpax' utility available at
25566 +         http://pax.grsecurity.net/.  The control flags will be read from
25567 +         an otherwise reserved part of the ELF header.  This marking has
25568 +         numerous drawbacks (no support for soft-mode, toolchain does not
25569 +         know about the non-standard use of the ELF header) therefore it
25570 +         has been deprecated in favour of PT_PAX_FLAGS support.
25571 +
25572 +         If you have applications not marked by the PT_PAX_FLAGS ELF
25573 +         program header then you MUST enable this option otherwise they
25574 +         will not get any protection.
25575 +
25576 +         Note that if you enable PT_PAX_FLAGS marking support as well,
25577 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
25578 +
25579 +config PAX_PT_PAX_FLAGS
25580 +       bool 'Use ELF program header marking'
25581 +       help
25582 +         Enabling this option will allow you to control PaX features on
25583 +         a per executable basis via the 'paxctl' utility available at
25584 +         http://pax.grsecurity.net/.  The control flags will be read from
25585 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
25586 +         has the benefits of supporting both soft mode and being fully
25587 +         integrated into the toolchain (the binutils patch is available
25588 +         from http://pax.grsecurity.net).
25589 +
25590 +         If you have applications not marked by the PT_PAX_FLAGS ELF
25591 +         program header then you MUST enable the EI_PAX marking support
25592 +         otherwise they will not get any protection.
25593 +
25594 +         Note that if you enable the legacy EI_PAX marking support as well,
25595 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
25596 +
25597 +choice
25598 +       prompt 'MAC system integration'
25599 +       default PAX_HAVE_ACL_FLAGS
25600 +       help
25601 +         Mandatory Access Control systems have the option of controlling
25602 +         PaX flags on a per executable basis, choose the method supported
25603 +         by your particular system.
25604 +
25605 +         - "none": if your MAC system does not interact with PaX,
25606 +         - "direct": if your MAC system defines pax_set_flags() itself,
25607 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
25608 +
25609 +         NOTE: this option is for developers/integrators only.
25610 +
25611 +config PAX_NO_ACL_FLAGS
25612 +       bool 'none'
25613 +
25614 +config PAX_HAVE_ACL_FLAGS
25615 +       bool 'direct'
25616 +
25617 +config PAX_HOOK_ACL_FLAGS
25618 +       bool 'hook'
25619 +endchoice
25620 +
25621 +endmenu
25622 +
25623 +menu "Non-executable pages"
25624 +       depends on PAX
25625 +
25626 +config PAX_NOEXEC
25627 +       bool "Enforce non-executable pages"
25628 +       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)
25629 +       help
25630 +         By design some architectures do not allow for protecting memory
25631 +         pages against execution or even if they do, Linux does not make
25632 +         use of this feature.  In practice this means that if a page is
25633 +         readable (such as the stack or heap) it is also executable.
25634 +
25635 +         There is a well known exploit technique that makes use of this
25636 +         fact and a common programming mistake where an attacker can
25637 +         introduce code of his choice somewhere in the attacked program's
25638 +         memory (typically the stack or the heap) and then execute it.
25639 +
25640 +         If the attacked program was running with different (typically
25641 +         higher) privileges than that of the attacker, then he can elevate
25642 +         his own privilege level (e.g. get a root shell, write to files for
25643 +         which he does not have write access to, etc).
25644 +
25645 +         Enabling this option will let you choose from various features
25646 +         that prevent the injection and execution of 'foreign' code in
25647 +         a program.
25648 +
25649 +         This will also break programs that rely on the old behaviour and
25650 +         expect that dynamically allocated memory via the malloc() family
25651 +         of functions is executable (which it is not).  Notable examples
25652 +         are the XFree86 4.x server, the java runtime and wine.
25653 +
25654 +config PAX_PAGEEXEC
25655 +       bool "Paging based non-executable pages"
25656 +       depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
25657 +       select PAX_NOVSYSCALL if X86_32
25658 +       help
25659 +         This implementation is based on the paging feature of the CPU.
25660 +         On i386 and ppc there is a variable but usually low performance
25661 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
25662 +         and x86_64 there is no performance impact.
25663 +
25664 +config PAX_SEGMEXEC
25665 +       bool "Segmentation based non-executable pages"
25666 +       depends on PAX_NOEXEC && X86_32
25667 +       select PAX_NOVSYSCALL
25668 +       help
25669 +         This implementation is based on the segmentation feature of the
25670 +         CPU and has little performance impact, however applications will
25671 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
25672 +
25673 +choice
25674 +       prompt "Default non-executable page method"
25675 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
25676 +       default PAX_DEFAULT_SEGMEXEC
25677 +       help
25678 +         Select the default non-executable page method applied to applications
25679 +         that do not select one themselves.
25680 +
25681 +config PAX_DEFAULT_PAGEEXEC
25682 +       bool "PAGEEXEC"
25683 +
25684 +config PAX_DEFAULT_SEGMEXEC
25685 +       bool "SEGMEXEC"
25686 +endchoice
25687 +
25688 +config PAX_EMUTRAMP
25689 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
25690 +       default y if PARISC || PPC32
25691 +       help
25692 +         There are some programs and libraries that for one reason or
25693 +         another attempt to execute special small code snippets from
25694 +         non-executable memory pages.  Most notable examples are the
25695 +         signal handler return code generated by the kernel itself and
25696 +         the GCC trampolines.
25697 +
25698 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
25699 +         such programs will no longer work under your kernel.
25700 +
25701 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
25702 +         utilities to enable trampoline emulation for the affected programs
25703 +         yet still have the protection provided by the non-executable pages.
25704 +
25705 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
25706 +         well, otherwise your system will not even boot.
25707 +
25708 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
25709 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
25710 +         for the affected files.
25711 +
25712 +         NOTE: enabling this feature *may* open up a loophole in the
25713 +         protection provided by non-executable pages that an attacker
25714 +         could abuse.  Therefore the best solution is to not have any
25715 +         files on your system that would require this option.  This can
25716 +         be achieved by not using libc5 (which relies on the kernel
25717 +         signal handler return code) and not using or rewriting programs
25718 +         that make use of the nested function implementation of GCC.
25719 +         Skilled users can just fix GCC itself so that it implements
25720 +         nested function calls in a way that does not interfere with PaX.
25721 +
25722 +config PAX_EMUSIGRT
25723 +       bool "Automatically emulate sigreturn trampolines"
25724 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
25725 +       default y
25726 +       help
25727 +         Enabling this option will have the kernel automatically detect
25728 +         and emulate signal return trampolines executing on the stack
25729 +         that would otherwise lead to task termination.
25730 +
25731 +         This solution is intended as a temporary one for users with
25732 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
25733 +         Modula-3 runtime, etc) or executables linked to such, basically
25734 +         everything that does not specify its own SA_RESTORER function in
25735 +         normal executable memory like glibc 2.1+ does.
25736 +
25737 +         On parisc and ppc you MUST enable this option, otherwise your
25738 +         system will not even boot.
25739 +
25740 +         NOTE: this feature cannot be disabled on a per executable basis
25741 +         and since it *does* open up a loophole in the protection provided
25742 +         by non-executable pages, the best solution is to not have any
25743 +         files on your system that would require this option.
25744 +
25745 +config PAX_MPROTECT
25746 +       bool "Restrict mprotect()"
25747 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
25748 +       help
25749 +         Enabling this option will prevent programs from
25750 +          - changing the executable status of memory pages that were
25751 +            not originally created as executable,
25752 +          - making read-only executable pages writable again,
25753 +          - creating executable pages from anonymous memory.
25754 +
25755 +         You should say Y here to complete the protection provided by
25756 +         the enforcement of non-executable pages.
25757 +
25758 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
25759 +         this feature on a per file basis.
25760 +
25761 +config PAX_NOELFRELOCS
25762 +       bool "Disallow ELF text relocations"
25763 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
25764 +       help
25765 +         Non-executable pages and mprotect() restrictions are effective
25766 +         in preventing the introduction of new executable code into an
25767 +         attacked task's address space.  There remain only two venues
25768 +         for this kind of attack: if the attacker can execute already
25769 +         existing code in the attacked task then he can either have it
25770 +         create and mmap() a file containing his code or have it mmap()
25771 +         an already existing ELF library that does not have position
25772 +         independent code in it and use mprotect() on it to make it
25773 +         writable and copy his code there.  While protecting against
25774 +         the former approach is beyond PaX, the latter can be prevented
25775 +         by having only PIC ELF libraries on one's system (which do not
25776 +         need to relocate their code).  If you are sure this is your case,
25777 +         then enable this option otherwise be careful as you may not even
25778 +         be able to boot or log on your system (for example, some PAM
25779 +         modules are erroneously compiled as non-PIC by default).
25780 +
25781 +         NOTE: if you are using dynamic ELF executables (as suggested
25782 +         when using ASLR) then you must have made sure that you linked
25783 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
25784 +         referenced there has already been updated to support this).
25785 +
25786 +config PAX_ETEXECRELOCS
25787 +       bool "Allow ELF ET_EXEC text relocations"
25788 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
25789 +       default y
25790 +       help
25791 +         On some architectures there are incorrectly created applications
25792 +         that require text relocations and would not work without enabling
25793 +         this option.  If you are an alpha, ia64 or parisc user, you should
25794 +         enable this option and disable it once you have made sure that
25795 +         none of your applications need it.
25796 +
25797 +config PAX_EMUPLT
25798 +       bool "Automatically emulate ELF PLT"
25799 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
25800 +       default y
25801 +       help
25802 +         Enabling this option will have the kernel automatically detect
25803 +         and emulate the Procedure Linkage Table entries in ELF files.
25804 +         On some architectures such entries are in writable memory, and
25805 +         become non-executable leading to task termination.  Therefore
25806 +         it is mandatory that you enable this option on alpha, parisc, ppc,
25807 +         sparc and sparc64, otherwise your system would not even boot.
25808 +
25809 +         NOTE: this feature *does* open up a loophole in the protection
25810 +         provided by the non-executable pages, therefore the proper
25811 +         solution is to modify the toolchain to produce a PLT that does
25812 +         not need to be writable.
25813 +
25814 +config PAX_DLRESOLVE
25815 +       bool
25816 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
25817 +       default y
25818 +
25819 +config PAX_SYSCALL
25820 +       bool
25821 +       depends on PAX_PAGEEXEC && PPC32
25822 +       default y
25823 +
25824 +config PAX_KERNEXEC
25825 +       bool "Enforce non-executable kernel pages"
25826 +       depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !DEBUG_RODATA
25827 +       select PAX_NOVSYSCALL
25828 +       help
25829 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
25830 +         that is, enabling this option will make it harder to inject
25831 +         and execute 'foreign' code in kernel memory itself.
25832 +
25833 +endmenu
25834 +
25835 +menu "Address Space Layout Randomization"
25836 +       depends on PAX
25837 +
25838 +config PAX_ASLR
25839 +       bool "Address Space Layout Randomization"
25840 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
25841 +       help
25842 +         Many if not most exploit techniques rely on the knowledge of
25843 +         certain addresses in the attacked program.  The following options
25844 +         will allow the kernel to apply a certain amount of randomization
25845 +         to specific parts of the program thereby forcing an attacker to
25846 +         guess them in most cases.  Any failed guess will most likely crash
25847 +         the attacked program which allows the kernel to detect such attempts
25848 +         and react on them.  PaX itself provides no reaction mechanisms,
25849 +         instead it is strongly encouraged that you make use of Nergal's
25850 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
25851 +         (http://www.grsecurity.net/) built-in crash detection features or
25852 +         develop one yourself.
25853 +
25854 +         By saying Y here you can choose to randomize the following areas:
25855 +          - top of the task's kernel stack
25856 +          - top of the task's userland stack
25857 +          - base address for mmap() requests that do not specify one
25858 +            (this includes all libraries)
25859 +          - base address of the main executable
25860 +
25861 +         It is strongly recommended to say Y here as address space layout
25862 +         randomization has negligible impact on performance yet it provides
25863 +         a very effective protection.
25864 +
25865 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
25866 +         this feature on a per file basis.
25867 +
25868 +config PAX_RANDKSTACK
25869 +       bool "Randomize kernel stack base"
25870 +       depends on PAX_ASLR && X86_TSC && X86_32
25871 +       help
25872 +         By saying Y here the kernel will randomize every task's kernel
25873 +         stack on every system call.  This will not only force an attacker
25874 +         to guess it but also prevent him from making use of possible
25875 +         leaked information about it.
25876 +
25877 +         Since the kernel stack is a rather scarce resource, randomization
25878 +         may cause unexpected stack overflows, therefore you should very
25879 +         carefully test your system.  Note that once enabled in the kernel
25880 +         configuration, this feature cannot be disabled on a per file basis.
25881 +
25882 +config PAX_RANDUSTACK
25883 +       bool "Randomize user stack base"
25884 +       depends on PAX_ASLR
25885 +       help
25886 +         By saying Y here the kernel will randomize every task's userland
25887 +         stack.  The randomization is done in two steps where the second
25888 +         one may apply a big amount of shift to the top of the stack and
25889 +         cause problems for programs that want to use lots of memory (more
25890 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
25891 +         For this reason the second step can be controlled by 'chpax' or
25892 +         'paxctl' on a per file basis.
25893 +
25894 +config PAX_RANDMMAP
25895 +       bool "Randomize mmap() base"
25896 +       depends on PAX_ASLR
25897 +       help
25898 +         By saying Y here the kernel will use a randomized base address for
25899 +         mmap() requests that do not specify one themselves.  As a result
25900 +         all dynamically loaded libraries will appear at random addresses
25901 +         and therefore be harder to exploit by a technique where an attacker
25902 +         attempts to execute library code for his purposes (e.g. spawn a
25903 +         shell from an exploited program that is running at an elevated
25904 +         privilege level).
25905 +
25906 +         Furthermore, if a program is relinked as a dynamic ELF file, its
25907 +         base address will be randomized as well, completing the full
25908 +         randomization of the address space layout.  Attacking such programs
25909 +         becomes a guess game.  You can find an example of doing this at
25910 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
25911 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
25912 +
25913 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
25914 +         feature on a per file basis.
25915 +
25916 +config PAX_NOVSYSCALL
25917 +       bool "Disable the vsyscall page"
25918 +       depends on PAX_ASLR && X86_32
25919 +       help
25920 +         The Linux 2.6 kernel introduced a new feature that speeds up or
25921 +         simplifies certain operations, such as system calls or returns
25922 +         from signal handlers.
25923 +
25924 +         Unfortunately the implementation also gives a powerful instrument
25925 +         into the hands of exploit writers: the so-called vsyscall page exists
25926 +         in every task at the same fixed address and it contains machine code
25927 +         that is very useful in performing the return-to-libc style attack.
25928 +
25929 +         Since this exploit technique cannot in general be protected against
25930 +         via kernel solutions, this option will allow you to disable the use
25931 +         of the vsyscall page and revert back to the old behaviour.
25932 +
25933 +endmenu
25934 +
25935 +menu "Miscellaneous hardening features"
25936 +
25937 +config PAX_MEMORY_SANITIZE
25938 +       bool "Sanitize all freed memory"
25939 +       help
25940 +         By saying Y here the kernel will erase memory pages as soon as they
25941 +         are freed.  This in turn reduces the lifetime of data stored in the
25942 +         pages, making it less likely that sensitive information such as
25943 +         passwords, cryptographic secrets, etc stay in memory for too long.
25944 +
25945 +         This is especially useful for programs whose runtime is short, long
25946 +         lived processes and the kernel itself benefit from this as long as
25947 +         they operate on whole memory pages and ensure timely freeing of pages
25948 +         that may hold sensitive information.
25949 +
25950 +         The tradeoff is performance impact, on a single CPU system kernel
25951 +         compilation sees a 3% slowdown, other systems and workloads may vary
25952 +         and you are advised to test this feature on your expected workload
25953 +         before deploying it.
25954 +
25955 +         Note that this feature does not protect data stored in live pages,
25956 +         e.g., process memory swapped to disk may stay there for a long time.
25957 +
25958 +config PAX_MEMORY_UDEREF
25959 +       bool "Prevent invalid userland pointer dereference"
25960 +       depends on X86_32
25961 +       select PAX_NOVSYSCALL
25962 +       help
25963 +         By saying Y here the kernel will be prevented from dereferencing
25964 +         userland pointers in contexts where the kernel expects only kernel
25965 +         pointers.  This is both a useful runtime debugging feature and a
25966 +         security measure that prevents exploiting a class of kernel bugs.
25967 +
25968 +         The tradeoff is that some virtualization solutions may experience
25969 +         a huge slowdown and therefore you should not enable this feature
25970 +         for kernels meant to run in such environments.  Whether a given VM
25971 +         solution is affected or not is best determined by simply trying it
25972 +         out, the performance impact will be obvious right on boot as this
25973 +         mechanism engages from very early on.  A good rule of thumb is that
25974 +         VMs running on CPUs without hardware virtualization support (i.e.,
25975 +         the majority of IA-32 CPUs) will likely experience the slowdown.
25976 +
25977 +endmenu
25978 +
25979 +endmenu
25980 +
25981 +source grsecurity/Kconfig
25982 +
25983  config KEYS
25984         bool "Enable access key retention support"
25985         help
25986 diff -urNp linux-2.6.17.7/security/commoncap.c linux-2.6.17.7/security/commoncap.c
25987 --- linux-2.6.17.7/security/commoncap.c 2006-07-24 23:36:01.000000000 -0400
25988 +++ linux-2.6.17.7/security/commoncap.c 2006-08-01 20:29:48.000000000 -0400
25989 @@ -24,6 +24,7 @@
25990  #include <linux/ptrace.h>
25991  #include <linux/xattr.h>
25992  #include <linux/hugetlb.h>
25993 +#include <linux/grsecurity.h>
25994  
25995  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
25996  {
25997 @@ -45,7 +46,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
25998  int cap_capable (struct task_struct *tsk, int cap)
25999  {
26000         /* Derived from include/linux/sched.h:capable. */
26001 -       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
26002 +       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
26003 +               return 0;
26004 +       return -EPERM;
26005 +}
26006 +
26007 +int cap_capable_nolog (struct task_struct *tsk, int cap)
26008 +{
26009 +       /* Derived from include/linux/sched.h:capable. */
26010 +       if (cap_raised (tsk->cap_effective, cap))
26011                 return 0;
26012         return -EPERM;
26013  }
26014 @@ -164,8 +173,11 @@ void cap_bprm_apply_creds (struct linux_
26015                 }
26016         }
26017  
26018 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
26019 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
26020 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
26021 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
26022 +
26023 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
26024 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
26025  
26026         /* For init, we want to retain the capabilities set
26027          * in the init_task struct. Thus we skip the usual
26028 @@ -176,6 +188,8 @@ void cap_bprm_apply_creds (struct linux_
26029                     cap_intersect (new_permitted, bprm->cap_effective);
26030         }
26031  
26032 +       gr_handle_chroot_caps(current);
26033 +
26034         /* AUD: Audit candidate if current->cap_effective is set */
26035  
26036         current->keep_capabilities = 0;
26037 @@ -321,12 +335,13 @@ int cap_vm_enough_memory(long pages)
26038  {
26039         int cap_sys_admin = 0;
26040  
26041 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
26042 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
26043                 cap_sys_admin = 1;
26044         return __vm_enough_memory(pages, cap_sys_admin);
26045  }
26046  
26047  EXPORT_SYMBOL(cap_capable);
26048 +EXPORT_SYMBOL(cap_capable_nolog);
26049  EXPORT_SYMBOL(cap_settime);
26050  EXPORT_SYMBOL(cap_ptrace);
26051  EXPORT_SYMBOL(cap_capget);
26052 diff -urNp linux-2.6.17.7/security/dummy.c linux-2.6.17.7/security/dummy.c
26053 --- linux-2.6.17.7/security/dummy.c     2006-07-24 23:36:01.000000000 -0400
26054 +++ linux-2.6.17.7/security/dummy.c     2006-08-01 20:29:48.000000000 -0400
26055 @@ -29,6 +29,7 @@
26056  #include <linux/hugetlb.h>
26057  #include <linux/ptrace.h>
26058  #include <linux/file.h>
26059 +#include <linux/grsecurity.h>
26060  
26061  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
26062  {
26063 @@ -139,8 +140,11 @@ static void dummy_bprm_apply_creds (stru
26064                 }
26065         }
26066  
26067 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
26068 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
26069 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
26070 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
26071 +
26072 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
26073 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
26074  
26075         dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
26076  }
This page took 1.86515 seconds and 3 git commands to generate.