]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.1.9-2.6.16.14.patch
- undo charset fuckup (again)
[packages/kernel.git] / grsecurity-2.1.9-2.6.16.14.patch
1 diff -urNp linux-2.6.16.12/arch/alpha/kernel/module.c linux-2.6.16.12/arch/alpha/kernel/module.c
2 --- linux-2.6.16.12/arch/alpha/kernel/module.c  2006-05-01 15:14:26.000000000 -0400
3 +++ linux-2.6.16.12/arch/alpha/kernel/module.c  2006-05-01 20:17:33.000000000 -0400
4 @@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, 
5  
6         /* The small sections were sorted to the end of the segment.
7            The following should definitely cover them.  */
8 -       gp = (u64)me->module_core + me->core_size - 0x8000;
9 +       gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
10         got = sechdrs[me->arch.gotsecindex].sh_addr;
11  
12         for (i = 0; i < n; i++) {
13 diff -urNp linux-2.6.16.12/arch/alpha/kernel/osf_sys.c linux-2.6.16.12/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.16.12/arch/alpha/kernel/osf_sys.c 2006-05-01 15:14:26.000000000 -0400
15 +++ linux-2.6.16.12/arch/alpha/kernel/osf_sys.c 2006-05-01 20:17:33.000000000 -0400
16 @@ -1274,6 +1274,10 @@ arch_get_unmapped_area(struct file *filp
17            merely specific addresses, but regions of memory -- perhaps
18            this feature should be incorporated into all ports?  */
19  
20 +#ifdef CONFIG_PAX_RANDMMAP
21 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
22 +#endif
23 +
24         if (addr) {
25                 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
26                 if (addr != (unsigned long) -ENOMEM)
27 @@ -1281,8 +1285,8 @@ arch_get_unmapped_area(struct file *filp
28         }
29  
30         /* Next, try allocating at TASK_UNMAPPED_BASE.  */
31 -       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
32 -                                        len, limit);
33 +       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
34 +
35         if (addr != (unsigned long) -ENOMEM)
36                 return addr;
37  
38 diff -urNp linux-2.6.16.12/arch/alpha/kernel/ptrace.c linux-2.6.16.12/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.16.12/arch/alpha/kernel/ptrace.c  2006-05-01 15:14:26.000000000 -0400
40 +++ linux-2.6.16.12/arch/alpha/kernel/ptrace.c  2006-05-01 20:17:33.000000000 -0400
41 @@ -15,6 +15,7 @@
42  #include <linux/slab.h>
43  #include <linux/security.h>
44  #include <linux/signal.h>
45 +#include <linux/grsecurity.h>
46  
47  #include <asm/uaccess.h>
48  #include <asm/pgtable.h>
49 @@ -267,7 +268,7 @@ do_sys_ptrace(long request, long pid, lo
50         struct task_struct *child;
51         unsigned long tmp;
52         size_t copied;
53 -       long ret;
54 +       long ret = 0;
55  
56         lock_kernel();
57         DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
58 @@ -288,6 +289,9 @@ do_sys_ptrace(long request, long pid, lo
59                 goto out;
60         }
61  
62 +       if (gr_handle_ptrace(child, request))
63 +               goto out;
64 +
65         if (request == PTRACE_ATTACH) {
66                 ret = ptrace_attach(child);
67                 goto out;
68 diff -urNp linux-2.6.16.12/arch/alpha/mm/fault.c linux-2.6.16.12/arch/alpha/mm/fault.c
69 --- linux-2.6.16.12/arch/alpha/mm/fault.c       2006-05-01 15:14:26.000000000 -0400
70 +++ linux-2.6.16.12/arch/alpha/mm/fault.c       2006-05-01 20:17:33.000000000 -0400
71 @@ -25,6 +25,7 @@
72  #include <linux/smp_lock.h>
73  #include <linux/interrupt.h>
74  #include <linux/module.h>
75 +#include <linux/binfmts.h>
76  
77  #include <asm/system.h>
78  #include <asm/uaccess.h>
79 @@ -56,6 +57,124 @@ __load_new_mm_context(struct mm_struct *
80         __reload_thread(pcb);
81  }
82  
83 +#ifdef CONFIG_PAX_PAGEEXEC
84 +/*
85 + * PaX: decide what to do with offenders (regs->pc = fault address)
86 + *
87 + * returns 1 when task should be killed
88 + *         2 when patched PLT trampoline was detected
89 + *         3 when unpatched PLT trampoline was detected
90 + */
91 +static int pax_handle_fetch_fault(struct pt_regs *regs)
92 +{
93 +
94 +#ifdef CONFIG_PAX_EMUPLT
95 +       int err;
96 +
97 +       do { /* PaX: patched PLT emulation #1 */
98 +               unsigned int ldah, ldq, jmp;
99 +
100 +               err = get_user(ldah, (unsigned int *)regs->pc);
101 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
102 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
103 +
104 +               if (err)
105 +                       break;
106 +
107 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
108 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
109 +                   jmp == 0x6BFB0000U)
110 +               {
111 +                       unsigned long r27, addr;
112 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
113 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
114 +
115 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
116 +                       err = get_user(r27, (unsigned long*)addr);
117 +                       if (err)
118 +                               break;
119 +
120 +                       regs->r27 = r27;
121 +                       regs->pc = r27;
122 +                       return 2;
123 +               }
124 +       } while (0);
125 +
126 +       do { /* PaX: patched PLT emulation #2 */
127 +               unsigned int ldah, lda, br;
128 +
129 +               err = get_user(ldah, (unsigned int *)regs->pc);
130 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
131 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
132 +
133 +               if (err)
134 +                       break;
135 +
136 +               if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
137 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
138 +                   (br & 0xFFE00000U) == 0xC3E00000U)
139 +               {
140 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
141 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
142 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
143 +
144 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
145 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
146 +                       return 2;
147 +               }
148 +       } while (0);
149 +
150 +       do { /* PaX: unpatched PLT emulation */
151 +               unsigned int br;
152 +
153 +               err = get_user(br, (unsigned int *)regs->pc);
154 +
155 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
156 +                       unsigned int br2, ldq, nop, jmp;
157 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
158 +
159 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
160 +                       err = get_user(br2, (unsigned int *)addr);
161 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
162 +                       err |= get_user(nop, (unsigned int *)(addr+8));
163 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
164 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
165 +
166 +                       if (err)
167 +                               break;
168 +
169 +                       if (br2 == 0xC3600000U &&
170 +                           ldq == 0xA77B000CU &&
171 +                           nop == 0x47FF041FU &&
172 +                           jmp == 0x6B7B0000U)
173 +                       {
174 +                               regs->r28 = regs->pc+4;
175 +                               regs->r27 = addr+16;
176 +                               regs->pc = resolver;
177 +                               return 3;
178 +                       }
179 +               }
180 +       } while (0);
181 +#endif
182 +
183 +       return 1;
184 +}
185 +
186 +void pax_report_insns(void *pc, void *sp)
187 +{
188 +       unsigned long i;
189 +
190 +       printk(KERN_ERR "PAX: bytes at PC: ");
191 +       for (i = 0; i < 5; i++) {
192 +               unsigned int c;
193 +               if (get_user(c, (unsigned int*)pc+i))
194 +                       printk("???????? ");
195 +               else
196 +                       printk("%08x ", c);
197 +       }
198 +       printk("\n");
199 +}
200 +#endif
201  
202  /*
203   * This routine handles page faults.  It determines the address,
204 @@ -133,8 +252,29 @@ do_page_fault(unsigned long address, uns
205   good_area:
206         si_code = SEGV_ACCERR;
207         if (cause < 0) {
208 -               if (!(vma->vm_flags & VM_EXEC))
209 +               if (!(vma->vm_flags & VM_EXEC)) {
210 +
211 +#ifdef CONFIG_PAX_PAGEEXEC
212 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
213 +                               goto bad_area;
214 +
215 +                       up_read(&mm->mmap_sem);
216 +                       switch(pax_handle_fetch_fault(regs)) {
217 +
218 +#ifdef CONFIG_PAX_EMUPLT
219 +                       case 2:
220 +                       case 3:
221 +                               return;
222 +#endif
223 +
224 +                       }
225 +                       pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
226 +                       do_exit(SIGKILL);
227 +#else
228                         goto bad_area;
229 +#endif
230 +
231 +               }
232         } else if (!cause) {
233                 /* Allow reads even for write-only mappings */
234                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
235 diff -urNp linux-2.6.16.12/arch/arm/mm/mmap.c linux-2.6.16.12/arch/arm/mm/mmap.c
236 --- linux-2.6.16.12/arch/arm/mm/mmap.c  2006-05-01 15:14:26.000000000 -0400
237 +++ linux-2.6.16.12/arch/arm/mm/mmap.c  2006-05-01 20:17:33.000000000 -0400
238 @@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
239         if (len > TASK_SIZE)
240                 return -ENOMEM;
241  
242 +#ifdef CONFIG_PAX_RANDMMAP
243 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
244 +#endif
245 +
246         if (addr) {
247                 if (do_align)
248                         addr = COLOUR_ALIGN(addr, pgoff);
249 @@ -76,7 +80,7 @@ arch_get_unmapped_area(struct file *filp
250         if (len > mm->cached_hole_size) {
251                 start_addr = addr = mm->free_area_cache;
252         } else {
253 -               start_addr = addr = TASK_UNMAPPED_BASE;
254 +               start_addr = addr = mm->mmap_base;
255                 mm->cached_hole_size = 0;
256         }
257  
258 @@ -93,8 +97,8 @@ full_search:
259                          * Start a new search - just in case we missed
260                          * some holes.
261                          */
262 -                       if (start_addr != TASK_UNMAPPED_BASE) {
263 -                               start_addr = addr = TASK_UNMAPPED_BASE;
264 +                       if (start_addr != mm->mmap_base) {
265 +                               start_addr = addr = mm->mmap_base;
266                                 mm->cached_hole_size = 0;
267                                 goto full_search;
268                         }
269 diff -urNp linux-2.6.16.12/arch/i386/boot/compressed/head.S linux-2.6.16.12/arch/i386/boot/compressed/head.S
270 --- linux-2.6.16.12/arch/i386/boot/compressed/head.S    2006-05-01 15:14:26.000000000 -0400
271 +++ linux-2.6.16.12/arch/i386/boot/compressed/head.S    2006-05-01 20:17:33.000000000 -0400
272 @@ -39,11 +39,13 @@ startup_32:
273         movl %eax,%gs
274  
275         lss stack_start,%esp
276 +       movl 0x000000,%ecx
277         xorl %eax,%eax
278  1:     incl %eax               # check that A20 really IS enabled
279         movl %eax,0x000000      # loop forever if it isn't
280         cmpl %eax,0x100000
281         je 1b
282 +       movl %ecx,0x000000
283  
284  /*
285   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
286 diff -urNp linux-2.6.16.12/arch/i386/Kconfig linux-2.6.16.12/arch/i386/Kconfig
287 --- linux-2.6.16.12/arch/i386/Kconfig   2006-05-01 15:14:26.000000000 -0400
288 +++ linux-2.6.16.12/arch/i386/Kconfig   2006-05-01 20:17:33.000000000 -0400
289 @@ -983,7 +983,7 @@ endchoice
290  
291  config PCI_BIOS
292         bool
293 -       depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
294 +       depends on !X86_VISWS && PCI && PCI_GOBIOS
295         default y
296  
297  config PCI_DIRECT
298 diff -urNp linux-2.6.16.12/arch/i386/Kconfig.cpu linux-2.6.16.12/arch/i386/Kconfig.cpu
299 --- linux-2.6.16.12/arch/i386/Kconfig.cpu       2006-05-01 15:14:26.000000000 -0400
300 +++ linux-2.6.16.12/arch/i386/Kconfig.cpu       2006-05-01 20:17:33.000000000 -0400
301 @@ -251,7 +251,7 @@ config X86_PPRO_FENCE
302  
303  config X86_F00F_BUG
304         bool
305 -       depends on M586MMX || M586TSC || M586 || M486 || M386
306 +       depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
307         default y
308  
309  config X86_WP_WORKS_OK
310 @@ -281,7 +281,7 @@ config X86_CMPXCHG64
311  
312  config X86_ALIGNMENT_16
313         bool
314 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
315 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
316         default y
317  
318  config X86_GOOD_APIC
319 diff -urNp linux-2.6.16.12/arch/i386/Kconfig.debug linux-2.6.16.12/arch/i386/Kconfig.debug
320 --- linux-2.6.16.12/arch/i386/Kconfig.debug     2006-05-01 15:14:26.000000000 -0400
321 +++ linux-2.6.16.12/arch/i386/Kconfig.debug     2006-05-01 20:17:33.000000000 -0400
322 @@ -44,7 +44,7 @@ config DEBUG_PAGEALLOC
323  
324  config DEBUG_RODATA
325         bool "Write protect kernel read-only data structures"
326 -       depends on DEBUG_KERNEL
327 +       depends on DEBUG_KERNEL && 0
328         help
329           Mark the kernel read-only data as write-protected in the pagetables,
330           in order to catch accidental (and incorrect) writes to such const
331 diff -urNp linux-2.6.16.12/arch/i386/kernel/acpi/sleep.c linux-2.6.16.12/arch/i386/kernel/acpi/sleep.c
332 --- linux-2.6.16.12/arch/i386/kernel/acpi/sleep.c       2006-05-01 15:14:26.000000000 -0400
333 +++ linux-2.6.16.12/arch/i386/kernel/acpi/sleep.c       2006-05-01 20:17:33.000000000 -0400
334 @@ -10,6 +10,7 @@
335  #include <linux/dmi.h>
336  #include <asm/smp.h>
337  #include <asm/tlbflush.h>
338 +#include <asm/desc.h>
339  
340  /* address in low memory of the wakeup routine. */
341  unsigned long acpi_wakeup_address = 0;
342 @@ -24,11 +25,22 @@ static void init_low_mapping(pgd_t * pgd
343  {
344         int pgd_ofs = 0;
345  
346 +#ifdef CONFIG_PAX_KERNEXEC
347 +       unsigned long cr0;
348 +
349 +       pax_open_kernel(cr0);
350 +#endif
351 +
352         while ((pgd_ofs < pgd_limit)
353                && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
354                 set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD));
355                 pgd_ofs++, pgd++;
356         }
357 +
358 +#ifdef CONFIG_PAX_KERNEXEC
359 +       pax_close_kernel(cr0);
360 +#endif
361 +
362         flush_tlb_all();
363  }
364  
365 @@ -55,7 +67,18 @@ int acpi_save_state_mem(void)
366   */
367  void acpi_restore_state_mem(void)
368  {
369 +#ifdef CONFIG_PAX_KERNEXEC
370 +       unsigned long cr0;
371 +
372 +       pax_open_kernel(cr0);
373 +#endif
374 +
375         zap_low_mappings();
376 +
377 +#ifdef CONFIG_PAX_KERNEXEC
378 +       pax_close_kernel(cr0);
379 +#endif
380 +
381  }
382  
383  /**
384 diff -urNp linux-2.6.16.12/arch/i386/kernel/apic.c linux-2.6.16.12/arch/i386/kernel/apic.c
385 --- linux-2.6.16.12/arch/i386/kernel/apic.c     2006-05-01 15:14:26.000000000 -0400
386 +++ linux-2.6.16.12/arch/i386/kernel/apic.c     2006-05-01 20:17:33.000000000 -0400
387 @@ -1150,7 +1150,7 @@ inline void smp_local_timer_interrupt(st
388  {
389         profile_tick(CPU_PROFILING, regs);
390  #ifdef CONFIG_SMP
391 -       update_process_times(user_mode_vm(regs));
392 +       update_process_times(user_mode(regs));
393  #endif
394  
395         /*
396 diff -urNp linux-2.6.16.12/arch/i386/kernel/apm.c linux-2.6.16.12/arch/i386/kernel/apm.c
397 --- linux-2.6.16.12/arch/i386/kernel/apm.c      2006-05-01 15:14:26.000000000 -0400
398 +++ linux-2.6.16.12/arch/i386/kernel/apm.c      2006-05-01 20:17:33.000000000 -0400
399 @@ -589,9 +589,18 @@ static u8 apm_bios_call(u32 func, u32 eb
400         struct desc_struct      save_desc_40;
401         struct desc_struct      *gdt;
402  
403 +#ifdef CONFIG_PAX_KERNEXEC
404 +       unsigned long           cr0;
405 +#endif
406 +
407         cpus = apm_save_cpus();
408         
409         cpu = get_cpu();
410 +
411 +#ifdef CONFIG_PAX_KERNEXEC
412 +       pax_open_kernel(cr0);
413 +#endif
414 +
415         gdt = get_cpu_gdt_table(cpu);
416         save_desc_40 = gdt[0x40 / 8];
417         gdt[0x40 / 8] = bad_bios_desc;
418 @@ -603,6 +612,11 @@ static u8 apm_bios_call(u32 func, u32 eb
419         APM_DO_RESTORE_SEGS;
420         local_irq_restore(flags);
421         gdt[0x40 / 8] = save_desc_40;
422 +
423 +#ifdef CONFIG_PAX_KERNEXEC
424 +       pax_close_kernel(cr0);
425 +#endif
426 +
427         put_cpu();
428         apm_restore_cpus(cpus);
429         
430 @@ -633,9 +647,18 @@ static u8 apm_bios_call_simple(u32 func,
431         struct desc_struct      save_desc_40;
432         struct desc_struct      *gdt;
433  
434 +#ifdef CONFIG_PAX_KERNEXEC
435 +       unsigned long           cr0;
436 +#endif
437 +
438         cpus = apm_save_cpus();
439         
440         cpu = get_cpu();
441 +
442 +#ifdef CONFIG_PAX_KERNEXEC
443 +       pax_open_kernel(cr0);
444 +#endif
445 +
446         gdt = get_cpu_gdt_table(cpu);
447         save_desc_40 = gdt[0x40 / 8];
448         gdt[0x40 / 8] = bad_bios_desc;
449 @@ -647,6 +670,11 @@ static u8 apm_bios_call_simple(u32 func,
450         APM_DO_RESTORE_SEGS;
451         local_irq_restore(flags);
452         gdt[0x40 / 8] = save_desc_40;
453 +
454 +#ifdef CONFIG_PAX_KERNEXEC
455 +       pax_close_kernel(cr0);
456 +#endif
457 +
458         put_cpu();
459         apm_restore_cpus(cpus);
460         return error;
461 diff -urNp linux-2.6.16.12/arch/i386/kernel/asm-offsets.c linux-2.6.16.12/arch/i386/kernel/asm-offsets.c
462 --- linux-2.6.16.12/arch/i386/kernel/asm-offsets.c      2006-05-01 15:14:26.000000000 -0400
463 +++ linux-2.6.16.12/arch/i386/kernel/asm-offsets.c      2006-05-01 20:17:33.000000000 -0400
464 @@ -68,5 +68,6 @@ void foo(void)
465                  sizeof(struct tss_struct));
466  
467         DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
468 +       DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
469         DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
470  }
471 diff -urNp linux-2.6.16.12/arch/i386/kernel/cpu/common.c linux-2.6.16.12/arch/i386/kernel/cpu/common.c
472 --- linux-2.6.16.12/arch/i386/kernel/cpu/common.c       2006-05-01 15:14:26.000000000 -0400
473 +++ linux-2.6.16.12/arch/i386/kernel/cpu/common.c       2006-05-01 20:17:33.000000000 -0400
474 @@ -4,7 +4,6 @@
475  #include <linux/smp.h>
476  #include <linux/module.h>
477  #include <linux/percpu.h>
478 -#include <linux/bootmem.h>
479  #include <asm/semaphore.h>
480  #include <asm/processor.h>
481  #include <asm/i387.h>
482 @@ -19,9 +18,6 @@
483  
484  #include "cpu.h"
485  
486 -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
487 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
488 -
489  DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
490  EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
491  
492 @@ -387,6 +383,10 @@ void __devinit identify_cpu(struct cpuin
493         if (this_cpu->c_init)
494                 this_cpu->c_init(c);
495  
496 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
497 +       clear_bit(X86_FEATURE_SEP, c->x86_capability);
498 +#endif
499 +
500         /* Disable the PN if appropriate */
501         squash_the_stupid_serial_number(c);
502  
503 @@ -573,11 +573,10 @@ void __init early_cpu_init(void)
504  void __devinit cpu_init(void)
505  {
506         int cpu = smp_processor_id();
507 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
508 +       struct tss_struct * t = init_tss + cpu;
509         struct thread_struct *thread = &current->thread;
510 -       struct desc_struct *gdt;
511 +       struct desc_struct *gdt = get_cpu_gdt_table(cpu);
512         __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
513 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
514  
515         if (cpu_test_and_set(cpu, cpu_initialized)) {
516                 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
517 @@ -595,29 +594,11 @@ void __devinit cpu_init(void)
518         }
519  
520         /*
521 -        * This is a horrible hack to allocate the GDT.  The problem
522 -        * is that cpu_init() is called really early for the boot CPU
523 -        * (and hence needs bootmem) but much later for the secondary
524 -        * CPUs, when bootmem will have gone away
525 -        */
526 -       if (NODE_DATA(0)->bdata->node_bootmem_map) {
527 -               gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
528 -               /* alloc_bootmem_pages panics on failure, so no check */
529 -               memset(gdt, 0, PAGE_SIZE);
530 -       } else {
531 -               gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
532 -               if (unlikely(!gdt)) {
533 -                       printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
534 -                       for (;;)
535 -                               local_irq_enable();
536 -               }
537 -       }
538 -
539 -       /*
540          * Initialize the per-CPU GDT with the boot GDT,
541          * and set up the GDT descriptor:
542          */
543 -       memcpy(gdt, cpu_gdt_table, GDT_SIZE);
544 +       if (cpu)
545 +               memcpy(gdt, cpu_gdt_table, GDT_SIZE);
546  
547         /* Set up GDT entry for 16bit stack */
548         *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
549 @@ -625,10 +606,10 @@ void __devinit cpu_init(void)
550                 ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
551                 (CPU_16BIT_STACK_SIZE - 1);
552  
553 -       cpu_gdt_descr->size = GDT_SIZE - 1;
554 -       cpu_gdt_descr->address = (unsigned long)gdt;
555 +       cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
556 +       cpu_gdt_descr[cpu].address = (unsigned long)gdt;
557  
558 -       load_gdt(cpu_gdt_descr);
559 +       load_gdt(&cpu_gdt_descr[cpu]);
560         load_idt(&idt_descr);
561  
562         /*
563 @@ -643,7 +624,7 @@ void __devinit cpu_init(void)
564         load_esp0(t, thread);
565         set_tss_desc(cpu,t);
566         load_TR_desc();
567 -       load_LDT(&init_mm.context);
568 +       _load_LDT(&init_mm.context);
569  
570  #ifdef CONFIG_DOUBLEFAULT
571         /* Set up doublefault TSS pointer in the GDT */
572 diff -urNp linux-2.6.16.12/arch/i386/kernel/doublefault.c linux-2.6.16.12/arch/i386/kernel/doublefault.c
573 --- linux-2.6.16.12/arch/i386/kernel/doublefault.c      2006-05-01 15:14:26.000000000 -0400
574 +++ linux-2.6.16.12/arch/i386/kernel/doublefault.c      2006-05-01 20:17:33.000000000 -0400
575 @@ -11,7 +11,7 @@
576  
577  #define DOUBLEFAULT_STACKSIZE (1024)
578  static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
579 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
580 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
581  
582  #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
583  
584 diff -urNp linux-2.6.16.12/arch/i386/kernel/efi.c linux-2.6.16.12/arch/i386/kernel/efi.c
585 --- linux-2.6.16.12/arch/i386/kernel/efi.c      2006-05-01 15:14:26.000000000 -0400
586 +++ linux-2.6.16.12/arch/i386/kernel/efi.c      2006-05-01 20:17:33.000000000 -0400
587 @@ -64,82 +64,58 @@ extern void * boot_ioremap(unsigned long
588  
589  static unsigned long efi_rt_eflags;
590  static DEFINE_SPINLOCK(efi_rt_lock);
591 -static pgd_t efi_bak_pg_dir_pointer[2];
592 +static pgd_t __initdata efi_bak_pg_dir_pointer[4];
593  
594 -static void efi_call_phys_prelog(void)
595 +static void __init efi_call_phys_prelog(void)
596  {
597 -       unsigned long cr4;
598 -       unsigned long temp;
599 -       struct Xgt_desc_struct *cpu_gdt_descr;
600 -
601         spin_lock(&efi_rt_lock);
602         local_irq_save(efi_rt_eflags);
603  
604 -       cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
605 +       efi_bak_pg_dir_pointer[0] = swapper_pg_dir[0];
606 +       swapper_pg_dir[0] = swapper_pg_dir[USER_PTRS_PER_PGD];
607  
608 -       /*
609 -        * If I don't have PSE, I should just duplicate two entries in page
610 -        * directory. If I have PSE, I just need to duplicate one entry in
611 -        * page directory.
612 -        */
613 -       cr4 = read_cr4();
614 -
615 -       if (cr4 & X86_CR4_PSE) {
616 -               efi_bak_pg_dir_pointer[0].pgd =
617 -                   swapper_pg_dir[pgd_index(0)].pgd;
618 -               swapper_pg_dir[0].pgd =
619 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
620 -       } else {
621 -               efi_bak_pg_dir_pointer[0].pgd =
622 -                   swapper_pg_dir[pgd_index(0)].pgd;
623 -               efi_bak_pg_dir_pointer[1].pgd =
624 -                   swapper_pg_dir[pgd_index(0x400000)].pgd;
625 -               swapper_pg_dir[pgd_index(0)].pgd =
626 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
627 -               temp = PAGE_OFFSET + 0x400000;
628 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
629 -                   swapper_pg_dir[pgd_index(temp)].pgd;
630 -       }
631 +#ifndef CONFIG_X86_PAE
632 +       efi_bak_pg_dir_pointer[1] = swapper_pg_dir[1];
633 +       swapper_pg_dir[1] = swapper_pg_dir[USER_PTRS_PER_PGD+1];
634 +       efi_bak_pg_dir_pointer[2] = swapper_pg_dir[2];
635 +       swapper_pg_dir[2] = swapper_pg_dir[USER_PTRS_PER_PGD+2];
636 +       efi_bak_pg_dir_pointer[3] = swapper_pg_dir[3];
637 +       swapper_pg_dir[3] = swapper_pg_dir[USER_PTRS_PER_PGD+3];
638 +#endif
639  
640         /*
641          * After the lock is released, the original page table is restored.
642          */
643 -       local_flush_tlb();
644 +       __flush_tlb_all();
645  
646 -       cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
647 -       load_gdt(cpu_gdt_descr);
648 +       cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
649 +       load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
650  }
651  
652 -static void efi_call_phys_epilog(void)
653 +static void __init efi_call_phys_epilog(void)
654  {
655 -       unsigned long cr4;
656 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
657 -
658 -       cpu_gdt_descr->address = __va(cpu_gdt_descr->address);
659 -       load_gdt(cpu_gdt_descr);
660 +       cpu_gdt_descr[0].address =
661 +               (unsigned long) __va(cpu_gdt_descr[0].address);
662 +       load_gdt(&cpu_gdt_descr[0]);
663  
664 -       cr4 = read_cr4();
665 +       swapper_pg_dir[0] = efi_bak_pg_dir_pointer[0];
666  
667 -       if (cr4 & X86_CR4_PSE) {
668 -               swapper_pg_dir[pgd_index(0)].pgd =
669 -                   efi_bak_pg_dir_pointer[0].pgd;
670 -       } else {
671 -               swapper_pg_dir[pgd_index(0)].pgd =
672 -                   efi_bak_pg_dir_pointer[0].pgd;
673 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
674 -                   efi_bak_pg_dir_pointer[1].pgd;
675 -       }
676 +#ifndef CONFIG_X86_PAE
677 +       swapper_pg_dir[1] = efi_bak_pg_dir_pointer[1];
678 +       swapper_pg_dir[2] = efi_bak_pg_dir_pointer[2];
679 +       swapper_pg_dir[3] = efi_bak_pg_dir_pointer[3];
680 +#endif
681  
682         /*
683          * After the lock is released, the original page table is restored.
684          */
685 -       local_flush_tlb();
686 +       __flush_tlb_all();
687  
688         local_irq_restore(efi_rt_eflags);
689         spin_unlock(&efi_rt_lock);
690  }
691  
692 -static efi_status_t
693 +static efi_status_t __init
694  phys_efi_set_virtual_address_map(unsigned long memory_map_size,
695                                  unsigned long descriptor_size,
696                                  u32 descriptor_version,
697 @@ -155,7 +131,7 @@ phys_efi_set_virtual_address_map(unsigne
698         return status;
699  }
700  
701 -static efi_status_t
702 +static efi_status_t __init
703  phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
704  {
705         efi_status_t status;
706 diff -urNp linux-2.6.16.12/arch/i386/kernel/efi_stub.S linux-2.6.16.12/arch/i386/kernel/efi_stub.S
707 --- linux-2.6.16.12/arch/i386/kernel/efi_stub.S 2006-05-01 15:14:26.000000000 -0400
708 +++ linux-2.6.16.12/arch/i386/kernel/efi_stub.S 2006-05-01 20:17:33.000000000 -0400
709 @@ -7,6 +7,7 @@
710  
711  #include <linux/config.h>
712  #include <linux/linkage.h>
713 +#include <linux/init.h>
714  #include <asm/page.h>
715  #include <asm/pgtable.h>
716  
717 @@ -22,7 +23,7 @@
718   * service functions will comply with gcc calling convention, too.
719   */
720  
721 -.text
722 +__INIT
723  ENTRY(efi_call_phys)
724         /*
725          * 0. The function can only be called in Linux kernel. So CS has been
726 @@ -38,9 +39,7 @@ ENTRY(efi_call_phys)
727          * The mapping of lower virtual memory has been created in prelog and
728          * epilog.
729          */
730 -       movl    $1f, %edx
731 -       subl    $__PAGE_OFFSET, %edx
732 -       jmp     *%edx
733 +       jmp     1f-__PAGE_OFFSET
734  1:
735  
736         /*
737 @@ -49,14 +48,8 @@ ENTRY(efi_call_phys)
738          * parameter 2, ..., param n. To make things easy, we save the return
739          * address of efi_call_phys in a global variable.
740          */
741 -       popl    %edx
742 -       movl    %edx, saved_return_addr
743 -       /* get the function pointer into ECX*/
744 -       popl    %ecx
745 -       movl    %ecx, efi_rt_function_ptr
746 -       movl    $2f, %edx
747 -       subl    $__PAGE_OFFSET, %edx
748 -       pushl   %edx
749 +       popl    (saved_return_addr)
750 +       popl    (efi_rt_function_ptr)
751  
752         /*
753          * 3. Clear PG bit in %CR0.
754 @@ -75,9 +68,8 @@ ENTRY(efi_call_phys)
755         /*
756          * 5. Call the physical function.
757          */
758 -       jmp     *%ecx
759 +       call    *(efi_rt_function_ptr-__PAGE_OFFSET)
760  
761 -2:
762         /*
763          * 6. After EFI runtime service returns, control will return to
764          * following instruction. We'd better readjust stack pointer first.
765 @@ -87,37 +79,29 @@ ENTRY(efi_call_phys)
766         /*
767          * 7. Restore PG bit
768          */
769 -       movl    %cr0, %edx
770 -       orl     $0x80000000, %edx
771 -       movl    %edx, %cr0
772 -       jmp     1f
773 -1:
774         /*
775          * 8. Now restore the virtual mode from flat mode by
776          * adding EIP with PAGE_OFFSET.
777          */
778 -       movl    $1f, %edx
779 -       jmp     *%edx
780 +       movl    %cr0, %edx
781 +       orl     $0x80000000, %edx
782 +       movl    %edx, %cr0
783 +       jmp     1f+__PAGE_OFFSET
784  1:
785  
786         /*
787          * 9. Balance the stack. And because EAX contain the return value,
788          * we'd better not clobber it.
789          */
790 -       leal    efi_rt_function_ptr, %edx
791 -       movl    (%edx), %ecx
792 -       pushl   %ecx
793 +       pushl   (efi_rt_function_ptr)
794  
795         /*
796 -        * 10. Push the saved return address onto the stack and return.
797 +        * 10. Return to the saved return address.
798          */
799 -       leal    saved_return_addr, %edx
800 -       movl    (%edx), %ecx
801 -       pushl   %ecx
802 -       ret
803 +       jmpl    *(saved_return_addr)
804  .previous
805  
806 -.data
807 +__INITDATA
808  saved_return_addr:
809         .long 0
810  efi_rt_function_ptr:
811 diff -urNp linux-2.6.16.12/arch/i386/kernel/entry.S linux-2.6.16.12/arch/i386/kernel/entry.S
812 --- linux-2.6.16.12/arch/i386/kernel/entry.S    2006-05-01 15:14:26.000000000 -0400
813 +++ linux-2.6.16.12/arch/i386/kernel/entry.S    2006-05-01 20:17:33.000000000 -0400
814 @@ -82,7 +82,7 @@ VM_MASK               = 0x00020000
815  #define resume_kernel          restore_nocheck
816  #endif
817  
818 -#define SAVE_ALL \
819 +#define __SAVE_ALL \
820         cld; \
821         pushl %es; \
822         pushl %ds; \
823 @@ -97,6 +97,18 @@ VM_MASK              = 0x00020000
824         movl %edx, %ds; \
825         movl %edx, %es;
826  
827 +#ifdef CONFIG_PAX_KERNEXEC
828 +#define SAVE_ALL \
829 +       __SAVE_ALL \
830 +       movl %cr0, %edx; \
831 +       movl %edx, %esi; \
832 +       orl $0x10000, %edx; \
833 +       xorl %edx, %esi; \
834 +       movl %edx, %cr0;
835 +#else
836 +#define SAVE_ALL __SAVE_ALL
837 +#endif
838 +
839  #define RESTORE_INT_REGS \
840         popl %ebx;      \
841         popl %ecx;      \
842 @@ -146,7 +158,19 @@ ret_from_intr:
843         movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
844         movb CS(%esp), %al
845         testl $(VM_MASK | 3), %eax
846 +
847 +#ifdef CONFIG_PAX_KERNEXEC
848 +       jnz resume_userspace
849 +
850 +       movl %cr0, %edx
851 +       xorl %esi, %edx
852 +       movl %edx, %cr0
853 +       jmp resume_kernel
854 +#else
855         jz resume_kernel
856 +#endif
857 +
858 +
859  ENTRY(resume_userspace)
860         cli                             # make sure we don't miss an interrupt
861                                         # setting need_resched or sigpending
862 @@ -213,6 +237,13 @@ sysenter_past_esp:
863         movl TI_flags(%ebp), %ecx
864         testw $_TIF_ALLWORK_MASK, %cx
865         jne syscall_exit_work
866 +
867 +#ifdef CONFIG_PAX_RANDKSTACK
868 +       pushl %eax
869 +       call pax_randomize_kstack
870 +       popl %eax
871 +#endif
872 +
873  /* if something modifies registers it must also disable sysexit */
874         movl EIP(%esp), %edx
875         movl OLDESP(%esp), %ecx
876 @@ -243,6 +274,10 @@ syscall_exit:
877         testw $_TIF_ALLWORK_MASK, %cx   # current->work
878         jne syscall_exit_work
879  
880 +#ifdef CONFIG_PAX_RANDKSTACK
881 +       call pax_randomize_kstack
882 +#endif
883 +
884  restore_all:
885         movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
886         # Warning: OLDSS(%esp) contains the wrong/random values if we
887 @@ -398,7 +433,7 @@ syscall_badsys:
888   * Build the entry stubs and pointer table with
889   * some assembler magic.
890   */
891 -.data
892 +.section .rodata,"a",@progbits
893  ENTRY(interrupt)
894  .text
895  
896 @@ -408,7 +443,7 @@ ENTRY(irq_entries_start)
897         ALIGN
898  1:     pushl $vector-256
899         jmp common_interrupt
900 -.data
901 +.section .rodata,"a",@progbits
902         .long 1b
903  .text
904  vector=vector+1
905 @@ -459,6 +494,15 @@ error_code:
906         movl %ecx, %ds
907         movl %ecx, %es
908         movl %esp,%eax                  # pt_regs pointer
909 +
910 +#ifdef CONFIG_PAX_KERNEXEC
911 +       movl %cr0, %ecx
912 +       movl %ecx, %esi
913 +       orl $0x10000, %ecx
914 +       xorl %ecx, %esi
915 +       movl %ecx, %cr0
916 +#endif
917 +
918         call *%edi
919         jmp ret_from_exception
920  
921 @@ -554,6 +598,13 @@ nmi_stack_correct:
922         xorl %edx,%edx          # zero error code
923         movl %esp,%eax          # pt_regs pointer
924         call do_nmi
925 +
926 +#ifdef CONFIG_PAX_KERNEXEC
927 +       movl %cr0, %edx
928 +       xorl %esi, %edx
929 +       movl %edx, %cr0
930 +#endif
931 +
932         jmp restore_all
933  
934  nmi_stack_fixup:
935 @@ -584,6 +635,13 @@ nmi_16bit_stack:
936         FIXUP_ESPFIX_STACK              # %eax == %esp
937         xorl %edx,%edx                  # zero error code
938         call do_nmi
939 +
940 +#ifdef CONFIG_PAX_KERNEXEC
941 +       movl %cr0, %edx
942 +       xorl %esi, %edx
943 +       movl %edx, %cr0
944 +#endif
945 +
946         RESTORE_REGS
947         lss 12+4(%esp), %esp            # back to 16bit stack
948  1:     iret
949 @@ -659,7 +717,6 @@ ENTRY(spurious_interrupt_bug)
950         pushl $do_spurious_interrupt_bug
951         jmp error_code
952  
953 -.section .rodata,"a"
954  #include "syscall_table.S"
955  
956  syscall_table_size=(.-sys_call_table)
957 diff -urNp linux-2.6.16.12/arch/i386/kernel/head.S linux-2.6.16.12/arch/i386/kernel/head.S
958 --- linux-2.6.16.12/arch/i386/kernel/head.S     2006-05-01 15:14:26.000000000 -0400
959 +++ linux-2.6.16.12/arch/i386/kernel/head.S     2006-05-01 20:17:33.000000000 -0400
960 @@ -48,6 +48,12 @@
961  
962  
963  /*
964 + * Real beginning of normal "text" segment
965 + */
966 +ENTRY(stext)
967 +ENTRY(_stext)
968 +
969 +/*
970   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
971   * %esi points to the real-mode code as a 32-bit pointer.
972   * CS and DS must be 4 GB flat segments, but we don't depend on
973 @@ -67,6 +73,19 @@ ENTRY(startup_32)
974         movl %eax,%fs
975         movl %eax,%gs
976  
977 +#ifdef CONFIG_PAX_KERNEXEC
978 +       movl $ __KERNEL_TEXT_OFFSET,%eax
979 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
980 +       rorl $16,%eax
981 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
982 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
983 +
984 +       movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
985 +       movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
986 +       rorl $16,%eax
987 +       movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
988 +#endif
989 +
990  /*
991   * Clear BSS first so that there are no surprises...
992   * No need to cld as DF is already clear from cld above...
993 @@ -114,24 +133,42 @@ ENTRY(startup_32)
994   * Warning: don't use %esi or the stack in this code.  However, %esp
995   * can be used as a GPR if you really need it...
996   */
997 -page_pde_offset = (__PAGE_OFFSET >> 20);
998 -
999 +#ifdef CONFIG_X86_PAE
1000 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
1001 +#else
1002 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
1003 +#endif
1004         movl $(pg0 - __PAGE_OFFSET), %edi
1005 +#ifdef CONFIG_X86_PAE
1006 +       movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1007 +#else
1008         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1009 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
1010 +#endif
1011 +       movl $0x063, %eax                       /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1012  10:
1013 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
1014 +       leal 0x063(%edi),%ecx                   /* Create PDE entry */
1015         movl %ecx,(%edx)                        /* Store identity PDE entry */
1016         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
1017 +#ifdef CONFIG_X86_PAE
1018 +       movl $0,4(%edx)
1019 +       movl $0,page_pde_offset+4(%edx)
1020 +       addl $8,%edx
1021 +       movl $512, %ecx
1022 +#else
1023         addl $4,%edx
1024         movl $1024, %ecx
1025 +#endif
1026  11:
1027         stosl
1028 +#ifdef CONFIG_X86_PAE
1029 +       movl $0,(%edi)
1030 +       addl $4,%edi
1031 +#endif
1032         addl $0x1000,%eax
1033         loop 11b
1034         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1035 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1036 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1037 +       /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1038 +       leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1039         cmpl %ebp,%eax
1040         jb 10b
1041         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1042 @@ -154,6 +191,11 @@ ENTRY(startup_32_smp)
1043         movl %eax,%fs
1044         movl %eax,%gs
1045  
1046 +       /* This is a secondary processor (AP) */
1047 +       xorl %ebx,%ebx
1048 +       incl %ebx
1049 +#endif /* CONFIG_SMP */
1050 +
1051  /*
1052   *     New page tables may be in 4Mbyte page mode and may
1053   *     be using the global pages. 
1054 @@ -169,26 +211,27 @@ ENTRY(startup_32_smp)
1055   *     not yet offset PAGE_OFFSET..
1056   */
1057  #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1058 +3:
1059         movl cr4_bits,%edx
1060         andl %edx,%edx
1061 -       jz 6f
1062 +       jz 5f
1063         movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
1064         orl %edx,%eax
1065         movl %eax,%cr4
1066  
1067 -       btl $5, %eax            # check if PAE is enabled
1068 -       jnc 6f
1069 +#ifdef CONFIG_X86_PAE
1070 +       movl %ebx,%edi
1071  
1072         /* Check if extended functions are implemented */
1073         movl $0x80000000, %eax
1074         cpuid
1075         cmpl $0x80000000, %eax
1076 -       jbe 6f
1077 +       jbe 4f
1078         mov $0x80000001, %eax
1079         cpuid
1080         /* Execute Disable bit supported? */
1081         btl $20, %edx
1082 -       jnc 6f
1083 +       jnc 4f
1084  
1085         /* Setup EFER (Extended Feature Enable Register) */
1086         movl $0xc0000080, %ecx
1087 @@ -197,14 +240,12 @@ ENTRY(startup_32_smp)
1088         btsl $11, %eax
1089         /* Make changes effective */
1090         wrmsr
1091 +       btsl $63,__supported_pte_mask-__PAGE_OFFSET
1092  
1093 -6:
1094 -       /* This is a secondary processor (AP) */
1095 -       xorl %ebx,%ebx
1096 -       incl %ebx
1097 -
1098 -3:
1099 -#endif /* CONFIG_SMP */
1100 +4:
1101 +       movl %edi,%ebx
1102 +#endif
1103 +5:
1104  
1105  /*
1106   * Enable paging
1107 @@ -229,9 +270,7 @@ ENTRY(startup_32_smp)
1108  
1109  #ifdef CONFIG_SMP
1110         andl %ebx,%ebx
1111 -       jz  1f                          /* Initial CPU cleans BSS */
1112 -       jmp checkCPUtype
1113 -1:
1114 +       jnz checkCPUtype        /* Initial CPU cleans BSS */
1115  #endif /* CONFIG_SMP */
1116  
1117  /*
1118 @@ -412,32 +451,50 @@ ignore_int:
1119  #endif
1120         iret
1121  
1122 -/*
1123 - * Real beginning of normal "text" segment
1124 - */
1125 -ENTRY(stext)
1126 -ENTRY(_stext)
1127 -
1128 -/*
1129 - * BSS section
1130 - */
1131 -.section ".bss.page_aligned","w"
1132 +.section .swapper_pg_dir,"a",@progbits
1133  ENTRY(swapper_pg_dir)
1134 +#ifdef CONFIG_X86_PAE
1135 +       .long swapper_pm_dir-__PAGE_OFFSET+1
1136 +       .long 0
1137 +       .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1138 +       .long 0
1139 +       .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1140 +       .long 0
1141 +       .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1142 +       .long 0
1143 +#else
1144         .fill 1024,4,0
1145 +#endif
1146 +
1147 +#ifdef CONFIG_X86_PAE
1148 +.section .swapper_pm_dir,"a",@progbits
1149 +ENTRY(swapper_pm_dir)
1150 +       .fill 512,8,0
1151 +       .fill 512,8,0
1152 +       .fill 512,8,0
1153 +       .fill 512,8,0
1154 +#endif
1155 +
1156 +.section .empty_zero_page,"a",@progbits
1157  ENTRY(empty_zero_page)
1158         .fill 4096,1,0
1159  
1160  /*
1161 - * This starts the data section.
1162 - */
1163 -.data
1164 + * The IDT has to be page-aligned to simplify the Pentium
1165 + * F0 0F bug workaround.. We have a special link segment
1166 + * for this.
1167 + */
1168 +.section .idt,"a",@progbits
1169 +ENTRY(idt_table)
1170 +       .fill 256,8,0
1171 +
1172 +.section .rodata,"a",@progbits
1173 +ready: .byte 0
1174  
1175  ENTRY(stack_start)
1176 -       .long init_thread_union+THREAD_SIZE
1177 +       .long init_thread_union+THREAD_SIZE-8
1178         .long __BOOT_DS
1179  
1180 -ready: .byte 0
1181 -
1182  int_msg:
1183         .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
1184  
1185 @@ -479,8 +536,8 @@ cpu_gdt_descr:
1186         .align L1_CACHE_BYTES
1187  ENTRY(boot_gdt_table)
1188         .fill GDT_ENTRY_BOOT_CS,8,0
1189 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
1190 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
1191 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
1192 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
1193  
1194  /*
1195   * The Global Descriptor Table contains 28 quadwords, per-CPU.
1196 @@ -500,10 +557,10 @@ ENTRY(cpu_gdt_table)
1197         .quad 0x0000000000000000        /* 0x53 reserved */
1198         .quad 0x0000000000000000        /* 0x5b reserved */
1199  
1200 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1201 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1202 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1203 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1204 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1205 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1206 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1207 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1208  
1209         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
1210         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
1211 @@ -513,24 +570,30 @@ ENTRY(cpu_gdt_table)
1212          * They code segments and data segments have fixed 64k limits,
1213          * the transfer segment sizes are set at run time.
1214          */
1215 -       .quad 0x00409a000000ffff        /* 0x90 32-bit code */
1216 -       .quad 0x00009a000000ffff        /* 0x98 16-bit code */
1217 -       .quad 0x000092000000ffff        /* 0xa0 16-bit data */
1218 -       .quad 0x0000920000000000        /* 0xa8 16-bit data */
1219 -       .quad 0x0000920000000000        /* 0xb0 16-bit data */
1220 +       .quad 0x00409b000000ffff        /* 0x90 32-bit code */
1221 +       .quad 0x00009b000000ffff        /* 0x98 16-bit code */
1222 +       .quad 0x000093000000ffff        /* 0xa0 16-bit data */
1223 +       .quad 0x0000930000000000        /* 0xa8 16-bit data */
1224 +       .quad 0x0000930000000000        /* 0xb0 16-bit data */
1225  
1226         /*
1227          * The APM segments have byte granularity and their bases
1228          * are set at run time.  All have 64k limits.
1229          */
1230 -       .quad 0x00409a000000ffff        /* 0xb8 APM CS    code */
1231 -       .quad 0x00009a000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1232 -       .quad 0x004092000000ffff        /* 0xc8 APM DS    data */
1233 +       .quad 0x00409b000000ffff        /* 0xb8 APM CS    code */
1234 +       .quad 0x00009b000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1235 +       .quad 0x004093000000ffff        /* 0xc8 APM DS    data */
1236  
1237 -       .quad 0x0000920000000000        /* 0xd0 - ESPFIX 16-bit SS */
1238 +       .quad 0x0000930000000000        /* 0xd0 - ESPFIX 16-bit SS */
1239         .quad 0x0000000000000000        /* 0xd8 - unused */
1240         .quad 0x0000000000000000        /* 0xe0 - unused */
1241         .quad 0x0000000000000000        /* 0xe8 - unused */
1242         .quad 0x0000000000000000        /* 0xf0 - unused */
1243         .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
1244  
1245 +       /* Be sure this is zeroed to avoid false validations in Xen */
1246 +       .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
1247 +
1248 +#ifdef CONFIG_SMP
1249 +       .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
1250 +#endif
1251 diff -urNp linux-2.6.16.12/arch/i386/kernel/i386_ksyms.c linux-2.6.16.12/arch/i386/kernel/i386_ksyms.c
1252 --- linux-2.6.16.12/arch/i386/kernel/i386_ksyms.c       2006-05-01 15:14:26.000000000 -0400
1253 +++ linux-2.6.16.12/arch/i386/kernel/i386_ksyms.c       2006-05-01 20:17:33.000000000 -0400
1254 @@ -3,6 +3,8 @@
1255  #include <asm/checksum.h>
1256  #include <asm/desc.h>
1257  
1258 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
1259 +
1260  EXPORT_SYMBOL(__down_failed);
1261  EXPORT_SYMBOL(__down_failed_interruptible);
1262  EXPORT_SYMBOL(__down_failed_trylock);
1263 diff -urNp linux-2.6.16.12/arch/i386/kernel/init_task.c linux-2.6.16.12/arch/i386/kernel/init_task.c
1264 --- linux-2.6.16.12/arch/i386/kernel/init_task.c        2006-05-01 15:14:26.000000000 -0400
1265 +++ linux-2.6.16.12/arch/i386/kernel/init_task.c        2006-05-01 20:17:33.000000000 -0400
1266 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
1267   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
1268   * no more per-task TSS's.
1269   */ 
1270 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
1271 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
1272  
1273 diff -urNp linux-2.6.16.12/arch/i386/kernel/ioport.c linux-2.6.16.12/arch/i386/kernel/ioport.c
1274 --- linux-2.6.16.12/arch/i386/kernel/ioport.c   2006-05-01 15:14:26.000000000 -0400
1275 +++ linux-2.6.16.12/arch/i386/kernel/ioport.c   2006-05-01 20:17:33.000000000 -0400
1276 @@ -16,6 +16,7 @@
1277  #include <linux/stddef.h>
1278  #include <linux/slab.h>
1279  #include <linux/thread_info.h>
1280 +#include <linux/grsecurity.h>
1281  
1282  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
1283  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
1284 @@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
1285  
1286         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
1287                 return -EINVAL;
1288 +#ifdef CONFIG_GRKERNSEC_IO
1289 +       if (turn_on) {
1290 +               gr_handle_ioperm();
1291 +#else
1292         if (turn_on && !capable(CAP_SYS_RAWIO))
1293 +#endif
1294                 return -EPERM;
1295 -
1296 +#ifdef CONFIG_GRKERNSEC_IO
1297 +       }
1298 +#endif
1299         /*
1300          * If it's the first ioperm() call in this thread's lifetime, set the
1301          * IO bitmap up. ioperm() is much less timing critical than clone(),
1302 @@ -88,7 +96,7 @@ asmlinkage long sys_ioperm(unsigned long
1303          * because the ->io_bitmap_max value must match the bitmap
1304          * contents:
1305          */
1306 -       tss = &per_cpu(init_tss, get_cpu());
1307 +       tss = init_tss + get_cpu();
1308  
1309         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
1310  
1311 @@ -142,8 +150,13 @@ asmlinkage long sys_iopl(unsigned long u
1312                 return -EINVAL;
1313         /* Trying to gain more privileges? */
1314         if (level > old) {
1315 +#ifdef CONFIG_GRKERNSEC_IO
1316 +               gr_handle_iopl();
1317 +               return -EPERM;
1318 +#else
1319                 if (!capable(CAP_SYS_RAWIO))
1320                         return -EPERM;
1321 +#endif
1322         }
1323         t->iopl = level << 12;
1324         regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
1325 diff -urNp linux-2.6.16.12/arch/i386/kernel/irq.c linux-2.6.16.12/arch/i386/kernel/irq.c
1326 --- linux-2.6.16.12/arch/i386/kernel/irq.c      2006-05-01 15:14:26.000000000 -0400
1327 +++ linux-2.6.16.12/arch/i386/kernel/irq.c      2006-05-01 20:17:33.000000000 -0400
1328 @@ -91,7 +91,7 @@ fastcall unsigned int do_IRQ(struct pt_r
1329                 int arg1, arg2, ebx;
1330  
1331                 /* build the stack frame on the IRQ stack */
1332 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1333 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1334                 irqctx->tinfo.task = curctx->tinfo.task;
1335                 irqctx->tinfo.previous_esp = current_stack_pointer;
1336  
1337 @@ -119,10 +119,10 @@ fastcall unsigned int do_IRQ(struct pt_r
1338   * gcc's 3.0 and earlier don't handle that correctly.
1339   */
1340  static char softirq_stack[NR_CPUS * THREAD_SIZE]
1341 -               __attribute__((__aligned__(THREAD_SIZE)));
1342 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1343  
1344  static char hardirq_stack[NR_CPUS * THREAD_SIZE]
1345 -               __attribute__((__aligned__(THREAD_SIZE)));
1346 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1347  
1348  /*
1349   * allocate per-cpu stacks for hardirq and for softirq processing
1350 @@ -182,7 +182,7 @@ asmlinkage void do_softirq(void)
1351                 irqctx->tinfo.previous_esp = current_stack_pointer;
1352  
1353                 /* build the stack frame on the softirq stack */
1354 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1355 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1356  
1357                 asm volatile(
1358                         "       xchgl   %%ebx,%%esp     \n"
1359 diff -urNp linux-2.6.16.12/arch/i386/kernel/ldt.c linux-2.6.16.12/arch/i386/kernel/ldt.c
1360 --- linux-2.6.16.12/arch/i386/kernel/ldt.c      2006-05-01 15:14:26.000000000 -0400
1361 +++ linux-2.6.16.12/arch/i386/kernel/ldt.c      2006-05-01 20:17:33.000000000 -0400
1362 @@ -103,6 +103,19 @@ int init_new_context(struct task_struct 
1363                 retval = copy_ldt(&mm->context, &old_mm->context);
1364                 up(&old_mm->context.sem);
1365         }
1366 +
1367 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1368 +       if (!mm->context.user_cs_limit) {
1369 +               mm->context.user_cs_base = 0UL;
1370 +               mm->context.user_cs_limit = ~0UL;
1371 +
1372 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
1373 +               cpus_clear(mm->context.cpu_user_cs_mask);
1374 +#endif
1375 +
1376 +       }
1377 +#endif
1378 +
1379         return retval;
1380  }
1381  
1382 @@ -160,7 +173,7 @@ static int read_default_ldt(void __user 
1383  {
1384         int err;
1385         unsigned long size;
1386 -       void *address;
1387 +       const void *address;
1388  
1389         err = 0;
1390         address = &default_ldt[0];
1391 @@ -215,6 +228,13 @@ static int write_ldt(void __user * ptr, 
1392                 }
1393         }
1394  
1395 +#ifdef CONFIG_PAX_SEGMEXEC
1396 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
1397 +               error = -EINVAL;
1398 +               goto out_unlock;
1399 +       }
1400 +#endif
1401 +
1402         entry_1 = LDT_entry_a(&ldt_info);
1403         entry_2 = LDT_entry_b(&ldt_info);
1404         if (oldmode)
1405 diff -urNp linux-2.6.16.12/arch/i386/kernel/module.c linux-2.6.16.12/arch/i386/kernel/module.c
1406 --- linux-2.6.16.12/arch/i386/kernel/module.c   2006-05-01 15:14:26.000000000 -0400
1407 +++ linux-2.6.16.12/arch/i386/kernel/module.c   2006-05-01 20:17:33.000000000 -0400
1408 @@ -21,6 +21,7 @@
1409  #include <linux/fs.h>
1410  #include <linux/string.h>
1411  #include <linux/kernel.h>
1412 +#include <asm/desc.h>
1413  
1414  #if 0
1415  #define DEBUGP printk
1416 @@ -32,9 +33,30 @@ void *module_alloc(unsigned long size)
1417  {
1418         if (size == 0)
1419                 return NULL;
1420 +
1421 +#ifdef CONFIG_PAX_KERNEXEC
1422 +       return vmalloc(size);
1423 +#else
1424         return vmalloc_exec(size);
1425 +#endif
1426 +
1427  }
1428  
1429 +#ifdef CONFIG_PAX_KERNEXEC
1430 +void *module_alloc_exec(unsigned long size)
1431 +{
1432 +       struct vm_struct *area;
1433 +
1434 +       if (size == 0)
1435 +               return NULL;
1436 +
1437 +       area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
1438 +       if (area)
1439 +               return area->addr;
1440 +
1441 +       return NULL;
1442 +}
1443 +#endif
1444  
1445  /* Free memory returned from module_alloc */
1446  void module_free(struct module *mod, void *module_region)
1447 @@ -44,6 +66,45 @@ void module_free(struct module *mod, voi
1448             table entries. */
1449  }
1450  
1451 +#ifdef CONFIG_PAX_KERNEXEC
1452 +void module_free_exec(struct module *mod, void *module_region)
1453 +{
1454 +       struct vm_struct **p, *tmp;
1455 +
1456 +       if (!module_region)
1457 +               return;
1458 +
1459 +       if ((PAGE_SIZE-1) & (unsigned long)module_region) {
1460 +               printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
1461 +               WARN_ON(1);
1462 +               return;
1463 +       }
1464 +
1465 +       write_lock(&vmlist_lock);
1466 +       for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
1467 +                if (tmp->addr == module_region)
1468 +                       break;
1469 +
1470 +       if (tmp) {
1471 +               unsigned long cr0;
1472 +
1473 +               pax_open_kernel(cr0);
1474 +               memset(tmp->addr, 0xCC, tmp->size);
1475 +               pax_close_kernel(cr0);
1476 +
1477 +               *p = tmp->next;
1478 +               kfree(tmp);
1479 +       }
1480 +       write_unlock(&vmlist_lock);
1481 +
1482 +       if (!tmp) {
1483 +               printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
1484 +                               module_region);
1485 +               WARN_ON(1);
1486 +       }
1487 +}
1488 +#endif
1489 +
1490  /* We don't need anything special. */
1491  int module_frob_arch_sections(Elf_Ehdr *hdr,
1492                               Elf_Shdr *sechdrs,
1493 @@ -62,14 +123,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1494         unsigned int i;
1495         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
1496         Elf32_Sym *sym;
1497 -       uint32_t *location;
1498 +       uint32_t *plocation, location;
1499  
1500         DEBUGP("Applying relocate section %u to %u\n", relsec,
1501                sechdrs[relsec].sh_info);
1502         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
1503                 /* This is where to make the change */
1504 -               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
1505 -                       + rel[i].r_offset;
1506 +               plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
1507 +               location = (uint32_t)plocation;
1508 +               if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
1509 +                       plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
1510                 /* This is the symbol it is referring to.  Note that all
1511                    undefined symbols have been resolved.  */
1512                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
1513 @@ -78,11 +141,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1514                 switch (ELF32_R_TYPE(rel[i].r_info)) {
1515                 case R_386_32:
1516                         /* We add the value into the location given */
1517 -                       *location += sym->st_value;
1518 +                       *plocation += sym->st_value;
1519                         break;
1520                 case R_386_PC32:
1521                         /* Add the value, subtract its postition */
1522 -                       *location += sym->st_value - (uint32_t)location;
1523 +                       *plocation += sym->st_value - location;
1524                         break;
1525                 default:
1526                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
1527 diff -urNp linux-2.6.16.12/arch/i386/kernel/process.c linux-2.6.16.12/arch/i386/kernel/process.c
1528 --- linux-2.6.16.12/arch/i386/kernel/process.c  2006-05-01 15:14:26.000000000 -0400
1529 +++ linux-2.6.16.12/arch/i386/kernel/process.c  2006-05-01 20:17:33.000000000 -0400
1530 @@ -377,7 +377,7 @@ void exit_thread(void)
1531         /* The process may have allocated an io port bitmap... nuke it. */
1532         if (unlikely(NULL != t->io_bitmap_ptr)) {
1533                 int cpu = get_cpu();
1534 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
1535 +               struct tss_struct *tss = init_tss + cpu;
1536  
1537                 kfree(t->io_bitmap_ptr);
1538                 t->io_bitmap_ptr = NULL;
1539 @@ -397,6 +397,9 @@ void flush_thread(void)
1540  {
1541         struct task_struct *tsk = current;
1542  
1543 +       __asm__("mov %0,%%fs\n"
1544 +               "mov %0,%%gs\n"
1545 +               : : "r" (0) : "memory");
1546         memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
1547         memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
1548         /*
1549 @@ -429,7 +432,7 @@ int copy_thread(int nr, unsigned long cl
1550         struct task_struct *tsk;
1551         int err;
1552  
1553 -       childregs = task_pt_regs(p);
1554 +       childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
1555         *childregs = *regs;
1556         childregs->eax = 0;
1557         childregs->esp = esp;
1558 @@ -472,6 +475,11 @@ int copy_thread(int nr, unsigned long cl
1559                 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1560                         goto out;
1561  
1562 +#ifdef CONFIG_PAX_SEGMEXEC
1563 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1564 +                       goto out;
1565 +#endif
1566 +
1567                 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
1568                 desc->a = LDT_entry_a(&info);
1569                 desc->b = LDT_entry_b(&info);
1570 @@ -636,7 +644,11 @@ struct task_struct fastcall * __switch_t
1571         struct thread_struct *prev = &prev_p->thread,
1572                                  *next = &next_p->thread;
1573         int cpu = smp_processor_id();
1574 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1575 +       struct tss_struct *tss = init_tss + cpu;
1576 +
1577 +#ifdef CONFIG_PAX_KERNEXEC
1578 +       unsigned long cr0;
1579 +#endif
1580  
1581         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
1582  
1583 @@ -659,11 +671,19 @@ struct task_struct fastcall * __switch_t
1584         savesegment(fs, prev->fs);
1585         savesegment(gs, prev->gs);
1586  
1587 +#ifdef CONFIG_PAX_KERNEXEC
1588 +       pax_open_kernel(cr0);
1589 +#endif
1590 +
1591         /*
1592          * Load the per-thread Thread-Local Storage descriptor.
1593          */
1594         load_TLS(next, cpu);
1595  
1596 +#ifdef CONFIG_PAX_KERNEXEC
1597 +       pax_close_kernel(cr0);
1598 +#endif
1599 +
1600         /*
1601          * Restore %fs and %gs if needed.
1602          *
1603 @@ -818,8 +838,18 @@ asmlinkage int sys_set_thread_area(struc
1604         struct desc_struct *desc;
1605         int cpu, idx;
1606  
1607 +#ifdef CONFIG_PAX_KERNEXEC
1608 +       unsigned long cr0;
1609 +#endif
1610 +
1611         if (copy_from_user(&info, u_info, sizeof(info)))
1612                 return -EFAULT;
1613 +
1614 +#ifdef CONFIG_PAX_SEGMEXEC
1615 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1616 +               return -EINVAL;
1617 +#endif
1618 +
1619         idx = info.entry_number;
1620  
1621         /*
1622 @@ -851,8 +881,17 @@ asmlinkage int sys_set_thread_area(struc
1623                 desc->a = LDT_entry_a(&info);
1624                 desc->b = LDT_entry_b(&info);
1625         }
1626 +
1627 +#ifdef CONFIG_PAX_KERNEXEC
1628 +       pax_open_kernel(cr0);
1629 +#endif
1630 +
1631         load_TLS(t, cpu);
1632  
1633 +#ifdef CONFIG_PAX_KERNEXEC
1634 +       pax_close_kernel(cr0);
1635 +#endif
1636 +
1637         put_cpu();
1638  
1639         return 0;
1640 @@ -908,9 +947,27 @@ asmlinkage int sys_get_thread_area(struc
1641         return 0;
1642  }
1643  
1644 -unsigned long arch_align_stack(unsigned long sp)
1645 +#ifdef CONFIG_PAX_RANDKSTACK
1646 +asmlinkage void pax_randomize_kstack(void)
1647  {
1648 -       if (randomize_va_space)
1649 -               sp -= get_random_int() % 8192;
1650 -       return sp & ~0xf;
1651 +       struct tss_struct *tss = init_tss + smp_processor_id();
1652 +       unsigned long time;
1653 +
1654 +       if (!randomize_va_space)
1655 +               return;
1656 +
1657 +       rdtscl(time);
1658 +
1659 +       /* P4 seems to return a 0 LSB, ignore it */
1660 +#ifdef CONFIG_MPENTIUM4
1661 +       time &= 0x1EUL;
1662 +       time <<= 2;
1663 +#else
1664 +       time &= 0xFUL;
1665 +       time <<= 3;
1666 +#endif
1667 +
1668 +       tss->esp0 ^= time;
1669 +       current->thread.esp0 = tss->esp0;
1670  }
1671 +#endif
1672 diff -urNp linux-2.6.16.12/arch/i386/kernel/ptrace.c linux-2.6.16.12/arch/i386/kernel/ptrace.c
1673 --- linux-2.6.16.12/arch/i386/kernel/ptrace.c   2006-05-01 15:14:26.000000000 -0400
1674 +++ linux-2.6.16.12/arch/i386/kernel/ptrace.c   2006-05-01 20:17:33.000000000 -0400
1675 @@ -17,6 +17,7 @@
1676  #include <linux/audit.h>
1677  #include <linux/seccomp.h>
1678  #include <linux/signal.h>
1679 +#include <linux/grsecurity.h>
1680  
1681  #include <asm/uaccess.h>
1682  #include <asm/pgtable.h>
1683 @@ -342,6 +343,11 @@ ptrace_set_thread_area(struct task_struc
1684         if (copy_from_user(&info, user_desc, sizeof(info)))
1685                 return -EFAULT;
1686  
1687 +#ifdef CONFIG_PAX_SEGMEXEC
1688 +       if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1689 +               return -EINVAL;
1690 +#endif
1691 +
1692         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1693                 return -EINVAL;
1694  
1695 @@ -432,6 +438,17 @@ long arch_ptrace(struct task_struct *chi
1696                           if(addr == (long) &dummy->u_debugreg[5]) break;
1697                           if(addr < (long) &dummy->u_debugreg[4] &&
1698                              ((unsigned long) data) >= TASK_SIZE-3) break;
1699 +
1700 +#ifdef CONFIG_GRKERNSEC
1701 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
1702 +                            addr <= (long) &dummy->u_debugreg[3]){
1703 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
1704 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
1705 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
1706 +                               if((type & 1) && (data & align))
1707 +                                       break;
1708 +                         }
1709 +#endif
1710                           
1711                           /* Sanity-check data. Take one half-byte at once with
1712                            * check = (val >> (16 + 4*i)) & 0xf. It contains the
1713 @@ -645,7 +662,7 @@ void send_sigtrap(struct task_struct *ts
1714         info.si_code = TRAP_BRKPT;
1715  
1716         /* User-mode eip? */
1717 -       info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
1718 +       info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
1719  
1720         /* Send us the fakey SIGTRAP */
1721         force_sig_info(SIGTRAP, &info, tsk);
1722 diff -urNp linux-2.6.16.12/arch/i386/kernel/reboot.c linux-2.6.16.12/arch/i386/kernel/reboot.c
1723 --- linux-2.6.16.12/arch/i386/kernel/reboot.c   2006-05-01 15:14:26.000000000 -0400
1724 +++ linux-2.6.16.12/arch/i386/kernel/reboot.c   2006-05-01 20:17:33.000000000 -0400
1725 @@ -138,18 +138,18 @@ core_initcall(reboot_init);
1726     doesn't work with at least one type of 486 motherboard.  It is easy
1727     to stop this code working; hence the copious comments. */
1728  
1729 -static unsigned long long
1730 +static const unsigned long long
1731  real_mode_gdt_entries [3] =
1732  {
1733         0x0000000000000000ULL,  /* Null descriptor */
1734 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
1735 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
1736 +       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
1737 +       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
1738  };
1739  
1740  static struct
1741  {
1742         unsigned short       size __attribute__ ((packed));
1743 -       unsigned long long * base __attribute__ ((packed));
1744 +       const unsigned long long * base __attribute__ ((packed));
1745  }
1746  real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
1747  real_mode_idt = { 0x3ff, NULL },
1748 @@ -203,6 +203,10 @@ void machine_real_restart(unsigned char 
1749  {
1750         unsigned long flags;
1751  
1752 +#ifdef CONFIG_PAX_KERNEXEC
1753 +       unsigned long cr0;
1754 +#endif
1755 +
1756         local_irq_disable();
1757  
1758         /* Write zero to CMOS register number 0x0f, which the BIOS POST
1759 @@ -223,9 +227,17 @@ void machine_real_restart(unsigned char 
1760            from the kernel segment.  This assumes the kernel segment starts at
1761            virtual address PAGE_OFFSET. */
1762  
1763 +#ifdef CONFIG_PAX_KERNEXEC
1764 +       pax_open_kernel(cr0);
1765 +#endif
1766 +
1767         memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
1768                 sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
1769  
1770 +#ifdef CONFIG_PAX_KERNEXEC
1771 +       pax_close_kernel(cr0);
1772 +#endif
1773 +
1774         /*
1775          * Use `swapper_pg_dir' as our page directory.
1776          */
1777 diff -urNp linux-2.6.16.12/arch/i386/kernel/setup.c linux-2.6.16.12/arch/i386/kernel/setup.c
1778 --- linux-2.6.16.12/arch/i386/kernel/setup.c    2006-05-01 15:14:26.000000000 -0400
1779 +++ linux-2.6.16.12/arch/i386/kernel/setup.c    2006-05-01 20:17:33.000000000 -0400
1780 @@ -60,6 +60,7 @@
1781  #include <asm/io.h>
1782  #include "setup_arch_pre.h"
1783  #include <bios_ebda.h>
1784 +#include <asm/desc.h>
1785  
1786  /* Forward Declaration. */
1787  void __init find_max_pfn(void);
1788 @@ -86,7 +87,11 @@ struct cpuinfo_x86 new_cpu_data __initda
1789  struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
1790  EXPORT_SYMBOL(boot_cpu_data);
1791  
1792 +#ifdef CONFIG_X86_PAE
1793 +unsigned long mmu_cr4_features = X86_CR4_PAE;
1794 +#else
1795  unsigned long mmu_cr4_features;
1796 +#endif
1797  
1798  #ifdef CONFIG_ACPI
1799         int acpi_disabled = 0;
1800 @@ -1444,12 +1449,22 @@ void apply_alternatives(void *start, voi
1801         struct alt_instr *a; 
1802         int diff, i, k;
1803          unsigned char **noptable = intel_nops; 
1804 +
1805 +#ifdef CONFIG_PAX_KERNEXEC
1806 +       unsigned long cr0;
1807 +#endif
1808 +
1809         for (i = 0; noptypes[i].cpuid >= 0; i++) { 
1810                 if (boot_cpu_has(noptypes[i].cpuid)) { 
1811                         noptable = noptypes[i].noptable;
1812                         break;
1813                 }
1814         } 
1815 +
1816 +#ifdef CONFIG_PAX_KERNEXEC
1817 +       pax_open_kernel(cr0);
1818 +#endif
1819 +
1820         for (a = start; (void *)a < end; a++) { 
1821                 if (!boot_cpu_has(a->cpuid))
1822                         continue;
1823 @@ -1464,6 +1479,11 @@ void apply_alternatives(void *start, voi
1824                         memcpy(a->instr + i, noptable[k], k); 
1825                 } 
1826         }
1827 +
1828 +#ifdef CONFIG_PAX_KERNEXEC
1829 +       pax_close_kernel(cr0);
1830 +#endif
1831 +
1832  } 
1833  
1834  void __init alternative_instructions(void)
1835 @@ -1542,14 +1562,14 @@ void __init setup_arch(char **cmdline_p)
1836  
1837         if (!MOUNT_ROOT_RDONLY)
1838                 root_mountflags &= ~MS_RDONLY;
1839 -       init_mm.start_code = (unsigned long) _text;
1840 -       init_mm.end_code = (unsigned long) _etext;
1841 +       init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
1842 +       init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
1843         init_mm.end_data = (unsigned long) _edata;
1844         init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
1845  
1846 -       code_resource.start = virt_to_phys(_text);
1847 -       code_resource.end = virt_to_phys(_etext)-1;
1848 -       data_resource.start = virt_to_phys(_etext);
1849 +       code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
1850 +       code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
1851 +       data_resource.start = virt_to_phys(_data);
1852         data_resource.end = virt_to_phys(_edata)-1;
1853  
1854         parse_cmdline_early(cmdline_p);
1855 diff -urNp linux-2.6.16.12/arch/i386/kernel/signal.c linux-2.6.16.12/arch/i386/kernel/signal.c
1856 --- linux-2.6.16.12/arch/i386/kernel/signal.c   2006-05-01 15:14:26.000000000 -0400
1857 +++ linux-2.6.16.12/arch/i386/kernel/signal.c   2006-05-01 20:17:33.000000000 -0400
1858 @@ -350,7 +350,17 @@ static int setup_frame(int sig, struct k
1859                         goto give_sigsegv;
1860         }
1861  
1862 +#ifdef CONFIG_PAX_NOVSYSCALL
1863 +       restorer = frame->retcode;
1864 +#else
1865         restorer = &__kernel_sigreturn;
1866 +
1867 +#ifdef CONFIG_PAX_SEGMEXEC
1868 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
1869 +               restorer -= SEGMEXEC_TASK_SIZE;
1870 +#endif
1871 +#endif
1872 +
1873         if (ka->sa.sa_flags & SA_RESTORER)
1874                 restorer = ka->sa.sa_restorer;
1875  
1876 @@ -446,7 +456,18 @@ static int setup_rt_frame(int sig, struc
1877                 goto give_sigsegv;
1878  
1879         /* Set up to return from userspace.  */
1880 +
1881 +#ifdef CONFIG_PAX_NOVSYSCALL
1882 +       restorer = frame->retcode;
1883 +#else
1884         restorer = &__kernel_rt_sigreturn;
1885 +
1886 +#ifdef CONFIG_PAX_SEGMEXEC
1887 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
1888 +               restorer -= SEGMEXEC_TASK_SIZE;
1889 +#endif
1890 +#endif
1891 +
1892         if (ka->sa.sa_flags & SA_RESTORER)
1893                 restorer = ka->sa.sa_restorer;
1894         err |= __put_user(restorer, &frame->pretcode);
1895 @@ -579,7 +600,7 @@ static void fastcall do_signal(struct pt
1896          * before reaching here, so testing against kernel
1897          * CS suffices.
1898          */
1899 -       if (!user_mode(regs))
1900 +       if (!user_mode_novm(regs))
1901                 return;
1902  
1903         if (try_to_freeze())
1904 diff -urNp linux-2.6.16.12/arch/i386/kernel/syscall_table.S linux-2.6.16.12/arch/i386/kernel/syscall_table.S
1905 --- linux-2.6.16.12/arch/i386/kernel/syscall_table.S    2006-05-01 15:14:26.000000000 -0400
1906 +++ linux-2.6.16.12/arch/i386/kernel/syscall_table.S    2006-05-01 20:17:33.000000000 -0400
1907 @@ -1,3 +1,4 @@
1908 +.section .rodata,"a",@progbits
1909  ENTRY(sys_call_table)
1910         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
1911         .long sys_exit
1912 diff -urNp linux-2.6.16.12/arch/i386/kernel/sysenter.c linux-2.6.16.12/arch/i386/kernel/sysenter.c
1913 --- linux-2.6.16.12/arch/i386/kernel/sysenter.c 2006-05-01 15:14:26.000000000 -0400
1914 +++ linux-2.6.16.12/arch/i386/kernel/sysenter.c 2006-05-01 20:17:33.000000000 -0400
1915 @@ -24,7 +24,7 @@ extern asmlinkage void sysenter_entry(vo
1916  void enable_sep_cpu(void)
1917  {
1918         int cpu = get_cpu();
1919 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1920 +       struct tss_struct *tss = init_tss + cpu;
1921  
1922         if (!boot_cpu_has(X86_FEATURE_SEP)) {
1923                 put_cpu();
1924 @@ -48,6 +48,7 @@ extern const char vsyscall_sysenter_star
1925  
1926  int __init sysenter_setup(void)
1927  {
1928 +#ifndef CONFIG_PAX_NOVSYSCALL
1929         void *page = (void *)get_zeroed_page(GFP_ATOMIC);
1930  
1931         __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
1932 @@ -62,6 +63,7 @@ int __init sysenter_setup(void)
1933         memcpy(page,
1934                &vsyscall_sysenter_start,
1935                &vsyscall_sysenter_end - &vsyscall_sysenter_start);
1936 +#endif
1937  
1938         return 0;
1939  }
1940 diff -urNp linux-2.6.16.12/arch/i386/kernel/sys_i386.c linux-2.6.16.12/arch/i386/kernel/sys_i386.c
1941 --- linux-2.6.16.12/arch/i386/kernel/sys_i386.c 2006-05-01 15:14:26.000000000 -0400
1942 +++ linux-2.6.16.12/arch/i386/kernel/sys_i386.c 2006-05-01 20:17:33.000000000 -0400
1943 @@ -107,6 +107,191 @@ out:
1944         return err;
1945  }
1946  
1947 +unsigned long
1948 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
1949 +               unsigned long len, unsigned long pgoff, unsigned long flags)
1950 +{
1951 +       struct mm_struct *mm = current->mm;
1952 +       struct vm_area_struct *vma;
1953 +       unsigned long start_addr, task_size = TASK_SIZE;
1954 +
1955 +#ifdef CONFIG_PAX_SEGMEXEC
1956 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
1957 +               task_size = SEGMEXEC_TASK_SIZE;
1958 +#endif
1959 +
1960 +       if (len > task_size)
1961 +               return -ENOMEM;
1962 +
1963 +#ifdef CONFIG_PAX_RANDMMAP
1964 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
1965 +#endif
1966 +
1967 +       if (addr) {
1968 +               addr = PAGE_ALIGN(addr);
1969 +               vma = find_vma(mm, addr);
1970 +               if (task_size - len >= addr &&
1971 +                   (!vma || addr + len <= vma->vm_start))
1972 +                       return addr;
1973 +       }
1974 +       if (len > mm->cached_hole_size) {
1975 +               start_addr = addr = mm->free_area_cache;
1976 +       } else {
1977 +               start_addr = addr = mm->mmap_base;
1978 +               mm->cached_hole_size = 0;
1979 +       }
1980 +
1981 +#ifdef CONFIG_PAX_PAGEEXEC
1982 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
1983 +               start_addr = 0x00110000UL;
1984 +
1985 +#ifdef CONFIG_PAX_RANDMMAP
1986 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
1987 +                       start_addr += mm->delta_mmap & 0x03FFFFFFUL;
1988 +#endif
1989 +
1990 +               if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
1991 +                       start_addr = addr = mm->mmap_base;
1992 +               else
1993 +                       addr = start_addr;
1994 +       }
1995 +#endif
1996 +
1997 +full_search:
1998 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
1999 +               /* At this point:  (!vma || addr < vma->vm_end). */
2000 +               if (task_size - len < addr) {
2001 +                       /*
2002 +                        * Start a new search - just in case we missed
2003 +                        * some holes.
2004 +                        */
2005 +                       if (start_addr != mm->mmap_base) {
2006 +                               start_addr = addr = mm->mmap_base;
2007 +                               mm->cached_hole_size = 0;
2008 +                               goto full_search;
2009 +                       }
2010 +                       return -ENOMEM;
2011 +               }
2012 +               if (!vma || addr + len <= vma->vm_start) {
2013 +                       /*
2014 +                        * Remember the place where we stopped the search:
2015 +                        */
2016 +                       mm->free_area_cache = addr + len;
2017 +                       return addr;
2018 +               }
2019 +               if (addr + mm->cached_hole_size < vma->vm_start)
2020 +                       mm->cached_hole_size = vma->vm_start - addr;
2021 +               addr = vma->vm_end;
2022 +               if (mm->start_brk <= addr && addr < mm->mmap_base) {
2023 +                       start_addr = addr = mm->mmap_base;
2024 +                       goto full_search;
2025 +               }
2026 +       }
2027 +}
2028 +
2029 +unsigned long
2030 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
2031 +                         const unsigned long len, const unsigned long pgoff,
2032 +                         const unsigned long flags)
2033 +{
2034 +       struct vm_area_struct *vma;
2035 +       struct mm_struct *mm = current->mm;
2036 +       unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
2037 +
2038 +#ifdef CONFIG_PAX_SEGMEXEC
2039 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
2040 +               task_size = SEGMEXEC_TASK_SIZE;
2041 +#endif
2042 +
2043 +       /* requested length too big for entire address space */
2044 +       if (len > task_size)
2045 +               return -ENOMEM;
2046 +
2047 +#ifdef CONFIG_PAX_PAGEEXEC
2048 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
2049 +               goto bottomup;
2050 +#endif
2051 +
2052 +#ifdef CONFIG_PAX_RANDMMAP
2053 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2054 +#endif
2055 +
2056 +       /* requesting a specific address */
2057 +       if (addr) {
2058 +               addr = PAGE_ALIGN(addr);
2059 +               vma = find_vma(mm, addr);
2060 +               if (task_size - len >= addr &&
2061 +                               (!vma || addr + len <= vma->vm_start))
2062 +                       return addr;
2063 +       }
2064 +
2065 +       /* check if free_area_cache is useful for us */
2066 +       if (len <= mm->cached_hole_size) {
2067 +               mm->cached_hole_size = 0;
2068 +               mm->free_area_cache = mm->mmap_base;
2069 +       }
2070 +
2071 +       /* either no address requested or can't fit in requested address hole */
2072 +       addr = mm->free_area_cache;
2073 +
2074 +       /* make sure it can fit in the remaining address space */
2075 +       if (addr > len) {
2076 +               vma = find_vma(mm, addr-len);
2077 +               if (!vma || addr <= vma->vm_start)
2078 +                       /* remember the address as a hint for next time */
2079 +                       return (mm->free_area_cache = addr-len);
2080 +       }
2081 +
2082 +       if (mm->mmap_base < len)
2083 +               goto bottomup;
2084 +
2085 +       addr = mm->mmap_base-len;
2086 +
2087 +       do {
2088 +               /*
2089 +                * Lookup failure means no vma is above this address,
2090 +                * else if new region fits below vma->vm_start,
2091 +                * return with success:
2092 +                */
2093 +               vma = find_vma(mm, addr);
2094 +               if (!vma || addr+len <= vma->vm_start)
2095 +                       /* remember the address as a hint for next time */
2096 +                       return (mm->free_area_cache = addr);
2097 +
2098 +               /* remember the largest hole we saw so far */
2099 +               if (addr + mm->cached_hole_size < vma->vm_start)
2100 +                       mm->cached_hole_size = vma->vm_start - addr;
2101 +
2102 +               /* try just below the current vma->vm_start */
2103 +               addr = vma->vm_start-len;
2104 +       } while (len < vma->vm_start);
2105 +
2106 +bottomup:
2107 +       /*
2108 +        * A failed mmap() very likely causes application failure,
2109 +        * so fall back to the bottom-up function here. This scenario
2110 +        * can happen with large stack limits and large mmap()
2111 +        * allocations.
2112 +        */
2113 +       mm->mmap_base = TASK_UNMAPPED_BASE;
2114 +
2115 +#ifdef CONFIG_PAX_RANDMMAP
2116 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
2117 +               mm->mmap_base += mm->delta_mmap;
2118 +#endif
2119 +
2120 +       mm->free_area_cache = mm->mmap_base;
2121 +       mm->cached_hole_size = ~0UL;
2122 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
2123 +       /*
2124 +        * Restore the topdown base:
2125 +        */
2126 +       mm->mmap_base = base;
2127 +       mm->free_area_cache = base;
2128 +       mm->cached_hole_size = ~0UL;
2129 +
2130 +       return addr;
2131 +}
2132  
2133  struct sel_arg_struct {
2134         unsigned long n;
2135 diff -urNp linux-2.6.16.12/arch/i386/kernel/traps.c linux-2.6.16.12/arch/i386/kernel/traps.c
2136 --- linux-2.6.16.12/arch/i386/kernel/traps.c    2006-05-01 15:14:26.000000000 -0400
2137 +++ linux-2.6.16.12/arch/i386/kernel/traps.c    2006-05-01 20:17:33.000000000 -0400
2138 @@ -28,6 +28,7 @@
2139  #include <linux/utsname.h>
2140  #include <linux/kprobes.h>
2141  #include <linux/kexec.h>
2142 +#include <linux/binfmts.h>
2143  
2144  #ifdef CONFIG_EISA
2145  #include <linux/ioport.h>
2146 @@ -60,18 +60,13 @@
2147  
2148  asmlinkage int system_call(void);
2149  
2150 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2151 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2152                 { 0, 0 }, { 0, 0 } };
2153  
2154  /* Do we ignore FPU interrupts ? */
2155  char ignore_fpu_irq = 0;
2156  
2157 -/*
2158 - * The IDT has to be page-aligned to simplify the Pentium
2159 - * F0 0F bug workaround.. We have a special link segment
2160 - * for this.
2161 - */
2162 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
2163 +extern struct desc_struct idt_table[256];
2164  
2165  asmlinkage void divide_error(void);
2166  asmlinkage void debug(void);
2167 @@ -127,18 +123,22 @@ static inline unsigned long print_contex
2168                                 char *log_lvl)
2169  {
2170         unsigned long addr;
2171 +       int i = kstack_depth_to_print;
2172  
2173  #ifdef CONFIG_FRAME_POINTER
2174         while (valid_stack_ptr(tinfo, (void *)ebp)) {
2175                 addr = *(unsigned long *)(ebp + 4);
2176                 print_addr_and_symbol(addr, log_lvl);
2177                 ebp = *(unsigned long *)ebp;
2178 +               --i;
2179         }
2180  #else
2181         while (valid_stack_ptr(tinfo, stack)) {
2182                 addr = *stack++;
2183 -               if (__kernel_text_address(addr))
2184 +               if (__kernel_text_address(addr)) {
2185                         print_addr_and_symbol(addr, log_lvl);
2186 +                       --i;
2187 +               }
2188         }
2189  #endif
2190         return ebp;
2191 @@ -269,7 +269,7 @@ void show_registers(struct pt_regs *regs
2192  
2193                 printk(KERN_EMERG "Code: ");
2194  
2195 -               eip = (u8 __user *)regs->eip - 43;
2196 +               eip = (u8 __user *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
2197                 for (i = 0; i < 64; i++, eip++) {
2198                         unsigned char c;
2199  
2200 @@ -277,7 +277,7 @@ void show_registers(struct pt_regs *regs
2201                                 printk(" Bad EIP value.");
2202                                 break;
2203                         }
2204 -                       if (eip == (u8 __user *)regs->eip)
2205 +                       if (eip == (u8 __user *)regs->eip + __KERNEL_TEXT_OFFSET)
2206                                 printk("<%02x> ", c);
2207                         else
2208                                 printk("%02x ", c);
2209 @@ -294,7 +294,7 @@ static void handle_BUG(struct pt_regs *r
2210         char c;
2211         unsigned long eip;
2212  
2213 -       eip = regs->eip;
2214 +       eip = regs->eip + __KERNEL_TEXT_OFFSET;
2215  
2216         if (eip < PAGE_OFFSET)
2217                 goto no_bug;
2218 @@ -396,7 +396,7 @@ void die(const char * str, struct pt_reg
2219  
2220  static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
2221  {
2222 -       if (!user_mode_vm(regs))
2223 +       if (!user_mode(regs))
2224                 die(str, regs, err);
2225  }
2226  
2227 @@ -414,7 +414,7 @@ static void __kprobes do_trap(int trapnr
2228                 goto trap_signal;
2229         }
2230  
2231 -       if (!user_mode(regs))
2232 +       if (!user_mode_novm(regs))
2233                 goto kernel_trap;
2234  
2235         trap_signal: {
2236 @@ -502,7 +502,7 @@ fastcall void __kprobes do_general_prote
2237                                               long error_code)
2238  {
2239         int cpu = get_cpu();
2240 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2241 +       struct tss_struct *tss = &init_tss[cpu];
2242         struct thread_struct *thread = &current->thread;
2243  
2244         /*
2245 @@ -538,9 +538,25 @@ fastcall void __kprobes do_general_prote
2246         if (regs->eflags & VM_MASK)
2247                 goto gp_in_vm86;
2248  
2249 -       if (!user_mode(regs))
2250 +       if (!user_mode_novm(regs))
2251                 goto gp_in_kernel;
2252  
2253 +#ifdef CONFIG_PAX_PAGEEXEC
2254 +       if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
2255 +               struct mm_struct *mm = current->mm;
2256 +               unsigned long limit;
2257 +
2258 +               down_write(&mm->mmap_sem);
2259 +               limit = mm->context.user_cs_limit;
2260 +               if (limit < TASK_SIZE) {
2261 +                       track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
2262 +                       up_write(&mm->mmap_sem);
2263 +                       return;
2264 +               }
2265 +               up_write(&mm->mmap_sem);
2266 +       }
2267 +#endif
2268 +
2269         current->thread.error_code = error_code;
2270         current->thread.trap_no = 13;
2271         force_sig(SIGSEGV, current);
2272 @@ -556,6 +572,13 @@ gp_in_kernel:
2273                 if (notify_die(DIE_GPF, "general protection fault", regs,
2274                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
2275                         return;
2276 +
2277 +#ifdef CONFIG_PAX_KERNEXEC
2278 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
2279 +                       die("PAX: suspicious general protection fault", regs, error_code);
2280 +               else
2281 +#endif
2282 +
2283                 die("general protection fault", regs, error_code);
2284         }
2285  }
2286 @@ -781,7 +804,7 @@ fastcall void __kprobes do_debug(struct 
2287                  * check for kernel mode by just checking the CPL
2288                  * of CS.
2289                  */
2290 -               if (!user_mode(regs))
2291 +               if (!user_mode_novm(regs))
2292                         goto clear_TF_reenable;
2293         }
2294  
2295 @@ -1071,7 +1094,19 @@ do { \
2296   */
2297  void set_intr_gate(unsigned int n, void *addr)
2298  {
2299 +
2300 +#ifdef CONFIG_PAX_KERNEXEC
2301 +       unsigned long cr0;
2302 +
2303 +       pax_open_kernel(cr0);
2304 +#endif
2305 +
2306         _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
2307 +
2308 +#ifdef CONFIG_PAX_KERNEXEC
2309 +       pax_close_kernel(cr0);
2310 +#endif
2311 +
2312  }
2313  
2314  /*
2315 diff -urNp linux-2.6.16.12/arch/i386/kernel/vm86.c linux-2.6.16.12/arch/i386/kernel/vm86.c
2316 --- linux-2.6.16.12/arch/i386/kernel/vm86.c     2006-05-01 15:14:26.000000000 -0400
2317 +++ linux-2.6.16.12/arch/i386/kernel/vm86.c     2006-05-01 20:17:33.000000000 -0400
2318 @@ -123,7 +123,7 @@ struct pt_regs * fastcall save_v86_state
2319                 do_exit(SIGSEGV);
2320         }
2321  
2322 -       tss = &per_cpu(init_tss, get_cpu());
2323 +       tss = init_tss + get_cpu();
2324         current->thread.esp0 = current->thread.saved_esp0;
2325         current->thread.sysenter_cs = __KERNEL_CS;
2326         load_esp0(tss, &current->thread);
2327 @@ -297,7 +297,7 @@ static void do_sys_vm86(struct kernel_vm
2328         savesegment(fs, tsk->thread.saved_fs);
2329         savesegment(gs, tsk->thread.saved_gs);
2330  
2331 -       tss = &per_cpu(init_tss, get_cpu());
2332 +       tss = init_tss + get_cpu();
2333         tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
2334         if (cpu_has_sep)
2335                 tsk->thread.sysenter_cs = 0;
2336 diff -urNp linux-2.6.16.12/arch/i386/kernel/vmlinux.lds.S linux-2.6.16.12/arch/i386/kernel/vmlinux.lds.S
2337 --- linux-2.6.16.12/arch/i386/kernel/vmlinux.lds.S      2006-05-01 15:14:26.000000000 -0400
2338 +++ linux-2.6.16.12/arch/i386/kernel/vmlinux.lds.S      2006-05-01 20:17:33.000000000 -0400
2339 @@ -4,9 +4,18 @@
2340  
2341  #define LOAD_OFFSET __PAGE_OFFSET
2342  
2343 +#include <linux/config.h>
2344 +
2345  #include <asm-generic/vmlinux.lds.h>
2346  #include <asm/thread_info.h>
2347  #include <asm/page.h>
2348 +#include <asm/segment.h>
2349 +
2350 +#ifdef CONFIG_X86_PAE
2351 +#define PMD_SHIFT 21
2352 +#else
2353 +#define PMD_SHIFT 22
2354 +#endif
2355  
2356  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2357  OUTPUT_ARCH(i386)
2358 @@ -15,67 +24,17 @@ jiffies = jiffies_64;
2359  SECTIONS
2360  {
2361    . = __KERNEL_START;
2362 -  phys_startup_32 = startup_32 - LOAD_OFFSET;
2363 -  /* read-only */
2364 -  _text = .;                   /* Text and read-only data */
2365 -  .text : AT(ADDR(.text) - LOAD_OFFSET) {
2366 -       *(.text)
2367 -       SCHED_TEXT
2368 -       LOCK_TEXT
2369 -       KPROBES_TEXT
2370 -       *(.fixup)
2371 -       *(.gnu.warning)
2372 -       } = 0x9090
2373 -
2374 -  _etext = .;                  /* End of text section */
2375 -
2376 -  . = ALIGN(16);               /* Exception table */
2377 -  __start___ex_table = .;
2378 -  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2379 -  __stop___ex_table = .;
2380 -
2381 -  RODATA
2382 +  phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
2383  
2384 -  /* writeable */
2385 -  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2386 -       *(.data)
2387 -       CONSTRUCTORS
2388 +  .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
2389 +       BYTE(0xEA) /* jmp far */
2390 +       LONG(phys_startup_32)
2391 +       SHORT(__BOOT_CS)
2392         }
2393  
2394 -  . = ALIGN(4096);
2395 -  __nosave_begin = .;
2396 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2397 -  . = ALIGN(4096);
2398 -  __nosave_end = .;
2399 -
2400 -  . = ALIGN(4096);
2401 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
2402 -       *(.data.idt)
2403 -  }
2404 -
2405 -  . = ALIGN(32);
2406 -  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2407 -       *(.data.cacheline_aligned)
2408 -  }
2409 -
2410 -  /* rarely changed data like cpu maps */
2411 -  . = ALIGN(32);
2412 -  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2413 -  _edata = .;                  /* End of data section */
2414 -
2415 -  . = ALIGN(THREAD_SIZE);      /* init_task */
2416 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2417 -       *(.data.init_task)
2418 -  }
2419 -
2420    /* will be freed after init */
2421    . = ALIGN(4096);             /* Init code and data */
2422    __init_begin = .;
2423 -  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
2424 -       _sinittext = .;
2425 -       *(.init.text)
2426 -       _einittext = .;
2427 -  }
2428    .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
2429    . = ALIGN(16);
2430    __setup_start = .;
2431 @@ -107,9 +66,7 @@ SECTIONS
2432    .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
2433         *(.altinstr_replacement)
2434    }
2435 -  /* .exit.text is discard at runtime, not link time, to deal with references
2436 -     from .altinstructions and .eh_frame */
2437 -  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
2438 +
2439    .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
2440    . = ALIGN(4096);
2441    __initramfs_start = .;
2442 @@ -119,10 +76,108 @@ SECTIONS
2443    __per_cpu_start = .;
2444    .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
2445    __per_cpu_end = .;
2446 +
2447 +  /* read-only */
2448 +
2449    . = ALIGN(4096);
2450 -  __init_end = .;
2451 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2452 +       _sinittext = .;
2453 +       *(.init.text)
2454 +       _einittext = .;
2455 +  }
2456 +
2457 +  /* .exit.text is discard at runtime, not link time, to deal with references
2458 +     from .altinstructions and .eh_frame */
2459 +  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
2460 +
2461 +#ifdef CONFIG_PAX_KERNEXEC
2462 +  .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2463 +       . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
2464 +       BYTE(0)
2465 +  }
2466 +#else
2467 +  . = ALIGN(4096);
2468 +#endif
2469 +
2470 +  __init_end = . + __KERNEL_TEXT_OFFSET;
2471    /* freed after init ends here */
2472 -       
2473 +
2474 +  _text = .;                   /* Text and read-only data */
2475 +  .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2476 +       *(.text)
2477 +       SCHED_TEXT
2478 +       LOCK_TEXT
2479 +       KPROBES_TEXT
2480 +       *(.fixup)
2481 +       *(.gnu.warning)
2482 +       } = 0x9090
2483 +
2484 +  _etext = .;                  /* End of text section */
2485 +  . += __KERNEL_TEXT_OFFSET;
2486 +  . = ALIGN(16);               /* Exception table */
2487 +  __start___ex_table = .;
2488 +  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2489 +  __stop___ex_table = .;
2490 +
2491 +  . = ALIGN(4096);
2492 +  .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
2493 +       *(.empty_zero_page)
2494 +
2495 +#ifdef CONFIG_X86_PAE
2496 +       *(.swapper_pm_dir)
2497 +#endif
2498 +
2499 +       *(.swapper_pg_dir)
2500 +       *(.idt)
2501 +       }
2502 +
2503 +  RODATA
2504 +
2505 +#ifdef CONFIG_PAX_KERNEXEC
2506 +  . = ALIGN(4096);
2507 +  MODULES_VADDR = .;
2508 +
2509 +  .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
2510 +       . += (4 * 1024 * 1024);
2511 +       . = ALIGN(1 << PMD_SHIFT) - 1;
2512 +       BYTE(0)
2513 +  }
2514 +
2515 +  MODULES_END = .;
2516 +#else
2517 +  . = ALIGN(32);
2518 +#endif
2519 +
2520 +  /* writeable */
2521 +  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2522 +       _data = .;
2523 +       *(.data)
2524 +       CONSTRUCTORS
2525 +       }
2526 +
2527 +  . = ALIGN(4096);
2528 +  __nosave_begin = .;
2529 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2530 +  . = ALIGN(4096);
2531 +  __nosave_end = .;
2532 +
2533 +  . = ALIGN(32);
2534 +  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2535 +       *(.data.cacheline_aligned)
2536 +  }
2537 +
2538 +  /* rarely changed data like cpu maps */
2539 +  . = ALIGN(32);
2540 +  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2541 +
2542 +  . = ALIGN(THREAD_SIZE);      /* init_task */
2543 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2544 +       *(.data.init_task)
2545 +  }
2546 +
2547 +  _edata = .;                  /* End of data section */
2548 +
2549 +  . = ALIGN(4096);
2550    __bss_start = .;             /* BSS */
2551    .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
2552         *(.bss.page_aligned)
2553 diff -urNp linux-2.6.16.12/arch/i386/mach-voyager/voyager_smp.c linux-2.6.16.12/arch/i386/mach-voyager/voyager_smp.c
2554 --- linux-2.6.16.12/arch/i386/mach-voyager/voyager_smp.c        2006-05-01 15:14:26.000000000 -0400
2555 +++ linux-2.6.16.12/arch/i386/mach-voyager/voyager_smp.c        2006-05-01 20:17:33.000000000 -0400
2556 @@ -1295,7 +1295,7 @@ smp_local_timer_interrupt(struct pt_regs
2557                                                 per_cpu(prof_counter, cpu);
2558                 }
2559  
2560 -               update_process_times(user_mode_vm(regs));
2561 +               update_process_times(user_mode(regs));
2562         }
2563  
2564         if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
2565 diff -urNp linux-2.6.16/arch/i386/mm/boot_ioremap.c linux-2.6.16/arch/i386/mm/boot_ioremap.c
2566 --- linux-2.6.16/arch/i386/mm/boot_ioremap.c    2007-04-02 01:58:56.298176750 +0200
2567 +++ linux-2.6.16/arch/i386/mm/boot_ioremap.c    2007-04-02 02:02:20.994969500 +0200
2568 @@ -7,57 +7,36 @@
2569   * Written by Dave Hansen <haveblue@us.ibm.com>
2570   */
2571  
2572 -
2573 -/*
2574 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
2575 - * keeps that from happenning.  If anyone has a better way, I'm listening.
2576 - *
2577 - * boot_pte_t is defined only if this all works correctly
2578 - */
2579 -
2580  #include <linux/config.h>
2581 -#undef CONFIG_X86_PAE
2582  #include <asm/page.h>
2583  #include <asm/pgtable.h>
2584  #include <asm/tlbflush.h>
2585  #include <linux/init.h>
2586  #include <linux/stddef.h>
2587  
2588 -/* 
2589 - * I'm cheating here.  It is known that the two boot PTE pages are 
2590 - * allocated next to each other.  I'm pretending that they're just
2591 - * one big array. 
2592 - */
2593 -
2594 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
2595 -
2596 -static unsigned long boot_pte_index(unsigned long vaddr)
2597 -{
2598 -       return __pa(vaddr) >> PAGE_SHIFT;
2599 -}
2600 -
2601 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
2602 -{
2603 -       boot_pte_t* boot_pg = (boot_pte_t*)pg0;
2604 -       return &boot_pg[boot_pte_index((unsigned long)address)];
2605 -}
2606 -
2607  /*
2608   * This is only for a caller who is clever enough to page-align
2609   * phys_addr and virtual_source, and who also has a preference
2610   * about which virtual address from which to steal ptes
2611   */
2612 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
2613 -                   void* virtual_source)
2614 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned int nrpages,
2615 +                   char* virtual_source)
2616  {
2617 -       boot_pte_t* pte;
2618 -       int i;
2619 -       char *vaddr = virtual_source;
2620 +       pgd_t *pgd;
2621 +       pud_t *pud;
2622 +       pmd_t *pmd;
2623 +       pte_t* pte;
2624 +       unsigned int i;
2625 +       unsigned long vaddr = (unsigned long)virtual_source;
2626 +
2627 +       pgd = pgd_offset_k(vaddr);
2628 +       pud = pud_offset(pgd, vaddr);
2629 +       pmd = pmd_offset(pud, vaddr);
2630 +       pte = pte_offset_kernel(pmd, vaddr);
2631  
2632 -       pte = boot_vaddr_to_pte(virtual_source);
2633         for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
2634                 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
2635 -               __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
2636 +               __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
2637         }
2638  }
2639  
2640 diff -urNp linux-2.6.16.12/arch/i386/mm/extable.c linux-2.6.16.12/arch/i386/mm/extable.c
2641 --- linux-2.6.16.12/arch/i386/mm/extable.c      2006-05-01 15:14:26.000000000 -0400
2642 +++ linux-2.6.16.12/arch/i386/mm/extable.c      2006-05-01 20:17:33.000000000 -0400
2643 @@ -12,7 +12,7 @@ int fixup_exception(struct pt_regs *regs
2644         const struct exception_table_entry *fixup;
2645  
2646  #ifdef CONFIG_PNPBIOS
2647 -       if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
2648 +       if (unlikely(regs->xcs == (GDT_ENTRY_PNPBIOS_BASE << 3)))
2649         {
2650                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
2651                 extern u32 pnp_bios_is_utter_crap;
2652 diff -urNp linux-2.6.16.12/arch/i386/mm/fault.c linux-2.6.16.12/arch/i386/mm/fault.c
2653 --- linux-2.6.16.12/arch/i386/mm/fault.c        2006-05-01 15:14:26.000000000 -0400
2654 +++ linux-2.6.16.12/arch/i386/mm/fault.c        2006-05-01 20:17:33.000000000 -0400
2655 @@ -22,6 +22,9 @@
2656  #include <linux/highmem.h>
2657  #include <linux/module.h>
2658  #include <linux/kprobes.h>
2659 +#include <linux/unistd.h>
2660 +#include <linux/compiler.h>
2661 +#include <linux/binfmts.h>
2662  
2663  #include <asm/system.h>
2664  #include <asm/uaccess.h>
2665 @@ -82,11 +85,13 @@ static inline unsigned long get_segment_
2666  
2667         /* Unlikely, but must come before segment checks. */
2668         if (unlikely((regs->eflags & VM_MASK) != 0))
2669 -               return eip + (seg << 4);
2670 +               return (eip & 0xFFFF) + (seg << 4);
2671         
2672         /* By far the most common cases. */
2673 -       if (likely(seg == __USER_CS || seg == __KERNEL_CS))
2674 +       if (likely(seg == __USER_CS))
2675                 return eip;
2676 +       if (likely(seg == __KERNEL_CS))
2677 +               return eip + __KERNEL_TEXT_OFFSET;
2678  
2679         /* Check the segment exists, is within the current LDT/GDT size,
2680            that kernel/user (ring 0..3) has the appropriate privilege,
2681 @@ -108,7 +113,7 @@ static inline unsigned long get_segment_
2682                 desc = (void *)desc + (seg & ~7);
2683         } else {
2684                 /* Must disable preemption while reading the GDT. */
2685 -               desc = (u32 *)get_cpu_gdt_table(get_cpu());
2686 +               desc = (u32 *)get_cpu_gdt_table(get_cpu());
2687                 desc = (void *)desc + (seg & ~7);
2688         }
2689  
2690 @@ -214,6 +219,30 @@ static noinline void force_sig_info_faul
2691  
2692  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
2693  
2694 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2695 +static int pax_handle_fetch_fault(struct pt_regs *regs);
2696 +#endif
2697 +
2698 +#ifdef CONFIG_PAX_PAGEEXEC
2699 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
2700 +{
2701 +       pgd_t *pgd;
2702 +       pud_t *pud;
2703 +       pmd_t *pmd;
2704 +
2705 +       pgd = pgd_offset(mm, address);
2706 +       if (!pgd_present(*pgd))
2707 +               return NULL;
2708 +       pud = pud_offset(pgd, address);
2709 +       if (!pud_present(*pud))
2710 +               return NULL;
2711 +       pmd = pmd_offset(pud, address);
2712 +       if (!pmd_present(*pmd))
2713 +               return NULL;
2714 +       return pmd;
2715 +}
2716 +#endif
2717 +
2718  /*
2719   * This routine handles page faults.  It determines the address,
2720   * and the problem, and then passes it off to one of the appropriate
2721 @@ -231,9 +260,15 @@ fastcall void __kprobes do_page_fault(st
2722         struct mm_struct *mm;
2723         struct vm_area_struct * vma;
2724         unsigned long address;
2725 -       unsigned long page;
2726         int write, si_code;
2727  
2728 +#ifdef CONFIG_PAX_PAGEEXEC
2729 +       pmd_t *pmd;
2730 +       pte_t *pte;
2731 +       spinlock_t *ptl;
2732 +       unsigned char pte_mask;
2733 +#endif
2734 +
2735         /* get the address */
2736          address = read_cr2();
2737  
2738 @@ -245,6 +280,7 @@ fastcall void __kprobes do_page_fault(st
2739                 local_irq_enable();
2740  
2741         tsk = current;
2742 +       mm = tsk->mm;
2743  
2744         si_code = SEGV_MAPERR;
2745  
2746 @@ -271,14 +307,12 @@ fastcall void __kprobes do_page_fault(st
2747                 goto bad_area_nosemaphore;
2748         } 
2749  
2750 -       mm = tsk->mm;
2751 -
2752         /*
2753          * If we're in an interrupt, have no user context or are running in an
2754          * atomic region then we must not take the fault..
2755          */
2756         if (in_atomic() || !mm)
2757 -               goto bad_area_nosemaphore;
2758 +               goto bad_area_nopax;
2759  
2760         /* When running in the kernel we expect faults to occur only to
2761          * addresses in user space.  All other faults represent errors in the
2762 @@ -298,10 +332,98 @@ fastcall void __kprobes do_page_fault(st
2763         if (!down_read_trylock(&mm->mmap_sem)) {
2764                 if ((error_code & 4) == 0 &&
2765                     !search_exception_tables(regs->eip))
2766 -                       goto bad_area_nosemaphore;
2767 +                       goto bad_area_nopax;
2768                 down_read(&mm->mmap_sem);
2769         }
2770  
2771 +#ifdef CONFIG_PAX_PAGEEXEC
2772 +       if (unlikely((error_code & 5) != 5 ||
2773 +                    (regs->eflags & X86_EFLAGS_VM) ||
2774 +                    !(mm->pax_flags & MF_PAX_PAGEEXEC)))
2775 +               goto not_pax_fault;
2776 +
2777 +       /* PaX: it's our fault, let's handle it if we can */
2778 +
2779 +       /* PaX: take a look at read faults before acquiring any locks */
2780 +       if (unlikely(!(error_code & 2) && (regs->eip == address))) {
2781 +               /* instruction fetch attempt from a protected page in user mode */
2782 +               up_read(&mm->mmap_sem);
2783 +               switch (pax_handle_fetch_fault(regs)) {
2784 +
2785 +#ifdef CONFIG_PAX_EMUTRAMP
2786 +               case 2:
2787 +                       return;
2788 +#endif
2789 +
2790 +               }
2791 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2792 +               do_exit(SIGKILL);
2793 +       }
2794 +
2795 +       pmd = pax_get_pmd(mm, address);
2796 +       if (unlikely(!pmd))
2797 +               goto not_pax_fault;
2798 +
2799 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
2800 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
2801 +               pte_unmap_unlock(pte, ptl);
2802 +               goto not_pax_fault;
2803 +       }
2804 +
2805 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
2806 +               /* write attempt to a protected page in user mode */
2807 +               pte_unmap_unlock(pte, ptl);
2808 +               goto not_pax_fault;
2809 +       }
2810 +
2811 +#ifdef CONFIG_SMP
2812 +       if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
2813 +#else
2814 +       if (likely(address > get_limit(regs->xcs)))
2815 +#endif
2816 +       {
2817 +               set_pte(pte, pte_mkread(*pte));
2818 +               __flush_tlb_one(address);
2819 +               pte_unmap_unlock(pte, ptl);
2820 +               up_read(&mm->mmap_sem);
2821 +               return;
2822 +       }
2823 +
2824 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
2825 +
2826 +       /*
2827 +        * PaX: fill DTLB with user rights and retry
2828 +        */
2829 +       __asm__ __volatile__ (
2830 +               "orb %2,%1\n"
2831 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
2832 +/*
2833 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
2834 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
2835 + * page fault when examined during a TLB load attempt. this is true not only
2836 + * for PTEs holding a non-present entry but also present entries that will
2837 + * raise a page fault (such as those set up by PaX, or the copy-on-write
2838 + * mechanism). in effect it means that we do *not* need to flush the TLBs
2839 + * for our target pages since their PTEs are simply not in the TLBs at all.
2840 +
2841 + * the best thing in omitting it is that we gain around 15-20% speed in the
2842 + * fast path of the page fault handler and can get rid of tracing since we
2843 + * can no longer flush unintended entries.
2844 + */
2845 +               "invlpg %0\n"
2846 +#endif
2847 +               "testb $0,%0\n"
2848 +               "xorb %3,%1\n"
2849 +               :
2850 +               : "m" (*(char*)address), "m" (*(char*)pte), "q" (pte_mask), "i" (_PAGE_USER)
2851 +               : "memory", "cc");
2852 +       pte_unmap_unlock(pte, ptl);
2853 +       up_read(&mm->mmap_sem);
2854 +       return;
2855 +
2856 +not_pax_fault:
2857 +#endif
2858 +
2859         vma = find_vma(mm, address);
2860         if (!vma)
2861                 goto bad_area;
2862 @@ -387,6 +509,37 @@ bad_area:
2863         up_read(&mm->mmap_sem);
2864  
2865  bad_area_nosemaphore:
2866 +
2867 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2868 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
2869 +
2870 +#ifdef CONFIG_PAX_PAGEEXEC
2871 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
2872 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2873 +                       do_exit(SIGKILL);
2874 +               }
2875 +#endif
2876 +
2877 +#ifdef CONFIG_PAX_SEGMEXEC
2878 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
2879 +
2880 +                       switch (pax_handle_fetch_fault(regs)) {
2881 +
2882 +#ifdef CONFIG_PAX_EMUTRAMP
2883 +                       case 2:
2884 +                               return;
2885 +#endif
2886 +
2887 +                       }
2888 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2889 +                       do_exit(SIGKILL);
2890 +               }
2891 +#endif
2892 +
2893 +       }
2894 +#endif
2895 +
2896 +bad_area_nopax:
2897         /* User mode accesses just cause a SIGSEGV */
2898         if (error_code & 4) {
2899                 /* 
2900 @@ -450,28 +603,53 @@ no_context:
2901  #endif
2902         if (address < PAGE_SIZE)
2903                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
2904 +
2905 +#ifdef CONFIG_PAX_KERNEXEC
2906 +#ifdef CONFIG_MODULES
2907 +       else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
2908 +#else
2909 +       else if (init_mm.start_code <= address && address < init_mm.end_code)
2910 +#endif
2911 +               if (tsk->signal->curr_ip)
2912 +                       printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
2913 +                                        NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
2914 +               else
2915 +                       printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
2916 +                                        tsk->comm, tsk->pid, tsk->uid, tsk->euid);
2917 +#endif
2918 +
2919         else
2920                 printk(KERN_ALERT "Unable to handle kernel paging request");
2921         printk(" at virtual address %08lx\n",address);
2922         printk(KERN_ALERT " printing eip:\n");
2923         printk("%08lx\n", regs->eip);
2924 -       page = read_cr3();
2925 -       page = ((unsigned long *) __va(page))[address >> 22];
2926 -       printk(KERN_ALERT "*pde = %08lx\n", page);
2927 -       /*
2928 -        * We must not directly access the pte in the highpte
2929 -        * case, the page table might be allocated in highmem.
2930 -        * And lets rather not kmap-atomic the pte, just in case
2931 -        * it's allocated already.
2932 -        */
2933 +       {
2934 +               unsigned long index = pgd_index(address);
2935 +               pgd_t *pgd;
2936 +               pud_t *pud;
2937 +               pmd_t *pmd;
2938 +               pte_t *pte;
2939 +
2940 +               pgd = index + (pgd_t *)__va(read_cr3());
2941 +               printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
2942 +               if (pgd_present(*pgd)) {
2943 +                       pud = pud_offset(pgd, address);
2944 +                       pmd = pmd_offset(pud, address);
2945 +                       printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
2946 +                       /*
2947 +                        * We must not directly access the pte in the highpte
2948 +                        * case, the page table might be allocated in highmem.
2949 +                        * And lets rather not kmap-atomic the pte, just in case
2950 +                        * it's allocated already.
2951 +                        */
2952  #ifndef CONFIG_HIGHPTE
2953 -       if (page & 1) {
2954 -               page &= PAGE_MASK;
2955 -               address &= 0x003ff000;
2956 -               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
2957 -               printk(KERN_ALERT "*pte = %08lx\n", page);
2958 -       }
2959 +                       if (pmd_present(*pmd) && !pmd_large(*pmd)) {
2960 +                               pte = pte_offset_kernel(pmd, address);
2961 +                               printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
2962 +                       }
2963  #endif
2964 +               }
2965 +       }
2966         tsk->thread.cr2 = address;
2967         tsk->thread.trap_no = 14;
2968         tsk->thread.error_code = error_code;
2969 @@ -521,7 +699,7 @@ vmalloc_fault:
2970                  * Do _not_ use "tsk" here. We might be inside
2971                  * an interrupt in the middle of a task switch..
2972                  */
2973 -               int index = pgd_index(address);
2974 +               unsigned long index = pgd_index(address);
2975                 unsigned long pgd_paddr;
2976                 pgd_t *pgd, *pgd_k;
2977                 pud_t *pud, *pud_k;
2978 @@ -558,3 +736,105 @@ vmalloc_fault:
2979                 return;
2980         }
2981  }
2982 +
2983 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2984 +/*
2985 + * PaX: decide what to do with offenders (regs->eip = fault address)
2986 + *
2987 + * returns 1 when task should be killed
2988 + *         2 when gcc trampoline was detected
2989 + */
2990 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2991 +{
2992 +
2993 +#ifdef CONFIG_PAX_EMUTRAMP
2994 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
2995 +       int err;
2996 +#endif
2997 +
2998 +       if (regs->eflags & X86_EFLAGS_VM)
2999 +               return 1;
3000 +
3001 +#ifdef CONFIG_PAX_EMUTRAMP
3002 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
3003 +               return 1;
3004 +
3005 +       do { /* PaX: gcc trampoline emulation #1 */
3006 +               unsigned char mov1, mov2;
3007 +               unsigned short jmp;
3008 +               unsigned long addr1, addr2;
3009 +
3010 +               err = get_user(mov1, (unsigned char __user *)regs->eip);
3011 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
3012 +               err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
3013 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
3014 +               err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
3015 +
3016 +               if (err)
3017 +                       break;
3018 +
3019 +               if ((mov1 & 0xF8) == 0xB8 &&
3020 +                   (mov2 & 0xF8) == 0xB8 &&
3021 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
3022 +                   (jmp & 0xF8FF) == 0xE0FF &&
3023 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07))
3024 +               {
3025 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
3026 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
3027 +                       regs->eip = addr2;
3028 +                       return 2;
3029 +               }
3030 +       } while (0);
3031 +
3032 +       do { /* PaX: gcc trampoline emulation #2 */
3033 +               unsigned char mov, jmp;
3034 +               unsigned long addr1, addr2;
3035 +
3036 +               err = get_user(mov, (unsigned char __user *)regs->eip);
3037 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
3038 +               err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
3039 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
3040 +
3041 +               if (err)
3042 +                       break;
3043 +
3044 +               if ((mov & 0xF8) == 0xB8 &&
3045 +                   jmp == 0xE9)
3046 +               {
3047 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
3048 +                       regs->eip += addr2 + 10;
3049 +                       return 2;
3050 +               }
3051 +       } while (0);
3052 +#endif
3053 +
3054 +       return 1; /* PaX in action */
3055 +}
3056 +#endif
3057 +
3058 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
3059 +void pax_report_insns(void *pc, void *sp)
3060 +{
3061 +       long i;
3062 +
3063 +       printk(KERN_ERR "PAX: bytes at PC: ");
3064 +       for (i = 0; i < 20; i++) {
3065 +               unsigned char c;
3066 +               if (get_user(c, (unsigned char __user *)pc+i))
3067 +                       printk("?? ");
3068 +               else
3069 +                       printk("%02x ", c);
3070 +       }
3071 +       printk("\n");
3072 +
3073 +       printk(KERN_ERR "PAX: bytes at SP-4: ");
3074 +       for (i = -1; i < 20; i++) {
3075 +               unsigned long c;
3076 +               if (get_user(c, (unsigned long __user *)sp+i))
3077 +                       printk("???????? ");
3078 +               else
3079 +                       printk("%08lx ", c);
3080 +       }
3081 +       printk("\n");
3082 +}
3083 +#endif
3084 diff -urNp linux-2.6.16.12/arch/i386/mm/hugetlbpage.c linux-2.6.16.12/arch/i386/mm/hugetlbpage.c
3085 --- linux-2.6.16.12/arch/i386/mm/hugetlbpage.c  2006-05-01 15:14:26.000000000 -0400
3086 +++ linux-2.6.16.12/arch/i386/mm/hugetlbpage.c  2006-05-01 20:17:33.000000000 -0400
3087 @@ -133,7 +133,12 @@ static unsigned long hugetlb_get_unmappe
3088  {
3089         struct mm_struct *mm = current->mm;
3090         struct vm_area_struct *vma;
3091 -       unsigned long start_addr;
3092 +       unsigned long start_addr, task_size = TASK_SIZE;
3093 +
3094 +#ifdef CONFIG_PAX_SEGMEXEC
3095 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
3096 +               task_size = SEGMEXEC_TASK_SIZE;
3097 +#endif
3098  
3099         if (len > mm->cached_hole_size) {
3100                 start_addr = mm->free_area_cache;
3101 @@ -147,7 +152,7 @@ full_search:
3102  
3103         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3104                 /* At this point:  (!vma || addr < vma->vm_end). */
3105 -               if (TASK_SIZE - len < addr) {
3106 +               if (task_size - len < addr) {
3107                         /*
3108                          * Start a new search - just in case we missed
3109                          * some holes.
3110 @@ -175,9 +180,8 @@ static unsigned long hugetlb_get_unmappe
3111  {
3112         struct mm_struct *mm = current->mm;
3113         struct vm_area_struct *vma, *prev_vma;
3114 -       unsigned long base = mm->mmap_base, addr = addr0;
3115 +       unsigned long base = mm->mmap_base, addr;
3116         unsigned long largest_hole = mm->cached_hole_size;
3117 -       int first_time = 1;
3118  
3119         /* don't allow allocations above current base */
3120         if (mm->free_area_cache > base)
3121 @@ -187,7 +191,7 @@ static unsigned long hugetlb_get_unmappe
3122                 largest_hole = 0;
3123                 mm->free_area_cache  = base;
3124         }
3125 -try_again:
3126 +
3127         /* make sure it can fit in the remaining address space */
3128         if (mm->free_area_cache < len)
3129                 goto fail;
3130 @@ -229,16 +233,6 @@ try_again:
3131  
3132  fail:
3133         /*
3134 -        * if hint left us with no space for the requested
3135 -        * mapping then try again:
3136 -        */
3137 -       if (first_time) {
3138 -               mm->free_area_cache = base;
3139 -               largest_hole = 0;
3140 -               first_time = 0;
3141 -               goto try_again;
3142 -       }
3143 -       /*
3144          * A failed mmap() very likely causes application failure,
3145          * so fall back to the bottom-up function here. This scenario
3146          * can happen with large stack limits and large mmap()
3147 @@ -264,16 +258,23 @@ hugetlb_get_unmapped_area(struct file *f
3148  {
3149         struct mm_struct *mm = current->mm;
3150         struct vm_area_struct *vma;
3151 +       unsigned long task_size = TASK_SIZE;
3152  
3153         if (len & ~HPAGE_MASK)
3154                 return -EINVAL;
3155 -       if (len > TASK_SIZE)
3156 +
3157 +#ifdef CONFIG_PAX_SEGMEXEC
3158 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
3159 +               task_size = SEGMEXEC_TASK_SIZE;
3160 +#endif
3161 +
3162 +       if (len > task_size || addr > task_size - len)
3163                 return -ENOMEM;
3164  
3165         if (addr) {
3166                 addr = ALIGN(addr, HPAGE_SIZE);
3167                 vma = find_vma(mm, addr);
3168 -               if (TASK_SIZE - len >= addr &&
3169 +               if (task_size - len >= addr &&
3170                     (!vma || addr + len <= vma->vm_start))
3171                         return addr;
3172         }
3173 diff -urNp linux-2.6.16.12/arch/i386/mm/init.c linux-2.6.16.12/arch/i386/mm/init.c
3174 --- linux-2.6.16.12/arch/i386/mm/init.c 2006-05-01 15:14:26.000000000 -0400
3175 +++ linux-2.6.16.12/arch/i386/mm/init.c 2006-05-01 20:17:33.000000000 -0400
3176 @@ -42,6 +42,7 @@
3177  #include <asm/tlb.h>
3178  #include <asm/tlbflush.h>
3179  #include <asm/sections.h>
3180 +#include <asm/desc.h>
3181  
3182  unsigned int __VMALLOC_RESERVE = 128 << 20;
3183  
3184 @@ -52,30 +53,6 @@ unsigned long highstart_pfn, highend_pfn
3185  int bad_ppro;
3186  
3187  /*
3188 - * Creates a middle page table and puts a pointer to it in the
3189 - * given global directory entry. This only returns the gd entry
3190 - * in non-PAE compilation mode, since the middle layer is folded.
3191 - */
3192 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
3193 -{
3194 -       pud_t *pud;
3195 -       pmd_t *pmd_table;
3196 -               
3197 -#ifdef CONFIG_X86_PAE
3198 -       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
3199 -       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
3200 -       pud = pud_offset(pgd, 0);
3201 -       if (pmd_table != pmd_offset(pud, 0)) 
3202 -               BUG();
3203 -#else
3204 -       pud = pud_offset(pgd, 0);
3205 -       pmd_table = pmd_offset(pud, 0);
3206 -#endif
3207 -
3208 -       return pmd_table;
3209 -}
3210 -
3211 -/*
3212   * Create a page table and place a pointer to it in a middle page
3213   * directory entry.
3214   */
3215 @@ -83,7 +60,11 @@ static pte_t * __init one_page_table_ini
3216  {
3217         if (pmd_none(*pmd)) {
3218                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
3219 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
3220 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
3221 +#else
3222                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
3223 +#endif
3224                 if (page_table != pte_offset_kernel(pmd, 0))
3225                         BUG();  
3226  
3227 @@ -118,8 +99,6 @@ static void __init page_table_range_init
3228         pgd = pgd_base + pgd_idx;
3229  
3230         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
3231 -               if (pgd_none(*pgd)) 
3232 -                       one_md_table_init(pgd);
3233                 pud = pud_offset(pgd, vaddr);
3234                 pmd = pmd_offset(pud, vaddr);
3235                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
3236 @@ -132,11 +111,22 @@ static void __init page_table_range_init
3237         }
3238  }
3239  
3240 -static inline int is_kernel_text(unsigned long addr)
3241 +static inline int is_kernel_text(unsigned long start, unsigned long end)
3242  {
3243 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
3244 -               return 1;
3245 -       return 0;
3246 +       unsigned long etext;
3247 +
3248 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
3249 +       etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
3250 +#else
3251 +       etext = (unsigned long)&_etext;
3252 +#endif
3253 +
3254 +       if ((start > etext + __KERNEL_TEXT_OFFSET ||
3255 +            end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
3256 +           (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
3257 +            end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
3258 +               return 0;
3259 +       return 1;
3260  }
3261  
3262  /*
3263 @@ -148,26 +138,24 @@ static void __init kernel_physical_mappi
3264  {
3265         unsigned long pfn;
3266         pgd_t *pgd;
3267 +       pud_t *pud;
3268         pmd_t *pmd;
3269         pte_t *pte;
3270 -       int pgd_idx, pmd_idx, pte_ofs;
3271 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
3272  
3273         pgd_idx = pgd_index(PAGE_OFFSET);
3274         pgd = pgd_base + pgd_idx;
3275         pfn = 0;
3276  
3277 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
3278 -               pmd = one_md_table_init(pgd);
3279 -               if (pfn >= max_low_pfn)
3280 -                       continue;
3281 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
3282 +               pud = pud_offset(pgd, 0);
3283 +               pmd = pmd_offset(pud, 0);
3284                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
3285 -                       unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
3286 +                       unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
3287  
3288                         /* Map with big pages if possible, otherwise create normal page tables. */
3289                         if (cpu_has_pse) {
3290 -                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
3291 -
3292 -                               if (is_kernel_text(address) || is_kernel_text(address2))
3293 +                               if (is_kernel_text(address, address + PMD_SIZE))
3294                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
3295                                 else
3296                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
3297 @@ -176,7 +164,7 @@ static void __init kernel_physical_mappi
3298                                 pte = one_page_table_init(pmd);
3299  
3300                                 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
3301 -                                               if (is_kernel_text(address))
3302 +                                               if (is_kernel_text(address, address + PAGE_SIZE))
3303                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
3304                                                 else
3305                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
3306 @@ -347,13 +335,6 @@ static void __init pagetable_init (void)
3307         unsigned long vaddr;
3308         pgd_t *pgd_base = swapper_pg_dir;
3309  
3310 -#ifdef CONFIG_X86_PAE
3311 -       int i;
3312 -       /* Init entries of the first-level page table to the zero page */
3313 -       for (i = 0; i < PTRS_PER_PGD; i++)
3314 -               set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
3315 -#endif
3316 -
3317         /* Enable PSE if available */
3318         if (cpu_has_pse) {
3319                 set_in_cr4(X86_CR4_PSE);
3320 @@ -377,17 +358,6 @@ static void __init pagetable_init (void)
3321         page_table_range_init(vaddr, 0, pgd_base);
3322  
3323         permanent_kmaps_init(pgd_base);
3324 -
3325 -#ifdef CONFIG_X86_PAE
3326 -       /*
3327 -        * Add low memory identity-mappings - SMP needs it when
3328 -        * starting up on an AP from real-mode. In the non-PAE
3329 -        * case we already have these mappings through head.S.
3330 -        * All user-space mappings are explicitly cleared after
3331 -        * SMP startup.
3332 -        */
3333 -       set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
3334 -#endif
3335  }
3336  
3337  #ifdef CONFIG_PM
3338 @@ -429,7 +399,6 @@ void zap_low_mappings (void)
3339         flush_tlb_all();
3340  }
3341  
3342 -static int disable_nx __initdata = 0;
3343  u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
3344  
3345  /*
3346 @@ -443,11 +412,9 @@ u64 __supported_pte_mask __read_mostly =
3347  void __init noexec_setup(const char *str)
3348  {
3349         if (!strncmp(str, "on",2) && cpu_has_nx) {
3350 -               __supported_pte_mask |= _PAGE_NX;
3351 -               disable_nx = 0;
3352 +               nx_enabled = 1;
3353         } else if (!strncmp(str,"off",3)) {
3354 -               disable_nx = 1;
3355 -               __supported_pte_mask &= ~_PAGE_NX;
3356 +               nx_enabled = 0;
3357         }
3358  }
3359  
3360 @@ -456,17 +423,13 @@ int nx_enabled = 0;
3361  
3362  static void __init set_nx(void)
3363  {
3364 -       unsigned int v[4], l, h;
3365 +       if (!nx_enabled && cpu_has_nx) {
3366 +               unsigned l, h;
3367  
3368 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
3369 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
3370 -               if ((v[3] & (1 << 20)) && !disable_nx) {
3371 -                       rdmsr(MSR_EFER, l, h);
3372 -                       l |= EFER_NX;
3373 -                       wrmsr(MSR_EFER, l, h);
3374 -                       nx_enabled = 1;
3375 -                       __supported_pte_mask |= _PAGE_NX;
3376 -               }
3377 +               __supported_pte_mask &= ~_PAGE_NX;
3378 +               rdmsr(MSR_EFER, l, h);
3379 +               l &= ~EFER_NX;
3380 +               wrmsr(MSR_EFER, l, h);
3381         }
3382  }
3383  
3384 @@ -518,14 +481,6 @@ void __init paging_init(void)
3385  
3386         load_cr3(swapper_pg_dir);
3387  
3388 -#ifdef CONFIG_X86_PAE
3389 -       /*
3390 -        * We will bail out later - printk doesn't work right now so
3391 -        * the user would just see a hanging kernel.
3392 -        */
3393 -       if (cpu_has_pae)
3394 -               set_in_cr4(X86_CR4_PAE);
3395 -#endif
3396         __flush_tlb_all();
3397  
3398         kmap_init();
3399 @@ -628,7 +583,7 @@ void __init mem_init(void)
3400         set_highmem_pages_init(bad_ppro);
3401  
3402         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
3403 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
3404 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
3405         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
3406  
3407         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
3408 @@ -645,10 +600,6 @@ void __init mem_init(void)
3409                 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
3410                );
3411  
3412 -#ifdef CONFIG_X86_PAE
3413 -       if (!cpu_has_pae)
3414 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
3415 -#endif
3416         if (boot_cpu_data.wp_works_ok < 0)
3417                 test_wp_bit();
3418  
3419 @@ -741,6 +692,36 @@ void free_initmem(void)
3420  {
3421         unsigned long addr;
3422  
3423 +#ifdef CONFIG_PAX_KERNEXEC
3424 +       /* PaX: limit KERNEL_CS to actual size */
3425 +       unsigned long limit;
3426 +       int cpu;
3427 +       pgd_t *pgd;
3428 +       pud_t *pud;
3429 +       pmd_t *pmd;
3430 +
3431 +#ifdef CONFIG_MODULES
3432 +       limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
3433 +#else
3434 +       limit = (unsigned long)&_etext;
3435 +#endif
3436 +       limit = (limit - 1UL) >> PAGE_SHIFT;
3437 +
3438 +       for (cpu = 0; cpu < NR_CPUS; cpu++) {
3439 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
3440 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
3441 +       }
3442 +
3443 +       /* PaX: make KERNEL_CS read-only */
3444 +       for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
3445 +               pgd = pgd_offset_k(addr);
3446 +               pud = pud_offset(pgd, addr);
3447 +               pmd = pmd_offset(pud, addr);
3448 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
3449 +       }
3450 +       flush_tlb_all();
3451 +#endif
3452 +
3453         addr = (unsigned long)(&__init_begin);
3454         for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
3455                 ClearPageReserved(virt_to_page(addr));
3456 diff -urNp linux-2.6.16.12/arch/i386/mm/mmap.c linux-2.6.16.12/arch/i386/mm/mmap.c
3457 --- linux-2.6.16.12/arch/i386/mm/mmap.c 2006-05-01 15:14:26.000000000 -0400
3458 +++ linux-2.6.16.12/arch/i386/mm/mmap.c 2006-05-01 20:17:33.000000000 -0400
3459 @@ -34,12 +34,18 @@
3460   * Leave an at least ~128 MB hole.
3461   */
3462  #define MIN_GAP (128*1024*1024)
3463 -#define MAX_GAP (TASK_SIZE/6*5)
3464 +#define MAX_GAP (task_size/6*5)
3465  
3466  static inline unsigned long mmap_base(struct mm_struct *mm)
3467  {
3468         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
3469         unsigned long random_factor = 0;
3470 +       unsigned long task_size = TASK_SIZE;
3471 +
3472 +#ifdef CONFIG_PAX_SEGMEXEC
3473 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
3474 +               task_size = SEGMEXEC_TASK_SIZE;
3475 +#endif
3476  
3477         if (current->flags & PF_RANDOMIZE)
3478                 random_factor = get_random_int() % (1024*1024);
3479 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
3480         else if (gap > MAX_GAP)
3481                 gap = MAX_GAP;
3482  
3483 -       return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
3484 +       return PAGE_ALIGN(task_size - gap - random_factor);
3485  }
3486  
3487  /*
3488 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
3489                         (current->personality & ADDR_COMPAT_LAYOUT) ||
3490                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
3491                 mm->mmap_base = TASK_UNMAPPED_BASE;
3492 +
3493 +#ifdef CONFIG_PAX_RANDMMAP
3494 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
3495 +                       mm->mmap_base += mm->delta_mmap;
3496 +#endif
3497 +
3498                 mm->get_unmapped_area = arch_get_unmapped_area;
3499                 mm->unmap_area = arch_unmap_area;
3500         } else {
3501                 mm->mmap_base = mmap_base(mm);
3502 +
3503 +#ifdef CONFIG_PAX_RANDMMAP
3504 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
3505 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3506 +#endif
3507 +
3508                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3509                 mm->unmap_area = arch_unmap_area_topdown;
3510         }
3511 diff -urNp linux-2.6.16.12/arch/i386/mm/pageattr.c linux-2.6.16.12/arch/i386/mm/pageattr.c
3512 --- linux-2.6.16.12/arch/i386/mm/pageattr.c     2006-05-01 15:14:26.000000000 -0400
3513 +++ linux-2.6.16.12/arch/i386/mm/pageattr.c     2006-05-01 20:17:33.000000000 -0400
3514 @@ -14,6 +14,7 @@
3515  #include <asm/tlbflush.h>
3516  #include <asm/pgalloc.h>
3517  #include <asm/sections.h>
3518 +#include <asm/desc.h>
3519  
3520  static DEFINE_SPINLOCK(cpa_lock);
3521  static struct list_head df_list = LIST_HEAD_INIT(df_list);
3522 @@ -77,7 +78,18 @@ static void set_pmd_pte(pte_t *kpte, uns
3523         struct page *page;
3524         unsigned long flags;
3525  
3526 +#ifdef CONFIG_PAX_KERNEXEC
3527 +       unsigned long cr0;
3528 +
3529 +       pax_open_kernel(cr0);
3530 +#endif
3531 +
3532         set_pte_atomic(kpte, pte);      /* change init_mm */
3533 +
3534 +#ifdef CONFIG_PAX_KERNEXEC
3535 +       pax_close_kernel(cr0);
3536 +#endif
3537 +
3538         if (PTRS_PER_PMD > 1)
3539                 return;
3540  
3541 @@ -104,7 +116,7 @@ static inline void revert_page(struct pa
3542         pte_t *linear;
3543  
3544         ref_prot =
3545 -       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
3546 +       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
3547                 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
3548  
3549         linear = (pte_t *)
3550 @@ -136,7 +148,7 @@ __change_page_attr(struct page *page, pg
3551                         struct page *split;
3552  
3553                         ref_prot =
3554 -                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
3555 +                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
3556                                 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
3557                         split = split_large_page(address, prot, ref_prot);
3558                         if (!split)
3559 diff -urNp linux-2.6.16.12/arch/i386/oprofile/backtrace.c linux-2.6.16.12/arch/i386/oprofile/backtrace.c
3560 --- linux-2.6.16.12/arch/i386/oprofile/backtrace.c      2006-05-01 15:14:26.000000000 -0400
3561 +++ linux-2.6.16.12/arch/i386/oprofile/backtrace.c      2006-05-01 20:17:33.000000000 -0400
3562 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
3563         head = (struct frame_head *)regs->ebp;
3564  #endif
3565  
3566 -       if (!user_mode_vm(regs)) {
3567 +       if (!user_mode(regs)) {
3568                 while (depth-- && valid_kernel_stack(head, regs))
3569                         head = dump_kernel_backtrace(head);
3570                 return;
3571 diff -urNp linux-2.6.16.12/arch/i386/power/cpu.c linux-2.6.16.12/arch/i386/power/cpu.c
3572 --- linux-2.6.16.12/arch/i386/power/cpu.c       2006-05-01 15:14:26.000000000 -0400
3573 +++ linux-2.6.16.12/arch/i386/power/cpu.c       2006-05-01 20:17:33.000000000 -0400
3574 @@ -62,7 +62,7 @@ static void do_fpu_end(void)
3575  static void fix_processor_context(void)
3576  {
3577         int cpu = smp_processor_id();
3578 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
3579 +       struct tss_struct * t = init_tss + cpu;
3580  
3581         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. */
3582  
3583 @@ -92,7 +92,7 @@ void __restore_processor_state(struct sa
3584         write_cr4(ctxt->cr4);
3585         write_cr3(ctxt->cr3);
3586         write_cr2(ctxt->cr2);
3587 -       write_cr2(ctxt->cr0);
3588 +       write_cr0(ctxt->cr0);
3589  
3590         /*
3591          * now restore the descriptor tables to their proper values
3592 diff -urNp linux-2.6.16.12/arch/ia64/ia32/binfmt_elf32.c linux-2.6.16.12/arch/ia64/ia32/binfmt_elf32.c
3593 --- linux-2.6.16.12/arch/ia64/ia32/binfmt_elf32.c       2006-05-01 15:14:26.000000000 -0400
3594 +++ linux-2.6.16.12/arch/ia64/ia32/binfmt_elf32.c       2006-05-01 20:17:33.000000000 -0400
3595 @@ -43,6 +43,17 @@ static void elf32_set_personality (void)
3596  
3597  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
3598  
3599 +#ifdef CONFIG_PAX_ASLR
3600 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
3601 +
3602 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
3603 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
3604 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
3605 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
3606 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
3607 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
3608 +#endif
3609 +
3610  /* Ugly but avoids duplication */
3611  #include "../../../fs/binfmt_elf.c"
3612  
3613 diff -urNp linux-2.6.16.12/arch/ia64/ia32/ia32priv.h linux-2.6.16.12/arch/ia64/ia32/ia32priv.h
3614 --- linux-2.6.16.12/arch/ia64/ia32/ia32priv.h   2006-05-01 15:14:26.000000000 -0400
3615 +++ linux-2.6.16.12/arch/ia64/ia32/ia32priv.h   2006-05-01 20:17:33.000000000 -0400
3616 @@ -305,7 +305,14 @@ struct old_linux32_dirent {
3617  #define ELF_DATA       ELFDATA2LSB
3618  #define ELF_ARCH       EM_386
3619  
3620 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
3621 +#ifdef CONFIG_PAX_RANDUSTACK
3622 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
3623 +#else
3624 +#define __IA32_DELTA_STACK     0UL
3625 +#endif
3626 +
3627 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
3628 +
3629  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
3630  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
3631  
3632 diff -urNp linux-2.6.16.12/arch/ia64/kernel/module.c linux-2.6.16.12/arch/ia64/kernel/module.c
3633 --- linux-2.6.16.12/arch/ia64/kernel/module.c   2006-05-01 15:14:26.000000000 -0400
3634 +++ linux-2.6.16.12/arch/ia64/kernel/module.c   2006-05-01 20:17:33.000000000 -0400
3635 @@ -322,7 +322,7 @@ module_alloc (unsigned long size)
3636  void
3637  module_free (struct module *mod, void *module_region)
3638  {
3639 -       if (mod->arch.init_unw_table && module_region == mod->module_init) {
3640 +       if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
3641                 unw_remove_unwind_table(mod->arch.init_unw_table);
3642                 mod->arch.init_unw_table = NULL;
3643         }
3644 @@ -500,15 +500,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
3645  }
3646  
3647  static inline int
3648 +in_init_rx (const struct module *mod, uint64_t addr)
3649 +{
3650 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
3651 +}
3652 +
3653 +static inline int
3654 +in_init_rw (const struct module *mod, uint64_t addr)
3655 +{
3656 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
3657 +}
3658 +
3659 +static inline int
3660  in_init (const struct module *mod, uint64_t addr)
3661  {
3662 -       return addr - (uint64_t) mod->module_init < mod->init_size;
3663 +       return in_init_rx(mod, value) || in_init_rw(mod, value);
3664 +}
3665 +
3666 +static inline int
3667 +in_core_rx (const struct module *mod, uint64_t addr)
3668 +{
3669 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
3670 +}
3671 +
3672 +static inline int
3673 +in_core_rw (const struct module *mod, uint64_t addr)
3674 +{
3675 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
3676  }
3677  
3678  static inline int
3679  in_core (const struct module *mod, uint64_t addr)
3680  {
3681 -       return addr - (uint64_t) mod->module_core < mod->core_size;
3682 +       return in_core_rx(mod, value) || in_core_rw(mod, value);
3683  }
3684  
3685  static inline int
3686 @@ -692,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_
3687                 break;
3688  
3689               case RV_BDREL:
3690 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
3691 +               if (in_init_rx(mod, val))
3692 +                       val -= (uint64_t) mod->module_init_rx;
3693 +               else if (in_init_rw(mod, val))
3694 +                       val -= (uint64_t) mod->module_init_rw;
3695 +               else if (in_core_rx(mod, val))
3696 +                       val -= (uint64_t) mod->module_core_rx;
3697 +               else if (in_core_rw(mod, val))
3698 +                       val -= (uint64_t) mod->module_core_rw;
3699                 break;
3700  
3701               case RV_LTV:
3702 @@ -826,15 +857,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
3703                  *     addresses have been selected...
3704                  */
3705                 uint64_t gp;
3706 -               if (mod->core_size > MAX_LTOFF)
3707 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
3708                         /*
3709                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
3710                          * at the end of the module.
3711                          */
3712 -                       gp = mod->core_size - MAX_LTOFF / 2;
3713 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
3714                 else
3715 -                       gp = mod->core_size / 2;
3716 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
3717 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
3718 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
3719                 mod->arch.gp = gp;
3720                 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
3721         }
3722 diff -urNp linux-2.6.16.12/arch/ia64/kernel/ptrace.c linux-2.6.16.12/arch/ia64/kernel/ptrace.c
3723 --- linux-2.6.16.12/arch/ia64/kernel/ptrace.c   2006-05-01 15:14:26.000000000 -0400
3724 +++ linux-2.6.16.12/arch/ia64/kernel/ptrace.c   2006-05-01 20:17:33.000000000 -0400
3725 @@ -19,6 +19,7 @@
3726  #include <linux/audit.h>
3727  #include <linux/signal.h>
3728  #include <linux/vs_pid.h>
3729 +#include <linux/grsecurity.h>
3730  
3731  #include <asm/pgtable.h>
3732  #include <asm/processor.h>
3733 @@ -1451,6 +1452,9 @@ sys_ptrace (long request, pid_t pid, uns
3734         if (pid == 1)           /* no messing around with init! */
3735                 goto out_tsk;
3736  
3737 +       if (gr_handle_ptrace(child, request))
3738 +               goto out_tsk;
3739 +
3740         if (request == PTRACE_ATTACH) {
3741                 ret = ptrace_attach(child);
3742                 goto out_tsk;
3743 diff -urNp linux-2.6.16.12/arch/ia64/kernel/sys_ia64.c linux-2.6.16.12/arch/ia64/kernel/sys_ia64.c
3744 --- linux-2.6.16.12/arch/ia64/kernel/sys_ia64.c 2006-05-01 15:14:26.000000000 -0400
3745 +++ linux-2.6.16.12/arch/ia64/kernel/sys_ia64.c 2006-05-01 20:17:33.000000000 -0400
3746 @@ -38,6 +38,13 @@ arch_get_unmapped_area (struct file *fil
3747         if (REGION_NUMBER(addr) == RGN_HPAGE)
3748                 addr = 0;
3749  #endif
3750 +
3751 +#ifdef CONFIG_PAX_RANDMMAP
3752 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
3753 +               addr = mm->free_area_cache;
3754 +       else
3755 +#endif
3756 +
3757         if (!addr)
3758                 addr = mm->free_area_cache;
3759  
3760 @@ -56,9 +63,9 @@ arch_get_unmapped_area (struct file *fil
3761         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3762                 /* At this point:  (!vma || addr < vma->vm_end). */
3763                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
3764 -                       if (start_addr != TASK_UNMAPPED_BASE) {
3765 +                       if (start_addr != mm->mmap_base) {
3766                                 /* Start a new search --- just in case we missed some holes.  */
3767 -                               addr = TASK_UNMAPPED_BASE;
3768 +                               addr = mm->mmap_base;
3769                                 goto full_search;
3770                         }
3771                         return -ENOMEM;
3772 diff -urNp linux-2.6.16.12/arch/ia64/mm/fault.c linux-2.6.16.12/arch/ia64/mm/fault.c
3773 --- linux-2.6.16.12/arch/ia64/mm/fault.c        2006-05-01 15:14:26.000000000 -0400
3774 +++ linux-2.6.16.12/arch/ia64/mm/fault.c        2006-05-01 20:17:33.000000000 -0400
3775 @@ -11,6 +11,7 @@
3776  #include <linux/interrupt.h>
3777  #include <linux/kprobes.h>
3778  #include <linux/vs_memory.h>
3779 +#include <linux/binfmts.h>
3780  
3781  #include <asm/pgtable.h>
3782  #include <asm/processor.h>
3783 @@ -52,6 +53,23 @@ mapped_kernel_page_is_present (unsigned 
3784         return pte_present(pte);
3785  }
3786  
3787 +#ifdef CONFIG_PAX_PAGEEXEC
3788 +void pax_report_insns(void *pc, void *sp)
3789 +{
3790 +       unsigned long i;
3791 +
3792 +       printk(KERN_ERR "PAX: bytes at PC: ");
3793 +       for (i = 0; i < 8; i++) {
3794 +               unsigned int c;
3795 +               if (get_user(c, (unsigned int*)pc+i))
3796 +                       printk("???????? ");
3797 +               else
3798 +                       printk("%08x ", c);
3799 +       }
3800 +       printk("\n");
3801 +}
3802 +#endif
3803 +
3804  void __kprobes
3805  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
3806  {
3807 @@ -114,9 +132,23 @@ ia64_do_page_fault (unsigned long addres
3808                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
3809                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
3810  
3811 -       if ((vma->vm_flags & mask) != mask)
3812 +       if ((vma->vm_flags & mask) != mask) {
3813 +
3814 +#ifdef CONFIG_PAX_PAGEEXEC
3815 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
3816 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
3817 +                               goto bad_area;
3818 +
3819 +                       up_read(&mm->mmap_sem);
3820 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
3821 +                       do_exit(SIGKILL);
3822 +               }
3823 +#endif
3824 +
3825                 goto bad_area;
3826  
3827 +       }
3828 +
3829    survive:
3830         /*
3831          * If for any reason at all we couldn't handle the fault, make
3832 diff -urNp linux-2.6.16.12/arch/ia64/mm/init.c linux-2.6.16.12/arch/ia64/mm/init.c
3833 --- linux-2.6.16.12/arch/ia64/mm/init.c 2006-05-01 15:14:26.000000000 -0400
3834 +++ linux-2.6.16.12/arch/ia64/mm/init.c 2006-05-01 20:17:33.000000000 -0400
3835 @@ -20,8 +20,8 @@
3836  #include <linux/swap.h>
3837  #include <linux/proc_fs.h>
3838  #include <linux/bitops.h>
3839 +#include <linux/a.out.h>
3840  
3841 -#include <asm/a.out.h>
3842  #include <asm/dma.h>
3843  #include <asm/ia32.h>
3844  #include <asm/io.h>
3845 diff -urNp linux-2.6.16.12/arch/mips/kernel/binfmt_elfn32.c linux-2.6.16.12/arch/mips/kernel/binfmt_elfn32.c
3846 --- linux-2.6.16.12/arch/mips/kernel/binfmt_elfn32.c    2006-05-01 15:14:26.000000000 -0400
3847 +++ linux-2.6.16.12/arch/mips/kernel/binfmt_elfn32.c    2006-05-01 20:17:33.000000000 -0400
3848 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
3849  #undef ELF_ET_DYN_BASE
3850  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
3851  
3852 +#ifdef CONFIG_PAX_ASLR
3853 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
3854 +
3855 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
3856 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3857 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
3858 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3859 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
3860 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3861 +#endif
3862 +
3863  #include <asm/processor.h>
3864  #include <linux/module.h>
3865  #include <linux/elfcore.h>
3866 diff -urNp linux-2.6.16.12/arch/mips/kernel/binfmt_elfo32.c linux-2.6.16.12/arch/mips/kernel/binfmt_elfo32.c
3867 --- linux-2.6.16.12/arch/mips/kernel/binfmt_elfo32.c    2006-05-01 15:14:26.000000000 -0400
3868 +++ linux-2.6.16.12/arch/mips/kernel/binfmt_elfo32.c    2006-05-01 20:17:33.000000000 -0400
3869 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
3870  #undef ELF_ET_DYN_BASE
3871  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
3872  
3873 +#ifdef CONFIG_PAX_ASLR
3874 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
3875 +
3876 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
3877 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3878 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
3879 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3880 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
3881 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3882 +#endif
3883 +
3884  #include <asm/processor.h>
3885  #include <linux/module.h>
3886  #include <linux/elfcore.h>
3887 diff -urNp linux-2.6.16.12/arch/mips/kernel/syscall.c linux-2.6.16.12/arch/mips/kernel/syscall.c
3888 --- linux-2.6.16.12/arch/mips/kernel/syscall.c  2006-05-01 15:14:26.000000000 -0400
3889 +++ linux-2.6.16.12/arch/mips/kernel/syscall.c  2006-05-01 20:17:33.000000000 -0400
3890 @@ -90,6 +90,11 @@ unsigned long arch_get_unmapped_area(str
3891         do_color_align = 0;
3892         if (filp || (flags & MAP_SHARED))
3893                 do_color_align = 1;
3894 +
3895 +#ifdef CONFIG_PAX_RANDMMAP
3896 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3897 +#endif
3898 +
3899         if (addr) {
3900                 if (do_color_align)
3901                         addr = COLOUR_ALIGN(addr, pgoff);
3902 @@ -100,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
3903                     (!vmm || addr + len <= vmm->vm_start))
3904                         return addr;
3905         }
3906 -       addr = TASK_UNMAPPED_BASE;
3907 +       addr = current->mm->mmap_base;
3908         if (do_color_align)
3909                 addr = COLOUR_ALIGN(addr, pgoff);
3910         else
3911 diff -urNp linux-2.6.16.12/arch/mips/mm/fault.c linux-2.6.16.12/arch/mips/mm/fault.c
3912 --- linux-2.6.16.12/arch/mips/mm/fault.c        2006-05-01 15:14:26.000000000 -0400
3913 +++ linux-2.6.16.12/arch/mips/mm/fault.c        2006-05-01 20:17:33.000000000 -0400
3914 @@ -27,6 +27,23 @@
3915  #include <asm/ptrace.h>
3916  #include <asm/highmem.h>               /* For VMALLOC_END */
3917  
3918 +#ifdef CONFIG_PAX_PAGEEXEC
3919 +void pax_report_insns(void *pc)
3920 +{
3921 +       unsigned long i;
3922 +
3923 +       printk(KERN_ERR "PAX: bytes at PC: ");
3924 +       for (i = 0; i < 5; i++) {
3925 +               unsigned int c;
3926 +               if (get_user(c, (unsigned int*)pc+i))
3927 +                       printk("???????? ");
3928 +               else
3929 +                       printk("%08x ", c);
3930 +       }
3931 +       printk("\n");
3932 +}
3933 +#endif
3934 +
3935  /*
3936   * This routine handles page faults.  It determines the address,
3937   * and the problem, and then passes it off to one of the appropriate
3938 diff -urNp linux-2.6.16.12/arch/parisc/kernel/module.c linux-2.6.16.12/arch/parisc/kernel/module.c
3939 --- linux-2.6.16.12/arch/parisc/kernel/module.c 2006-05-01 15:14:26.000000000 -0400
3940 +++ linux-2.6.16.12/arch/parisc/kernel/module.c 2006-05-01 20:17:33.000000000 -0400
3941 @@ -72,16 +72,38 @@
3942  
3943  /* three functions to determine where in the module core
3944   * or init pieces the location is */
3945 +static inline int is_init_rx(struct module *me, void *loc)
3946 +{
3947 +       return (loc >= me->module_init_rx &&
3948 +               loc < (me->module_init_rx + me->init_size_rx));
3949 +}
3950 +
3951 +static inline int is_init_rw(struct module *me, void *loc)
3952 +{
3953 +       return (loc >= me->module_init_rw &&
3954 +               loc < (me->module_init_rw + me->init_size_rw));
3955 +}
3956 +
3957  static inline int is_init(struct module *me, void *loc)
3958  {
3959 -       return (loc >= me->module_init &&
3960 -               loc <= (me->module_init + me->init_size));
3961 +       return is_init_rx(me, loc) || is_init_rw(me, loc);
3962 +}
3963 +
3964 +static inline int is_core_rx(struct module *me, void *loc)
3965 +{
3966 +       return (loc >= me->module_core_rx &&
3967 +               loc < (me->module_core_rx + me->core_size_rx));
3968 +}
3969 +
3970 +static inline int is_core_rw(struct module *me, void *loc)
3971 +{
3972 +       return (loc >= me->module_core_rw &&
3973 +               loc < (me->module_core_rw + me->core_size_rw));
3974  }
3975  
3976  static inline int is_core(struct module *me, void *loc)
3977  {
3978 -       return (loc >= me->module_core &&
3979 -               loc <= (me->module_core + me->core_size));
3980 +       return is_core_rx(me, loc) || is_core_rw(me, loc);
3981  }
3982  
3983  static inline int is_local(struct module *me, void *loc)
3984 @@ -289,21 +311,21 @@ int module_frob_arch_sections(CONST Elf_
3985         }
3986  
3987         /* align things a bit */
3988 -       me->core_size = ALIGN(me->core_size, 16);
3989 -       me->arch.got_offset = me->core_size;
3990 -       me->core_size += gots * sizeof(struct got_entry);
3991 -
3992 -       me->core_size = ALIGN(me->core_size, 16);
3993 -       me->arch.fdesc_offset = me->core_size;
3994 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
3995 -
3996 -       me->core_size = ALIGN(me->core_size, 16);
3997 -       me->arch.stub_offset = me->core_size;
3998 -       me->core_size += stubs * sizeof(struct stub_entry);
3999 -
4000 -       me->init_size = ALIGN(me->init_size, 16);
4001 -       me->arch.init_stub_offset = me->init_size;
4002 -       me->init_size += init_stubs * sizeof(struct stub_entry);
4003 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
4004 +       me->arch.got_offset = me->core_size_rw;
4005 +       me->core_size_rw += gots * sizeof(struct got_entry);
4006 +
4007 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
4008 +       me->arch.fdesc_offset = me->core_size_rw;
4009 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
4010 +
4011 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
4012 +       me->arch.stub_offset = me->core_size_rx;
4013 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
4014 +
4015 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
4016 +       me->arch.init_stub_offset = me->init_size_rx;
4017 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
4018  
4019         me->arch.got_max = gots;
4020         me->arch.fdesc_max = fdescs;
4021 @@ -323,7 +345,7 @@ static Elf64_Word get_got(struct module 
4022  
4023         BUG_ON(value == 0);
4024  
4025 -       got = me->module_core + me->arch.got_offset;
4026 +       got = me->module_core_rw + me->arch.got_offset;
4027         for (i = 0; got[i].addr; i++)
4028                 if (got[i].addr == value)
4029                         goto out;
4030 @@ -341,7 +363,7 @@ static Elf64_Word get_got(struct module 
4031  #ifdef __LP64__
4032  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
4033  {
4034 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
4035 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
4036  
4037         if (!value) {
4038                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
4039 @@ -359,7 +381,7 @@ static Elf_Addr get_fdesc(struct module 
4040  
4041         /* Create new one */
4042         fdesc->addr = value;
4043 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
4044 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
4045         return (Elf_Addr)fdesc;
4046  }
4047  #endif /* __LP64__ */
4048 @@ -373,12 +395,12 @@ static Elf_Addr get_stub(struct module *
4049         if(init_section) {
4050                 i = me->arch.init_stub_count++;
4051                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
4052 -               stub = me->module_init + me->arch.init_stub_offset + 
4053 +               stub = me->module_init_rx + me->arch.init_stub_offset + 
4054                         i * sizeof(struct stub_entry);
4055         } else {
4056                 i = me->arch.stub_count++;
4057                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
4058 -               stub = me->module_core + me->arch.stub_offset + 
4059 +               stub = me->module_core_rx + me->arch.stub_offset + 
4060                         i * sizeof(struct stub_entry);
4061         }
4062  
4063 @@ -721,7 +743,7 @@ register_unwind_table(struct module *me,
4064  
4065         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
4066         end = table + sechdrs[me->arch.unwind_section].sh_size;
4067 -       gp = (Elf_Addr)me->module_core + me->arch.got_offset;
4068 +       gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
4069  
4070         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
4071                me->arch.unwind_section, table, end, gp);
4072 diff -urNp linux-2.6.16.12/arch/parisc/kernel/ptrace.c linux-2.6.16.12/arch/parisc/kernel/ptrace.c
4073 --- linux-2.6.16.12/arch/parisc/kernel/ptrace.c 2006-05-01 15:14:26.000000000 -0400
4074 +++ linux-2.6.16.12/arch/parisc/kernel/ptrace.c 2006-05-01 20:17:33.000000000 -0400
4075 @@ -18,6 +18,7 @@
4076  #include <linux/security.h>
4077  #include <linux/compat.h>
4078  #include <linux/signal.h>
4079 +#include <linux/grsecurity.h>
4080  
4081  #include <asm/uaccess.h>
4082  #include <asm/pgtable.h>
4083 diff -urNp linux-2.6.16.12/arch/parisc/kernel/sys_parisc.c linux-2.6.16.12/arch/parisc/kernel/sys_parisc.c
4084 --- linux-2.6.16.12/arch/parisc/kernel/sys_parisc.c     2006-05-01 15:14:26.000000000 -0400
4085 +++ linux-2.6.16.12/arch/parisc/kernel/sys_parisc.c     2006-05-01 20:17:33.000000000 -0400
4086 @@ -105,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
4087         if (len > TASK_SIZE)
4088                 return -ENOMEM;
4089         if (!addr)
4090 -               addr = TASK_UNMAPPED_BASE;
4091 +               addr = current->mm->mmap_base;
4092  
4093         if (filp) {
4094                 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
4095 diff -urNp linux-2.6.16.12/arch/parisc/kernel/traps.c linux-2.6.16.12/arch/parisc/kernel/traps.c
4096 --- linux-2.6.16.12/arch/parisc/kernel/traps.c  2006-05-01 15:14:26.000000000 -0400
4097 +++ linux-2.6.16.12/arch/parisc/kernel/traps.c  2006-05-01 20:17:33.000000000 -0400
4098 @@ -712,9 +712,7 @@ void handle_interruption(int code, struc
4099  
4100                         down_read(&current->mm->mmap_sem);
4101                         vma = find_vma(current->mm,regs->iaoq[0]);
4102 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
4103 -                               && (vma->vm_flags & VM_EXEC)) {
4104 -
4105 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
4106                                 fault_address = regs->iaoq[0];
4107                                 fault_space = regs->iasq[0];
4108  
4109 diff -urNp linux-2.6.16.12/arch/parisc/mm/fault.c linux-2.6.16.12/arch/parisc/mm/fault.c
4110 --- linux-2.6.16.12/arch/parisc/mm/fault.c      2006-05-01 15:14:26.000000000 -0400
4111 +++ linux-2.6.16.12/arch/parisc/mm/fault.c      2006-05-01 20:17:33.000000000 -0400
4112 @@ -16,6 +16,8 @@
4113  #include <linux/sched.h>
4114  #include <linux/interrupt.h>
4115  #include <linux/module.h>
4116 +#include <linux/unistd.h>
4117 +#include <linux/binfmts.h>
4118  
4119  #include <asm/uaccess.h>
4120  #include <asm/traps.h>
4121 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
4122  static unsigned long
4123  parisc_acctyp(unsigned long code, unsigned int inst)
4124  {
4125 -       if (code == 6 || code == 16)
4126 +       if (code == 6 || code == 7 || code == 16)
4127             return VM_EXEC;
4128  
4129         switch (inst & 0xf0000000) {
4130 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
4131                         }
4132  #endif
4133  
4134 +#ifdef CONFIG_PAX_PAGEEXEC
4135 +/*
4136 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
4137 + *
4138 + * returns 1 when task should be killed
4139 + *         2 when rt_sigreturn trampoline was detected
4140 + *         3 when unpatched PLT trampoline was detected
4141 + */
4142 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4143 +{
4144 +
4145 +#ifdef CONFIG_PAX_EMUPLT
4146 +       int err;
4147 +
4148 +       do { /* PaX: unpatched PLT emulation */
4149 +               unsigned int bl, depwi;
4150 +
4151 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
4152 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
4153 +
4154 +               if (err)
4155 +                       break;
4156 +
4157 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
4158 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
4159 +
4160 +                       err = get_user(ldw, (unsigned int*)addr);
4161 +                       err |= get_user(bv, (unsigned int*)(addr+4));
4162 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
4163 +
4164 +                       if (err)
4165 +                               break;
4166 +
4167 +                       if (ldw == 0x0E801096U &&
4168 +                           bv == 0xEAC0C000U &&
4169 +                           ldw2 == 0x0E881095U)
4170 +                       {
4171 +                               unsigned int resolver, map;
4172 +
4173 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
4174 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
4175 +                               if (err)
4176 +                                       break;
4177 +
4178 +                               regs->gr[20] = instruction_pointer(regs)+8;
4179 +                               regs->gr[21] = map;
4180 +                               regs->gr[22] = resolver;
4181 +                               regs->iaoq[0] = resolver | 3UL;
4182 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
4183 +                               return 3;
4184 +                       }
4185 +               }
4186 +       } while (0);
4187 +#endif
4188 +
4189 +#ifdef CONFIG_PAX_EMUTRAMP
4190 +
4191 +#ifndef CONFIG_PAX_EMUSIGRT
4192 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
4193 +               return 1;
4194 +#endif
4195 +
4196 +       do { /* PaX: rt_sigreturn emulation */
4197 +               unsigned int ldi1, ldi2, bel, nop;
4198 +
4199 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
4200 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
4201 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
4202 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
4203 +
4204 +               if (err)
4205 +                       break;
4206 +
4207 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
4208 +                   ldi2 == 0x3414015AU &&
4209 +                   bel == 0xE4008200U &&
4210 +                   nop == 0x08000240U)
4211 +               {
4212 +                       regs->gr[25] = (ldi1 & 2) >> 1;
4213 +                       regs->gr[20] = __NR_rt_sigreturn;
4214 +                       regs->gr[31] = regs->iaoq[1] + 16;
4215 +                       regs->sr[0] = regs->iasq[1];
4216 +                       regs->iaoq[0] = 0x100UL;
4217 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
4218 +                       regs->iasq[0] = regs->sr[2];
4219 +                       regs->iasq[1] = regs->sr[2];
4220 +                       return 2;
4221 +               }
4222 +       } while (0);
4223 +#endif
4224 +
4225 +       return 1;
4226 +}
4227 +
4228 +void pax_report_insns(void *pc, void *sp)
4229 +{
4230 +       unsigned long i;
4231 +
4232 +       printk(KERN_ERR "PAX: bytes at PC: ");
4233 +       for (i = 0; i < 5; i++) {
4234 +               unsigned int c;
4235 +               if (get_user(c, (unsigned int*)pc+i))
4236 +                       printk("???????? ");
4237 +               else
4238 +                       printk("%08x ", c);
4239 +       }
4240 +       printk("\n");
4241 +}
4242 +#endif
4243 +
4244  void do_page_fault(struct pt_regs *regs, unsigned long code,
4245                               unsigned long address)
4246  {
4247 @@ -168,8 +280,33 @@ good_area:
4248  
4249         acc_type = parisc_acctyp(code,regs->iir);
4250  
4251 -       if ((vma->vm_flags & acc_type) != acc_type)
4252 +       if ((vma->vm_flags & acc_type) != acc_type) {
4253 +
4254 +#ifdef CONFIG_PAX_PAGEEXEC
4255 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
4256 +                   (address & ~3UL) == instruction_pointer(regs))
4257 +               {
4258 +                       up_read(&mm->mmap_sem);
4259 +                       switch(pax_handle_fetch_fault(regs)) {
4260 +
4261 +#ifdef CONFIG_PAX_EMUPLT
4262 +                       case 3:
4263 +                               return;
4264 +#endif
4265 +
4266 +#ifdef CONFIG_PAX_EMUTRAMP
4267 +                       case 2:
4268 +                               return;
4269 +#endif
4270 +
4271 +                       }
4272 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
4273 +                       do_exit(SIGKILL);
4274 +               }
4275 +#endif
4276 +
4277                 goto bad_area;
4278 +       }
4279  
4280         /*
4281          * If for any reason at all we couldn't handle the fault, make
4282 diff -urNp linux-2.6.16.12/arch/powerpc/mm/fault.c linux-2.6.16.12/arch/powerpc/mm/fault.c
4283 --- linux-2.6.16.12/arch/powerpc/mm/fault.c     2006-05-01 15:14:26.000000000 -0400
4284 +++ linux-2.6.16.12/arch/powerpc/mm/fault.c     2006-05-01 20:17:33.000000000 -0400
4285 @@ -31,6 +31,7 @@
4286  #include <linux/highmem.h>
4287  #include <linux/module.h>
4288  #include <linux/kprobes.h>
4289 +#include <linux/binfmts.h>
4290  
4291  #include <asm/page.h>
4292  #include <asm/pgtable.h>
4293 @@ -105,6 +106,38 @@ static void do_dabr(struct pt_regs *regs
4294  }
4295  #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
4296  
4297 +#ifdef CONFIG_PAX_PAGEEXEC
4298 +/*
4299 + * PaX: decide what to do with offenders (regs->nip = fault address)
4300 + *
4301 + * returns 1 when task should be killed
4302 + */
4303 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4304 +{
4305 +
4306 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
4307 +       int err;
4308 +#endif
4309 +
4310 +       return 1;
4311 +}
4312 +
4313 +void pax_report_insns(void *pc, void *sp)
4314 +{
4315 +       unsigned long i;
4316 +
4317 +       printk(KERN_ERR "PAX: bytes at PC: ");
4318 +       for (i = 0; i < 5; i++) {
4319 +               unsigned int c;
4320 +               if (get_user(c, (unsigned int*)pc+i))
4321 +                       printk("???????? ");
4322 +               else
4323 +                       printk("%08x ", c);
4324 +       }
4325 +       printk("\n");
4326 +}
4327 +#endif
4328 +
4329  /*
4330   * For 600- and 800-family processors, the error_code parameter is DSISR
4331   * for a data fault, SRR1 for an instruction fault. For 400-family processors
4332 @@ -333,6 +366,19 @@ bad_area:
4333  bad_area_nosemaphore:
4334         /* User mode accesses cause a SIGSEGV */
4335         if (user_mode(regs)) {
4336 +
4337 +#ifdef CONFIG_PAX_PAGEEXEC
4338 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
4339 +                       if (is_exec && (error_code & DSISR_PROTFAULT)) {
4340 +                               switch (pax_handle_fetch_fault(regs)) {
4341 +                               }
4342 +
4343 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
4344 +                               do_exit(SIGKILL);
4345 +                       }
4346 +               }
4347 +#endif
4348 +
4349                 _exception(SIGSEGV, regs, code, address);
4350                 return 0;
4351         }
4352 diff -urNp linux-2.6.16.12/arch/powerpc/mm/mmap.c linux-2.6.16.12/arch/powerpc/mm/mmap.c
4353 --- linux-2.6.16.12/arch/powerpc/mm/mmap.c      2006-05-01 15:14:26.000000000 -0400
4354 +++ linux-2.6.16.12/arch/powerpc/mm/mmap.c      2006-05-01 20:17:33.000000000 -0400
4355 @@ -76,10 +76,22 @@ void arch_pick_mmap_layout(struct mm_str
4356          */
4357         if (mmap_is_legacy()) {
4358                 mm->mmap_base = TASK_UNMAPPED_BASE;
4359 +
4360 +#ifdef CONFIG_PAX_RANDMMAP
4361 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
4362 +                       mm->mmap_base += mm->delta_mmap;
4363 +#endif
4364 +
4365                 mm->get_unmapped_area = arch_get_unmapped_area;
4366                 mm->unmap_area = arch_unmap_area;
4367         } else {
4368                 mm->mmap_base = mmap_base();
4369 +
4370 +#ifdef CONFIG_PAX_RANDMMAP
4371 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
4372 +                       mm->mmap_base -= mm->delta_mmap;
4373 +#endif
4374 +
4375                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4376                 mm->unmap_area = arch_unmap_area_topdown;
4377         }
4378 diff -urNp linux-2.6.16.12/arch/ppc/kernel/module.c linux-2.6.16.12/arch/ppc/kernel/module.c
4379 --- linux-2.6.16.12/arch/ppc/kernel/module.c    2006-05-01 15:14:26.000000000 -0400
4380 +++ linux-2.6.16.12/arch/ppc/kernel/module.c    2006-05-01 20:17:33.000000000 -0400
4381 @@ -164,8 +164,8 @@ static uint32_t do_plt_call(void *locati
4382  
4383         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
4384         /* Init, or core PLT? */
4385 -       if (location >= mod->module_core
4386 -           && location < mod->module_core + mod->core_size)
4387 +       if (location >= mod->module_core_rx
4388 +           && location < mod->module_core_rx + mod->core_size_rx)
4389                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
4390         else
4391                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
4392 diff -urNp linux-2.6.16.12/arch/ppc/mm/fault.c linux-2.6.16.12/arch/ppc/mm/fault.c
4393 --- linux-2.6.16.12/arch/ppc/mm/fault.c 2006-05-01 15:14:26.000000000 -0400
4394 +++ linux-2.6.16.12/arch/ppc/mm/fault.c 2006-05-01 20:17:33.000000000 -0400
4395 @@ -28,6 +28,11 @@
4396  #include <linux/interrupt.h>
4397  #include <linux/highmem.h>
4398  #include <linux/module.h>
4399 +#include <linux/slab.h>
4400 +#include <linux/pagemap.h>
4401 +#include <linux/compiler.h>
4402 +#include <linux/binfmts.h>
4403 +#include <linux/unistd.h>
4404  
4405  #include <asm/page.h>
4406  #include <asm/pgtable.h>
4407 @@ -51,6 +56,364 @@ unsigned long pte_misses;   /* updated by 
4408  unsigned long pte_errors;      /* updated by do_page_fault() */
4409  unsigned int probingmem;
4410  
4411 +#ifdef CONFIG_PAX_EMUSIGRT
4412 +void pax_syscall_close(struct vm_area_struct * vma)
4413 +{
4414 +       vma->vm_mm->call_syscall = 0UL;
4415 +}
4416 +
4417 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
4418 +{
4419 +       struct page* page;
4420 +       unsigned int *kaddr;
4421 +
4422 +       page = alloc_page(GFP_HIGHUSER);
4423 +       if (!page)
4424 +               return NOPAGE_OOM;
4425 +
4426 +       kaddr = kmap(page);
4427 +       memset(kaddr, 0, PAGE_SIZE);
4428 +       kaddr[0] = 0x44000002U; /* sc */
4429 +       __flush_dcache_icache(kaddr);
4430 +       kunmap(page);
4431 +       if (type)
4432 +               *type = VM_FAULT_MAJOR;
4433 +       return page;
4434 +}
4435 +
4436 +static struct vm_operations_struct pax_vm_ops = {
4437 +       .close = pax_syscall_close,
4438 +       .nopage = pax_syscall_nopage,
4439 +};
4440 +
4441 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4442 +{
4443 +       int ret;
4444 +
4445 +       memset(vma, 0, sizeof(*vma));
4446 +       vma->vm_mm = current->mm;
4447 +       vma->vm_start = addr;
4448 +       vma->vm_end = addr + PAGE_SIZE;
4449 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4450 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
4451 +       vma->vm_ops = &pax_vm_ops;
4452 +
4453 +       ret = insert_vm_struct(current->mm, vma);
4454 +       if (ret)
4455 +               return ret;
4456 +
4457 +       ++current->mm->total_vm;
4458 +       return 0;
4459 +}
4460 +#endif
4461 +
4462 +#ifdef CONFIG_PAX_PAGEEXEC
4463 +/*
4464 + * PaX: decide what to do with offenders (regs->nip = fault address)
4465 + *
4466 + * returns 1 when task should be killed
4467 + *         2 when patched GOT trampoline was detected
4468 + *         3 when patched PLT trampoline was detected
4469 + *         4 when unpatched PLT trampoline was detected
4470 + *         5 when sigreturn trampoline was detected
4471 + *         7 when rt_sigreturn trampoline was detected
4472 + */
4473 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4474 +{
4475 +
4476 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
4477 +       int err;
4478 +#endif
4479 +
4480 +#ifdef CONFIG_PAX_EMUPLT
4481 +       do { /* PaX: patched GOT emulation */
4482 +               unsigned int blrl;
4483 +
4484 +               err = get_user(blrl, (unsigned int*)regs->nip);
4485 +
4486 +               if (!err && blrl == 0x4E800021U) {
4487 +                       unsigned long temp = regs->nip;
4488 +
4489 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
4490 +                       regs->link = temp + 4UL;
4491 +                       return 2;
4492 +               }
4493 +       } while (0);
4494 +
4495 +       do { /* PaX: patched PLT emulation #1 */
4496 +               unsigned int b;
4497 +
4498 +               err = get_user(b, (unsigned int *)regs->nip);
4499 +
4500 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
4501 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
4502 +                       return 3;
4503 +               }
4504 +       } while (0);
4505 +
4506 +       do { /* PaX: unpatched PLT emulation #1 */
4507 +               unsigned int li, b;
4508 +
4509 +               err = get_user(li, (unsigned int *)regs->nip);
4510 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
4511 +
4512 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
4513 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
4514 +                       unsigned long addr = b | 0xFC000000UL;
4515 +
4516 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
4517 +                       err = get_user(rlwinm, (unsigned int*)addr);
4518 +                       err |= get_user(add, (unsigned int*)(addr+4));
4519 +                       err |= get_user(li2, (unsigned int*)(addr+8));
4520 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
4521 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
4522 +                       err |= get_user(li3, (unsigned int*)(addr+20));
4523 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
4524 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
4525 +
4526 +                       if (err)
4527 +                               break;
4528 +
4529 +                       if (rlwinm == 0x556C083CU &&
4530 +                           add == 0x7D6C5A14U &&
4531 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
4532 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
4533 +                           mtctr == 0x7D8903A6U &&
4534 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
4535 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
4536 +                           bctr == 0x4E800420U)
4537 +                       {
4538 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4539 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4540 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
4541 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4542 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
4543 +                               regs->nip = regs->ctr;
4544 +                               return 4;
4545 +                       }
4546 +               }
4547 +       } while (0);
4548 +
4549 +#if 0
4550 +       do { /* PaX: unpatched PLT emulation #2 */
4551 +               unsigned int lis, lwzu, b, bctr;
4552 +
4553 +               err = get_user(lis, (unsigned int *)regs->nip);
4554 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
4555 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
4556 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
4557 +
4558 +               if (err)
4559 +                       break;
4560 +
4561 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
4562 +                   (lwzu & 0xU) == 0xU &&
4563 +                   (b & 0xFC000003U) == 0x48000000U &&
4564 +                   bctr == 0x4E800420U)
4565 +               {
4566 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
4567 +                       unsigned long addr = b | 0xFC000000UL;
4568 +
4569 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
4570 +                       err = get_user(addis, (unsigned int*)addr);
4571 +                       err |= get_user(addi, (unsigned int*)(addr+4));
4572 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
4573 +                       err |= get_user(add, (unsigned int*)(addr+12));
4574 +                       err |= get_user(li2, (unsigned int*)(addr+16));
4575 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
4576 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
4577 +                       err |= get_user(li3, (unsigned int*)(addr+28));
4578 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
4579 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
4580 +
4581 +                       if (err)
4582 +                               break;
4583 +
4584 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
4585 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
4586 +                           rlwinm == 0x556C083CU &&
4587 +                           add == 0x7D6C5A14U &&
4588 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
4589 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
4590 +                           mtctr == 0x7D8903A6U &&
4591 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
4592 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
4593 +                           bctr == 0x4E800420U)
4594 +                       {
4595 +                               regs->gpr[PT_R11] = 
4596 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4597 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4598 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
4599 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4600 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
4601 +                               regs->nip = regs->ctr;
4602 +                               return 4;
4603 +                       }
4604 +               }
4605 +       } while (0);
4606 +#endif
4607 +
4608 +       do { /* PaX: unpatched PLT emulation #3 */
4609 +               unsigned int li, b;
4610 +
4611 +               err = get_user(li, (unsigned int *)regs->nip);
4612 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
4613 +
4614 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
4615 +                       unsigned int addis, lwz, mtctr, bctr;
4616 +                       unsigned long addr = b | 0xFC000000UL;
4617 +
4618 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
4619 +                       err = get_user(addis, (unsigned int*)addr);
4620 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
4621 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
4622 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
4623 +
4624 +                       if (err)
4625 +                               break;
4626 +
4627 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
4628 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
4629 +                           mtctr == 0x7D6903A6U &&
4630 +                           bctr == 0x4E800420U)
4631 +                       {
4632 +                               unsigned int r11;
4633 +
4634 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4635 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4636 +
4637 +                               err = get_user(r11, (unsigned int*)addr);
4638 +                               if (err)
4639 +                                       break;
4640 +
4641 +                               regs->gpr[PT_R11] = r11;
4642 +                               regs->ctr = r11;
4643 +                               regs->nip = r11;
4644 +                               return 4;
4645 +                       }
4646 +               }
4647 +       } while (0);
4648 +#endif
4649 +
4650 +#ifdef CONFIG_PAX_EMUSIGRT
4651 +       do { /* PaX: sigreturn emulation */
4652 +               unsigned int li, sc;
4653 +
4654 +               err = get_user(li, (unsigned int *)regs->nip);
4655 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
4656 +
4657 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
4658 +                       struct vm_area_struct *vma;
4659 +                       unsigned long call_syscall;
4660 +
4661 +                       down_read(&current->mm->mmap_sem);
4662 +                       call_syscall = current->mm->call_syscall;
4663 +                       up_read(&current->mm->mmap_sem);
4664 +                       if (likely(call_syscall))
4665 +                               goto emulate;
4666 +
4667 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4668 +
4669 +                       down_write(&current->mm->mmap_sem);
4670 +                       if (current->mm->call_syscall) {
4671 +                               call_syscall = current->mm->call_syscall;
4672 +                               up_write(&current->mm->mmap_sem);
4673 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
4674 +                               goto emulate;
4675 +                       }
4676 +
4677 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4678 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
4679 +                               up_write(&current->mm->mmap_sem);
4680 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
4681 +                               return 1;
4682 +                       }
4683 +
4684 +                       if (pax_insert_vma(vma, call_syscall)) {
4685 +                               up_write(&current->mm->mmap_sem);
4686 +                               kmem_cache_free(vm_area_cachep, vma);
4687 +                               return 1;
4688 +                       }
4689 +
4690 +                       current->mm->call_syscall = call_syscall;
4691 +                       up_write(&current->mm->mmap_sem);
4692 +
4693 +emulate:
4694 +                       regs->gpr[PT_R0] = __NR_sigreturn;
4695 +                       regs->nip = call_syscall;
4696 +                       return 5;
4697 +               }
4698 +       } while (0);
4699 +
4700 +       do { /* PaX: rt_sigreturn emulation */
4701 +               unsigned int li, sc;
4702 +
4703 +               err = get_user(li, (unsigned int *)regs->nip);
4704 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
4705 +
4706 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
4707 +                       struct vm_area_struct *vma;
4708 +                       unsigned int call_syscall;
4709 +
4710 +                       down_read(&current->mm->mmap_sem);
4711 +                       call_syscall = current->mm->call_syscall;
4712 +                       up_read(&current->mm->mmap_sem);
4713 +                       if (likely(call_syscall))
4714 +                               goto rt_emulate;
4715 +
4716 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4717 +
4718 +                       down_write(&current->mm->mmap_sem);
4719 +                       if (current->mm->call_syscall) {
4720 +                               call_syscall = current->mm->call_syscall;
4721 +                               up_write(&current->mm->mmap_sem);
4722 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
4723 +                               goto rt_emulate;
4724 +                       }
4725 +
4726 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4727 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
4728 +                               up_write(&current->mm->mmap_sem);
4729 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
4730 +                               return 1;
4731 +                       }
4732 +
4733 +                       if (pax_insert_vma(vma, call_syscall)) {
4734 +                               up_write(&current->mm->mmap_sem);
4735 +                               kmem_cache_free(vm_area_cachep, vma);
4736 +                               return 1;
4737 +                       }
4738 +
4739 +                       current->mm->call_syscall = call_syscall;
4740 +                       up_write(&current->mm->mmap_sem);
4741 +
4742 +rt_emulate:
4743 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
4744 +                       regs->nip = call_syscall;
4745 +                       return 6;
4746 +               }
4747 +       } while (0);
4748 +#endif
4749 +
4750 +       return 1;
4751 +}
4752 +
4753 +void pax_report_insns(void *pc, void *sp)
4754 +{
4755 +       unsigned long i;
4756 +
4757 +       printk(KERN_ERR "PAX: bytes at PC: ");
4758 +       for (i = 0; i < 5; i++) {
4759 +               unsigned int c;
4760 +               if (get_user(c, (unsigned int*)pc+i))
4761 +                       printk("???????? ");
4762 +               else
4763 +                       printk("%08x ", c);
4764 +       }
4765 +       printk("\n");
4766 +}
4767 +#endif
4768 +
4769  /*
4770   * Check whether the instruction at regs->nip is a store using
4771   * an update addressing form which will update r1.
4772 @@ -111,7 +474,7 @@ int do_page_fault(struct pt_regs *regs, 
4773          * indicate errors in DSISR but can validly be set in SRR1.
4774          */
4775         if (TRAP(regs) == 0x400)
4776 -               error_code &= 0x48200000;
4777 +               error_code &= 0x58200000;
4778         else
4779                 is_write = error_code & 0x02000000;
4780  #endif /* CONFIG_4xx || CONFIG_BOOKE */
4781 @@ -205,15 +568,14 @@ good_area:
4782         } else if (TRAP(regs) == 0x400) {
4783                 pte_t *ptep;
4784  
4785 -#if 0
4786 +#if 1
4787                 /* It would be nice to actually enforce the VM execute
4788                    permission on CPUs which can do so, but far too
4789                    much stuff in userspace doesn't get the permissions
4790                    right, so we let any page be executed for now. */
4791                 if (! (vma->vm_flags & VM_EXEC))
4792                         goto bad_area;
4793 -#endif
4794 -
4795 +#else
4796                 /* Since 4xx/Book-E supports per-page execute permission,
4797                  * we lazily flush dcache to icache. */
4798                 ptep = NULL;
4799 @@ -233,6 +595,7 @@ good_area:
4800                 if (ptep != NULL)
4801                         pte_unmap(ptep);
4802  #endif
4803 +#endif
4804         /* a read */
4805         } else {
4806                 /* protection fault */
4807 @@ -278,6 +641,33 @@ bad_area:
4808  
4809         /* User mode accesses cause a SIGSEGV */
4810         if (user_mode(regs)) {
4811 +
4812 +#ifdef CONFIG_PAX_PAGEEXEC
4813 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
4814 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
4815 +                               switch (pax_handle_fetch_fault(regs)) {
4816 +
4817 +#ifdef CONFIG_PAX_EMUPLT
4818 +                               case 2:
4819 +                               case 3:
4820 +                               case 4:
4821 +                                       return 0;
4822 +#endif
4823 +
4824 +#ifdef CONFIG_PAX_EMUSIGRT
4825 +                               case 5:
4826 +                               case 6:
4827 +                                       return 0;
4828 +#endif
4829 +
4830 +                               }
4831 +
4832 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
4833 +                               do_exit(SIGKILL);
4834 +                       }
4835 +               }
4836 +#endif
4837 +
4838                 _exception(SIGSEGV, regs, code, address);
4839                 return 0;
4840         }
4841 diff -urNp linux-2.6.16.12/arch/s390/kernel/module.c linux-2.6.16.12/arch/s390/kernel/module.c
4842 --- linux-2.6.16.12/arch/s390/kernel/module.c   2006-05-01 15:14:26.000000000 -0400
4843 +++ linux-2.6.16.12/arch/s390/kernel/module.c   2006-05-01 20:17:33.000000000 -0400
4844 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
4845  
4846         /* Increase core size by size of got & plt and set start
4847            offsets for got and plt. */
4848 -       me->core_size = ALIGN(me->core_size, 4);
4849 -       me->arch.got_offset = me->core_size;
4850 -       me->core_size += me->arch.got_size;
4851 -       me->arch.plt_offset = me->core_size;
4852 -       me->core_size += me->arch.plt_size;
4853 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
4854 +       me->arch.got_offset = me->core_size_rw;
4855 +       me->core_size_rw += me->arch.got_size;
4856 +       me->arch.plt_offset = me->core_size_rx;
4857 +       me->core_size_rx += me->arch.plt_size;
4858         return 0;
4859  }
4860  
4861 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4862                 if (info->got_initialized == 0) {
4863                         Elf_Addr *gotent;
4864  
4865 -                       gotent = me->module_core + me->arch.got_offset +
4866 +                       gotent = me->module_core_rw + me->arch.got_offset +
4867                                 info->got_offset;
4868                         *gotent = val;
4869                         info->got_initialized = 1;
4870 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4871                 else if (r_type == R_390_GOTENT ||
4872                          r_type == R_390_GOTPLTENT)
4873                         *(unsigned int *) loc =
4874 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
4875 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
4876                 else if (r_type == R_390_GOT64 ||
4877                          r_type == R_390_GOTPLT64)
4878                         *(unsigned long *) loc = val;
4879 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4880         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
4881                 if (info->plt_initialized == 0) {
4882                         unsigned int *ip;
4883 -                       ip = me->module_core + me->arch.plt_offset +
4884 +                       ip = me->module_core_rx + me->arch.plt_offset +
4885                                 info->plt_offset;
4886  #ifndef CONFIG_64BIT
4887                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
4888 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4889                         val = me->arch.plt_offset - me->arch.got_offset +
4890                                 info->plt_offset + rela->r_addend;
4891                 else
4892 -                       val =  (Elf_Addr) me->module_core +
4893 +                       val =  (Elf_Addr) me->module_core_rx +
4894                                 me->arch.plt_offset + info->plt_offset + 
4895                                 rela->r_addend - loc;
4896                 if (r_type == R_390_PLT16DBL)
4897 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4898         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
4899         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
4900                 val = val + rela->r_addend -
4901 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
4902 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
4903                 if (r_type == R_390_GOTOFF16)
4904                         *(unsigned short *) loc = val;
4905                 else if (r_type == R_390_GOTOFF32)
4906 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4907                 break;
4908         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
4909         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
4910 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
4911 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
4912                         rela->r_addend - loc;
4913                 if (r_type == R_390_GOTPC)
4914                         *(unsigned int *) loc = val;
4915 diff -urNp linux-2.6.16.12/arch/sparc/kernel/ptrace.c linux-2.6.16.12/arch/sparc/kernel/ptrace.c
4916 --- linux-2.6.16.12/arch/sparc/kernel/ptrace.c  2006-05-01 15:14:26.000000000 -0400
4917 +++ linux-2.6.16.12/arch/sparc/kernel/ptrace.c  2006-05-01 20:17:33.000000000 -0400
4918 @@ -19,6 +19,7 @@
4919  #include <linux/smp_lock.h>
4920  #include <linux/security.h>
4921  #include <linux/signal.h>
4922 +#include <linux/grsecurity.h>
4923  
4924  #include <asm/pgtable.h>
4925  #include <asm/system.h>
4926 @@ -304,6 +305,11 @@ asmlinkage void do_ptrace(struct pt_regs
4927                 goto out_tsk;
4928         }
4929  
4930 +       if (gr_handle_ptrace(child, request)) {
4931 +               pt_error_return(regs, EPERM);
4932 +               goto out_tsk;
4933 +       }
4934 +
4935         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
4936             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
4937                 if (ptrace_attach(child)) {
4938 diff -urNp linux-2.6.16.12/arch/sparc/kernel/sys_sparc.c linux-2.6.16.12/arch/sparc/kernel/sys_sparc.c
4939 --- linux-2.6.16.12/arch/sparc/kernel/sys_sparc.c       2006-05-01 15:14:26.000000000 -0400
4940 +++ linux-2.6.16.12/arch/sparc/kernel/sys_sparc.c       2006-05-01 20:17:33.000000000 -0400
4941 @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
4942         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
4943                 return -ENOMEM;
4944         if (!addr)
4945 -               addr = TASK_UNMAPPED_BASE;
4946 +               addr = current->mm->mmap_base;
4947  
4948         if (flags & MAP_SHARED)
4949                 addr = COLOUR_ALIGN(addr);
4950 diff -urNp linux-2.6.16.12/arch/sparc/Makefile linux-2.6.16.12/arch/sparc/Makefile
4951 --- linux-2.6.16.12/arch/sparc/Makefile 2006-05-01 15:14:26.000000000 -0400
4952 +++ linux-2.6.16.12/arch/sparc/Makefile 2006-05-01 20:17:33.000000000 -0400
4953 @@ -34,7 +34,7 @@ libs-y += arch/sparc/prom/ arch/sparc/li
4954  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
4955  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
4956  CORE_Y         := $(core-y)
4957 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
4958 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
4959  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
4960  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
4961  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
4962 diff -urNp linux-2.6.16.12/arch/sparc/mm/fault.c linux-2.6.16.12/arch/sparc/mm/fault.c
4963 --- linux-2.6.16.12/arch/sparc/mm/fault.c       2006-05-01 15:14:26.000000000 -0400
4964 +++ linux-2.6.16.12/arch/sparc/mm/fault.c       2006-05-01 20:17:33.000000000 -0400
4965 @@ -21,6 +21,10 @@
4966  #include <linux/smp_lock.h>
4967  #include <linux/interrupt.h>
4968  #include <linux/module.h>
4969 +#include <linux/slab.h>
4970 +#include <linux/pagemap.h>
4971 +#include <linux/compiler.h>
4972 +#include <linux/binfmts.h>
4973  
4974  #include <asm/system.h>
4975  #include <asm/page.h>
4976 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
4977         return safe_compute_effective_address(regs, insn);
4978  }
4979  
4980 +#ifdef CONFIG_PAX_PAGEEXEC
4981 +void pax_emuplt_close(struct vm_area_struct * vma)
4982 +{
4983 +       vma->vm_mm->call_dl_resolve = 0UL;
4984 +}
4985 +
4986 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
4987 +{
4988 +       struct page* page;
4989 +       unsigned int *kaddr;
4990 +
4991 +       page = alloc_page(GFP_HIGHUSER);
4992 +       if (!page)
4993 +               return NOPAGE_OOM;
4994 +
4995 +       kaddr = kmap(page);
4996 +       memset(kaddr, 0, PAGE_SIZE);
4997 +       kaddr[0] = 0x9DE3BFA8U; /* save */
4998 +       flush_dcache_page(page);
4999 +       kunmap(page);
5000 +       if (type)
5001 +               *type = VM_FAULT_MAJOR;
5002 +
5003 +       return page;
5004 +}
5005 +
5006 +static struct vm_operations_struct pax_vm_ops = {
5007 +       .close = pax_emuplt_close,
5008 +       .nopage = pax_emuplt_nopage,
5009 +};
5010 +
5011 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
5012 +{
5013 +       int ret;
5014 +
5015 +       memset(vma, 0, sizeof(*vma));
5016 +       vma->vm_mm = current->mm;
5017 +       vma->vm_start = addr;
5018 +       vma->vm_end = addr + PAGE_SIZE;
5019 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
5020 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
5021 +       vma->vm_ops = &pax_vm_ops;
5022 +
5023 +       ret = insert_vm_struct(current->mm, vma);
5024 +       if (ret)
5025 +               return ret;
5026 +
5027 +       ++current->mm->total_vm;
5028 +       return 0;
5029 +}
5030 +
5031 +/*
5032 + * PaX: decide what to do with offenders (regs->pc = fault address)
5033 + *
5034 + * returns 1 when task should be killed
5035 + *         2 when patched PLT trampoline was detected
5036 + *         3 when unpatched PLT trampoline was detected
5037 + */
5038 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5039 +{
5040 +
5041 +#ifdef CONFIG_PAX_EMUPLT
5042 +       int err;
5043 +
5044 +       do { /* PaX: patched PLT emulation #1 */
5045 +               unsigned int sethi1, sethi2, jmpl;
5046 +
5047 +               err = get_user(sethi1, (unsigned int*)regs->pc);
5048 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
5049 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
5050 +
5051 +               if (err)
5052 +                       break;
5053 +
5054 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5055 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
5056 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
5057 +               {
5058 +                       unsigned int addr;
5059 +
5060 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
5061 +                       addr = regs->u_regs[UREG_G1];
5062 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
5063 +                       regs->pc = addr;
5064 +                       regs->npc = addr+4;
5065 +                       return 2;
5066 +               }
5067 +       } while (0);
5068 +
5069 +       { /* PaX: patched PLT emulation #2 */
5070 +               unsigned int ba;
5071 +
5072 +               err = get_user(ba, (unsigned int*)regs->pc);
5073 +
5074 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
5075 +                       unsigned int addr;
5076 +
5077 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
5078 +                       regs->pc = addr;
5079 +                       regs->npc = addr+4;
5080 +                       return 2;
5081 +               }
5082 +       }
5083 +
5084 +       do { /* PaX: patched PLT emulation #3 */
5085 +               unsigned int sethi, jmpl, nop;
5086 +
5087 +               err = get_user(sethi, (unsigned int*)regs->pc);
5088 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
5089 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
5090 +
5091 +               if (err)
5092 +                       break;
5093 +
5094 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5095 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
5096 +                   nop == 0x01000000U)
5097 +               {
5098 +                       unsigned int addr;
5099 +
5100 +                       addr = (sethi & 0x003FFFFFU) << 10;
5101 +                       regs->u_regs[UREG_G1] = addr;
5102 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
5103 +                       regs->pc = addr;
5104 +                       regs->npc = addr+4;
5105 +                       return 2;
5106 +               }
5107 +       } while (0);
5108 +
5109 +       do { /* PaX: unpatched PLT emulation step 1 */
5110 +               unsigned int sethi, ba, nop;
5111 +
5112 +               err = get_user(sethi, (unsigned int*)regs->pc);
5113 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
5114 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
5115 +
5116 +               if (err)
5117 +                       break;
5118 +
5119 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5120 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
5121 +                   nop == 0x01000000U)
5122 +               {
5123 +                       unsigned int addr, save, call;
5124 +
5125 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
5126 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
5127 +                       else
5128 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
5129 +
5130 +                       err = get_user(save, (unsigned int*)addr);
5131 +                       err |= get_user(call, (unsigned int*)(addr+4));
5132 +                       err |= get_user(nop, (unsigned int*)(addr+8));
5133 +                       if (err)
5134 +                               break;
5135 +
5136 +                       if (save == 0x9DE3BFA8U &&
5137 +                           (call & 0xC0000000U) == 0x40000000U &&
5138 +                           nop == 0x01000000U)
5139 +                       {
5140 +                               struct vm_area_struct *vma;
5141 +                               unsigned long call_dl_resolve;
5142 +
5143 +                               down_read(&current->mm->mmap_sem);
5144 +                               call_dl_resolve = current->mm->call_dl_resolve;
5145 +                               up_read(&current->mm->mmap_sem);
5146 +                               if (likely(call_dl_resolve))
5147 +                                       goto emulate;
5148 +
5149 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5150 +
5151 +                               down_write(&current->mm->mmap_sem);
5152 +                               if (current->mm->call_dl_resolve) {
5153 +                                       call_dl_resolve = current->mm->call_dl_resolve;
5154 +                                       up_write(&current->mm->mmap_sem);
5155 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
5156 +                                       goto emulate;
5157 +                               }
5158 +
5159 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5160 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
5161 +                                       up_write(&current->mm->mmap_sem);
5162 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
5163 +                                       return 1;
5164 +                               }
5165 +
5166 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
5167 +                                       up_write(&current->mm->mmap_sem);
5168 +                                       kmem_cache_free(vm_area_cachep, vma);
5169 +                                       return 1;
5170 +                               }
5171 +
5172 +                               current->mm->call_dl_resolve = call_dl_resolve;
5173 +                               up_write(&current->mm->mmap_sem);
5174 +
5175 +emulate:
5176 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5177 +                               regs->pc = call_dl_resolve;
5178 +                               regs->npc = addr+4;
5179 +                               return 3;
5180 +                       }
5181 +               }
5182 +       } while (0);
5183 +
5184 +       do { /* PaX: unpatched PLT emulation step 2 */
5185 +               unsigned int save, call, nop;
5186 +
5187 +               err = get_user(save, (unsigned int*)(regs->pc-4));
5188 +               err |= get_user(call, (unsigned int*)regs->pc);
5189 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
5190 +               if (err)
5191 +                       break;
5192 +
5193 +               if (save == 0x9DE3BFA8U &&
5194 +                   (call & 0xC0000000U) == 0x40000000U &&
5195 +                   nop == 0x01000000U)
5196 +               {
5197 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
5198 +
5199 +                       regs->u_regs[UREG_RETPC] = regs->pc;
5200 +                       regs->pc = dl_resolve;
5201 +                       regs->npc = dl_resolve+4;
5202 +                       return 3;
5203 +               }
5204 +       } while (0);
5205 +#endif
5206 +
5207 +       return 1;
5208 +}
5209 +
5210 +void pax_report_insns(void *pc, void *sp)
5211 +{
5212 +       unsigned long i;
5213 +
5214 +       printk(KERN_ERR "PAX: bytes at PC: ");
5215 +       for (i = 0; i < 5; i++) {
5216 +               unsigned int c;
5217 +               if (get_user(c, (unsigned int*)pc+i))
5218 +                       printk("???????? ");
5219 +               else
5220 +                       printk("%08x ", c);
5221 +       }
5222 +       printk("\n");
5223 +}
5224 +#endif
5225 +
5226  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
5227                                unsigned long address)
5228  {
5229 @@ -280,6 +530,24 @@ good_area:
5230                 if(!(vma->vm_flags & VM_WRITE))
5231                         goto bad_area;
5232         } else {
5233 +
5234 +#ifdef CONFIG_PAX_PAGEEXEC
5235 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
5236 +                       up_read(&mm->mmap_sem);
5237 +                       switch (pax_handle_fetch_fault(regs)) {
5238 +
5239 +#ifdef CONFIG_PAX_EMUPLT
5240 +                       case 2:
5241 +                       case 3:
5242 +                               return;
5243 +#endif
5244 +
5245 +                       }
5246 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
5247 +                       do_exit(SIGKILL);
5248 +               }
5249 +#endif
5250 +
5251                 /* Allow reads even for write-only mappings */
5252                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
5253                         goto bad_area;
5254 diff -urNp linux-2.6.16.12/arch/sparc/mm/init.c linux-2.6.16.12/arch/sparc/mm/init.c
5255 --- linux-2.6.16.12/arch/sparc/mm/init.c        2006-05-01 15:14:26.000000000 -0400
5256 +++ linux-2.6.16.12/arch/sparc/mm/init.c        2006-05-01 20:17:33.000000000 -0400
5257 @@ -333,17 +333,17 @@ void __init paging_init(void)
5258  
5259         /* Initialize the protection map with non-constant, MMU dependent values. */
5260         protection_map[0] = PAGE_NONE;
5261 -       protection_map[1] = PAGE_READONLY;
5262 -       protection_map[2] = PAGE_COPY;
5263 -       protection_map[3] = PAGE_COPY;
5264 +       protection_map[1] = PAGE_READONLY_NOEXEC;
5265 +       protection_map[2] = PAGE_COPY_NOEXEC;
5266 +       protection_map[3] = PAGE_COPY_NOEXEC;
5267         protection_map[4] = PAGE_READONLY;
5268         protection_map[5] = PAGE_READONLY;
5269         protection_map[6] = PAGE_COPY;
5270         protection_map[7] = PAGE_COPY;
5271         protection_map[8] = PAGE_NONE;
5272 -       protection_map[9] = PAGE_READONLY;
5273 -       protection_map[10] = PAGE_SHARED;
5274 -       protection_map[11] = PAGE_SHARED;
5275 +       protection_map[9] = PAGE_READONLY_NOEXEC;
5276 +       protection_map[10] = PAGE_SHARED_NOEXEC;
5277 +       protection_map[11] = PAGE_SHARED_NOEXEC;
5278         protection_map[12] = PAGE_READONLY;
5279         protection_map[13] = PAGE_READONLY;
5280         protection_map[14] = PAGE_SHARED;
5281 diff -urNp linux-2.6.16.12/arch/sparc/mm/srmmu.c linux-2.6.16.12/arch/sparc/mm/srmmu.c
5282 --- linux-2.6.16.12/arch/sparc/mm/srmmu.c       2006-05-01 15:14:26.000000000 -0400
5283 +++ linux-2.6.16.12/arch/sparc/mm/srmmu.c       2006-05-01 20:17:33.000000000 -0400
5284 @@ -2148,6 +2148,13 @@ void __init ld_mmu_srmmu(void)
5285         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
5286         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
5287         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
5288 +
5289 +#ifdef CONFIG_PAX_PAGEEXEC
5290 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
5291 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
5292 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
5293 +#endif
5294 +
5295         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
5296         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
5297         pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
5298 diff -urNp linux-2.6.16.12/arch/sparc64/kernel/ptrace.c linux-2.6.16.12/arch/sparc64/kernel/ptrace.c
5299 --- linux-2.6.16.12/arch/sparc64/kernel/ptrace.c        2006-05-01 15:14:26.000000000 -0400
5300 +++ linux-2.6.16.12/arch/sparc64/kernel/ptrace.c        2006-05-01 20:17:33.000000000 -0400
5301 @@ -22,6 +22,7 @@
5302  #include <linux/seccomp.h>
5303  #include <linux/audit.h>
5304  #include <linux/signal.h>
5305 +#include <linux/grsecurity.h>
5306  
5307  #include <asm/asi.h>
5308  #include <asm/pgtable.h>
5309 @@ -214,6 +215,11 @@ asmlinkage void do_ptrace(struct pt_regs
5310                 goto out_tsk;
5311         }
5312  
5313 +       if (gr_handle_ptrace(child, (long)request)) {
5314 +               pt_error_return(regs, EPERM);
5315 +               goto out_tsk;
5316 +       }
5317 +
5318         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
5319             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
5320                 if (ptrace_attach(child)) {
5321 diff -urNp linux-2.6.16.12/arch/sparc64/kernel/sys_sparc.c linux-2.6.16.12/arch/sparc64/kernel/sys_sparc.c
5322 --- linux-2.6.16.12/arch/sparc64/kernel/sys_sparc.c     2006-05-01 15:14:26.000000000 -0400
5323 +++ linux-2.6.16.12/arch/sparc64/kernel/sys_sparc.c     2006-05-01 20:17:33.000000000 -0400
5324 @@ -73,6 +73,10 @@ unsigned long arch_get_unmapped_area(str
5325         if (filp || (flags & MAP_SHARED))
5326                 do_color_align = 1;
5327  
5328 +#ifdef CONFIG_PAX_RANDMMAP
5329 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5330 +#endif
5331 +
5332         if (addr) {
5333                 if (do_color_align)
5334                         addr = COLOUR_ALIGN(addr, pgoff);
5335 @@ -87,7 +91,7 @@ unsigned long arch_get_unmapped_area(str
5336  
5337         if (len <= mm->cached_hole_size) {
5338                 mm->cached_hole_size = 0;
5339 -               mm->free_area_cache = TASK_UNMAPPED_BASE;
5340 +               mm->free_area_cache = mm->mmap_base;
5341         }
5342         start_addr = addr = mm->free_area_cache;
5343  
5344 @@ -106,8 +110,8 @@ full_search:
5345                         vma = find_vma(mm, PAGE_OFFSET);
5346                 }
5347                 if (task_size < addr) {
5348 -                       if (start_addr != TASK_UNMAPPED_BASE) {
5349 -                               start_addr = addr = TASK_UNMAPPED_BASE;
5350 +                       if (start_addr != mm->mmap_base) {
5351 +                               start_addr = addr = mm->mmap_base;
5352                                 mm->cached_hole_size = 0;
5353                                 goto full_search;
5354                         }
5355 diff -urNp linux-2.6.16.12/arch/sparc64/mm/fault.c linux-2.6.16.12/arch/sparc64/mm/fault.c
5356 --- linux-2.6.16.12/arch/sparc64/mm/fault.c     2006-05-01 15:14:26.000000000 -0400
5357 +++ linux-2.6.16.12/arch/sparc64/mm/fault.c     2006-05-01 20:17:33.000000000 -0400
5358 @@ -19,6 +19,10 @@
5359  #include <linux/init.h>
5360  #include <linux/interrupt.h>
5361  #include <linux/kprobes.h>
5362 +#include <linux/slab.h>
5363 +#include <linux/pagemap.h>
5364 +#include <linux/compiler.h>
5365 +#include <linux/binfmts.h>
5366  
5367  #include <asm/page.h>
5368  #include <asm/pgtable.h>
5369 @@ -251,6 +255,369 @@ cannot_handle:
5370         unhandled_fault (address, current, regs);
5371  }
5372  
5373 +#ifdef CONFIG_PAX_PAGEEXEC
5374 +#ifdef CONFIG_PAX_EMUPLT
5375 +static void pax_emuplt_close(struct vm_area_struct * vma)
5376 +{
5377 +       vma->vm_mm->call_dl_resolve = 0UL;
5378 +}
5379 +
5380 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
5381 +{
5382 +       struct page* page;
5383 +       unsigned int *kaddr;
5384 +
5385 +       page = alloc_page(GFP_HIGHUSER);
5386 +       if (!page)
5387 +               return NOPAGE_OOM;
5388 +
5389 +       kaddr = kmap(page);
5390 +       memset(kaddr, 0, PAGE_SIZE);
5391 +       kaddr[0] = 0x9DE3BFA8U; /* save */
5392 +       flush_dcache_page(page);
5393 +       kunmap(page);
5394 +       if (type)
5395 +               *type = VM_FAULT_MAJOR;
5396 +       return page;
5397 +}
5398 +
5399 +static struct vm_operations_struct pax_vm_ops = {
5400 +       .close = pax_emuplt_close,
5401 +       .nopage = pax_emuplt_nopage,
5402 +};
5403 +
5404 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
5405 +{
5406 +       int ret;
5407 +
5408 +       memset(vma, 0, sizeof(*vma));
5409 +       vma->vm_mm = current->mm;
5410 +       vma->vm_start = addr;
5411 +       vma->vm_end = addr + PAGE_SIZE;
5412 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
5413 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
5414 +       vma->vm_ops = &pax_vm_ops;
5415 +
5416 +       ret = insert_vm_struct(current->mm, vma);
5417 +       if (ret)
5418 +               return ret;
5419 +
5420 +       ++current->mm->total_vm;
5421 +       return 0;
5422 +}
5423 +#endif
5424 +
5425 +/*
5426 + * PaX: decide what to do with offenders (regs->tpc = fault address)
5427 + *
5428 + * returns 1 when task should be killed
5429 + *         2 when patched PLT trampoline was detected
5430 + *         3 when unpatched PLT trampoline was detected
5431 + */
5432 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5433 +{
5434 +
5435 +#ifdef CONFIG_PAX_EMUPLT
5436 +       int err;
5437 +
5438 +       do { /* PaX: patched PLT emulation #1 */
5439 +               unsigned int sethi1, sethi2, jmpl;
5440 +
5441 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
5442 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
5443 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
5444 +
5445 +               if (err)
5446 +                       break;
5447 +
5448 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5449 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
5450 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
5451 +               {
5452 +                       unsigned long addr;
5453 +
5454 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
5455 +                       addr = regs->u_regs[UREG_G1];
5456 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
5457 +                       regs->tpc = addr;
5458 +                       regs->tnpc = addr+4;
5459 +                       return 2;
5460 +               }
5461 +       } while (0);
5462 +
5463 +       { /* PaX: patched PLT emulation #2 */
5464 +               unsigned int ba;
5465 +
5466 +               err = get_user(ba, (unsigned int*)regs->tpc);
5467 +
5468 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
5469 +                       unsigned long addr;
5470 +
5471 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
5472 +                       regs->tpc = addr;
5473 +                       regs->tnpc = addr+4;
5474 +                       return 2;
5475 +               }
5476 +       }
5477 +
5478 +       do { /* PaX: patched PLT emulation #3 */
5479 +               unsigned int sethi, jmpl, nop;
5480 +
5481 +               err = get_user(sethi, (unsigned int*)regs->tpc);
5482 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
5483 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
5484 +
5485 +               if (err)
5486 +                       break;
5487 +
5488 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5489 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
5490 +                   nop == 0x01000000U)
5491 +               {
5492 +                       unsigned long addr;
5493 +
5494 +                       addr = (sethi & 0x003FFFFFU) << 10;
5495 +                       regs->u_regs[UREG_G1] = addr;
5496 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
5497 +                       regs->tpc = addr;
5498 +                       regs->tnpc = addr+4;
5499 +                       return 2;
5500 +               }
5501 +       } while (0);
5502 +
5503 +       do { /* PaX: patched PLT emulation #4 */
5504 +               unsigned int mov1, call, mov2;
5505 +
5506 +               err = get_user(mov1, (unsigned int*)regs->tpc);
5507 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
5508 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
5509 +
5510 +               if (err)
5511 +                       break;
5512 +
5513 +               if (mov1 == 0x8210000FU &&
5514 +                   (call & 0xC0000000U) == 0x40000000U &&
5515 +                   mov2 == 0x9E100001U)
5516 +               {
5517 +                       unsigned long addr;
5518 +
5519 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
5520 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5521 +                       regs->tpc = addr;
5522 +                       regs->tnpc = addr+4;
5523 +                       return 2;
5524 +               }
5525 +       } while (0);
5526 +
5527 +       do { /* PaX: patched PLT emulation #5 */
5528 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
5529 +
5530 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
5531 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
5532 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
5533 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
5534 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
5535 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
5536 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
5537 +
5538 +               if (err)
5539 +                       break;
5540 +
5541 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5542 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
5543 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
5544 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
5545 +                   sllx == 0x83287020 &&
5546 +                   jmpl == 0x81C04005U &&
5547 +                   nop == 0x01000000U)
5548 +               {
5549 +                       unsigned long addr;
5550 +
5551 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
5552 +                       regs->u_regs[UREG_G1] <<= 32;
5553 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
5554 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
5555 +                       regs->tpc = addr;
5556 +                       regs->tnpc = addr+4;
5557 +                       return 2;
5558 +               }
5559 +       } while (0);
5560 +
5561 +       do { /* PaX: patched PLT emulation #6 */
5562 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
5563 +
5564 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
5565 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
5566 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
5567 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
5568 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
5569 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
5570 +
5571 +               if (err)
5572 +                       break;
5573 +
5574 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5575 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
5576 +                   sllx == 0x83287020 &&
5577 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
5578 +                   jmpl == 0x81C04005U &&
5579 +                   nop == 0x01000000U)
5580 +               {
5581 +                       unsigned long addr;
5582 +
5583 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
5584 +                       regs->u_regs[UREG_G1] <<= 32;
5585 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
5586 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
5587 +                       regs->tpc = addr;
5588 +                       regs->tnpc = addr+4;
5589 +                       return 2;
5590 +               }
5591 +       } while (0);
5592 +
5593 +       do { /* PaX: patched PLT emulation #7 */
5594 +               unsigned int sethi, ba, nop;
5595 +
5596 +               err = get_user(sethi, (unsigned int*)regs->tpc);
5597 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
5598 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
5599 +
5600 +               if (err)
5601 +                       break;
5602 +
5603 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5604 +                   (ba & 0xFFF00000U) == 0x30600000U &&
5605 +                   nop == 0x01000000U)
5606 +               {
5607 +                       unsigned long addr;
5608 +
5609 +                       addr = (sethi & 0x003FFFFFU) << 10;
5610 +                       regs->u_regs[UREG_G1] = addr;
5611 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
5612 +                       regs->tpc = addr;
5613 +                       regs->tnpc = addr+4;
5614 +                       return 2;
5615 +               }
5616 +       } while (0);
5617 +
5618 +       do { /* PaX: unpatched PLT emulation step 1 */
5619 +               unsigned int sethi, ba, nop;
5620 +
5621 +               err = get_user(sethi, (unsigned int*)regs->tpc);
5622 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
5623 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
5624 +
5625 +               if (err)
5626 +                       break;
5627 +
5628 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5629 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
5630 +                   nop == 0x01000000U)
5631 +               {
5632 +                       unsigned long addr;
5633 +                       unsigned int save, call;
5634 +
5635 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
5636 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
5637 +                       else
5638 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
5639 +
5640 +                       err = get_user(save, (unsigned int*)addr);
5641 +                       err |= get_user(call, (unsigned int*)(addr+4));
5642 +                       err |= get_user(nop, (unsigned int*)(addr+8));
5643 +                       if (err)
5644 +                               break;
5645 +
5646 +                       if (save == 0x9DE3BFA8U &&
5647 +                           (call & 0xC0000000U) == 0x40000000U &&
5648 +                           nop == 0x01000000U)
5649 +                       {
5650 +                               struct vm_area_struct *vma;
5651 +                               unsigned long call_dl_resolve;
5652 +
5653 +                               down_read(&current->mm->mmap_sem);
5654 +                               call_dl_resolve = current->mm->call_dl_resolve;
5655 +                               up_read(&current->mm->mmap_sem);
5656 +                               if (likely(call_dl_resolve))
5657 +                                       goto emulate;
5658 +
5659 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5660 +
5661 +                               down_write(&current->mm->mmap_sem);
5662 +                               if (current->mm->call_dl_resolve) {
5663 +                                       call_dl_resolve = current->mm->call_dl_resolve;
5664 +                                       up_write(&current->mm->mmap_sem);
5665 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
5666 +                                       goto emulate;
5667 +                               }
5668 +
5669 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5670 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
5671 +                                       up_write(&current->mm->mmap_sem);
5672 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
5673 +                                       return 1;
5674 +                               }
5675 +
5676 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
5677 +                                       up_write(&current->mm->mmap_sem);
5678 +                                       kmem_cache_free(vm_area_cachep, vma);
5679 +                                       return 1;
5680 +                               }
5681 +
5682 +                               current->mm->call_dl_resolve = call_dl_resolve;
5683 +                               up_write(&current->mm->mmap_sem);
5684 +
5685 +emulate:
5686 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5687 +                               regs->tpc = call_dl_resolve;
5688 +                               regs->tnpc = addr+4;
5689 +                               return 3;
5690 +                       }
5691 +               }
5692 +       } while (0);
5693 +
5694 +       do { /* PaX: unpatched PLT emulation step 2 */
5695 +               unsigned int save, call, nop;
5696 +
5697 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
5698 +               err |= get_user(call, (unsigned int*)regs->tpc);
5699 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
5700 +               if (err)
5701 +                       break;
5702 +
5703 +               if (save == 0x9DE3BFA8U &&
5704 +                   (call & 0xC0000000U) == 0x40000000U &&
5705 +                   nop == 0x01000000U)
5706 +               {
5707 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5708 +
5709 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
5710 +                       regs->tpc = dl_resolve;
5711 +                       regs->tnpc = dl_resolve+4;
5712 +                       return 3;
5713 +               }
5714 +       } while (0);
5715 +#endif
5716 +
5717 +       return 1;
5718 +}
5719 +
5720 +void pax_report_insns(void *pc, void *sp)
5721 +{
5722 +       unsigned long i;
5723 +
5724 +       printk(KERN_ERR "PAX: bytes at PC: ");
5725 +       for (i = 0; i < 5; i++) {
5726 +               unsigned int c;
5727 +               if (get_user(c, (unsigned int*)pc+i))
5728 +                       printk("???????? ");
5729 +               else
5730 +                       printk("%08x ", c);
5731 +       }
5732 +       printk("\n");
5733 +}
5734 +#endif
5735 +
5736  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
5737  {
5738         struct mm_struct *mm = current->mm;
5739 @@ -293,8 +660,10 @@ asmlinkage void __kprobes do_sparc64_fau
5740                 goto intr_or_no_mm;
5741  
5742         if (test_thread_flag(TIF_32BIT)) {
5743 -               if (!(regs->tstate & TSTATE_PRIV))
5744 +               if (!(regs->tstate & TSTATE_PRIV)) {
5745                         regs->tpc &= 0xffffffff;
5746 +                       regs->tnpc &= 0xffffffff;
5747 +               }
5748                 address &= 0xffffffff;
5749         }
5750  
5751 @@ -311,6 +680,29 @@ asmlinkage void __kprobes do_sparc64_fau
5752         if (!vma)
5753                 goto bad_area;
5754  
5755 +#ifdef CONFIG_PAX_PAGEEXEC
5756 +       /* PaX: detect ITLB misses on non-exec pages */
5757 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
5758 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
5759 +       {
5760 +               if (address != regs->tpc)
5761 +                       goto good_area;
5762 +
5763 +               up_read(&mm->mmap_sem);
5764 +               switch (pax_handle_fetch_fault(regs)) {
5765 +
5766 +#ifdef CONFIG_PAX_EMUPLT
5767 +               case 2:
5768 +               case 3:
5769 +                       return;
5770 +#endif
5771 +
5772 +               }
5773 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
5774 +               do_exit(SIGKILL);
5775 +       }
5776 +#endif
5777 +
5778         /* Pure DTLB misses do not tell us whether the fault causing
5779          * load/store/atomic was a write or not, it only says that there
5780          * was no match.  So in such a case we (carefully) read the
5781 diff -urNp linux-2.6.16.12/arch/v850/kernel/module.c linux-2.6.16.12/arch/v850/kernel/module.c
5782 --- linux-2.6.16.12/arch/v850/kernel/module.c   2006-05-01 15:14:26.000000000 -0400
5783 +++ linux-2.6.16.12/arch/v850/kernel/module.c   2006-05-01 20:17:33.000000000 -0400
5784 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
5785         tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
5786  
5787         /* Init, or core PLT? */
5788 -       if (location >= mod->module_core
5789 -           && location < mod->module_core + mod->core_size)
5790 +       if (location >= mod->module_core_rx
5791 +           && location < mod->module_core_rx + mod->core_size_rx)
5792                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
5793         else
5794                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
5795 diff -urNp linux-2.6.16.12/arch/x86_64/boot/compressed/head.S linux-2.6.16.12/arch/x86_64/boot/compressed/head.S
5796 --- linux-2.6.16.12/arch/x86_64/boot/compressed/head.S  2006-05-01 15:14:26.000000000 -0400
5797 +++ linux-2.6.16.12/arch/x86_64/boot/compressed/head.S  2006-05-01 20:17:33.000000000 -0400
5798 @@ -41,11 +41,13 @@ startup_32:
5799         movl %eax,%gs
5800  
5801         lss stack_start,%esp
5802 +       movl 0x000000,%ecx
5803         xorl %eax,%eax
5804  1:     incl %eax               # check that A20 really IS enabled
5805         movl %eax,0x000000      # loop forever if it isn't
5806         cmpl %eax,0x100000
5807         je 1b
5808 +       movl %ecx,0x000000
5809  
5810  /*
5811   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
5812 diff -urNp linux-2.6.16.12/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.16.12/arch/x86_64/ia32/ia32_binfmt.c
5813 --- linux-2.6.16.12/arch/x86_64/ia32/ia32_binfmt.c      2006-05-01 15:14:26.000000000 -0400
5814 +++ linux-2.6.16.12/arch/x86_64/ia32/ia32_binfmt.c      2006-05-01 20:17:33.000000000 -0400
5815 @@ -186,6 +186,17 @@ struct elf_prpsinfo
5816  //#include <asm/ia32.h>
5817  #include <linux/elf.h>
5818  
5819 +#ifdef CONFIG_PAX_ASLR
5820 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
5821 +
5822 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5823 +#define PAX_DELTA_MMAP_LEN(tsk)                16
5824 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5825 +#define PAX_DELTA_EXEC_LEN(tsk)                16
5826 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5827 +#define PAX_DELTA_STACK_LEN(tsk)       16
5828 +#endif
5829 +
5830  typedef struct user_i387_ia32_struct elf_fpregset_t;
5831  typedef struct user32_fxsr_struct elf_fpxregset_t;
5832  
5833 diff -urNp linux-2.6.16.12/arch/x86_64/ia32/mmap32.c linux-2.6.16.12/arch/x86_64/ia32/mmap32.c
5834 --- linux-2.6.16.12/arch/x86_64/ia32/mmap32.c   2006-05-01 15:14:26.000000000 -0400
5835 +++ linux-2.6.16.12/arch/x86_64/ia32/mmap32.c   2006-05-01 20:17:33.000000000 -0400
5836 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
5837                         (current->personality & ADDR_COMPAT_LAYOUT) ||
5838                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
5839                 mm->mmap_base = TASK_UNMAPPED_BASE;
5840 +
5841 +#ifdef CONFIG_PAX_RANDMMAP
5842 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5843 +                       mm->mmap_base += mm->delta_mmap;
5844 +#endif
5845 +
5846                 mm->get_unmapped_area = arch_get_unmapped_area;
5847                 mm->unmap_area = arch_unmap_area;
5848         } else {
5849                 mm->mmap_base = mmap_base(mm);
5850 +
5851 +#ifdef CONFIG_PAX_RANDMMAP
5852 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5853 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
5854 +#endif
5855 +
5856                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
5857                 mm->unmap_area = arch_unmap_area_topdown;
5858         }
5859 diff -urNp linux-2.6.16.12/arch/x86_64/kernel/process.c linux-2.6.16.12/arch/x86_64/kernel/process.c
5860 --- linux-2.6.16.12/arch/x86_64/kernel/process.c        2006-05-01 15:14:26.000000000 -0400
5861 +++ linux-2.6.16.12/arch/x86_64/kernel/process.c        2006-05-01 20:17:33.000000000 -0400
5862 @@ -840,9 +840,3 @@ int dump_task_regs(struct task_struct *t
5863         return 1;
5864  }
5865  
5866 -unsigned long arch_align_stack(unsigned long sp)
5867 -{
5868 -       if (randomize_va_space)
5869 -               sp -= get_random_int() % 8192;
5870 -       return sp & ~0xf;
5871 -}
5872 diff -urNp linux-2.6.16.12/arch/x86_64/kernel/ptrace.c linux-2.6.16.12/arch/x86_64/kernel/ptrace.c
5873 --- linux-2.6.16.12/arch/x86_64/kernel/ptrace.c 2006-05-01 15:14:26.000000000 -0400
5874 +++ linux-2.6.16.12/arch/x86_64/kernel/ptrace.c 2006-05-01 20:17:33.000000000 -0400
5875 @@ -19,6 +19,7 @@
5876  #include <linux/audit.h>
5877  #include <linux/seccomp.h>
5878  #include <linux/signal.h>
5879 +#include <linux/grsecurity.h>
5880  
5881  #include <asm/uaccess.h>
5882  #include <asm/pgtable.h>
5883 diff -urNp linux-2.6.16.12/arch/x86_64/kernel/setup64.c linux-2.6.16.12/arch/x86_64/kernel/setup64.c
5884 --- linux-2.6.16.12/arch/x86_64/kernel/setup64.c        2006-05-01 15:14:26.000000000 -0400
5885 +++ linux-2.6.16.12/arch/x86_64/kernel/setup64.c        2006-05-01 20:17:33.000000000 -0400
5886 @@ -38,7 +38,6 @@ struct desc_ptr idt_descr = { 256 * 16, 
5887  char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
5888  
5889  unsigned long __supported_pte_mask __read_mostly = ~0UL;
5890 -static int do_not_nx __cpuinitdata = 0;
5891  
5892  /* noexec=on|off
5893  Control non executable mappings for 64bit processes.
5894 @@ -50,16 +49,14 @@ int __init nonx_setup(char *str)
5895  {
5896         if (!strncmp(str, "on", 2)) {
5897                  __supported_pte_mask |= _PAGE_NX; 
5898 -               do_not_nx = 0; 
5899         } else if (!strncmp(str, "off", 3)) {
5900 -               do_not_nx = 1;
5901                 __supported_pte_mask &= ~_PAGE_NX;
5902          }
5903         return 0;
5904  } 
5905  __setup("noexec=", nonx_setup);        /* parsed early actually */
5906  
5907 -int force_personality32 = READ_IMPLIES_EXEC;
5908 +int force_personality32;
5909  
5910  /* noexec32=on|off
5911  Control non executable heap for 32bit processes.
5912 @@ -173,7 +170,7 @@ void __cpuinit check_efer(void)
5913         unsigned long efer;
5914  
5915         rdmsrl(MSR_EFER, efer); 
5916 -        if (!(efer & EFER_NX) || do_not_nx) { 
5917 +        if (!(efer & EFER_NX)) { 
5918                  __supported_pte_mask &= ~_PAGE_NX; 
5919          }       
5920  }
5921 diff -urNp linux-2.6.16.12/arch/x86_64/kernel/sys_x86_64.c linux-2.6.16.12/arch/x86_64/kernel/sys_x86_64.c
5922 --- linux-2.6.16.12/arch/x86_64/kernel/sys_x86_64.c     2006-05-01 15:14:26.000000000 -0400
5923 +++ linux-2.6.16.12/arch/x86_64/kernel/sys_x86_64.c     2006-05-01 20:17:33.000000000 -0400
5924 @@ -66,8 +66,8 @@ out:
5925         return error;
5926  }
5927  
5928 -static void find_start_end(unsigned long flags, unsigned long *begin,
5929 -                          unsigned long *end)
5930 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
5931 +                          unsigned long *begin, unsigned long *end)
5932  {
5933         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
5934                 /* This is usually used needed to map code in small
5935 @@ -80,7 +80,7 @@ static void find_start_end(unsigned long
5936                 *begin = 0x40000000; 
5937                 *end = 0x80000000;              
5938         } else {
5939 -               *begin = TASK_UNMAPPED_BASE;
5940 +               *begin = mm->mmap_base;
5941                 *end = TASK_SIZE; 
5942         }
5943  } 
5944 @@ -94,11 +94,15 @@ arch_get_unmapped_area(struct file *filp
5945         unsigned long start_addr;
5946         unsigned long begin, end;
5947         
5948 -       find_start_end(flags, &begin, &end); 
5949 +       find_start_end(mm, flags, &begin, &end); 
5950  
5951         if (len > end)
5952                 return -ENOMEM;
5953  
5954 +#ifdef CONFIG_PAX_RANDMMAP
5955 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5956 +#endif
5957 +
5958         if (addr) {
5959                 addr = PAGE_ALIGN(addr);
5960                 vma = find_vma(mm, addr);
5961 diff -urNp linux-2.6.16.12/arch/x86_64/mm/fault.c linux-2.6.16.12/arch/x86_64/mm/fault.c
5962 --- linux-2.6.16.12/arch/x86_64/mm/fault.c      2006-05-01 15:14:26.000000000 -0400
5963 +++ linux-2.6.16.12/arch/x86_64/mm/fault.c      2006-05-01 20:17:33.000000000 -0400
5964 @@ -24,6 +24,7 @@
5965  #include <linux/compiler.h>
5966  #include <linux/module.h>
5967  #include <linux/kprobes.h>
5968 +#include <linux/binfmts.h>
5969  
5970  #include <asm/system.h>
5971  #include <asm/uaccess.h>
5972 @@ -292,6 +293,33 @@ static int vmalloc_fault(unsigned long a
5973         return 0;
5974  }
5975  
5976 +#ifdef CONFIG_PAX_PAGEEXEC
5977 +void pax_report_insns(void *pc, void *sp)
5978 +{
5979 +       long i;
5980 +
5981 +       printk(KERN_ERR "PAX: bytes at PC: ");
5982 +       for (i = 0; i < 20; i++) {
5983 +               unsigned char c;
5984 +               if (get_user(c, (unsigned char __user *)pc+i))
5985 +                       printk("?? ");
5986 +               else
5987 +                       printk("%02x ", c);
5988 +       }
5989 +       printk("\n");
5990 +
5991 +       printk(KERN_ERR "PAX: bytes at SP-8: ");
5992 +       for (i = -1; i < 10; i++) {
5993 +               unsigned long c;
5994 +               if (get_user(c, (unsigned long __user *)sp+i))
5995 +                       printk("???????????????? ");
5996 +               else
5997 +                       printk("%016lx ", c);
5998 +       }
5999 +       printk("\n");
6000 +}
6001 +#endif
6002 +
6003  int page_fault_trace = 0;
6004  int exception_trace = 1;
6005  
6006 @@ -416,6 +444,8 @@ asmlinkage void __kprobes do_page_fault(
6007  good_area:
6008         info.si_code = SEGV_ACCERR;
6009         write = 0;
6010 +       if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
6011 +               goto bad_area;
6012         switch (error_code & (PF_PROT|PF_WRITE)) {
6013                 default:        /* 3: write, present */
6014                         /* fall through */
6015 @@ -482,7 +512,14 @@ bad_area_nosemaphore:
6016                                         tsk->comm, tsk->pid, address, regs->rip,
6017                                         regs->rsp, error_code);
6018                 }
6019 -       
6020 +
6021 +#ifdef CONFIG_PAX_PAGEEXEC
6022 +               if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
6023 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
6024 +                       do_exit(SIGKILL);
6025 +               }
6026 +#endif
6027 +
6028                 tsk->thread.cr2 = address;
6029                 /* Kernel addresses are always protection faults */
6030                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
6031 diff -urNp linux-2.6.16.12/arch/x86_64/mm/mmap.c linux-2.6.16.12/arch/x86_64/mm/mmap.c
6032 --- linux-2.6.16.12/arch/x86_64/mm/mmap.c       2006-05-01 15:14:26.000000000 -0400
6033 +++ linux-2.6.16.12/arch/x86_64/mm/mmap.c       2006-05-01 20:17:33.000000000 -0400
6034 @@ -24,6 +24,12 @@ void arch_pick_mmap_layout(struct mm_str
6035                 unsigned rnd = get_random_int() & 0xfffffff;
6036                 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
6037         }
6038 +
6039 +#ifdef CONFIG_PAX_RANDMMAP
6040 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
6041 +               mm->mmap_base += mm->delta_mmap;
6042 +#endif
6043 +
6044         mm->get_unmapped_area = arch_get_unmapped_area;
6045         mm->unmap_area = arch_unmap_area;
6046  }
6047 diff -urNp linux-2.6.16.12/drivers/char/agp/frontend.c linux-2.6.16.12/drivers/char/agp/frontend.c
6048 --- linux-2.6.16.12/drivers/char/agp/frontend.c 2006-05-01 15:14:26.000000000 -0400
6049 +++ linux-2.6.16.12/drivers/char/agp/frontend.c 2006-05-01 20:17:33.000000000 -0400
6050 @@ -841,7 +841,7 @@ static int agpioc_reserve_wrap(struct ag
6051         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
6052                 return -EFAULT;
6053  
6054 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
6055 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
6056                 return -EFAULT;
6057  
6058         client = agp_find_client_by_pid(reserve.pid);
6059 diff -urNp linux-2.6.16.12/drivers/char/keyboard.c linux-2.6.16.12/drivers/char/keyboard.c
6060 --- linux-2.6.16.12/drivers/char/keyboard.c     2006-05-01 15:14:26.000000000 -0400
6061 +++ linux-2.6.16.12/drivers/char/keyboard.c     2006-05-01 20:17:33.000000000 -0400
6062 @@ -607,6 +607,16 @@ static void k_spec(struct vc_data *vc, u
6063              kbd->kbdmode == VC_MEDIUMRAW) &&
6064              value != KVAL(K_SAK))
6065                 return;         /* SAK is allowed even in raw mode */
6066 +
6067 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
6068 +       {
6069 +               void *func = fn_handler[value];
6070 +               if (func == fn_show_state || func == fn_show_ptregs ||
6071 +                   func == fn_show_mem)
6072 +                       return;
6073 +       }
6074 +#endif
6075 +
6076         fn_handler[value](vc, regs);
6077  }
6078  
6079 diff -urNp linux-2.6.16.12/drivers/char/mem.c linux-2.6.16.12/drivers/char/mem.c
6080 --- linux-2.6.16.12/drivers/char/mem.c  2006-05-01 15:14:26.000000000 -0400
6081 +++ linux-2.6.16.12/drivers/char/mem.c  2006-05-01 20:17:33.000000000 -0400
6082 @@ -27,6 +27,7 @@
6083  #include <linux/crash_dump.h>
6084  #include <linux/backing-dev.h>
6085  #include <linux/bootmem.h>
6086 +#include <linux/grsecurity.h>
6087  
6088  #include <asm/uaccess.h>
6089  #include <asm/io.h>
6090 @@ -35,6 +36,10 @@
6091  # include <linux/efi.h>
6092  #endif
6093  
6094 +#ifdef CONFIG_GRKERNSEC
6095 +extern struct file_operations grsec_fops;
6096 +#endif
6097 +
6098  /*
6099   * Architectures vary in how they handle caching for addresses
6100   * outside of main memory.
6101 @@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f
6102         if (!valid_phys_addr_range(p, &count))
6103                 return -EFAULT;
6104  
6105 +#ifdef CONFIG_GRKERNSEC_KMEM
6106 +       gr_handle_mem_write();
6107 +       return -EPERM;
6108 +#endif
6109 +
6110         written = 0;
6111  
6112  #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
6113 @@ -258,6 +268,11 @@ static int mmap_mem(struct file * file, 
6114                                                  size,
6115                                                  vma->vm_page_prot);
6116  
6117 +#ifdef CONFIG_GRKERNSEC_KMEM
6118 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
6119 +               return -EPERM;
6120 +#endif
6121 +
6122         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
6123         if (remap_pfn_range(vma,
6124                             vma->vm_start,
6125 @@ -487,6 +502,11 @@ static ssize_t write_kmem(struct file * 
6126         ssize_t written;
6127         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
6128  
6129 +#ifdef CONFIG_GRKERNSEC_KMEM
6130 +       gr_handle_kmem_write();
6131 +       return -EPERM;
6132 +#endif
6133 +
6134         if (p < (unsigned long) high_memory) {
6135  
6136                 wrote = count;
6137 @@ -633,9 +633,25 @@
6138                         count = size;
6139  
6140                 zap_page_range(vma, addr, count, NULL);
6141 -               if (zeromap_page_range(vma, addr, count, PAGE_COPY))
6142 +               if (zeromap_page_range(vma, addr, count, vma->vm_page_prot))
6143                         break;
6144  
6145 +#ifdef CONFIG_PAX_SEGMEXEC
6146 +               if (vma->vm_flags & VM_MIRROR) {
6147 +                       unsigned long addr_m;
6148 +                       struct vm_area_struct * vma_m;
6149 +
6150 +                       addr_m = vma->vm_start + vma->vm_mirror;
6151 +                       vma_m = find_vma(mm, addr_m);
6152 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
6153 +                               addr_m = addr + vma->vm_mirror;
6154 +                               zap_page_range(vma_m, addr_m, count, NULL);
6155 +                       } else
6156 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
6157 +                                               addr, vma->vm_start);
6158 +               }
6159 +#endif
6160 +
6161                 size -= count;
6162                 buf += count;
6163                 addr += count;
6164 @@ -762,6 +798,16 @@ static loff_t memory_lseek(struct file *
6165  
6166  static int open_port(struct inode * inode, struct file * filp)
6167  {
6168 +#ifdef CONFIG_GRKERNSEC_KMEM
6169 +       gr_handle_open_port();
6170 +       return -EPERM;
6171 +#endif
6172 +
6173 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
6174 +}
6175 +
6176 +static int open_mem(struct inode * inode, struct file * filp)
6177 +{
6178         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
6179  }
6180  
6181 @@ -769,7 +815,6 @@ static int open_port(struct inode * inod
6182  #define full_lseek      null_lseek
6183  #define write_zero     write_null
6184  #define read_full       read_zero
6185 -#define open_mem       open_port
6186  #define open_kmem      open_mem
6187  #define open_oldmem    open_mem
6188  
6189 @@ -891,6 +936,11 @@ static int memory_open(struct inode * in
6190                         filp->f_op = &oldmem_fops;
6191                         break;
6192  #endif
6193 +#ifdef CONFIG_GRKERNSEC
6194 +               case 13:
6195 +                       filp->f_op = &grsec_fops;
6196 +                       break;
6197 +#endif
6198                 default:
6199                         return -ENXIO;
6200         }
6201 @@ -923,6 +973,9 @@ static const struct {
6202  #ifdef CONFIG_CRASH_DUMP
6203         {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
6204  #endif
6205 +#ifdef CONFIG_GRKERNSEC
6206 +       {13,"grsec",    S_IRUSR | S_IWUGO,          &grsec_fops},
6207 +#endif
6208  };
6209  
6210  static struct class *mem_class;
6211 diff -urNp linux-2.6.16.12/drivers/char/random.c linux-2.6.16.12/drivers/char/random.c
6212 --- linux-2.6.16.12/drivers/char/random.c       2006-05-01 15:14:26.000000000 -0400
6213 +++ linux-2.6.16.12/drivers/char/random.c       2006-05-01 20:17:33.000000000 -0400
6214 @@ -249,8 +249,13 @@
6215  /*
6216   * Configuration information
6217   */
6218 +#ifdef CONFIG_GRKERNSEC_RANDNET
6219 +#define INPUT_POOL_WORDS 256
6220 +#define OUTPUT_POOL_WORDS 64
6221 +#else
6222  #define INPUT_POOL_WORDS 128
6223  #define OUTPUT_POOL_WORDS 32
6224 +#endif
6225  #define SEC_XFER_SIZE 512
6226  
6227  /*
6228 @@ -1659,3 +1664,25 @@ randomize_range(unsigned long start, uns
6229                 return 0;
6230         return PAGE_ALIGN(get_random_int() % range + start);
6231  }
6232 +
6233 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
6234 +unsigned long pax_get_random_long(void)
6235 +{
6236 +       static time_t   rekey_time;
6237 +       static __u32    secret[12];
6238 +       time_t          t;
6239 +
6240 +       /*
6241 +        * Pick a random secret every REKEY_INTERVAL seconds.
6242 +        */
6243 +       t = get_seconds();
6244 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
6245 +               rekey_time = t;
6246 +               get_random_bytes(secret, sizeof(secret));
6247 +       }
6248 +
6249 +       secret[1] = half_md4_transform(secret+8, secret);
6250 +       secret[0] = half_md4_transform(secret+8, secret);
6251 +       return *(unsigned long *)secret;
6252 +}
6253 +#endif
6254 diff -urNp linux-2.6.16.12/drivers/char/vt_ioctl.c linux-2.6.16.12/drivers/char/vt_ioctl.c
6255 --- linux-2.6.16.12/drivers/char/vt_ioctl.c     2006-05-01 15:14:26.000000000 -0400
6256 +++ linux-2.6.16.12/drivers/char/vt_ioctl.c     2006-05-01 20:17:33.000000000 -0400
6257 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
6258         case KDSKBENT:
6259                 if (!perm)
6260                         return -EPERM;
6261 +
6262 +#ifdef CONFIG_GRKERNSEC
6263 +               if (!capable(CAP_SYS_TTY_CONFIG))
6264 +                       return -EPERM;
6265 +#endif
6266 +
6267                 if (!i && v == K_NOSUCHMAP) {
6268                         /* disallocate map */
6269                         key_map = key_maps[s];
6270 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
6271                         goto reterr;
6272                 }
6273  
6274 +#ifdef CONFIG_GRKERNSEC
6275 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
6276 +                       ret = -EPERM;
6277 +                       goto reterr;
6278 +               }
6279 +#endif
6280 +
6281                 q = func_table[i];
6282                 first_free = funcbufptr + (funcbufsize - funcbufleft);
6283                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
6284 diff -urNp linux-2.6.16.12/drivers/ieee1394/ohci1394.c linux-2.6.16.12/drivers/ieee1394/ohci1394.c
6285 --- linux-2.6.16.12/drivers/ieee1394/ohci1394.c 2006-05-01 15:14:26.000000000 -0400
6286 +++ linux-2.6.16.12/drivers/ieee1394/ohci1394.c 2006-05-01 20:17:33.000000000 -0400
6287 @@ -162,9 +162,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
6288  printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
6289  
6290  /* Module Parameters */
6291 -static int phys_dma = 1;
6292 +static int phys_dma = 0;
6293  module_param(phys_dma, int, 0644);
6294 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
6295 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
6296  
6297  static void dma_trm_tasklet(unsigned long data);
6298  static void dma_trm_reset(struct dma_trm_ctx *d);
6299 diff -urNp linux-2.6.16.12/drivers/mtd/devices/doc2001.c linux-2.6.16.12/drivers/mtd/devices/doc2001.c
6300 --- linux-2.6.16.12/drivers/mtd/devices/doc2001.c       2006-05-01 15:14:26.000000000 -0400
6301 +++ linux-2.6.16.12/drivers/mtd/devices/doc2001.c       2006-05-01 20:17:33.000000000 -0400
6302 @@ -423,6 +423,8 @@ static int doc_read_ecc (struct mtd_info
6303         /* Don't allow read past end of device */
6304         if (from >= this->totlen)
6305                 return -EINVAL;
6306 +       if (!len)
6307 +               return -EINVAL;
6308  
6309         /* Don't allow a single read to cross a 512-byte block boundary */
6310         if (from + len > ((from | 0x1ff) + 1))
6311 diff -urNp linux-2.6.16.12/drivers/net/wan/sdla_ppp.c linux-2.6.16.12/drivers/net/wan/sdla_ppp.c
6312 --- linux-2.6.16.12/drivers/net/wan/sdla_ppp.c  2006-05-01 15:14:26.000000000 -0400
6313 +++ linux-2.6.16.12/drivers/net/wan/sdla_ppp.c  2006-05-01 20:17:33.000000000 -0400
6314 @@ -451,7 +451,7 @@ static int update(struct wan_device *wan
6315         sdla_t* card = wandev->private;
6316         struct net_device* dev;
6317          volatile ppp_private_area_t *ppp_priv_area;
6318 -       ppp_flags_t *flags = card->flags;
6319 +       ppp_flags_t *flags;
6320         unsigned long timeout;
6321  
6322         /* sanity checks */
6323 @@ -475,6 +475,7 @@ static int update(struct wan_device *wan
6324         
6325         ppp_priv_area->update_comms_stats = 2;
6326         ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
6327 +       flags = card->flags;
6328         flags->imask |= PPP_INTR_TIMER; 
6329         
6330         /* wait a maximum of 1 second for the statistics to be updated */ 
6331 diff -urNp linux-2.6.16.12/drivers/pci/proc.c linux-2.6.16.12/drivers/pci/proc.c
6332 --- linux-2.6.16.12/drivers/pci/proc.c  2006-05-01 15:14:26.000000000 -0400
6333 +++ linux-2.6.16.12/drivers/pci/proc.c  2006-05-01 20:17:33.000000000 -0400
6334 @@ -569,7 +569,15 @@ static struct file_operations proc_pci_o
6335  
6336  static void legacy_proc_init(void)
6337  {
6338 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6339 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6340 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR, NULL);
6341 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6342 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
6343 +#endif
6344 +#else
6345         struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
6346 +#endif
6347         if (entry)
6348                 entry->proc_fops = &proc_pci_operations;
6349  }
6350 @@ -598,7 +606,15 @@ static int __init pci_proc_init(void)
6351  {
6352         struct proc_dir_entry *entry;
6353         struct pci_dev *dev = NULL;
6354 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6355 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6356 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
6357 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6358 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
6359 +#endif
6360 +#else
6361         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
6362 +#endif
6363         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
6364         if (entry)
6365                 entry->proc_fops = &proc_bus_pci_dev_operations;
6366 diff -urNp linux-2.6.16.12/drivers/pnp/pnpbios/bioscalls.c linux-2.6.16.12/drivers/pnp/pnpbios/bioscalls.c
6367 --- linux-2.6.16.12/drivers/pnp/pnpbios/bioscalls.c     2006-05-01 15:14:26.000000000 -0400
6368 +++ linux-2.6.16.12/drivers/pnp/pnpbios/bioscalls.c     2006-05-01 20:17:33.000000000 -0400
6369 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
6370  set_limit(gdt[(selname) >> 3], size); \
6371  } while(0)
6372  
6373 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
6374 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
6375  
6376  /*
6377   * At some point we want to use this stack frame pointer to unwind
6378 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
6379         struct desc_struct save_desc_40;
6380         int cpu;
6381  
6382 +#ifdef CONFIG_PAX_KERNEXEC
6383 +       unsigned long cr0;
6384 +#endif
6385 +
6386         /*
6387          * PnP BIOSes are generally not terribly re-entrant.
6388          * Also, don't rely on them to save everything correctly.
6389 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
6390         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
6391         spin_lock_irqsave(&pnp_bios_lock, flags);
6392  
6393 +#ifdef CONFIG_PAX_KERNEXEC
6394 +       pax_open_kernel(cr0);
6395 +#endif
6396 +
6397         /* The lock prevents us bouncing CPU here */
6398         if (ts1_size)
6399                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
6400 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
6401                   "i" (0)
6402                 : "memory"
6403         );
6404 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
6405  
6406         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
6407 +
6408 +#ifdef CONFIG_PAX_KERNEXEC
6409 +       pax_close_kernel(cr0);
6410 +#endif
6411 +
6412 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
6413         put_cpu();
6414  
6415         /* If we get here and this is set then the PnP BIOS faulted on us. */
6416 diff -urNp linux-2.6.16.12/drivers/scsi/libata-scsi.c linux-2.6.16.12/drivers/scsi/libata-scsi.c
6417 --- linux-2.6.16.12/drivers/scsi/libata-scsi.c  2006-05-01 15:14:26.000000000 -0400
6418 +++ linux-2.6.16.12/drivers/scsi/libata-scsi.c  2006-05-01 20:17:33.000000000 -0400
6419 @@ -1591,7 +1591,7 @@ unsigned int ata_scsiop_inq_80(struct at
6420         return 0;
6421  }
6422  
6423 -static const char * const inq_83_str = "Linux ATA-SCSI simulator";
6424 +static const char inq_83_str[] = "Linux ATA-SCSI simulator";
6425  
6426  /**
6427   *     ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
6428 @@ -1610,13 +1610,13 @@ unsigned int ata_scsiop_inq_83(struct at
6429                               unsigned int buflen)
6430  {
6431         rbuf[1] = 0x83;                 /* this page code */
6432 -       rbuf[3] = 4 + strlen(inq_83_str);       /* page len */
6433 +       rbuf[3] = 3 + sizeof(inq_83_str);       /* page len */
6434  
6435         /* our one and only identification descriptor (vendor-specific) */
6436 -       if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) {
6437 +       if (buflen >= (sizeof(inq_83_str) + 4 + 4 - 1)) {
6438                 rbuf[4 + 0] = 2;        /* code set: ASCII */
6439 -               rbuf[4 + 3] = strlen(inq_83_str);
6440 -               memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str));
6441 +               rbuf[4 + 3] = sizeof(inq_83_str)-1;
6442 +               memcpy(rbuf + 4 + 4, inq_83_str, sizeof(inq_83_str)-1);
6443         }
6444  
6445         return 0;
6446 diff -urNp linux-2.6.16.12/drivers/video/vesafb.c linux-2.6.16.12/drivers/video/vesafb.c
6447 --- linux-2.6.16.12/drivers/video/vesafb.c      2006-05-01 15:14:26.000000000 -0400
6448 +++ linux-2.6.16.12/drivers/video/vesafb.c      2006-05-01 20:17:33.000000000 -0400
6449 @@ -251,7 +251,7 @@ static int __init vesafb_probe(struct pl
6450                 size_remap = size_total;
6451         vesafb_fix.smem_len = size_remap;
6452  
6453 -#ifndef __i386__
6454 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
6455         screen_info.vesapm_seg = 0;
6456  #endif
6457  
6458 diff -urNp linux-2.6.16.12/fs/binfmt_aout.c linux-2.6.16.12/fs/binfmt_aout.c
6459 --- linux-2.6.16.12/fs/binfmt_aout.c    2006-05-01 15:14:26.000000000 -0400
6460 +++ linux-2.6.16.12/fs/binfmt_aout.c    2006-05-01 20:17:33.000000000 -0400
6461 @@ -25,6 +25,7 @@
6462  #include <linux/personality.h>
6463  #include <linux/init.h>
6464  #include <linux/vs_memory.h>
6465 +#include <linux/grsecurity.h>
6466  
6467  #include <asm/system.h>
6468  #include <asm/uaccess.h>
6469 @@ -124,10 +125,12 @@ static int aout_core_dump(long signr, st
6470  /* If the size of the dump file exceeds the rlimit, then see what would happen
6471     if we wrote the stack, but not the data area.  */
6472  #ifdef __sparc__
6473 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
6474         if ((dump.u_dsize+dump.u_ssize) >
6475             current->signal->rlim[RLIMIT_CORE].rlim_cur)
6476                 dump.u_dsize = 0;
6477  #else
6478 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
6479         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
6480             current->signal->rlim[RLIMIT_CORE].rlim_cur)
6481                 dump.u_dsize = 0;
6482 @@ -135,10 +138,12 @@ static int aout_core_dump(long signr, st
6483  
6484  /* Make sure we have enough room to write the stack and data areas. */
6485  #ifdef __sparc__
6486 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
6487         if ((dump.u_ssize) >
6488             current->signal->rlim[RLIMIT_CORE].rlim_cur)
6489                 dump.u_ssize = 0;
6490  #else
6491 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
6492         if ((dump.u_ssize+1) * PAGE_SIZE >
6493             current->signal->rlim[RLIMIT_CORE].rlim_cur)
6494                 dump.u_ssize = 0;
6495 @@ -288,6 +293,8 @@ static int load_aout_binary(struct linux
6496         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
6497         if (rlim >= RLIM_INFINITY)
6498                 rlim = ~0;
6499 +
6500 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
6501         if (ex.a_data + ex.a_bss > rlim)
6502                 return -ENOMEM;
6503  
6504 @@ -320,6 +327,28 @@ static int load_aout_binary(struct linux
6505         current->mm->mmap = NULL;
6506         compute_creds(bprm);
6507         current->flags &= ~PF_FORKNOEXEC;
6508 +
6509 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
6510 +       current->mm->pax_flags = 0UL;
6511 +#endif
6512 +
6513 +#ifdef CONFIG_PAX_PAGEEXEC
6514 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
6515 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
6516 +
6517 +#ifdef CONFIG_PAX_EMUTRAMP
6518 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
6519 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
6520 +#endif
6521 +
6522 +#ifdef CONFIG_PAX_MPROTECT
6523 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
6524 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
6525 +#endif
6526 +
6527 +       }
6528 +#endif
6529 +
6530  #ifdef __sparc__
6531         if (N_MAGIC(ex) == NMAGIC) {
6532                 loff_t pos = fd_offset;
6533 @@ -415,7 +444,7 @@ static int load_aout_binary(struct linux
6534  
6535                 down_write(&current->mm->mmap_sem);
6536                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
6537 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
6538 +                               PROT_READ | PROT_WRITE,
6539                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
6540                                 fd_offset + ex.a_text);
6541                 up_write(&current->mm->mmap_sem);
6542 diff -urNp linux-2.6.16.12/fs/binfmt_elf.c linux-2.6.16.12/fs/binfmt_elf.c
6543 --- linux-2.6.16.12/fs/binfmt_elf.c     2006-05-01 15:14:26.000000000 -0400
6544 +++ linux-2.6.16.12/fs/binfmt_elf.c     2006-05-01 20:17:33.000000000 -0400
6545 @@ -39,11 +39,16 @@
6546  #include <linux/random.h>
6547  #include <linux/vs_memory.h>
6548  #include <linux/vs_cvirt.h>
6549 +#include <linux/grsecurity.h>
6550  
6551  #include <asm/uaccess.h>
6552  #include <asm/param.h>
6553  #include <asm/page.h>
6554  
6555 +#ifdef CONFIG_PAX_SEGMEXEC
6556 +#include <asm/desc.h>
6557 +#endif
6558 +
6559  #include <linux/elf.h>
6560  
6561  static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
6562 @@ -91,6 +96,8 @@ static struct linux_binfmt elf_format = 
6563  
6564  static int set_brk(unsigned long start, unsigned long end)
6565  {
6566 +       unsigned long e = end;
6567 +
6568         start = ELF_PAGEALIGN(start);
6569         end = ELF_PAGEALIGN(end);
6570         if (end > start) {
6571 @@ -101,7 +108,7 @@ static int set_brk(unsigned long start, 
6572                 if (BAD_ADDR(addr))
6573                         return addr;
6574         }
6575 -       current->mm->start_brk = current->mm->brk = end;
6576 +       current->mm->start_brk = current->mm->brk = e;
6577         return 0;
6578  }
6579  
6580 @@ -317,10 +324,9 @@ static unsigned long load_elf_interp(str
6581  {
6582         struct elf_phdr *elf_phdata;
6583         struct elf_phdr *eppnt;
6584 -       unsigned long load_addr = 0;
6585 -       int load_addr_set = 0;
6586 +       unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
6587         unsigned long last_bss = 0, elf_bss = 0;
6588 -       unsigned long error = ~0UL;
6589 +       unsigned long error = -EINVAL;
6590         int retval, i, size;
6591  
6592         /* First of all, some simple consistency checks */
6593 @@ -359,59 +365,80 @@ static unsigned long load_elf_interp(str
6594                 goto out_close;
6595         }
6596  
6597 +#ifdef CONFIG_PAX_SEGMEXEC
6598 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6599 +               task_size = SEGMEXEC_TASK_SIZE;
6600 +#endif
6601 +
6602         eppnt = elf_phdata;
6603 +       min_addr = task_size;
6604 +       max_addr = 0;
6605 +       error = -ENOMEM;
6606 +
6607         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
6608 -         if (eppnt->p_type == PT_LOAD) {
6609 -           int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
6610 -           int elf_prot = 0;
6611 -           unsigned long vaddr = 0;
6612 -           unsigned long k, map_addr;
6613 -
6614 -           if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
6615 -           if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
6616 -           if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
6617 -           vaddr = eppnt->p_vaddr;
6618 -           if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
6619 -               elf_type |= MAP_FIXED;
6620 -
6621 -           map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
6622 -           error = map_addr;
6623 -           if (BAD_ADDR(map_addr))
6624 -               goto out_close;
6625 -
6626 -           if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
6627 -               load_addr = map_addr - ELF_PAGESTART(vaddr);
6628 -               load_addr_set = 1;
6629 -           }
6630 -
6631 -           /*
6632 -            * Check to see if the section's size will overflow the
6633 -            * allowed task size. Note that p_filesz must always be
6634 -            * <= p_memsize so it is only necessary to check p_memsz.
6635 -            */
6636 -           k = load_addr + eppnt->p_vaddr;
6637 -           if (BAD_ADDR(k) || eppnt->p_filesz > eppnt->p_memsz ||
6638 -               eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
6639 -               error = -ENOMEM;
6640 +               if (eppnt->p_type != PT_LOAD)
6641 +                       continue;
6642 +
6643 +               /*
6644 +                * Check to see if the section's size will overflow the
6645 +                * allowed task size. Note that p_filesz must always be
6646 +                * <= p_memsize so it is only necessary to check p_memsz.
6647 +                */
6648 +               if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
6649 +                       goto out_close;
6650 +
6651 +               if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
6652 +                       min_addr = ELF_PAGESTART(eppnt->p_vaddr);
6653 +               if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
6654 +                       max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
6655 +       }
6656 +       if (min_addr >= max_addr)
6657                 goto out_close;
6658 -           }
6659  
6660 -           /*
6661 -            * Find the end of the file mapping for this phdr, and keep
6662 -            * track of the largest address we see for this.
6663 -            */
6664 -           k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
6665 -           if (k > elf_bss)
6666 -               elf_bss = k;
6667 -
6668 -           /*
6669 -            * Do the same thing for the memory mapping - between
6670 -            * elf_bss and last_bss is the bss section.
6671 -            */
6672 -           k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
6673 -           if (k > last_bss)
6674 -               last_bss = k;
6675 -         }
6676 +       eppnt = elf_phdata;
6677 +       for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
6678 +               int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
6679 +               int elf_prot = 0;
6680 +               unsigned long vaddr;
6681 +               unsigned long k, map_addr;
6682 +
6683 +               if (eppnt->p_type != PT_LOAD)
6684 +                       continue;
6685 +
6686 +               if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
6687 +               if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
6688 +               if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
6689 +               vaddr = eppnt->p_vaddr;
6690 +
6691 +               if (!load_addr && interp_elf_ex->e_type == ET_DYN) {
6692 +                       load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
6693 +
6694 +                       if (load_addr > task_size)
6695 +                               goto out_close;
6696 +
6697 +                       load_addr -= min_addr;
6698 +               }
6699 +
6700 +               map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
6701 +               error = map_addr;
6702 +               if (BAD_ADDR(map_addr))
6703 +                       goto out_close;
6704 +
6705 +               /*
6706 +                * Find the end of the file mapping for this phdr, and keep
6707 +                * track of the largest address we see for this.
6708 +                */
6709 +               k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
6710 +               if (k > elf_bss)
6711 +                       elf_bss = k;
6712 +
6713 +               /*
6714 +                * Do the same thing for the memory mapping - between
6715 +                * elf_bss and last_bss is the bss section.
6716 +                */
6717 +               k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
6718 +               if (k > last_bss)
6719 +                       last_bss = k;
6720         }
6721  
6722         /*
6723 @@ -448,7 +475,7 @@ out:
6724  static unsigned long load_aout_interp(struct exec * interp_ex,
6725                              struct file * interpreter)
6726  {
6727 -       unsigned long text_data, elf_entry = ~0UL;
6728 +       unsigned long text_data, elf_entry = -EINVAL;
6729         char __user * addr;
6730         loff_t offset;
6731  
6732 @@ -492,6 +519,180 @@ out:
6733         return elf_entry;
6734  }
6735  
6736 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
6737 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
6738 +{
6739 +       unsigned long pax_flags = 0UL;
6740 +
6741 +#ifdef CONFIG_PAX_PAGEEXEC
6742 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
6743 +               pax_flags |= MF_PAX_PAGEEXEC;
6744 +#endif
6745 +
6746 +#ifdef CONFIG_PAX_SEGMEXEC
6747 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
6748 +               pax_flags |= MF_PAX_SEGMEXEC;
6749 +#endif
6750 +
6751 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
6752 +       if (pax_flags & MF_PAX_PAGEEXEC)
6753 +               pax_flags &= ~MF_PAX_SEGMEXEC;
6754 +#endif
6755 +
6756 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
6757 +       if (pax_flags & MF_PAX_SEGMEXEC)
6758 +               pax_flags &= ~MF_PAX_PAGEEXEC;
6759 +#endif
6760 +
6761 +#ifdef CONFIG_PAX_EMUTRAMP
6762 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
6763 +               pax_flags |= MF_PAX_EMUTRAMP;
6764 +#endif
6765 +
6766 +#ifdef CONFIG_PAX_MPROTECT
6767 +       if (elf_phdata->p_flags & PF_MPROTECT)
6768 +               pax_flags |= MF_PAX_MPROTECT;
6769 +#endif
6770 +
6771 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
6772 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
6773 +               pax_flags |= MF_PAX_RANDMMAP;
6774 +#endif
6775 +
6776 +       return pax_flags;
6777 +}
6778 +#endif
6779 +
6780 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
6781 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
6782 +{
6783 +       unsigned long pax_flags = 0UL;
6784 +
6785 +#ifdef CONFIG_PAX_PAGEEXEC
6786 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
6787 +               pax_flags |= MF_PAX_PAGEEXEC;
6788 +#endif
6789 +
6790 +#ifdef CONFIG_PAX_SEGMEXEC
6791 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
6792 +               pax_flags |= MF_PAX_SEGMEXEC;
6793 +#endif
6794 +
6795 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
6796 +       if (pax_flags & MF_PAX_PAGEEXEC)
6797 +               pax_flags &= ~MF_PAX_SEGMEXEC;
6798 +#endif
6799 +
6800 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
6801 +       if (pax_flags & MF_PAX_SEGMEXEC)
6802 +               pax_flags &= ~MF_PAX_PAGEEXEC;
6803 +#endif
6804 +
6805 +#ifdef CONFIG_PAX_EMUTRAMP
6806 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
6807 +               pax_flags |= MF_PAX_EMUTRAMP;
6808 +#endif
6809 +
6810 +#ifdef CONFIG_PAX_MPROTECT
6811 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
6812 +               pax_flags |= MF_PAX_MPROTECT;
6813 +#endif
6814 +
6815 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
6816 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
6817 +               pax_flags |= MF_PAX_RANDMMAP;
6818 +#endif
6819 +
6820 +       return pax_flags;
6821 +}
6822 +#endif
6823 +
6824 +#ifdef CONFIG_PAX_EI_PAX
6825 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
6826 +{
6827 +       unsigned long pax_flags = 0UL;
6828 +
6829 +#ifdef CONFIG_PAX_PAGEEXEC
6830 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
6831 +               pax_flags |= MF_PAX_PAGEEXEC;
6832 +#endif
6833 +
6834 +#ifdef CONFIG_PAX_SEGMEXEC
6835 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
6836 +               pax_flags |= MF_PAX_SEGMEXEC;
6837 +#endif
6838 +
6839 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
6840 +       if (pax_flags & MF_PAX_PAGEEXEC)
6841 +               pax_flags &= ~MF_PAX_SEGMEXEC;
6842 +#endif
6843 +
6844 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
6845 +       if (pax_flags & MF_PAX_SEGMEXEC)
6846 +               pax_flags &= ~MF_PAX_PAGEEXEC;
6847 +#endif
6848 +
6849 +#ifdef CONFIG_PAX_EMUTRAMP
6850 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
6851 +               pax_flags |= MF_PAX_EMUTRAMP;
6852 +#endif
6853 +
6854 +#ifdef CONFIG_PAX_MPROTECT
6855 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
6856 +               pax_flags |= MF_PAX_MPROTECT;
6857 +#endif
6858 +
6859 +#ifdef CONFIG_PAX_ASLR
6860 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
6861 +               pax_flags |= MF_PAX_RANDMMAP;
6862 +#endif
6863 +
6864 +       return pax_flags;
6865 +}
6866 +#endif
6867 +
6868 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
6869 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
6870 +{
6871 +       unsigned long pax_flags = 0UL;
6872 +
6873 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
6874 +       unsigned long i;
6875 +#endif
6876 +
6877 +#ifdef CONFIG_PAX_EI_PAX
6878 +       pax_flags = pax_parse_ei_pax(elf_ex);
6879 +#endif
6880 +
6881 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
6882 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
6883 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
6884 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
6885 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
6886 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
6887 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
6888 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
6889 +                               return -EINVAL;
6890 +
6891 +#ifdef CONFIG_PAX_SOFTMODE
6892 +                       if (pax_softmode)
6893 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
6894 +                       else
6895 +#endif
6896 +
6897 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
6898 +                       break;
6899 +               }
6900 +#endif
6901 +
6902 +       if (0 > pax_check_flags(&pax_flags))
6903 +               return -EINVAL;
6904 +
6905 +       current->mm->pax_flags = pax_flags;
6906 +       return 0;
6907 +}
6908 +#endif
6909 +
6910  /*
6911   * These are the functions used to load ELF style executables and shared
6912   * libraries.  There is no binary dependent code anywhere else.
6913 @@ -523,7 +724,7 @@ static int load_elf_binary(struct linux_
6914         char * elf_interpreter = NULL;
6915         unsigned int interpreter_type = INTERPRETER_NONE;
6916         unsigned char ibcs2_interpreter = 0;
6917 -       unsigned long error;
6918 +       unsigned long error = 0;
6919         struct elf_phdr * elf_ppnt, *elf_phdata;
6920         unsigned long elf_bss, elf_brk;
6921         int elf_exec_fileno;
6922 @@ -541,6 +742,7 @@ static int load_elf_binary(struct linux_
6923                 struct elfhdr interp_elf_ex;
6924                 struct exec interp_ex;
6925         } *loc;
6926 +       unsigned long task_size = TASK_SIZE;
6927  
6928         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
6929         if (!loc) {
6930 @@ -766,14 +968,88 @@ static int load_elf_binary(struct linux_
6931         current->mm->end_code = 0;
6932         current->mm->mmap = NULL;
6933         current->flags &= ~PF_FORKNOEXEC;
6934 +
6935 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
6936 +       current->mm->pax_flags = 0UL;
6937 +#endif
6938 +
6939 +#ifdef CONFIG_PAX_DLRESOLVE
6940 +       current->mm->call_dl_resolve = 0UL;
6941 +#endif
6942 +
6943 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
6944 +       current->mm->call_syscall = 0UL;
6945 +#endif
6946 +
6947 +#ifdef CONFIG_PAX_ASLR
6948 +       current->mm->delta_mmap = 0UL;
6949 +       current->mm->delta_exec = 0UL;
6950 +       current->mm->delta_stack = 0UL;
6951 +#endif
6952 +
6953         current->mm->def_flags = def_flags;
6954  
6955 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
6956 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
6957 +               send_sig(SIGKILL, current, 0);
6958 +               goto out_free_dentry;
6959 +       }
6960 +#endif
6961 +
6962 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
6963 +       pax_set_initial_flags(bprm);
6964 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
6965 +       if (pax_set_initial_flags_func)
6966 +               (pax_set_initial_flags_func)(bprm);
6967 +#endif
6968 +
6969 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
6970 +       if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
6971 +               current->mm->context.user_cs_limit = PAGE_SIZE;
6972 +#endif
6973 +
6974 +#ifdef CONFIG_PAX_SEGMEXEC
6975 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
6976 +               int cpu = get_cpu();
6977 +
6978 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
6979 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
6980 +               set_user_cs(current->mm, cpu);
6981 +               put_cpu();
6982 +               task_size = SEGMEXEC_TASK_SIZE;
6983 +       }
6984 +#endif
6985 +
6986 +#ifdef CONFIG_PAX_ASLR
6987 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
6988 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
6989 +
6990 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
6991 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
6992 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
6993 +       }
6994 +#endif
6995 +
6996 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6997 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
6998 +               executable_stack = EXSTACK_DEFAULT;
6999 +#endif
7000 +
7001         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
7002            may depend on the personality.  */
7003         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
7004 +
7005 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7006 +       if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
7007 +#endif
7008 +
7009         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
7010                 current->personality |= READ_IMPLIES_EXEC;
7011  
7012 +#ifdef CONFIG_PAX_ASLR
7013 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
7014 +#endif
7015 +
7016         if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
7017                 current->flags |= PF_RANDOMIZE;
7018         arch_pick_mmap_layout(current->mm);
7019 @@ -845,6 +1121,15 @@ static int load_elf_binary(struct linux_
7020                            base, as well as whatever program they might try to exec.  This
7021                            is because the brk will follow the loader, and is not movable.  */
7022                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
7023 +
7024 +#ifdef CONFIG_PAX_RANDMMAP
7025 +                       /* PaX: randomize base address at the default exe base if requested */
7026 +                       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
7027 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
7028 +                               elf_flags |= MAP_FIXED;
7029 +                       }
7030 +#endif
7031 +
7032                 }
7033  
7034                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
7035 @@ -872,9 +1157,9 @@ static int load_elf_binary(struct linux_
7036                  * allowed task size. Note that p_filesz must always be
7037                  * <= p_memsz so it is only necessary to check p_memsz.
7038                  */
7039 -               if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
7040 -                   elf_ppnt->p_memsz > TASK_SIZE ||
7041 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
7042 +               if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
7043 +                   elf_ppnt->p_memsz > task_size ||
7044 +                   task_size - elf_ppnt->p_memsz < k) {
7045                         /* set_brk can never work.  Avoid overflows.  */
7046                         send_sig(SIGKILL, current, 0);
7047                         goto out_free_dentry;
7048 @@ -901,6 +1186,12 @@ static int load_elf_binary(struct linux_
7049         start_data += load_bias;
7050         end_data += load_bias;
7051  
7052 +#ifdef CONFIG_PAX_RANDMMAP
7053 +       if (randomize_va_space)
7054 +               elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
7055 +#undef pax_delta_mask
7056 +#endif
7057 +
7058         /* Calling set_brk effectively mmaps the pages that we need
7059          * for the bss and break sections.  We must do this before
7060          * mapping in the interpreter, to make sure it doesn't wind
7061 @@ -1153,7 +1444,7 @@ static int dump_seek(struct file *file, 
7062   *
7063   * I think we should skip something. But I am not sure how. H.J.
7064   */
7065 -static int maydump(struct vm_area_struct *vma)
7066 +static int maydump(struct vm_area_struct *vma, long signr)
7067  {
7068         /* Do not dump I/O mapped devices or special mappings */
7069         if (vma->vm_flags & (VM_IO | VM_RESERVED))
7070 @@ -1164,7 +1455,7 @@ static int maydump(struct vm_area_struct
7071                 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
7072  
7073         /* If it hasn't been written to, don't write it out */
7074 -       if (!vma->anon_vma)
7075 +       if (signr != SIGKILL && !vma->anon_vma)
7076                 return 0;
7077  
7078         return 1;
7079 @@ -1218,8 +1509,11 @@ static int writenote(struct memelfnote *
7080  #undef DUMP_SEEK
7081  
7082  #define DUMP_WRITE(addr, nr)   \
7083 +       do { \
7084 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
7085         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
7086 -               goto end_coredump;
7087 +               goto end_coredump; \
7088 +       } while (0);
7089  #define DUMP_SEEK(off) \
7090         if (!dump_seek(file, (off))) \
7091                 goto end_coredump;
7092 @@ -1570,7 +1864,7 @@ static int elf_core_dump(long signr, str
7093                 phdr.p_offset = offset;
7094                 phdr.p_vaddr = vma->vm_start;
7095                 phdr.p_paddr = 0;
7096 -               phdr.p_filesz = maydump(vma) ? sz : 0;
7097 +               phdr.p_filesz = maydump(vma, signr) ? sz : 0;
7098                 phdr.p_memsz = sz;
7099                 offset += phdr.p_filesz;
7100                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
7101 @@ -1603,7 +1897,7 @@ static int elf_core_dump(long signr, str
7102         for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
7103                 unsigned long addr;
7104  
7105 -               if (!maydump(vma))
7106 +               if (!maydump(vma, signr))
7107                         continue;
7108  
7109                 for (addr = vma->vm_start;
7110 @@ -1622,6 +1916,7 @@ static int elf_core_dump(long signr, str
7111                                         void *kaddr;
7112                                         flush_cache_page(vma, addr, page_to_pfn(page));
7113                                         kaddr = kmap(page);
7114 +                                       gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
7115                                         if ((size += PAGE_SIZE) > limit ||
7116                                             !dump_write(file, kaddr,
7117                                             PAGE_SIZE)) {
7118 diff -urNp linux-2.6.16.12/fs/binfmt_flat.c linux-2.6.16.12/fs/binfmt_flat.c
7119 --- linux-2.6.16.12/fs/binfmt_flat.c    2006-05-01 15:14:26.000000000 -0400
7120 +++ linux-2.6.16.12/fs/binfmt_flat.c    2006-05-01 20:17:33.000000000 -0400
7121 @@ -542,7 +542,9 @@ static int load_flat_file(struct linux_b
7122                                 realdatastart = (unsigned long) -ENOMEM;
7123                         printk("Unable to allocate RAM for process data, errno %d\n",
7124                                         (int)-datapos);
7125 +                       down_write(&current->mm->mmap_sem);
7126                         do_munmap(current->mm, textpos, text_len);
7127 +                       up_write(&current->mm->mmap_sem);
7128                         return realdatastart;
7129                 }
7130                 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
7131 @@ -563,8 +565,10 @@ static int load_flat_file(struct linux_b
7132                 }
7133                 if (result >= (unsigned long)-4096) {
7134                         printk("Unable to read data+bss, errno %d\n", (int)-result);
7135 +                       down_write(&current->mm->mmap_sem);
7136                         do_munmap(current->mm, textpos, text_len);
7137                         do_munmap(current->mm, realdatastart, data_len + extra);
7138 +                       up_write(&current->mm->mmap_sem);
7139                         return result;
7140                 }
7141  
7142 @@ -626,8 +630,10 @@ static int load_flat_file(struct linux_b
7143                 }
7144                 if (result >= (unsigned long)-4096) {
7145                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
7146 +                       down_write(&current->mm->mmap_sem);
7147                         do_munmap(current->mm, textpos, text_len + data_len + extra +
7148                                 MAX_SHARED_LIBS * sizeof(unsigned long));
7149 +                       up_write(&current->mm->mmap_sem);
7150                         return result;
7151                 }
7152         }
7153 diff -urNp linux-2.6.16.12/fs/binfmt_misc.c linux-2.6.16.12/fs/binfmt_misc.c
7154 --- linux-2.6.16.12/fs/binfmt_misc.c    2006-05-01 15:14:26.000000000 -0400
7155 +++ linux-2.6.16.12/fs/binfmt_misc.c    2006-05-01 20:17:33.000000000 -0400
7156 @@ -112,9 +112,11 @@ static int load_misc_binary(struct linux
7157         struct files_struct *files = NULL;
7158  
7159         retval = -ENOEXEC;
7160 -       if (!enabled)
7161 +       if (!enabled || bprm->misc)
7162                 goto _ret;
7163  
7164 +       bprm->misc++;
7165 +
7166         /* to keep locking time low, we copy the interpreter string */
7167         read_lock(&entries_lock);
7168         fmt = check_file(bprm);
7169 diff -urNp linux-2.6.16.12/fs/buffer.c linux-2.6.16.12/fs/buffer.c
7170 --- linux-2.6.16.12/fs/buffer.c 2006-05-01 15:14:26.000000000 -0400
7171 +++ linux-2.6.16.12/fs/buffer.c 2006-05-01 20:17:33.000000000 -0400
7172 @@ -42,6 +42,7 @@
7173  #include <linux/bitops.h>
7174  #include <linux/mpage.h>
7175  #include <linux/bit_spinlock.h>
7176 +#include <linux/grsecurity.h>
7177  
7178  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
7179  static void invalidate_bh_lrus(void);
7180 @@ -2166,6 +2167,7 @@ static int __generic_cont_expand(struct 
7181  
7182         err = -EFBIG;
7183          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
7184 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
7185         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
7186                 send_sig(SIGXFSZ, current, 0);
7187                 goto out;
7188 diff -urNp linux-2.6.16.12/fs/compat.c linux-2.6.16.12/fs/compat.c
7189 --- linux-2.6.16.12/fs/compat.c 2006-05-01 15:14:26.000000000 -0400
7190 +++ linux-2.6.16.12/fs/compat.c 2006-05-01 20:17:33.000000000 -0400
7191 @@ -46,6 +46,7 @@
7192  #include <linux/rwsem.h>
7193  #include <linux/acct.h>
7194  #include <linux/mm.h>
7195 +#include <linux/grsecurity.h>
7196  
7197  #include <net/sock.h>          /* siocdevprivate_ioctl */
7198  
7199 @@ -1476,6 +1477,11 @@ int compat_do_execve(char * filename,
7200         struct file *file;
7201         int retval;
7202         int i;
7203 +#ifdef CONFIG_GRKERNSEC
7204 +       struct file *old_exec_file;
7205 +       struct acl_subject_label *old_acl;
7206 +       struct rlimit old_rlim[RLIM_NLIMITS];
7207 +#endif
7208  
7209         retval = -ENOMEM;
7210         bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
7211 @@ -1494,6 +1500,15 @@ int compat_do_execve(char * filename,
7212         bprm->file = file;
7213         bprm->filename = filename;
7214         bprm->interp = filename;
7215 +
7216 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
7217 +       retval = -EAGAIN;
7218 +       if (gr_handle_nproc())
7219 +               goto out_file;
7220 +       retval = -EACCES;
7221 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
7222 +               goto out_file;
7223 +
7224         bprm->mm = mm_alloc();
7225         retval = -ENOMEM;
7226         if (!bprm->mm)
7227 @@ -1532,10 +1547,39 @@ int compat_do_execve(char * filename,
7228         if (retval < 0)
7229                 goto out;
7230  
7231 +       if (!gr_tpe_allow(file)) {
7232 +               retval = -EACCES;
7233 +               goto out;
7234 +       }
7235 +
7236 +       if (gr_check_crash_exec(file)) {
7237 +               retval = -EACCES;
7238 +               goto out;
7239 +       }
7240 +
7241 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
7242 +
7243 +       gr_handle_exec_args(bprm, (char __user * __user *)argv);
7244 +
7245 +#ifdef CONFIG_GRKERNSEC
7246 +       old_acl = current->acl;
7247 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
7248 +       old_exec_file = current->exec_file;
7249 +       get_file(file);
7250 +       current->exec_file = file;
7251 +#endif
7252 +
7253 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
7254 +
7255         retval = search_binary_handler(bprm, regs);
7256         if (retval >= 0) {
7257                 free_arg_pages(bprm);
7258  
7259 +#ifdef CONFIG_GRKERNSEC
7260 +               if (old_exec_file)
7261 +                       fput(old_exec_file);
7262 +#endif
7263 +
7264                 /* execve success */
7265                 security_bprm_free(bprm);
7266                 acct_update_integrals(current);
7267 @@ -1543,6 +1587,13 @@ int compat_do_execve(char * filename,
7268                 return retval;
7269         }
7270  
7271 +#ifdef CONFIG_GRKERNSEC
7272 +       current->acl = old_acl;
7273 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
7274 +       fput(current->exec_file);
7275 +       current->exec_file = old_exec_file;
7276 +#endif
7277 +
7278  out:
7279         /* Something went wrong, return the inode and free the argument pages*/
7280         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
7281 diff -urNp linux-2.6.16.12/fs/dcache.c linux-2.6.16.12/fs/dcache.c
7282 --- linux-2.6.16.12/fs/dcache.c 2006-05-01 15:14:26.000000000 -0400
7283 +++ linux-2.6.16.12/fs/dcache.c 2006-05-01 20:17:33.000000000 -0400
7284 @@ -1370,7 +1370,7 @@ already_unhashed:
7285   *
7286   * "buflen" should be positive. Caller holds the dcache_lock.
7287   */
7288 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
7289 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
7290                         struct dentry *root, struct vfsmount *rootmnt,
7291                         char *buffer, int buflen)
7292  {
7293 diff -urNp linux-2.6.16.12/fs/exec.c linux-2.6.16.12/fs/exec.c
7294 --- linux-2.6.16.12/fs/exec.c   2006-05-01 15:14:26.000000000 -0400
7295 +++ linux-2.6.16.12/fs/exec.c   2006-05-01 20:17:33.000000000 -0400
7296 @@ -51,6 +51,8 @@
7297  #include <linux/cn_proc.h>
7298  #include <linux/vs_cvirt.h>
7299  #include <linux/vs_memory.h>
7300 +#include <linux/random.h>
7301 +#include <linux/grsecurity.h>
7302  
7303  #include <asm/uaccess.h>
7304  #include <asm/mmu_context.h>
7305 @@ -69,6 +71,15 @@ EXPORT_SYMBOL(suid_dumpable);
7306  static struct linux_binfmt *formats;
7307  static DEFINE_RWLOCK(binfmt_lock);
7308  
7309 +#ifdef CONFIG_PAX_SOFTMODE
7310 +unsigned int pax_softmode;
7311 +#endif
7312 +
7313 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
7314 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
7315 +EXPORT_SYMBOL(pax_set_initial_flags_func);
7316 +#endif
7317 +
7318  int register_binfmt(struct linux_binfmt * fmt)
7319  {
7320         struct linux_binfmt ** tmp = &formats;
7321 @@ -314,6 +325,10 @@ void install_arg_page(struct vm_area_str
7322         if (unlikely(anon_vma_prepare(vma)))
7323                 goto out;
7324  
7325 +#ifdef CONFIG_PAX_SEGMEXEC
7326 +       if (page_count(page) == 1)
7327 +#endif
7328 +
7329         flush_dcache_page(page);
7330         pte = get_locked_pte(mm, address, &ptl);
7331         if (!pte)
7332 @@ -323,9 +338,21 @@ void install_arg_page(struct vm_area_str
7333                 goto out;
7334         }
7335         inc_mm_counter(mm, anon_rss);
7336 +
7337 +#ifdef CONFIG_PAX_SEGMEXEC
7338 +       if (page_count(page) == 1)
7339 +#endif
7340 +
7341         lru_cache_add_active(page);
7342         set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
7343                                         page, vma->vm_page_prot))));
7344 +
7345 +#ifdef CONFIG_PAX_SEGMEXEC
7346 +       if (page_count(page) != 1)
7347 +               page_add_anon_rmap(page, vma, address);
7348 +       else
7349 +#endif
7350 +
7351         page_add_new_anon_rmap(page, vma, address);
7352         pte_unmap_unlock(pte, ptl);
7353  
7354 @@ -348,6 +375,10 @@ int setup_arg_pages(struct linux_binprm 
7355         int i, ret;
7356         long arg_size;
7357  
7358 +#ifdef CONFIG_PAX_SEGMEXEC
7359 +       struct vm_area_struct *mpnt_m = NULL;
7360 +#endif
7361 +
7362  #ifdef CONFIG_STACK_GROWSUP
7363         /* Move the argument and environment strings to the bottom of the
7364          * stack space.
7365 @@ -412,6 +443,18 @@ int setup_arg_pages(struct linux_binprm 
7366  
7367         memset(mpnt, 0, sizeof(*mpnt));
7368  
7369 +#ifdef CONFIG_PAX_SEGMEXEC
7370 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
7371 +               mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7372 +               if (!mpnt_m) {
7373 +                       kmem_cache_free(vm_area_cachep, mpnt);
7374 +                       return -ENOMEM;
7375 +               }
7376 +
7377 +               memset(mpnt_m, 0, sizeof(*mpnt_m));
7378 +       }
7379 +#endif
7380 +
7381         down_write(&mm->mmap_sem);
7382         {
7383                 mpnt->vm_mm = mm;
7384 @@ -432,14 +475,51 @@ int setup_arg_pages(struct linux_binprm 
7385                 else
7386                         mpnt->vm_flags = VM_STACK_FLAGS;
7387                 mpnt->vm_flags |= mm->def_flags;
7388 +
7389 +#ifdef CONFIG_PAX_PAGEEXEC
7390 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
7391 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & 0x7];
7392 +               else
7393 +#endif
7394 +
7395                 mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
7396                 if ((ret = insert_vm_struct(mm, mpnt))) {
7397                         up_write(&mm->mmap_sem);
7398                         kmem_cache_free(vm_area_cachep, mpnt);
7399 +
7400 +#ifdef CONFIG_PAX_SEGMEXEC
7401 +                       if (mpnt_m)
7402 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
7403 +#endif
7404 +
7405                         return ret;
7406                 }
7407                 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
7408                 mm->stack_vm = mm->total_vm;
7409 +
7410 +#ifdef CONFIG_PAX_SEGMEXEC
7411 +               if (mpnt_m) {
7412 +                       *mpnt_m = *mpnt;
7413 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
7414 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
7415 +                               mpnt_m->vm_page_prot = PAGE_NONE;
7416 +                       }
7417 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
7418 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
7419 +                       if ((ret = insert_vm_struct(mm, mpnt_m))) {
7420 +                               up_write(&mm->mmap_sem);
7421 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
7422 +                               return ret;
7423 +                       }
7424 +                       mpnt_m->vm_flags |= VM_MIRROR;
7425 +                       mpnt->vm_flags |= VM_MIRROR;
7426 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
7427 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
7428 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
7429 +                       mm->total_vm += vma_pages(mpnt_m);
7430 +               }
7431 +#endif
7432 +
7433         }
7434  
7435         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
7436 @@ -447,6 +527,14 @@ int setup_arg_pages(struct linux_binprm 
7437                 if (page) {
7438                         bprm->page[i] = NULL;
7439                         install_arg_page(mpnt, page, stack_base);
7440 +
7441 +#ifdef CONFIG_PAX_SEGMEXEC
7442 +                       if (mpnt_m) {
7443 +                               page_cache_get(page);
7444 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
7445 +                       }
7446 +#endif
7447 +
7448                 }
7449                 stack_base += PAGE_SIZE;
7450         }
7451 @@ -1144,6 +1232,11 @@ int do_execve(char * filename,
7452         struct file *file;
7453         int retval;
7454         int i;
7455 +#ifdef CONFIG_GRKERNSEC
7456 +       struct file *old_exec_file;
7457 +       struct acl_subject_label *old_acl;
7458 +       struct rlimit old_rlim[RLIM_NLIMITS];
7459 +#endif
7460  
7461         retval = -ENOMEM;
7462         bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
7463 @@ -1156,10 +1249,29 @@ int do_execve(char * filename,
7464         if (IS_ERR(file))
7465                 goto out_kfree;
7466  
7467 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
7468 +
7469 +       if (gr_handle_nproc()) {
7470 +               allow_write_access(file);
7471 +               fput(file);
7472 +               return -EAGAIN;
7473 +       }
7474 +
7475 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
7476 +               allow_write_access(file);
7477 +               fput(file);
7478 +               return -EACCES;
7479 +       }
7480 +
7481         sched_exec();
7482  
7483         bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
7484  
7485 +#ifdef CONFIG_PAX_RANDUSTACK
7486 +       if (randomize_va_space)
7487 +               bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
7488 +#endif
7489 +
7490         bprm->file = file;
7491         bprm->filename = filename;
7492         bprm->interp = filename;
7493 @@ -1201,8 +1313,38 @@ int do_execve(char * filename,
7494         if (retval < 0)
7495                 goto out;
7496  
7497 +       if (!gr_tpe_allow(file)) {
7498 +               retval = -EACCES;
7499 +               goto out;
7500 +       }
7501 +
7502 +       if (gr_check_crash_exec(file)) {
7503 +               retval = -EACCES;
7504 +               goto out;
7505 +       }
7506 +
7507 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
7508 +
7509 +       gr_handle_exec_args(bprm, argv);
7510 +
7511 +#ifdef CONFIG_GRKERNSEC
7512 +       old_acl = current->acl;
7513 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
7514 +       old_exec_file = current->exec_file;
7515 +       get_file(file);
7516 +       current->exec_file = file;
7517 +#endif
7518 +
7519 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
7520 +       if (retval < 0)
7521 +               goto out_fail;
7522 +
7523         retval = search_binary_handler(bprm,regs);
7524         if (retval >= 0) {
7525 +#ifdef CONFIG_GRKERNSEC
7526 +               if (old_exec_file)
7527 +                       fput(old_exec_file);
7528 +#endif
7529                 free_arg_pages(bprm);
7530  
7531                 /* execve success */
7532 @@ -1212,6 +1354,14 @@ int do_execve(char * filename,
7533                 return retval;
7534         }
7535  
7536 +out_fail:
7537 +#ifdef CONFIG_GRKERNSEC
7538 +       current->acl = old_acl;
7539 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
7540 +       fput(current->exec_file);
7541 +       current->exec_file = old_exec_file;
7542 +#endif
7543 +
7544  out:
7545         /* Something went wrong, return the inode and free the argument pages*/
7546         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
7547 @@ -1372,6 +1522,114 @@ static void format_corename(char *corena
7548         *out_ptr = 0;
7549  }
7550  
7551 +int pax_check_flags(unsigned long * flags)
7552 +{
7553 +       int retval = 0;
7554 +
7555 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
7556 +       if (*flags & MF_PAX_SEGMEXEC)
7557 +       {
7558 +               *flags &= ~MF_PAX_SEGMEXEC;
7559 +               retval = -EINVAL;
7560 +       }
7561 +#endif
7562 +
7563 +       if ((*flags & MF_PAX_PAGEEXEC)
7564 +
7565 +#ifdef CONFIG_PAX_PAGEEXEC
7566 +           &&  (*flags & MF_PAX_SEGMEXEC)
7567 +#endif
7568 +
7569 +          )
7570 +       {
7571 +               *flags &= ~MF_PAX_PAGEEXEC;
7572 +               retval = -EINVAL;
7573 +       }
7574 +
7575 +       if ((*flags & MF_PAX_MPROTECT)
7576 +
7577 +#ifdef CONFIG_PAX_MPROTECT
7578 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
7579 +#endif
7580 +
7581 +          )
7582 +       {
7583 +               *flags &= ~MF_PAX_MPROTECT;
7584 +               retval = -EINVAL;
7585 +       }
7586 +
7587 +       if ((*flags & MF_PAX_EMUTRAMP)
7588 +
7589 +#ifdef CONFIG_PAX_EMUTRAMP
7590 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
7591 +#endif
7592 +
7593 +          )
7594 +       {
7595 +               *flags &= ~MF_PAX_EMUTRAMP;
7596 +               retval = -EINVAL;
7597 +       }
7598 +
7599 +       return retval;
7600 +}
7601 +
7602 +EXPORT_SYMBOL(pax_check_flags);
7603 +
7604 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7605 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
7606 +{
7607 +       struct task_struct *tsk = current;
7608 +       struct mm_struct *mm = current->mm;
7609 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
7610 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
7611 +       char* path_exec=NULL;
7612 +       char* path_fault=NULL;
7613 +       unsigned long start=0UL, end=0UL, offset=0UL;
7614 +
7615 +       if (buffer_exec && buffer_fault) {
7616 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
7617 +
7618 +               down_read(&mm->mmap_sem);
7619 +               vma = mm->mmap;
7620 +               while (vma && (!vma_exec || !vma_fault)) {
7621 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
7622 +                               vma_exec = vma;
7623 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
7624 +                               vma_fault = vma;
7625 +                       vma = vma->vm_next;
7626 +               }
7627 +               if (vma_exec) {
7628 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
7629 +                       if (IS_ERR(path_exec))
7630 +                               path_exec = "<path too long>";
7631 +               }
7632 +               if (vma_fault) {
7633 +                       start = vma_fault->vm_start;
7634 +                       end = vma_fault->vm_end;
7635 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
7636 +                       if (vma_fault->vm_file) {
7637 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
7638 +                               if (IS_ERR(path_fault))
7639 +                                       path_fault = "<path too long>";
7640 +                       } else
7641 +                               path_fault = "<anonymous mapping>";
7642 +               }
7643 +               up_read(&mm->mmap_sem);
7644 +       }
7645 +       if (tsk->signal->curr_ip)
7646 +               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);
7647 +       else
7648 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
7649 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
7650 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
7651 +                       tsk->uid, tsk->euid, pc, sp);
7652 +       free_page((unsigned long)buffer_exec);
7653 +       free_page((unsigned long)buffer_fault);
7654 +       pax_report_insns(pc, sp);
7655 +       do_coredump(SIGKILL, SIGKILL, regs);
7656 +}
7657 +#endif
7658 +
7659  static void zap_threads (struct mm_struct *mm)
7660  {
7661         struct task_struct *g, *p;
7662 @@ -1489,6 +1747,10 @@ int do_coredump(long signr, int exit_cod
7663          */
7664         clear_thread_flag(TIF_SIGPENDING);
7665  
7666 +       if (signr == SIGKILL || signr == SIGILL)
7667 +               gr_handle_brute_attach(current);
7668 +
7669 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
7670         if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
7671                 goto fail_unlock;
7672  
7673 diff -urNp linux-2.6.16.12/fs/fcntl.c linux-2.6.16.12/fs/fcntl.c
7674 --- linux-2.6.16.12/fs/fcntl.c  2006-05-01 15:14:26.000000000 -0400
7675 +++ linux-2.6.16.12/fs/fcntl.c  2006-05-01 20:17:33.000000000 -0400
7676 @@ -19,6 +19,7 @@
7677  #include <linux/signal.h>
7678  #include <linux/rcupdate.h>
7679  #include <linux/vs_limit.h>
7680 +#include <linux/grsecurity.h>
7681  
7682  #include <asm/poll.h>
7683  #include <asm/siginfo.h>
7684 @@ -64,6 +65,7 @@ static int locate_fd(struct files_struct
7685         struct fdtable *fdt;
7686  
7687         error = -EINVAL;
7688 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
7689         if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
7690                 goto out;
7691  
7692 @@ -84,6 +86,7 @@ repeat:
7693         }
7694         
7695         error = -EMFILE;
7696 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
7697         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
7698                 goto out;
7699         if (!vx_files_avail(1))
7700 @@ -146,6 +149,8 @@ asmlinkage long sys_dup2(unsigned int ol
7701         struct files_struct * files = current->files;
7702         struct fdtable *fdt;
7703  
7704 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
7705 +
7706         spin_lock(&files->file_lock);
7707         if (!(file = fcheck(oldfd)))
7708                 goto out_unlock;
7709 @@ -435,7 +440,8 @@ static inline int sigio_perm(struct task
7710         return (((fown->euid == 0) ||
7711                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
7712                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
7713 -               !security_file_send_sigiotask(p, fown, sig));
7714 +               !security_file_send_sigiotask(p, fown, sig) &&
7715 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
7716  }
7717  
7718  static void send_sigio_to_task(struct task_struct *p,
7719 diff -urNp linux-2.6.16.12/fs/Kconfig linux-2.6.16.12/fs/Kconfig
7720 --- linux-2.6.16.12/fs/Kconfig  2006-05-01 15:14:26.000000000 -0400
7721 +++ linux-2.6.16.12/fs/Kconfig  2006-05-01 20:17:33.000000000 -0400
7722 @@ -796,7 +796,7 @@ config PROC_FS
7723  
7724  config PROC_KCORE
7725         bool "/proc/kcore support" if !ARM
7726 -       depends on PROC_FS && MMU
7727 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
7728  
7729  config PROC_VMCORE
7730          bool "/proc/vmcore support (EXPERIMENTAL)"
7731 diff -urNp linux-2.6.16.12/fs/namei.c linux-2.6.16.12/fs/namei.c
7732 --- linux-2.6.16.12/fs/namei.c  2006-05-01 15:14:26.000000000 -0400
7733 +++ linux-2.6.16.12/fs/namei.c  2006-05-01 20:17:33.000000000 -0400
7734 @@ -36,6 +36,7 @@
7735  #include <linux/vserver/inode.h>
7736  #include <linux/vs_tag.h>
7737  #include <linux/vserver/debug.h>
7738 +#include <linux/grsecurity.h>
7739  #include <asm/namei.h>
7740  #include <asm/uaccess.h>
7741  
7742 @@ -632,6 +633,13 @@ static inline int do_follow_link(struct 
7743         err = security_inode_follow_link(path->dentry, nd);
7744         if (err)
7745                 goto loop;
7746 +
7747 +       if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
7748 +                                 path->dentry->d_inode, path->dentry, nd->mnt)) {
7749 +               err = -EACCES;
7750 +               goto loop;
7751 +       }
7752 +
7753         current->link_count++;
7754         current->total_link_count++;
7755         nd->depth++;
7756 @@ -994,11 +1002,18 @@ return_reval:
7757                                 break;
7758                 }
7759  return_base:
7760 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
7761 +                       path_release(nd);
7762 +                       return -ENOENT;
7763 +               }
7764                 return 0;
7765  out_dput:
7766                 dput_path(&next, nd);
7767                 break;
7768         }
7769 +       if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
7770 +               err = -ENOENT;
7771 +
7772         path_release(nd);
7773  return_err:
7774         return err;
7775 @@ -1652,6 +1667,17 @@ int open_namei(int dfd, const char *path
7776                                          nd, flag);
7777                 if (error)
7778                         return error;
7779 +
7780 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
7781 +                       error = -EPERM;
7782 +                       goto exit;
7783 +               }
7784 +
7785 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
7786 +                       error = -EACCES;
7787 +                       goto exit;
7788 +               }
7789 +
7790                 goto ok;
7791         }
7792  
7793 @@ -1686,9 +1712,16 @@ do_last:
7794  
7795         /* Negative dentry, just create the file */
7796         if (!path.dentry->d_inode) {
7797 +               if (!gr_acl_handle_creat(path.dentry, nd->dentry, nd->mnt, flag, mode)) {
7798 +                       error = -EACCES;
7799 +                       mutex_unlock(&dir->d_inode->i_mutex);
7800 +                       goto exit_dput;
7801 +               }
7802                 if (!IS_POSIXACL(dir->d_inode))
7803                         mode &= ~current->fs->umask;
7804                 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
7805 +               if (!error)
7806 +                       gr_handle_create(path.dentry, nd->mnt);
7807                 mutex_unlock(&dir->d_inode->i_mutex);
7808                 dput(nd->dentry);
7809                 nd->dentry = path.dentry;
7810 @@ -1703,6 +1736,23 @@ do_last:
7811         /*
7812          * It already exists.
7813          */
7814 +
7815 +       if (gr_handle_rawio(path.dentry->d_inode)) {
7816 +               mutex_unlock(&dir->d_inode->i_mutex);
7817 +               error = -EPERM;
7818 +               goto exit_dput;
7819 +       }
7820 +       if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
7821 +               mutex_unlock(&dir->d_inode->i_mutex);
7822 +               error = -EACCES;
7823 +               goto exit_dput;
7824 +       }
7825 +       if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
7826 +               mutex_unlock(&dir->d_inode->i_mutex);
7827 +               error = -EACCES;
7828 +               goto exit_dput;
7829 +       }
7830 +
7831         mutex_unlock(&dir->d_inode->i_mutex);
7832  
7833         error = -EEXIST;
7834 @@ -1768,6 +1818,13 @@ do_link:
7835         error = security_inode_follow_link(path.dentry, nd);
7836         if (error)
7837                 goto exit_dput;
7838 +
7839 +       if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
7840 +                                 path.dentry, nd->mnt)) {
7841 +               error = -EACCES;
7842 +               goto exit_dput;
7843 +       }
7844 +
7845         error = __do_follow_link(&path, nd);
7846         if (error)
7847                 return error;
7848 @@ -1889,6 +1946,22 @@ asmlinkage long sys_mknodat(int dfd, con
7849         if (!IS_POSIXACL(nd.dentry->d_inode))
7850                 mode &= ~current->fs->umask;
7851         if (!IS_ERR(dentry)) {
7852 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
7853 +                       error = -EPERM;
7854 +                       dput(dentry);
7855 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
7856 +                       path_release(&nd);
7857 +                       goto out;
7858 +               }
7859 +
7860 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
7861 +                       error = -EACCES;
7862 +                       dput(dentry);
7863 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
7864 +                       path_release(&nd);
7865 +                       goto out;
7866 +               }
7867 +
7868                 switch (mode & S_IFMT) {
7869                 case 0: case S_IFREG:
7870                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
7871 @@ -1907,6 +1980,10 @@ asmlinkage long sys_mknodat(int dfd, con
7872                 default:
7873                         error = -EINVAL;
7874                 }
7875 +
7876 +               if (!error)
7877 +                       gr_handle_create(dentry, nd.mnt);
7878 +
7879                 dput(dentry);
7880         }
7881         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7882 @@ -1962,10 +2039,19 @@ asmlinkage long sys_mkdirat(int dfd, con
7883                 dentry = lookup_create(&nd, 1);
7884                 error = PTR_ERR(dentry);
7885                 if (!IS_ERR(dentry)) {
7886 +                       error = 0;
7887                         if (!IS_POSIXACL(nd.dentry->d_inode))
7888                                 mode &= ~current->fs->umask;
7889 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
7890 -                               mode, &nd);
7891 +
7892 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
7893 +                               error = -EACCES;
7894 +
7895 +                       if (!error)
7896 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry,
7897 +                                       mode, &nd);
7898 +                       if (!error)
7899 +                               gr_handle_create(dentry, nd.mnt);
7900 +
7901                         dput(dentry);
7902                 }
7903                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7904 @@ -2050,6 +2136,8 @@ static long do_rmdir(int dfd, const char
7905         char * name;
7906         struct dentry *dentry;
7907         struct nameidata nd;
7908 +       ino_t saved_ino = 0;
7909 +       dev_t saved_dev = 0;
7910  
7911         name = getname(pathname);
7912         if(IS_ERR(name))
7913 @@ -2074,7 +2162,21 @@ static long do_rmdir(int dfd, const char
7914         dentry = lookup_hash(&nd);
7915         error = PTR_ERR(dentry);
7916         if (!IS_ERR(dentry)) {
7917 -               error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
7918 +               error = 0;
7919 +               if (dentry->d_inode) {
7920 +                       if (dentry->d_inode->i_nlink <= 1) {
7921 +                               saved_ino = dentry->d_inode->i_ino;
7922 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
7923 +                       }
7924 +
7925 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
7926 +                               error = -EACCES;
7927 +               }
7928 +
7929 +               if (!error)
7930 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
7931 +               if (!error && (saved_dev || saved_ino))
7932 +                       gr_handle_delete(saved_ino, saved_dev);
7933                 dput(dentry);
7934         }
7935         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7936 @@ -2134,6 +2236,8 @@ static long do_unlinkat(int dfd, const c
7937         struct dentry *dentry;
7938         struct nameidata nd;
7939         struct inode *inode = NULL;
7940 +       ino_t saved_ino = 0;
7941 +       dev_t saved_dev = 0;
7942  
7943         name = getname(pathname);
7944         if(IS_ERR(name))
7945 @@ -2149,13 +2253,26 @@ static long do_unlinkat(int dfd, const c
7946         dentry = lookup_hash(&nd);
7947         error = PTR_ERR(dentry);
7948         if (!IS_ERR(dentry)) {
7949 +               error = 0;
7950                 /* Why not before? Because we want correct error value */
7951                 if (nd.last.name[nd.last.len])
7952                         goto slashes;
7953                 inode = dentry->d_inode;
7954 -               if (inode)
7955 +               if (inode) {
7956 +                       if (inode->i_nlink <= 1) {
7957 +                               saved_ino = inode->i_ino;
7958 +                               saved_dev = inode->i_sb->s_dev;
7959 +                       }
7960 +
7961 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
7962 +                               error = -EACCES;
7963 +
7964                         atomic_inc(&inode->i_count);
7965 -               error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
7966 +               }
7967 +               if (!error)
7968 +                       error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
7969 +               if (!error && (saved_ino || saved_dev))
7970 +                       gr_handle_delete(saved_ino, saved_dev);
7971         exit2:
7972                 dput(dentry);
7973         }
7974 @@ -2234,8 +2351,16 @@ asmlinkage long sys_symlinkat(const char
7975                 dentry = lookup_create(&nd, 0);
7976                 error = PTR_ERR(dentry);
7977                 if (!IS_ERR(dentry)) {
7978 -                       error = vfs_symlink(nd.dentry->d_inode, dentry,
7979 -                               from, S_IALLUGO, &nd);
7980 +                       error = 0;
7981 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
7982 +                               error = -EACCES;
7983 +
7984 +                       if (!error)
7985 +                               error = vfs_symlink(nd.dentry->d_inode, dentry,
7986 +                                       from, S_IALLUGO, &nd);
7987 +
7988 +                       if (!error)
7989 +                               gr_handle_create(dentry, nd.mnt);
7990                         dput(dentry);
7991                 }
7992                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7993 @@ -2328,8 +2453,21 @@ asmlinkage long sys_linkat(int olddfd, c
7994         new_dentry = lookup_create(&nd, 0);
7995         error = PTR_ERR(new_dentry);
7996         if (!IS_ERR(new_dentry)) {
7997 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode,
7998 -                       new_dentry, &nd);
7999 +               error = 0;
8000 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
8001 +                                      old_nd.dentry->d_inode,
8002 +                                      old_nd.dentry->d_inode->i_mode, to))
8003 +                       error = -EPERM;
8004 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
8005 +                                       old_nd.dentry, old_nd.mnt, to))
8006 +                       error = -EACCES;
8007 +               if (!error)
8008 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry,
8009 +                                       &nd);
8010 +
8011 +               if (!error)
8012 +                       gr_handle_create(new_dentry, nd.mnt);
8013 +
8014                 dput(new_dentry);
8015         }
8016         mutex_unlock(&nd.dentry->d_inode->i_mutex);
8017 @@ -2558,8 +2696,16 @@ static int do_rename(int olddfd, const c
8018         if (new_dentry == trap)
8019                 goto exit5;
8020  
8021 -       error = vfs_rename(old_dir->d_inode, old_dentry,
8022 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
8023 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
8024 +                                    newname);
8025 +
8026 +       if (!error)
8027 +               error = vfs_rename(old_dir->d_inode, old_dentry,
8028                                    new_dir->d_inode, new_dentry);
8029 +       if (!error)
8030 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
8031 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
8032  exit5:
8033         dput(new_dentry);
8034  exit4:
8035 diff -urNp linux-2.6.16.12/fs/namespace.c linux-2.6.16.12/fs/namespace.c
8036 --- linux-2.6.16.12/fs/namespace.c      2006-05-01 15:14:26.000000000 -0400
8037 +++ linux-2.6.16.12/fs/namespace.c      2006-05-01 20:17:33.000000000 -0400
8038 @@ -25,6 +25,8 @@
8039  #include <linux/mount.h>
8040  #include <linux/vserver/namespace.h>
8041  #include <linux/vserver/tag.h>
8042 +#include <linux/sched.h>
8043 +#include <linux/grsecurity.h>
8044  #include <asm/uaccess.h>
8045  #include <asm/unistd.h>
8046  #include "pnode.h"
8047 @@ -630,6 +632,8 @@ static int do_umount(struct vfsmount *mn
8048                         DQUOT_OFF(sb->s_dqh);
8049                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
8050                         unlock_kernel();
8051 +
8052 +                       gr_log_remount(mnt->mnt_devname, retval);
8053                 }
8054                 up_write(&sb->s_umount);
8055                 return retval;
8056 @@ -650,6 +654,9 @@ static int do_umount(struct vfsmount *mn
8057                 security_sb_umount_busy(mnt);
8058         up_write(&namespace_sem);
8059         release_mounts(&umount_list);
8060 +
8061 +       gr_log_unmount(mnt->mnt_devname, retval);
8062 +
8063         return retval;
8064  }
8065  
8066 @@ -1400,6 +1407,11 @@ long do_mount(char *dev_name, char *dir_
8067         if (retval)
8068                 goto dput_out;
8069  
8070 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
8071 +               retval = -EPERM;
8072 +               goto dput_out;
8073 +       }
8074 +
8075         if (flags & MS_REMOUNT)
8076                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
8077                                     data_page, tag);
8078 @@ -1414,6 +1426,9 @@ long do_mount(char *dev_name, char *dir_
8079                                       dev_name, data_page);
8080  dput_out:
8081         path_release(&nd);
8082 +
8083 +       gr_log_mount(dev_name, dir_name, retval);
8084 +
8085         return retval;
8086  }
8087  
8088 @@ -1666,6 +1681,9 @@ asmlinkage long sys_pivot_root(const cha
8089         if (!capable(CAP_SYS_ADMIN))
8090                 return -EPERM;
8091  
8092 +       if (gr_handle_chroot_pivot())
8093 +               return -EPERM;
8094 +
8095         lock_kernel();
8096  
8097         error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
8098 diff -urNp linux-2.6.16.12/fs/open.c linux-2.6.16.12/fs/open.c
8099 --- linux-2.6.16.12/fs/open.c   2006-05-01 15:14:26.000000000 -0400
8100 +++ linux-2.6.16.12/fs/open.c   2006-05-01 20:17:33.000000000 -0400
8101 @@ -30,6 +30,7 @@
8102  #include <linux/vs_limit.h>
8103  #include <linux/vs_dlimit.h>
8104  #include <linux/vserver/tag.h>
8105 +#include <linux/grsecurity.h>
8106  
8107  #include <asm/unistd.h>
8108  
8109 @@ -211,6 +212,9 @@ int do_truncate(struct dentry *dentry, l
8110         if (length < 0)
8111                 return -EINVAL;
8112  
8113 +       if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
8114 +               return -EACCES;
8115 +
8116         newattrs.ia_size = length;
8117         newattrs.ia_valid = ATTR_SIZE | time_attrs;
8118         if (filp) {
8119 @@ -411,6 +415,12 @@ asmlinkage long sys_utime(char __user * 
8120                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
8121                         goto dput_and_out;
8122         }
8123 +
8124 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
8125 +               error = -EACCES;
8126 +               goto dput_and_out;
8127 +       }
8128 +
8129         mutex_lock(&inode->i_mutex);
8130         error = notify_change(nd.dentry, &newattrs);
8131         mutex_unlock(&inode->i_mutex);
8132 @@ -464,6 +474,12 @@ long do_utimes(int dfd, char __user *fil
8133                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
8134                         goto dput_and_out;
8135         }
8136 +
8137 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
8138 +               error = -EACCES;
8139 +               goto dput_and_out;
8140 +       }
8141 +
8142         mutex_lock(&inode->i_mutex);
8143         error = notify_change(nd.dentry, &newattrs);
8144         mutex_unlock(&inode->i_mutex);
8145 @@ -531,6 +547,10 @@ asmlinkage long sys_faccessat(int dfd, c
8146                    && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
8147                    && !special_file(nd.dentry->d_inode->i_mode))
8148                         res = -EROFS;
8149 +
8150 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
8151 +                       res = -EACCES;
8152 +
8153                 path_release(&nd);
8154         }
8155  
8156 @@ -559,6 +579,8 @@ asmlinkage long sys_chdir(const char __u
8157         if (error)
8158                 goto dput_and_out;
8159  
8160 +       gr_log_chdir(nd.dentry, nd.mnt);
8161 +
8162         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
8163  
8164  dput_and_out:
8165 @@ -589,6 +611,13 @@ asmlinkage long sys_fchdir(unsigned int 
8166                 goto out_putf;
8167  
8168         error = file_permission(file, MAY_EXEC);
8169 +
8170 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
8171 +               error = -EPERM;
8172 +
8173 +       if (!error)
8174 +               gr_log_chdir(dentry, mnt);
8175 +
8176         if (!error)
8177                 set_fs_pwd(current->fs, mnt, dentry);
8178  out_putf:
8179 @@ -614,8 +643,16 @@ asmlinkage long sys_chroot(const char __
8180         if (!capable(CAP_SYS_CHROOT))
8181                 goto dput_and_out;
8182  
8183 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
8184 +               goto dput_and_out;
8185 +
8186         set_fs_root(current->fs, nd.mnt, nd.dentry);
8187         set_fs_altroot();
8188 +
8189 +       gr_handle_chroot_caps(current);
8190 +
8191 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
8192 +
8193         error = 0;
8194  dput_and_out:
8195         path_release(&nd);
8196 @@ -644,9 +681,22 @@ asmlinkage long sys_fchmod(unsigned int 
8197         err = -EPERM;
8198         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
8199                 goto out_putf;
8200 +
8201 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
8202 +               err = -EACCES;
8203 +               goto out_putf;
8204 +       }
8205 +
8206         mutex_lock(&inode->i_mutex);
8207         if (mode == (mode_t) -1)
8208                 mode = inode->i_mode;
8209 +
8210 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
8211 +               err = -EPERM;
8212 +               mutex_unlock(&inode->i_mutex);
8213 +               goto out_putf;
8214 +       }
8215 +
8216         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
8217         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
8218         err = notify_change(dentry, &newattrs);
8219 @@ -679,9 +729,21 @@ asmlinkage long sys_fchmodat(int dfd, co
8220         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
8221                 goto dput_and_out;
8222  
8223 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
8224 +               error = -EACCES;
8225 +               goto dput_and_out;
8226 +       };
8227 +
8228         mutex_lock(&inode->i_mutex);
8229         if (mode == (mode_t) -1)
8230                 mode = inode->i_mode;
8231 +
8232 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
8233 +               error = -EACCES;
8234 +               mutex_unlock(&inode->i_mutex);
8235 +               goto dput_and_out;
8236 +       }
8237 +
8238         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
8239         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
8240         error = notify_change(nd.dentry, &newattrs);
8241 @@ -716,6 +778,12 @@ static int chown_common(struct dentry * 
8242         error = -EPERM;
8243         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
8244                 goto out;
8245 +
8246 +       if (!gr_acl_handle_chown(dentry, mnt)) {
8247 +               error = -EACCES;
8248 +               goto out;
8249 +       }
8250 +
8251         newattrs.ia_valid =  ATTR_CTIME;
8252         if (user != (uid_t) -1) {
8253                 newattrs.ia_valid |= ATTR_UID;
8254 @@ -992,6 +1061,7 @@ repeat:
8255          * N.B. For clone tasks sharing a files structure, this test
8256          * will limit the total number of files that can be opened.
8257          */
8258 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
8259         if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
8260                 goto out;
8261  
8262 diff -urNp linux-2.6.16.12/fs/proc/array.c linux-2.6.16.12/fs/proc/array.c
8263 --- linux-2.6.16.12/fs/proc/array.c     2006-05-01 15:14:26.000000000 -0400
8264 +++ linux-2.6.16.12/fs/proc/array.c     2006-05-01 20:17:33.000000000 -0400
8265 @@ -306,6 +306,21 @@ static inline char *task_cap(struct task
8266                 (unsigned)vx_info_mbcap(vxi, p->cap_effective));
8267  }
8268  
8269 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
8270 +static inline char *task_pax(struct task_struct *p, char *buffer)
8271 +{
8272 +       if (p->mm)
8273 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
8274 +                               p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
8275 +                               p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
8276 +                               p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
8277 +                               p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
8278 +                               p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
8279 +       else
8280 +               return buffer + sprintf(buffer, "PaX:\t-----\n");
8281 +}
8282 +#endif
8283 +
8284  int proc_pid_status(struct task_struct *task, char * buffer)
8285  {
8286         char * orig = buffer;
8287 @@ -370,9 +385,20 @@ int proc_pid_status(struct task_struct *
8288  #if defined(CONFIG_S390)
8289         buffer = task_show_regs(task, buffer);
8290  #endif
8291 +
8292 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
8293 +       buffer = task_pax(task, buffer);
8294 +#endif
8295 +
8296         return buffer - orig;
8297  }
8298  
8299 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8300 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
8301 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
8302 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
8303 +#endif
8304 +
8305  static int do_task_stat(struct task_struct *task, char * buffer, int whole)
8306  {
8307         unsigned long vsize, eip, esp, wchan = ~0UL;
8308 @@ -463,6 +489,19 @@ static int do_task_stat(struct task_stru
8309                 stime = task->stime;
8310         }
8311  
8312 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8313 +       if (PAX_RAND_FLAGS(mm)) {
8314 +               eip = 0;
8315 +               esp = 0;
8316 +               wchan = 0;
8317 +       }
8318 +#endif
8319 +#ifdef CONFIG_GRKERNSEC_HIDESYM
8320 +       wchan = 0;
8321 +       eip =0;
8322 +       esp =0;
8323 +#endif
8324 +
8325         /* scale priority and nice values from timeslices to -20..20 */
8326         /* to make it look like a "normal" Unix priority/nice value  */
8327         priority = task_prio(task);
8328 @@ -514,9 +553,15 @@ static int do_task_stat(struct task_stru
8329                 vsize,
8330                 mm ? get_mm_rss(mm) : 0,
8331                 rsslim,
8332 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8333 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
8334 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
8335 +               PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
8336 +#else
8337                 mm ? mm->start_code : 0,
8338                 mm ? mm->end_code : 0,
8339                 mm ? mm->start_stack : 0,
8340 +#endif
8341                 esp,
8342                 eip,
8343                 /* The signal information here is obsolete.
8344 @@ -562,3 +607,14 @@ int proc_pid_statm(struct task_struct *t
8345         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
8346                        size, resident, shared, text, lib, data, 0);
8347  }
8348 +
8349 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8350 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
8351 +{
8352 +       int len;
8353 +
8354 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
8355 +       return len;
8356 +}
8357 +#endif
8358 +
8359 diff -urNp linux-2.6.16.12/fs/proc/base.c linux-2.6.16.12/fs/proc/base.c
8360 --- linux-2.6.16.12/fs/proc/base.c      2006-05-01 15:14:26.000000000 -0400
8361 +++ linux-2.6.16.12/fs/proc/base.c      2006-05-01 20:17:33.000000000 -0400
8362 @@ -74,6 +74,7 @@
8363  #include <linux/poll.h>
8364  #include <linux/vs_network.h>
8365  #include <linux/vs_pid.h>
8366 +#include <linux/grsecurity.h>
8367  #include "internal.h"
8368  
8369  /*
8370 @@ -128,6 +129,9 @@ enum pid_directory_inos {
8371  #ifdef CONFIG_AUDITSYSCALL
8372         PROC_TGID_LOGINUID,
8373  #endif
8374 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8375 +       PROC_TGID_IPADDR,
8376 +#endif
8377         PROC_TGID_OOM_SCORE,
8378         PROC_TGID_OOM_ADJUST,
8379         PROC_TID_INO,
8380 @@ -207,6 +211,9 @@ static struct pid_entry tgid_base_stuff[
8381         E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
8382         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
8383         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
8384 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8385 +       E(PROC_TGID_IPADDR,     "ipaddr",  S_IFREG|S_IRUSR),
8386 +#endif
8387  #ifdef CONFIG_MMU
8388         E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
8389  #endif
8390 @@ -417,7 +424,7 @@ static int proc_task_root_link(struct in
8391         (task->parent == current && \
8392         (task->ptrace & PT_PTRACED) && \
8393          (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
8394 -        security_ptrace(current,task) == 0))
8395 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
8396  
8397  static int proc_pid_environ(struct task_struct *task, char * buffer)
8398  {
8399 @@ -601,9 +608,25 @@ static int proc_check_root(struct inode 
8400  
8401  static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
8402  {
8403 +       int ret = -EACCES;
8404 +       struct task_struct *task;
8405 +
8406         if (generic_permission(inode, mask, NULL) != 0)
8407 -               return -EACCES;
8408 -       return proc_check_root(inode);
8409 +               goto out;
8410 +
8411 +       ret = proc_check_root(inode);
8412 +       if (ret)
8413 +               goto out;
8414 +
8415 +       task = proc_task(inode);
8416 +
8417 +       if (!task)
8418 +               goto out;
8419 +
8420 +       ret = gr_acl_handle_procpidmem(task);
8421 +
8422 +out:
8423 +       return ret;
8424  }
8425  
8426  static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd)
8427 @@ -1361,6 +1384,9 @@ static struct inode *proc_pid_make_inode
8428         }
8429         /* procfs is xid tagged */
8430         inode->i_tag = (tag_t)vx_task_xid(task);
8431 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8432 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
8433 +#endif
8434         security_task_to_inode(task, inode);
8435  
8436  out:
8437 @@ -1394,7 +1420,9 @@ static int pid_revalidate(struct dentry 
8438         if (pid_alive(task)) {
8439                 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
8440                         inode->i_uid = task->euid;
8441 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
8442                         inode->i_gid = task->egid;
8443 +#endif
8444                 } else {
8445                         inode->i_uid = 0;
8446                         inode->i_gid = 0;
8447 @@ -1726,6 +1754,12 @@ static struct dentry *proc_pident_lookup
8448                         inode->i_fop = &proc_info_file_operations;
8449                         ei->op.proc_read = proc_pid_status;
8450                         break;
8451 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8452 +               case PROC_TGID_IPADDR:
8453 +                       inode->i_fop = &proc_info_file_operations;
8454 +                       ei->op.proc_read = proc_pid_ipaddr;
8455 +                       break;
8456 +#endif
8457                 case PROC_TID_STAT:
8458                         inode->i_fop = &proc_info_file_operations;
8459                         ei->op.proc_read = proc_tid_stat;
8460 @@ -2066,11 +2100,35 @@ struct dentry *proc_pid_lookup(struct in
8461         if (!proc_pid_visible(task, tgid))
8462                 goto out_drop_task;
8463  
8464 +       if (gr_check_hidden_task(task)) {
8465 +               put_task_struct(task);
8466 +               goto out;
8467 +       }
8468 +
8469 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8470 +       if (current->uid && (task->uid != current->uid)
8471 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8472 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
8473 +#endif
8474 +       ) {
8475 +               put_task_struct(task);
8476 +               goto out;
8477 +       }
8478 +#endif
8479 +
8480         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
8481         if (!inode)
8482                 goto out_drop_task;
8483  
8484 +
8485 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8486 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
8487 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8488 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
8489 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
8490 +#else
8491         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
8492 +#endif
8493         inode->i_op = &proc_tgid_base_inode_operations;
8494         inode->i_fop = &proc_tgid_base_operations;
8495         inode->i_flags|=S_IMMUTABLE;
8496 @@ -2169,6 +2227,9 @@ out:
8497  static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
8498  {
8499         struct task_struct *p;
8500 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8501 +       struct task_struct *tmp = current;
8502 +#endif
8503         int nr_tgids = 0;
8504  
8505         index--;
8506 @@ -2193,6 +2254,18 @@ static int get_tgid_list(int index, unsi
8507                 /* check for context visibility */
8508                 if (!proc_pid_visible(p, tgid))
8509                         continue;
8510 +               if (gr_pid_is_chrooted(p))
8511 +                       continue;
8512 +               if (gr_check_hidden_task(p))
8513 +                       continue;
8514 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8515 +               if (tmp->uid && (p->uid != tmp->uid)
8516 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8517 +                   && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
8518 +#endif
8519 +               )
8520 +                       continue;
8521 +#endif
8522                 if (--index >= 0)
8523                         continue;
8524                 tgids[nr_tgids] = vx_map_tgid(tgid);
8525 diff -urNp linux-2.6.16.12/fs/proc/inode.c linux-2.6.16.12/fs/proc/inode.c
8526 --- linux-2.6.16.12/fs/proc/inode.c     2006-05-01 15:14:26.000000000 -0400
8527 +++ linux-2.6.16.12/fs/proc/inode.c     2006-05-01 20:17:33.000000000 -0400
8528 @@ -168,7 +168,11 @@ struct inode *proc_get_inode(struct supe
8529                 if (de->mode) {
8530                         inode->i_mode = de->mode;
8531                         inode->i_uid = de->uid;
8532 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8533 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
8534 +#else
8535                         inode->i_gid = de->gid;
8536 +#endif
8537                 }
8538                 if (de->vx_flags)
8539                         PROC_I(inode)->vx_flags = de->vx_flags;
8540 diff -urNp linux-2.6.16.12/fs/proc/internal.h linux-2.6.16.12/fs/proc/internal.h
8541 --- linux-2.6.16.12/fs/proc/internal.h  2006-05-01 15:14:26.000000000 -0400
8542 +++ linux-2.6.16.12/fs/proc/internal.h  2006-05-01 20:17:33.000000000 -0400
8543 @@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
8544  extern int proc_tgid_stat(struct task_struct *, char *);
8545  extern int proc_pid_status(struct task_struct *, char *);
8546  extern int proc_pid_statm(struct task_struct *, char *);
8547 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8548 +extern int proc_pid_ipaddr(struct task_struct*,char*);
8549 +#endif
8550  
8551  void free_proc_entry(struct proc_dir_entry *de);
8552  
8553 diff -urNp linux-2.6.16.12/fs/proc/proc_misc.c linux-2.6.16.12/fs/proc/proc_misc.c
8554 --- linux-2.6.16.12/fs/proc/proc_misc.c 2006-05-01 15:14:26.000000000 -0400
8555 +++ linux-2.6.16.12/fs/proc/proc_misc.c 2006-05-01 20:17:33.000000000 -0400
8556 @@ -651,6 +651,8 @@ void create_seq_entry(char *name, mode_t
8557  void __init proc_misc_init(void)
8558  {
8559         struct proc_dir_entry *entry;
8560 +       int gr_mode = 0;
8561 +
8562         static struct {
8563                 char *name;
8564                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
8565 @@ -666,7 +668,9 @@ void __init proc_misc_init(void)
8566                 {"stram",       stram_read_proc},
8567  #endif
8568                 {"filesystems", filesystems_read_proc},
8569 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
8570                 {"cmdline",     cmdline_read_proc},
8571 +#endif
8572                 {"locks",       locks_read_proc},
8573                 {"execdomains", execdomains_read_proc},
8574                 {NULL,}
8575 @@ -674,31 +678,49 @@ void __init proc_misc_init(void)
8576         for (p = simple_ones; p->name; p++)
8577                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
8578  
8579 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8580 +       gr_mode = S_IRUSR;
8581 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8582 +       gr_mode = S_IRUSR | S_IRGRP;
8583 +#endif
8584 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8585 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
8586 +#endif
8587 +
8588         proc_symlink("mounts", NULL, "self/mounts");
8589  
8590         /* And now for trickier ones */
8591         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
8592         if (entry)
8593                 entry->proc_fops = &proc_kmsg_operations;
8594 +
8595 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8596 +       create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
8597 +#else
8598         create_seq_entry("devices", 0, &proc_devinfo_operations);
8599 +#endif
8600         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
8601         create_seq_entry("partitions", 0, &proc_partitions_operations);
8602         create_seq_entry("stat", 0, &proc_stat_operations);
8603         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
8604  #ifdef CONFIG_SLAB
8605 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8606 +       create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
8607 +#else
8608         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
8609  #endif
8610 +#endif
8611         create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
8612         create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
8613         create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
8614         create_seq_entry("diskstats", 0, &proc_diskstats_operations);
8615  #ifdef CONFIG_MODULES
8616 -       create_seq_entry("modules", 0, &proc_modules_operations);
8617 +       create_seq_entry("modules", gr_mode, &proc_modules_operations);
8618  #endif
8619  #ifdef CONFIG_SCHEDSTATS
8620         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
8621  #endif
8622 -#ifdef CONFIG_PROC_KCORE
8623 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
8624         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
8625         if (proc_root_kcore) {
8626                 proc_root_kcore->proc_fops = &proc_kcore_operations;
8627 diff -urNp linux-2.6.16.12/fs/proc/root.c linux-2.6.16.12/fs/proc/root.c
8628 --- linux-2.6.16.12/fs/proc/root.c      2006-05-01 15:14:26.000000000 -0400
8629 +++ linux-2.6.16.12/fs/proc/root.c      2006-05-01 20:17:33.000000000 -0400
8630 @@ -56,7 +56,13 @@ void __init proc_root_init(void)
8631                 return;
8632         }
8633         proc_misc_init();
8634 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8635 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
8636 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8637 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
8638 +#else
8639         proc_net = proc_mkdir("net", NULL);
8640 +#endif
8641         proc_net_stat = proc_mkdir("net/stat", NULL);
8642  
8643  #ifdef CONFIG_SYSVIPC
8644 @@ -80,7 +86,15 @@ void __init proc_root_init(void)
8645  #ifdef CONFIG_PROC_DEVICETREE
8646         proc_device_tree_init();
8647  #endif
8648 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8649 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8650 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
8651 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8652 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
8653 +#endif
8654 +#else
8655         proc_bus = proc_mkdir("bus", NULL);
8656 +#endif
8657         proc_vx_init();
8658  }
8659  
8660 diff -urNp linux-2.6.16.12/fs/proc/task_mmu.c linux-2.6.16.12/fs/proc/task_mmu.c
8661 --- linux-2.6.16.12/fs/proc/task_mmu.c  2006-05-01 15:14:26.000000000 -0400
8662 +++ linux-2.6.16.12/fs/proc/task_mmu.c  2006-05-01 20:17:33.000000000 -0400
8663 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
8664                 "VmStk:\t%8lu kB\n"
8665                 "VmExe:\t%8lu kB\n"
8666                 "VmLib:\t%8lu kB\n"
8667 -               "VmPTE:\t%8lu kB\n",
8668 -               hiwater_vm << (PAGE_SHIFT-10),
8669 +               "VmPTE:\t%8lu kB\n"
8670 +
8671 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8672 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
8673 +#endif
8674 +
8675 +               ,hiwater_vm << (PAGE_SHIFT-10),
8676                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
8677                 mm->locked_vm << (PAGE_SHIFT-10),
8678                 hiwater_rss << (PAGE_SHIFT-10),
8679                 total_rss << (PAGE_SHIFT-10),
8680                 data << (PAGE_SHIFT-10),
8681                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
8682 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
8683 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
8684 +
8685 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8686 +               , mm->context.user_cs_base, mm->context.user_cs_limit
8687 +#endif
8688 +
8689 +       );
8690 +
8691         return buffer;
8692  }
8693  
8694 @@ -118,6 +130,12 @@ struct mem_size_stats
8695         unsigned long private_dirty;
8696  };
8697  
8698 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8699 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
8700 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
8701 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
8702 +#endif
8703 +
8704  static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
8705  {
8706         struct task_struct *task = m->private;
8707 @@ -136,13 +154,30 @@ static int show_map_internal(struct seq_
8708         }
8709  
8710         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
8711 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8712 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
8713 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
8714 +#else
8715                         vma->vm_start,
8716                         vma->vm_end,
8717 +#endif
8718 +
8719 +#if 0
8720 +                       flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
8721 +                       flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
8722 +                       flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
8723 +#else
8724                         flags & VM_READ ? 'r' : '-',
8725                         flags & VM_WRITE ? 'w' : '-',
8726                         flags & VM_EXEC ? 'x' : '-',
8727 +#endif
8728 +
8729                         flags & VM_MAYSHARE ? 's' : 'p',
8730 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8731 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
8732 +#else
8733                         vma->vm_pgoff << PAGE_SHIFT,
8734 +#endif
8735                         MAJOR(dev), MINOR(dev), ino, &len);
8736  
8737         /*
8738 @@ -154,13 +189,13 @@ static int show_map_internal(struct seq_
8739                 seq_path(m, file->f_vfsmnt, file->f_dentry, "\n");
8740         } else {
8741                 if (mm) {
8742 -                       if (vma->vm_start <= mm->start_brk &&
8743 -                                               vma->vm_end >= mm->brk) {
8744 +                       if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
8745                                 pad_len_spaces(m, len);
8746                                 seq_puts(m, "[heap]");
8747                         } else {
8748 -                               if (vma->vm_start <= mm->start_stack &&
8749 -                                       vma->vm_end >= mm->start_stack) {
8750 +                               if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
8751 +                                   (vma->vm_start <= mm->start_stack &&
8752 +                                       vma->vm_end >= mm->start_stack)) {
8753  
8754                                         pad_len_spaces(m, len);
8755                                         seq_puts(m, "[stack]");
8756 @@ -173,7 +208,25 @@ static int show_map_internal(struct seq_
8757         }
8758         seq_putc(m, '\n');
8759  
8760 -       if (mss)
8761 +       
8762 +       if (mss) {
8763 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8764 +           if (PAX_RAND_FLAGS(mm))
8765 +               seq_printf(m,
8766 +                          "Size:          %8lu kB\n"
8767 +                          "Rss:           %8lu kB\n"
8768 +                          "Shared_Clean:  %8lu kB\n"
8769 +                          "Shared_Dirty:  %8lu kB\n"
8770 +                          "Private_Clean: %8lu kB\n"
8771 +                          "Private_Dirty: %8lu kB\n",
8772 +                          0UL,
8773 +                          0UL,
8774 +                          0UL,
8775 +                          0UL,
8776 +                          0UL,
8777 +                          0UL);
8778 +           else
8779 +#endif
8780                 seq_printf(m,
8781                            "Size:          %8lu kB\n"
8782                            "Rss:           %8lu kB\n"
8783 @@ -187,6 +240,7 @@ static int show_map_internal(struct seq_
8784                            mss->shared_dirty  >> 10,
8785                            mss->private_clean >> 10,
8786                            mss->private_dirty >> 10);
8787 +       }
8788  
8789         if (m->count < m->size)  /* vma is copied successfully */
8790                 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
8791 diff -urNp linux-2.6.16.12/fs/readdir.c linux-2.6.16.12/fs/readdir.c
8792 --- linux-2.6.16.12/fs/readdir.c        2006-05-01 15:14:26.000000000 -0400
8793 +++ linux-2.6.16.12/fs/readdir.c        2006-05-01 20:17:33.000000000 -0400
8794 @@ -16,6 +16,8 @@
8795  #include <linux/security.h>
8796  #include <linux/syscalls.h>
8797  #include <linux/unistd.h>
8798 +#include <linux/namei.h>
8799 +#include <linux/grsecurity.h>
8800  
8801  #include <asm/uaccess.h>
8802  
8803 @@ -65,6 +67,7 @@ struct old_linux_dirent {
8804  
8805  struct readdir_callback {
8806         struct old_linux_dirent __user * dirent;
8807 +       struct file * file;
8808         int result;
8809  };
8810  
8811 @@ -76,6 +79,10 @@ static int fillonedir(void * __buf, cons
8812  
8813         if (buf->result)
8814                 return -EINVAL;
8815 +
8816 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8817 +               return 0;
8818 +
8819         buf->result++;
8820         dirent = buf->dirent;
8821         if (!access_ok(VERIFY_WRITE, dirent,
8822 @@ -107,6 +114,7 @@ asmlinkage long old_readdir(unsigned int
8823  
8824         buf.result = 0;
8825         buf.dirent = dirent;
8826 +       buf.file = file;
8827  
8828         error = vfs_readdir(file, fillonedir, &buf);
8829         if (error >= 0)
8830 @@ -133,6 +141,7 @@ struct linux_dirent {
8831  struct getdents_callback {
8832         struct linux_dirent __user * current_dir;
8833         struct linux_dirent __user * previous;
8834 +       struct file * file;
8835         int count;
8836         int error;
8837  };
8838 @@ -147,6 +156,10 @@ static int filldir(void * __buf, const c
8839         buf->error = -EINVAL;   /* only used if we fail.. */
8840         if (reclen > buf->count)
8841                 return -EINVAL;
8842 +
8843 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8844 +               return 0;
8845 +
8846         dirent = buf->previous;
8847         if (dirent) {
8848                 if (__put_user(offset, &dirent->d_off))
8849 @@ -191,6 +204,7 @@ asmlinkage long sys_getdents(unsigned in
8850  
8851         buf.current_dir = dirent;
8852         buf.previous = NULL;
8853 +       buf.file = file;
8854         buf.count = count;
8855         buf.error = 0;
8856  
8857 @@ -217,6 +231,7 @@ out:
8858  struct getdents_callback64 {
8859         struct linux_dirent64 __user * current_dir;
8860         struct linux_dirent64 __user * previous;
8861 +       struct file * file;
8862         int count;
8863         int error;
8864  };
8865 @@ -231,6 +246,10 @@ static int filldir64(void * __buf, const
8866         buf->error = -EINVAL;   /* only used if we fail.. */
8867         if (reclen > buf->count)
8868                 return -EINVAL;
8869 +
8870 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8871 +               return 0;
8872 +
8873         dirent = buf->previous;
8874         if (dirent) {
8875                 if (__put_user(offset, &dirent->d_off))
8876 @@ -277,6 +296,7 @@ asmlinkage long sys_getdents64(unsigned 
8877  
8878         buf.current_dir = dirent;
8879         buf.previous = NULL;
8880 +       buf.file = file;
8881         buf.count = count;
8882         buf.error = 0;
8883  
8884 diff -urNp linux-2.6.16.12/fs/xfs/linux-2.6/xfs_file.c linux-2.6.16.12/fs/xfs/linux-2.6/xfs_file.c
8885 --- linux-2.6.16.12/fs/xfs/linux-2.6/xfs_file.c 2006-05-01 15:14:26.000000000 -0400
8886 +++ linux-2.6.16.12/fs/xfs/linux-2.6/xfs_file.c 2006-05-01 20:17:33.000000000 -0400
8887 @@ -413,6 +413,11 @@ linvfs_file_mmap(
8888         vattr_t         va = { .va_mask = XFS_AT_UPDATIME };
8889         int             error;
8890  
8891 +#ifdef CONFIG_PAX_PAGEEXEC
8892 +       if (vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC)
8893 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
8894 +#endif
8895 +
8896         vma->vm_ops = &linvfs_file_vm_ops;
8897  
8898  #ifdef CONFIG_XFS_DMAPI
8899 diff -urNp linux-2.6.16.12/grsecurity/gracl_alloc.c linux-2.6.16.12/grsecurity/gracl_alloc.c
8900 --- linux-2.6.16.12/grsecurity/gracl_alloc.c    1969-12-31 19:00:00.000000000 -0500
8901 +++ linux-2.6.16.12/grsecurity/gracl_alloc.c    2006-05-01 20:17:33.000000000 -0400
8902 @@ -0,0 +1,91 @@
8903 +#include <linux/kernel.h>
8904 +#include <linux/mm.h>
8905 +#include <linux/slab.h>
8906 +#include <linux/vmalloc.h>
8907 +#include <linux/gracl.h>
8908 +#include <linux/grsecurity.h>
8909 +
8910 +static unsigned long alloc_stack_next = 1;
8911 +static unsigned long alloc_stack_size = 1;
8912 +static void **alloc_stack;
8913 +
8914 +static __inline__ int
8915 +alloc_pop(void)
8916 +{
8917 +       if (alloc_stack_next == 1)
8918 +               return 0;
8919 +
8920 +       kfree(alloc_stack[alloc_stack_next - 2]);
8921 +
8922 +       alloc_stack_next--;
8923 +
8924 +       return 1;
8925 +}
8926 +
8927 +static __inline__ void
8928 +alloc_push(void *buf)
8929 +{
8930 +       if (alloc_stack_next >= alloc_stack_size)
8931 +               BUG();
8932 +
8933 +       alloc_stack[alloc_stack_next - 1] = buf;
8934 +
8935 +       alloc_stack_next++;
8936 +
8937 +       return;
8938 +}
8939 +
8940 +void *
8941 +acl_alloc(unsigned long len)
8942 +{
8943 +       void *ret;
8944 +
8945 +       if (len > PAGE_SIZE)
8946 +               BUG();
8947 +
8948 +       ret = kmalloc(len, GFP_KERNEL);
8949 +
8950 +       if (ret)
8951 +               alloc_push(ret);
8952 +
8953 +       return ret;
8954 +}
8955 +
8956 +void
8957 +acl_free_all(void)
8958 +{
8959 +       if (gr_acl_is_enabled() || !alloc_stack)
8960 +               return;
8961 +
8962 +       while (alloc_pop()) ;
8963 +
8964 +       if (alloc_stack) {
8965 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
8966 +                       kfree(alloc_stack);
8967 +               else
8968 +                       vfree(alloc_stack);
8969 +       }
8970 +
8971 +       alloc_stack = NULL;
8972 +       alloc_stack_size = 1;
8973 +       alloc_stack_next = 1;
8974 +
8975 +       return;
8976 +}
8977 +
8978 +int
8979 +acl_alloc_stack_init(unsigned long size)
8980 +{
8981 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
8982 +               alloc_stack =
8983 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
8984 +       else
8985 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
8986 +
8987 +       alloc_stack_size = size;
8988 +
8989 +       if (!alloc_stack)
8990 +               return 0;
8991 +       else
8992 +               return 1;
8993 +}
8994 diff -urNp linux-2.6.16.12/grsecurity/gracl.c linux-2.6.16.12/grsecurity/gracl.c
8995 --- linux-2.6.16.12/grsecurity/gracl.c  1969-12-31 19:00:00.000000000 -0500
8996 +++ linux-2.6.16.12/grsecurity/gracl.c  2006-05-01 20:17:33.000000000 -0400
8997 @@ -0,0 +1,3533 @@
8998 +#include <linux/kernel.h>
8999 +#include <linux/module.h>
9000 +#include <linux/sched.h>
9001 +#include <linux/mm.h>
9002 +#include <linux/file.h>
9003 +#include <linux/fs.h>
9004 +#include <linux/namei.h>
9005 +#include <linux/mount.h>
9006 +#include <linux/tty.h>
9007 +#include <linux/proc_fs.h>
9008 +#include <linux/smp_lock.h>
9009 +#include <linux/slab.h>
9010 +#include <linux/vmalloc.h>
9011 +#include <linux/types.h>
9012 +#include <linux/capability.h>
9013 +#include <linux/sysctl.h>
9014 +#include <linux/netdevice.h>
9015 +#include <linux/ptrace.h>
9016 +#include <linux/gracl.h>
9017 +#include <linux/gralloc.h>
9018 +#include <linux/grsecurity.h>
9019 +#include <linux/grinternal.h>
9020 +#include <linux/percpu.h>
9021 +
9022 +#include <asm/uaccess.h>
9023 +#include <asm/errno.h>
9024 +#include <asm/mman.h>
9025 +
9026 +static struct acl_role_db acl_role_set;
9027 +static struct name_db name_set;
9028 +static struct inodev_db inodev_set;
9029 +
9030 +/* for keeping track of userspace pointers used for subjects, so we
9031 +   can share references in the kernel as well
9032 +*/
9033 +
9034 +static struct dentry *real_root;
9035 +static struct vfsmount *real_root_mnt;
9036 +
9037 +static struct acl_subj_map_db subj_map_set;
9038 +
9039 +static struct acl_role_label *default_role;
9040 +
9041 +static u16 acl_sp_role_value;
9042 +
9043 +extern char *gr_shared_page[4];
9044 +static DECLARE_MUTEX(gr_dev_sem);
9045 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
9046 +
9047 +struct gr_arg *gr_usermode;
9048 +
9049 +static unsigned int gr_status = GR_STATUS_INIT;
9050 +
9051 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
9052 +extern void gr_clear_learn_entries(void);
9053 +
9054 +#ifdef CONFIG_GRKERNSEC_RESLOG
9055 +extern void gr_log_resource(const struct task_struct *task,
9056 +                           const int res, const unsigned long wanted, const int gt);
9057 +#endif
9058 +
9059 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
9060 +                        struct dentry *root, struct vfsmount *rootmnt,
9061 +                        char *buffer, int buflen);
9062 +
9063 +unsigned char *gr_system_salt;
9064 +unsigned char *gr_system_sum;
9065 +
9066 +static struct sprole_pw **acl_special_roles = NULL;
9067 +static __u16 num_sprole_pws = 0;
9068 +
9069 +static struct acl_role_label *kernel_role = NULL;
9070 +
9071 +static unsigned int gr_auth_attempts = 0;
9072 +static unsigned long gr_auth_expires = 0UL;
9073 +
9074 +extern int gr_init_uidset(void);
9075 +extern void gr_free_uidset(void);
9076 +extern void gr_remove_uid(uid_t uid);
9077 +extern int gr_find_uid(uid_t uid);
9078 +
9079 +__inline__ int
9080 +gr_acl_is_enabled(void)
9081 +{
9082 +       return (gr_status & GR_READY);
9083 +}
9084 +
9085 +char gr_roletype_to_char(void)
9086 +{
9087 +       switch (current->role->roletype &
9088 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
9089 +                GR_ROLE_SPECIAL)) {
9090 +       case GR_ROLE_DEFAULT:
9091 +               return 'D';
9092 +       case GR_ROLE_USER:
9093 +               return 'U';
9094 +       case GR_ROLE_GROUP:
9095 +               return 'G';
9096 +       case GR_ROLE_SPECIAL:
9097 +               return 'S';
9098 +       }
9099 +
9100 +       return 'X';
9101 +}
9102 +
9103 +__inline__ int
9104 +gr_acl_tpe_check(void)
9105 +{
9106 +       if (unlikely(!(gr_status & GR_READY)))
9107 +               return 0;
9108 +       if (current->role->roletype & GR_ROLE_TPE)
9109 +               return 1;
9110 +       else
9111 +               return 0;
9112 +}
9113 +
9114 +int
9115 +gr_handle_rawio(const struct inode *inode)
9116 +{
9117 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
9118 +       if (inode && S_ISBLK(inode->i_mode) &&
9119 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
9120 +           !capable(CAP_SYS_RAWIO))
9121 +               return 1;
9122 +#endif
9123 +       return 0;
9124 +}
9125 +
9126 +static int
9127 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
9128 +{
9129 +       int i;
9130 +       unsigned long *l1;
9131 +       unsigned long *l2;
9132 +       unsigned char *c1;
9133 +       unsigned char *c2;
9134 +       int num_longs;
9135 +
9136 +       if (likely(lena != lenb))
9137 +               return 0;
9138 +
9139 +       l1 = (unsigned long *)a;
9140 +       l2 = (unsigned long *)b;
9141 +
9142 +       num_longs = lena / sizeof(unsigned long);
9143 +
9144 +       for (i = num_longs; i--; l1++, l2++) {
9145 +               if (unlikely(*l1 != *l2))
9146 +                       return 0;
9147 +       }
9148 +
9149 +       c1 = (unsigned char *) l1;
9150 +       c2 = (unsigned char *) l2;
9151 +
9152 +       i = lena - (num_longs * sizeof(unsigned long)); 
9153 +
9154 +       for (; i--; c1++, c2++) {
9155 +               if (unlikely(*c1 != *c2))
9156 +                       return 0;
9157 +       }
9158 +
9159 +       return 1;
9160 +}
9161 +               
9162 +static char *
9163 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
9164 +              struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
9165 +{
9166 +       char *end = buf + buflen;
9167 +       char *retval;
9168 +       int namelen = 0;
9169 +
9170 +       *--end = '\0';
9171 +
9172 +       retval = end - 1;
9173 +       *retval = '/';
9174 +
9175 +       if (dentry == root && vfsmnt == rootmnt)
9176 +               return retval;
9177 +       if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
9178 +               namelen = strlen(dentry->d_name.name);
9179 +               buflen -= namelen;
9180 +               if (buflen < 2)
9181 +                       goto err;
9182 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
9183 +                       buflen--;
9184 +       }
9185 +
9186 +       retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
9187 +       if (unlikely(IS_ERR(retval)))
9188 +err:
9189 +               retval = strcpy(buf, "<path too long>");
9190 +       else if (namelen != 0) {
9191 +               end = buf + buflen - 1; // accounts for null termination
9192 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
9193 +                       *end++ = '/'; // accounted for above with buflen--
9194 +               memcpy(end, dentry->d_name.name, namelen);
9195 +       }
9196 +
9197 +       return retval;
9198 +}
9199 +
9200 +static char *
9201 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
9202 +               char *buf, int buflen)
9203 +{
9204 +       char *res;
9205 +
9206 +       /* we can use real_root, real_root_mnt, because this is only called
9207 +          by the RBAC system */
9208 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
9209 +
9210 +       return res;
9211 +}
9212 +
9213 +static char *
9214 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
9215 +           char *buf, int buflen)
9216 +{
9217 +       char *res;
9218 +       struct dentry *root;
9219 +       struct vfsmount *rootmnt;
9220 +
9221 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
9222 +       read_lock(&child_reaper->fs->lock);
9223 +       root = dget(child_reaper->fs->root);
9224 +       rootmnt = mntget(child_reaper->fs->rootmnt);
9225 +       read_unlock(&child_reaper->fs->lock);
9226 +
9227 +       spin_lock(&dcache_lock);
9228 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
9229 +       spin_unlock(&dcache_lock);
9230 +
9231 +       dput(root);
9232 +       mntput(rootmnt);
9233 +       return res;
9234 +}
9235 +
9236 +static char *
9237 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
9238 +{
9239 +       char *ret;
9240 +       spin_lock(&dcache_lock);
9241 +       ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
9242 +                            PAGE_SIZE);
9243 +       spin_unlock(&dcache_lock);
9244 +       return ret;
9245 +}
9246 +
9247 +char *
9248 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
9249 +{
9250 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
9251 +                            PAGE_SIZE);
9252 +}
9253 +
9254 +char *
9255 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
9256 +{
9257 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
9258 +                          PAGE_SIZE);
9259 +}
9260 +
9261 +char *
9262 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
9263 +{
9264 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
9265 +                          PAGE_SIZE);
9266 +}
9267 +
9268 +char *
9269 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
9270 +{
9271 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
9272 +                          PAGE_SIZE);
9273 +}
9274 +
9275 +char *
9276 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
9277 +{
9278 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
9279 +                          PAGE_SIZE);
9280 +}
9281 +
9282 +__inline__ __u32
9283 +to_gr_audit(const __u32 reqmode)
9284 +{
9285 +       /* masks off auditable permission flags, then shifts them to create
9286 +          auditing flags, and adds the special case of append auditing if
9287 +          we're requesting write */
9288 +       return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
9289 +}
9290 +
9291 +struct acl_subject_label *
9292 +lookup_subject_map(const struct acl_subject_label *userp)
9293 +{
9294 +       unsigned int index = shash(userp, subj_map_set.s_size);
9295 +       struct subject_map *match;
9296 +
9297 +       match = subj_map_set.s_hash[index];
9298 +
9299 +       while (match && match->user != userp)
9300 +               match = match->next;
9301 +
9302 +       if (match != NULL)
9303 +               return match->kernel;
9304 +       else
9305 +               return NULL;
9306 +}
9307 +
9308 +static void
9309 +insert_subj_map_entry(struct subject_map *subjmap)
9310 +{
9311 +       unsigned int index = shash(subjmap->user, subj_map_set.s_size);
9312 +       struct subject_map **curr;
9313 +
9314 +       subjmap->prev = NULL;
9315 +
9316 +       curr = &subj_map_set.s_hash[index];
9317 +       if (*curr != NULL)
9318 +               (*curr)->prev = subjmap;
9319 +
9320 +       subjmap->next = *curr;
9321 +       *curr = subjmap;
9322 +
9323 +       return;
9324 +}
9325 +
9326 +static struct acl_role_label *
9327 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
9328 +                     const gid_t gid)
9329 +{
9330 +       unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
9331 +       struct acl_role_label *match;
9332 +       struct role_allowed_ip *ipp;
9333 +       unsigned int x;
9334 +
9335 +       match = acl_role_set.r_hash[index];
9336 +
9337 +       while (match) {
9338 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
9339 +                       for (x = 0; x < match->domain_child_num; x++) {
9340 +                               if (match->domain_children[x] == uid)
9341 +                                       goto found;
9342 +                       }
9343 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
9344 +                       break;
9345 +               match = match->next;
9346 +       }
9347 +found:
9348 +       if (match == NULL) {
9349 +             try_group:
9350 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
9351 +               match = acl_role_set.r_hash[index];
9352 +
9353 +               while (match) {
9354 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
9355 +                               for (x = 0; x < match->domain_child_num; x++) {
9356 +                                       if (match->domain_children[x] == gid)
9357 +                                               goto found2;
9358 +                               }
9359 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
9360 +                               break;
9361 +                       match = match->next;
9362 +               }
9363 +found2:
9364 +               if (match == NULL)
9365 +                       match = default_role;
9366 +               if (match->allowed_ips == NULL)
9367 +                       return match;
9368 +               else {
9369 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
9370 +                               if (likely
9371 +                                   ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
9372 +                                    (ntohl(ipp->addr) & ipp->netmask)))
9373 +                                       return match;
9374 +                       }
9375 +                       match = default_role;
9376 +               }
9377 +       } else if (match->allowed_ips == NULL) {
9378 +               return match;
9379 +       } else {
9380 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
9381 +                       if (likely
9382 +                           ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
9383 +                            (ntohl(ipp->addr) & ipp->netmask)))
9384 +                               return match;
9385 +               }
9386 +               goto try_group;
9387 +       }
9388 +
9389 +       return match;
9390 +}
9391 +
9392 +struct acl_subject_label *
9393 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
9394 +                     const struct acl_role_label *role)
9395 +{
9396 +       unsigned int index = fhash(ino, dev, role->subj_hash_size);
9397 +       struct acl_subject_label *match;
9398 +
9399 +       match = role->subj_hash[index];
9400 +
9401 +       while (match && (match->inode != ino || match->device != dev ||
9402 +              (match->mode & GR_DELETED))) {
9403 +               match = match->next;
9404 +       }
9405 +
9406 +       if (match && !(match->mode & GR_DELETED))
9407 +               return match;
9408 +       else
9409 +               return NULL;
9410 +}
9411 +
9412 +static struct acl_object_label *
9413 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
9414 +                    const struct acl_subject_label *subj)
9415 +{
9416 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
9417 +       struct acl_object_label *match;
9418 +
9419 +       match = subj->obj_hash[index];
9420 +
9421 +       while (match && (match->inode != ino || match->device != dev ||
9422 +              (match->mode & GR_DELETED))) {
9423 +               match = match->next;
9424 +       }
9425 +
9426 +       if (match && !(match->mode & GR_DELETED))
9427 +               return match;
9428 +       else
9429 +               return NULL;
9430 +}
9431 +
9432 +static struct acl_object_label *
9433 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
9434 +                    const struct acl_subject_label *subj)
9435 +{
9436 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
9437 +       struct acl_object_label *match;
9438 +
9439 +       match = subj->obj_hash[index];
9440 +
9441 +       while (match && (match->inode != ino || match->device != dev ||
9442 +              !(match->mode & GR_DELETED))) {
9443 +               match = match->next;
9444 +       }
9445 +
9446 +       if (match && (match->mode & GR_DELETED))
9447 +               return match;
9448 +
9449 +       match = subj->obj_hash[index];
9450 +
9451 +       while (match && (match->inode != ino || match->device != dev ||
9452 +              (match->mode & GR_DELETED))) {
9453 +               match = match->next;
9454 +       }
9455 +
9456 +       if (match && !(match->mode & GR_DELETED))
9457 +               return match;
9458 +       else
9459 +               return NULL;
9460 +}
9461 +
9462 +static struct name_entry *
9463 +lookup_name_entry(const char *name)
9464 +{
9465 +       unsigned int len = strlen(name);
9466 +       unsigned int key = full_name_hash(name, len);
9467 +       unsigned int index = key % name_set.n_size;
9468 +       struct name_entry *match;
9469 +
9470 +       match = name_set.n_hash[index];
9471 +
9472 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
9473 +               match = match->next;
9474 +
9475 +       return match;
9476 +}
9477 +
9478 +static struct inodev_entry *
9479 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
9480 +{
9481 +       unsigned int index = fhash(ino, dev, inodev_set.i_size);
9482 +       struct inodev_entry *match;
9483 +
9484 +       match = inodev_set.i_hash[index];
9485 +
9486 +       while (match && (match->nentry->inode != ino || match->nentry->device != dev))
9487 +               match = match->next;
9488 +
9489 +       return match;
9490 +}
9491 +
9492 +static void
9493 +insert_inodev_entry(struct inodev_entry *entry)
9494 +{
9495 +       unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
9496 +                                   inodev_set.i_size);
9497 +       struct inodev_entry **curr;
9498 +
9499 +       entry->prev = NULL;
9500 +
9501 +       curr = &inodev_set.i_hash[index];
9502 +       if (*curr != NULL)
9503 +               (*curr)->prev = entry;
9504 +       
9505 +       entry->next = *curr;
9506 +       *curr = entry;
9507 +
9508 +       return;
9509 +}
9510 +
9511 +static void
9512 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
9513 +{
9514 +       unsigned int index =
9515 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
9516 +       struct acl_role_label **curr;
9517 +
9518 +       role->prev = NULL;
9519 +
9520 +       curr = &acl_role_set.r_hash[index];
9521 +       if (*curr != NULL)
9522 +               (*curr)->prev = role;
9523 +
9524 +       role->next = *curr;
9525 +       *curr = role;
9526 +
9527 +       return;
9528 +}
9529 +
9530 +static void
9531 +insert_acl_role_label(struct acl_role_label *role)
9532 +{
9533 +       int i;
9534 +
9535 +       if (role->roletype & GR_ROLE_DOMAIN) {
9536 +               for (i = 0; i < role->domain_child_num; i++)
9537 +                       __insert_acl_role_label(role, role->domain_children[i]);
9538 +       } else
9539 +               __insert_acl_role_label(role, role->uidgid);
9540 +}
9541 +                                       
9542 +static int
9543 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
9544 +{
9545 +       struct name_entry **curr, *nentry;
9546 +       struct inodev_entry *ientry;
9547 +       unsigned int len = strlen(name);
9548 +       unsigned int key = full_name_hash(name, len);
9549 +       unsigned int index = key % name_set.n_size;
9550 +
9551 +       curr = &name_set.n_hash[index];
9552 +
9553 +       while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
9554 +               curr = &((*curr)->next);
9555 +
9556 +       if (*curr != NULL)
9557 +               return 1;
9558 +
9559 +       nentry = acl_alloc(sizeof (struct name_entry));
9560 +       if (nentry == NULL)
9561 +               return 0;
9562 +       ientry = acl_alloc(sizeof (struct inodev_entry));
9563 +       if (ientry == NULL)
9564 +               return 0;
9565 +       ientry->nentry = nentry;
9566 +
9567 +       nentry->key = key;
9568 +       nentry->name = name;
9569 +       nentry->inode = inode;
9570 +       nentry->device = device;
9571 +       nentry->len = len;
9572 +
9573 +       nentry->prev = NULL;
9574 +       curr = &name_set.n_hash[index];
9575 +       if (*curr != NULL)
9576 +               (*curr)->prev = nentry;
9577 +       nentry->next = *curr;
9578 +       *curr = nentry;
9579 +
9580 +       /* insert us into the table searchable by inode/dev */
9581 +       insert_inodev_entry(ientry);
9582 +
9583 +       return 1;
9584 +}
9585 +
9586 +static void
9587 +insert_acl_obj_label(struct acl_object_label *obj,
9588 +                    struct acl_subject_label *subj)
9589 +{
9590 +       unsigned int index =
9591 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
9592 +       struct acl_object_label **curr;
9593 +
9594 +       
9595 +       obj->prev = NULL;
9596 +
9597 +       curr = &subj->obj_hash[index];
9598 +       if (*curr != NULL)
9599 +               (*curr)->prev = obj;
9600 +
9601 +       obj->next = *curr;
9602 +       *curr = obj;
9603 +
9604 +       return;
9605 +}
9606 +
9607 +static void
9608 +insert_acl_subj_label(struct acl_subject_label *obj,
9609 +                     struct acl_role_label *role)
9610 +{
9611 +       unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
9612 +       struct acl_subject_label **curr;
9613 +
9614 +       obj->prev = NULL;
9615 +
9616 +       curr = &role->subj_hash[index];
9617 +       if (*curr != NULL)
9618 +               (*curr)->prev = obj;
9619 +
9620 +       obj->next = *curr;
9621 +       *curr = obj;
9622 +
9623 +       return;
9624 +}
9625 +
9626 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
9627 +
9628 +static void *
9629 +create_table(__u32 * len, int elementsize)
9630 +{
9631 +       unsigned int table_sizes[] = {
9632 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
9633 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
9634 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
9635 +               268435399, 536870909, 1073741789, 2147483647
9636 +       };
9637 +       void *newtable = NULL;
9638 +       unsigned int pwr = 0;
9639 +
9640 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
9641 +              table_sizes[pwr] <= *len)
9642 +               pwr++;
9643 +
9644 +       if (table_sizes[pwr] <= *len)
9645 +               return newtable;
9646 +
9647 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
9648 +               newtable =
9649 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
9650 +       else
9651 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
9652 +
9653 +       *len = table_sizes[pwr];
9654 +
9655 +       return newtable;
9656 +}
9657 +
9658 +static int
9659 +init_variables(const struct gr_arg *arg)
9660 +{
9661 +       unsigned int stacksize;
9662 +
9663 +       subj_map_set.s_size = arg->role_db.num_subjects;
9664 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
9665 +       name_set.n_size = arg->role_db.num_objects;
9666 +       inodev_set.i_size = arg->role_db.num_objects;
9667 +
9668 +       if (!subj_map_set.s_size || !acl_role_set.r_size ||
9669 +           !name_set.n_size || !inodev_set.i_size)
9670 +               return 1;
9671 +
9672 +       if (!gr_init_uidset())
9673 +               return 1;
9674 +
9675 +       /* set up the stack that holds allocation info */
9676 +
9677 +       stacksize = arg->role_db.num_pointers + 5;
9678 +
9679 +       if (!acl_alloc_stack_init(stacksize))
9680 +               return 1;
9681 +
9682 +       /* grab reference for the real root dentry and vfsmount */
9683 +       read_lock(&child_reaper->fs->lock);
9684 +       real_root_mnt = mntget(child_reaper->fs->rootmnt);
9685 +       real_root = dget(child_reaper->fs->root);
9686 +       read_unlock(&child_reaper->fs->lock);
9687 +       
9688 +
9689 +       subj_map_set.s_hash =
9690 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
9691 +       acl_role_set.r_hash =
9692 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
9693 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
9694 +       inodev_set.i_hash =
9695 +           (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
9696 +
9697 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
9698 +           !name_set.n_hash || !inodev_set.i_hash)
9699 +               return 1;
9700 +
9701 +       memset(subj_map_set.s_hash, 0,
9702 +              sizeof(struct subject_map *) * subj_map_set.s_size);
9703 +       memset(acl_role_set.r_hash, 0,
9704 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
9705 +       memset(name_set.n_hash, 0,
9706 +              sizeof (struct name_entry *) * name_set.n_size);
9707 +       memset(inodev_set.i_hash, 0,
9708 +              sizeof (struct inodev_entry *) * inodev_set.i_size);
9709 +
9710 +       return 0;
9711 +}
9712 +
9713 +/* free information not needed after startup
9714 +   currently contains user->kernel pointer mappings for subjects
9715 +*/
9716 +
9717 +static void
9718 +free_init_variables(void)
9719 +{
9720 +       __u32 i;
9721 +
9722 +       if (subj_map_set.s_hash) {
9723 +               for (i = 0; i < subj_map_set.s_size; i++) {
9724 +                       if (subj_map_set.s_hash[i]) {
9725 +                               kfree(subj_map_set.s_hash[i]);
9726 +                               subj_map_set.s_hash[i] = NULL;
9727 +                       }
9728 +               }
9729 +
9730 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
9731 +                   PAGE_SIZE)
9732 +                       kfree(subj_map_set.s_hash);
9733 +               else
9734 +                       vfree(subj_map_set.s_hash);
9735 +       }
9736 +
9737 +       return;
9738 +}
9739 +
9740 +static void
9741 +free_variables(void)
9742 +{
9743 +       struct acl_subject_label *s;
9744 +       struct acl_role_label *r;
9745 +       struct task_struct *task, *task2;
9746 +       unsigned int i, x;
9747 +
9748 +       gr_clear_learn_entries();
9749 +
9750 +       read_lock(&tasklist_lock);
9751 +       do_each_thread(task2, task) {
9752 +               task->acl_sp_role = 0;
9753 +               task->acl_role_id = 0;
9754 +               task->acl = NULL;
9755 +               task->role = NULL;
9756 +       } while_each_thread(task2, task);
9757 +       read_unlock(&tasklist_lock);
9758 +
9759 +       /* release the reference to the real root dentry and vfsmount */
9760 +       if (real_root)
9761 +               dput(real_root);
9762 +       real_root = NULL;
9763 +       if (real_root_mnt)
9764 +               mntput(real_root_mnt);
9765 +       real_root_mnt = NULL;
9766 +
9767 +       /* free all object hash tables */
9768 +
9769 +       FOR_EACH_ROLE_START(r, i)
9770 +               if (r->subj_hash == NULL)
9771 +                       break;
9772 +               FOR_EACH_SUBJECT_START(r, s, x)
9773 +                       if (s->obj_hash == NULL)
9774 +                               break;
9775 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
9776 +                               kfree(s->obj_hash);
9777 +                       else
9778 +                               vfree(s->obj_hash);
9779 +               FOR_EACH_SUBJECT_END(s, x)
9780 +               FOR_EACH_NESTED_SUBJECT_START(r, s)
9781 +                       if (s->obj_hash == NULL)
9782 +                               break;
9783 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
9784 +                               kfree(s->obj_hash);
9785 +                       else
9786 +                               vfree(s->obj_hash);
9787 +               FOR_EACH_NESTED_SUBJECT_END(s)
9788 +               if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
9789 +                       kfree(r->subj_hash);
9790 +               else
9791 +                       vfree(r->subj_hash);
9792 +               r->subj_hash = NULL;
9793 +       FOR_EACH_ROLE_END(r,i)
9794 +
9795 +       acl_free_all();
9796 +
9797 +       if (acl_role_set.r_hash) {
9798 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
9799 +                   PAGE_SIZE)
9800 +                       kfree(acl_role_set.r_hash);
9801 +               else
9802 +                       vfree(acl_role_set.r_hash);
9803 +       }
9804 +       if (name_set.n_hash) {
9805 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
9806 +                   PAGE_SIZE)
9807 +                       kfree(name_set.n_hash);
9808 +               else
9809 +                       vfree(name_set.n_hash);
9810 +       }
9811 +
9812 +       if (inodev_set.i_hash) {
9813 +               if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
9814 +                   PAGE_SIZE)
9815 +                       kfree(inodev_set.i_hash);
9816 +               else
9817 +                       vfree(inodev_set.i_hash);
9818 +       }
9819 +
9820 +       gr_free_uidset();
9821 +
9822 +       memset(&name_set, 0, sizeof (struct name_db));
9823 +       memset(&inodev_set, 0, sizeof (struct inodev_db));
9824 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
9825 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
9826 +
9827 +       default_role = NULL;
9828 +
9829 +       return;
9830 +}
9831 +
9832 +static __u32
9833 +count_user_objs(struct acl_object_label *userp)
9834 +{
9835 +       struct acl_object_label o_tmp;
9836 +       __u32 num = 0;
9837 +
9838 +       while (userp) {
9839 +               if (copy_from_user(&o_tmp, userp,
9840 +                                  sizeof (struct acl_object_label)))
9841 +                       break;
9842 +
9843 +               userp = o_tmp.prev;
9844 +               num++;
9845 +       }
9846 +
9847 +       return num;
9848 +}
9849 +
9850 +static struct acl_subject_label *
9851 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
9852 +
9853 +static int
9854 +copy_user_glob(struct acl_object_label *obj)
9855 +{
9856 +       struct acl_object_label *g_tmp, **guser;
9857 +       unsigned int len;
9858 +       char *tmp;
9859 +
9860 +       if (obj->globbed == NULL)
9861 +               return 0;
9862 +
9863 +       guser = &obj->globbed;
9864 +       while (*guser) {
9865 +               g_tmp = (struct acl_object_label *)
9866 +                       acl_alloc(sizeof (struct acl_object_label));
9867 +               if (g_tmp == NULL)
9868 +                       return -ENOMEM;
9869 +
9870 +               if (copy_from_user(g_tmp, *guser,
9871 +                                  sizeof (struct acl_object_label)))
9872 +                       return -EFAULT;
9873 +
9874 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
9875 +
9876 +               if (!len || len >= PATH_MAX)
9877 +                       return -EINVAL;
9878 +
9879 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
9880 +                       return -ENOMEM;
9881 +
9882 +               if (copy_from_user(tmp, g_tmp->filename, len))
9883 +                       return -EFAULT;
9884 +
9885 +               g_tmp->filename = tmp;
9886 +
9887 +               *guser = g_tmp;
9888 +               guser = &(g_tmp->next);
9889 +       }
9890 +
9891 +       return 0;
9892 +}
9893 +
9894 +static int
9895 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
9896 +              struct acl_role_label *role)
9897 +{
9898 +       struct acl_object_label *o_tmp;
9899 +       unsigned int len;
9900 +       int ret;
9901 +       char *tmp;
9902 +
9903 +       while (userp) {
9904 +               if ((o_tmp = (struct acl_object_label *)
9905 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
9906 +                       return -ENOMEM;
9907 +
9908 +               if (copy_from_user(o_tmp, userp,
9909 +                                  sizeof (struct acl_object_label)))
9910 +                       return -EFAULT;
9911 +
9912 +               userp = o_tmp->prev;
9913 +
9914 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
9915 +
9916 +               if (!len || len >= PATH_MAX)
9917 +                       return -EINVAL;
9918 +
9919 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
9920 +                       return -ENOMEM;
9921 +
9922 +               if (copy_from_user(tmp, o_tmp->filename, len))
9923 +                       return -EFAULT;
9924 +
9925 +               o_tmp->filename = tmp;
9926 +
9927 +               insert_acl_obj_label(o_tmp, subj);
9928 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
9929 +                                      o_tmp->device))
9930 +                       return -ENOMEM;
9931 +
9932 +               ret = copy_user_glob(o_tmp);
9933 +               if (ret)
9934 +                       return ret;
9935 +
9936 +               if (o_tmp->nested) {
9937 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
9938 +                       if (IS_ERR(o_tmp->nested))
9939 +                               return PTR_ERR(o_tmp->nested);
9940 +
9941 +                       /* insert into nested subject list */
9942 +                       o_tmp->nested->next = role->hash->first;
9943 +                       role->hash->first = o_tmp->nested;
9944 +               }
9945 +       }
9946 +
9947 +       return 0;
9948 +}
9949 +
9950 +static __u32
9951 +count_user_subjs(struct acl_subject_label *userp)
9952 +{
9953 +       struct acl_subject_label s_tmp;
9954 +       __u32 num = 0;
9955 +
9956 +       while (userp) {
9957 +               if (copy_from_user(&s_tmp, userp,
9958 +                                  sizeof (struct acl_subject_label)))
9959 +                       break;
9960 +
9961 +               userp = s_tmp.prev;
9962 +               /* do not count nested subjects against this count, since
9963 +                  they are not included in the hash table, but are
9964 +                  attached to objects.  We have already counted
9965 +                  the subjects in userspace for the allocation 
9966 +                  stack
9967 +               */
9968 +               if (!(s_tmp.mode & GR_NESTED))
9969 +                       num++;
9970 +       }
9971 +
9972 +       return num;
9973 +}
9974 +
9975 +static int
9976 +copy_user_allowedips(struct acl_role_label *rolep)
9977 +{
9978 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
9979 +
9980 +       ruserip = rolep->allowed_ips;
9981 +
9982 +       while (ruserip) {
9983 +               rlast = rtmp;
9984 +
9985 +               if ((rtmp = (struct role_allowed_ip *)
9986 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
9987 +                       return -ENOMEM;
9988 +
9989 +               if (copy_from_user(rtmp, ruserip,
9990 +                                  sizeof (struct role_allowed_ip)))
9991 +                       return -EFAULT;
9992 +
9993 +               ruserip = rtmp->prev;
9994 +
9995 +               if (!rlast) {
9996 +                       rtmp->prev = NULL;
9997 +                       rolep->allowed_ips = rtmp;
9998 +               } else {
9999 +                       rlast->next = rtmp;
10000 +                       rtmp->prev = rlast;
10001 +               }
10002 +
10003 +               if (!ruserip)
10004 +                       rtmp->next = NULL;
10005 +       }
10006 +
10007 +       return 0;
10008 +}
10009 +
10010 +static int
10011 +copy_user_transitions(struct acl_role_label *rolep)
10012 +{
10013 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
10014 +       
10015 +       unsigned int len;
10016 +       char *tmp;
10017 +
10018 +       rusertp = rolep->transitions;
10019 +
10020 +       while (rusertp) {
10021 +               rlast = rtmp;
10022 +
10023 +               if ((rtmp = (struct role_transition *)
10024 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
10025 +                       return -ENOMEM;
10026 +
10027 +               if (copy_from_user(rtmp, rusertp,
10028 +                                  sizeof (struct role_transition)))
10029 +                       return -EFAULT;
10030 +
10031 +               rusertp = rtmp->prev;
10032 +
10033 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
10034 +
10035 +               if (!len || len >= GR_SPROLE_LEN)
10036 +                       return -EINVAL;
10037 +
10038 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
10039 +                       return -ENOMEM;
10040 +
10041 +               if (copy_from_user(tmp, rtmp->rolename, len))
10042 +                       return -EFAULT;
10043 +
10044 +               rtmp->rolename = tmp;
10045 +
10046 +               if (!rlast) {
10047 +                       rtmp->prev = NULL;
10048 +                       rolep->transitions = rtmp;
10049 +               } else {
10050 +                       rlast->next = rtmp;
10051 +                       rtmp->prev = rlast;
10052 +               }
10053 +
10054 +               if (!rusertp)
10055 +                       rtmp->next = NULL;
10056 +       }
10057 +
10058 +       return 0;
10059 +}
10060 +
10061 +static struct acl_subject_label *
10062 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
10063 +{
10064 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
10065 +       unsigned int len;
10066 +       char *tmp;
10067 +       __u32 num_objs;
10068 +       struct acl_ip_label **i_tmp, *i_utmp2;
10069 +       struct gr_hash_struct ghash;
10070 +       struct subject_map *subjmap;
10071 +       unsigned int i_num;
10072 +       int err;
10073 +
10074 +       s_tmp = lookup_subject_map(userp);
10075 +
10076 +       /* we've already copied this subject into the kernel, just return
10077 +          the reference to it, and don't copy it over again
10078 +       */
10079 +       if (s_tmp)
10080 +               return(s_tmp);
10081 +
10082 +       if ((s_tmp = (struct acl_subject_label *)
10083 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
10084 +               return ERR_PTR(-ENOMEM);
10085 +
10086 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
10087 +       if (subjmap == NULL)
10088 +               return ERR_PTR(-ENOMEM);
10089 +
10090 +       subjmap->user = userp;
10091 +       subjmap->kernel = s_tmp;
10092 +       insert_subj_map_entry(subjmap);
10093 +
10094 +       if (copy_from_user(s_tmp, userp,
10095 +                          sizeof (struct acl_subject_label)))
10096 +               return ERR_PTR(-EFAULT);
10097 +
10098 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
10099 +
10100 +       if (!len || len >= PATH_MAX)
10101 +               return ERR_PTR(-EINVAL);
10102 +
10103 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
10104 +               return ERR_PTR(-ENOMEM);
10105 +
10106 +       if (copy_from_user(tmp, s_tmp->filename, len))
10107 +               return ERR_PTR(-EFAULT);
10108 +
10109 +       s_tmp->filename = tmp;
10110 +
10111 +       if (!strcmp(s_tmp->filename, "/"))
10112 +               role->root_label = s_tmp;
10113 +
10114 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
10115 +               return ERR_PTR(-EFAULT);
10116 +
10117 +       /* copy user and group transition tables */
10118 +
10119 +       if (s_tmp->user_trans_num) {
10120 +               uid_t *uidlist;
10121 +
10122 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
10123 +               if (uidlist == NULL)
10124 +                       return ERR_PTR(-ENOMEM);
10125 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
10126 +                       return ERR_PTR(-EFAULT);
10127 +
10128 +               s_tmp->user_transitions = uidlist;
10129 +       }
10130 +
10131 +       if (s_tmp->group_trans_num) {
10132 +               gid_t *gidlist;
10133 +
10134 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
10135 +               if (gidlist == NULL)
10136 +                       return ERR_PTR(-ENOMEM);
10137 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
10138 +                       return ERR_PTR(-EFAULT);
10139 +
10140 +               s_tmp->group_transitions = gidlist;
10141 +       }
10142 +
10143 +       /* set up object hash table */
10144 +       num_objs = count_user_objs(ghash.first);
10145 +
10146 +       s_tmp->obj_hash_size = num_objs;
10147 +       s_tmp->obj_hash =
10148 +           (struct acl_object_label **)
10149 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
10150 +
10151 +       if (!s_tmp->obj_hash)
10152 +               return ERR_PTR(-ENOMEM);
10153 +
10154 +       memset(s_tmp->obj_hash, 0,
10155 +              s_tmp->obj_hash_size *
10156 +              sizeof (struct acl_object_label *));
10157 +
10158 +       /* add in objects */
10159 +       err = copy_user_objs(ghash.first, s_tmp, role);
10160 +
10161 +       if (err)
10162 +               return ERR_PTR(err);
10163 +
10164 +       /* set pointer for parent subject */
10165 +       if (s_tmp->parent_subject) {
10166 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
10167 +
10168 +               if (IS_ERR(s_tmp2))
10169 +                       return s_tmp2;
10170 +
10171 +               s_tmp->parent_subject = s_tmp2;
10172 +       }
10173 +
10174 +       /* add in ip acls */
10175 +
10176 +       if (!s_tmp->ip_num) {
10177 +               s_tmp->ips = NULL;
10178 +               goto insert;
10179 +       }
10180 +
10181 +       i_tmp =
10182 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
10183 +                                              sizeof (struct
10184 +                                                      acl_ip_label *));
10185 +
10186 +       if (!i_tmp)
10187 +               return ERR_PTR(-ENOMEM);
10188 +
10189 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
10190 +               *(i_tmp + i_num) =
10191 +                   (struct acl_ip_label *)
10192 +                   acl_alloc(sizeof (struct acl_ip_label));
10193 +               if (!*(i_tmp + i_num))
10194 +                       return ERR_PTR(-ENOMEM);
10195 +
10196 +               if (copy_from_user
10197 +                   (&i_utmp2, s_tmp->ips + i_num,
10198 +                    sizeof (struct acl_ip_label *)))
10199 +                       return ERR_PTR(-EFAULT);
10200 +
10201 +               if (copy_from_user
10202 +                   (*(i_tmp + i_num), i_utmp2,
10203 +                    sizeof (struct acl_ip_label)))
10204 +                       return ERR_PTR(-EFAULT);
10205 +               
10206 +               if ((*(i_tmp + i_num))->iface == NULL)
10207 +                       continue;
10208 +
10209 +               len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
10210 +               if (!len || len >= IFNAMSIZ)
10211 +                       return ERR_PTR(-EINVAL);
10212 +               tmp = acl_alloc(len);
10213 +               if (tmp == NULL)
10214 +                       return ERR_PTR(-ENOMEM);
10215 +               if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
10216 +                       return ERR_PTR(-EFAULT);
10217 +               (*(i_tmp + i_num))->iface = tmp;
10218 +       }
10219 +
10220 +       s_tmp->ips = i_tmp;
10221 +
10222 +insert:
10223 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
10224 +                              s_tmp->device))
10225 +               return ERR_PTR(-ENOMEM);
10226 +
10227 +       return s_tmp;
10228 +}
10229 +
10230 +static int
10231 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
10232 +{
10233 +       struct acl_subject_label s_pre;
10234 +       struct acl_subject_label * ret;
10235 +       int err;
10236 +
10237 +       while (userp) {
10238 +               if (copy_from_user(&s_pre, userp,
10239 +                                  sizeof (struct acl_subject_label)))
10240 +                       return -EFAULT;
10241 +               
10242 +               /* do not add nested subjects here, add
10243 +                  while parsing objects
10244 +               */
10245 +
10246 +               if (s_pre.mode & GR_NESTED) {
10247 +                       userp = s_pre.prev;
10248 +                       continue;
10249 +               }
10250 +
10251 +               ret = do_copy_user_subj(userp, role);
10252 +
10253 +               err = PTR_ERR(ret);
10254 +               if (IS_ERR(ret))
10255 +                       return err;
10256 +
10257 +               insert_acl_subj_label(ret, role);
10258 +
10259 +               userp = s_pre.prev;
10260 +       }
10261 +
10262 +       return 0;
10263 +}
10264 +
10265 +static int
10266 +copy_user_acl(struct gr_arg *arg)
10267 +{
10268 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
10269 +       struct sprole_pw *sptmp;
10270 +       struct gr_hash_struct *ghash;
10271 +       uid_t *domainlist;
10272 +       unsigned int r_num;
10273 +       unsigned int len;
10274 +       char *tmp;
10275 +       int err = 0;
10276 +       __u16 i;
10277 +       __u32 num_subjs;
10278 +
10279 +       /* we need a default and kernel role */
10280 +       if (arg->role_db.num_roles < 2)
10281 +               return -EINVAL;
10282 +
10283 +       /* copy special role authentication info from userspace */
10284 +
10285 +       num_sprole_pws = arg->num_sprole_pws;
10286 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
10287 +
10288 +       if (!acl_special_roles) {
10289 +               err = -ENOMEM;
10290 +               goto cleanup;
10291 +       }
10292 +
10293 +       for (i = 0; i < num_sprole_pws; i++) {
10294 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
10295 +               if (!sptmp) {
10296 +                       err = -ENOMEM;
10297 +                       goto cleanup;
10298 +               }
10299 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
10300 +                                  sizeof (struct sprole_pw))) {
10301 +                       err = -EFAULT;
10302 +                       goto cleanup;
10303 +               }
10304 +
10305 +               len =
10306 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
10307 +
10308 +               if (!len || len >= GR_SPROLE_LEN) {
10309 +                       err = -EINVAL;
10310 +                       goto cleanup;
10311 +               }
10312 +
10313 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
10314 +                       err = -ENOMEM;
10315 +                       goto cleanup;
10316 +               }
10317 +
10318 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
10319 +                       err = -EFAULT;
10320 +                       goto cleanup;
10321 +               }
10322 +
10323 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10324 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
10325 +#endif
10326 +               sptmp->rolename = tmp;
10327 +               acl_special_roles[i] = sptmp;
10328 +       }
10329 +
10330 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
10331 +
10332 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
10333 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
10334 +
10335 +               if (!r_tmp) {
10336 +                       err = -ENOMEM;
10337 +                       goto cleanup;
10338 +               }
10339 +
10340 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
10341 +                                  sizeof (struct acl_role_label *))) {
10342 +                       err = -EFAULT;
10343 +                       goto cleanup;
10344 +               }
10345 +
10346 +               if (copy_from_user(r_tmp, r_utmp2,
10347 +                                  sizeof (struct acl_role_label))) {
10348 +                       err = -EFAULT;
10349 +                       goto cleanup;
10350 +               }
10351 +
10352 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
10353 +
10354 +               if (!len || len >= PATH_MAX) {
10355 +                       err = -EINVAL;
10356 +                       goto cleanup;
10357 +               }
10358 +
10359 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
10360 +                       err = -ENOMEM;
10361 +                       goto cleanup;
10362 +               }
10363 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
10364 +                       err = -EFAULT;
10365 +                       goto cleanup;
10366 +               }
10367 +               r_tmp->rolename = tmp;
10368 +
10369 +               if (!strcmp(r_tmp->rolename, "default")
10370 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
10371 +                       default_role = r_tmp;
10372 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
10373 +                       kernel_role = r_tmp;
10374 +               }
10375 +
10376 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
10377 +                       err = -ENOMEM;
10378 +                       goto cleanup;
10379 +               }
10380 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
10381 +                       err = -EFAULT;
10382 +                       goto cleanup;
10383 +               }
10384 +
10385 +               r_tmp->hash = ghash;
10386 +
10387 +               num_subjs = count_user_subjs(r_tmp->hash->first);
10388 +
10389 +               r_tmp->subj_hash_size = num_subjs;
10390 +               r_tmp->subj_hash =
10391 +                   (struct acl_subject_label **)
10392 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
10393 +
10394 +               if (!r_tmp->subj_hash) {
10395 +                       err = -ENOMEM;
10396 +                       goto cleanup;
10397 +               }
10398 +
10399 +               err = copy_user_allowedips(r_tmp);
10400 +               if (err)
10401 +                       goto cleanup;
10402 +
10403 +               /* copy domain info */
10404 +               if (r_tmp->domain_children != NULL) {
10405 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
10406 +                       if (domainlist == NULL) {
10407 +                               err = -ENOMEM;
10408 +                               goto cleanup;
10409 +                       }
10410 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
10411 +                               err = -EFAULT;
10412 +                               goto cleanup;
10413 +                       }
10414 +                       r_tmp->domain_children = domainlist;
10415 +               }
10416 +
10417 +               err = copy_user_transitions(r_tmp);
10418 +               if (err)
10419 +                       goto cleanup;
10420 +
10421 +               memset(r_tmp->subj_hash, 0,
10422 +                      r_tmp->subj_hash_size *
10423 +                      sizeof (struct acl_subject_label *));
10424 +
10425 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
10426 +
10427 +               if (err)
10428 +                       goto cleanup;
10429 +
10430 +               /* set nested subject list to null */
10431 +               r_tmp->hash->first = NULL;
10432 +
10433 +               insert_acl_role_label(r_tmp);
10434 +       }
10435 +
10436 +       goto return_err;
10437 +      cleanup:
10438 +       free_variables();
10439 +      return_err:
10440 +       return err;
10441 +
10442 +}
10443 +
10444 +static int
10445 +gracl_init(struct gr_arg *args)
10446 +{
10447 +       int error = 0;
10448 +
10449 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
10450 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
10451 +
10452 +       if (init_variables(args)) {
10453 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
10454 +               error = -ENOMEM;
10455 +               free_variables();
10456 +               goto out;
10457 +       }
10458 +
10459 +       error = copy_user_acl(args);
10460 +       free_init_variables();
10461 +       if (error) {
10462 +               free_variables();
10463 +               goto out;
10464 +       }
10465 +
10466 +       if ((error = gr_set_acls(0))) {
10467 +               free_variables();
10468 +               goto out;
10469 +       }
10470 +
10471 +       gr_status |= GR_READY;
10472 +      out:
10473 +       return error;
10474 +}
10475 +
10476 +/* derived from glibc fnmatch() 0: match, 1: no match*/
10477 +
10478 +static int
10479 +glob_match(const char *p, const char *n)
10480 +{
10481 +       char c;
10482 +
10483 +       while ((c = *p++) != '\0') {
10484 +       switch (c) {
10485 +               case '?':
10486 +                       if (*n == '\0')
10487 +                               return 1;
10488 +                       else if (*n == '/')
10489 +                               return 1;
10490 +                       break;
10491 +               case '\\':
10492 +                       if (*n != c)
10493 +                               return 1;
10494 +                       break;
10495 +               case '*':
10496 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
10497 +                               if (*n == '/')
10498 +                                       return 1;
10499 +                               else if (c == '?') {
10500 +                                       if (*n == '\0')
10501 +                                               return 1;
10502 +                                       else
10503 +                                               ++n;
10504 +                               }
10505 +                       }
10506 +                       if (c == '\0') {
10507 +                               return 0;
10508 +                       } else {
10509 +                               const char *endp;
10510 +
10511 +                               if ((endp = strchr(n, '/')) == NULL)
10512 +                                       endp = n + strlen(n);
10513 +
10514 +                               if (c == '[') {
10515 +                                       for (--p; n < endp; ++n)
10516 +                                               if (!glob_match(p, n))
10517 +                                                       return 0;
10518 +                               } else if (c == '/') {
10519 +                                       while (*n != '\0' && *n != '/')
10520 +                                               ++n;
10521 +                                       if (*n == '/' && !glob_match(p, n + 1))
10522 +                                               return 0;
10523 +                               } else {
10524 +                                       for (--p; n < endp; ++n)
10525 +                                               if (*n == c && !glob_match(p, n))
10526 +                                                       return 0;
10527 +                               }
10528 +
10529 +                               return 1;
10530 +                       }
10531 +               case '[':
10532 +                       {
10533 +                       int not;
10534 +                       char cold;
10535 +
10536 +                       if (*n == '\0' || *n == '/')
10537 +                               return 1;
10538 +
10539 +                       not = (*p == '!' || *p == '^');
10540 +                       if (not)
10541 +                               ++p;
10542 +
10543 +                       c = *p++;
10544 +                       for (;;) {
10545 +                               unsigned char fn = (unsigned char)*n;
10546 +
10547 +                               if (c == '\0')
10548 +                                       return 1;
10549 +                               else {
10550 +                                       if (c == fn)
10551 +                                               goto matched;
10552 +                                       cold = c;
10553 +                                       c = *p++;
10554 +
10555 +                                       if (c == '-' && *p != ']') {
10556 +                                               unsigned char cend = *p++;
10557 +
10558 +                                               if (cend == '\0')
10559 +                                                       return 1;
10560 +
10561 +                                               if (cold <= fn && fn <= cend)
10562 +                                                       goto matched;
10563 +
10564 +                                               c = *p++;
10565 +                                       }
10566 +                               }
10567 +
10568 +                               if (c == ']')
10569 +                                       break;
10570 +                       }
10571 +                       if (!not)
10572 +                               return 1;
10573 +                       break;
10574 +               matched:
10575 +                       while (c != ']') {
10576 +                               if (c == '\0')
10577 +                                       return 1;
10578 +
10579 +                               c = *p++;
10580 +                       }
10581 +                       if (not)
10582 +                               return 1;
10583 +               }
10584 +               break;
10585 +       default:
10586 +               if (c != *n)
10587 +                       return 1;
10588 +       }
10589 +
10590 +       ++n;
10591 +       }
10592 +
10593 +       if (*n == '\0')
10594 +               return 0;
10595 +
10596 +       if (*n == '/')
10597 +               return 0;
10598 +
10599 +       return 1;
10600 +}
10601 +
10602 +static struct acl_object_label *
10603 +chk_glob_label(struct acl_object_label *globbed,
10604 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
10605 +{
10606 +       struct acl_object_label *tmp;
10607 +
10608 +       if (*path == NULL)
10609 +               *path = gr_to_filename_nolock(dentry, mnt);
10610 +
10611 +       tmp = globbed;
10612 +
10613 +       while (tmp) {
10614 +               if (!glob_match(tmp->filename, *path))
10615 +                       return tmp;
10616 +               tmp = tmp->next;
10617 +       }
10618 +
10619 +       return NULL;
10620 +}
10621 +
10622 +static struct acl_object_label *
10623 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
10624 +           const ino_t curr_ino, const dev_t curr_dev,
10625 +           const struct acl_subject_label *subj, char **path)
10626 +{
10627 +       struct acl_subject_label *tmpsubj;
10628 +       struct acl_object_label *retval;
10629 +       struct acl_object_label *retval2;
10630 +
10631 +       tmpsubj = (struct acl_subject_label *) subj;
10632 +       read_lock(&gr_inode_lock);
10633 +       do {
10634 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
10635 +               if (retval) {
10636 +                       if (retval->globbed) {
10637 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
10638 +                                               (struct vfsmount *)orig_mnt, path);
10639 +                               if (retval2)
10640 +                                       retval = retval2;
10641 +                       }
10642 +                       break;
10643 +               }
10644 +       } while ((tmpsubj = tmpsubj->parent_subject));
10645 +       read_unlock(&gr_inode_lock);
10646 +
10647 +       return retval;
10648 +}
10649 +
10650 +static __inline__ struct acl_object_label *
10651 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
10652 +           const struct dentry *curr_dentry,
10653 +           const struct acl_subject_label *subj, char **path)
10654 +{
10655 +       return __full_lookup(orig_dentry, orig_mnt,
10656 +                            curr_dentry->d_inode->i_ino, 
10657 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
10658 +}
10659 +
10660 +static struct acl_object_label *
10661 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10662 +             const struct acl_subject_label *subj, char *path)
10663 +{
10664 +       struct dentry *dentry = (struct dentry *) l_dentry;
10665 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
10666 +       struct acl_object_label *retval;
10667 +
10668 +       spin_lock(&dcache_lock);
10669 +
10670 +       for (;;) {
10671 +               if (dentry == real_root && mnt == real_root_mnt)
10672 +                       break;
10673 +
10674 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
10675 +                       if (mnt->mnt_parent == mnt)
10676 +                               break;
10677 +
10678 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10679 +                       if (retval != NULL)
10680 +                               goto out;
10681 +
10682 +                       dentry = mnt->mnt_mountpoint;
10683 +                       mnt = mnt->mnt_parent;
10684 +                       continue;
10685 +               }
10686 +
10687 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10688 +               if (retval != NULL)
10689 +                       goto out;
10690 +
10691 +               dentry = dentry->d_parent;
10692 +       }
10693 +
10694 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10695 +
10696 +       if (retval == NULL)
10697 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
10698 +out:
10699 +       spin_unlock(&dcache_lock);
10700 +       return retval;
10701 +}
10702 +
10703 +static __inline__ struct acl_object_label *
10704 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10705 +             const struct acl_subject_label *subj)
10706 +{
10707 +       char *path = NULL;
10708 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
10709 +}
10710 +
10711 +static __inline__ struct acl_object_label *
10712 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10713 +                    const struct acl_subject_label *subj, char *path)
10714 +{
10715 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
10716 +}
10717 +
10718 +static struct acl_subject_label *
10719 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10720 +              const struct acl_role_label *role)
10721 +{
10722 +       struct dentry *dentry = (struct dentry *) l_dentry;
10723 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
10724 +       struct acl_subject_label *retval;
10725 +
10726 +       spin_lock(&dcache_lock);
10727 +
10728 +       for (;;) {
10729 +               if (dentry == real_root && mnt == real_root_mnt)
10730 +                       break;
10731 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
10732 +                       if (mnt->mnt_parent == mnt)
10733 +                               break;
10734 +
10735 +                       read_lock(&gr_inode_lock);
10736 +                       retval =
10737 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
10738 +                                               dentry->d_inode->i_sb->s_dev, role);
10739 +                       read_unlock(&gr_inode_lock);
10740 +                       if (retval != NULL)
10741 +                               goto out;
10742 +
10743 +                       dentry = mnt->mnt_mountpoint;
10744 +                       mnt = mnt->mnt_parent;
10745 +                       continue;
10746 +               }
10747 +
10748 +               read_lock(&gr_inode_lock);
10749 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
10750 +                                         dentry->d_inode->i_sb->s_dev, role);
10751 +               read_unlock(&gr_inode_lock);
10752 +               if (retval != NULL)
10753 +                       goto out;
10754 +
10755 +               dentry = dentry->d_parent;
10756 +       }
10757 +
10758 +       read_lock(&gr_inode_lock);
10759 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
10760 +                                 dentry->d_inode->i_sb->s_dev, role);
10761 +       read_unlock(&gr_inode_lock);
10762 +
10763 +       if (unlikely(retval == NULL)) {
10764 +               read_lock(&gr_inode_lock);
10765 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
10766 +                                         real_root->d_inode->i_sb->s_dev, role);
10767 +               read_unlock(&gr_inode_lock);
10768 +       }
10769 +out:
10770 +       spin_unlock(&dcache_lock);
10771 +
10772 +       return retval;
10773 +}
10774 +
10775 +static void
10776 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
10777 +{
10778 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
10779 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
10780 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
10781 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
10782 +
10783 +       return;
10784 +}
10785 +
10786 +static void
10787 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
10788 +                      const unsigned int effective, const unsigned int fs)
10789 +{
10790 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
10791 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
10792 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
10793 +                      type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
10794 +
10795 +       return;
10796 +}
10797 +
10798 +__u32
10799 +gr_check_link(const struct dentry * new_dentry,
10800 +             const struct dentry * parent_dentry,
10801 +             const struct vfsmount * parent_mnt,
10802 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
10803 +{
10804 +       struct acl_object_label *obj;
10805 +       __u32 oldmode, newmode;
10806 +       __u32 needmode;
10807 +
10808 +       if (unlikely(!(gr_status & GR_READY)))
10809 +               return (GR_CREATE | GR_LINK);
10810 +
10811 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
10812 +       oldmode = obj->mode;
10813 +
10814 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
10815 +               oldmode |= (GR_CREATE | GR_LINK);
10816 +
10817 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
10818 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
10819 +               needmode |= GR_SETID | GR_AUDIT_SETID;
10820 +
10821 +       newmode =
10822 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
10823 +                           oldmode | needmode);
10824 +
10825 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
10826 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
10827 +                             GR_INHERIT | GR_AUDIT_INHERIT);
10828 +
10829 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
10830 +               goto bad;
10831 +
10832 +       if ((oldmode & needmode) != needmode)
10833 +               goto bad;
10834 +
10835 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
10836 +       if ((newmode & needmode) != needmode)
10837 +               goto bad;
10838 +
10839 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
10840 +               return newmode;
10841 +bad:
10842 +       needmode = oldmode;
10843 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
10844 +               needmode |= GR_SETID;
10845 +       
10846 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
10847 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
10848 +               return (GR_CREATE | GR_LINK);
10849 +       } else if (newmode & GR_SUPPRESS)
10850 +               return GR_SUPPRESS;
10851 +       else
10852 +               return 0;
10853 +}
10854 +
10855 +__u32
10856 +gr_search_file(const struct dentry * dentry, const __u32 mode,
10857 +              const struct vfsmount * mnt)
10858 +{
10859 +       __u32 retval = mode;
10860 +       struct acl_subject_label *curracl;
10861 +       struct acl_object_label *currobj;
10862 +
10863 +       if (unlikely(!(gr_status & GR_READY)))
10864 +               return (mode & ~GR_AUDITS);
10865 +
10866 +       curracl = current->acl;
10867 +
10868 +       currobj = chk_obj_label(dentry, mnt, curracl);
10869 +       retval = currobj->mode & mode;
10870 +
10871 +       if (unlikely
10872 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
10873 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
10874 +               __u32 new_mode = mode;
10875 +
10876 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10877 +
10878 +               retval = new_mode;
10879 +
10880 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
10881 +                       new_mode |= GR_INHERIT;
10882 +
10883 +               if (!(mode & GR_NOLEARN))
10884 +                       gr_log_learn(current, dentry, mnt, new_mode);
10885 +       }
10886 +
10887 +       return retval;
10888 +}
10889 +
10890 +__u32
10891 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
10892 +               const struct vfsmount * mnt, const __u32 mode)
10893 +{
10894 +       struct name_entry *match;
10895 +       struct acl_object_label *matchpo;
10896 +       struct acl_subject_label *curracl;
10897 +       char *path;
10898 +       __u32 retval;
10899 +
10900 +       if (unlikely(!(gr_status & GR_READY)))
10901 +               return (mode & ~GR_AUDITS);
10902 +
10903 +       preempt_disable();
10904 +       path = gr_to_filename_rbac(new_dentry, mnt);
10905 +       match = lookup_name_entry(path);
10906 +
10907 +       if (!match)
10908 +               goto check_parent;
10909 +
10910 +       curracl = current->acl;
10911 +
10912 +       read_lock(&gr_inode_lock);
10913 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
10914 +       read_unlock(&gr_inode_lock);
10915 +
10916 +       if (matchpo) {
10917 +               if ((matchpo->mode & mode) !=
10918 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
10919 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
10920 +                       __u32 new_mode = mode;
10921 +
10922 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10923 +
10924 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
10925 +
10926 +                       preempt_enable();
10927 +                       return new_mode;
10928 +               }
10929 +               preempt_enable();
10930 +               return (matchpo->mode & mode);
10931 +       }
10932 +
10933 +      check_parent:
10934 +       curracl = current->acl;
10935 +
10936 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
10937 +       retval = matchpo->mode & mode;
10938 +
10939 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
10940 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
10941 +               __u32 new_mode = mode;
10942 +
10943 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10944 +
10945 +               gr_log_learn(current, new_dentry, mnt, new_mode);
10946 +               preempt_enable();
10947 +               return new_mode;
10948 +       }
10949 +
10950 +       preempt_enable();
10951 +       return retval;
10952 +}
10953 +
10954 +int
10955 +gr_check_hidden_task(const struct task_struct *task)
10956 +{
10957 +       if (unlikely(!(gr_status & GR_READY)))
10958 +               return 0;
10959 +
10960 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
10961 +               return 1;
10962 +
10963 +       return 0;
10964 +}
10965 +
10966 +int
10967 +gr_check_protected_task(const struct task_struct *task)
10968 +{
10969 +       if (unlikely(!(gr_status & GR_READY) || !task))
10970 +               return 0;
10971 +
10972 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
10973 +           task->acl != current->acl)
10974 +               return 1;
10975 +
10976 +       return 0;
10977 +}
10978 +
10979 +void
10980 +gr_copy_label(struct task_struct *tsk)
10981 +{
10982 +       tsk->signal->used_accept = 0;
10983 +       tsk->acl_sp_role = 0;
10984 +       tsk->acl_role_id = current->acl_role_id;
10985 +       tsk->acl = current->acl;
10986 +       tsk->role = current->role;
10987 +       tsk->signal->curr_ip = current->signal->curr_ip;
10988 +       if (current->exec_file)
10989 +               get_file(current->exec_file);
10990 +       tsk->exec_file = current->exec_file;
10991 +       tsk->is_writable = current->is_writable;
10992 +       if (unlikely(current->signal->used_accept))
10993 +               current->signal->curr_ip = 0;
10994 +
10995 +       return;
10996 +}
10997 +
10998 +static void
10999 +gr_set_proc_res(struct task_struct *task)
11000 +{
11001 +       struct acl_subject_label *proc;
11002 +       unsigned short i;
11003 +
11004 +       proc = task->acl;
11005 +
11006 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
11007 +               return;
11008 +
11009 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
11010 +               if (!(proc->resmask & (1 << i)))
11011 +                       continue;
11012 +
11013 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
11014 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
11015 +       }
11016 +
11017 +       return;
11018 +}
11019 +
11020 +int
11021 +gr_check_user_change(int real, int effective, int fs)
11022 +{
11023 +       unsigned int i;
11024 +       __u16 num;
11025 +       uid_t *uidlist;
11026 +       int curuid;
11027 +       int realok = 0;
11028 +       int effectiveok = 0;
11029 +       int fsok = 0;
11030 +
11031 +       if (unlikely(!(gr_status & GR_READY)))
11032 +               return 0;
11033 +
11034 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
11035 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
11036 +
11037 +       num = current->acl->user_trans_num;
11038 +       uidlist = current->acl->user_transitions;
11039 +
11040 +       if (uidlist == NULL)
11041 +               return 0;
11042 +
11043 +       if (real == -1)
11044 +               realok = 1;
11045 +       if (effective == -1)
11046 +               effectiveok = 1;
11047 +       if (fs == -1)
11048 +               fsok = 1;
11049 +
11050 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
11051 +               for (i = 0; i < num; i++) {
11052 +                       curuid = (int)uidlist[i];
11053 +                       if (real == curuid)
11054 +                               realok = 1;
11055 +                       if (effective == curuid)
11056 +                               effectiveok = 1;
11057 +                       if (fs == curuid)
11058 +                               fsok = 1;
11059 +               }
11060 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
11061 +               for (i = 0; i < num; i++) {
11062 +                       curuid = (int)uidlist[i];
11063 +                       if (real == curuid)
11064 +                               break;
11065 +                       if (effective == curuid)
11066 +                               break;
11067 +                       if (fs == curuid)
11068 +                               break;
11069 +               }
11070 +               /* not in deny list */
11071 +               if (i == num) {
11072 +                       realok = 1;
11073 +                       effectiveok = 1;
11074 +                       fsok = 1;
11075 +               }
11076 +       }
11077 +
11078 +       if (realok && effectiveok && fsok)
11079 +               return 0;
11080 +       else {
11081 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
11082 +               return 1;
11083 +       }
11084 +}
11085 +
11086 +int
11087 +gr_check_group_change(int real, int effective, int fs)
11088 +{
11089 +       unsigned int i;
11090 +       __u16 num;
11091 +       gid_t *gidlist;
11092 +       int curgid;
11093 +       int realok = 0;
11094 +       int effectiveok = 0;
11095 +       int fsok = 0;
11096 +
11097 +       if (unlikely(!(gr_status & GR_READY)))
11098 +               return 0;
11099 +
11100 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
11101 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
11102 +
11103 +       num = current->acl->group_trans_num;
11104 +       gidlist = current->acl->group_transitions;
11105 +
11106 +       if (gidlist == NULL)
11107 +               return 0;
11108 +
11109 +       if (real == -1)
11110 +               realok = 1;
11111 +       if (effective == -1)
11112 +               effectiveok = 1;
11113 +       if (fs == -1)
11114 +               fsok = 1;
11115 +
11116 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
11117 +               for (i = 0; i < num; i++) {
11118 +                       curgid = (int)gidlist[i];
11119 +                       if (real == curgid)
11120 +                               realok = 1;
11121 +                       if (effective == curgid)
11122 +                               effectiveok = 1;
11123 +                       if (fs == curgid)
11124 +                               fsok = 1;
11125 +               }
11126 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
11127 +               for (i = 0; i < num; i++) {
11128 +                       curgid = (int)gidlist[i];
11129 +                       if (real == curgid)
11130 +                               break;
11131 +                       if (effective == curgid)
11132 +                               break;
11133 +                       if (fs == curgid)
11134 +                               break;
11135 +               }
11136 +               /* not in deny list */
11137 +               if (i == num) {
11138 +                       realok = 1;
11139 +                       effectiveok = 1;
11140 +                       fsok = 1;
11141 +               }
11142 +       }
11143 +
11144 +       if (realok && effectiveok && fsok)
11145 +               return 0;
11146 +       else {
11147 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
11148 +               return 1;
11149 +       }
11150 +}
11151 +
11152 +void
11153 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
11154 +{
11155 +       struct acl_role_label *role = task->role;
11156 +       struct acl_subject_label *subj = NULL;
11157 +       struct acl_object_label *obj;
11158 +       struct file *filp;
11159 +
11160 +       if (unlikely(!(gr_status & GR_READY)))
11161 +               return;
11162 +
11163 +       filp = task->exec_file;
11164 +
11165 +       /* kernel process, we'll give them the kernel role */
11166 +       if (unlikely(!filp)) {
11167 +               task->role = kernel_role;
11168 +               task->acl = kernel_role->root_label;
11169 +               return;
11170 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
11171 +               role = lookup_acl_role_label(task, uid, gid);
11172 +
11173 +       /* perform subject lookup in possibly new role
11174 +          we can use this result below in the case where role == task->role
11175 +       */
11176 +       subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
11177 +
11178 +       /* if we changed uid/gid, but result in the same role
11179 +          and are using inheritance, don't lose the inherited subject
11180 +          if current subject is other than what normal lookup
11181 +          would result in, we arrived via inheritance, don't
11182 +          lose subject
11183 +       */
11184 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
11185 +                                  (subj == task->acl)))
11186 +               task->acl = subj;
11187 +
11188 +       task->role = role;
11189 +
11190 +       task->is_writable = 0;
11191 +
11192 +       /* ignore additional mmap checks for processes that are writable 
11193 +          by the default ACL */
11194 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
11195 +       if (unlikely(obj->mode & GR_WRITE))
11196 +               task->is_writable = 1;
11197 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
11198 +       if (unlikely(obj->mode & GR_WRITE))
11199 +               task->is_writable = 1;
11200 +
11201 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11202 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
11203 +#endif
11204 +
11205 +       gr_set_proc_res(task);
11206 +
11207 +       return;
11208 +}
11209 +
11210 +int
11211 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
11212 +{
11213 +       struct task_struct *task = current;
11214 +       struct acl_subject_label *newacl;
11215 +       struct acl_object_label *obj;
11216 +       __u32 retmode;
11217 +
11218 +       if (unlikely(!(gr_status & GR_READY)))
11219 +               return 0;
11220 +
11221 +       newacl = chk_subj_label(dentry, mnt, task->role);
11222 +
11223 +       task_lock(task);
11224 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
11225 +            GR_POVERRIDE) && (task->acl != newacl) &&
11226 +            !(task->role->roletype & GR_ROLE_GOD) &&
11227 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
11228 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
11229 +           (atomic_read(&task->fs->count) > 1 ||
11230 +            atomic_read(&task->files->count) > 1 ||
11231 +            atomic_read(&task->sighand->count) > 1)) {
11232 +                task_unlock(task);
11233 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
11234 +               return -EACCES;
11235 +       }
11236 +       task_unlock(task);
11237 +
11238 +       obj = chk_obj_label(dentry, mnt, task->acl);
11239 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
11240 +
11241 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
11242 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
11243 +               if (obj->nested)
11244 +                       task->acl = obj->nested;
11245 +               else
11246 +                       task->acl = newacl;
11247 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
11248 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
11249 +
11250 +       task->is_writable = 0;
11251 +
11252 +       /* ignore additional mmap checks for processes that are writable 
11253 +          by the default ACL */
11254 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
11255 +       if (unlikely(obj->mode & GR_WRITE))
11256 +               task->is_writable = 1;
11257 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
11258 +       if (unlikely(obj->mode & GR_WRITE))
11259 +               task->is_writable = 1;
11260 +
11261 +       gr_set_proc_res(task);
11262 +
11263 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11264 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
11265 +#endif
11266 +       return 0;
11267 +}
11268 +
11269 +static void
11270 +do_handle_delete(const ino_t ino, const dev_t dev)
11271 +{
11272 +       struct acl_object_label *matchpo;
11273 +       struct acl_subject_label *matchps;
11274 +       struct acl_subject_label *subj;
11275 +       struct acl_role_label *role;
11276 +       unsigned int i, x;
11277 +
11278 +       FOR_EACH_ROLE_START(role, i)
11279 +               FOR_EACH_SUBJECT_START(role, subj, x)
11280 +                       if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
11281 +                               matchpo->mode |= GR_DELETED;
11282 +               FOR_EACH_SUBJECT_END(subj,x)
11283 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
11284 +                       if (subj->inode == ino && subj->device == dev)
11285 +                               subj->mode |= GR_DELETED;
11286 +               FOR_EACH_NESTED_SUBJECT_END(subj)
11287 +               if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
11288 +                       matchps->mode |= GR_DELETED;
11289 +       FOR_EACH_ROLE_END(role,i)
11290 +
11291 +       return;
11292 +}
11293 +
11294 +void
11295 +gr_handle_delete(const ino_t ino, const dev_t dev)
11296 +{
11297 +       if (unlikely(!(gr_status & GR_READY)))
11298 +               return;
11299 +
11300 +       write_lock(&gr_inode_lock);
11301 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
11302 +               do_handle_delete(ino, dev);
11303 +       write_unlock(&gr_inode_lock);
11304 +
11305 +       return;
11306 +}
11307 +
11308 +static void
11309 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
11310 +                    const ino_t newinode, const dev_t newdevice,
11311 +                    struct acl_subject_label *subj)
11312 +{
11313 +       unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
11314 +       struct acl_object_label *match;
11315 +
11316 +       match = subj->obj_hash[index];
11317 +
11318 +       while (match && (match->inode != oldinode ||
11319 +              match->device != olddevice ||
11320 +              !(match->mode & GR_DELETED)))
11321 +               match = match->next;
11322 +
11323 +       if (match && (match->inode == oldinode)
11324 +           && (match->device == olddevice)
11325 +           && (match->mode & GR_DELETED)) {
11326 +               if (match->prev == NULL) {
11327 +                       subj->obj_hash[index] = match->next;
11328 +                       if (match->next != NULL)
11329 +                               match->next->prev = NULL;
11330 +               } else {
11331 +                       match->prev->next = match->next;
11332 +                       if (match->next != NULL)
11333 +                               match->next->prev = match->prev;
11334 +               }
11335 +               match->prev = NULL;
11336 +               match->next = NULL;
11337 +               match->inode = newinode;
11338 +               match->device = newdevice;
11339 +               match->mode &= ~GR_DELETED;
11340 +
11341 +               insert_acl_obj_label(match, subj);
11342 +       }
11343 +
11344 +       return;
11345 +}
11346 +
11347 +static void
11348 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
11349 +                     const ino_t newinode, const dev_t newdevice,
11350 +                     struct acl_role_label *role)
11351 +{
11352 +       unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
11353 +       struct acl_subject_label *match;
11354 +
11355 +       match = role->subj_hash[index];
11356 +
11357 +       while (match && (match->inode != oldinode ||
11358 +              match->device != olddevice ||
11359 +              !(match->mode & GR_DELETED)))
11360 +               match = match->next;
11361 +
11362 +       if (match && (match->inode == oldinode)
11363 +           && (match->device == olddevice)
11364 +           && (match->mode & GR_DELETED)) {
11365 +               if (match->prev == NULL) {
11366 +                       role->subj_hash[index] = match->next;
11367 +                       if (match->next != NULL)
11368 +                               match->next->prev = NULL;
11369 +               } else {
11370 +                       match->prev->next = match->next;
11371 +                       if (match->next != NULL)
11372 +                               match->next->prev = match->prev;
11373 +               }
11374 +               match->prev = NULL;
11375 +               match->next = NULL;
11376 +               match->inode = newinode;
11377 +               match->device = newdevice;
11378 +               match->mode &= ~GR_DELETED;
11379 +
11380 +               insert_acl_subj_label(match, role);
11381 +       }
11382 +
11383 +       return;
11384 +}
11385 +
11386 +static void
11387 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
11388 +                   const ino_t newinode, const dev_t newdevice)
11389 +{
11390 +       unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
11391 +       struct inodev_entry *match;
11392 +
11393 +       match = inodev_set.i_hash[index];
11394 +
11395 +       while (match && (match->nentry->inode != oldinode ||
11396 +              match->nentry->device != olddevice))
11397 +               match = match->next;
11398 +
11399 +       if (match && (match->nentry->inode == oldinode)
11400 +           && (match->nentry->device == olddevice)) {
11401 +               if (match->prev == NULL) {
11402 +                       inodev_set.i_hash[index] = match->next;
11403 +                       if (match->next != NULL)
11404 +                               match->next->prev = NULL;
11405 +               } else {
11406 +                       match->prev->next = match->next;
11407 +                       if (match->next != NULL)
11408 +                               match->next->prev = match->prev;
11409 +               }
11410 +               match->prev = NULL;
11411 +               match->next = NULL;
11412 +               match->nentry->inode = newinode;
11413 +               match->nentry->device = newdevice;
11414 +
11415 +               insert_inodev_entry(match);
11416 +       }
11417 +
11418 +       return;
11419 +}
11420 +
11421 +static void
11422 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
11423 +                const struct vfsmount *mnt)
11424 +{
11425 +       struct acl_subject_label *subj;
11426 +       struct acl_role_label *role;
11427 +       unsigned int i, x;
11428 +
11429 +       FOR_EACH_ROLE_START(role, i)
11430 +               update_acl_subj_label(matchn->inode, matchn->device,
11431 +                                     dentry->d_inode->i_ino,
11432 +                                     dentry->d_inode->i_sb->s_dev, role);
11433 +
11434 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
11435 +                       if ((subj->inode == dentry->d_inode->i_ino) &&
11436 +                           (subj->device == dentry->d_inode->i_sb->s_dev)) {
11437 +                               subj->inode = dentry->d_inode->i_ino;
11438 +                               subj->device = dentry->d_inode->i_sb->s_dev;
11439 +                       }
11440 +               FOR_EACH_NESTED_SUBJECT_END(subj)
11441 +               FOR_EACH_SUBJECT_START(role, subj, x)
11442 +                       update_acl_obj_label(matchn->inode, matchn->device,
11443 +                                            dentry->d_inode->i_ino,
11444 +                                            dentry->d_inode->i_sb->s_dev, subj);
11445 +               FOR_EACH_SUBJECT_END(subj,x)
11446 +       FOR_EACH_ROLE_END(role,i)
11447 +
11448 +       update_inodev_entry(matchn->inode, matchn->device,
11449 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
11450 +
11451 +       return;
11452 +}
11453 +
11454 +void
11455 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
11456 +{
11457 +       struct name_entry *matchn;
11458 +
11459 +       if (unlikely(!(gr_status & GR_READY)))
11460 +               return;
11461 +
11462 +       preempt_disable();
11463 +       matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
11464 +
11465 +       if (unlikely((unsigned long)matchn)) {
11466 +               write_lock(&gr_inode_lock);
11467 +               do_handle_create(matchn, dentry, mnt);
11468 +               write_unlock(&gr_inode_lock);
11469 +       }
11470 +       preempt_enable();
11471 +
11472 +       return;
11473 +}
11474 +
11475 +void
11476 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
11477 +                struct dentry *old_dentry,
11478 +                struct dentry *new_dentry,
11479 +                struct vfsmount *mnt, const __u8 replace)
11480 +{
11481 +       struct name_entry *matchn;
11482 +
11483 +       if (unlikely(!(gr_status & GR_READY)))
11484 +               return;
11485 +
11486 +       preempt_disable();
11487 +       matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
11488 +
11489 +       /* we wouldn't have to check d_inode if it weren't for
11490 +          NFS silly-renaming
11491 +        */
11492 +
11493 +       write_lock(&gr_inode_lock);
11494 +       if (unlikely(replace && new_dentry->d_inode)) {
11495 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
11496 +                                       new_dentry->d_inode->i_sb->s_dev) &&
11497 +                   (old_dentry->d_inode->i_nlink <= 1)))
11498 +                       do_handle_delete(new_dentry->d_inode->i_ino,
11499 +                                        new_dentry->d_inode->i_sb->s_dev);
11500 +       }
11501 +
11502 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
11503 +                               old_dentry->d_inode->i_sb->s_dev) &&
11504 +           (old_dentry->d_inode->i_nlink <= 1)))
11505 +               do_handle_delete(old_dentry->d_inode->i_ino,
11506 +                                old_dentry->d_inode->i_sb->s_dev);
11507 +
11508 +       if (unlikely((unsigned long)matchn))
11509 +               do_handle_create(matchn, old_dentry, mnt);
11510 +
11511 +       write_unlock(&gr_inode_lock);
11512 +       preempt_enable();
11513 +
11514 +       return;
11515 +}
11516 +
11517 +static int
11518 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
11519 +                        unsigned char **sum)
11520 +{
11521 +       struct acl_role_label *r;
11522 +       struct role_allowed_ip *ipp;
11523 +       struct role_transition *trans;
11524 +       unsigned int i;
11525 +       int found = 0;
11526 +
11527 +       /* check transition table */
11528 +
11529 +       for (trans = current->role->transitions; trans; trans = trans->next) {
11530 +               if (!strcmp(rolename, trans->rolename)) {
11531 +                       found = 1;
11532 +                       break;
11533 +               }
11534 +       }
11535 +
11536 +       if (!found)
11537 +               return 0;
11538 +
11539 +       /* handle special roles that do not require authentication
11540 +          and check ip */
11541 +
11542 +       FOR_EACH_ROLE_START(r, i)
11543 +               if (!strcmp(rolename, r->rolename) &&
11544 +                   (r->roletype & GR_ROLE_SPECIAL)) {
11545 +                       found = 0;
11546 +                       if (r->allowed_ips != NULL) {
11547 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
11548 +                                       if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
11549 +                                            (ntohl(ipp->addr) & ipp->netmask))
11550 +                                               found = 1;
11551 +                               }
11552 +                       } else
11553 +                               found = 2;
11554 +                       if (!found)
11555 +                               return 0;
11556 +
11557 +                       if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
11558 +                           ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
11559 +                               *salt = NULL;
11560 +                               *sum = NULL;
11561 +                               return 1;
11562 +                       }
11563 +               }
11564 +       FOR_EACH_ROLE_END(r,i)
11565 +
11566 +       for (i = 0; i < num_sprole_pws; i++) {
11567 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
11568 +                       *salt = acl_special_roles[i]->salt;
11569 +                       *sum = acl_special_roles[i]->sum;
11570 +                       return 1;
11571 +               }
11572 +       }
11573 +
11574 +       return 0;
11575 +}
11576 +
11577 +static void
11578 +assign_special_role(char *rolename)
11579 +{
11580 +       struct acl_object_label *obj;
11581 +       struct acl_role_label *r;
11582 +       struct acl_role_label *assigned = NULL;
11583 +       struct task_struct *tsk;
11584 +       struct file *filp;
11585 +       unsigned int i;
11586 +
11587 +       FOR_EACH_ROLE_START(r, i)
11588 +               if (!strcmp(rolename, r->rolename) &&
11589 +                   (r->roletype & GR_ROLE_SPECIAL))
11590 +                       assigned = r;
11591 +       FOR_EACH_ROLE_END(r,i)
11592 +
11593 +       if (!assigned)
11594 +               return;
11595 +
11596 +       read_lock(&tasklist_lock);
11597 +       read_lock(&grsec_exec_file_lock);
11598 +
11599 +       tsk = current->parent;
11600 +       if (tsk == NULL)
11601 +               goto out_unlock;
11602 +
11603 +       filp = tsk->exec_file;
11604 +       if (filp == NULL)
11605 +               goto out_unlock;
11606 +
11607 +       tsk->is_writable = 0;
11608 +
11609 +       tsk->acl_sp_role = 1;
11610 +       tsk->acl_role_id = ++acl_sp_role_value;
11611 +       tsk->role = assigned;
11612 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
11613 +
11614 +       /* ignore additional mmap checks for processes that are writable 
11615 +          by the default ACL */
11616 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
11617 +       if (unlikely(obj->mode & GR_WRITE))
11618 +               tsk->is_writable = 1;
11619 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
11620 +       if (unlikely(obj->mode & GR_WRITE))
11621 +               tsk->is_writable = 1;
11622 +
11623 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11624 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
11625 +#endif
11626 +
11627 +out_unlock:
11628 +       read_unlock(&grsec_exec_file_lock);
11629 +       read_unlock(&tasklist_lock);
11630 +       return;
11631 +}
11632 +
11633 +int gr_check_secure_terminal(struct task_struct *task)
11634 +{
11635 +       struct task_struct *p, *p2, *p3;
11636 +       struct files_struct *files;
11637 +       struct fdtable *fdt;
11638 +       struct file *our_file = NULL, *file;
11639 +       int i;
11640 +
11641 +       if (task->signal->tty == NULL)
11642 +               return 1;
11643 +
11644 +       files = get_files_struct(task);
11645 +       if (files != NULL) {
11646 +               rcu_read_lock();
11647 +               fdt = files_fdtable(files);
11648 +               for (i=0; i < fdt->max_fds; i++) {
11649 +                       file = fcheck_files(files, i);
11650 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
11651 +                               get_file(file);
11652 +                               our_file = file;
11653 +                       }
11654 +               }
11655 +               rcu_read_unlock();
11656 +               put_files_struct(files);
11657 +       }
11658 +
11659 +       if (our_file == NULL)
11660 +               return 1;
11661 +
11662 +       read_lock(&tasklist_lock);
11663 +       do_each_thread(p2, p) {
11664 +               files = get_files_struct(p);
11665 +               if (files == NULL ||
11666 +                   (p->signal && p->signal->tty == task->signal->tty)) {
11667 +                       if (files != NULL)
11668 +                               put_files_struct(files);
11669 +                       continue;
11670 +               }
11671 +               rcu_read_lock();
11672 +               fdt = files_fdtable(files);
11673 +               for (i=0; i < fdt->max_fds; i++) {
11674 +                       file = fcheck_files(files, i);
11675 +                       if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
11676 +                           file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
11677 +                               p3 = task;
11678 +                               while (p3->pid > 0) {
11679 +                                       if (p3 == p)
11680 +                                               break;
11681 +                                       p3 = p3->parent;
11682 +                               }
11683 +                               if (p3 == p)
11684 +                                       break;
11685 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
11686 +                               gr_handle_alertkill(p);
11687 +                               rcu_read_unlock();
11688 +                               put_files_struct(files);
11689 +                               read_unlock(&tasklist_lock);
11690 +                               fput(our_file);
11691 +                               return 0;
11692 +                       }
11693 +               }
11694 +               rcu_read_unlock();
11695 +               put_files_struct(files);
11696 +       } while_each_thread(p2, p);
11697 +       read_unlock(&tasklist_lock);
11698 +
11699 +       fput(our_file);
11700 +       return 1;
11701 +}
11702 +
11703 +ssize_t
11704 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
11705 +{
11706 +       struct gr_arg_wrapper uwrap;
11707 +       unsigned char *sprole_salt;
11708 +       unsigned char *sprole_sum;
11709 +       int error = sizeof (struct gr_arg_wrapper);
11710 +       int error2 = 0;
11711 +
11712 +       down(&gr_dev_sem);
11713 +
11714 +       if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
11715 +               error = -EPERM;
11716 +               goto out;
11717 +       }
11718 +
11719 +       if (count != sizeof (struct gr_arg_wrapper)) {
11720 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
11721 +               error = -EINVAL;
11722 +               goto out;
11723 +       }
11724 +
11725 +       
11726 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
11727 +               gr_auth_expires = 0;
11728 +               gr_auth_attempts = 0;
11729 +       }
11730 +
11731 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
11732 +               error = -EFAULT;
11733 +               goto out;
11734 +       }
11735 +
11736 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
11737 +               error = -EINVAL;
11738 +               goto out;
11739 +       }
11740 +
11741 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
11742 +               error = -EFAULT;
11743 +               goto out;
11744 +       }
11745 +
11746 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
11747 +           gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
11748 +           time_after(gr_auth_expires, get_seconds())) {
11749 +               error = -EBUSY;
11750 +               goto out;
11751 +       }
11752 +
11753 +       /* if non-root trying to do anything other than use a special role,
11754 +          do not attempt authentication, do not count towards authentication
11755 +          locking
11756 +        */
11757 +
11758 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
11759 +           gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
11760 +           current->uid) {
11761 +               error = -EPERM;
11762 +               goto out;
11763 +       }
11764 +
11765 +       /* ensure pw and special role name are null terminated */
11766 +
11767 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
11768 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
11769 +
11770 +       /* Okay. 
11771 +        * We have our enough of the argument structure..(we have yet
11772 +        * to copy_from_user the tables themselves) . Copy the tables
11773 +        * only if we need them, i.e. for loading operations. */
11774 +
11775 +       switch (gr_usermode->mode) {
11776 +       case STATUS:
11777 +                       if (gr_status & GR_READY) {
11778 +                               error = 1;
11779 +                               if (!gr_check_secure_terminal(current))
11780 +                                       error = 3;
11781 +                       } else
11782 +                               error = 2;
11783 +                       goto out;
11784 +       case SHUTDOWN:
11785 +               if ((gr_status & GR_READY)
11786 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11787 +                       gr_status &= ~GR_READY;
11788 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
11789 +                       free_variables();
11790 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
11791 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
11792 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
11793 +               } else if (gr_status & GR_READY) {
11794 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
11795 +                       error = -EPERM;
11796 +               } else {
11797 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
11798 +                       error = -EAGAIN;
11799 +               }
11800 +               break;
11801 +       case ENABLE:
11802 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
11803 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
11804 +               else {
11805 +                       if (gr_status & GR_READY)
11806 +                               error = -EAGAIN;
11807 +                       else
11808 +                               error = error2;
11809 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
11810 +               }
11811 +               break;
11812 +       case RELOAD:
11813 +               if (!(gr_status & GR_READY)) {
11814 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
11815 +                       error = -EAGAIN;
11816 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11817 +                       lock_kernel();
11818 +                       gr_status &= ~GR_READY;
11819 +                       free_variables();
11820 +                       if (!(error2 = gracl_init(gr_usermode))) {
11821 +                               unlock_kernel();
11822 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
11823 +                       } else {
11824 +                               unlock_kernel();
11825 +                               error = error2;
11826 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
11827 +                       }
11828 +               } else {
11829 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
11830 +                       error = -EPERM;
11831 +               }
11832 +               break;
11833 +       case SEGVMOD:
11834 +               if (unlikely(!(gr_status & GR_READY))) {
11835 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
11836 +                       error = -EAGAIN;
11837 +                       break;
11838 +               }
11839 +
11840 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11841 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
11842 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
11843 +                               struct acl_subject_label *segvacl;
11844 +                               segvacl =
11845 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
11846 +                                                         gr_usermode->segv_device,
11847 +                                                         current->role);
11848 +                               if (segvacl) {
11849 +                                       segvacl->crashes = 0;
11850 +                                       segvacl->expires = 0;
11851 +                               }
11852 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
11853 +                               gr_remove_uid(gr_usermode->segv_uid);
11854 +                       }
11855 +               } else {
11856 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
11857 +                       error = -EPERM;
11858 +               }
11859 +               break;
11860 +       case SPROLE:
11861 +       case SPROLEPAM:
11862 +               if (unlikely(!(gr_status & GR_READY))) {
11863 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
11864 +                       error = -EAGAIN;
11865 +                       break;
11866 +               }
11867 +
11868 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
11869 +                       current->role->expires = 0;
11870 +                       current->role->auth_attempts = 0;
11871 +               }
11872 +
11873 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
11874 +                   time_after(current->role->expires, get_seconds())) {
11875 +                       error = -EBUSY;
11876 +                       goto out;
11877 +               }
11878 +
11879 +               if (lookup_special_role_auth
11880 +                   (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
11881 +                   && ((!sprole_salt && !sprole_sum)
11882 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
11883 +                       char *p = "";
11884 +                       assign_special_role(gr_usermode->sp_role);
11885 +                       read_lock(&tasklist_lock);
11886 +                       if (current->parent)
11887 +                               p = current->parent->role->rolename;
11888 +                       read_unlock(&tasklist_lock);
11889 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
11890 +                                       p, acl_sp_role_value);
11891 +               } else {
11892 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
11893 +                       error = -EPERM;
11894 +                       if(!(current->role->auth_attempts++))
11895 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
11896 +
11897 +                       goto out;
11898 +               }
11899 +               break;
11900 +       case UNSPROLE:
11901 +               if (unlikely(!(gr_status & GR_READY))) {
11902 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
11903 +                       error = -EAGAIN;
11904 +                       break;
11905 +               }
11906 +
11907 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
11908 +                       char *p = "";
11909 +                       int i = 0;
11910 +
11911 +                       read_lock(&tasklist_lock);
11912 +                       if (current->parent) {
11913 +                               p = current->parent->role->rolename;
11914 +                               i = current->parent->acl_role_id;
11915 +                       }
11916 +                       read_unlock(&tasklist_lock);
11917 +
11918 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
11919 +                       gr_set_acls(1);
11920 +               } else {
11921 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
11922 +                       error = -EPERM;
11923 +                       goto out;
11924 +               }
11925 +               break;
11926 +       default:
11927 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
11928 +               error = -EINVAL;
11929 +               break;
11930 +       }
11931 +
11932 +       if (error != -EPERM)
11933 +               goto out;
11934 +
11935 +       if(!(gr_auth_attempts++))
11936 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
11937 +
11938 +      out:
11939 +       up(&gr_dev_sem);
11940 +       return error;
11941 +}
11942 +
11943 +int
11944 +gr_set_acls(const int type)
11945 +{
11946 +       struct acl_object_label *obj;
11947 +       struct task_struct *task, *task2;
11948 +       struct file *filp;
11949 +       struct acl_role_label *role = current->role;
11950 +       __u16 acl_role_id = current->acl_role_id;
11951 +
11952 +       read_lock(&tasklist_lock);
11953 +       read_lock(&grsec_exec_file_lock);
11954 +       do_each_thread(task2, task) {
11955 +               /* check to see if we're called from the exit handler,
11956 +                  if so, only replace ACLs that have inherited the admin
11957 +                  ACL */
11958 +
11959 +               if (type && (task->role != role ||
11960 +                            task->acl_role_id != acl_role_id))
11961 +                       continue;
11962 +
11963 +               task->acl_role_id = 0;
11964 +               task->acl_sp_role = 0;
11965 +
11966 +               if ((filp = task->exec_file)) {
11967 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
11968 +
11969 +                       task->acl =
11970 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
11971 +                                          task->role);
11972 +                       if (task->acl) {
11973 +                               struct acl_subject_label *curr;
11974 +                               curr = task->acl;
11975 +
11976 +                               task->is_writable = 0;
11977 +                               /* ignore additional mmap checks for processes that are writable 
11978 +                                  by the default ACL */
11979 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
11980 +                               if (unlikely(obj->mode & GR_WRITE))
11981 +                                       task->is_writable = 1;
11982 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
11983 +                               if (unlikely(obj->mode & GR_WRITE))
11984 +                                       task->is_writable = 1;
11985 +
11986 +                               gr_set_proc_res(task);
11987 +
11988 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11989 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
11990 +#endif
11991 +                       } else {
11992 +                               read_unlock(&grsec_exec_file_lock);
11993 +                               read_unlock(&tasklist_lock);
11994 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
11995 +                               return 1;
11996 +                       }
11997 +               } else {
11998 +                       // it's a kernel process
11999 +                       task->role = kernel_role;
12000 +                       task->acl = kernel_role->root_label;
12001 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
12002 +                       task->acl->mode &= ~GR_PROCFIND;
12003 +#endif
12004 +               }
12005 +       } while_each_thread(task2, task);
12006 +       read_unlock(&grsec_exec_file_lock);
12007 +       read_unlock(&tasklist_lock);
12008 +       return 0;
12009 +}
12010 +
12011 +void
12012 +gr_learn_resource(const struct task_struct *task,
12013 +                 const int res, const unsigned long wanted, const int gt)
12014 +{
12015 +       struct acl_subject_label *acl;
12016 +
12017 +       if (unlikely((gr_status & GR_READY) &&
12018 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
12019 +               goto skip_reslog;
12020 +
12021 +#ifdef CONFIG_GRKERNSEC_RESLOG
12022 +       gr_log_resource(task, res, wanted, gt);
12023 +#endif
12024 +      skip_reslog:
12025 +
12026 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
12027 +               return;
12028 +
12029 +       acl = task->acl;
12030 +
12031 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
12032 +                  !(acl->resmask & (1 << (unsigned short) res))))
12033 +               return;
12034 +
12035 +       if (wanted >= acl->res[res].rlim_cur) {
12036 +               unsigned long res_add;
12037 +
12038 +               res_add = wanted;
12039 +               switch (res) {
12040 +               case RLIMIT_CPU:
12041 +                       res_add += GR_RLIM_CPU_BUMP;
12042 +                       break;
12043 +               case RLIMIT_FSIZE:
12044 +                       res_add += GR_RLIM_FSIZE_BUMP;
12045 +                       break;
12046 +               case RLIMIT_DATA:
12047 +                       res_add += GR_RLIM_DATA_BUMP;
12048 +                       break;
12049 +               case RLIMIT_STACK:
12050 +                       res_add += GR_RLIM_STACK_BUMP;
12051 +                       break;
12052 +               case RLIMIT_CORE:
12053 +                       res_add += GR_RLIM_CORE_BUMP;
12054 +                       break;
12055 +               case RLIMIT_RSS:
12056 +                       res_add += GR_RLIM_RSS_BUMP;
12057 +                       break;
12058 +               case RLIMIT_NPROC:
12059 +                       res_add += GR_RLIM_NPROC_BUMP;
12060 +                       break;
12061 +               case RLIMIT_NOFILE:
12062 +                       res_add += GR_RLIM_NOFILE_BUMP;
12063 +                       break;
12064 +               case RLIMIT_MEMLOCK:
12065 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
12066 +                       break;
12067 +               case RLIMIT_AS:
12068 +                       res_add += GR_RLIM_AS_BUMP;
12069 +                       break;
12070 +               case RLIMIT_LOCKS:
12071 +                       res_add += GR_RLIM_LOCKS_BUMP;
12072 +                       break;
12073 +               }
12074 +
12075 +               acl->res[res].rlim_cur = res_add;
12076 +
12077 +               if (wanted > acl->res[res].rlim_max)
12078 +                       acl->res[res].rlim_max = res_add;
12079 +
12080 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
12081 +                              task->role->roletype, acl->filename,
12082 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
12083 +                              "", (unsigned long) res);
12084 +       }
12085 +
12086 +       return;
12087 +}
12088 +
12089 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
12090 +void
12091 +pax_set_initial_flags(struct linux_binprm *bprm)
12092 +{
12093 +       struct task_struct *task = current;
12094 +        struct acl_subject_label *proc;
12095 +       unsigned long flags;
12096 +
12097 +        if (unlikely(!(gr_status & GR_READY)))
12098 +                return;
12099 +
12100 +       flags = pax_get_flags(task);
12101 +
12102 +        proc = task->acl;
12103 +
12104 +       if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
12105 +               flags &= ~MF_PAX_PAGEEXEC;
12106 +       if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
12107 +               flags &= ~MF_PAX_SEGMEXEC;
12108 +       if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
12109 +               flags &= ~MF_PAX_RANDMMAP;
12110 +       if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
12111 +               flags &= ~MF_PAX_EMUTRAMP;
12112 +       if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
12113 +               flags &= ~MF_PAX_MPROTECT;
12114 +
12115 +       if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
12116 +               flags |= MF_PAX_PAGEEXEC;
12117 +       if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
12118 +               flags |= MF_PAX_SEGMEXEC;
12119 +       if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
12120 +               flags |= MF_PAX_RANDMMAP;
12121 +       if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
12122 +               flags |= MF_PAX_EMUTRAMP;
12123 +       if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
12124 +               flags |= MF_PAX_MPROTECT;
12125 +
12126 +       pax_set_flags(task, flags);
12127 +
12128 +        return;
12129 +}
12130 +#endif
12131 +
12132 +#ifdef CONFIG_SYSCTL
12133 +extern struct proc_dir_entry *proc_sys_root;
12134 +
12135 +/* the following function is called under the BKL */
12136 +
12137 +__u32
12138 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
12139 +                const void *newval)
12140 +{
12141 +       struct proc_dir_entry *tmp;
12142 +       struct nameidata nd;
12143 +       const char *proc_sys = "/proc/sys";
12144 +       char *path;
12145 +       struct acl_object_label *obj;
12146 +       unsigned short len = 0, pos = 0, depth = 0, i;
12147 +       __u32 err = 0;
12148 +       __u32 mode = 0;
12149 +
12150 +       if (unlikely(!(gr_status & GR_READY)))
12151 +               return 1;
12152 +
12153 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
12154 +
12155 +       if (oldval)
12156 +               mode |= GR_READ;
12157 +       if (newval)
12158 +               mode |= GR_WRITE;
12159 +
12160 +       /* convert the requested sysctl entry into a pathname */
12161 +
12162 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
12163 +               len += strlen(tmp->name);
12164 +               len++;
12165 +               depth++;
12166 +       }
12167 +
12168 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
12169 +               return 0;       /* deny */
12170 +
12171 +       memset(path, 0, PAGE_SIZE);
12172 +
12173 +       memcpy(path, proc_sys, strlen(proc_sys));
12174 +
12175 +       pos += strlen(proc_sys);
12176 +
12177 +       for (; depth > 0; depth--) {
12178 +               path[pos] = '/';
12179 +               pos++;
12180 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
12181 +                    tmp = tmp->parent) {
12182 +                       if (depth == i) {
12183 +                               memcpy(path + pos, tmp->name,
12184 +                                      strlen(tmp->name));
12185 +                               pos += strlen(tmp->name);
12186 +                       }
12187 +                       i++;
12188 +               }
12189 +       }
12190 +
12191 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
12192 +
12193 +       if (err)
12194 +               goto out;
12195 +
12196 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
12197 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
12198 +
12199 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
12200 +                    ((err & mode) != mode))) {
12201 +               __u32 new_mode = mode;
12202 +
12203 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12204 +
12205 +               err = new_mode;
12206 +               gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
12207 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
12208 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
12209 +                              path, (mode & GR_READ) ? " reading" : "",
12210 +                              (mode & GR_WRITE) ? " writing" : "");
12211 +               err = 0;
12212 +       } else if ((err & mode) != mode) {
12213 +               err = 0;
12214 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
12215 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
12216 +                              path, (mode & GR_READ) ? " reading" : "",
12217 +                              (mode & GR_WRITE) ? " writing" : "");
12218 +       }
12219 +
12220 +       path_release(&nd);
12221 +
12222 +      out:
12223 +       return err;
12224 +}
12225 +#endif
12226 +
12227 +int
12228 +gr_handle_proc_ptrace(struct task_struct *task)
12229 +{
12230 +       struct file *filp;
12231 +       struct task_struct *tmp = task;
12232 +       struct task_struct *curtemp = current;
12233 +       __u32 retmode;
12234 +
12235 +       if (unlikely(!(gr_status & GR_READY)))
12236 +               return 0;
12237 +
12238 +       read_lock(&tasklist_lock);
12239 +       read_lock(&grsec_exec_file_lock);
12240 +       filp = task->exec_file;
12241 +
12242 +       while (tmp->pid > 0) {
12243 +               if (tmp == curtemp)
12244 +                       break;
12245 +               tmp = tmp->parent;
12246 +       }
12247 +
12248 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
12249 +               read_unlock(&grsec_exec_file_lock);
12250 +               read_unlock(&tasklist_lock);
12251 +               return 1;
12252 +       }
12253 +
12254 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
12255 +       read_unlock(&grsec_exec_file_lock);
12256 +       read_unlock(&tasklist_lock);
12257 +
12258 +       if (retmode & GR_NOPTRACE)
12259 +               return 1;
12260 +
12261 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
12262 +           && (current->acl != task->acl || (current->acl != current->role->root_label
12263 +           && current->pid != task->pid)))
12264 +               return 1;
12265 +
12266 +       return 0;
12267 +}
12268 +
12269 +int
12270 +gr_handle_ptrace(struct task_struct *task, const long request)
12271 +{
12272 +       struct task_struct *tmp = task;
12273 +       struct task_struct *curtemp = current;
12274 +       __u32 retmode;
12275 +
12276 +       if (unlikely(!(gr_status & GR_READY)))
12277 +               return 0;
12278 +
12279 +       read_lock(&tasklist_lock);
12280 +       while (tmp->pid > 0) {
12281 +               if (tmp == curtemp)
12282 +                       break;
12283 +               tmp = tmp->parent;
12284 +       }
12285 +
12286 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
12287 +               read_unlock(&tasklist_lock);
12288 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12289 +               return 1;
12290 +       }
12291 +       read_unlock(&tasklist_lock);
12292 +
12293 +       read_lock(&grsec_exec_file_lock);
12294 +       if (unlikely(!task->exec_file)) {
12295 +               read_unlock(&grsec_exec_file_lock);
12296 +               return 0;
12297 +       }
12298 +
12299 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
12300 +       read_unlock(&grsec_exec_file_lock);
12301 +
12302 +       if (retmode & GR_NOPTRACE) {
12303 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12304 +               return 1;
12305 +       }
12306 +               
12307 +       if (retmode & GR_PTRACERD) {
12308 +               switch (request) {
12309 +               case PTRACE_POKETEXT:
12310 +               case PTRACE_POKEDATA:
12311 +               case PTRACE_POKEUSR:
12312 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
12313 +               case PTRACE_SETREGS:
12314 +               case PTRACE_SETFPREGS:
12315 +#endif
12316 +#ifdef CONFIG_X86
12317 +               case PTRACE_SETFPXREGS:
12318 +#endif
12319 +#ifdef CONFIG_ALTIVEC
12320 +               case PTRACE_SETVRREGS:
12321 +#endif
12322 +                       return 1;
12323 +               default:
12324 +                       return 0;
12325 +               }
12326 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
12327 +                  !(current->role->roletype & GR_ROLE_GOD) &&
12328 +                  (current->acl != task->acl)) {
12329 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12330 +               return 1;
12331 +       }
12332 +
12333 +       return 0;
12334 +}
12335 +
12336 +static int is_writable_mmap(const struct file *filp)
12337 +{
12338 +       struct task_struct *task = current;
12339 +       struct acl_object_label *obj, *obj2;
12340 +
12341 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
12342 +           !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
12343 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
12344 +               obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
12345 +                                    task->role->root_label);
12346 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
12347 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
12348 +                       return 1;
12349 +               }
12350 +       }
12351 +       return 0;
12352 +}
12353 +
12354 +int
12355 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
12356 +{
12357 +       __u32 mode;
12358 +
12359 +       if (unlikely(!file || !(prot & PROT_EXEC)))
12360 +               return 1;
12361 +
12362 +       if (is_writable_mmap(file))
12363 +               return 0;
12364 +
12365 +       mode =
12366 +           gr_search_file(file->f_dentry,
12367 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
12368 +                          file->f_vfsmnt);
12369 +
12370 +       if (!gr_tpe_allow(file))
12371 +               return 0;
12372 +
12373 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
12374 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12375 +               return 0;
12376 +       } else if (unlikely(!(mode & GR_EXEC))) {
12377 +               return 0;
12378 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
12379 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12380 +               return 1;
12381 +       }
12382 +
12383 +       return 1;
12384 +}
12385 +
12386 +int
12387 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
12388 +{
12389 +       __u32 mode;
12390 +
12391 +       if (unlikely(!file || !(prot & PROT_EXEC)))
12392 +               return 1;
12393 +
12394 +       if (is_writable_mmap(file))
12395 +               return 0;
12396 +
12397 +       mode =
12398 +           gr_search_file(file->f_dentry,
12399 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
12400 +                          file->f_vfsmnt);
12401 +
12402 +       if (!gr_tpe_allow(file))
12403 +               return 0;
12404 +
12405 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
12406 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12407 +               return 0;
12408 +       } else if (unlikely(!(mode & GR_EXEC))) {
12409 +               return 0;
12410 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
12411 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12412 +               return 1;
12413 +       }
12414 +
12415 +       return 1;
12416 +}
12417 +
12418 +void
12419 +gr_acl_handle_psacct(struct task_struct *task, const long code)
12420 +{
12421 +       unsigned long runtime;
12422 +       unsigned long cputime;
12423 +       unsigned int wday, cday;
12424 +       __u8 whr, chr;
12425 +       __u8 wmin, cmin;
12426 +       __u8 wsec, csec;
12427 +
12428 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
12429 +                    !(task->acl->mode & GR_PROCACCT)))
12430 +               return;
12431 +
12432 +       runtime = xtime.tv_sec - task->start_time.tv_sec;
12433 +       wday = runtime / (3600 * 24);
12434 +       runtime -= wday * (3600 * 24);
12435 +       whr = runtime / 3600;
12436 +       runtime -= whr * 3600;
12437 +       wmin = runtime / 60;
12438 +       runtime -= wmin * 60;
12439 +       wsec = runtime;
12440 +
12441 +       cputime = (task->utime + task->stime) / HZ;
12442 +       cday = cputime / (3600 * 24);
12443 +       cputime -= cday * (3600 * 24);
12444 +       chr = cputime / 3600;
12445 +       cputime -= chr * 3600;
12446 +       cmin = cputime / 60;
12447 +       cputime -= cmin * 60;
12448 +       csec = cputime;
12449 +
12450 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
12451 +
12452 +       return;
12453 +}
12454 +
12455 +void gr_set_kernel_label(struct task_struct *task)
12456 +{
12457 +       if (gr_status & GR_READY) {
12458 +               task->role = kernel_role;
12459 +               task->acl = kernel_role->root_label;
12460 +       }
12461 +       return;
12462 +}
12463 +
12464 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
12465 +{
12466 +       struct task_struct *task = current;
12467 +       struct dentry *dentry = file->f_dentry;
12468 +       struct vfsmount *mnt = file->f_vfsmnt;
12469 +       struct acl_object_label *obj, *tmp;
12470 +       struct acl_subject_label *subj;
12471 +       unsigned int bufsize;
12472 +       int is_not_root;
12473 +       char *path;
12474 +
12475 +       if (unlikely(!(gr_status & GR_READY)))
12476 +               return 1;
12477 +
12478 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
12479 +               return 1;
12480 +
12481 +       subj = task->acl;
12482 +       do {
12483 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
12484 +               if (obj != NULL)
12485 +                       return (obj->mode & GR_FIND) ? 1 : 0;
12486 +       } while ((subj = subj->parent_subject));
12487 +       
12488 +       obj = chk_obj_label(dentry, mnt, task->acl);
12489 +       if (obj->globbed == NULL)
12490 +               return (obj->mode & GR_FIND) ? 1 : 0;
12491 +
12492 +       is_not_root = ((obj->filename[0] == '/') &&
12493 +                  (obj->filename[1] == '\0')) ? 0 : 1;
12494 +       bufsize = PAGE_SIZE - namelen - is_not_root;
12495 +
12496 +       /* check bufsize > PAGE_SIZE || bufsize == 0 */
12497 +       if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
12498 +               return 1;
12499 +
12500 +       preempt_disable();
12501 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
12502 +                          bufsize);
12503 +
12504 +       bufsize = strlen(path);
12505 +
12506 +       /* if base is "/", don't append an additional slash */
12507 +       if (is_not_root)
12508 +               *(path + bufsize) = '/';
12509 +       memcpy(path + bufsize + is_not_root, name, namelen);
12510 +       *(path + bufsize + namelen + is_not_root) = '\0';
12511 +
12512 +       tmp = obj->globbed;
12513 +       while (tmp) {
12514 +               if (!glob_match(tmp->filename, path)) {
12515 +                       preempt_enable();
12516 +                       return (tmp->mode & GR_FIND) ? 1 : 0;
12517 +               }
12518 +               tmp = tmp->next;
12519 +       }
12520 +       preempt_enable();
12521 +       return (obj->mode & GR_FIND) ? 1 : 0;
12522 +}
12523 +
12524 +EXPORT_SYMBOL(gr_learn_resource);
12525 +EXPORT_SYMBOL(gr_set_kernel_label);
12526 +#ifdef CONFIG_SECURITY
12527 +EXPORT_SYMBOL(gr_check_user_change);
12528 +EXPORT_SYMBOL(gr_check_group_change);
12529 +#endif
12530 +
12531 diff -urNp linux-2.6.16.12/grsecurity/gracl_cap.c linux-2.6.16.12/grsecurity/gracl_cap.c
12532 --- linux-2.6.16.12/grsecurity/gracl_cap.c      1969-12-31 19:00:00.000000000 -0500
12533 +++ linux-2.6.16.12/grsecurity/gracl_cap.c      2006-05-01 20:17:33.000000000 -0400
12534 @@ -0,0 +1,110 @@
12535 +#include <linux/kernel.h>
12536 +#include <linux/module.h>
12537 +#include <linux/sched.h>
12538 +#include <linux/capability.h>
12539 +#include <linux/gracl.h>
12540 +#include <linux/grsecurity.h>
12541 +#include <linux/grinternal.h>
12542 +
12543 +static const char *captab_log[] = {
12544 +       "CAP_CHOWN",
12545 +       "CAP_DAC_OVERRIDE",
12546 +       "CAP_DAC_READ_SEARCH",
12547 +       "CAP_FOWNER",
12548 +       "CAP_FSETID",
12549 +       "CAP_KILL",
12550 +       "CAP_SETGID",
12551 +       "CAP_SETUID",
12552 +       "CAP_SETPCAP",
12553 +       "CAP_LINUX_IMMUTABLE",
12554 +       "CAP_NET_BIND_SERVICE",
12555 +       "CAP_NET_BROADCAST",
12556 +       "CAP_NET_ADMIN",
12557 +       "CAP_NET_RAW",
12558 +       "CAP_IPC_LOCK",
12559 +       "CAP_IPC_OWNER",
12560 +       "CAP_SYS_MODULE",
12561 +       "CAP_SYS_RAWIO",
12562 +       "CAP_SYS_CHROOT",
12563 +       "CAP_SYS_PTRACE",
12564 +       "CAP_SYS_PACCT",
12565 +       "CAP_SYS_ADMIN",
12566 +       "CAP_SYS_BOOT",
12567 +       "CAP_SYS_NICE",
12568 +       "CAP_SYS_RESOURCE",
12569 +       "CAP_SYS_TIME",
12570 +       "CAP_SYS_TTY_CONFIG",
12571 +       "CAP_MKNOD",
12572 +       "CAP_LEASE"
12573 +};
12574 +
12575 +EXPORT_SYMBOL(gr_task_is_capable);
12576 +
12577 +int
12578 +gr_task_is_capable(struct task_struct *task, const int cap)
12579 +{
12580 +       struct acl_subject_label *curracl;
12581 +       __u32 cap_drop = 0, cap_mask = 0;
12582 +
12583 +       if (!gr_acl_is_enabled())
12584 +               return 1;
12585 +
12586 +       curracl = task->acl;
12587 +
12588 +       cap_drop = curracl->cap_lower;
12589 +       cap_mask = curracl->cap_mask;
12590 +
12591 +       while ((curracl = curracl->parent_subject)) {
12592 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
12593 +                       cap_drop |= curracl->cap_lower & (1 << cap);
12594 +               cap_mask |= curracl->cap_mask;
12595 +       }
12596 +
12597 +       if (!cap_raised(cap_drop, cap))
12598 +               return 1;
12599 +
12600 +       curracl = task->acl;
12601 +
12602 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
12603 +           && cap_raised(task->cap_effective, cap)) {
12604 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
12605 +                              task->role->roletype, task->uid,
12606 +                              task->gid, task->exec_file ?
12607 +                              gr_to_filename(task->exec_file->f_dentry,
12608 +                              task->exec_file->f_vfsmnt) : curracl->filename,
12609 +                              curracl->filename, 0UL,
12610 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
12611 +               return 1;
12612 +       }
12613 +
12614 +       if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
12615 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
12616 +
12617 +       return 0;
12618 +}
12619 +
12620 +int
12621 +gr_is_capable_nolog(const int cap)
12622 +{
12623 +       struct acl_subject_label *curracl;
12624 +       __u32 cap_drop = 0, cap_mask = 0;
12625 +
12626 +       if (!gr_acl_is_enabled())
12627 +               return 1;
12628 +
12629 +       curracl = current->acl;
12630 +
12631 +       cap_drop = curracl->cap_lower;
12632 +       cap_mask = curracl->cap_mask;
12633 +
12634 +       while ((curracl = curracl->parent_subject)) {
12635 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
12636 +               cap_mask |= curracl->cap_mask;
12637 +       }
12638 +
12639 +       if (!cap_raised(cap_drop, cap))
12640 +               return 1;
12641 +
12642 +       return 0;
12643 +}
12644 +
12645 diff -urNp linux-2.6.16.12/grsecurity/gracl_fs.c linux-2.6.16.12/grsecurity/gracl_fs.c
12646 --- linux-2.6.16.12/grsecurity/gracl_fs.c       1969-12-31 19:00:00.000000000 -0500
12647 +++ linux-2.6.16.12/grsecurity/gracl_fs.c       2006-05-01 20:17:33.000000000 -0400
12648 @@ -0,0 +1,423 @@
12649 +#include <linux/kernel.h>
12650 +#include <linux/sched.h>
12651 +#include <linux/types.h>
12652 +#include <linux/fs.h>
12653 +#include <linux/file.h>
12654 +#include <linux/stat.h>
12655 +#include <linux/grsecurity.h>
12656 +#include <linux/grinternal.h>
12657 +#include <linux/gracl.h>
12658 +
12659 +__u32
12660 +gr_acl_handle_hidden_file(const struct dentry * dentry,
12661 +                         const struct vfsmount * mnt)
12662 +{
12663 +       __u32 mode;
12664 +
12665 +       if (unlikely(!dentry->d_inode))
12666 +               return GR_FIND;
12667 +
12668 +       mode =
12669 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
12670 +
12671 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
12672 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
12673 +               return mode;
12674 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
12675 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
12676 +               return 0;
12677 +       } else if (unlikely(!(mode & GR_FIND)))
12678 +               return 0;
12679 +
12680 +       return GR_FIND;
12681 +}
12682 +
12683 +__u32
12684 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12685 +                  const int fmode)
12686 +{
12687 +       __u32 reqmode = GR_FIND;
12688 +       __u32 mode;
12689 +
12690 +       if (unlikely(!dentry->d_inode))
12691 +               return reqmode;
12692 +
12693 +       if (unlikely(fmode & O_APPEND))
12694 +               reqmode |= GR_APPEND;
12695 +       else if (unlikely(fmode & FMODE_WRITE))
12696 +               reqmode |= GR_WRITE;
12697 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
12698 +               reqmode |= GR_READ;
12699 +
12700 +       mode =
12701 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
12702 +                          mnt);
12703 +
12704 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12705 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
12706 +                              reqmode & GR_READ ? " reading" : "",
12707 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12708 +                              GR_APPEND ? " appending" : "");
12709 +               return reqmode;
12710 +       } else
12711 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12712 +       {
12713 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
12714 +                              reqmode & GR_READ ? " reading" : "",
12715 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12716 +                              GR_APPEND ? " appending" : "");
12717 +               return 0;
12718 +       } else if (unlikely((mode & reqmode) != reqmode))
12719 +               return 0;
12720 +
12721 +       return reqmode;
12722 +}
12723 +
12724 +__u32
12725 +gr_acl_handle_creat(const struct dentry * dentry,
12726 +                   const struct dentry * p_dentry,
12727 +                   const struct vfsmount * p_mnt, const int fmode,
12728 +                   const int imode)
12729 +{
12730 +       __u32 reqmode = GR_WRITE | GR_CREATE;
12731 +       __u32 mode;
12732 +
12733 +       if (unlikely(fmode & O_APPEND))
12734 +               reqmode |= GR_APPEND;
12735 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
12736 +               reqmode |= GR_READ;
12737 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
12738 +               reqmode |= GR_SETID;
12739 +
12740 +       mode =
12741 +           gr_check_create(dentry, p_dentry, p_mnt,
12742 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
12743 +
12744 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12745 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
12746 +                              reqmode & GR_READ ? " reading" : "",
12747 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12748 +                              GR_APPEND ? " appending" : "");
12749 +               return reqmode;
12750 +       } else
12751 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12752 +       {
12753 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
12754 +                              reqmode & GR_READ ? " reading" : "",
12755 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12756 +                              GR_APPEND ? " appending" : "");
12757 +               return 0;
12758 +       } else if (unlikely((mode & reqmode) != reqmode))
12759 +               return 0;
12760 +
12761 +       return reqmode;
12762 +}
12763 +
12764 +__u32
12765 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
12766 +                    const int fmode)
12767 +{
12768 +       __u32 mode, reqmode = GR_FIND;
12769 +
12770 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
12771 +               reqmode |= GR_EXEC;
12772 +       if (fmode & S_IWOTH)
12773 +               reqmode |= GR_WRITE;
12774 +       if (fmode & S_IROTH)
12775 +               reqmode |= GR_READ;
12776 +
12777 +       mode =
12778 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
12779 +                          mnt);
12780 +
12781 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12782 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
12783 +                              reqmode & GR_READ ? " reading" : "",
12784 +                              reqmode & GR_WRITE ? " writing" : "",
12785 +                              reqmode & GR_EXEC ? " executing" : "");
12786 +               return reqmode;
12787 +       } else
12788 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12789 +       {
12790 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
12791 +                              reqmode & GR_READ ? " reading" : "",
12792 +                              reqmode & GR_WRITE ? " writing" : "",
12793 +                              reqmode & GR_EXEC ? " executing" : "");
12794 +               return 0;
12795 +       } else if (unlikely((mode & reqmode) != reqmode))
12796 +               return 0;
12797 +
12798 +       return reqmode;
12799 +}
12800 +
12801 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
12802 +{
12803 +       __u32 mode;
12804 +
12805 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
12806 +
12807 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
12808 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
12809 +               return mode;
12810 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
12811 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
12812 +               return 0;
12813 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
12814 +               return 0;
12815 +
12816 +       return (reqmode);
12817 +}
12818 +
12819 +__u32
12820 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
12821 +{
12822 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
12823 +}
12824 +
12825 +__u32
12826 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
12827 +{
12828 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
12829 +}
12830 +
12831 +__u32
12832 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
12833 +{
12834 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
12835 +}
12836 +
12837 +__u32
12838 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
12839 +{
12840 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
12841 +}
12842 +
12843 +__u32
12844 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
12845 +                    mode_t mode)
12846 +{
12847 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
12848 +               return 1;
12849 +
12850 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
12851 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
12852 +                                  GR_FCHMOD_ACL_MSG);
12853 +       } else {
12854 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
12855 +       }
12856 +}
12857 +
12858 +__u32
12859 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
12860 +                   mode_t mode)
12861 +{
12862 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
12863 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
12864 +                                  GR_CHMOD_ACL_MSG);
12865 +       } else {
12866 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
12867 +       }
12868 +}
12869 +
12870 +__u32
12871 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
12872 +{
12873 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
12874 +}
12875 +
12876 +__u32
12877 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
12878 +{
12879 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
12880 +}
12881 +
12882 +__u32
12883 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
12884 +{
12885 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
12886 +                          GR_UNIXCONNECT_ACL_MSG);
12887 +}
12888 +
12889 +/* hardlinks require at minimum create permission,
12890 +   any additional privilege required is based on the
12891 +   privilege of the file being linked to
12892 +*/
12893 +__u32
12894 +gr_acl_handle_link(const struct dentry * new_dentry,
12895 +                  const struct dentry * parent_dentry,
12896 +                  const struct vfsmount * parent_mnt,
12897 +                  const struct dentry * old_dentry,
12898 +                  const struct vfsmount * old_mnt, const char *to)
12899 +{
12900 +       __u32 mode;
12901 +       __u32 needmode = GR_CREATE | GR_LINK;
12902 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
12903 +
12904 +       mode =
12905 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
12906 +                         old_mnt);
12907 +
12908 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
12909 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
12910 +               return mode;
12911 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
12912 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
12913 +               return 0;
12914 +       } else if (unlikely((mode & needmode) != needmode))
12915 +               return 0;
12916 +
12917 +       return 1;
12918 +}
12919 +
12920 +__u32
12921 +gr_acl_handle_symlink(const struct dentry * new_dentry,
12922 +                     const struct dentry * parent_dentry,
12923 +                     const struct vfsmount * parent_mnt, const char *from)
12924 +{
12925 +       __u32 needmode = GR_WRITE | GR_CREATE;
12926 +       __u32 mode;
12927 +
12928 +       mode =
12929 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
12930 +                           GR_CREATE | GR_AUDIT_CREATE |
12931 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
12932 +
12933 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
12934 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
12935 +               return mode;
12936 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
12937 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
12938 +               return 0;
12939 +       } else if (unlikely((mode & needmode) != needmode))
12940 +               return 0;
12941 +
12942 +       return (GR_WRITE | GR_CREATE);
12943 +}
12944 +
12945 +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)
12946 +{
12947 +       __u32 mode;
12948 +
12949 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
12950 +
12951 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
12952 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
12953 +               return mode;
12954 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
12955 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
12956 +               return 0;
12957 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
12958 +               return 0;
12959 +
12960 +       return (reqmode);
12961 +}
12962 +
12963 +__u32
12964 +gr_acl_handle_mknod(const struct dentry * new_dentry,
12965 +                   const struct dentry * parent_dentry,
12966 +                   const struct vfsmount * parent_mnt,
12967 +                   const int mode)
12968 +{
12969 +       __u32 reqmode = GR_WRITE | GR_CREATE;
12970 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
12971 +               reqmode |= GR_SETID;
12972 +
12973 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
12974 +                                 reqmode, GR_MKNOD_ACL_MSG);
12975 +}
12976 +
12977 +__u32
12978 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
12979 +                   const struct dentry *parent_dentry,
12980 +                   const struct vfsmount *parent_mnt)
12981 +{
12982 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
12983 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
12984 +}
12985 +
12986 +#define RENAME_CHECK_SUCCESS(old, new) \
12987 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
12988 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
12989 +
12990 +int
12991 +gr_acl_handle_rename(struct dentry *new_dentry,
12992 +                    struct dentry *parent_dentry,
12993 +                    const struct vfsmount *parent_mnt,
12994 +                    struct dentry *old_dentry,
12995 +                    struct inode *old_parent_inode,
12996 +                    struct vfsmount *old_mnt, const char *newname)
12997 +{
12998 +       __u32 comp1, comp2;
12999 +       int error = 0;
13000 +
13001 +       if (unlikely(!gr_acl_is_enabled()))
13002 +               return 0;
13003 +
13004 +       if (!new_dentry->d_inode) {
13005 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
13006 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
13007 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
13008 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
13009 +                                      GR_DELETE | GR_AUDIT_DELETE |
13010 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
13011 +                                      GR_SUPPRESS, old_mnt);
13012 +       } else {
13013 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
13014 +                                      GR_CREATE | GR_DELETE |
13015 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
13016 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
13017 +                                      GR_SUPPRESS, parent_mnt);
13018 +               comp2 =
13019 +                   gr_search_file(old_dentry,
13020 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
13021 +                                  GR_DELETE | GR_AUDIT_DELETE |
13022 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
13023 +       }
13024 +
13025 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
13026 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
13027 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
13028 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
13029 +                && !(comp2 & GR_SUPPRESS)) {
13030 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
13031 +               error = -EACCES;
13032 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
13033 +               error = -EACCES;
13034 +
13035 +       return error;
13036 +}
13037 +
13038 +void
13039 +gr_acl_handle_exit(void)
13040 +{
13041 +       u16 id;
13042 +       char *rolename;
13043 +       struct file *exec_file;
13044 +
13045 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
13046 +               id = current->acl_role_id;
13047 +               rolename = current->role->rolename;
13048 +               gr_set_acls(1);
13049 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
13050 +       }
13051 +
13052 +       write_lock(&grsec_exec_file_lock);
13053 +       exec_file = current->exec_file;
13054 +       current->exec_file = NULL;
13055 +       write_unlock(&grsec_exec_file_lock);
13056 +
13057 +       if (exec_file)
13058 +               fput(exec_file);
13059 +}
13060 +
13061 +int
13062 +gr_acl_handle_procpidmem(const struct task_struct *task)
13063 +{
13064 +       if (unlikely(!gr_acl_is_enabled()))
13065 +               return 0;
13066 +
13067 +       if (task->acl->mode & GR_PROTPROCFD)
13068 +               return -EACCES;
13069 +
13070 +       return 0;
13071 +}
13072 diff -urNp linux-2.6.16.12/grsecurity/gracl_ip.c linux-2.6.16.12/grsecurity/gracl_ip.c
13073 --- linux-2.6.16.12/grsecurity/gracl_ip.c       1969-12-31 19:00:00.000000000 -0500
13074 +++ linux-2.6.16.12/grsecurity/gracl_ip.c       2006-05-01 20:17:33.000000000 -0400
13075 @@ -0,0 +1,313 @@
13076 +#include <linux/kernel.h>
13077 +#include <asm/uaccess.h>
13078 +#include <asm/errno.h>
13079 +#include <net/sock.h>
13080 +#include <linux/file.h>
13081 +#include <linux/fs.h>
13082 +#include <linux/net.h>
13083 +#include <linux/in.h>
13084 +#include <linux/skbuff.h>
13085 +#include <linux/ip.h>
13086 +#include <linux/udp.h>
13087 +#include <linux/smp_lock.h>
13088 +#include <linux/types.h>
13089 +#include <linux/sched.h>
13090 +#include <linux/netdevice.h>
13091 +#include <linux/inetdevice.h>
13092 +#include <linux/gracl.h>
13093 +#include <linux/grsecurity.h>
13094 +#include <linux/grinternal.h>
13095 +
13096 +#define GR_BIND        0x01
13097 +#define GR_CONNECT     0x02
13098 +#define GR_INVERT      0x04
13099 +
13100 +static const char * gr_protocols[256] = {
13101 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
13102 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
13103 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
13104 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
13105 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
13106 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
13107 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
13108 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
13109 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
13110 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
13111 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
13112 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
13113 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
13114 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
13115 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
13116 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
13117 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
13118 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
13119 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
13120 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
13121 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
13122 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
13123 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
13124 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
13125 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
13126 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
13127 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
13128 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
13129 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
13130 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
13131 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
13132 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
13133 +       };
13134 +
13135 +static const char * gr_socktypes[11] = {
13136 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
13137 +       "unknown:7", "unknown:8", "unknown:9", "packet"
13138 +       };
13139 +
13140 +const char *
13141 +gr_proto_to_name(unsigned char proto)
13142 +{
13143 +       return gr_protocols[proto];
13144 +}
13145 +
13146 +const char *
13147 +gr_socktype_to_name(unsigned char type)
13148 +{
13149 +       return gr_socktypes[type];
13150 +}
13151 +
13152 +int
13153 +gr_search_socket(const int domain, const int type, const int protocol)
13154 +{
13155 +       struct acl_subject_label *curr;
13156 +
13157 +       if (unlikely(!gr_acl_is_enabled()))
13158 +               goto exit;
13159 +
13160 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
13161 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
13162 +               goto exit;      // let the kernel handle it
13163 +
13164 +       curr = current->acl;
13165 +
13166 +       if (!curr->ips)
13167 +               goto exit;
13168 +
13169 +       if ((curr->ip_type & (1 << type)) &&
13170 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
13171 +               goto exit;
13172 +
13173 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
13174 +               /* we don't place acls on raw sockets , and sometimes
13175 +                  dgram/ip sockets are opened for ioctl and not
13176 +                  bind/connect, so we'll fake a bind learn log */
13177 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
13178 +                       __u32 fakeip = 0;
13179 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13180 +                                      current->role->roletype, current->uid,
13181 +                                      current->gid, current->exec_file ?
13182 +                                      gr_to_filename(current->exec_file->f_dentry,
13183 +                                      current->exec_file->f_vfsmnt) :
13184 +                                      curr->filename, curr->filename,
13185 +                                      NIPQUAD(fakeip), 0, type,
13186 +                                      protocol, GR_CONNECT, 
13187 +NIPQUAD(current->signal->curr_ip));
13188 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
13189 +                       __u32 fakeip = 0;
13190 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13191 +                                      current->role->roletype, current->uid,
13192 +                                      current->gid, current->exec_file ?
13193 +                                      gr_to_filename(current->exec_file->f_dentry,
13194 +                                      current->exec_file->f_vfsmnt) :
13195 +                                      curr->filename, curr->filename,
13196 +                                      NIPQUAD(fakeip), 0, type,
13197 +                                      protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
13198 +               }
13199 +               /* we'll log when they use connect or bind */
13200 +               goto exit;
13201 +       }
13202 +
13203 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
13204 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
13205 +
13206 +       return 0;
13207 +      exit:
13208 +       return 1;
13209 +}
13210 +
13211 +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)
13212 +{
13213 +       if ((ip->mode & mode) &&
13214 +           (ip_port >= ip->low) &&
13215 +           (ip_port <= ip->high) &&
13216 +           ((ntohl(ip_addr) & our_netmask) ==
13217 +            (ntohl(our_addr) & our_netmask))
13218 +           && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
13219 +           && (ip->type & (1 << type))) {
13220 +               if (ip->mode & GR_INVERT)
13221 +                       return 2; // specifically denied
13222 +               else
13223 +                       return 1; // allowed
13224 +       }
13225 +
13226 +       return 0; // not specifically allowed, may continue parsing
13227 +}
13228 +
13229 +static int
13230 +gr_search_connectbind(const int mode, const struct sock *sk,
13231 +                     const struct sockaddr_in *addr, const int type)
13232 +{
13233 +       char iface[IFNAMSIZ] = {0};
13234 +       struct acl_subject_label *curr;
13235 +       struct acl_ip_label *ip;
13236 +       struct net_device *dev;
13237 +       struct in_device *idev;
13238 +       unsigned long i;
13239 +       int ret;
13240 +       __u32 ip_addr = 0;
13241 +       __u32 our_addr;
13242 +       __u32 our_netmask;
13243 +       char *p;
13244 +       __u16 ip_port = 0;
13245 +
13246 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
13247 +               return 1;
13248 +
13249 +       curr = current->acl;
13250 +
13251 +       if (!curr->ips)
13252 +               return 1;
13253 +
13254 +       ip_addr = addr->sin_addr.s_addr;
13255 +       ip_port = ntohs(addr->sin_port);
13256 +
13257 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
13258 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13259 +                              current->role->roletype, current->uid,
13260 +                              current->gid, current->exec_file ?
13261 +                              gr_to_filename(current->exec_file->f_dentry,
13262 +                              current->exec_file->f_vfsmnt) :
13263 +                              curr->filename, curr->filename,
13264 +                              NIPQUAD(ip_addr), ip_port, type,
13265 +                              sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
13266 +               return 1;
13267 +       }
13268 +
13269 +       for (i = 0; i < curr->ip_num; i++) {
13270 +               ip = *(curr->ips + i);
13271 +               if (ip->iface != NULL) {
13272 +                       strncpy(iface, ip->iface, IFNAMSIZ - 1);
13273 +                       p = strchr(iface, ':');
13274 +                       if (p != NULL)
13275 +                               *p = '\0';
13276 +                       dev = dev_get_by_name(iface);
13277 +                       if (dev == NULL)
13278 +                               continue;
13279 +                       idev = in_dev_get(dev);
13280 +                       if (idev == NULL) {
13281 +                               dev_put(dev);
13282 +                               continue;
13283 +                       }
13284 +                       rcu_read_lock();
13285 +                       for_ifa(idev) {
13286 +                               if (!strcmp(ip->iface, ifa->ifa_label)) {
13287 +                                       our_addr = ifa->ifa_address;
13288 +                                       our_netmask = 0xffffffff;
13289 +                                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
13290 +                                       if (ret == 1) {
13291 +                                               rcu_read_unlock();
13292 +                                               in_dev_put(idev);
13293 +                                               dev_put(dev);
13294 +                                               return 1;
13295 +                                       } else if (ret == 2) {
13296 +                                               rcu_read_unlock();
13297 +                                               in_dev_put(idev);
13298 +                                               dev_put(dev);
13299 +                                               goto denied;
13300 +                                       }
13301 +                               }
13302 +                       } endfor_ifa(idev);
13303 +                       rcu_read_unlock();
13304 +                       in_dev_put(idev);
13305 +                       dev_put(dev);
13306 +               } else {
13307 +                       our_addr = ip->addr;
13308 +                       our_netmask = ip->netmask;
13309 +                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
13310 +                       if (ret == 1)
13311 +                               return 1;
13312 +                       else if (ret == 2)
13313 +                               goto denied;
13314 +               }
13315 +       }
13316 +
13317 +denied:
13318 +       if (mode == GR_BIND)
13319 +               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));
13320 +       else if (mode == GR_CONNECT)
13321 +               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));
13322 +
13323 +       return 0;
13324 +}
13325 +
13326 +int
13327 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
13328 +{
13329 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
13330 +}
13331 +
13332 +int
13333 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
13334 +{
13335 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
13336 +}
13337 +
13338 +int gr_search_listen(const struct socket *sock)
13339 +{
13340 +       struct sock *sk = sock->sk;
13341 +       struct sockaddr_in addr;
13342 +
13343 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
13344 +       addr.sin_port = inet_sk(sk)->sport;
13345 +
13346 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
13347 +}
13348 +
13349 +int gr_search_accept(const struct socket *sock)
13350 +{
13351 +       struct sock *sk = sock->sk;
13352 +       struct sockaddr_in addr;
13353 +
13354 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
13355 +       addr.sin_port = inet_sk(sk)->sport;
13356 +
13357 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
13358 +}
13359 +
13360 +int
13361 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
13362 +{
13363 +       if (addr)
13364 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
13365 +       else {
13366 +               struct sockaddr_in sin;
13367 +               const struct inet_sock *inet = inet_sk(sk);
13368 +
13369 +               sin.sin_addr.s_addr = inet->daddr;
13370 +               sin.sin_port = inet->dport;
13371 +
13372 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
13373 +       }
13374 +}
13375 +
13376 +int
13377 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
13378 +{
13379 +       struct sockaddr_in sin;
13380 +
13381 +       if (unlikely(skb->len < sizeof (struct udphdr)))
13382 +               return 1;       // skip this packet
13383 +
13384 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
13385 +       sin.sin_port = skb->h.uh->source;
13386 +
13387 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
13388 +}
13389 diff -urNp linux-2.6.16.12/grsecurity/gracl_learn.c linux-2.6.16.12/grsecurity/gracl_learn.c
13390 --- linux-2.6.16.12/grsecurity/gracl_learn.c    1969-12-31 19:00:00.000000000 -0500
13391 +++ linux-2.6.16.12/grsecurity/gracl_learn.c    2006-05-01 20:17:33.000000000 -0400
13392 @@ -0,0 +1,204 @@
13393 +#include <linux/kernel.h>
13394 +#include <linux/mm.h>
13395 +#include <linux/sched.h>
13396 +#include <linux/poll.h>
13397 +#include <linux/smp_lock.h>
13398 +#include <linux/string.h>
13399 +#include <linux/file.h>
13400 +#include <linux/types.h>
13401 +#include <linux/vmalloc.h>
13402 +#include <linux/grinternal.h>
13403 +
13404 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
13405 +                                  size_t count, loff_t *ppos);
13406 +extern int gr_acl_is_enabled(void);
13407 +
13408 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
13409 +static int gr_learn_attached;
13410 +
13411 +/* use a 512k buffer */
13412 +#define LEARN_BUFFER_SIZE (512 * 1024)
13413 +
13414 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
13415 +static DECLARE_MUTEX(gr_learn_user_sem);
13416 +
13417 +/* we need to maintain two buffers, so that the kernel context of grlearn
13418 +   uses a semaphore around the userspace copying, and the other kernel contexts
13419 +   use a spinlock when copying into the buffer, since they cannot sleep
13420 +*/
13421 +static char *learn_buffer;
13422 +static char *learn_buffer_user;
13423 +static int learn_buffer_len;
13424 +static int learn_buffer_user_len;
13425 +
13426 +static ssize_t
13427 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
13428 +{
13429 +       DECLARE_WAITQUEUE(wait, current);
13430 +       ssize_t retval = 0;
13431 +
13432 +       add_wait_queue(&learn_wait, &wait);
13433 +       set_current_state(TASK_INTERRUPTIBLE);
13434 +       do {
13435 +               down(&gr_learn_user_sem);
13436 +               spin_lock(&gr_learn_lock);
13437 +               if (learn_buffer_len)
13438 +                       break;
13439 +               spin_unlock(&gr_learn_lock);
13440 +               up(&gr_learn_user_sem);
13441 +               if (file->f_flags & O_NONBLOCK) {
13442 +                       retval = -EAGAIN;
13443 +                       goto out;
13444 +               }
13445 +               if (signal_pending(current)) {
13446 +                       retval = -ERESTARTSYS;
13447 +                       goto out;
13448 +               }
13449 +
13450 +               schedule();
13451 +       } while (1);
13452 +
13453 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
13454 +       learn_buffer_user_len = learn_buffer_len;
13455 +       retval = learn_buffer_len;
13456 +       learn_buffer_len = 0;
13457 +
13458 +       spin_unlock(&gr_learn_lock);
13459 +
13460 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
13461 +               retval = -EFAULT;
13462 +
13463 +       up(&gr_learn_user_sem);
13464 +out:
13465 +       set_current_state(TASK_RUNNING);
13466 +       remove_wait_queue(&learn_wait, &wait);
13467 +       return retval;
13468 +}
13469 +
13470 +static unsigned int
13471 +poll_learn(struct file * file, poll_table * wait)
13472 +{
13473 +       poll_wait(file, &learn_wait, wait);
13474 +
13475 +       if (learn_buffer_len)
13476 +               return (POLLIN | POLLRDNORM);
13477 +
13478 +       return 0;
13479 +}
13480 +
13481 +void
13482 +gr_clear_learn_entries(void)
13483 +{
13484 +       char *tmp;
13485 +
13486 +       down(&gr_learn_user_sem);
13487 +       if (learn_buffer != NULL) {
13488 +               spin_lock(&gr_learn_lock);
13489 +               tmp = learn_buffer;
13490 +               learn_buffer = NULL;
13491 +               spin_unlock(&gr_learn_lock);
13492 +               vfree(learn_buffer);
13493 +       }
13494 +       if (learn_buffer_user != NULL) {
13495 +               vfree(learn_buffer_user);
13496 +               learn_buffer_user = NULL;
13497 +       }
13498 +       learn_buffer_len = 0;
13499 +       up(&gr_learn_user_sem);
13500 +
13501 +       return;
13502 +}
13503 +
13504 +void
13505 +gr_add_learn_entry(const char *fmt, ...)
13506 +{
13507 +       va_list args;
13508 +       unsigned int len;
13509 +
13510 +       if (!gr_learn_attached)
13511 +               return;
13512 +
13513 +       spin_lock(&gr_learn_lock);
13514 +
13515 +       /* leave a gap at the end so we know when it's "full" but don't have to
13516 +          compute the exact length of the string we're trying to append
13517 +       */
13518 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
13519 +               spin_unlock(&gr_learn_lock);
13520 +               wake_up_interruptible(&learn_wait);
13521 +               return;
13522 +       }
13523 +       if (learn_buffer == NULL) {
13524 +               spin_unlock(&gr_learn_lock);
13525 +               return;
13526 +       }
13527 +
13528 +       va_start(args, fmt);
13529 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
13530 +       va_end(args);
13531 +
13532 +       learn_buffer_len += len + 1;
13533 +
13534 +       spin_unlock(&gr_learn_lock);
13535 +       wake_up_interruptible(&learn_wait);
13536 +
13537 +       return;
13538 +}
13539 +
13540 +static int
13541 +open_learn(struct inode *inode, struct file *file)
13542 +{
13543 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
13544 +               return -EBUSY;
13545 +       if (file->f_mode & FMODE_READ) {
13546 +               down(&gr_learn_user_sem);
13547 +               if (learn_buffer == NULL)
13548 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
13549 +               if (learn_buffer_user == NULL)
13550 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
13551 +               if (learn_buffer == NULL)
13552 +                       return -ENOMEM;
13553 +               if (learn_buffer_user == NULL)
13554 +                       return -ENOMEM;
13555 +               learn_buffer_len = 0;
13556 +               learn_buffer_user_len = 0;
13557 +               gr_learn_attached = 1;
13558 +               up(&gr_learn_user_sem);
13559 +       }
13560 +       return 0;
13561 +}
13562 +
13563 +static int
13564 +close_learn(struct inode *inode, struct file *file)
13565 +{
13566 +       char *tmp;
13567 +
13568 +       if (file->f_mode & FMODE_READ) {
13569 +               down(&gr_learn_user_sem);
13570 +               if (learn_buffer != NULL) {
13571 +                       spin_lock(&gr_learn_lock);
13572 +                       tmp = learn_buffer;
13573 +                       learn_buffer = NULL;
13574 +                       spin_unlock(&gr_learn_lock);
13575 +                       vfree(tmp);
13576 +               }
13577 +               if (learn_buffer_user != NULL) {
13578 +                       vfree(learn_buffer_user);
13579 +                       learn_buffer_user = NULL;
13580 +               }
13581 +               learn_buffer_len = 0;
13582 +               learn_buffer_user_len = 0;
13583 +               gr_learn_attached = 0;
13584 +               up(&gr_learn_user_sem);
13585 +       }
13586 +
13587 +       return 0;
13588 +}
13589 +               
13590 +struct file_operations grsec_fops = {
13591 +       .read           = read_learn,
13592 +       .write          = write_grsec_handler,
13593 +       .open           = open_learn,
13594 +       .release        = close_learn,
13595 +       .poll           = poll_learn,
13596 +};
13597 diff -urNp linux-2.6.16.12/grsecurity/gracl_res.c linux-2.6.16.12/grsecurity/gracl_res.c
13598 --- linux-2.6.16.12/grsecurity/gracl_res.c      1969-12-31 19:00:00.000000000 -0500
13599 +++ linux-2.6.16.12/grsecurity/gracl_res.c      2006-05-01 20:17:33.000000000 -0400
13600 @@ -0,0 +1,42 @@
13601 +#include <linux/kernel.h>
13602 +#include <linux/sched.h>
13603 +#include <linux/gracl.h>
13604 +#include <linux/grinternal.h>
13605 +
13606 +static const char *restab_log[] = {
13607 +       [RLIMIT_CPU] = "RLIMIT_CPU",
13608 +       [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
13609 +       [RLIMIT_DATA] = "RLIMIT_DATA",
13610 +       [RLIMIT_STACK] = "RLIMIT_STACK",
13611 +       [RLIMIT_CORE] = "RLIMIT_CORE",
13612 +       [RLIMIT_RSS] = "RLIMIT_RSS",
13613 +       [RLIMIT_NPROC] = "RLIMIT_NPROC",
13614 +       [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
13615 +       [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
13616 +       [RLIMIT_AS] = "RLIMIT_AS",
13617 +       [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
13618 +       [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
13619 +};
13620 +
13621 +void
13622 +gr_log_resource(const struct task_struct *task,
13623 +               const int res, const unsigned long wanted, const int gt)
13624 +{
13625 +       if (res == RLIMIT_NPROC && 
13626 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
13627 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
13628 +               return;
13629 +       else if (res == RLIMIT_MEMLOCK &&
13630 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
13631 +               return;
13632 +
13633 +       preempt_disable();
13634 +
13635 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
13636 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
13637 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
13638 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
13639 +       preempt_enable_no_resched();
13640 +
13641 +       return;
13642 +}
13643 diff -urNp linux-2.6.16.12/grsecurity/gracl_segv.c linux-2.6.16.12/grsecurity/gracl_segv.c
13644 --- linux-2.6.16.12/grsecurity/gracl_segv.c     1969-12-31 19:00:00.000000000 -0500
13645 +++ linux-2.6.16.12/grsecurity/gracl_segv.c     2006-05-01 20:17:33.000000000 -0400
13646 @@ -0,0 +1,295 @@
13647 +#include <linux/kernel.h>
13648 +#include <linux/mm.h>
13649 +#include <asm/uaccess.h>
13650 +#include <asm/errno.h>
13651 +#include <asm/mman.h>
13652 +#include <net/sock.h>
13653 +#include <linux/file.h>
13654 +#include <linux/fs.h>
13655 +#include <linux/net.h>
13656 +#include <linux/in.h>
13657 +#include <linux/smp_lock.h>
13658 +#include <linux/slab.h>
13659 +#include <linux/types.h>
13660 +#include <linux/sched.h>
13661 +#include <linux/timer.h>
13662 +#include <linux/gracl.h>
13663 +#include <linux/grsecurity.h>
13664 +#include <linux/grinternal.h>
13665 +
13666 +static struct crash_uid *uid_set;
13667 +static unsigned short uid_used;
13668 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
13669 +extern rwlock_t gr_inode_lock;
13670 +extern struct acl_subject_label *
13671 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
13672 +                             struct acl_role_label *role);
13673 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
13674 +
13675 +int
13676 +gr_init_uidset(void)
13677 +{
13678 +       uid_set =
13679 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
13680 +       uid_used = 0;
13681 +
13682 +       return uid_set ? 1 : 0;
13683 +}
13684 +
13685 +void
13686 +gr_free_uidset(void)
13687 +{
13688 +       if (uid_set)
13689 +               kfree(uid_set);
13690 +
13691 +       return;
13692 +}
13693 +
13694 +int
13695 +gr_find_uid(const uid_t uid)
13696 +{
13697 +       struct crash_uid *tmp = uid_set;
13698 +       uid_t buid;
13699 +       int low = 0, high = uid_used - 1, mid;
13700 +
13701 +       while (high >= low) {
13702 +               mid = (low + high) >> 1;
13703 +               buid = tmp[mid].uid;
13704 +               if (buid == uid)
13705 +                       return mid;
13706 +               if (buid > uid)
13707 +                       high = mid - 1;
13708 +               if (buid < uid)
13709 +                       low = mid + 1;
13710 +       }
13711 +
13712 +       return -1;
13713 +}
13714 +
13715 +static __inline__ void
13716 +gr_insertsort(void)
13717 +{
13718 +       unsigned short i, j;
13719 +       struct crash_uid index;
13720 +
13721 +       for (i = 1; i < uid_used; i++) {
13722 +               index = uid_set[i];
13723 +               j = i;
13724 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
13725 +                       uid_set[j] = uid_set[j - 1];
13726 +                       j--;
13727 +               }
13728 +               uid_set[j] = index;
13729 +       }
13730 +
13731 +       return;
13732 +}
13733 +
13734 +static __inline__ void
13735 +gr_insert_uid(const uid_t uid, const unsigned long expires)
13736 +{
13737 +       int loc;
13738 +
13739 +       if (uid_used == GR_UIDTABLE_MAX)
13740 +               return;
13741 +
13742 +       loc = gr_find_uid(uid);
13743 +
13744 +       if (loc >= 0) {
13745 +               uid_set[loc].expires = expires;
13746 +               return;
13747 +       }
13748 +
13749 +       uid_set[uid_used].uid = uid;
13750 +       uid_set[uid_used].expires = expires;
13751 +       uid_used++;
13752 +
13753 +       gr_insertsort();
13754 +
13755 +       return;
13756 +}
13757 +
13758 +void
13759 +gr_remove_uid(const unsigned short loc)
13760 +{
13761 +       unsigned short i;
13762 +
13763 +       for (i = loc + 1; i < uid_used; i++)
13764 +               uid_set[i - 1] = uid_set[i];
13765 +
13766 +       uid_used--;
13767 +
13768 +       return;
13769 +}
13770 +
13771 +int
13772 +gr_check_crash_uid(const uid_t uid)
13773 +{
13774 +       int loc;
13775 +       int ret = 0;
13776 +
13777 +       if (unlikely(!gr_acl_is_enabled()))
13778 +               return 0;
13779 +
13780 +       spin_lock(&gr_uid_lock);
13781 +       loc = gr_find_uid(uid);
13782 +
13783 +       if (loc < 0)
13784 +               goto out_unlock;
13785 +
13786 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
13787 +               gr_remove_uid(loc);
13788 +       else
13789 +               ret = 1;
13790 +
13791 +out_unlock:
13792 +       spin_unlock(&gr_uid_lock);
13793 +       return ret;
13794 +}
13795 +
13796 +static __inline__ int
13797 +proc_is_setxid(const struct task_struct *task)
13798 +{
13799 +       if (task->uid != task->euid || task->uid != task->suid ||
13800 +           task->uid != task->fsuid)
13801 +               return 1;
13802 +       if (task->gid != task->egid || task->gid != task->sgid ||
13803 +           task->gid != task->fsgid)
13804 +               return 1;
13805 +
13806 +       return 0;
13807 +}
13808 +static __inline__ int
13809 +gr_fake_force_sig(int sig, struct task_struct *t)
13810 +{
13811 +       unsigned long int flags;
13812 +       int ret;
13813 +
13814 +       spin_lock_irqsave(&t->sighand->siglock, flags);
13815 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
13816 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
13817 +               sigdelset(&t->blocked, sig);
13818 +               recalc_sigpending_tsk(t);
13819 +       }
13820 +       ret = specific_send_sig_info(sig, (void*)1L, t);
13821 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
13822 +
13823 +       return ret;
13824 +}
13825 +
13826 +void
13827 +gr_handle_crash(struct task_struct *task, const int sig)
13828 +{
13829 +       struct acl_subject_label *curr;
13830 +       struct acl_subject_label *curr2;
13831 +       struct task_struct *tsk, *tsk2;
13832 +
13833 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
13834 +               return;
13835 +
13836 +       if (unlikely(!gr_acl_is_enabled()))
13837 +               return;
13838 +
13839 +       curr = task->acl;
13840 +
13841 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
13842 +               return;
13843 +
13844 +       if (time_before_eq(curr->expires, get_seconds())) {
13845 +               curr->expires = 0;
13846 +               curr->crashes = 0;
13847 +       }
13848 +
13849 +       curr->crashes++;
13850 +
13851 +       if (!curr->expires)
13852 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
13853 +
13854 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
13855 +           time_after(curr->expires, get_seconds())) {
13856 +               if (task->uid && proc_is_setxid(task)) {
13857 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
13858 +                       spin_lock(&gr_uid_lock);
13859 +                       gr_insert_uid(task->uid, curr->expires);
13860 +                       spin_unlock(&gr_uid_lock);
13861 +                       curr->expires = 0;
13862 +                       curr->crashes = 0;
13863 +                       read_lock(&tasklist_lock);
13864 +                       do_each_thread(tsk2, tsk) {
13865 +                               if (tsk != task && tsk->uid == task->uid)
13866 +                                       gr_fake_force_sig(SIGKILL, tsk);
13867 +                       } while_each_thread(tsk2, tsk);
13868 +                       read_unlock(&tasklist_lock);
13869 +               } else {
13870 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
13871 +                       read_lock(&tasklist_lock);
13872 +                       do_each_thread(tsk2, tsk) {
13873 +                               if (likely(tsk != task)) {
13874 +                                       curr2 = tsk->acl;
13875 +
13876 +                                       if (curr2->device == curr->device &&
13877 +                                           curr2->inode == curr->inode)
13878 +                                               gr_fake_force_sig(SIGKILL, tsk);
13879 +                               }
13880 +                       } while_each_thread(tsk2, tsk);
13881 +                       read_unlock(&tasklist_lock);
13882 +               }
13883 +       }
13884 +
13885 +       return;
13886 +}
13887 +
13888 +int
13889 +gr_check_crash_exec(const struct file *filp)
13890 +{
13891 +       struct acl_subject_label *curr;
13892 +
13893 +       if (unlikely(!gr_acl_is_enabled()))
13894 +               return 0;
13895 +
13896 +       read_lock(&gr_inode_lock);
13897 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
13898 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
13899 +                                    current->role);
13900 +       read_unlock(&gr_inode_lock);
13901 +
13902 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
13903 +           (!curr->crashes && !curr->expires))
13904 +               return 0;
13905 +
13906 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
13907 +           time_after(curr->expires, get_seconds()))
13908 +               return 1;
13909 +       else if (time_before_eq(curr->expires, get_seconds())) {
13910 +               curr->crashes = 0;
13911 +               curr->expires = 0;
13912 +       }
13913 +
13914 +       return 0;
13915 +}
13916 +
13917 +void
13918 +gr_handle_alertkill(struct task_struct *task)
13919 +{
13920 +       struct acl_subject_label *curracl;
13921 +       __u32 curr_ip;
13922 +       struct task_struct *p, *p2;
13923 +
13924 +       if (unlikely(!gr_acl_is_enabled()))
13925 +               return;
13926 +
13927 +       curracl = task->acl;
13928 +       curr_ip = task->signal->curr_ip;
13929 +
13930 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
13931 +               read_lock(&tasklist_lock);
13932 +               do_each_thread(p2, p) {
13933 +                       if (p->signal->curr_ip == curr_ip)
13934 +                               gr_fake_force_sig(SIGKILL, p);
13935 +               } while_each_thread(p2, p);
13936 +               read_unlock(&tasklist_lock);
13937 +       } else if (curracl->mode & GR_KILLPROC)
13938 +               gr_fake_force_sig(SIGKILL, task);
13939 +
13940 +       return;
13941 +}
13942 diff -urNp linux-2.6.16.12/grsecurity/gracl_shm.c linux-2.6.16.12/grsecurity/gracl_shm.c
13943 --- linux-2.6.16.12/grsecurity/gracl_shm.c      1969-12-31 19:00:00.000000000 -0500
13944 +++ linux-2.6.16.12/grsecurity/gracl_shm.c      2006-05-01 20:17:34.000000000 -0400
13945 @@ -0,0 +1,34 @@
13946 +#include <linux/kernel.h>
13947 +#include <linux/mm.h>
13948 +#include <linux/sched.h>
13949 +#include <linux/file.h>
13950 +#include <linux/ipc.h>
13951 +#include <linux/gracl.h>
13952 +#include <linux/grsecurity.h>
13953 +#include <linux/grinternal.h>
13954 +#include <linux/vs_pid.h>
13955 +
13956 +int
13957 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
13958 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
13959 +{
13960 +       struct task_struct *task;
13961 +
13962 +       if (!gr_acl_is_enabled())
13963 +               return 1;
13964 +
13965 +       task = find_task_by_pid(shm_cprid);
13966 +
13967 +       if (unlikely(!task))
13968 +               task = find_task_by_pid(shm_lapid);
13969 +
13970 +       if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
13971 +                             (task->pid == shm_lapid)) &&
13972 +                    (task->acl->mode & GR_PROTSHM) &&
13973 +                    (task->acl != current->acl))) {
13974 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
13975 +               return 0;
13976 +       }
13977 +
13978 +       return 1;
13979 +}
13980 diff -urNp linux-2.6.16.12/grsecurity/grsec_chdir.c linux-2.6.16.12/grsecurity/grsec_chdir.c
13981 --- linux-2.6.16.12/grsecurity/grsec_chdir.c    1969-12-31 19:00:00.000000000 -0500
13982 +++ linux-2.6.16.12/grsecurity/grsec_chdir.c    2006-05-01 20:17:34.000000000 -0400
13983 @@ -0,0 +1,19 @@
13984 +#include <linux/kernel.h>
13985 +#include <linux/sched.h>
13986 +#include <linux/fs.h>
13987 +#include <linux/file.h>
13988 +#include <linux/grsecurity.h>
13989 +#include <linux/grinternal.h>
13990 +
13991 +void
13992 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
13993 +{
13994 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
13995 +       if ((grsec_enable_chdir && grsec_enable_group &&
13996 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
13997 +                                             !grsec_enable_group)) {
13998 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
13999 +       }
14000 +#endif
14001 +       return;
14002 +}
14003 diff -urNp linux-2.6.16.12/grsecurity/grsec_chroot.c linux-2.6.16.12/grsecurity/grsec_chroot.c
14004 --- linux-2.6.16.12/grsecurity/grsec_chroot.c   1969-12-31 19:00:00.000000000 -0500
14005 +++ linux-2.6.16.12/grsecurity/grsec_chroot.c   2006-05-01 20:17:34.000000000 -0400
14006 @@ -0,0 +1,332 @@
14007 +#include <linux/kernel.h>
14008 +#include <linux/module.h>
14009 +#include <linux/sched.h>
14010 +#include <linux/file.h>
14011 +#include <linux/fs.h>
14012 +#include <linux/mount.h>
14013 +#include <linux/types.h>
14014 +#include <linux/grinternal.h>
14015 +
14016 +int
14017 +gr_handle_chroot_unix(const pid_t pid)
14018 +{
14019 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
14020 +       struct pid *spid = NULL;
14021 +
14022 +       if (unlikely(!grsec_enable_chroot_unix))
14023 +               return 1;
14024 +
14025 +       if (likely(!proc_is_chrooted(current)))
14026 +               return 1;
14027 +
14028 +       read_lock(&tasklist_lock);
14029 +
14030 +       spid = find_pid(PIDTYPE_PID, pid);
14031 +       if (spid) {
14032 +               struct task_struct *p;
14033 +               p = pid_task(&spid->pid_list, PIDTYPE_PID);
14034 +               task_lock(p);
14035 +               if (unlikely(!have_same_root(current, p))) {
14036 +                       task_unlock(p);
14037 +                       read_unlock(&tasklist_lock);
14038 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
14039 +                       return 0;
14040 +               }
14041 +               task_unlock(p);
14042 +       }
14043 +       read_unlock(&tasklist_lock);
14044 +#endif
14045 +       return 1;
14046 +}
14047 +
14048 +int
14049 +gr_handle_chroot_nice(void)
14050 +{
14051 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
14052 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
14053 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
14054 +               return -EPERM;
14055 +       }
14056 +#endif
14057 +       return 0;
14058 +}
14059 +
14060 +int
14061 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
14062 +{
14063 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
14064 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
14065 +                       && proc_is_chrooted(current)) {
14066 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
14067 +               return -EACCES;
14068 +       }
14069 +#endif
14070 +       return 0;
14071 +}
14072 +
14073 +int
14074 +gr_handle_chroot_rawio(const struct inode *inode)
14075 +{
14076 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14077 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
14078 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
14079 +               return 1;
14080 +#endif
14081 +       return 0;
14082 +}
14083 +
14084 +int
14085 +gr_pid_is_chrooted(struct task_struct *p)
14086 +{
14087 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
14088 +       if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !p)
14089 +               return 0;
14090 +
14091 +       task_lock(p);
14092 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
14093 +           !have_same_root(current, p)) {
14094 +               task_unlock(p);
14095 +               return 1;
14096 +       }
14097 +       task_unlock(p);
14098 +#endif
14099 +       return 0;
14100 +}
14101 +
14102 +EXPORT_SYMBOL(gr_pid_is_chrooted);
14103 +
14104 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
14105 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
14106 +{
14107 +       struct dentry *dentry = (struct dentry *)u_dentry;
14108 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
14109 +       struct dentry *realroot;
14110 +       struct vfsmount *realrootmnt;
14111 +       struct dentry *currentroot;
14112 +       struct vfsmount *currentmnt;
14113 +       int ret = 1;
14114 +
14115 +       read_lock(&child_reaper->fs->lock);
14116 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
14117 +       realroot = dget(child_reaper->fs->root);
14118 +       read_unlock(&child_reaper->fs->lock);
14119 +
14120 +       read_lock(&current->fs->lock);
14121 +       currentmnt = mntget(current->fs->rootmnt);
14122 +       currentroot = dget(current->fs->root);
14123 +       read_unlock(&current->fs->lock);
14124 +
14125 +       spin_lock(&dcache_lock);
14126 +       for (;;) {
14127 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
14128 +                    || (dentry == currentroot && mnt == currentmnt)))
14129 +                       break;
14130 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
14131 +                       if (mnt->mnt_parent == mnt)
14132 +                               break;
14133 +                       dentry = mnt->mnt_mountpoint;
14134 +                       mnt = mnt->mnt_parent;
14135 +                       continue;
14136 +               }
14137 +               dentry = dentry->d_parent;
14138 +       }
14139 +       spin_unlock(&dcache_lock);
14140 +
14141 +       dput(currentroot);
14142 +       mntput(currentmnt);
14143 +
14144 +       /* access is outside of chroot */
14145 +       if (dentry == realroot && mnt == realrootmnt)
14146 +               ret = 0;
14147 +
14148 +       dput(realroot);
14149 +       mntput(realrootmnt);
14150 +       return ret;
14151 +}
14152 +#endif
14153 +
14154 +int
14155 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
14156 +{
14157 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
14158 +       if (!grsec_enable_chroot_fchdir)
14159 +               return 1;
14160 +
14161 +       if (!proc_is_chrooted(current))
14162 +               return 1;
14163 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
14164 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
14165 +               return 0;
14166 +       }
14167 +#endif
14168 +       return 1;
14169 +}
14170 +
14171 +int
14172 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
14173 +               const time_t shm_createtime)
14174 +{
14175 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
14176 +       struct pid *pid = NULL;
14177 +       time_t starttime;
14178 +
14179 +       if (unlikely(!grsec_enable_chroot_shmat))
14180 +               return 1;
14181 +
14182 +       if (likely(!proc_is_chrooted(current)))
14183 +               return 1;
14184 +
14185 +       read_lock(&tasklist_lock);
14186 +
14187 +       pid = find_pid(PIDTYPE_PID, shm_cprid);
14188 +       if (pid) {
14189 +               struct task_struct *p;
14190 +               p = pid_task(&pid->pid_list, PIDTYPE_PID);
14191 +               task_lock(p);
14192 +               starttime = p->start_time.tv_sec;
14193 +               if (unlikely(!have_same_root(current, p) &&
14194 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
14195 +                       task_unlock(p);
14196 +                       read_unlock(&tasklist_lock);
14197 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
14198 +                       return 0;
14199 +               }
14200 +               task_unlock(p);
14201 +       } else {
14202 +               pid = find_pid(PIDTYPE_PID, shm_lapid);
14203 +               if (pid) {
14204 +                       struct task_struct *p;
14205 +                       p = pid_task(&pid->pid_list, PIDTYPE_PID);
14206 +                       task_lock(p);
14207 +                       if (unlikely(!have_same_root(current, p))) {
14208 +                               task_unlock(p);
14209 +                               read_unlock(&tasklist_lock);
14210 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
14211 +                               return 0;
14212 +                       }
14213 +                       task_unlock(p);
14214 +               }
14215 +       }
14216 +
14217 +       read_unlock(&tasklist_lock);
14218 +#endif
14219 +       return 1;
14220 +}
14221 +
14222 +void
14223 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
14224 +{
14225 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
14226 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
14227 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
14228 +#endif
14229 +       return;
14230 +}
14231 +
14232 +int
14233 +gr_handle_chroot_mknod(const struct dentry *dentry,
14234 +                      const struct vfsmount *mnt, const int mode)
14235 +{
14236 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
14237 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
14238 +           proc_is_chrooted(current)) {
14239 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
14240 +               return -EPERM;
14241 +       }
14242 +#endif
14243 +       return 0;
14244 +}
14245 +
14246 +int
14247 +gr_handle_chroot_mount(const struct dentry *dentry,
14248 +                      const struct vfsmount *mnt, const char *dev_name)
14249 +{
14250 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
14251 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
14252 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
14253 +               return -EPERM;
14254 +       }
14255 +#endif
14256 +       return 0;
14257 +}
14258 +
14259 +int
14260 +gr_handle_chroot_pivot(void)
14261 +{
14262 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
14263 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
14264 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
14265 +               return -EPERM;
14266 +       }
14267 +#endif
14268 +       return 0;
14269 +}
14270 +
14271 +int
14272 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
14273 +{
14274 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
14275 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
14276 +           !gr_is_outside_chroot(dentry, mnt)) {
14277 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
14278 +               return -EPERM;
14279 +       }
14280 +#endif
14281 +       return 0;
14282 +}
14283 +
14284 +void
14285 +gr_handle_chroot_caps(struct task_struct *task)
14286 +{
14287 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14288 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
14289 +               task->cap_permitted =
14290 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
14291 +               task->cap_inheritable =
14292 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
14293 +               task->cap_effective =
14294 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
14295 +       }
14296 +#endif
14297 +       return;
14298 +}
14299 +
14300 +int
14301 +gr_handle_chroot_sysctl(const int op)
14302 +{
14303 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
14304 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
14305 +           && (op & 002))
14306 +               return -EACCES;
14307 +#endif
14308 +       return 0;
14309 +}
14310 +
14311 +void
14312 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
14313 +{
14314 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
14315 +       if (grsec_enable_chroot_chdir)
14316 +               set_fs_pwd(current->fs, mnt, dentry);
14317 +#endif
14318 +       return;
14319 +}
14320 +
14321 +int
14322 +gr_handle_chroot_chmod(const struct dentry *dentry,
14323 +                      const struct vfsmount *mnt, const int mode)
14324 +{
14325 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
14326 +       if (grsec_enable_chroot_chmod &&
14327 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
14328 +           proc_is_chrooted(current)) {
14329 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
14330 +               return -EPERM;
14331 +       }
14332 +#endif
14333 +       return 0;
14334 +}
14335 +
14336 +#ifdef CONFIG_SECURITY
14337 +EXPORT_SYMBOL(gr_handle_chroot_caps);
14338 +#endif
14339 diff -urNp linux-2.6.16.12/grsecurity/grsec_disabled.c linux-2.6.16.12/grsecurity/grsec_disabled.c
14340 --- linux-2.6.16.12/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
14341 +++ linux-2.6.16.12/grsecurity/grsec_disabled.c 2006-05-01 20:17:34.000000000 -0400
14342 @@ -0,0 +1,418 @@
14343 +#include <linux/kernel.h>
14344 +#include <linux/module.h>
14345 +#include <linux/config.h>
14346 +#include <linux/sched.h>
14347 +#include <linux/file.h>
14348 +#include <linux/fs.h>
14349 +#include <linux/kdev_t.h>
14350 +#include <linux/net.h>
14351 +#include <linux/in.h>
14352 +#include <linux/ip.h>
14353 +#include <linux/skbuff.h>
14354 +#include <linux/sysctl.h>
14355 +
14356 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14357 +void
14358 +pax_set_initial_flags(struct linux_binprm *bprm)
14359 +{
14360 +       return;
14361 +}
14362 +#endif
14363 +
14364 +#ifdef CONFIG_SYSCTL
14365 +__u32
14366 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
14367 +{
14368 +       return mode;
14369 +}
14370 +#endif
14371 +
14372 +int
14373 +gr_acl_is_enabled(void)
14374 +{
14375 +       return 0;
14376 +}
14377 +
14378 +int
14379 +gr_handle_rawio(const struct inode *inode)
14380 +{
14381 +       return 0;
14382 +}
14383 +
14384 +void
14385 +gr_acl_handle_psacct(struct task_struct *task, const long code)
14386 +{
14387 +       return;
14388 +}
14389 +
14390 +int
14391 +gr_handle_ptrace(struct task_struct *task, const long request)
14392 +{
14393 +       return 0;
14394 +}
14395 +
14396 +int
14397 +gr_handle_proc_ptrace(struct task_struct *task)
14398 +{
14399 +       return 0;
14400 +}
14401 +
14402 +void
14403 +gr_learn_resource(const struct task_struct *task,
14404 +                 const int res, const unsigned long wanted, const int gt)
14405 +{
14406 +       return;
14407 +}
14408 +
14409 +int
14410 +gr_set_acls(const int type)
14411 +{
14412 +       return 0;
14413 +}
14414 +
14415 +int
14416 +gr_check_hidden_task(const struct task_struct *tsk)
14417 +{
14418 +       return 0;
14419 +}
14420 +
14421 +int
14422 +gr_check_protected_task(const struct task_struct *task)
14423 +{
14424 +       return 0;
14425 +}
14426 +
14427 +void
14428 +gr_copy_label(struct task_struct *tsk)
14429 +{
14430 +       return;
14431 +}
14432 +
14433 +void
14434 +gr_set_pax_flags(struct task_struct *task)
14435 +{
14436 +       return;
14437 +}
14438 +
14439 +int
14440 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
14441 +{
14442 +       return 0;
14443 +}
14444 +
14445 +void
14446 +gr_handle_delete(const ino_t ino, const dev_t dev)
14447 +{
14448 +       return;
14449 +}
14450 +
14451 +void
14452 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
14453 +{
14454 +       return;
14455 +}
14456 +
14457 +void
14458 +gr_handle_crash(struct task_struct *task, const int sig)
14459 +{
14460 +       return;
14461 +}
14462 +
14463 +int
14464 +gr_check_crash_exec(const struct file *filp)
14465 +{
14466 +       return 0;
14467 +}
14468 +
14469 +int
14470 +gr_check_crash_uid(const uid_t uid)
14471 +{
14472 +       return 0;
14473 +}
14474 +
14475 +void
14476 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
14477 +                struct dentry *old_dentry,
14478 +                struct dentry *new_dentry,
14479 +                struct vfsmount *mnt, const __u8 replace)
14480 +{
14481 +       return;
14482 +}
14483 +
14484 +int
14485 +gr_search_socket(const int family, const int type, const int protocol)
14486 +{
14487 +       return 1;
14488 +}
14489 +
14490 +int
14491 +gr_search_connectbind(const int mode, const struct socket *sock,
14492 +                     const struct sockaddr_in *addr)
14493 +{
14494 +       return 1;
14495 +}
14496 +
14497 +int
14498 +gr_task_is_capable(struct task_struct *task, const int cap)
14499 +{
14500 +       return 1;
14501 +}
14502 +
14503 +int
14504 +gr_is_capable_nolog(const int cap)
14505 +{
14506 +       return 1;
14507 +}
14508 +
14509 +void
14510 +gr_handle_alertkill(struct task_struct *task)
14511 +{
14512 +       return;
14513 +}
14514 +
14515 +__u32
14516 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
14517 +{
14518 +       return 1;
14519 +}
14520 +
14521 +__u32
14522 +gr_acl_handle_hidden_file(const struct dentry * dentry,
14523 +                         const struct vfsmount * mnt)
14524 +{
14525 +       return 1;
14526 +}
14527 +
14528 +__u32
14529 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
14530 +                  const int fmode)
14531 +{
14532 +       return 1;
14533 +}
14534 +
14535 +__u32
14536 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
14537 +{
14538 +       return 1;
14539 +}
14540 +
14541 +__u32
14542 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
14543 +{
14544 +       return 1;
14545 +}
14546 +
14547 +int
14548 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
14549 +                  unsigned int *vm_flags)
14550 +{
14551 +       return 1;
14552 +}
14553 +
14554 +__u32
14555 +gr_acl_handle_truncate(const struct dentry * dentry,
14556 +                      const struct vfsmount * mnt)
14557 +{
14558 +       return 1;
14559 +}
14560 +
14561 +__u32
14562 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
14563 +{
14564 +       return 1;
14565 +}
14566 +
14567 +__u32
14568 +gr_acl_handle_access(const struct dentry * dentry,
14569 +                    const struct vfsmount * mnt, const int fmode)
14570 +{
14571 +       return 1;
14572 +}
14573 +
14574 +__u32
14575 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
14576 +                    mode_t mode)
14577 +{
14578 +       return 1;
14579 +}
14580 +
14581 +__u32
14582 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
14583 +                   mode_t mode)
14584 +{
14585 +       return 1;
14586 +}
14587 +
14588 +__u32
14589 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
14590 +{
14591 +       return 1;
14592 +}
14593 +
14594 +void
14595 +grsecurity_init(void)
14596 +{
14597 +       return;
14598 +}
14599 +
14600 +__u32
14601 +gr_acl_handle_mknod(const struct dentry * new_dentry,
14602 +                   const struct dentry * parent_dentry,
14603 +                   const struct vfsmount * parent_mnt,
14604 +                   const int mode)
14605 +{
14606 +       return 1;
14607 +}
14608 +
14609 +__u32
14610 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
14611 +                   const struct dentry * parent_dentry,
14612 +                   const struct vfsmount * parent_mnt)
14613 +{
14614 +       return 1;
14615 +}
14616 +
14617 +__u32
14618 +gr_acl_handle_symlink(const struct dentry * new_dentry,
14619 +                     const struct dentry * parent_dentry,
14620 +                     const struct vfsmount * parent_mnt, const char *from)
14621 +{
14622 +       return 1;
14623 +}
14624 +
14625 +__u32
14626 +gr_acl_handle_link(const struct dentry * new_dentry,
14627 +                  const struct dentry * parent_dentry,
14628 +                  const struct vfsmount * parent_mnt,
14629 +                  const struct dentry * old_dentry,
14630 +                  const struct vfsmount * old_mnt, const char *to)
14631 +{
14632 +       return 1;
14633 +}
14634 +
14635 +int
14636 +gr_acl_handle_rename(const struct dentry *new_dentry,
14637 +                    const struct dentry *parent_dentry,
14638 +                    const struct vfsmount *parent_mnt,
14639 +                    const struct dentry *old_dentry,
14640 +                    const struct inode *old_parent_inode,
14641 +                    const struct vfsmount *old_mnt, const char *newname)
14642 +{
14643 +       return 0;
14644 +}
14645 +
14646 +int
14647 +gr_acl_handle_filldir(const struct file *file, const char *name,
14648 +                     const int namelen, const ino_t ino)
14649 +{
14650 +       return 1;
14651 +}
14652 +
14653 +int
14654 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
14655 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
14656 +{
14657 +       return 1;
14658 +}
14659 +
14660 +int
14661 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
14662 +{
14663 +       return 1;
14664 +}
14665 +
14666 +int
14667 +gr_search_accept(const struct socket *sock)
14668 +{
14669 +       return 1;
14670 +}
14671 +
14672 +int
14673 +gr_search_listen(const struct socket *sock)
14674 +{
14675 +       return 1;
14676 +}
14677 +
14678 +int
14679 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
14680 +{
14681 +       return 1;
14682 +}
14683 +
14684 +__u32
14685 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
14686 +{
14687 +       return 1;
14688 +}
14689 +
14690 +__u32
14691 +gr_acl_handle_creat(const struct dentry * dentry,
14692 +                   const struct dentry * p_dentry,
14693 +                   const struct vfsmount * p_mnt, const int fmode,
14694 +                   const int imode)
14695 +{
14696 +       return 1;
14697 +}
14698 +
14699 +void
14700 +gr_acl_handle_exit(void)
14701 +{
14702 +       return;
14703 +}
14704 +
14705 +int
14706 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
14707 +{
14708 +       return 1;
14709 +}
14710 +
14711 +void
14712 +gr_set_role_label(const uid_t uid, const gid_t gid)
14713 +{
14714 +       return;
14715 +}
14716 +
14717 +int
14718 +gr_acl_handle_procpidmem(const struct task_struct *task)
14719 +{
14720 +       return 0;
14721 +}
14722 +
14723 +int
14724 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
14725 +{
14726 +       return 1;
14727 +}
14728 +
14729 +int
14730 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
14731 +{
14732 +       return 1;
14733 +}
14734 +
14735 +void
14736 +gr_set_kernel_label(struct task_struct *task)
14737 +{
14738 +       return;
14739 +}
14740 +
14741 +int
14742 +gr_check_user_change(int real, int effective, int fs)
14743 +{
14744 +       return 0;
14745 +}
14746 +
14747 +int
14748 +gr_check_group_change(int real, int effective, int fs)
14749 +{
14750 +       return 0;
14751 +}
14752 +
14753 +
14754 +EXPORT_SYMBOL(gr_task_is_capable);
14755 +EXPORT_SYMBOL(gr_learn_resource);
14756 +EXPORT_SYMBOL(gr_set_kernel_label);
14757 +#ifdef CONFIG_SECURITY
14758 +EXPORT_SYMBOL(gr_check_user_change);
14759 +EXPORT_SYMBOL(gr_check_group_change);
14760 +#endif
14761 diff -urNp linux-2.6.16.12/grsecurity/grsec_exec.c linux-2.6.16.12/grsecurity/grsec_exec.c
14762 --- linux-2.6.16.12/grsecurity/grsec_exec.c     1969-12-31 19:00:00.000000000 -0500
14763 +++ linux-2.6.16.12/grsecurity/grsec_exec.c     2006-05-01 20:17:34.000000000 -0400
14764 @@ -0,0 +1,88 @@
14765 +#include <linux/kernel.h>
14766 +#include <linux/sched.h>
14767 +#include <linux/file.h>
14768 +#include <linux/binfmts.h>
14769 +#include <linux/smp_lock.h>
14770 +#include <linux/fs.h>
14771 +#include <linux/types.h>
14772 +#include <linux/grdefs.h>
14773 +#include <linux/grinternal.h>
14774 +#include <linux/capability.h>
14775 +
14776 +#include <asm/uaccess.h>
14777 +
14778 +#ifdef CONFIG_GRKERNSEC_EXECLOG
14779 +static char gr_exec_arg_buf[132];
14780 +static DECLARE_MUTEX(gr_exec_arg_sem);
14781 +#endif
14782 +
14783 +int
14784 +gr_handle_nproc(void)
14785 +{
14786 +#ifdef CONFIG_GRKERNSEC_EXECVE
14787 +       if (grsec_enable_execve && current->user &&
14788 +           (atomic_read(&current->user->processes) >
14789 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
14790 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
14791 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
14792 +               return -EAGAIN;
14793 +       }
14794 +#endif
14795 +       return 0;
14796 +}
14797 +
14798 +void
14799 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
14800 +{
14801 +#ifdef CONFIG_GRKERNSEC_EXECLOG
14802 +       char *grarg = gr_exec_arg_buf;
14803 +       unsigned int i, x, execlen = 0;
14804 +       char c;
14805 +
14806 +       if (!((grsec_enable_execlog && grsec_enable_group &&
14807 +              in_group_p(grsec_audit_gid))
14808 +             || (grsec_enable_execlog && !grsec_enable_group)))
14809 +               return;
14810 +
14811 +       down(&gr_exec_arg_sem);
14812 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
14813 +
14814 +       if (unlikely(argv == NULL))
14815 +               goto log;
14816 +
14817 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
14818 +               const char __user *p;
14819 +               unsigned int len;
14820 +
14821 +               if (copy_from_user(&p, argv + i, sizeof(p)))
14822 +                       goto log;
14823 +               if (!p)
14824 +                       goto log;
14825 +               len = strnlen_user(p, 128 - execlen);
14826 +               if (len > 128 - execlen)
14827 +                       len = 128 - execlen;
14828 +               else if (len > 0)
14829 +                       len--;
14830 +               if (copy_from_user(grarg + execlen, p, len))
14831 +                       goto log;
14832 +
14833 +               /* rewrite unprintable characters */
14834 +               for (x = 0; x < len; x++) {
14835 +                       c = *(grarg + execlen + x);
14836 +                       if (c < 32 || c > 126)
14837 +                               *(grarg + execlen + x) = ' ';
14838 +               }
14839 +
14840 +               execlen += len;
14841 +               *(grarg + execlen) = ' ';
14842 +               *(grarg + execlen + 1) = '\0';
14843 +               execlen++;
14844 +       }
14845 +
14846 +      log:
14847 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
14848 +                       bprm->file->f_vfsmnt, grarg);
14849 +       up(&gr_exec_arg_sem);
14850 +#endif
14851 +       return;
14852 +}
14853 diff -urNp linux-2.6.16.12/grsecurity/grsec_fifo.c linux-2.6.16.12/grsecurity/grsec_fifo.c
14854 --- linux-2.6.16.12/grsecurity/grsec_fifo.c     1969-12-31 19:00:00.000000000 -0500
14855 +++ linux-2.6.16.12/grsecurity/grsec_fifo.c     2006-05-01 20:17:34.000000000 -0400
14856 @@ -0,0 +1,22 @@
14857 +#include <linux/kernel.h>
14858 +#include <linux/sched.h>
14859 +#include <linux/fs.h>
14860 +#include <linux/file.h>
14861 +#include <linux/grinternal.h>
14862 +
14863 +int
14864 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
14865 +              const struct dentry *dir, const int flag, const int acc_mode)
14866 +{
14867 +#ifdef CONFIG_GRKERNSEC_FIFO
14868 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
14869 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
14870 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
14871 +           (current->fsuid != dentry->d_inode->i_uid)) {
14872 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
14873 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
14874 +               return -EACCES;
14875 +       }
14876 +#endif
14877 +       return 0;
14878 +}
14879 diff -urNp linux-2.6.16.12/grsecurity/grsec_fork.c linux-2.6.16.12/grsecurity/grsec_fork.c
14880 --- linux-2.6.16.12/grsecurity/grsec_fork.c     1969-12-31 19:00:00.000000000 -0500
14881 +++ linux-2.6.16.12/grsecurity/grsec_fork.c     2006-05-01 20:17:34.000000000 -0400
14882 @@ -0,0 +1,14 @@
14883 +#include <linux/kernel.h>
14884 +#include <linux/sched.h>
14885 +#include <linux/grsecurity.h>
14886 +#include <linux/grinternal.h>
14887 +
14888 +void
14889 +gr_log_forkfail(const int retval)
14890 +{
14891 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
14892 +       if (grsec_enable_forkfail)
14893 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
14894 +#endif
14895 +       return;
14896 +}
14897 diff -urNp linux-2.6.16.12/grsecurity/grsec_init.c linux-2.6.16.12/grsecurity/grsec_init.c
14898 --- linux-2.6.16.12/grsecurity/grsec_init.c     1969-12-31 19:00:00.000000000 -0500
14899 +++ linux-2.6.16.12/grsecurity/grsec_init.c     2006-05-01 20:17:34.000000000 -0400
14900 @@ -0,0 +1,232 @@
14901 +#include <linux/kernel.h>
14902 +#include <linux/sched.h>
14903 +#include <linux/mm.h>
14904 +#include <linux/smp_lock.h>
14905 +#include <linux/gracl.h>
14906 +#include <linux/slab.h>
14907 +#include <linux/vmalloc.h>
14908 +#include <linux/percpu.h>
14909 +
14910 +int grsec_enable_shm;
14911 +int grsec_enable_link;
14912 +int grsec_enable_dmesg;
14913 +int grsec_enable_fifo;
14914 +int grsec_enable_execve;
14915 +int grsec_enable_execlog;
14916 +int grsec_enable_signal;
14917 +int grsec_enable_forkfail;
14918 +int grsec_enable_time;
14919 +int grsec_enable_audit_textrel;
14920 +int grsec_enable_group;
14921 +int grsec_audit_gid;
14922 +int grsec_enable_chdir;
14923 +int grsec_enable_audit_ipc;
14924 +int grsec_enable_mount;
14925 +int grsec_enable_chroot_findtask;
14926 +int grsec_enable_chroot_mount;
14927 +int grsec_enable_chroot_shmat;
14928 +int grsec_enable_chroot_fchdir;
14929 +int grsec_enable_chroot_double;
14930 +int grsec_enable_chroot_pivot;
14931 +int grsec_enable_chroot_chdir;
14932 +int grsec_enable_chroot_chmod;
14933 +int grsec_enable_chroot_mknod;
14934 +int grsec_enable_chroot_nice;
14935 +int grsec_enable_chroot_execlog;
14936 +int grsec_enable_chroot_caps;
14937 +int grsec_enable_chroot_sysctl;
14938 +int grsec_enable_chroot_unix;
14939 +int grsec_enable_tpe;
14940 +int grsec_tpe_gid;
14941 +int grsec_enable_tpe_all;
14942 +int grsec_enable_randpid;
14943 +int grsec_enable_socket_all;
14944 +int grsec_socket_all_gid;
14945 +int grsec_enable_socket_client;
14946 +int grsec_socket_client_gid;
14947 +int grsec_enable_socket_server;
14948 +int grsec_socket_server_gid;
14949 +int grsec_lock;
14950 +
14951 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
14952 +unsigned long grsec_alert_wtime = 0;
14953 +unsigned long grsec_alert_fyet = 0;
14954 +
14955 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
14956 +
14957 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
14958 +
14959 +char *gr_shared_page[4];
14960 +
14961 +char *gr_alert_log_fmt;
14962 +char *gr_audit_log_fmt;
14963 +char *gr_alert_log_buf;
14964 +char *gr_audit_log_buf;
14965 +
14966 +extern struct gr_arg *gr_usermode;
14967 +extern unsigned char *gr_system_salt;
14968 +extern unsigned char *gr_system_sum;
14969 +
14970 +void
14971 +grsecurity_init(void)
14972 +{
14973 +       int j;
14974 +       /* create the per-cpu shared pages */
14975 +
14976 +       preempt_disable();
14977 +       for (j = 0; j < 4; j++) {
14978 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
14979 +               if (gr_shared_page[j] == NULL) {
14980 +                       panic("Unable to allocate grsecurity shared page");
14981 +                       return;
14982 +               }
14983 +       }
14984 +       preempt_enable();
14985 +
14986 +       /* allocate log buffers */
14987 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
14988 +       if (!gr_alert_log_fmt) {
14989 +               panic("Unable to allocate grsecurity alert log format buffer");
14990 +               return;
14991 +       }
14992 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
14993 +       if (!gr_audit_log_fmt) {
14994 +               panic("Unable to allocate grsecurity audit log format buffer");
14995 +               return;
14996 +       }
14997 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
14998 +       if (!gr_alert_log_buf) {
14999 +               panic("Unable to allocate grsecurity alert log buffer");
15000 +               return;
15001 +       }
15002 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
15003 +       if (!gr_audit_log_buf) {
15004 +               panic("Unable to allocate grsecurity audit log buffer");
15005 +               return;
15006 +       }
15007 +
15008 +       /* allocate memory for authentication structure */
15009 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
15010 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
15011 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
15012 +
15013 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
15014 +               panic("Unable to allocate grsecurity authentication structure");
15015 +               return;
15016 +       }
15017 +
15018 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
15019 +#ifndef CONFIG_GRKERNSEC_SYSCTL
15020 +       grsec_lock = 1;
15021 +#endif
15022 +#ifdef CONFIG_GRKERNSEC_SHM
15023 +       grsec_enable_shm = 1;
15024 +#endif
15025 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
15026 +       grsec_enable_audit_textrel = 1;
15027 +#endif
15028 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
15029 +       grsec_enable_group = 1;
15030 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
15031 +#endif
15032 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
15033 +       grsec_enable_chdir = 1;
15034 +#endif
15035 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15036 +       grsec_enable_audit_ipc = 1;
15037 +#endif
15038 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15039 +       grsec_enable_mount = 1;
15040 +#endif
15041 +#ifdef CONFIG_GRKERNSEC_LINK
15042 +       grsec_enable_link = 1;
15043 +#endif
15044 +#ifdef CONFIG_GRKERNSEC_DMESG
15045 +       grsec_enable_dmesg = 1;
15046 +#endif
15047 +#ifdef CONFIG_GRKERNSEC_FIFO
15048 +       grsec_enable_fifo = 1;
15049 +#endif
15050 +#ifdef CONFIG_GRKERNSEC_EXECVE
15051 +       grsec_enable_execve = 1;
15052 +#endif
15053 +#ifdef CONFIG_GRKERNSEC_EXECLOG
15054 +       grsec_enable_execlog = 1;
15055 +#endif
15056 +#ifdef CONFIG_GRKERNSEC_SIGNAL
15057 +       grsec_enable_signal = 1;
15058 +#endif
15059 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
15060 +       grsec_enable_forkfail = 1;
15061 +#endif
15062 +#ifdef CONFIG_GRKERNSEC_TIME
15063 +       grsec_enable_time = 1;
15064 +#endif
15065 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
15066 +       grsec_enable_chroot_findtask = 1;
15067 +#endif
15068 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
15069 +       grsec_enable_chroot_unix = 1;
15070 +#endif
15071 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
15072 +       grsec_enable_chroot_mount = 1;
15073 +#endif
15074 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
15075 +       grsec_enable_chroot_fchdir = 1;
15076 +#endif
15077 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
15078 +       grsec_enable_chroot_shmat = 1;
15079 +#endif
15080 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
15081 +       grsec_enable_chroot_double = 1;
15082 +#endif
15083 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
15084 +       grsec_enable_chroot_pivot = 1;
15085 +#endif
15086 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
15087 +       grsec_enable_chroot_chdir = 1;
15088 +#endif
15089 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
15090 +       grsec_enable_chroot_chmod = 1;
15091 +#endif
15092 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
15093 +       grsec_enable_chroot_mknod = 1;
15094 +#endif
15095 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
15096 +       grsec_enable_chroot_nice = 1;
15097 +#endif
15098 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
15099 +       grsec_enable_chroot_execlog = 1;
15100 +#endif
15101 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
15102 +       grsec_enable_chroot_caps = 1;
15103 +#endif
15104 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
15105 +       grsec_enable_chroot_sysctl = 1;
15106 +#endif
15107 +#ifdef CONFIG_GRKERNSEC_TPE
15108 +       grsec_enable_tpe = 1;
15109 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
15110 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
15111 +       grsec_enable_tpe_all = 1;
15112 +#endif
15113 +#endif
15114 +#ifdef CONFIG_GRKERNSEC_RANDPID
15115 +       grsec_enable_randpid = 1;
15116 +#endif
15117 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
15118 +       grsec_enable_socket_all = 1;
15119 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
15120 +#endif
15121 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
15122 +       grsec_enable_socket_client = 1;
15123 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
15124 +#endif
15125 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
15126 +       grsec_enable_socket_server = 1;
15127 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
15128 +#endif
15129 +#endif
15130 +
15131 +       return;
15132 +}
15133 diff -urNp linux-2.6.16.12/grsecurity/grsec_ipc.c linux-2.6.16.12/grsecurity/grsec_ipc.c
15134 --- linux-2.6.16.12/grsecurity/grsec_ipc.c      1969-12-31 19:00:00.000000000 -0500
15135 +++ linux-2.6.16.12/grsecurity/grsec_ipc.c      2006-05-01 20:17:34.000000000 -0400
15136 @@ -0,0 +1,81 @@
15137 +#include <linux/kernel.h>
15138 +#include <linux/sched.h>
15139 +#include <linux/types.h>
15140 +#include <linux/ipc.h>
15141 +#include <linux/grsecurity.h>
15142 +#include <linux/grinternal.h>
15143 +
15144 +void
15145 +gr_log_msgget(const int ret, const int msgflg)
15146 +{
15147 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15148 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15149 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15150 +                                         !grsec_enable_group)) && (ret >= 0)
15151 +           && (msgflg & IPC_CREAT))
15152 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
15153 +#endif
15154 +       return;
15155 +}
15156 +
15157 +void
15158 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
15159 +{
15160 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15161 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15162 +            grsec_enable_audit_ipc) ||
15163 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15164 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
15165 +#endif
15166 +       return;
15167 +}
15168 +
15169 +void
15170 +gr_log_semget(const int err, const int semflg)
15171 +{
15172 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15173 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15174 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15175 +                                         !grsec_enable_group)) && (err >= 0)
15176 +           && (semflg & IPC_CREAT))
15177 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
15178 +#endif
15179 +       return;
15180 +}
15181 +
15182 +void
15183 +gr_log_semrm(const uid_t uid, const uid_t cuid)
15184 +{
15185 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15186 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15187 +            grsec_enable_audit_ipc) ||
15188 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15189 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
15190 +#endif
15191 +       return;
15192 +}
15193 +
15194 +void
15195 +gr_log_shmget(const int err, const int shmflg, const size_t size)
15196 +{
15197 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15198 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15199 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15200 +                                         !grsec_enable_group)) && (err >= 0)
15201 +           && (shmflg & IPC_CREAT))
15202 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
15203 +#endif
15204 +       return;
15205 +}
15206 +
15207 +void
15208 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
15209 +{
15210 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15211 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15212 +            grsec_enable_audit_ipc) ||
15213 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15214 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
15215 +#endif
15216 +       return;
15217 +}
15218 diff -urNp linux-2.6.16.12/grsecurity/grsec_link.c linux-2.6.16.12/grsecurity/grsec_link.c
15219 --- linux-2.6.16.12/grsecurity/grsec_link.c     1969-12-31 19:00:00.000000000 -0500
15220 +++ linux-2.6.16.12/grsecurity/grsec_link.c     2006-05-01 20:17:34.000000000 -0400
15221 @@ -0,0 +1,39 @@
15222 +#include <linux/kernel.h>
15223 +#include <linux/sched.h>
15224 +#include <linux/fs.h>
15225 +#include <linux/file.h>
15226 +#include <linux/grinternal.h>
15227 +
15228 +int
15229 +gr_handle_follow_link(const struct inode *parent,
15230 +                     const struct inode *inode,
15231 +                     const struct dentry *dentry, const struct vfsmount *mnt)
15232 +{
15233 +#ifdef CONFIG_GRKERNSEC_LINK
15234 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
15235 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
15236 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
15237 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
15238 +               return -EACCES;
15239 +       }
15240 +#endif
15241 +       return 0;
15242 +}
15243 +
15244 +int
15245 +gr_handle_hardlink(const struct dentry *dentry,
15246 +                  const struct vfsmount *mnt,
15247 +                  struct inode *inode, const int mode, const char *to)
15248 +{
15249 +#ifdef CONFIG_GRKERNSEC_LINK
15250 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
15251 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
15252 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
15253 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
15254 +           !capable(CAP_FOWNER) && current->uid) {
15255 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
15256 +               return -EPERM;
15257 +       }
15258 +#endif
15259 +       return 0;
15260 +}
15261 diff -urNp linux-2.6.16.12/grsecurity/grsec_log.c linux-2.6.16.12/grsecurity/grsec_log.c
15262 --- linux-2.6.16.12/grsecurity/grsec_log.c      1969-12-31 19:00:00.000000000 -0500
15263 +++ linux-2.6.16.12/grsecurity/grsec_log.c      2006-05-01 20:17:34.000000000 -0400
15264 @@ -0,0 +1,265 @@
15265 +#include <linux/kernel.h>
15266 +#include <linux/sched.h>
15267 +#include <linux/file.h>
15268 +#include <linux/tty.h>
15269 +#include <linux/fs.h>
15270 +#include <linux/grinternal.h>
15271 +
15272 +#define BEGIN_LOCKS(x) \
15273 +       read_lock(&tasklist_lock); \
15274 +       read_lock(&grsec_exec_file_lock); \
15275 +       if (x != GR_DO_AUDIT) \
15276 +               spin_lock(&grsec_alert_lock); \
15277 +       else \
15278 +               spin_lock(&grsec_audit_lock)
15279 +
15280 +#define END_LOCKS(x) \
15281 +       if (x != GR_DO_AUDIT) \
15282 +               spin_unlock(&grsec_alert_lock); \
15283 +       else \
15284 +               spin_unlock(&grsec_audit_lock); \
15285 +       read_unlock(&grsec_exec_file_lock); \
15286 +       read_unlock(&tasklist_lock); \
15287 +       if (x == GR_DONT_AUDIT) \
15288 +               gr_handle_alertkill(current)
15289 +
15290 +enum {
15291 +       FLOODING,
15292 +       NO_FLOODING
15293 +};
15294 +
15295 +extern char *gr_alert_log_fmt;
15296 +extern char *gr_audit_log_fmt;
15297 +extern char *gr_alert_log_buf;
15298 +extern char *gr_audit_log_buf;
15299 +
15300 +static int gr_log_start(int audit)
15301 +{
15302 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
15303 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
15304 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15305 +
15306 +       if (audit == GR_DO_AUDIT)
15307 +               goto set_fmt;
15308 +
15309 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
15310 +               grsec_alert_wtime = jiffies;
15311 +               grsec_alert_fyet = 0;
15312 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
15313 +               grsec_alert_fyet++;
15314 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
15315 +               grsec_alert_wtime = jiffies;
15316 +               grsec_alert_fyet++;
15317 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
15318 +               return FLOODING;
15319 +       } else return FLOODING;
15320 +
15321 +set_fmt:
15322 +       memset(buf, 0, PAGE_SIZE);
15323 +       if (current->signal->curr_ip && gr_acl_is_enabled()) {
15324 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
15325 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
15326 +       } else if (current->signal->curr_ip) {
15327 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
15328 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
15329 +       } else if (gr_acl_is_enabled()) {
15330 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
15331 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
15332 +       } else {
15333 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
15334 +               strcpy(buf, fmt);
15335 +       }
15336 +
15337 +       return NO_FLOODING;
15338 +}
15339 +
15340 +static void gr_log_middle(int audit, const char *msg, va_list ap)
15341 +{
15342 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15343 +       unsigned int len = strlen(buf);
15344 +
15345 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
15346 +
15347 +       return;
15348 +}
15349 +
15350 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
15351 +{
15352 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15353 +       unsigned int len = strlen(buf);
15354 +       va_list ap;
15355 +
15356 +       va_start(ap, msg);
15357 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
15358 +       va_end(ap);
15359 +
15360 +       return;
15361 +}
15362 +
15363 +static void gr_log_end(int audit)
15364 +{
15365 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15366 +       unsigned int len = strlen(buf);
15367 +
15368 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
15369 +       printk("%s\n", buf);
15370 +
15371 +       return;
15372 +}
15373 +
15374 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
15375 +{
15376 +       int logtype;
15377 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
15378 +       char *str1, *str2, *str3;
15379 +       int num1, num2;
15380 +       unsigned long ulong1, ulong2;
15381 +       struct dentry *dentry;
15382 +       struct vfsmount *mnt;
15383 +       struct file *file;
15384 +       struct task_struct *task;
15385 +       va_list ap;
15386 +
15387 +       BEGIN_LOCKS(audit);
15388 +       logtype = gr_log_start(audit);
15389 +       if (logtype == FLOODING) {
15390 +               END_LOCKS(audit);
15391 +               return;
15392 +       }
15393 +       va_start(ap, argtypes);
15394 +       switch (argtypes) {
15395 +       case GR_TTYSNIFF:
15396 +               task = va_arg(ap, struct task_struct *);
15397 +               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);
15398 +               break;
15399 +       case GR_RBAC:
15400 +               dentry = va_arg(ap, struct dentry *);
15401 +               mnt = va_arg(ap, struct vfsmount *);
15402 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
15403 +               break;
15404 +       case GR_RBAC_STR:
15405 +               dentry = va_arg(ap, struct dentry *);
15406 +               mnt = va_arg(ap, struct vfsmount *);
15407 +               str1 = va_arg(ap, char *);
15408 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
15409 +               break;
15410 +       case GR_STR_RBAC:
15411 +               str1 = va_arg(ap, char *);
15412 +               dentry = va_arg(ap, struct dentry *);
15413 +               mnt = va_arg(ap, struct vfsmount *);
15414 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
15415 +               break;
15416 +       case GR_RBAC_MODE2:
15417 +               dentry = va_arg(ap, struct dentry *);
15418 +               mnt = va_arg(ap, struct vfsmount *);
15419 +               str1 = va_arg(ap, char *);
15420 +               str2 = va_arg(ap, char *);
15421 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
15422 +               break;
15423 +       case GR_RBAC_MODE3:
15424 +               dentry = va_arg(ap, struct dentry *);
15425 +               mnt = va_arg(ap, struct vfsmount *);
15426 +               str1 = va_arg(ap, char *);
15427 +               str2 = va_arg(ap, char *);
15428 +               str3 = va_arg(ap, char *);
15429 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
15430 +               break;
15431 +       case GR_FILENAME:
15432 +               dentry = va_arg(ap, struct dentry *);
15433 +               mnt = va_arg(ap, struct vfsmount *);
15434 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
15435 +               break;
15436 +       case GR_STR_FILENAME:
15437 +               str1 = va_arg(ap, char *);
15438 +               dentry = va_arg(ap, struct dentry *);
15439 +               mnt = va_arg(ap, struct vfsmount *);
15440 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
15441 +               break;
15442 +       case GR_FILENAME_STR:
15443 +               dentry = va_arg(ap, struct dentry *);
15444 +               mnt = va_arg(ap, struct vfsmount *);
15445 +               str1 = va_arg(ap, char *);
15446 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
15447 +               break;
15448 +       case GR_FILENAME_TWO_INT:
15449 +               dentry = va_arg(ap, struct dentry *);
15450 +               mnt = va_arg(ap, struct vfsmount *);
15451 +               num1 = va_arg(ap, int);
15452 +               num2 = va_arg(ap, int);
15453 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
15454 +               break;
15455 +       case GR_FILENAME_TWO_INT_STR:
15456 +               dentry = va_arg(ap, struct dentry *);
15457 +               mnt = va_arg(ap, struct vfsmount *);
15458 +               num1 = va_arg(ap, int);
15459 +               num2 = va_arg(ap, int);
15460 +               str1 = va_arg(ap, char *);
15461 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
15462 +               break;
15463 +       case GR_TEXTREL:
15464 +               file = va_arg(ap, struct file *);
15465 +               ulong1 = va_arg(ap, unsigned long);
15466 +               ulong2 = va_arg(ap, unsigned long);
15467 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
15468 +               break;
15469 +       case GR_PTRACE:
15470 +               task = va_arg(ap, struct task_struct *);
15471 +               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);
15472 +               break;
15473 +       case GR_RESOURCE:
15474 +               task = va_arg(ap, struct task_struct *);
15475 +               ulong1 = va_arg(ap, unsigned long);
15476 +               str1 = va_arg(ap, char *);
15477 +               ulong2 = va_arg(ap, unsigned long);
15478 +               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);
15479 +               break;
15480 +       case GR_CAP:
15481 +               task = va_arg(ap, struct task_struct *);
15482 +               str1 = va_arg(ap, char *);
15483 +               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);
15484 +               break;
15485 +       case GR_SIG:
15486 +               task = va_arg(ap, struct task_struct *);
15487 +               num1 = va_arg(ap, int);
15488 +               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);
15489 +               break;
15490 +       case GR_CRASH1:
15491 +               task = va_arg(ap, struct task_struct *);
15492 +               ulong1 = va_arg(ap, unsigned long);
15493 +               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);
15494 +               break;
15495 +       case GR_CRASH2:
15496 +               task = va_arg(ap, struct task_struct *);
15497 +               ulong1 = va_arg(ap, unsigned long);
15498 +               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);
15499 +               break;
15500 +       case GR_PSACCT:
15501 +               {
15502 +                       unsigned int wday, cday;
15503 +                       __u8 whr, chr;
15504 +                       __u8 wmin, cmin;
15505 +                       __u8 wsec, csec;
15506 +                       char cur_tty[64] = { 0 };
15507 +                       char parent_tty[64] = { 0 };
15508 +
15509 +                       task = va_arg(ap, struct task_struct *);
15510 +                       wday = va_arg(ap, unsigned int);
15511 +                       cday = va_arg(ap, unsigned int);
15512 +                       whr = va_arg(ap, int);
15513 +                       chr = va_arg(ap, int);
15514 +                       wmin = va_arg(ap, int);
15515 +                       cmin = va_arg(ap, int);
15516 +                       wsec = va_arg(ap, int);
15517 +                       csec = va_arg(ap, int);
15518 +                       ulong1 = va_arg(ap, unsigned long);
15519 +
15520 +                       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);
15521 +               }
15522 +               break;
15523 +       default:
15524 +               gr_log_middle(audit, msg, ap);
15525 +       }
15526 +       va_end(ap);
15527 +       gr_log_end(audit);
15528 +       END_LOCKS(audit);
15529 +}
15530 diff -urNp linux-2.6.16.12/grsecurity/grsec_mem.c linux-2.6.16.12/grsecurity/grsec_mem.c
15531 --- linux-2.6.16.12/grsecurity/grsec_mem.c      1969-12-31 19:00:00.000000000 -0500
15532 +++ linux-2.6.16.12/grsecurity/grsec_mem.c      2006-05-01 20:17:34.000000000 -0400
15533 @@ -0,0 +1,71 @@
15534 +#include <linux/kernel.h>
15535 +#include <linux/sched.h>
15536 +#include <linux/mm.h>
15537 +#include <linux/mman.h>
15538 +#include <linux/grinternal.h>
15539 +
15540 +void
15541 +gr_handle_ioperm(void)
15542 +{
15543 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
15544 +       return;
15545 +}
15546 +
15547 +void
15548 +gr_handle_iopl(void)
15549 +{
15550 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
15551 +       return;
15552 +}
15553 +
15554 +void
15555 +gr_handle_mem_write(void)
15556 +{
15557 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
15558 +       return;
15559 +}
15560 +
15561 +void
15562 +gr_handle_kmem_write(void)
15563 +{
15564 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
15565 +       return;
15566 +}
15567 +
15568 +void
15569 +gr_handle_open_port(void)
15570 +{
15571 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
15572 +       return;
15573 +}
15574 +
15575 +int
15576 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
15577 +{
15578 +       unsigned long start, end;
15579 +
15580 +       start = offset;
15581 +       end = start + vma->vm_end - vma->vm_start;
15582 +
15583 +       if (start > end) {
15584 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
15585 +               return -EPERM;
15586 +       }
15587 +
15588 +       /* allowed ranges : ISA I/O BIOS */
15589 +       if ((start >= __pa(high_memory))
15590 +#ifdef CONFIG_X86
15591 +           || (start >= 0x000a0000 && end <= 0x00100000)
15592 +           || (start >= 0x00000000 && end <= 0x00001000)
15593 +#endif
15594 +       )
15595 +               return 0;
15596 +
15597 +       if (vma->vm_flags & VM_WRITE) {
15598 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
15599 +               return -EPERM;
15600 +       } else
15601 +               vma->vm_flags &= ~VM_MAYWRITE;
15602 +
15603 +       return 0;
15604 +}
15605 diff -urNp linux-2.6.16.12/grsecurity/grsec_mount.c linux-2.6.16.12/grsecurity/grsec_mount.c
15606 --- linux-2.6.16.12/grsecurity/grsec_mount.c    1969-12-31 19:00:00.000000000 -0500
15607 +++ linux-2.6.16.12/grsecurity/grsec_mount.c    2006-05-01 20:17:34.000000000 -0400
15608 @@ -0,0 +1,34 @@
15609 +#include <linux/kernel.h>
15610 +#include <linux/sched.h>
15611 +#include <linux/grsecurity.h>
15612 +#include <linux/grinternal.h>
15613 +
15614 +void
15615 +gr_log_remount(const char *devname, const int retval)
15616 +{
15617 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15618 +       if (grsec_enable_mount && (retval >= 0))
15619 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
15620 +#endif
15621 +       return;
15622 +}
15623 +
15624 +void
15625 +gr_log_unmount(const char *devname, const int retval)
15626 +{
15627 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15628 +       if (grsec_enable_mount && (retval >= 0))
15629 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
15630 +#endif
15631 +       return;
15632 +}
15633 +
15634 +void
15635 +gr_log_mount(const char *from, const char *to, const int retval)
15636 +{
15637 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15638 +       if (grsec_enable_mount && (retval >= 0))
15639 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
15640 +#endif
15641 +       return;
15642 +}
15643 diff -urNp linux-2.6.16.12/grsecurity/grsec_rand.c linux-2.6.16.12/grsecurity/grsec_rand.c
15644 --- linux-2.6.16.12/grsecurity/grsec_rand.c     1969-12-31 19:00:00.000000000 -0500
15645 +++ linux-2.6.16.12/grsecurity/grsec_rand.c     2006-05-01 20:17:34.000000000 -0400
15646 @@ -0,0 +1,26 @@
15647 +#include <linux/kernel.h>
15648 +#include <linux/sched.h>
15649 +#include <linux/smp_lock.h>
15650 +#include <linux/grsecurity.h>
15651 +#include <linux/grinternal.h>
15652 +
15653 +extern int pid_max;
15654 +
15655 +int
15656 +gr_random_pid(void)
15657 +{
15658 +#ifdef CONFIG_GRKERNSEC_RANDPID
15659 +       int pid;
15660 +
15661 +       if (grsec_enable_randpid && current->fs->root) {
15662 +               /* return a pid in the range 1 ... pid_max - 1
15663 +                  optimize this so we don't have to do a real division
15664 +               */
15665 +               pid = 1 + (get_random_long() % pid_max);
15666 +               if (pid == pid_max)
15667 +                       pid = pid_max - 1;
15668 +               return pid;
15669 +       }
15670 +#endif
15671 +       return 0;
15672 +}
15673 diff -urNp linux-2.6.16.12/grsecurity/grsec_sig.c linux-2.6.16.12/grsecurity/grsec_sig.c
15674 --- linux-2.6.16.12/grsecurity/grsec_sig.c      1969-12-31 19:00:00.000000000 -0500
15675 +++ linux-2.6.16.12/grsecurity/grsec_sig.c      2006-05-01 20:17:34.000000000 -0400
15676 @@ -0,0 +1,59 @@
15677 +#include <linux/kernel.h>
15678 +#include <linux/sched.h>
15679 +#include <linux/grsecurity.h>
15680 +#include <linux/grinternal.h>
15681 +
15682 +void
15683 +gr_log_signal(const int sig, const struct task_struct *t)
15684 +{
15685 +#ifdef CONFIG_GRKERNSEC_SIGNAL
15686 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
15687 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
15688 +               if (t->pid == current->pid) {
15689 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
15690 +               } else {
15691 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
15692 +               }
15693 +       }
15694 +#endif
15695 +       return;
15696 +}
15697 +
15698 +int
15699 +gr_handle_signal(const struct task_struct *p, const int sig)
15700 +{
15701 +#ifdef CONFIG_GRKERNSEC
15702 +       if (current->pid > 1 && gr_check_protected_task(p)) {
15703 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
15704 +               return -EPERM;
15705 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
15706 +               return -EPERM;
15707 +       }
15708 +#endif
15709 +       return 0;
15710 +}
15711 +
15712 +void gr_handle_brute_attach(struct task_struct *p)
15713 +{
15714 +#ifdef CONFIG_GRKERNSEC_BRUTE
15715 +       read_lock(&tasklist_lock);
15716 +       read_lock(&grsec_exec_file_lock);
15717 +       if (p->parent && p->parent->exec_file == p->exec_file)
15718 +               p->parent->brute = 1;
15719 +       read_unlock(&grsec_exec_file_lock);
15720 +       read_unlock(&tasklist_lock);
15721 +#endif
15722 +       return;
15723 +}
15724 +
15725 +void gr_handle_brute_check(void)
15726 +{
15727 +#ifdef CONFIG_GRKERNSEC_BRUTE
15728 +       if (current->brute) {
15729 +               set_current_state(TASK_UNINTERRUPTIBLE);
15730 +               schedule_timeout(30 * HZ);
15731 +       }
15732 +#endif
15733 +       return;
15734 +}
15735 +
15736 diff -urNp linux-2.6.16.12/grsecurity/grsec_sock.c linux-2.6.16.12/grsecurity/grsec_sock.c
15737 --- linux-2.6.16.12/grsecurity/grsec_sock.c     1969-12-31 19:00:00.000000000 -0500
15738 +++ linux-2.6.16.12/grsecurity/grsec_sock.c     2006-05-01 20:17:34.000000000 -0400
15739 @@ -0,0 +1,263 @@
15740 +#include <linux/kernel.h>
15741 +#include <linux/module.h>
15742 +#include <linux/sched.h>
15743 +#include <linux/file.h>
15744 +#include <linux/net.h>
15745 +#include <linux/in.h>
15746 +#include <linux/ip.h>
15747 +#include <net/sock.h>
15748 +#include <net/inet_sock.h>
15749 +#include <linux/grsecurity.h>
15750 +#include <linux/grinternal.h>
15751 +#include <linux/gracl.h>
15752 +
15753 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
15754 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
15755 +EXPORT_SYMBOL(udp_v4_lookup);
15756 +#endif
15757 +
15758 +EXPORT_SYMBOL(gr_cap_rtnetlink);
15759 +
15760 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
15761 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
15762 +
15763 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
15764 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
15765 +
15766 +#ifdef CONFIG_UNIX_MODULE
15767 +EXPORT_SYMBOL(gr_acl_handle_unix);
15768 +EXPORT_SYMBOL(gr_acl_handle_mknod);
15769 +EXPORT_SYMBOL(gr_handle_chroot_unix);
15770 +EXPORT_SYMBOL(gr_handle_create);
15771 +#endif
15772 +
15773 +#ifdef CONFIG_GRKERNSEC
15774 +#define gr_conn_table_size 32749
15775 +struct conn_table_entry {
15776 +       struct conn_table_entry *next;
15777 +       struct signal_struct *sig;
15778 +};
15779 +
15780 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
15781 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
15782 +
15783 +extern const char * gr_socktype_to_name(unsigned char type);
15784 +extern const char * gr_proto_to_name(unsigned char proto);
15785 +
15786 +static __inline__ int 
15787 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
15788 +{
15789 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
15790 +}
15791 +
15792 +static __inline__ int
15793 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, 
15794 +          __u16 sport, __u16 dport)
15795 +{
15796 +       if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
15797 +                    sig->gr_sport == sport && sig->gr_dport == dport))
15798 +               return 1;
15799 +       else
15800 +               return 0;
15801 +}
15802 +
15803 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
15804 +{
15805 +       struct conn_table_entry **match;
15806 +       unsigned int index;
15807 +
15808 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
15809 +                         sig->gr_sport, sig->gr_dport, 
15810 +                         gr_conn_table_size);
15811 +
15812 +       newent->sig = sig;
15813 +       
15814 +       match = &gr_conn_table[index];
15815 +       newent->next = *match;
15816 +       *match = newent;
15817 +
15818 +       return;
15819 +}
15820 +
15821 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
15822 +{
15823 +       struct conn_table_entry *match, *last = NULL;
15824 +       unsigned int index;
15825 +
15826 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
15827 +                         sig->gr_sport, sig->gr_dport, 
15828 +                         gr_conn_table_size);
15829 +
15830 +       match = gr_conn_table[index];
15831 +       while (match && !conn_match(match->sig, 
15832 +               sig->gr_saddr, sig->gr_daddr, sig->gr_sport, 
15833 +               sig->gr_dport)) {
15834 +               last = match;
15835 +               match = match->next;
15836 +       }
15837 +
15838 +       if (match) {
15839 +               if (last)
15840 +                       last->next = match->next;
15841 +               else
15842 +                       gr_conn_table[index] = NULL;
15843 +               kfree(match);
15844 +       }
15845 +
15846 +       return;
15847 +}
15848 +
15849 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
15850 +                                            __u16 sport, __u16 dport)
15851 +{
15852 +       struct conn_table_entry *match;
15853 +       unsigned int index;
15854 +
15855 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
15856 +
15857 +       match = gr_conn_table[index];
15858 +       while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
15859 +               match = match->next;
15860 +
15861 +       if (match)
15862 +               return match->sig;
15863 +       else
15864 +               return NULL;
15865 +}
15866 +
15867 +#endif
15868 +
15869 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
15870 +{
15871 +#ifdef CONFIG_GRKERNSEC
15872 +       struct signal_struct *sig = task->signal;
15873 +       struct conn_table_entry *newent;
15874 +
15875 +       newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
15876 +       if (newent == NULL)
15877 +               return;
15878 +       /* no bh lock needed since we are called with bh disabled */
15879 +       spin_lock(&gr_conn_table_lock);
15880 +       gr_del_task_from_ip_table_nolock(sig);
15881 +       sig->gr_saddr = inet->rcv_saddr;
15882 +       sig->gr_daddr = inet->daddr;
15883 +       sig->gr_sport = inet->sport;
15884 +       sig->gr_dport = inet->dport;
15885 +       gr_add_to_task_ip_table_nolock(sig, newent);
15886 +       spin_unlock(&gr_conn_table_lock);
15887 +#endif
15888 +       return;
15889 +}
15890 +
15891 +void gr_del_task_from_ip_table(struct task_struct *task)
15892 +{
15893 +#ifdef CONFIG_GRKERNSEC
15894 +       spin_lock(&gr_conn_table_lock);
15895 +       gr_del_task_from_ip_table_nolock(task->signal);
15896 +       spin_unlock(&gr_conn_table_lock);
15897 +#endif
15898 +       return;
15899 +}
15900 +
15901 +void
15902 +gr_attach_curr_ip(const struct sock *sk)
15903 +{
15904 +#ifdef CONFIG_GRKERNSEC
15905 +       struct signal_struct *p, *set;
15906 +       const struct inet_sock *inet = inet_sk(sk);     
15907 +
15908 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
15909 +               return;
15910 +
15911 +       set = current->signal;
15912 +
15913 +       spin_lock_bh(&gr_conn_table_lock);
15914 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
15915 +                                   inet->dport, inet->sport);
15916 +       if (unlikely(p != NULL)) {
15917 +               set->curr_ip = p->curr_ip;
15918 +               set->used_accept = 1;
15919 +               gr_del_task_from_ip_table_nolock(p);
15920 +               spin_unlock_bh(&gr_conn_table_lock);
15921 +               return;
15922 +       }
15923 +       spin_unlock_bh(&gr_conn_table_lock);
15924 +
15925 +       set->curr_ip = inet->daddr;
15926 +       set->used_accept = 1;
15927 +#endif
15928 +       return;
15929 +}
15930 +
15931 +int
15932 +gr_handle_sock_all(const int family, const int type, const int protocol)
15933 +{
15934 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
15935 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
15936 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
15937 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
15938 +               return -EACCES;
15939 +       }
15940 +#endif
15941 +       return 0;
15942 +}
15943 +
15944 +int
15945 +gr_handle_sock_server(const struct sockaddr *sck)
15946 +{
15947 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
15948 +       if (grsec_enable_socket_server &&
15949 +           in_group_p(grsec_socket_server_gid) &&
15950 +           sck && (sck->sa_family != AF_UNIX) &&
15951 +           (sck->sa_family != AF_LOCAL)) {
15952 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
15953 +               return -EACCES;
15954 +       }
15955 +#endif
15956 +       return 0;
15957 +}
15958 +
15959 +int
15960 +gr_handle_sock_server_other(const struct sock *sck)
15961 +{
15962 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
15963 +       if (grsec_enable_socket_server &&
15964 +           in_group_p(grsec_socket_server_gid) &&
15965 +           sck && (sck->sk_family != AF_UNIX) &&
15966 +           (sck->sk_family != AF_LOCAL)) {
15967 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
15968 +               return -EACCES;
15969 +       }
15970 +#endif
15971 +       return 0;
15972 +}
15973 +
15974 +int
15975 +gr_handle_sock_client(const struct sockaddr *sck)
15976 +{
15977 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
15978 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
15979 +           sck && (sck->sa_family != AF_UNIX) &&
15980 +           (sck->sa_family != AF_LOCAL)) {
15981 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
15982 +               return -EACCES;
15983 +       }
15984 +#endif
15985 +       return 0;
15986 +}
15987 +
15988 +__u32
15989 +gr_cap_rtnetlink(void)
15990 +{
15991 +#ifdef CONFIG_GRKERNSEC
15992 +       if (!gr_acl_is_enabled())
15993 +               return current->cap_effective;
15994 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
15995 +                gr_task_is_capable(current, CAP_NET_ADMIN))
15996 +               return current->cap_effective;
15997 +       else
15998 +               return 0;
15999 +#else
16000 +       return current->cap_effective;
16001 +#endif
16002 +}
16003 diff -urNp linux-2.6.16.12/grsecurity/grsec_sysctl.c linux-2.6.16.12/grsecurity/grsec_sysctl.c
16004 --- linux-2.6.16.12/grsecurity/grsec_sysctl.c   1969-12-31 19:00:00.000000000 -0500
16005 +++ linux-2.6.16.12/grsecurity/grsec_sysctl.c   2006-05-01 20:17:34.000000000 -0400
16006 @@ -0,0 +1,456 @@
16007 +#include <linux/kernel.h>
16008 +#include <linux/sched.h>
16009 +#include <linux/sysctl.h>
16010 +#include <linux/grsecurity.h>
16011 +#include <linux/grinternal.h>
16012 +
16013 +#ifdef CONFIG_GRKERNSEC_MODSTOP
16014 +int grsec_modstop;
16015 +#endif
16016 +
16017 +int
16018 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
16019 +{
16020 +#ifdef CONFIG_GRKERNSEC_SYSCTL
16021 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
16022 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
16023 +               return -EACCES;
16024 +       }
16025 +#endif
16026 +#ifdef CONFIG_GRKERNSEC_MODSTOP
16027 +       if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
16028 +           grsec_modstop && (op & 002)) {
16029 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
16030 +               return -EACCES;
16031 +       }
16032 +#endif
16033 +       return 0;
16034 +}
16035 +
16036 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
16037 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
16038 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
16039 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
16040 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
16041 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
16042 +GS_RANDPID, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
16043 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, 
16044 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
16045 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP};
16046 +
16047 +
16048 +ctl_table grsecurity_table[] = {
16049 +#ifdef CONFIG_GRKERNSEC_SYSCTL
16050 +#ifdef CONFIG_GRKERNSEC_LINK
16051 +       {
16052 +               .ctl_name       = GS_LINK,
16053 +               .procname       = "linking_restrictions",
16054 +               .data           = &grsec_enable_link,
16055 +               .maxlen         = sizeof(int),
16056 +               .mode           = 0600,
16057 +               .proc_handler   = &proc_dointvec,
16058 +       },
16059 +#endif
16060 +#ifdef CONFIG_GRKERNSEC_FIFO
16061 +       {
16062 +               .ctl_name       = GS_FIFO,
16063 +               .procname       = "fifo_restrictions",
16064 +               .data           = &grsec_enable_fifo,
16065 +               .maxlen         = sizeof(int),
16066 +               .mode           = 0600,
16067 +               .proc_handler   = &proc_dointvec,
16068 +       },
16069 +#endif
16070 +#ifdef CONFIG_GRKERNSEC_EXECVE
16071 +       {
16072 +               .ctl_name       = GS_EXECVE,
16073 +               .procname       = "execve_limiting",
16074 +               .data           = &grsec_enable_execve,
16075 +               .maxlen         = sizeof(int),
16076 +               .mode           = 0600,
16077 +               .proc_handler   = &proc_dointvec,
16078 +       },
16079 +#endif
16080 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16081 +       {
16082 +               .ctl_name       = GS_EXECLOG,
16083 +               .procname       = "exec_logging",
16084 +               .data           = &grsec_enable_execlog,
16085 +               .maxlen         = sizeof(int),
16086 +               .mode           = 0600,
16087 +               .proc_handler   = &proc_dointvec,
16088 +       },
16089 +#endif
16090 +#ifdef CONFIG_GRKERNSEC_SIGNAL
16091 +       {
16092 +               .ctl_name       = GS_SIGNAL,
16093 +               .procname       = "signal_logging",
16094 +               .data           = &grsec_enable_signal,
16095 +               .maxlen         = sizeof(int),
16096 +               .mode           = 0600,
16097 +               .proc_handler   = &proc_dointvec,
16098 +       },
16099 +#endif
16100 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
16101 +       {
16102 +               .ctl_name       = GS_FORKFAIL,
16103 +               .procname       = "forkfail_logging",
16104 +               .data           = &grsec_enable_forkfail,
16105 +               .maxlen         = sizeof(int),
16106 +               .mode           = 0600,
16107 +               .proc_handler   = &proc_dointvec,
16108 +       },
16109 +#endif
16110 +#ifdef CONFIG_GRKERNSEC_TIME
16111 +       {
16112 +               .ctl_name       = GS_TIME,
16113 +               .procname       = "timechange_logging",
16114 +               .data           = &grsec_enable_time,
16115 +               .maxlen         = sizeof(int),
16116 +               .mode           = 0600,
16117 +               .proc_handler   = &proc_dointvec,
16118 +       },
16119 +#endif
16120 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16121 +       {
16122 +               .ctl_name       = GS_CHROOT_SHMAT,
16123 +               .procname       = "chroot_deny_shmat",
16124 +               .data           = &grsec_enable_chroot_shmat,
16125 +               .maxlen         = sizeof(int),
16126 +               .mode           = 0600,
16127 +               .proc_handler   = &proc_dointvec,
16128 +       },
16129 +#endif
16130 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16131 +       {
16132 +               .ctl_name       = GS_CHROOT_UNIX,
16133 +               .procname       = "chroot_deny_unix",
16134 +               .data           = &grsec_enable_chroot_unix,
16135 +               .maxlen         = sizeof(int),
16136 +               .mode           = 0600,
16137 +               .proc_handler   = &proc_dointvec,
16138 +       },
16139 +#endif
16140 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16141 +       {
16142 +               .ctl_name       = GS_CHROOT_MNT,
16143 +               .procname       = "chroot_deny_mount",
16144 +               .data           = &grsec_enable_chroot_mount,
16145 +               .maxlen         = sizeof(int),
16146 +               .mode           = 0600,
16147 +               .proc_handler   = &proc_dointvec,
16148 +       },
16149 +#endif
16150 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16151 +       {
16152 +               .ctl_name       = GS_CHROOT_FCHDIR,
16153 +               .procname       = "chroot_deny_fchdir",
16154 +               .data           = &grsec_enable_chroot_fchdir,
16155 +               .maxlen         = sizeof(int),
16156 +               .mode           = 0600,
16157 +               .proc_handler   = &proc_dointvec,
16158 +       },
16159 +#endif
16160 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
16161 +       {
16162 +               .ctl_name       = GS_CHROOT_DBL,
16163 +               .procname       = "chroot_deny_chroot",
16164 +               .data           = &grsec_enable_chroot_double,
16165 +               .maxlen         = sizeof(int),
16166 +               .mode           = 0600,
16167 +               .proc_handler   = &proc_dointvec,
16168 +       },
16169 +#endif
16170 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16171 +       {
16172 +               .ctl_name       = GS_CHROOT_PVT,
16173 +               .procname       = "chroot_deny_pivot",
16174 +               .data           = &grsec_enable_chroot_pivot,
16175 +               .maxlen         = sizeof(int),
16176 +               .mode           = 0600,
16177 +               .proc_handler   = &proc_dointvec,
16178 +       },
16179 +#endif
16180 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
16181 +       {
16182 +               .ctl_name       = GS_CHROOT_CD,
16183 +               .procname       = "chroot_enforce_chdir",
16184 +               .data           = &grsec_enable_chroot_chdir,
16185 +               .maxlen         = sizeof(int),
16186 +               .mode           = 0600,
16187 +               .proc_handler   = &proc_dointvec,
16188 +       },
16189 +#endif
16190 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
16191 +       {
16192 +               .ctl_name       = GS_CHROOT_CM,
16193 +               .procname       = "chroot_deny_chmod",
16194 +               .data           = &grsec_enable_chroot_chmod,
16195 +               .maxlen         = sizeof(int),
16196 +               .mode           = 0600,
16197 +               .proc_handler   = &proc_dointvec,
16198 +       },
16199 +#endif
16200 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16201 +       {
16202 +               .ctl_name       = GS_CHROOT_MK,
16203 +               .procname       = "chroot_deny_mknod",
16204 +               .data           = &grsec_enable_chroot_mknod,
16205 +               .maxlen         = sizeof(int),
16206 +               .mode           = 0600,
16207 +               .proc_handler   = &proc_dointvec,
16208 +       },
16209 +#endif
16210 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16211 +       {
16212 +               .ctl_name       = GS_CHROOT_NI,
16213 +               .procname       = "chroot_restrict_nice",
16214 +               .data           = &grsec_enable_chroot_nice,
16215 +               .maxlen         = sizeof(int),
16216 +               .mode           = 0600,
16217 +               .proc_handler   = &proc_dointvec,
16218 +       },
16219 +#endif
16220 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16221 +       {
16222 +               .ctl_name       = GS_CHROOT_EXECLOG,
16223 +               .procname       = "chroot_execlog",
16224 +               .data           = &grsec_enable_chroot_execlog,
16225 +               .maxlen         = sizeof(int),
16226 +               .mode           = 0600,
16227 +               .proc_handler   = &proc_dointvec,
16228 +       },
16229 +#endif
16230 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16231 +       {
16232 +               .ctl_name       = GS_CHROOT_CAPS,
16233 +               .procname       = "chroot_caps",
16234 +               .data           = &grsec_enable_chroot_caps,
16235 +               .maxlen         = sizeof(int),
16236 +               .mode           = 0600,
16237 +               .proc_handler   = &proc_dointvec,
16238 +       },
16239 +#endif
16240 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
16241 +       {
16242 +               .ctl_name       = GS_CHROOT_SYSCTL,
16243 +               .procname       = "chroot_deny_sysctl",
16244 +               .data           = &grsec_enable_chroot_sysctl,
16245 +               .maxlen         = sizeof(int),
16246 +               .mode           = 0600,
16247 +               .proc_handler   = &proc_dointvec,
16248 +       },
16249 +#endif
16250 +#ifdef CONFIG_GRKERNSEC_TPE
16251 +       {
16252 +               .ctl_name       = GS_TPE,
16253 +               .procname       = "tpe",
16254 +               .data           = &grsec_enable_tpe,
16255 +               .maxlen         = sizeof(int),
16256 +               .mode           = 0600,
16257 +               .proc_handler   = &proc_dointvec,
16258 +       },
16259 +       {
16260 +               .ctl_name       = GS_TPE_GID,
16261 +               .procname       = "tpe_gid",
16262 +               .data           = &grsec_tpe_gid,
16263 +               .maxlen         = sizeof(int),
16264 +               .mode           = 0600,
16265 +               .proc_handler   = &proc_dointvec,
16266 +       },
16267 +#endif
16268 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
16269 +       {
16270 +               .ctl_name       = GS_TPE_ALL,
16271 +               .procname       = "tpe_restrict_all",
16272 +               .data           = &grsec_enable_tpe_all,
16273 +               .maxlen         = sizeof(int),
16274 +               .mode           = 0600,
16275 +               .proc_handler   = &proc_dointvec,
16276 +       },
16277 +#endif
16278 +#ifdef CONFIG_GRKERNSEC_RANDPID
16279 +       {
16280 +               .ctl_name       = GS_RANDPID,
16281 +               .procname       = "rand_pids",
16282 +               .data           = &grsec_enable_randpid,
16283 +               .maxlen         = sizeof(int),
16284 +               .mode           = 0600,
16285 +               .proc_handler   = &proc_dointvec,
16286 +       },
16287 +#endif
16288 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
16289 +       {
16290 +               .ctl_name       = GS_SOCKET_ALL,
16291 +               .procname       = "socket_all",
16292 +               .data           = &grsec_enable_socket_all,
16293 +               .maxlen         = sizeof(int),
16294 +               .mode           = 0600,
16295 +               .proc_handler   = &proc_dointvec,
16296 +       },
16297 +       {
16298 +               .ctl_name       = GS_SOCKET_ALL_GID,
16299 +               .procname       = "socket_all_gid",
16300 +               .data           = &grsec_socket_all_gid,
16301 +               .maxlen         = sizeof(int),
16302 +               .mode           = 0600,
16303 +               .proc_handler   = &proc_dointvec,
16304 +       },
16305 +#endif
16306 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
16307 +       {
16308 +               .ctl_name       = GS_SOCKET_CLIENT,
16309 +               .procname       = "socket_client",
16310 +               .data           = &grsec_enable_socket_client,
16311 +               .maxlen         = sizeof(int),
16312 +               .mode           = 0600,
16313 +               .proc_handler   = &proc_dointvec,
16314 +       },
16315 +       {
16316 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
16317 +               .procname       = "socket_client_gid",
16318 +               .data           = &grsec_socket_client_gid,
16319 +               .maxlen         = sizeof(int),
16320 +               .mode           = 0600,
16321 +               .proc_handler   = &proc_dointvec,
16322 +       },
16323 +#endif
16324 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
16325 +       {
16326 +               .ctl_name       = GS_SOCKET_SERVER,
16327 +               .procname       = "socket_server",
16328 +               .data           = &grsec_enable_socket_server,
16329 +               .maxlen         = sizeof(int),
16330 +               .mode           = 0600,
16331 +               .proc_handler   = &proc_dointvec,
16332 +       },
16333 +       {
16334 +               .ctl_name       = GS_SOCKET_SERVER_GID,
16335 +               .procname       = "socket_server_gid",
16336 +               .data           = &grsec_socket_server_gid,
16337 +               .maxlen         = sizeof(int),
16338 +               .mode           = 0600,
16339 +               .proc_handler   = &proc_dointvec,
16340 +       },
16341 +#endif
16342 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
16343 +       {
16344 +               .ctl_name       = GS_GROUP,
16345 +               .procname       = "audit_group",
16346 +               .data           = &grsec_enable_group,
16347 +               .maxlen         = sizeof(int),
16348 +               .mode           = 0600,
16349 +               .proc_handler   = &proc_dointvec,
16350 +       },
16351 +       {
16352 +               .ctl_name       = GS_GID,
16353 +               .procname       = "audit_gid",
16354 +               .data           = &grsec_audit_gid,
16355 +               .maxlen         = sizeof(int),
16356 +               .mode           = 0600,
16357 +               .proc_handler   = &proc_dointvec,
16358 +       },
16359 +#endif
16360 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16361 +       {
16362 +               .ctl_name       = GS_ACHDIR,
16363 +               .procname       = "audit_chdir",
16364 +               .data           = &grsec_enable_chdir,
16365 +               .maxlen         = sizeof(int),
16366 +               .mode           = 0600,
16367 +               .proc_handler   = &proc_dointvec,
16368 +       },
16369 +#endif
16370 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16371 +       {
16372 +               .ctl_name       = GS_AMOUNT,
16373 +               .procname       = "audit_mount",
16374 +               .data           = &grsec_enable_mount,
16375 +               .maxlen         = sizeof(int),
16376 +               .mode           = 0600,
16377 +               .proc_handler   = &proc_dointvec,
16378 +       },
16379 +#endif
16380 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16381 +       {
16382 +               .ctl_name       = GS_AIPC,
16383 +               .procname       = "audit_ipc",
16384 +               .data           = &grsec_enable_audit_ipc,
16385 +               .maxlen         = sizeof(int),
16386 +               .mode           = 0600,
16387 +               .proc_handler   = &proc_dointvec,
16388 +       },
16389 +#endif
16390 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
16391 +       {
16392 +               .ctl_name       = GS_TEXTREL,
16393 +               .procname       = "audit_textrel",
16394 +               .data           = &grsec_enable_audit_textrel,
16395 +               .maxlen         = sizeof(int),
16396 +               .mode           = 0600,
16397 +               .proc_handler   = &proc_dointvec,
16398 +       },
16399 +#endif
16400 +#ifdef CONFIG_GRKERNSEC_DMESG
16401 +       {
16402 +               .ctl_name       = GS_DMSG,
16403 +               .procname       = "dmesg",
16404 +               .data           = &grsec_enable_dmesg,
16405 +               .maxlen         = sizeof(int),
16406 +               .mode           = 0600,
16407 +               .proc_handler   = &proc_dointvec,
16408 +       },
16409 +#endif
16410 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16411 +       {
16412 +               .ctl_name       = GS_FINDTASK,
16413 +               .procname       = "chroot_findtask",
16414 +               .data           = &grsec_enable_chroot_findtask,
16415 +               .maxlen         = sizeof(int),
16416 +               .mode           = 0600,
16417 +               .proc_handler   = &proc_dointvec,
16418 +       },
16419 +#endif
16420 +#ifdef CONFIG_GRKERNSEC_SHM
16421 +       {
16422 +               .ctl_name       = GS_SHM,
16423 +               .procname       = "destroy_unused_shm",
16424 +               .data           = &grsec_enable_shm,
16425 +               .maxlen         = sizeof(int),
16426 +               .mode           = 0600,
16427 +               .proc_handler   = &proc_dointvec,
16428 +       },
16429 +#endif
16430 +       {
16431 +               .ctl_name       = GS_LOCK,
16432 +               .procname       = "grsec_lock",
16433 +               .data           = &grsec_lock,
16434 +               .maxlen         = sizeof(int),
16435 +               .mode           = 0600,
16436 +               .proc_handler   = &proc_dointvec,
16437 +       },
16438 +#endif
16439 +#ifdef CONFIG_GRKERNSEC_MODSTOP
16440 +       {
16441 +               .ctl_name       = GS_MODSTOP,
16442 +               .procname       = "disable_modules",
16443 +               .data           = &grsec_modstop,
16444 +               .maxlen         = sizeof(int),
16445 +               .mode           = 0600,
16446 +               .proc_handler   = &proc_dointvec,
16447 +       },
16448 +#endif
16449 +       { .ctl_name = 0 }
16450 +};
16451 +#endif
16452 +
16453 +int gr_check_modstop(void)
16454 +{
16455 +#ifdef CONFIG_GRKERNSEC_MODSTOP
16456 +       if (grsec_modstop == 1) {
16457 +               gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
16458 +               return 1;
16459 +       }
16460 +#endif
16461 +       return 0;
16462 +}
16463 diff -urNp linux-2.6.16.12/grsecurity/grsec_textrel.c linux-2.6.16.12/grsecurity/grsec_textrel.c
16464 --- linux-2.6.16.12/grsecurity/grsec_textrel.c  1969-12-31 19:00:00.000000000 -0500
16465 +++ linux-2.6.16.12/grsecurity/grsec_textrel.c  2006-05-01 20:17:34.000000000 -0400
16466 @@ -0,0 +1,16 @@
16467 +#include <linux/kernel.h>
16468 +#include <linux/sched.h>
16469 +#include <linux/mm.h>
16470 +#include <linux/file.h>
16471 +#include <linux/grinternal.h>
16472 +#include <linux/grsecurity.h>
16473 +
16474 +void
16475 +gr_log_textrel(struct vm_area_struct * vma)
16476 +{
16477 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
16478 +       if (grsec_enable_audit_textrel)
16479 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
16480 +#endif
16481 +       return;
16482 +}
16483 diff -urNp linux-2.6.16.12/grsecurity/grsec_time.c linux-2.6.16.12/grsecurity/grsec_time.c
16484 --- linux-2.6.16.12/grsecurity/grsec_time.c     1969-12-31 19:00:00.000000000 -0500
16485 +++ linux-2.6.16.12/grsecurity/grsec_time.c     2006-05-01 20:17:34.000000000 -0400
16486 @@ -0,0 +1,13 @@
16487 +#include <linux/kernel.h>
16488 +#include <linux/sched.h>
16489 +#include <linux/grinternal.h>
16490 +
16491 +void
16492 +gr_log_timechange(void)
16493 +{
16494 +#ifdef CONFIG_GRKERNSEC_TIME
16495 +       if (grsec_enable_time)
16496 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
16497 +#endif
16498 +       return;
16499 +}
16500 diff -urNp linux-2.6.16.12/grsecurity/grsec_tpe.c linux-2.6.16.12/grsecurity/grsec_tpe.c
16501 --- linux-2.6.16.12/grsecurity/grsec_tpe.c      1969-12-31 19:00:00.000000000 -0500
16502 +++ linux-2.6.16.12/grsecurity/grsec_tpe.c      2006-05-01 20:17:34.000000000 -0400
16503 @@ -0,0 +1,37 @@
16504 +#include <linux/kernel.h>
16505 +#include <linux/sched.h>
16506 +#include <linux/file.h>
16507 +#include <linux/fs.h>
16508 +#include <linux/grinternal.h>
16509 +
16510 +extern int gr_acl_tpe_check(void);
16511 +
16512 +int
16513 +gr_tpe_allow(const struct file *file)
16514 +{
16515 +#ifdef CONFIG_GRKERNSEC
16516 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
16517 +
16518 +       if (current->uid && ((grsec_enable_tpe &&
16519 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
16520 +           !in_group_p(grsec_tpe_gid)
16521 +#else
16522 +           in_group_p(grsec_tpe_gid)
16523 +#endif
16524 +           ) || gr_acl_tpe_check()) &&
16525 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
16526 +                                               (inode->i_mode & S_IWOTH))))) {
16527 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
16528 +               return 0;
16529 +       }
16530 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
16531 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
16532 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
16533 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
16534 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
16535 +               return 0;
16536 +       }
16537 +#endif
16538 +#endif
16539 +       return 1;
16540 +}
16541 diff -urNp linux-2.6.16.12/grsecurity/grsum.c linux-2.6.16.12/grsecurity/grsum.c
16542 --- linux-2.6.16.12/grsecurity/grsum.c  1969-12-31 19:00:00.000000000 -0500
16543 +++ linux-2.6.16.12/grsecurity/grsum.c  2006-05-01 20:17:34.000000000 -0400
16544 @@ -0,0 +1,59 @@
16545 +#include <linux/kernel.h>
16546 +#include <linux/sched.h>
16547 +#include <linux/mm.h>
16548 +#include <asm/scatterlist.h>
16549 +#include <linux/crypto.h>
16550 +#include <linux/gracl.h>
16551 +
16552 +
16553 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
16554 +#error "crypto and sha256 must be built into the kernel"
16555 +#endif
16556 +
16557 +int
16558 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
16559 +{
16560 +       char *p;
16561 +       struct crypto_tfm *tfm;
16562 +       unsigned char temp_sum[GR_SHA_LEN];
16563 +       struct scatterlist sg[2];
16564 +       volatile int retval = 0;
16565 +       volatile int dummy = 0;
16566 +       unsigned int i;
16567 +
16568 +       tfm = crypto_alloc_tfm("sha256", 0);
16569 +       if (tfm == NULL) {
16570 +               /* should never happen, since sha256 should be built in */
16571 +               return 1;
16572 +       }
16573 +
16574 +       crypto_digest_init(tfm);
16575 +
16576 +       p = salt;
16577 +       sg[0].page = virt_to_page(p);
16578 +       sg[0].offset = ((long) p & ~PAGE_MASK);
16579 +       sg[0].length = GR_SALT_LEN;
16580 +       
16581 +       crypto_digest_update(tfm, sg, 1);
16582 +
16583 +       p = entry->pw;
16584 +       sg[0].page = virt_to_page(p);
16585 +       sg[0].offset = ((long) p & ~PAGE_MASK);
16586 +       sg[0].length = strlen(entry->pw);
16587 +
16588 +       crypto_digest_update(tfm, sg, 1);
16589 +
16590 +       crypto_digest_final(tfm, temp_sum);
16591 +
16592 +       memset(entry->pw, 0, GR_PW_LEN);
16593 +
16594 +       for (i = 0; i < GR_SHA_LEN; i++)
16595 +               if (sum[i] != temp_sum[i])
16596 +                       retval = 1;
16597 +               else
16598 +                       dummy = 1;      // waste a cycle
16599 +
16600 +       crypto_free_tfm(tfm);
16601 +
16602 +       return retval;
16603 +}
16604 diff -urNp linux-2.6.16.12/grsecurity/Kconfig linux-2.6.16.12/grsecurity/Kconfig
16605 --- linux-2.6.16.12/grsecurity/Kconfig  1969-12-31 19:00:00.000000000 -0500
16606 +++ linux-2.6.16.12/grsecurity/Kconfig  2006-05-01 20:17:34.000000000 -0400
16607 @@ -0,0 +1,888 @@
16608 +#
16609 +# grecurity configuration
16610 +#
16611 +
16612 +menu "Grsecurity"
16613 +
16614 +config GRKERNSEC
16615 +       bool "Grsecurity"
16616 +       select CRYPTO
16617 +       select CRYPTO_SHA256
16618 +       help
16619 +         If you say Y here, you will be able to configure many features
16620 +         that will enhance the security of your system.  It is highly
16621 +         recommended that you say Y here and read through the help
16622 +         for each option so that you fully understand the features and
16623 +         can evaluate their usefulness for your machine.
16624 +
16625 +choice
16626 +       prompt "Security Level"
16627 +       depends GRKERNSEC
16628 +       default GRKERNSEC_CUSTOM
16629 +
16630 +config GRKERNSEC_LOW
16631 +       bool "Low"
16632 +       select GRKERNSEC_LINK
16633 +       select GRKERNSEC_FIFO
16634 +       select GRKERNSEC_RANDPID
16635 +       select GRKERNSEC_EXECVE
16636 +       select GRKERNSEC_RANDNET
16637 +       select GRKERNSEC_DMESG
16638 +       select GRKERNSEC_CHROOT_CHDIR
16639 +       select GRKERNSEC_MODSTOP if (MODULES)
16640 +
16641 +       help
16642 +         If you choose this option, several of the grsecurity options will
16643 +         be enabled that will give you greater protection against a number
16644 +         of attacks, while assuring that none of your software will have any
16645 +         conflicts with the additional security measures.  If you run a lot
16646 +         of unusual software, or you are having problems with the higher
16647 +         security levels, you should say Y here.  With this option, the
16648 +         following features are enabled:
16649 +
16650 +         - Linking restrictions
16651 +         - FIFO restrictions
16652 +         - Randomized PIDs
16653 +         - Enforcing RLIMIT_NPROC on execve
16654 +         - Restricted dmesg
16655 +         - Enforced chdir("/") on chroot
16656 +         - Runtime module disabling
16657 +
16658 +config GRKERNSEC_MEDIUM
16659 +       bool "Medium"
16660 +       select PAX
16661 +       select PAX_EI_PAX
16662 +       select PAX_PT_PAX_FLAGS
16663 +       select PAX_HAVE_ACL_FLAGS
16664 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
16665 +       select GRKERNSEC_CHROOT_SYSCTL
16666 +       select GRKERNSEC_LINK
16667 +       select GRKERNSEC_FIFO
16668 +       select GRKERNSEC_RANDPID
16669 +       select GRKERNSEC_EXECVE
16670 +       select GRKERNSEC_DMESG
16671 +       select GRKERNSEC_RANDNET
16672 +       select GRKERNSEC_FORKFAIL
16673 +       select GRKERNSEC_TIME
16674 +       select GRKERNSEC_SIGNAL
16675 +       select GRKERNSEC_CHROOT
16676 +       select GRKERNSEC_CHROOT_UNIX
16677 +       select GRKERNSEC_CHROOT_MOUNT
16678 +       select GRKERNSEC_CHROOT_PIVOT
16679 +       select GRKERNSEC_CHROOT_DOUBLE
16680 +       select GRKERNSEC_CHROOT_CHDIR
16681 +       select GRKERNSEC_CHROOT_MKNOD
16682 +       select GRKERNSEC_PROC
16683 +       select GRKERNSEC_PROC_USERGROUP
16684 +       select GRKERNSEC_MODSTOP if (MODULES)
16685 +       select PAX_RANDUSTACK
16686 +       select PAX_ASLR
16687 +       select PAX_RANDMMAP
16688 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
16689 +
16690 +       help
16691 +         If you say Y here, several features in addition to those included
16692 +         in the low additional security level will be enabled.  These
16693 +         features provide even more security to your system, though in rare
16694 +         cases they may be incompatible with very old or poorly written
16695 +         software.  If you enable this option, make sure that your auth
16696 +         service (identd) is running as gid 1001.  With this option, 
16697 +         the following features (in addition to those provided in the 
16698 +         low additional security level) will be enabled:
16699 +
16700 +         - Randomized TCP source ports
16701 +         - Failed fork logging
16702 +         - Time change logging
16703 +         - Signal logging
16704 +         - Deny mounts in chroot
16705 +         - Deny double chrooting
16706 +         - Deny sysctl writes in chroot
16707 +         - Deny mknod in chroot
16708 +         - Deny access to abstract AF_UNIX sockets out of chroot
16709 +         - Deny pivot_root in chroot
16710 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
16711 +         - /proc restrictions with special GID set to 10 (usually wheel)
16712 +         - Address Space Layout Randomization (ASLR)
16713 +
16714 +config GRKERNSEC_HIGH
16715 +       bool "High"
16716 +       select GRKERNSEC_LINK
16717 +       select GRKERNSEC_FIFO
16718 +       select GRKERNSEC_RANDPID
16719 +       select GRKERNSEC_EXECVE
16720 +       select GRKERNSEC_DMESG
16721 +       select GRKERNSEC_FORKFAIL
16722 +       select GRKERNSEC_TIME
16723 +       select GRKERNSEC_SIGNAL
16724 +       select GRKERNSEC_CHROOT_SHMAT
16725 +       select GRKERNSEC_CHROOT_UNIX
16726 +       select GRKERNSEC_CHROOT_MOUNT
16727 +       select GRKERNSEC_CHROOT_FCHDIR
16728 +       select GRKERNSEC_CHROOT_PIVOT
16729 +       select GRKERNSEC_CHROOT_DOUBLE
16730 +       select GRKERNSEC_CHROOT_CHDIR
16731 +       select GRKERNSEC_CHROOT_MKNOD
16732 +       select GRKERNSEC_CHROOT_CAPS
16733 +       select GRKERNSEC_CHROOT_SYSCTL
16734 +       select GRKERNSEC_CHROOT_FINDTASK
16735 +       select GRKERNSEC_PROC
16736 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
16737 +       select GRKERNSEC_HIDESYM
16738 +       select GRKERNSEC_BRUTE
16739 +       select GRKERNSEC_SHM if (SYSVIPC)
16740 +       select GRKERNSEC_PROC_USERGROUP
16741 +       select GRKERNSEC_KMEM
16742 +       select GRKERNSEC_RESLOG
16743 +       select GRKERNSEC_RANDNET
16744 +       select GRKERNSEC_PROC_ADD
16745 +       select GRKERNSEC_CHROOT_CHMOD
16746 +       select GRKERNSEC_CHROOT_NICE
16747 +       select GRKERNSEC_AUDIT_MOUNT
16748 +       select GRKERNSEC_MODSTOP if (MODULES)
16749 +       select PAX
16750 +       select PAX_RANDUSTACK
16751 +       select PAX_ASLR
16752 +       select PAX_RANDMMAP
16753 +       select PAX_NOEXEC
16754 +       select PAX_MPROTECT
16755 +       select PAX_EI_PAX
16756 +       select PAX_PT_PAX_FLAGS
16757 +       select PAX_HAVE_ACL_FLAGS
16758 +       select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
16759 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
16760 +       select PAX_SEGMEXEC if (X86 && !X86_64)
16761 +       select PAX_PAGEEXEC if (!X86)
16762 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
16763 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
16764 +       select PAX_SYSCALL if (PPC32)
16765 +       select PAX_EMUTRAMP if (PARISC)
16766 +       select PAX_EMUSIGRT if (PARISC)
16767 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
16768 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
16769 +       help
16770 +         If you say Y here, many of the features of grsecurity will be
16771 +         enabled, which will protect you against many kinds of attacks
16772 +         against your system.  The heightened security comes at a cost
16773 +         of an increased chance of incompatibilities with rare software
16774 +         on your machine.  Since this security level enables PaX, you should
16775 +         view <http://pax.grsecurity.net> and read about the PaX
16776 +         project.  While you are there, download chpax and run it on
16777 +         binaries that cause problems with PaX.  Also remember that
16778 +         since the /proc restrictions are enabled, you must run your
16779 +         identd as gid 1001.  This security level enables the following 
16780 +         features in addition to those listed in the low and medium 
16781 +         security levels:
16782 +
16783 +         - Additional /proc restrictions
16784 +         - Chmod restrictions in chroot
16785 +         - No signals, ptrace, or viewing of processes outside of chroot
16786 +         - Capability restrictions in chroot
16787 +         - Deny fchdir out of chroot
16788 +         - Priority restrictions in chroot
16789 +         - Segmentation-based implementation of PaX
16790 +         - Mprotect restrictions
16791 +         - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
16792 +         - Kernel stack randomization
16793 +         - Mount/unmount/remount logging
16794 +         - Kernel symbol hiding
16795 +         - Destroy unused shared memory        
16796 +         - Prevention of memory exhaustion-based exploits
16797 +config GRKERNSEC_CUSTOM
16798 +       bool "Custom"
16799 +       help
16800 +         If you say Y here, you will be able to configure every grsecurity
16801 +         option, which allows you to enable many more features that aren't
16802 +         covered in the basic security levels.  These additional features
16803 +         include TPE, socket restrictions, and the sysctl system for
16804 +         grsecurity.  It is advised that you read through the help for
16805 +         each option to determine its usefulness in your situation.
16806 +
16807 +endchoice
16808 +
16809 +menu "Address Space Protection"
16810 +depends on GRKERNSEC
16811 +
16812 +config GRKERNSEC_KMEM
16813 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
16814 +       help
16815 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
16816 +         be written to via mmap or otherwise to modify the running kernel.
16817 +         /dev/port will also not be allowed to be opened. If you have module
16818 +         support disabled, enabling this will close up four ways that are
16819 +         currently used  to insert malicious code into the running kernel.
16820 +         Even with all these features enabled, we still highly recommend that
16821 +         you use the RBAC system, as it is still possible for an attacker to
16822 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
16823 +         If you are not using XFree86, you may be able to stop this additional
16824 +         case by enabling the 'Disable privileged I/O' option. Though nothing
16825 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
16826 +         but only to video memory, which is the only writing we allow in this
16827 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
16828 +         not be allowed to mprotect it with PROT_WRITE later.
16829 +         It is highly recommended that you say Y here if you meet all the
16830 +         conditions above.
16831 +
16832 +config GRKERNSEC_IO
16833 +       bool "Disable privileged I/O"
16834 +       depends on X86
16835 +       select RTC
16836 +       help
16837 +         If you say Y here, all ioperm and iopl calls will return an error.
16838 +         Ioperm and iopl can be used to modify the running kernel.
16839 +         Unfortunately, some programs need this access to operate properly,
16840 +         the most notable of which are XFree86 and hwclock.  hwclock can be
16841 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
16842 +         enabled if this option is enabled, to ensure that hwclock operates
16843 +         correctly.  XFree86 still will not operate correctly with this option
16844 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
16845 +         and you still want to protect your kernel against modification,
16846 +         use the RBAC system.
16847 +
16848 +config GRKERNSEC_PROC_MEMMAP
16849 +       bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
16850 +       depends on PAX_NOEXEC || PAX_ASLR
16851 +       help
16852 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
16853 +         give no information about the addresses of its mappings if
16854 +         PaX features that rely on random addresses are enabled on the task.
16855 +         If you use PaX it is greatly recommended that you say Y here as it
16856 +         closes up a hole that makes the full ASLR useless for suid
16857 +         binaries.
16858 +
16859 +config GRKERNSEC_BRUTE
16860 +       bool "Deter exploit bruteforcing"
16861 +       help
16862 +         If you say Y here, attempts to bruteforce exploits against forking
16863 +         daemons such as apache or sshd will be deterred.  When a child of a
16864 +         forking daemon is killed by PaX or crashes due to an illegal
16865 +         instruction, the parent process will be delayed 30 seconds upon every
16866 +         subsequent fork until the administrator is able to assess the
16867 +         situation and restart the daemon.  It is recommended that you also
16868 +         enable signal logging in the auditing section so that logs are
16869 +         generated when a process performs an illegal instruction.
16870 +
16871 +config GRKERNSEC_MODSTOP
16872 +       bool "Runtime module disabling"
16873 +       depends on MODULES
16874 +       help
16875 +         If you say Y here, you will be able to disable the ability to (un)load
16876 +         modules at runtime.  This feature is useful if you need the ability
16877 +         to load kernel modules at boot time, but do not want to allow an
16878 +         attacker to load a rootkit kernel module into the system, or to remove
16879 +         a loaded kernel module important to system functioning.  You should
16880 +         enable the /dev/mem protection feature as well, since rootkits can be
16881 +         inserted into the kernel via other methods than kernel modules.  Since
16882 +         an untrusted module could still be loaded by modifying init scripts and
16883 +         rebooting the system, it is also recommended that you enable the RBAC
16884 +         system.  If you enable this option, a sysctl option with name
16885 +         "disable_modules" will be created.  Setting this option to "1" disables
16886 +         module loading.  After this option is set, no further writes to it are
16887 +         allowed until the system is rebooted.
16888 +
16889 +config GRKERNSEC_HIDESYM
16890 +       bool "Hide kernel symbols"
16891 +       help
16892 +         If you say Y here, getting information on loaded modules, and
16893 +         displaying all kernel symbols through a syscall will be restricted
16894 +         to users with CAP_SYS_MODULE.  This option is only effective
16895 +         provided the following conditions are met:
16896 +         1) The kernel using grsecurity is not precompiled by some distribution
16897 +         2) You are using the RBAC system and hiding other files such as your
16898 +            kernel image and System.map
16899 +         3) You have the additional /proc restrictions enabled, which removes
16900 +            /proc/kcore
16901 +         If the above conditions are met, this option will aid to provide a
16902 +         useful protection against local and remote kernel exploitation of
16903 +         overflows and arbitrary read/write vulnerabilities.
16904 +
16905 +endmenu
16906 +menu "Role Based Access Control Options"
16907 +depends on GRKERNSEC
16908 +
16909 +config GRKERNSEC_ACL_HIDEKERN
16910 +       bool "Hide kernel processes"
16911 +       help
16912 +         If you say Y here, all kernel threads will be hidden to all
16913 +         processes but those whose subject has the "view hidden processes"
16914 +         flag.
16915 +
16916 +config GRKERNSEC_ACL_MAXTRIES
16917 +       int "Maximum tries before password lockout"
16918 +       default 3
16919 +       help
16920 +         This option enforces the maximum number of times a user can attempt
16921 +         to authorize themselves with the grsecurity RBAC system before being
16922 +         denied the ability to attempt authorization again for a specified time.
16923 +         The lower the number, the harder it will be to brute-force a password.
16924 +
16925 +config GRKERNSEC_ACL_TIMEOUT
16926 +       int "Time to wait after max password tries, in seconds"
16927 +       default 30
16928 +       help
16929 +         This option specifies the time the user must wait after attempting to
16930 +         authorize to the RBAC system with the maximum number of invalid
16931 +         passwords.  The higher the number, the harder it will be to brute-force
16932 +         a password.
16933 +
16934 +endmenu
16935 +menu "Filesystem Protections"
16936 +depends on GRKERNSEC
16937 +
16938 +config GRKERNSEC_PROC
16939 +       bool "Proc restrictions"
16940 +       help
16941 +         If you say Y here, the permissions of the /proc filesystem
16942 +         will be altered to enhance system security and privacy.  You MUST
16943 +         choose either a user only restriction or a user and group restriction.
16944 +         Depending upon the option you choose, you can either restrict users to
16945 +         see only the processes they themselves run, or choose a group that can
16946 +         view all processes and files normally restricted to root if you choose
16947 +         the "restrict to user only" option.  NOTE: If you're running identd as
16948 +         a non-root user, you will have to run it as the group you specify here.
16949 +
16950 +config GRKERNSEC_PROC_USER
16951 +       bool "Restrict /proc to user only"
16952 +       depends on GRKERNSEC_PROC
16953 +       help
16954 +         If you say Y here, non-root users will only be able to view their own
16955 +         processes, and restricts them from viewing network-related information,
16956 +         and viewing kernel symbol and module information.
16957 +
16958 +config GRKERNSEC_PROC_USERGROUP
16959 +       bool "Allow special group"
16960 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
16961 +       help
16962 +         If you say Y here, you will be able to select a group that will be
16963 +         able to view all processes, network-related information, and
16964 +         kernel and symbol information.  This option is useful if you want
16965 +         to run identd as a non-root user.
16966 +
16967 +config GRKERNSEC_PROC_GID
16968 +       int "GID for special group"
16969 +       depends on GRKERNSEC_PROC_USERGROUP
16970 +       default 1001
16971 +
16972 +config GRKERNSEC_PROC_ADD
16973 +       bool "Additional restrictions"
16974 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
16975 +       help
16976 +         If you say Y here, additional restrictions will be placed on
16977 +         /proc that keep normal users from viewing device information and 
16978 +         slabinfo information that could be useful for exploits.
16979 +
16980 +config GRKERNSEC_LINK
16981 +       bool "Linking restrictions"
16982 +       help
16983 +         If you say Y here, /tmp race exploits will be prevented, since users
16984 +         will no longer be able to follow symlinks owned by other users in
16985 +         world-writable +t directories (i.e. /tmp), unless the owner of the
16986 +         symlink is the owner of the directory. users will also not be
16987 +         able to hardlink to files they do not own.  If the sysctl option is
16988 +         enabled, a sysctl option with name "linking_restrictions" is created.
16989 +
16990 +config GRKERNSEC_FIFO
16991 +       bool "FIFO restrictions"
16992 +       help
16993 +         If you say Y here, users will not be able to write to FIFOs they don't
16994 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
16995 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
16996 +         option is enabled, a sysctl option with name "fifo_restrictions" is
16997 +         created.
16998 +
16999 +config GRKERNSEC_CHROOT
17000 +       bool "Chroot jail restrictions"
17001 +       help
17002 +         If you say Y here, you will be able to choose several options that will
17003 +         make breaking out of a chrooted jail much more difficult.  If you
17004 +         encounter no software incompatibilities with the following options, it
17005 +         is recommended that you enable each one.
17006 +
17007 +config GRKERNSEC_CHROOT_MOUNT
17008 +       bool "Deny mounts"
17009 +       depends on GRKERNSEC_CHROOT
17010 +       help
17011 +         If you say Y here, processes inside a chroot will not be able to
17012 +         mount or remount filesystems.  If the sysctl option is enabled, a
17013 +         sysctl option with name "chroot_deny_mount" is created.
17014 +
17015 +config GRKERNSEC_CHROOT_DOUBLE
17016 +       bool "Deny double-chroots"
17017 +       depends on GRKERNSEC_CHROOT
17018 +       help
17019 +         If you say Y here, processes inside a chroot will not be able to chroot
17020 +         again outside the chroot.  This is a widely used method of breaking
17021 +         out of a chroot jail and should not be allowed.  If the sysctl 
17022 +         option is enabled, a sysctl option with name 
17023 +         "chroot_deny_chroot" is created.
17024 +
17025 +config GRKERNSEC_CHROOT_PIVOT
17026 +       bool "Deny pivot_root in chroot"
17027 +       depends on GRKERNSEC_CHROOT
17028 +       help
17029 +         If you say Y here, processes inside a chroot will not be able to use
17030 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
17031 +         works similar to chroot in that it changes the root filesystem.  This
17032 +         function could be misused in a chrooted process to attempt to break out
17033 +         of the chroot, and therefore should not be allowed.  If the sysctl
17034 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
17035 +         created.
17036 +
17037 +config GRKERNSEC_CHROOT_CHDIR
17038 +       bool "Enforce chdir(\"/\") on all chroots"
17039 +       depends on GRKERNSEC_CHROOT
17040 +       help
17041 +         If you say Y here, the current working directory of all newly-chrooted
17042 +         applications will be set to the the root directory of the chroot.
17043 +         The man page on chroot(2) states:
17044 +         Note that this call does not change  the  current  working
17045 +         directory,  so  that `.' can be outside the tree rooted at
17046 +         `/'.  In particular, the  super-user  can  escape  from  a
17047 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
17048 +
17049 +         It is recommended that you say Y here, since it's not known to break
17050 +         any software.  If the sysctl option is enabled, a sysctl option with
17051 +         name "chroot_enforce_chdir" is created.
17052 +
17053 +config GRKERNSEC_CHROOT_CHMOD
17054 +       bool "Deny (f)chmod +s"
17055 +       depends on GRKERNSEC_CHROOT
17056 +       help
17057 +         If you say Y here, processes inside a chroot will not be able to chmod
17058 +         or fchmod files to make them have suid or sgid bits.  This protects
17059 +         against another published method of breaking a chroot.  If the sysctl
17060 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
17061 +         created.
17062 +
17063 +config GRKERNSEC_CHROOT_FCHDIR
17064 +       bool "Deny fchdir out of chroot"
17065 +       depends on GRKERNSEC_CHROOT
17066 +       help
17067 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
17068 +         to a file descriptor of the chrooting process that points to a directory
17069 +         outside the filesystem will be stopped.  If the sysctl option
17070 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
17071 +
17072 +config GRKERNSEC_CHROOT_MKNOD
17073 +       bool "Deny mknod"
17074 +       depends on GRKERNSEC_CHROOT
17075 +       help
17076 +         If you say Y here, processes inside a chroot will not be allowed to
17077 +         mknod.  The problem with using mknod inside a chroot is that it
17078 +         would allow an attacker to create a device entry that is the same
17079 +         as one on the physical root of your system, which could range from
17080 +         anything from the console device to a device for your harddrive (which
17081 +         they could then use to wipe the drive or steal data).  It is recommended
17082 +         that you say Y here, unless you run into software incompatibilities.
17083 +         If the sysctl option is enabled, a sysctl option with name
17084 +         "chroot_deny_mknod" is created.
17085 +
17086 +config GRKERNSEC_CHROOT_SHMAT
17087 +       bool "Deny shmat() out of chroot"
17088 +       depends on GRKERNSEC_CHROOT
17089 +       help
17090 +         If you say Y here, processes inside a chroot will not be able to attach
17091 +         to shared memory segments that were created outside of the chroot jail.
17092 +         It is recommended that you say Y here.  If the sysctl option is enabled,
17093 +         a sysctl option with name "chroot_deny_shmat" is created.
17094 +
17095 +config GRKERNSEC_CHROOT_UNIX
17096 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
17097 +       depends on GRKERNSEC_CHROOT
17098 +       help
17099 +         If you say Y here, processes inside a chroot will not be able to
17100 +         connect to abstract (meaning not belonging to a filesystem) Unix
17101 +         domain sockets that were bound outside of a chroot.  It is recommended
17102 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
17103 +         with name "chroot_deny_unix" is created.
17104 +
17105 +config GRKERNSEC_CHROOT_FINDTASK
17106 +       bool "Protect outside processes"
17107 +       depends on GRKERNSEC_CHROOT
17108 +       help
17109 +         If you say Y here, processes inside a chroot will not be able to
17110 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
17111 +         getsid, or view any process outside of the chroot.  If the sysctl
17112 +         option is enabled, a sysctl option with name "chroot_findtask" is
17113 +         created.
17114 +
17115 +config GRKERNSEC_CHROOT_NICE
17116 +       bool "Restrict priority changes"
17117 +       depends on GRKERNSEC_CHROOT
17118 +       help
17119 +         If you say Y here, processes inside a chroot will not be able to raise
17120 +         the priority of processes in the chroot, or alter the priority of
17121 +         processes outside the chroot.  This provides more security than simply
17122 +         removing CAP_SYS_NICE from the process' capability set.  If the
17123 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
17124 +         is created.
17125 +
17126 +config GRKERNSEC_CHROOT_SYSCTL
17127 +       bool "Deny sysctl writes"
17128 +       depends on GRKERNSEC_CHROOT
17129 +       help
17130 +         If you say Y here, an attacker in a chroot will not be able to
17131 +         write to sysctl entries, either by sysctl(2) or through a /proc
17132 +         interface.  It is strongly recommended that you say Y here. If the
17133 +         sysctl option is enabled, a sysctl option with name
17134 +         "chroot_deny_sysctl" is created.
17135 +
17136 +config GRKERNSEC_CHROOT_CAPS
17137 +       bool "Capability restrictions"
17138 +       depends on GRKERNSEC_CHROOT
17139 +       help
17140 +         If you say Y here, the capabilities on all root processes within a
17141 +         chroot jail will be lowered to stop module insertion, raw i/o,
17142 +         system and net admin tasks, rebooting the system, modifying immutable
17143 +         files, modifying IPC owned by another, and changing the system time.
17144 +         This is left an option because it can break some apps.  Disable this
17145 +         if your chrooted apps are having problems performing those kinds of
17146 +         tasks.  If the sysctl option is enabled, a sysctl option with
17147 +         name "chroot_caps" is created.
17148 +
17149 +endmenu
17150 +menu "Kernel Auditing"
17151 +depends on GRKERNSEC
17152 +
17153 +config GRKERNSEC_AUDIT_GROUP
17154 +       bool "Single group for auditing"
17155 +       help
17156 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
17157 +         will only operate on a group you specify.  This option is recommended
17158 +         if you only want to watch certain users instead of having a large
17159 +         amount of logs from the entire system.  If the sysctl option is enabled,
17160 +         a sysctl option with name "audit_group" is created.
17161 +
17162 +config GRKERNSEC_AUDIT_GID
17163 +       int "GID for auditing"
17164 +       depends on GRKERNSEC_AUDIT_GROUP
17165 +       default 1007
17166 +
17167 +config GRKERNSEC_EXECLOG
17168 +       bool "Exec logging"
17169 +       help
17170 +         If you say Y here, all execve() calls will be logged (since the
17171 +         other exec*() calls are frontends to execve(), all execution
17172 +         will be logged).  Useful for shell-servers that like to keep track
17173 +         of their users.  If the sysctl option is enabled, a sysctl option with
17174 +         name "exec_logging" is created.
17175 +         WARNING: This option when enabled will produce a LOT of logs, especially
17176 +         on an active system.
17177 +
17178 +config GRKERNSEC_RESLOG
17179 +       bool "Resource logging"
17180 +       help
17181 +         If you say Y here, all attempts to overstep resource limits will
17182 +         be logged with the resource name, the requested size, and the current
17183 +         limit.  It is highly recommended that you say Y here.
17184 +
17185 +config GRKERNSEC_CHROOT_EXECLOG
17186 +       bool "Log execs within chroot"
17187 +       help
17188 +         If you say Y here, all executions inside a chroot jail will be logged
17189 +         to syslog.  This can cause a large amount of logs if certain
17190 +         applications (eg. djb's daemontools) are installed on the system, and
17191 +         is therefore left as an option.  If the sysctl option is enabled, a
17192 +         sysctl option with name "chroot_execlog" is created.
17193 +
17194 +config GRKERNSEC_AUDIT_CHDIR
17195 +       bool "Chdir logging"
17196 +       help
17197 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
17198 +         option is enabled, a sysctl option with name "audit_chdir" is created.
17199 +
17200 +config GRKERNSEC_AUDIT_MOUNT
17201 +       bool "(Un)Mount logging"
17202 +       help
17203 +         If you say Y here, all mounts and unmounts will be logged.  If the
17204 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
17205 +         created.
17206 +
17207 +config GRKERNSEC_AUDIT_IPC
17208 +       bool "IPC logging"
17209 +       help
17210 +         If you say Y here, creation and removal of message queues, semaphores,
17211 +         and shared memory will be logged.  If the sysctl option is enabled, a
17212 +         sysctl option with name "audit_ipc" is created.
17213 +
17214 +config GRKERNSEC_SIGNAL
17215 +       bool "Signal logging"
17216 +       help
17217 +         If you say Y here, certain important signals will be logged, such as
17218 +         SIGSEGV, which will as a result inform you of when a error in a program
17219 +         occurred, which in some cases could mean a possible exploit attempt.
17220 +         If the sysctl option is enabled, a sysctl option with name
17221 +         "signal_logging" is created.
17222 +
17223 +config GRKERNSEC_FORKFAIL
17224 +       bool "Fork failure logging"
17225 +       help
17226 +         If you say Y here, all failed fork() attempts will be logged.
17227 +         This could suggest a fork bomb, or someone attempting to overstep
17228 +         their process limit.  If the sysctl option is enabled, a sysctl option
17229 +         with name "forkfail_logging" is created.
17230 +
17231 +config GRKERNSEC_TIME
17232 +       bool "Time change logging"
17233 +       help
17234 +         If you say Y here, any changes of the system clock will be logged.
17235 +         If the sysctl option is enabled, a sysctl option with name
17236 +         "timechange_logging" is created.
17237 +
17238 +config GRKERNSEC_PROC_IPADDR
17239 +       bool "/proc/<pid>/ipaddr support"
17240 +       help
17241 +         If you say Y here, a new entry will be added to each /proc/<pid>
17242 +         directory that contains the IP address of the person using the task.
17243 +         The IP is carried across local TCP and AF_UNIX stream sockets.
17244 +         This information can be useful for IDS/IPSes to perform remote response
17245 +         to a local attack.  The entry is readable by only the owner of the
17246 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
17247 +         the RBAC system), and thus does not create privacy concerns.
17248 +
17249 +config GRKERNSEC_AUDIT_TEXTREL
17250 +       bool 'ELF text relocations logging (READ HELP)'
17251 +       depends on PAX_MPROTECT
17252 +       help
17253 +         If you say Y here, text relocations will be logged with the filename
17254 +         of the offending library or binary.  The purpose of the feature is
17255 +         to help Linux distribution developers get rid of libraries and
17256 +         binaries that need text relocations which hinder the future progress
17257 +         of PaX.  Only Linux distribution developers should say Y here, and
17258 +         never on a production machine, as this option creates an information
17259 +         leak that could aid an attacker in defeating the randomization of
17260 +         a single memory region.  If the sysctl option is enabled, a sysctl
17261 +         option with name "audit_textrel" is created.
17262 +
17263 +endmenu
17264 +
17265 +menu "Executable Protections"
17266 +depends on GRKERNSEC
17267 +
17268 +config GRKERNSEC_EXECVE
17269 +       bool "Enforce RLIMIT_NPROC on execs"
17270 +       help
17271 +         If you say Y here, users with a resource limit on processes will
17272 +         have the value checked during execve() calls.  The current system
17273 +         only checks the system limit during fork() calls.  If the sysctl option
17274 +         is enabled, a sysctl option with name "execve_limiting" is created.
17275 +
17276 +config GRKERNSEC_SHM
17277 +       bool "Destroy unused shared memory"
17278 +       depends on SYSVIPC
17279 +       help
17280 +         If you say Y here, shared memory will be destroyed when no one is
17281 +         attached to it.  Otherwise, resources involved with the shared
17282 +         memory can be used up and not be associated with any process (as the
17283 +         shared memory still exists, and the creating process has exited).  If
17284 +         the sysctl option is enabled, a sysctl option with name
17285 +         "destroy_unused_shm" is created.
17286 +
17287 +config GRKERNSEC_DMESG
17288 +       bool "Dmesg(8) restriction"
17289 +       help
17290 +         If you say Y here, non-root users will not be able to use dmesg(8)
17291 +         to view up to the last 4kb of messages in the kernel's log buffer.
17292 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
17293 +         created.
17294 +
17295 +config GRKERNSEC_RANDPID
17296 +       bool "Randomized PIDs"
17297 +       help
17298 +         If you say Y here, all PIDs created on the system will be
17299 +         pseudo-randomly generated.  This is extremely effective along
17300 +         with the /proc restrictions to disallow an attacker from guessing
17301 +         pids of daemons, etc.  PIDs are also used in some cases as part
17302 +         of a naming system for temporary files, so this option would keep
17303 +         those filenames from being predicted as well.  We also use code
17304 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
17305 +         option is enabled, a sysctl option with name "rand_pids" is created.
17306 +
17307 +config GRKERNSEC_TPE
17308 +       bool "Trusted Path Execution (TPE)"
17309 +       help
17310 +         If you say Y here, you will be able to choose a gid to add to the
17311 +         supplementary groups of users you want to mark as "untrusted."
17312 +         These users will not be able to execute any files that are not in
17313 +         root-owned directories writable only by root.  If the sysctl option
17314 +         is enabled, a sysctl option with name "tpe" is created.
17315 +
17316 +config GRKERNSEC_TPE_ALL
17317 +       bool "Partially restrict non-root users"
17318 +       depends on GRKERNSEC_TPE
17319 +       help
17320 +         If you say Y here, All non-root users other than the ones in the
17321 +         group specified in the main TPE option will only be allowed to
17322 +         execute files in directories they own that are not group or
17323 +         world-writable, or in directories owned by root and writable only by
17324 +         root.  If the sysctl option is enabled, a sysctl option with name
17325 +         "tpe_restrict_all" is created.
17326 +
17327 +config GRKERNSEC_TPE_INVERT
17328 +       bool "Invert GID option"
17329 +       depends on GRKERNSEC_TPE
17330 +       help
17331 +         If you say Y here, the group you specify in the TPE configuration will
17332 +         decide what group TPE restrictions will be *disabled* for.  This
17333 +         option is useful if you want TPE restrictions to be applied to most
17334 +         users on the system.
17335 +
17336 +config GRKERNSEC_TPE_GID
17337 +       int "GID for untrusted users"
17338 +       depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
17339 +       default 1005
17340 +       help
17341 +         If you have selected the "Invert GID option" above, setting this
17342 +         GID determines what group TPE restrictions will be *disabled* for.
17343 +         If you have not selected the "Invert GID option" above, setting this
17344 +         GID determines what group TPE restrictions will be *enabled* for.
17345 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
17346 +         is created.
17347 +
17348 +config GRKERNSEC_TPE_GID
17349 +       int "GID for trusted users"
17350 +       depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
17351 +       default 1005
17352 +       help
17353 +         If you have selected the "Invert GID option" above, setting this
17354 +         GID determines what group TPE restrictions will be *disabled* for.
17355 +         If you have not selected the "Invert GID option" above, setting this
17356 +         GID determines what group TPE restrictions will be *enabled* for.
17357 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
17358 +         is created.
17359 +
17360 +endmenu
17361 +menu "Network Protections"
17362 +depends on GRKERNSEC
17363 +
17364 +config GRKERNSEC_RANDNET
17365 +       bool "Larger entropy pools"
17366 +       help
17367 +         If you say Y here, the entropy pools used for many features of Linux
17368 +         and grsecurity will be doubled in size.  Since several grsecurity
17369 +         features use additional randomness, it is recommended that you say Y
17370 +         here.  Saying Y here has a similar effect as modifying
17371 +         /proc/sys/kernel/random/poolsize.
17372 +
17373 +config GRKERNSEC_SOCKET
17374 +       bool "Socket restrictions"
17375 +       help
17376 +         If you say Y here, you will be able to choose from several options.
17377 +         If you assign a GID on your system and add it to the supplementary
17378 +         groups of users you want to restrict socket access to, this patch
17379 +         will perform up to three things, based on the option(s) you choose.
17380 +
17381 +config GRKERNSEC_SOCKET_ALL
17382 +       bool "Deny any sockets to group"
17383 +       depends on GRKERNSEC_SOCKET
17384 +       help
17385 +         If you say Y here, you will be able to choose a GID of whose users will
17386 +         be unable to connect to other hosts from your machine or run server
17387 +         applications from your machine.  If the sysctl option is enabled, a
17388 +         sysctl option with name "socket_all" is created.
17389 +
17390 +config GRKERNSEC_SOCKET_ALL_GID
17391 +       int "GID to deny all sockets for"
17392 +       depends on GRKERNSEC_SOCKET_ALL
17393 +       default 1004
17394 +       help
17395 +         Here you can choose the GID to disable socket access for. Remember to
17396 +         add the users you want socket access disabled for to the GID
17397 +         specified here.  If the sysctl option is enabled, a sysctl option
17398 +         with name "socket_all_gid" is created.
17399 +
17400 +config GRKERNSEC_SOCKET_CLIENT
17401 +       bool "Deny client sockets to group"
17402 +       depends on GRKERNSEC_SOCKET
17403 +       help
17404 +         If you say Y here, you will be able to choose a GID of whose users will
17405 +         be unable to connect to other hosts from your machine, but will be
17406 +         able to run servers.  If this option is enabled, all users in the group
17407 +         you specify will have to use passive mode when initiating ftp transfers
17408 +         from the shell on your machine.  If the sysctl option is enabled, a
17409 +         sysctl option with name "socket_client" is created.
17410 +
17411 +config GRKERNSEC_SOCKET_CLIENT_GID
17412 +       int "GID to deny client sockets for"
17413 +       depends on GRKERNSEC_SOCKET_CLIENT
17414 +       default 1003
17415 +       help
17416 +         Here you can choose the GID to disable client socket access for.
17417 +         Remember to add the users you want client socket access disabled for to
17418 +         the GID specified here.  If the sysctl option is enabled, a sysctl
17419 +         option with name "socket_client_gid" is created.
17420 +
17421 +config GRKERNSEC_SOCKET_SERVER
17422 +       bool "Deny server sockets to group"
17423 +       depends on GRKERNSEC_SOCKET
17424 +       help
17425 +         If you say Y here, you will be able to choose a GID of whose users will
17426 +         be unable to run server applications from your machine.  If the sysctl
17427 +         option is enabled, a sysctl option with name "socket_server" is created.
17428 +
17429 +config GRKERNSEC_SOCKET_SERVER_GID
17430 +       int "GID to deny server sockets for"
17431 +       depends on GRKERNSEC_SOCKET_SERVER
17432 +       default 1002
17433 +       help
17434 +         Here you can choose the GID to disable server socket access for.
17435 +         Remember to add the users you want server socket access disabled for to
17436 +         the GID specified here.  If the sysctl option is enabled, a sysctl
17437 +         option with name "socket_server_gid" is created.
17438 +
17439 +endmenu
17440 +menu "Sysctl support"
17441 +depends on GRKERNSEC && SYSCTL
17442 +
17443 +config GRKERNSEC_SYSCTL
17444 +       bool "Sysctl support"
17445 +       help
17446 +         If you say Y here, you will be able to change the options that
17447 +         grsecurity runs with at bootup, without having to recompile your
17448 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
17449 +         to enable (1) or disable (0) various features.  All the sysctl entries
17450 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
17451 +         All features enabled in the kernel configuration are disabled at boot
17452 +         if you do not say Y to the "Turn on features by default" option.
17453 +         All options should be set at startup, and the grsec_lock entry should
17454 +         be set to a non-zero value after all the options are set.
17455 +         *THIS IS EXTREMELY IMPORTANT*
17456 +
17457 +config GRKERNSEC_SYSCTL_ON
17458 +       bool "Turn on features by default"
17459 +       depends on GRKERNSEC_SYSCTL
17460 +       help
17461 +         If you say Y here, instead of having all features enabled in the
17462 +         kernel configuration disabled at boot time, the features will be
17463 +         enabled at boot time.  It is recommended you say Y here unless
17464 +         there is some reason you would want all sysctl-tunable features to
17465 +         be disabled by default.  As mentioned elsewhere, it is important
17466 +         to enable the grsec_lock entry once you have finished modifying
17467 +         the sysctl entries.
17468 +
17469 +endmenu
17470 +menu "Logging Options"
17471 +depends on GRKERNSEC
17472 +
17473 +config GRKERNSEC_FLOODTIME
17474 +       int "Seconds in between log messages (minimum)"
17475 +       default 10
17476 +       help
17477 +         This option allows you to enforce the number of seconds between
17478 +         grsecurity log messages.  The default should be suitable for most
17479 +         people, however, if you choose to change it, choose a value small enough
17480 +         to allow informative logs to be produced, but large enough to
17481 +         prevent flooding.
17482 +
17483 +config GRKERNSEC_FLOODBURST
17484 +       int "Number of messages in a burst (maximum)"
17485 +       default 4
17486 +       help
17487 +         This option allows you to choose the maximum number of messages allowed
17488 +         within the flood time interval you chose in a separate option.  The
17489 +         default should be suitable for most people, however if you find that
17490 +         many of your logs are being interpreted as flooding, you may want to
17491 +         raise this value.
17492 +
17493 +endmenu
17494 +
17495 +endmenu
17496 diff -urNp linux-2.6.16.12/grsecurity/Makefile linux-2.6.16.12/grsecurity/Makefile
17497 --- linux-2.6.16.12/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
17498 +++ linux-2.6.16.12/grsecurity/Makefile 2006-05-01 20:17:34.000000000 -0400
17499 @@ -0,0 +1,20 @@
17500 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
17501 +# during 2001-2005 it has been completely redesigned by Brad Spengler
17502 +# into an RBAC system
17503 +#
17504 +# All code in this directory and various hooks inserted throughout the kernel
17505 +# are copyright Brad Spengler, and released under the GPL v2 or higher
17506 +
17507 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
17508 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
17509 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
17510 +
17511 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
17512 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
17513 +       gracl_learn.o grsec_log.o
17514 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
17515 +
17516 +ifndef CONFIG_GRKERNSEC
17517 +obj-y += grsec_disabled.o
17518 +endif
17519 +
17520 diff -urNp linux-2.6.16.12/include/asm-alpha/a.out.h linux-2.6.16.12/include/asm-alpha/a.out.h
17521 --- linux-2.6.16.12/include/asm-alpha/a.out.h   2006-05-01 15:14:26.000000000 -0400
17522 +++ linux-2.6.16.12/include/asm-alpha/a.out.h   2006-05-01 20:17:34.000000000 -0400
17523 @@ -98,7 +98,7 @@ struct exec
17524         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
17525                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
17526  
17527 -#define STACK_TOP \
17528 +#define __STACK_TOP \
17529    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
17530  
17531  #endif
17532 diff -urNp linux-2.6.16.12/include/asm-alpha/elf.h linux-2.6.16.12/include/asm-alpha/elf.h
17533 --- linux-2.6.16.12/include/asm-alpha/elf.h     2006-05-01 15:14:26.000000000 -0400
17534 +++ linux-2.6.16.12/include/asm-alpha/elf.h     2006-05-01 20:17:34.000000000 -0400
17535 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
17536  
17537  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
17538  
17539 +#ifdef CONFIG_PAX_ASLR
17540 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
17541 +
17542 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17543 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
17544 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17545 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
17546 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17547 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
17548 +#endif
17549 +
17550  /* $0 is set by ld.so to a pointer to a function which might be 
17551     registered using atexit.  This provides a mean for the dynamic
17552     linker to call DT_FINI functions for shared libraries that have
17553 diff -urNp linux-2.6.16.12/include/asm-alpha/page.h linux-2.6.16.12/include/asm-alpha/page.h
17554 --- linux-2.6.16.12/include/asm-alpha/page.h    2006-05-01 15:14:26.000000000 -0400
17555 +++ linux-2.6.16.12/include/asm-alpha/page.h    2006-05-01 20:17:34.000000000 -0400
17556 @@ -98,6 +98,15 @@ typedef unsigned long pgprot_t;
17557  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
17558                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17559  
17560 +#ifdef CONFIG_PAX_PAGEEXEC
17561 +#ifdef CONFIG_PAX_MPROTECT
17562 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17563 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17564 +#else
17565 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17566 +#endif
17567 +#endif
17568 +
17569  #endif /* __KERNEL__ */
17570  
17571  #include <asm-generic/page.h>
17572 diff -urNp linux-2.6.16.12/include/asm-alpha/pgtable.h linux-2.6.16.12/include/asm-alpha/pgtable.h
17573 --- linux-2.6.16.12/include/asm-alpha/pgtable.h 2006-05-01 15:14:26.000000000 -0400
17574 +++ linux-2.6.16.12/include/asm-alpha/pgtable.h 2006-05-01 20:17:34.000000000 -0400
17575 @@ -102,6 +102,17 @@ struct vm_area_struct;
17576  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
17577  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
17578  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
17579 +
17580 +#ifdef CONFIG_PAX_PAGEEXEC
17581 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
17582 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
17583 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
17584 +#else
17585 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17586 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17587 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17588 +#endif
17589 +
17590  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
17591  
17592  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
17593 diff -urNp linux-2.6.16.12/include/asm-arm/a.out.h linux-2.6.16.12/include/asm-arm/a.out.h
17594 --- linux-2.6.16.12/include/asm-arm/a.out.h     2006-05-01 15:14:26.000000000 -0400
17595 +++ linux-2.6.16.12/include/asm-arm/a.out.h     2006-05-01 20:17:34.000000000 -0400
17596 @@ -28,7 +28,7 @@ struct exec
17597  #define M_ARM 103
17598  
17599  #ifdef __KERNEL__
17600 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
17601 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
17602                          TASK_SIZE : TASK_SIZE_26)
17603  #endif
17604  
17605 diff -urNp linux-2.6.16.12/include/asm-arm/elf.h linux-2.6.16.12/include/asm-arm/elf.h
17606 --- linux-2.6.16.12/include/asm-arm/elf.h       2006-05-01 15:14:26.000000000 -0400
17607 +++ linux-2.6.16.12/include/asm-arm/elf.h       2006-05-01 20:17:34.000000000 -0400
17608 @@ -56,6 +56,17 @@ typedef struct user_fp elf_fpregset_t;
17609  
17610  #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
17611  
17612 +#ifdef CONFIG_PAX_ASLR
17613 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x00008000UL
17614 +
17615 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17616 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
17617 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17618 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
17619 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17620 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
17621 +#endif
17622 +
17623  /* When the program starts, a1 contains a pointer to a function to be 
17624     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
17625     have no such handler.  */
17626 diff -urNp linux-2.6.16.12/include/asm-i386/a.out.h linux-2.6.16.12/include/asm-i386/a.out.h
17627 --- linux-2.6.16.12/include/asm-i386/a.out.h    2006-05-01 15:14:26.000000000 -0400
17628 +++ linux-2.6.16.12/include/asm-i386/a.out.h    2006-05-01 20:17:34.000000000 -0400
17629 @@ -19,7 +19,11 @@ struct exec
17630  
17631  #ifdef __KERNEL__
17632  
17633 -#define STACK_TOP      TASK_SIZE
17634 +#ifdef CONFIG_PAX_SEGMEXEC
17635 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
17636 +#else
17637 +#define __STACK_TOP TASK_SIZE
17638 +#endif
17639  
17640  #endif
17641  
17642 diff -urNp linux-2.6.16.12/include/asm-i386/auxvec.h linux-2.6.16.12/include/asm-i386/auxvec.h
17643 --- linux-2.6.16.12/include/asm-i386/auxvec.h   2006-05-01 15:14:26.000000000 -0400
17644 +++ linux-2.6.16.12/include/asm-i386/auxvec.h   2006-05-01 20:17:34.000000000 -0400
17645 @@ -5,7 +5,9 @@
17646   * Architecture-neutral AT_ values in 0-17, leave some room
17647   * for more of them, start the x86-specific ones at 32.
17648   */
17649 +#ifndef CONFIG_PAX_NOVSYSCALL
17650  #define AT_SYSINFO             32
17651  #define AT_SYSINFO_EHDR                33
17652 +#endif
17653  
17654  #endif
17655 diff -urNp linux-2.6.16.12/include/asm-i386/desc.h linux-2.6.16.12/include/asm-i386/desc.h
17656 --- linux-2.6.16.12/include/asm-i386/desc.h     2006-05-01 15:14:26.000000000 -0400
17657 +++ linux-2.6.16.12/include/asm-i386/desc.h     2006-05-01 20:17:34.000000000 -0400
17658 @@ -10,11 +10,13 @@
17659  
17660  #include <linux/preempt.h>
17661  #include <linux/smp.h>
17662 -#include <linux/percpu.h>
17663 +#include <linux/sched.h>
17664  
17665  #include <asm/mmu.h>
17666 +#include <asm/pgtable.h>
17667 +#include <asm/tlbflush.h>
17668  
17669 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
17670 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
17671  
17672  DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
17673  
17674 @@ -24,13 +26,53 @@ struct Xgt_desc_struct {
17675         unsigned short pad;
17676  } __attribute__ ((packed));
17677  
17678 -extern struct Xgt_desc_struct idt_descr;
17679 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
17680 -
17681 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
17682  
17683  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
17684  {
17685 -       return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
17686 +       return cpu_gdt_table[cpu];
17687 +}
17688 +
17689 +#define pax_open_kernel(cr0)           \
17690 +do {                                   \
17691 +       typecheck(unsigned long,cr0);   \
17692 +       preempt_disable();              \
17693 +       cr0 = read_cr0();               \
17694 +       write_cr0(cr0 & ~0x10000UL);    \
17695 +} while(0)
17696 +
17697 +#define pax_close_kernel(cr0)          \
17698 +do {                                   \
17699 +       typecheck(unsigned long,cr0);   \
17700 +       write_cr0(cr0);                 \
17701 +       preempt_enable_no_resched();    \
17702 +} while(0)
17703 +
17704 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
17705 +{
17706 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17707 +       unsigned long base = mm->context.user_cs_base;
17708 +       unsigned long limit = mm->context.user_cs_limit;
17709 +
17710 +#ifdef CONFIG_PAX_KERNEXEC
17711 +       unsigned long cr0;
17712 +
17713 +       pax_open_kernel(cr0);
17714 +#endif
17715 +
17716 +       if (likely(limit)) {
17717 +               limit -= 1UL;
17718 +               limit >>= 12;
17719 +       }
17720 +
17721 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
17722 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
17723 +
17724 +#ifdef CONFIG_PAX_KERNEXEC
17725 +       pax_close_kernel(cr0);
17726 +#endif
17727 +
17728 +#endif
17729  }
17730  
17731  #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
17732 @@ -50,7 +92,7 @@ static inline struct desc_struct *get_cp
17733   * This is the ldt that every process will get unless we need
17734   * something other than this.
17735   */
17736 -extern struct desc_struct default_ldt[];
17737 +extern const struct desc_struct default_ldt[];
17738  extern void set_intr_gate(unsigned int irq, void * addr);
17739  
17740  #define _set_tssldt_desc(n,addr,limit,type) \
17741 @@ -64,7 +106,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
17742         "rorl $16,%1" \
17743         : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
17744  
17745 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
17746 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
17747  {
17748         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
17749                 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
17750 @@ -72,11 +114,28 @@ static inline void __set_tss_desc(unsign
17751  
17752  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
17753  
17754 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
17755 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
17756  {
17757         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
17758  }
17759  
17760 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
17761 +{
17762 +
17763 +#ifdef CONFIG_PAX_KERNEXEC
17764 +       unsigned long cr0;
17765 +
17766 +       pax_open_kernel(cr0);
17767 +#endif
17768 +
17769 +       _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
17770 +
17771 +#ifdef CONFIG_PAX_KERNEXEC
17772 +       pax_close_kernel(cr0);
17773 +#endif
17774 +
17775 +}
17776 +
17777  #define LDT_entry_a(info) \
17778         ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
17779  
17780 @@ -90,7 +149,7 @@ static inline void set_ldt_desc(unsigned
17781         ((info)->seg_32bit << 22) | \
17782         ((info)->limit_in_pages << 23) | \
17783         ((info)->useable << 20) | \
17784 -       0x7000)
17785 +       0x7100)
17786  
17787  #define LDT_empty(info) (\
17788         (info)->base_addr       == 0    && \
17789 @@ -134,7 +193,7 @@ static inline void clear_LDT(void)
17790   */
17791  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
17792  {
17793 -       void *segments = pc->ldt;
17794 +       const void *segments = pc->ldt;
17795         int count = pc->size;
17796  
17797         if (likely(!count)) {
17798 @@ -162,6 +221,22 @@ static inline unsigned long get_desc_bas
17799         return base;
17800  }
17801  
17802 +static inline void _load_LDT(mm_context_t *pc)
17803 +{
17804 +       int cpu = get_cpu();
17805 +       const void *segments = pc->ldt;
17806 +       int count = pc->size;
17807 +
17808 +       if (likely(!count)) {
17809 +               segments = &default_ldt[0];
17810 +               count = 5;
17811 +       }
17812 +               
17813 +       __set_ldt_desc(cpu, segments, count);
17814 +       load_LDT_desc();
17815 +       put_cpu();
17816 +}
17817 +
17818  #endif /* !__ASSEMBLY__ */
17819  
17820  #endif
17821 diff -urNp linux-2.6.16.12/include/asm-i386/elf.h linux-2.6.16.12/include/asm-i386/elf.h
17822 --- linux-2.6.16.12/include/asm-i386/elf.h      2006-05-01 15:14:26.000000000 -0400
17823 +++ linux-2.6.16.12/include/asm-i386/elf.h      2006-05-01 20:17:34.000000000 -0400
17824 @@ -71,7 +71,22 @@ typedef struct user_fxsr_struct elf_fpxr
17825     the loader.  We need to make sure that it is out of the way of the program
17826     that it will "exec", and that there is sufficient room for the brk.  */
17827  
17828 +#ifdef CONFIG_PAX_SEGMEXEC
17829 +#define ELF_ET_DYN_BASE        ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
17830 +#else
17831  #define ELF_ET_DYN_BASE                ((TASK_UNMAPPED_BASE) * 2)
17832 +#endif
17833 +
17834 +#ifdef CONFIG_PAX_ASLR
17835 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
17836 +
17837 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17838 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
17839 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17840 +#define PAX_DELTA_EXEC_LEN(tsk)                15
17841 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17842 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
17843 +#endif
17844  
17845  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
17846     now struct_user_regs, they are different) */
17847 @@ -131,7 +146,14 @@ extern int dump_task_extended_fpu (struc
17848  
17849  #define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
17850  #define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
17851 +
17852 +#ifndef CONFIG_PAX_NOVSYSCALL
17853 +#ifdef CONFIG_PAX_SEGMEXEC
17854 +#define VSYSCALL_ENTRY ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
17855 +#else
17856  #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
17857 +#endif
17858 +
17859  extern void __kernel_vsyscall;
17860  
17861  #define ARCH_DLINFO                                            \
17862 @@ -187,3 +209,5 @@ do {                                                                              \
17863  #endif
17864  
17865  #endif
17866 +
17867 +#endif
17868 diff -urNp linux-2.6.16.12/include/asm-i386/i387.h linux-2.6.16.12/include/asm-i386/i387.h
17869 --- linux-2.6.16.12/include/asm-i386/i387.h     2006-05-01 15:14:26.000000000 -0400
17870 +++ linux-2.6.16.12/include/asm-i386/i387.h     2006-05-01 20:17:34.000000000 -0400
17871 @@ -31,8 +31,8 @@ extern void init_fpu(struct task_struct 
17872   */
17873  #define restore_fpu(tsk)                       \
17874         alternative_input(                      \
17875 -               "nop ; frstor %1",              \
17876 -               "fxrstor %1",                   \
17877 +               "nop ; frstor %2",              \
17878 +               "fxrstor %2",                   \
17879                 X86_FEATURE_FXSR,               \
17880                 "m" ((tsk)->thread.i387.fxsave))
17881  
17882 diff -urNp linux-2.6.16.12/include/asm-i386/mach-default/apm.h linux-2.6.16.12/include/asm-i386/mach-default/apm.h
17883 --- linux-2.6.16.12/include/asm-i386/mach-default/apm.h 2006-05-01 15:14:26.000000000 -0400
17884 +++ linux-2.6.16.12/include/asm-i386/mach-default/apm.h 2006-05-01 20:17:34.000000000 -0400
17885 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
17886         __asm__ __volatile__(APM_DO_ZERO_SEGS
17887                 "pushl %%edi\n\t"
17888                 "pushl %%ebp\n\t"
17889 -               "lcall *%%cs:apm_bios_entry\n\t"
17890 +               "lcall *%%ss:apm_bios_entry\n\t"
17891                 "setc %%al\n\t"
17892                 "popl %%ebp\n\t"
17893                 "popl %%edi\n\t"
17894 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
17895         __asm__ __volatile__(APM_DO_ZERO_SEGS
17896                 "pushl %%edi\n\t"
17897                 "pushl %%ebp\n\t"
17898 -               "lcall *%%cs:apm_bios_entry\n\t"
17899 +               "lcall *%%ss:apm_bios_entry\n\t"
17900                 "setc %%bl\n\t"
17901                 "popl %%ebp\n\t"
17902                 "popl %%edi\n\t"
17903 diff -urNp linux-2.6.16.12/include/asm-i386/mman.h linux-2.6.16.12/include/asm-i386/mman.h
17904 --- linux-2.6.16.12/include/asm-i386/mman.h     2006-05-01 15:14:26.000000000 -0400
17905 +++ linux-2.6.16.12/include/asm-i386/mman.h     2006-05-01 20:17:34.000000000 -0400
17906 @@ -11,6 +11,10 @@
17907  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
17908  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
17909  
17910 +#ifdef CONFIG_PAX_SEGMEXEC
17911 +#define MAP_MIRROR     0x20000
17912 +#endif
17913 +
17914  #define MCL_CURRENT    1               /* lock all current mappings */
17915  #define MCL_FUTURE     2               /* lock all future mappings */
17916  
17917 diff -urNp linux-2.6.16.12/include/asm-i386/mmu_context.h linux-2.6.16.12/include/asm-i386/mmu_context.h
17918 --- linux-2.6.16.12/include/asm-i386/mmu_context.h      2006-05-01 15:14:26.000000000 -0400
17919 +++ linux-2.6.16.12/include/asm-i386/mmu_context.h      2006-05-01 20:17:34.000000000 -0400
17920 @@ -46,6 +46,13 @@ static inline void switch_mm(struct mm_s
17921                  */
17922                 if (unlikely(prev->context.ldt != next->context.ldt))
17923                         load_LDT_nolock(&next->context, cpu);
17924 +
17925 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17926 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
17927 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
17928 +#endif
17929 +
17930 +               set_user_cs(next, cpu);
17931         }
17932  #ifdef CONFIG_SMP
17933         else {
17934 @@ -58,6 +65,12 @@ static inline void switch_mm(struct mm_s
17935                          */
17936                         load_cr3(next->pgd);
17937                         load_LDT_nolock(&next->context, cpu);
17938 +
17939 +#ifdef CONFIG_PAX_PAGEEXEC
17940 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
17941 +#endif
17942 +
17943 +                       set_user_cs(next, cpu);
17944                 }
17945         }
17946  #endif
17947 diff -urNp linux-2.6.16.12/include/asm-i386/mmu.h linux-2.6.16.12/include/asm-i386/mmu.h
17948 --- linux-2.6.16.12/include/asm-i386/mmu.h      2006-05-01 15:14:26.000000000 -0400
17949 +++ linux-2.6.16.12/include/asm-i386/mmu.h      2006-05-01 20:17:34.000000000 -0400
17950 @@ -12,6 +12,17 @@ typedef struct { 
17951         int size;
17952         struct semaphore sem;
17953         void *ldt;
17954 +
17955 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17956 +       unsigned long user_cs_base;
17957 +       unsigned long user_cs_limit;
17958 +
17959 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17960 +       cpumask_t cpu_user_cs_mask;
17961 +#endif
17962 +
17963 +#endif
17964 +
17965  } mm_context_t;
17966  
17967  #endif
17968 diff -urNp linux-2.6.16.12/include/asm-i386/module.h linux-2.6.16.12/include/asm-i386/module.h
17969 --- linux-2.6.16.12/include/asm-i386/module.h   2006-05-01 15:14:26.000000000 -0400
17970 +++ linux-2.6.16.12/include/asm-i386/module.h   2006-05-01 20:17:34.000000000 -0400
17971 @@ -72,6 +72,12 @@ struct mod_arch_specific
17972  #define MODULE_STACKSIZE ""
17973  #endif
17974  
17975 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
17976 +#ifdef CONFIG_GRKERNSEC
17977 +#define MODULE_GRSEC "GRSECURITY "
17978 +#else
17979 +#define MODULE_GRSEC ""
17980 +#endif
17981 +
17982 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
17983  
17984  #endif /* _ASM_I386_MODULE_H */
17985 diff -urNp linux-2.6.16.12/include/asm-i386/page.h linux-2.6.16.12/include/asm-i386/page.h
17986 --- linux-2.6.16.12/include/asm-i386/page.h     2006-05-01 15:14:26.000000000 -0400
17987 +++ linux-2.6.16.12/include/asm-i386/page.h     2006-05-01 20:17:34.000000000 -0400
17988 @@ -57,7 +57,6 @@ typedef struct { unsigned long long pgpr
17989  typedef struct { unsigned long pte_low; } pte_t;
17990  typedef struct { unsigned long pgd; } pgd_t;
17991  typedef struct { unsigned long pgprot; } pgprot_t;
17992 -#define boot_pte_t pte_t /* or would you rather have a typedef */
17993  #define pte_val(x)     ((x).pte_low)
17994  #define HPAGE_SHIFT    22
17995  #endif
17996 @@ -113,6 +112,15 @@ extern int page_is_ram(unsigned long pag
17997  #define __PHYSICAL_START       CONFIG_PHYSICAL_START
17998  #define __KERNEL_START         (__PAGE_OFFSET + __PHYSICAL_START)
17999  #define __MAXMEM               (-__PAGE_OFFSET-__VMALLOC_RESERVE)
18000 +#ifdef CONFIG_PAX_KERNEXEC
18001 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + ((__PHYSICAL_START + ~(4*1024*1024)) & (4*1024*1024)))
18002 +#ifndef __ASSEMBLY__
18003 +extern unsigned char MODULES_VADDR[];
18004 +extern unsigned char MODULES_END[];
18005 +#endif
18006 +#else
18007 +#define __KERNEL_TEXT_OFFSET   (0)
18008 +#endif
18009  
18010  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
18011  #define PHYSICAL_START         ((unsigned long)__PHYSICAL_START)
18012 @@ -135,6 +143,19 @@ extern int page_is_ram(unsigned long pag
18013         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
18014                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18015  
18016 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18017 +#ifdef CONFIG_PAX_MPROTECT
18018 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18019 +                         ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
18020 +#else
18021 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
18022 +#endif
18023 +#endif
18024 +
18025 +#ifdef CONFIG_PAX_PAGEEXEC
18026 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
18027 +#endif
18028 +
18029  #endif /* __KERNEL__ */
18030  
18031  #include <asm-generic/page.h>
18032 diff -urNp linux-2.6.16.12/include/asm-i386/pgalloc.h linux-2.6.16.12/include/asm-i386/pgalloc.h
18033 --- linux-2.6.16.12/include/asm-i386/pgalloc.h  2006-05-01 15:14:26.000000000 -0400
18034 +++ linux-2.6.16.12/include/asm-i386/pgalloc.h  2006-05-01 20:17:34.000000000 -0400
18035 @@ -3,11 +3,12 @@
18036  
18037  #include <linux/config.h>
18038  #include <asm/fixmap.h>
18039 +#include <asm/desc.h>
18040  #include <linux/threads.h>
18041  #include <linux/mm.h>          /* for struct page */
18042  
18043  #define pmd_populate_kernel(mm, pmd, pte) \
18044 -               set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
18045 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
18046  
18047  #define pmd_populate(mm, pmd, pte)                             \
18048         set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
18049 diff -urNp linux-2.6.16.12/include/asm-i386/pgtable.h linux-2.6.16.12/include/asm-i386/pgtable.h
18050 --- linux-2.6.16.12/include/asm-i386/pgtable.h  2006-05-01 15:14:26.000000000 -0400
18051 +++ linux-2.6.16.12/include/asm-i386/pgtable.h  2006-05-01 20:17:34.000000000 -0400
18052 @@ -34,7 +34,6 @@ struct vm_area_struct;
18053   */
18054  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
18055  extern unsigned long empty_zero_page[1024];
18056 -extern pgd_t swapper_pg_dir[1024];
18057  extern kmem_cache_t *pgd_cache;
18058  extern kmem_cache_t *pmd_cache;
18059  extern spinlock_t pgd_lock;
18060 @@ -59,6 +58,11 @@ void paging_init(void);
18061  # include <asm/pgtable-2level-defs.h>
18062  #endif
18063  
18064 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
18065 +#ifdef CONFIG_X86_PAE
18066 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
18067 +#endif
18068 +
18069  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
18070  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
18071  
18072 @@ -68,9 +72,11 @@ void paging_init(void);
18073  #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
18074  #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
18075  
18076 +#ifndef CONFIG_X86_PAE
18077  #define TWOLEVEL_PGDIR_SHIFT   22
18078  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
18079  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
18080 +#endif
18081  
18082  /* Just any arbitrary offset to the start of the vmalloc VM area: the
18083   * current 8MB value just means that there will be a 8MB "hole" after the
18084 @@ -141,17 +147,26 @@ void paging_init(void);
18085  
18086  #define PAGE_SHARED_EXEC \
18087         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
18088 -#define PAGE_COPY_NOEXEC \
18089 -       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18090  #define PAGE_COPY_EXEC \
18091         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18092 -#define PAGE_COPY \
18093 -       PAGE_COPY_NOEXEC
18094  #define PAGE_READONLY \
18095         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18096  #define PAGE_READONLY_EXEC \
18097         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18098  
18099 +#ifdef CONFIG_PAX_PAGEEXEC
18100 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
18101 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
18102 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
18103 +#else
18104 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18105 +# define PAGE_COPY_NOEXEC \
18106 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18107 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18108 +#endif
18109 +
18110 +#define PAGE_COPY \
18111 +       PAGE_COPY_NOEXEC
18112  #define _PAGE_KERNEL \
18113         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
18114  #define _PAGE_KERNEL_EXEC \
18115 @@ -176,18 +191,18 @@ extern unsigned long long __PAGE_KERNEL,
18116   * This is the closest we can get..
18117   */
18118  #define __P000 PAGE_NONE
18119 -#define __P001 PAGE_READONLY
18120 -#define __P010 PAGE_COPY
18121 -#define __P011 PAGE_COPY
18122 +#define __P001 PAGE_READONLY_NOEXEC
18123 +#define __P010 PAGE_COPY_NOEXEC
18124 +#define __P011 PAGE_COPY_NOEXEC
18125  #define __P100 PAGE_READONLY_EXEC
18126  #define __P101 PAGE_READONLY_EXEC
18127  #define __P110 PAGE_COPY_EXEC
18128  #define __P111 PAGE_COPY_EXEC
18129  
18130  #define __S000 PAGE_NONE
18131 -#define __S001 PAGE_READONLY
18132 -#define __S010 PAGE_SHARED
18133 -#define __S011 PAGE_SHARED
18134 +#define __S001 PAGE_READONLY_NOEXEC
18135 +#define __S010 PAGE_SHARED_NOEXEC
18136 +#define __S011 PAGE_SHARED_NOEXEC
18137  #define __S100 PAGE_READONLY_EXEC
18138  #define __S101 PAGE_READONLY_EXEC
18139  #define __S110 PAGE_SHARED_EXEC
18140 @@ -432,6 +447,9 @@ extern void noexec_setup(const char *str
18141  
18142  #endif /* !__ASSEMBLY__ */
18143  
18144 +#define HAVE_ARCH_UNMAPPED_AREA
18145 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
18146 +
18147  #ifdef CONFIG_FLATMEM
18148  #define kern_addr_valid(addr)  (1)
18149  #endif /* CONFIG_FLATMEM */
18150 diff -urNp linux-2.6.16.12/include/asm-i386/processor.h linux-2.6.16.12/include/asm-i386/processor.h
18151 --- linux-2.6.16.12/include/asm-i386/processor.h        2006-05-01 15:14:26.000000000 -0400
18152 +++ linux-2.6.16.12/include/asm-i386/processor.h        2006-05-01 20:17:34.000000000 -0400
18153 @@ -19,7 +19,6 @@
18154  #include <linux/cache.h>
18155  #include <linux/config.h>
18156  #include <linux/threads.h>
18157 -#include <asm/percpu.h>
18158  
18159  /* flag for disabling the tsc */
18160  extern int tsc_disable;
18161 @@ -90,8 +89,6 @@ struct cpuinfo_x86 {
18162  
18163  extern struct cpuinfo_x86 boot_cpu_data;
18164  extern struct cpuinfo_x86 new_cpu_data;
18165 -extern struct tss_struct doublefault_tss;
18166 -DECLARE_PER_CPU(struct tss_struct, init_tss);
18167  
18168  #ifdef CONFIG_SMP
18169  extern struct cpuinfo_x86 cpu_data[];
18170 @@ -321,10 +318,19 @@ extern int bootloader_type;
18171  #define __TASK_SIZE            (__PAGE_OFFSET)
18172  #define TASK_SIZE              ((unsigned long)__TASK_SIZE)
18173  
18174 +#ifdef CONFIG_PAX_SEGMEXEC
18175 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
18176 +#endif
18177 +
18178  /* This decides where the kernel will search for a free chunk of vm
18179   * space during mmap's.
18180   */
18181 +
18182 +#ifdef CONFIG_PAX_SEGMEXEC
18183 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
18184 +#else
18185  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
18186 +#endif
18187  
18188  #define HAVE_ARCH_PICK_MMAP_LAYOUT
18189  
18190 @@ -440,6 +446,9 @@ struct tss_struct {
18191  
18192  #define ARCH_MIN_TASKALIGN     16
18193  
18194 +extern struct tss_struct doublefault_tss;
18195 +extern struct tss_struct init_tss[NR_CPUS];
18196 +
18197  struct thread_struct {
18198  /* cached TLS descriptors. */
18199         struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
18200 @@ -468,6 +477,7 @@ struct thread_struct {
18201  };
18202  
18203  #define INIT_THREAD  {                                                 \
18204 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
18205         .vm86_info = NULL,                                              \
18206         .sysenter_cs = __KERNEL_CS,                                     \
18207         .io_bitmap_ptr = NULL,                                          \
18208 @@ -480,7 +490,7 @@ struct thread_struct {
18209   * be within the limit.
18210   */
18211  #define INIT_TSS  {                                                    \
18212 -       .esp0           = sizeof(init_stack) + (long)&init_stack,       \
18213 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
18214         .ss0            = __KERNEL_DS,                                  \
18215         .ss1            = __KERNEL_CS,                                  \
18216         .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,                     \
18217 @@ -556,11 +566,7 @@ void show_trace(struct task_struct *task
18218  unsigned long get_wchan(struct task_struct *p);
18219  
18220  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
18221 -#define KSTK_TOP(info)                                                 \
18222 -({                                                                     \
18223 -       unsigned long *__ptr = (unsigned long *)(info);                 \
18224 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
18225 -})
18226 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
18227  
18228  /*
18229   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
18230 @@ -575,7 +581,7 @@ unsigned long get_wchan(struct task_stru
18231  #define task_pt_regs(task)                                             \
18232  ({                                                                     \
18233         struct pt_regs *__regs__;                                       \
18234 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
18235 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
18236         __regs__ - 1;                                                   \
18237  })
18238  
18239 @@ -699,7 +705,7 @@ static inline void rep_nop(void)
18240  static inline void prefetch(const void *x)
18241  {
18242         alternative_input(ASM_NOP4,
18243 -                         "prefetchnta (%1)",
18244 +                         "prefetchnta (%2)",
18245                           X86_FEATURE_XMM,
18246                           "r" (x));
18247  }
18248 @@ -713,7 +719,7 @@ static inline void prefetch(const void *
18249  static inline void prefetchw(const void *x)
18250  {
18251         alternative_input(ASM_NOP4,
18252 -                         "prefetchw (%1)",
18253 +                         "prefetchw (%2)",
18254                           X86_FEATURE_3DNOW,
18255                           "r" (x));
18256  }
18257 diff -urNp linux-2.6.16.12/include/asm-i386/ptrace.h linux-2.6.16.12/include/asm-i386/ptrace.h
18258 --- linux-2.6.16.12/include/asm-i386/ptrace.h   2006-05-01 15:14:26.000000000 -0400
18259 +++ linux-2.6.16.12/include/asm-i386/ptrace.h   2006-05-01 20:17:34.000000000 -0400
18260 @@ -65,17 +65,18 @@ struct task_struct;
18261  extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
18262  
18263  /*
18264 - * user_mode_vm(regs) determines whether a register set came from user mode.
18265 + * user_mode(regs) determines whether a register set came from user mode.
18266   * This is true if V8086 mode was enabled OR if the register set was from
18267   * protected mode with RPL-3 CS value.  This tricky test checks that with
18268   * one comparison.  Many places in the kernel can bypass this full check
18269 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
18270 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
18271 + * be used.
18272   */
18273 -static inline int user_mode(struct pt_regs *regs)
18274 +static inline int user_mode_novm(struct pt_regs *regs)
18275  {
18276         return (regs->xcs & 3) != 0;
18277  }
18278 -static inline int user_mode_vm(struct pt_regs *regs)
18279 +static inline int user_mode(struct pt_regs *regs)
18280  {
18281         return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
18282  }
18283 diff -urNp linux-2.6.16.12/include/asm-i386/system.h linux-2.6.16.12/include/asm-i386/system.h
18284 --- linux-2.6.16.12/include/asm-i386/system.h   2006-05-01 15:14:26.000000000 -0400
18285 +++ linux-2.6.16.12/include/asm-i386/system.h   2006-05-01 20:17:34.000000000 -0400
18286 @@ -5,6 +5,7 @@
18287  #include <linux/kernel.h>
18288  #include <asm/segment.h>
18289  #include <asm/cpufeature.h>
18290 +#include <asm/page.h>
18291  #include <linux/bitops.h> /* for LOCK_PREFIX */
18292  
18293  #ifdef __KERNEL__
18294 @@ -151,7 +152,7 @@ static inline unsigned long get_limit(un
18295         unsigned long __limit;
18296         __asm__("lsll %1,%0"
18297                 :"=r" (__limit):"r" (segment));
18298 -       return __limit+1;
18299 +       return __limit;
18300  }
18301  
18302  #define nop() __asm__ __volatile__ ("nop")
18303 @@ -379,15 +380,15 @@ struct alt_instr { 
18304         asm volatile ("661:\n\t" oldinstr "\n662:\n"                 \
18305                       ".section .altinstructions,\"a\"\n"            \
18306                       "  .align 4\n"                                   \
18307 -                     "  .long 661b\n"            /* label */          \
18308 +                     "  .long 661b + %c1\n"      /* label */          \
18309                       "  .long 663f\n"            /* new instruction */         \
18310                       "  .byte %c0\n"             /* feature bit */    \
18311                       "  .byte 662b-661b\n"       /* sourcelen */      \
18312                       "  .byte 664f-663f\n"       /* replacementlen */ \
18313                       ".previous\n"                                             \
18314 -                     ".section .altinstr_replacement,\"ax\"\n"                 \
18315 +                     ".section .altinstr_replacement,\"a\"\n"                  \
18316                       "663:\n\t" newinstr "\n664:\n"   /* replacement */    \
18317 -                     ".previous" :: "i" (feature) : "memory")  
18318 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET) : "memory")  
18319  
18320  /*
18321   * Alternative inline assembly with input.
18322 @@ -403,15 +404,15 @@ struct alt_instr { 
18323         asm volatile ("661:\n\t" oldinstr "\n662:\n"                            \
18324                       ".section .altinstructions,\"a\"\n"                       \
18325                       "  .align 4\n"                                            \
18326 -                     "  .long 661b\n"            /* label */                   \
18327 +                     "  .long 661b + %c1\n"      /* label */                   \
18328                       "  .long 663f\n"            /* new instruction */         \
18329                       "  .byte %c0\n"             /* feature bit */             \
18330                       "  .byte 662b-661b\n"       /* sourcelen */               \
18331                       "  .byte 664f-663f\n"       /* replacementlen */          \
18332                       ".previous\n"                                             \
18333 -                     ".section .altinstr_replacement,\"ax\"\n"                 \
18334 +                     ".section .altinstr_replacement,\"a\"\n"                  \
18335                       "663:\n\t" newinstr "\n664:\n"   /* replacement */        \
18336 -                     ".previous" :: "i" (feature), ##input)
18337 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET), ##input)
18338  
18339  /*
18340   * Force strict CPU ordering.
18341 @@ -557,6 +558,6 @@ static inline void sched_cacheflush(void
18342         wbinvd();
18343  }
18344  
18345 -extern unsigned long arch_align_stack(unsigned long sp);
18346 +#define arch_align_stack(x) (x)
18347  
18348  #endif
18349 diff -urNp linux-2.6.16.12/include/asm-ia64/elf.h linux-2.6.16.12/include/asm-ia64/elf.h
18350 --- linux-2.6.16.12/include/asm-ia64/elf.h      2006-05-01 15:14:26.000000000 -0400
18351 +++ linux-2.6.16.12/include/asm-ia64/elf.h      2006-05-01 20:17:34.000000000 -0400
18352 @@ -163,6 +163,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
18353  typedef struct ia64_fpreg elf_fpreg_t;
18354  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
18355  
18356 +#ifdef CONFIG_PAX_ASLR
18357 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
18358 +
18359 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18360 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
18361 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18362 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
18363 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18364 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
18365 +#endif
18366  
18367  
18368  struct pt_regs;        /* forward declaration... */
18369 diff -urNp linux-2.6.16.12/include/asm-ia64/page.h linux-2.6.16.12/include/asm-ia64/page.h
18370 --- linux-2.6.16.12/include/asm-ia64/page.h     2006-05-01 15:14:26.000000000 -0400
18371 +++ linux-2.6.16.12/include/asm-ia64/page.h     2006-05-01 20:17:34.000000000 -0400
18372 @@ -219,4 +219,13 @@ get_order (unsigned long size)
18373                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
18374                                           ? VM_EXEC : 0))
18375  
18376 +#ifdef CONFIG_PAX_PAGEEXEC
18377 +#ifdef CONFIG_PAX_MPROTECT
18378 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18379 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18380 +#else
18381 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18382 +#endif
18383 +#endif
18384 +
18385  #endif /* _ASM_IA64_PAGE_H */
18386 diff -urNp linux-2.6.16.12/include/asm-ia64/pgtable.h linux-2.6.16.12/include/asm-ia64/pgtable.h
18387 --- linux-2.6.16.12/include/asm-ia64/pgtable.h  2006-05-01 15:14:26.000000000 -0400
18388 +++ linux-2.6.16.12/include/asm-ia64/pgtable.h  2006-05-01 20:17:34.000000000 -0400
18389 @@ -144,6 +144,17 @@
18390  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
18391  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
18392  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
18393 +
18394 +#ifdef CONFIG_PAX_PAGEEXEC
18395 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
18396 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
18397 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
18398 +#else
18399 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18400 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18401 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18402 +#endif
18403 +
18404  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
18405  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
18406  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
18407 diff -urNp linux-2.6.16.12/include/asm-ia64/processor.h linux-2.6.16.12/include/asm-ia64/processor.h
18408 --- linux-2.6.16.12/include/asm-ia64/processor.h        2006-05-01 15:14:26.000000000 -0400
18409 +++ linux-2.6.16.12/include/asm-ia64/processor.h        2006-05-01 20:17:34.000000000 -0400
18410 @@ -284,7 +284,7 @@ struct thread_struct {
18411         .on_ustack =    0,                                      \
18412         .ksp =          0,                                      \
18413         .map_base =     DEFAULT_MAP_BASE,                       \
18414 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
18415 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
18416         .task_size =    DEFAULT_TASK_SIZE,                      \
18417         .last_fph_cpu =  -1,                                    \
18418         INIT_THREAD_IA32                                        \
18419 diff -urNp linux-2.6.16.12/include/asm-ia64/ustack.h linux-2.6.16.12/include/asm-ia64/ustack.h
18420 --- linux-2.6.16.12/include/asm-ia64/ustack.h   2006-05-01 15:14:26.000000000 -0400
18421 +++ linux-2.6.16.12/include/asm-ia64/ustack.h   2006-05-01 20:17:34.000000000 -0400
18422 @@ -11,6 +11,6 @@
18423  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
18424  /* Make a default stack size of 2GB */
18425  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
18426 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
18427 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
18428  
18429  #endif /* _ASM_IA64_USTACK_H */
18430 diff -urNp linux-2.6.16.12/include/asm-mips/a.out.h linux-2.6.16.12/include/asm-mips/a.out.h
18431 --- linux-2.6.16.12/include/asm-mips/a.out.h    2006-05-01 15:14:26.000000000 -0400
18432 +++ linux-2.6.16.12/include/asm-mips/a.out.h    2006-05-01 20:17:34.000000000 -0400
18433 @@ -36,10 +36,10 @@ struct exec
18434  #ifdef __KERNEL__
18435  
18436  #ifdef CONFIG_32BIT
18437 -#define STACK_TOP      TASK_SIZE
18438 +#define __STACK_TOP    TASK_SIZE
18439  #endif
18440  #ifdef CONFIG_64BIT
18441 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
18442 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
18443  #endif
18444  
18445  #endif
18446 diff -urNp linux-2.6.16.12/include/asm-mips/elf.h linux-2.6.16.12/include/asm-mips/elf.h
18447 --- linux-2.6.16.12/include/asm-mips/elf.h      2006-05-01 15:14:26.000000000 -0400
18448 +++ linux-2.6.16.12/include/asm-mips/elf.h      2006-05-01 20:17:34.000000000 -0400
18449 @@ -331,4 +331,15 @@ extern int dump_task_fpu(struct task_str
18450  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
18451  #endif
18452  
18453 +#ifdef CONFIG_PAX_ASLR
18454 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
18455 +
18456 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18457 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
18458 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18459 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
18460 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18461 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
18462 +#endif
18463 +
18464  #endif /* _ASM_ELF_H */
18465 diff -urNp linux-2.6.16.12/include/asm-mips/page.h linux-2.6.16.12/include/asm-mips/page.h
18466 --- linux-2.6.16.12/include/asm-mips/page.h     2006-05-01 15:14:26.000000000 -0400
18467 +++ linux-2.6.16.12/include/asm-mips/page.h     2006-05-01 20:17:34.000000000 -0400
18468 @@ -151,6 +151,15 @@ typedef struct { unsigned long pgprot; }
18469  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18470                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18471  
18472 +#ifdef CONFIG_PAX_PAGEEXEC
18473 +#ifdef CONFIG_PAX_MPROTECT
18474 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18475 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18476 +#else
18477 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18478 +#endif
18479 +#endif
18480 +
18481  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
18482  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
18483  
18484 diff -urNp linux-2.6.16.12/include/asm-parisc/a.out.h linux-2.6.16.12/include/asm-parisc/a.out.h
18485 --- linux-2.6.16.12/include/asm-parisc/a.out.h  2006-05-01 15:14:26.000000000 -0400
18486 +++ linux-2.6.16.12/include/asm-parisc/a.out.h  2006-05-01 20:17:34.000000000 -0400
18487 @@ -22,7 +22,7 @@ struct exec
18488  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
18489   * prumpf */
18490  
18491 -#define STACK_TOP      TASK_SIZE
18492 +#define __STACK_TOP    TASK_SIZE
18493  
18494  #endif
18495  
18496 diff -urNp linux-2.6.16.12/include/asm-parisc/elf.h linux-2.6.16.12/include/asm-parisc/elf.h
18497 --- linux-2.6.16.12/include/asm-parisc/elf.h    2006-05-01 15:14:26.000000000 -0400
18498 +++ linux-2.6.16.12/include/asm-parisc/elf.h    2006-05-01 20:17:34.000000000 -0400
18499 @@ -337,6 +337,17 @@ struct pt_regs;    /* forward declaration..
18500  
18501  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
18502  
18503 +#ifdef CONFIG_PAX_ASLR
18504 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
18505 +
18506 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18507 +#define PAX_DELTA_MMAP_LEN(tsk)                16
18508 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18509 +#define PAX_DELTA_EXEC_LEN(tsk)                16
18510 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18511 +#define PAX_DELTA_STACK_LEN(tsk)       16
18512 +#endif
18513 +
18514  /* This yields a mask that user programs can use to figure out what
18515     instruction set this CPU supports.  This could be done in user space,
18516     but it's not easy, and we've already done it here.  */
18517 diff -urNp linux-2.6.16.12/include/asm-parisc/page.h linux-2.6.16.12/include/asm-parisc/page.h
18518 --- linux-2.6.16.12/include/asm-parisc/page.h   2006-05-01 15:14:26.000000000 -0400
18519 +++ linux-2.6.16.12/include/asm-parisc/page.h   2006-05-01 20:17:34.000000000 -0400
18520 @@ -150,6 +150,15 @@ extern int npmem_ranges;
18521  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18522                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18523  
18524 +#ifdef CONFIG_PAX_PAGEEXEC
18525 +#ifdef CONFIG_PAX_MPROTECT
18526 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18527 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18528 +#else
18529 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18530 +#endif
18531 +#endif
18532 +
18533  #endif /* __KERNEL__ */
18534  
18535  #include <asm-generic/page.h>
18536 diff -urNp linux-2.6.16.12/include/asm-parisc/pgtable.h linux-2.6.16.12/include/asm-parisc/pgtable.h
18537 --- linux-2.6.16.12/include/asm-parisc/pgtable.h        2006-05-01 15:14:26.000000000 -0400
18538 +++ linux-2.6.16.12/include/asm-parisc/pgtable.h        2006-05-01 20:17:34.000000000 -0400
18539 @@ -212,6 +212,17 @@ extern  void *vmalloc_start;
18540  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
18541  #define PAGE_COPY       PAGE_EXECREAD
18542  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
18543 +
18544 +#ifdef CONFIG_PAX_PAGEEXEC
18545 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
18546 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
18547 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
18548 +#else
18549 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18550 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18551 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18552 +#endif
18553 +
18554  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
18555  #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
18556  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
18557 diff -urNp linux-2.6.16.12/include/asm-powerpc/a.out.h linux-2.6.16.12/include/asm-powerpc/a.out.h
18558 --- linux-2.6.16.12/include/asm-powerpc/a.out.h 2006-05-01 15:14:26.000000000 -0400
18559 +++ linux-2.6.16.12/include/asm-powerpc/a.out.h 2006-05-01 20:17:34.000000000 -0400
18560 @@ -23,12 +23,12 @@ struct exec
18561  #define STACK_TOP_USER64 TASK_SIZE_USER64
18562  #define STACK_TOP_USER32 TASK_SIZE_USER32
18563  
18564 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
18565 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
18566                    STACK_TOP_USER32 : STACK_TOP_USER64)
18567  
18568  #else /* __powerpc64__ */
18569  
18570 -#define STACK_TOP TASK_SIZE
18571 +#define __STACK_TOP TASK_SIZE
18572  
18573  #endif /* __powerpc64__ */
18574  #endif /* __KERNEL__ */
18575 diff -urNp linux-2.6.16.12/include/asm-powerpc/elf.h linux-2.6.16.12/include/asm-powerpc/elf.h
18576 --- linux-2.6.16.12/include/asm-powerpc/elf.h   2006-05-01 15:14:26.000000000 -0400
18577 +++ linux-2.6.16.12/include/asm-powerpc/elf.h   2006-05-01 20:17:34.000000000 -0400
18578 @@ -176,6 +176,26 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF
18579  
18580  #define ELF_ET_DYN_BASE         (0x08000000)
18581  
18582 +#ifdef CONFIG_PAX_ASLR
18583 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
18584 +
18585 +#ifdef __powerpc64__
18586 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18587 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
18588 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18589 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
18590 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18591 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 16 : 28)
18592 +#else
18593 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18594 +#define PAX_DELTA_MMAP_LEN(tsk)                15
18595 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18596 +#define PAX_DELTA_EXEC_LEN(tsk)                15
18597 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18598 +#define PAX_DELTA_STACK_LEN(tsk)       15
18599 +#endif
18600 +#endif
18601 +
18602  #ifdef __KERNEL__
18603  
18604  /* Common routine for both 32-bit and 64-bit processes */
18605 diff -urNp linux-2.6.16.12/include/asm-powerpc/page_64.h linux-2.6.16.12/include/asm-powerpc/page_64.h
18606 --- linux-2.6.16.12/include/asm-powerpc/page_64.h       2006-05-01 15:14:26.000000000 -0400
18607 +++ linux-2.6.16.12/include/asm-powerpc/page_64.h       2006-05-01 20:17:34.000000000 -0400
18608 @@ -169,6 +169,15 @@ extern unsigned int HPAGE_SHIFT;
18609         (test_thread_flag(TIF_32BIT) ? \
18610          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
18611  
18612 +#ifdef CONFIG_PAX_PAGEEXEC
18613 +#ifdef CONFIG_PAX_MPROTECT
18614 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18615 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18616 +#else
18617 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18618 +#endif
18619 +#endif
18620 +
18621  #include <asm-generic/page.h>
18622  
18623  #endif /* __KERNEL__ */
18624 diff -urNp linux-2.6.16.12/include/asm-ppc/page.h linux-2.6.16.12/include/asm-ppc/page.h
18625 --- linux-2.6.16.12/include/asm-ppc/page.h      2006-05-01 15:14:26.000000000 -0400
18626 +++ linux-2.6.16.12/include/asm-ppc/page.h      2006-05-01 20:17:34.000000000 -0400
18627 @@ -175,5 +175,14 @@ extern __inline__ int get_order(unsigned
18628  /* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
18629  #define __HAVE_ARCH_GATE_AREA          1
18630  
18631 +#ifdef CONFIG_PAX_PAGEEXEC
18632 +#ifdef CONFIG_PAX_MPROTECT
18633 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18634 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18635 +#else
18636 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18637 +#endif
18638 +#endif
18639 +
18640  #endif /* __KERNEL__ */
18641  #endif /* _PPC_PAGE_H */
18642 diff -urNp linux-2.6.16.12/include/asm-ppc/pgtable.h linux-2.6.16.12/include/asm-ppc/pgtable.h
18643 --- linux-2.6.16.12/include/asm-ppc/pgtable.h   2006-05-01 15:14:26.000000000 -0400
18644 +++ linux-2.6.16.12/include/asm-ppc/pgtable.h   2006-05-01 20:17:34.000000000 -0400
18645 @@ -441,11 +441,21 @@ extern unsigned long ioremap_bot, iorema
18646  
18647  #define PAGE_NONE      __pgprot(_PAGE_BASE)
18648  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
18649 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
18650 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
18651  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
18652 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
18653 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
18654  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
18655 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
18656 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
18657 +
18658 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
18659 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
18660 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
18661 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
18662 +#else
18663 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18664 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18665 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18666 +#endif
18667  
18668  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
18669  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
18670 @@ -457,21 +467,21 @@ extern unsigned long ioremap_bot, iorema
18671   * This is the closest we can get..
18672   */
18673  #define __P000 PAGE_NONE
18674 -#define __P001 PAGE_READONLY_X
18675 -#define __P010 PAGE_COPY
18676 -#define __P011 PAGE_COPY_X
18677 -#define __P100 PAGE_READONLY
18678 +#define __P001 PAGE_READONLY_NOEXEC
18679 +#define __P010 PAGE_COPY_NOEXEC
18680 +#define __P011 PAGE_COPY_NOEXEC
18681 +#define __P100 PAGE_READONLY_X
18682  #define __P101 PAGE_READONLY_X
18683 -#define __P110 PAGE_COPY
18684 +#define __P110 PAGE_COPY_X
18685  #define __P111 PAGE_COPY_X
18686  
18687  #define __S000 PAGE_NONE
18688 -#define __S001 PAGE_READONLY_X
18689 -#define __S010 PAGE_SHARED
18690 -#define __S011 PAGE_SHARED_X
18691 -#define __S100 PAGE_READONLY
18692 +#define __S001 PAGE_READONLY_NOEXEC
18693 +#define __S010 PAGE_SHARED_NOEXEC
18694 +#define __S011 PAGE_SHARED_NOEXEC
18695 +#define __S100 PAGE_READONLY_X
18696  #define __S101 PAGE_READONLY_X
18697 -#define __S110 PAGE_SHARED
18698 +#define __S110 PAGE_SHARED_X
18699  #define __S111 PAGE_SHARED_X
18700  
18701  #ifndef __ASSEMBLY__
18702 diff -urNp linux-2.6.16.12/include/asm-sparc/a.out.h linux-2.6.16.12/include/asm-sparc/a.out.h
18703 --- linux-2.6.16.12/include/asm-sparc/a.out.h   2006-05-01 15:14:26.000000000 -0400
18704 +++ linux-2.6.16.12/include/asm-sparc/a.out.h   2006-05-01 20:17:34.000000000 -0400
18705 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
18706  
18707  #include <asm/page.h>
18708  
18709 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
18710 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
18711  
18712  #endif /* __KERNEL__ */
18713  
18714 diff -urNp linux-2.6.16.12/include/asm-sparc/elf.h linux-2.6.16.12/include/asm-sparc/elf.h
18715 --- linux-2.6.16.12/include/asm-sparc/elf.h     2006-05-01 15:14:26.000000000 -0400
18716 +++ linux-2.6.16.12/include/asm-sparc/elf.h     2006-05-01 20:17:34.000000000 -0400
18717 @@ -145,6 +145,17 @@ typedef struct {
18718  
18719  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
18720  
18721 +#ifdef CONFIG_PAX_ASLR
18722 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
18723 +
18724 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18725 +#define PAX_DELTA_MMAP_LEN(tsk)                16
18726 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18727 +#define PAX_DELTA_EXEC_LEN(tsk)                16
18728 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18729 +#define PAX_DELTA_STACK_LEN(tsk)       16
18730 +#endif
18731 +
18732  /* This yields a mask that user programs can use to figure out what
18733     instruction set this cpu supports.  This can NOT be done in userspace
18734     on Sparc.  */
18735 diff -urNp linux-2.6.16.12/include/asm-sparc/page.h linux-2.6.16.12/include/asm-sparc/page.h
18736 --- linux-2.6.16.12/include/asm-sparc/page.h    2006-05-01 15:14:26.000000000 -0400
18737 +++ linux-2.6.16.12/include/asm-sparc/page.h    2006-05-01 20:17:34.000000000 -0400
18738 @@ -164,6 +164,15 @@ extern unsigned long pfn_base;
18739  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18740                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18741  
18742 +#ifdef CONFIG_PAX_PAGEEXEC
18743 +#ifdef CONFIG_PAX_MPROTECT
18744 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18745 +                        ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18746 +#else
18747 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18748 +#endif
18749 +#endif
18750 +
18751  #endif /* __KERNEL__ */
18752  
18753  #include <asm-generic/page.h>
18754 diff -urNp linux-2.6.16.12/include/asm-sparc/pgtable.h linux-2.6.16.12/include/asm-sparc/pgtable.h
18755 --- linux-2.6.16.12/include/asm-sparc/pgtable.h 2006-05-01 15:14:26.000000000 -0400
18756 +++ linux-2.6.16.12/include/asm-sparc/pgtable.h 2006-05-01 20:17:34.000000000 -0400
18757 @@ -50,6 +50,13 @@ BTFIXUPDEF_INT(page_none)
18758  BTFIXUPDEF_INT(page_shared)
18759  BTFIXUPDEF_INT(page_copy)
18760  BTFIXUPDEF_INT(page_readonly)
18761 +
18762 +#ifdef CONFIG_PAX_PAGEEXEC
18763 +BTFIXUPDEF_INT(page_shared_noexec)
18764 +BTFIXUPDEF_INT(page_copy_noexec)
18765 +BTFIXUPDEF_INT(page_readonly_noexec)
18766 +#endif
18767 +
18768  BTFIXUPDEF_INT(page_kernel)
18769  
18770  #define PMD_SHIFT              SUN4C_PMD_SHIFT
18771 @@ -71,6 +78,16 @@ BTFIXUPDEF_INT(page_kernel)
18772  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
18773  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
18774  
18775 +#ifdef CONFIG_PAX_PAGEEXEC
18776 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
18777 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
18778 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
18779 +#else
18780 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18781 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18782 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18783 +#endif
18784 +
18785  extern unsigned long page_kernel;
18786  
18787  #ifdef MODULE
18788 diff -urNp linux-2.6.16.12/include/asm-sparc/pgtsrmmu.h linux-2.6.16.12/include/asm-sparc/pgtsrmmu.h
18789 --- linux-2.6.16.12/include/asm-sparc/pgtsrmmu.h        2006-05-01 15:14:26.000000000 -0400
18790 +++ linux-2.6.16.12/include/asm-sparc/pgtsrmmu.h        2006-05-01 20:17:34.000000000 -0400
18791 @@ -115,6 +115,16 @@
18792                                     SRMMU_EXEC | SRMMU_REF)
18793  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18794                                     SRMMU_EXEC | SRMMU_REF)
18795 +
18796 +#ifdef CONFIG_PAX_PAGEEXEC
18797 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18798 +                                          SRMMU_WRITE | SRMMU_REF)
18799 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18800 +                                          SRMMU_REF)
18801 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18802 +                                          SRMMU_REF)
18803 +#endif
18804 +
18805  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
18806                                     SRMMU_DIRTY | SRMMU_REF)
18807  
18808 diff -urNp linux-2.6.16.12/include/asm-sparc/uaccess.h linux-2.6.16.12/include/asm-sparc/uaccess.h
18809 --- linux-2.6.16.12/include/asm-sparc/uaccess.h 2006-05-01 15:14:26.000000000 -0400
18810 +++ linux-2.6.16.12/include/asm-sparc/uaccess.h 2006-05-01 20:17:34.000000000 -0400
18811 @@ -41,7 +41,7 @@
18812   * No one can read/write anything from userland in the kernel space by setting
18813   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
18814   */
18815 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
18816 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
18817  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
18818  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
18819  #define access_ok(type, addr, size)                                    \
18820 diff -urNp linux-2.6.16.12/include/asm-sparc64/a.out.h linux-2.6.16.12/include/asm-sparc64/a.out.h
18821 --- linux-2.6.16.12/include/asm-sparc64/a.out.h 2006-05-01 15:14:26.000000000 -0400
18822 +++ linux-2.6.16.12/include/asm-sparc64/a.out.h 2006-05-01 20:17:34.000000000 -0400
18823 @@ -95,7 +95,7 @@ struct relocation_info /* used when head
18824  
18825  #ifdef __KERNEL__
18826  
18827 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
18828 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
18829  
18830  #endif
18831  
18832 diff -urNp linux-2.6.16.12/include/asm-sparc64/elf.h linux-2.6.16.12/include/asm-sparc64/elf.h
18833 --- linux-2.6.16.12/include/asm-sparc64/elf.h   2006-05-01 15:14:26.000000000 -0400
18834 +++ linux-2.6.16.12/include/asm-sparc64/elf.h   2006-05-01 20:17:34.000000000 -0400
18835 @@ -140,6 +140,16 @@ typedef struct {
18836  #define ELF_ET_DYN_BASE         0x0000010000000000UL
18837  #endif
18838  
18839 +#ifdef CONFIG_PAX_ASLR
18840 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
18841 +
18842 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
18843 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
18844 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
18845 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
18846 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18847 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
18848 +#endif
18849  
18850  /* This yields a mask that user programs can use to figure out what
18851     instruction set this cpu supports.  */
18852 diff -urNp linux-2.6.16.12/include/asm-sparc64/page.h linux-2.6.16.12/include/asm-sparc64/page.h
18853 --- linux-2.6.16.12/include/asm-sparc64/page.h  2006-05-01 15:14:26.000000000 -0400
18854 +++ linux-2.6.16.12/include/asm-sparc64/page.h  2006-05-01 20:17:34.000000000 -0400
18855 @@ -147,6 +147,15 @@ extern unsigned long page_to_pfn(struct 
18856  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18857                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18858  
18859 +#ifdef CONFIG_PAX_PAGEEXEC
18860 +#ifdef CONFIG_PAX_MPROTECT
18861 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18862 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18863 +#else
18864 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18865 +#endif
18866 +#endif
18867 +
18868  #endif /* !(__KERNEL__) */
18869  
18870  #include <asm-generic/page.h>
18871 diff -urNp linux-2.6.16.12/include/asm-x86_64/a.out.h linux-2.6.16.12/include/asm-x86_64/a.out.h
18872 --- linux-2.6.16.12/include/asm-x86_64/a.out.h  2006-05-01 15:14:26.000000000 -0400
18873 +++ linux-2.6.16.12/include/asm-x86_64/a.out.h  2006-05-01 20:17:34.000000000 -0400
18874 @@ -21,7 +21,7 @@ struct exec
18875  
18876  #ifdef __KERNEL__
18877  #include <linux/thread_info.h>
18878 -#define STACK_TOP TASK_SIZE
18879 +#define __STACK_TOP TASK_SIZE
18880  #endif
18881  
18882  #endif /* __A_OUT_GNU_H__ */
18883 diff -urNp linux-2.6.16.12/include/asm-x86_64/elf.h linux-2.6.16.12/include/asm-x86_64/elf.h
18884 --- linux-2.6.16.12/include/asm-x86_64/elf.h    2006-05-01 15:14:26.000000000 -0400
18885 +++ linux-2.6.16.12/include/asm-x86_64/elf.h    2006-05-01 20:17:34.000000000 -0400
18886 @@ -89,6 +89,17 @@ typedef struct user_i387_struct elf_fpre
18887  
18888  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
18889  
18890 +#ifdef CONFIG_PAX_ASLR
18891 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
18892 +
18893 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18894 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
18895 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18896 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
18897 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18898 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 32)
18899 +#endif
18900 +
18901  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
18902     now struct_user_regs, they are different). Assumes current is the process
18903     getting dumped. */
18904 diff -urNp linux-2.6.16.12/include/asm-x86_64/ia32.h linux-2.6.16.12/include/asm-x86_64/ia32.h
18905 --- linux-2.6.16.12/include/asm-x86_64/ia32.h   2006-05-01 15:14:26.000000000 -0400
18906 +++ linux-2.6.16.12/include/asm-x86_64/ia32.h   2006-05-01 20:17:34.000000000 -0400
18907 @@ -157,7 +157,13 @@ struct ustat32 {
18908         char                    f_fpack[6];
18909  };
18910  
18911 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
18912 +#ifdef CONFIG_PAX_RANDUSTACK
18913 +#define IA32_DELTA_STACK (current->mm->delta_stack)
18914 +#else
18915 +#define IA32_DELTA_STACK 0UL
18916 +#endif
18917 +
18918 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
18919  
18920  #ifdef __KERNEL__
18921  struct user_desc;
18922 diff -urNp linux-2.6.16.12/include/asm-x86_64/page.h linux-2.6.16.12/include/asm-x86_64/page.h
18923 --- linux-2.6.16.12/include/asm-x86_64/page.h   2006-05-01 15:14:26.000000000 -0400
18924 +++ linux-2.6.16.12/include/asm-x86_64/page.h   2006-05-01 20:17:34.000000000 -0400
18925 @@ -138,6 +138,15 @@ typedef struct { unsigned long pgprot; }
18926         (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
18927          VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18928  
18929 +#ifdef CONFIG_PAX_PAGEEXEC
18930 +#ifdef CONFIG_PAX_MPROTECT
18931 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18932 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18933 +#else
18934 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18935 +#endif
18936 +#endif
18937 +
18938  #define __HAVE_ARCH_GATE_AREA 1        
18939  
18940  #endif /* __KERNEL__ */
18941 diff -urNp linux-2.6.16.12/include/asm-x86_64/pgalloc.h linux-2.6.16.12/include/asm-x86_64/pgalloc.h
18942 --- linux-2.6.16.12/include/asm-x86_64/pgalloc.h        2006-05-01 15:14:26.000000000 -0400
18943 +++ linux-2.6.16.12/include/asm-x86_64/pgalloc.h        2006-05-01 20:17:34.000000000 -0400
18944 @@ -7,7 +7,7 @@
18945  #include <linux/mm.h>
18946  
18947  #define pmd_populate_kernel(mm, pmd, pte) \
18948 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
18949 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
18950  #define pud_populate(mm, pud, pmd) \
18951                 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
18952  #define pgd_populate(mm, pgd, pud) \
18953 diff -urNp linux-2.6.16.12/include/asm-x86_64/pgtable.h linux-2.6.16.12/include/asm-x86_64/pgtable.h
18954 --- linux-2.6.16.12/include/asm-x86_64/pgtable.h        2006-05-01 15:14:26.000000000 -0400
18955 +++ linux-2.6.16.12/include/asm-x86_64/pgtable.h        2006-05-01 20:17:34.000000000 -0400
18956 @@ -180,6 +180,10 @@ static inline pte_t ptep_get_and_clear_f
18957  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18958  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18959  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18960 +
18961 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
18962 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
18963 +
18964  #define __PAGE_KERNEL \
18965         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
18966  #define __PAGE_KERNEL_EXEC \
18967 @@ -268,7 +272,13 @@ static inline pte_t pfn_pte(unsigned lon
18968  #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
18969  static inline int pte_user(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
18970  static inline int pte_read(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
18971 -static inline int pte_exec(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
18972 +extern inline int pte_exec(pte_t pte)
18973 +{
18974 +       if (__supported_pte_mask & _PAGE_NX)
18975 +               return pte_val(pte) & _PAGE_NX;
18976 +       else
18977 +               return pte_val(pte) & _PAGE_USER;
18978 +}
18979  static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
18980  static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
18981  static inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_RW; }
18982 @@ -276,12 +286,26 @@ static inline int pte_file(pte_t pte)             {
18983  static inline int pte_huge(pte_t pte)          { return (pte_val(pte) & __LARGE_PTE) == __LARGE_PTE; }
18984  
18985  static inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
18986 -static inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
18987 +extern inline pte_t pte_exprotect(pte_t pte)
18988 +{
18989 +       if (__supported_pte_mask & _PAGE_NX)
18990 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
18991 +       else
18992 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
18993 +       return pte;
18994 +}
18995  static inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
18996  static inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
18997  static inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
18998  static inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
18999 -static inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
19000 +extern inline pte_t pte_mkexec(pte_t pte)
19001 +{
19002 +       if (__supported_pte_mask & _PAGE_NX)
19003 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
19004 +       else
19005 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
19006 +       return pte;
19007 +}
19008  static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
19009  static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
19010  static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
19011 diff -urNp linux-2.6.16.12/include/asm-x86_64/system.h linux-2.6.16.12/include/asm-x86_64/system.h
19012 --- linux-2.6.16.12/include/asm-x86_64/system.h 2006-05-01 15:14:26.000000000 -0400
19013 +++ linux-2.6.16.12/include/asm-x86_64/system.h 2006-05-01 20:17:34.000000000 -0400
19014 @@ -372,6 +372,6 @@ static inline unsigned long __cmpxchg(vo
19015  
19016  void cpu_idle_wait(void);
19017  
19018 -extern unsigned long arch_align_stack(unsigned long sp);
19019 +#define arch_align_stack(x) (x)
19020  
19021  #endif
19022 diff -urNp linux-2.6.16.12/include/linux/a.out.h linux-2.6.16.12/include/linux/a.out.h
19023 --- linux-2.6.16.12/include/linux/a.out.h       2006-05-01 15:14:26.000000000 -0400
19024 +++ linux-2.6.16.12/include/linux/a.out.h       2006-05-01 20:17:34.000000000 -0400
19025 @@ -7,6 +7,16 @@
19026  
19027  #include <asm/a.out.h>
19028  
19029 +#ifdef CONFIG_PAX_RANDUSTACK
19030 +#define __DELTA_STACK (current->mm->delta_stack)
19031 +#else
19032 +#define __DELTA_STACK 0UL
19033 +#endif
19034 +
19035 +#ifndef STACK_TOP
19036 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
19037 +#endif
19038 +
19039  #endif /* __STRUCT_EXEC_OVERRIDE__ */
19040  
19041  /* these go in the N_MACHTYPE field */
19042 @@ -37,6 +47,14 @@ enum machine_type {
19043    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
19044  };
19045  
19046 +/* Constants for the N_FLAGS field */
19047 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
19048 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
19049 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
19050 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
19051 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
19052 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
19053 +
19054  #if !defined (N_MAGIC)
19055  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
19056  #endif
19057 diff -urNp linux-2.6.16.12/include/linux/binfmts.h linux-2.6.16.12/include/linux/binfmts.h
19058 --- linux-2.6.16.12/include/linux/binfmts.h     2006-05-01 15:14:26.000000000 -0400
19059 +++ linux-2.6.16.12/include/linux/binfmts.h     2006-05-01 20:17:34.000000000 -0400
19060 @@ -7,10 +7,10 @@ struct pt_regs;
19061  
19062  /*
19063   * MAX_ARG_PAGES defines the number of pages allocated for arguments
19064 - * and envelope for the new program. 32 should suffice, this gives
19065 - * a maximum env+arg of 128kB w/4KB pages!
19066 + * and envelope for the new program. 33 should suffice, this gives
19067 + * a maximum env+arg of 132kB w/4KB pages!
19068   */
19069 -#define MAX_ARG_PAGES 32
19070 +#define MAX_ARG_PAGES 33
19071  
19072  /* sizeof(linux_binprm->buf) */
19073  #define BINPRM_BUF_SIZE 128
19074 @@ -38,6 +38,7 @@ struct linux_binprm{
19075         unsigned interp_flags;
19076         unsigned interp_data;
19077         unsigned long loader, exec;
19078 +       int misc;
19079  };
19080  
19081  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
19082 @@ -87,5 +88,8 @@ extern void compute_creds(struct linux_b
19083  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
19084  extern int set_binfmt(struct linux_binfmt *new);
19085  
19086 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
19087 +void pax_report_insns(void *pc, void *sp);
19088 +
19089  #endif /* __KERNEL__ */
19090  #endif /* _LINUX_BINFMTS_H */
19091 diff -urNp linux-2.6.16.12/include/linux/capability.h linux-2.6.16.12/include/linux/capability.h
19092 --- linux-2.6.16.12/include/linux/capability.h  2006-05-01 15:14:26.000000000 -0400
19093 +++ linux-2.6.16.12/include/linux/capability.h  2006-05-01 20:17:34.000000000 -0400
19094 @@ -364,6 +364,7 @@ static inline kernel_cap_t cap_invert(ke
19095  #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
19096  
19097  extern int capable(int cap);
19098 +extern int capable_nolog(int cap);
19099  
19100  #endif /* __KERNEL__ */
19101  
19102 diff -urNp linux-2.6.16.12/include/linux/elf.h linux-2.6.16.12/include/linux/elf.h
19103 --- linux-2.6.16.12/include/linux/elf.h 2006-05-01 15:14:26.000000000 -0400
19104 +++ linux-2.6.16.12/include/linux/elf.h 2006-05-01 20:17:34.000000000 -0400
19105 @@ -5,6 +5,10 @@
19106  #include <linux/auxvec.h>
19107  #include <asm/elf.h>
19108  
19109 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19110 +#undef elf_read_implies_exec
19111 +#endif
19112 +
19113  #ifndef elf_read_implies_exec
19114    /* Executables for which elf_read_implies_exec() returns TRUE will
19115       have the READ_IMPLIES_EXEC personality flag set automatically.
19116 @@ -46,6 +50,16 @@ typedef __s64        Elf64_Sxword;
19117  
19118  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
19119  
19120 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
19121 +
19122 +/* Constants for the e_flags field */
19123 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
19124 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
19125 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
19126 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
19127 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
19128 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
19129 +
19130  /* These constants define the different elf file types */
19131  #define ET_NONE   0
19132  #define ET_REL    1
19133 @@ -138,6 +152,8 @@ typedef __s64       Elf64_Sxword;
19134  #define DT_DEBUG       21
19135  #define DT_TEXTREL     22
19136  #define DT_JMPREL      23
19137 +#define DT_FLAGS       30
19138 +  #define DF_TEXTREL   0x00000004
19139  #define DT_LOPROC      0x70000000
19140  #define DT_HIPROC      0x7fffffff
19141  
19142 @@ -267,6 +283,19 @@ typedef struct elf64_hdr {
19143  #define PF_W           0x2
19144  #define PF_X           0x1
19145  
19146 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
19147 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
19148 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
19149 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
19150 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
19151 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
19152 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
19153 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
19154 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
19155 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
19156 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
19157 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
19158 +
19159  typedef struct elf32_phdr{
19160    Elf32_Word   p_type;
19161    Elf32_Off    p_offset;
19162 @@ -359,6 +388,8 @@ typedef struct elf64_shdr {
19163  #define        EI_OSABI        7
19164  #define        EI_PAD          8
19165  
19166 +#define        EI_PAX          14
19167 +
19168  #define        ELFMAG0         0x7f            /* EI_MAG */
19169  #define        ELFMAG1         'E'
19170  #define        ELFMAG2         'L'
19171 @@ -415,6 +446,7 @@ extern Elf32_Dyn _DYNAMIC [];
19172  #define elfhdr         elf32_hdr
19173  #define elf_phdr       elf32_phdr
19174  #define elf_note       elf32_note
19175 +#define elf_dyn                Elf32_Dyn
19176  
19177  #else
19178  
19179 @@ -422,6 +454,7 @@ extern Elf64_Dyn _DYNAMIC [];
19180  #define elfhdr         elf64_hdr
19181  #define elf_phdr       elf64_phdr
19182  #define elf_note       elf64_note
19183 +#define elf_dyn                Elf64_Dyn
19184  
19185  #endif
19186  
19187 diff -urNp linux-2.6.16.12/include/linux/gracl.h linux-2.6.16.12/include/linux/gracl.h
19188 --- linux-2.6.16.12/include/linux/gracl.h       1969-12-31 19:00:00.000000000 -0500
19189 +++ linux-2.6.16.12/include/linux/gracl.h       2006-05-01 20:17:34.000000000 -0400
19190 @@ -0,0 +1,316 @@
19191 +#ifndef GR_ACL_H
19192 +#define GR_ACL_H
19193 +
19194 +#include <linux/grdefs.h>
19195 +#include <linux/resource.h>
19196 +#include <linux/dcache.h>
19197 +#include <asm/resource.h>
19198 +
19199 +/* Major status information */
19200 +
19201 +#define GR_VERSION  "grsecurity 2.1.9"
19202 +#define GRSECURITY_VERSION 0x219
19203 +
19204 +enum {
19205 +
19206 +       SHUTDOWN = 0,
19207 +       ENABLE = 1,
19208 +       SPROLE = 2,
19209 +       RELOAD = 3,
19210 +       SEGVMOD = 4,
19211 +       STATUS = 5,
19212 +       UNSPROLE = 6,
19213 +       PASSSET = 7,
19214 +       SPROLEPAM = 8
19215 +};
19216 +
19217 +/* Password setup definitions
19218 + * kernel/grhash.c */
19219 +enum {
19220 +       GR_PW_LEN = 128,
19221 +       GR_SALT_LEN = 16,
19222 +       GR_SHA_LEN = 32,
19223 +};
19224 +
19225 +enum {
19226 +       GR_SPROLE_LEN = 64,
19227 +};
19228 +
19229 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
19230 +
19231 +/* Begin Data Structures */
19232 +
19233 +struct sprole_pw {
19234 +       unsigned char *rolename;
19235 +       unsigned char salt[GR_SALT_LEN];
19236 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
19237 +};
19238 +
19239 +struct name_entry {
19240 +       __u32 key;
19241 +       ino_t inode;
19242 +       dev_t device;
19243 +       char *name;
19244 +       __u16 len;
19245 +       struct name_entry *prev;
19246 +       struct name_entry *next;
19247 +};
19248 +
19249 +struct inodev_entry {
19250 +       struct name_entry *nentry;
19251 +       struct inodev_entry *prev;
19252 +       struct inodev_entry *next;
19253 +};
19254 +
19255 +struct acl_role_db {
19256 +       struct acl_role_label **r_hash;
19257 +       __u32 r_size;
19258 +};
19259 +
19260 +struct inodev_db {
19261 +       struct inodev_entry **i_hash;
19262 +       __u32 i_size;
19263 +};
19264 +
19265 +struct name_db {
19266 +       struct name_entry **n_hash;
19267 +       __u32 n_size;
19268 +};
19269 +
19270 +struct crash_uid {
19271 +       uid_t uid;
19272 +       unsigned long expires;
19273 +};
19274 +
19275 +struct gr_hash_struct {
19276 +       void **table;
19277 +       void **nametable;
19278 +       void *first;
19279 +       __u32 table_size;
19280 +       __u32 used_size;
19281 +       int type;
19282 +};
19283 +
19284 +/* Userspace Grsecurity ACL data structures */
19285 +
19286 +struct acl_subject_label {
19287 +       char *filename;
19288 +       ino_t inode;
19289 +       dev_t device;
19290 +       __u32 mode;
19291 +       __u32 cap_mask;
19292 +       __u32 cap_lower;
19293 +
19294 +       struct rlimit res[GR_NLIMITS];
19295 +       __u16 resmask;
19296 +
19297 +       __u8 user_trans_type;
19298 +       __u8 group_trans_type;
19299 +       uid_t *user_transitions;
19300 +       gid_t *group_transitions;
19301 +       __u16 user_trans_num;
19302 +       __u16 group_trans_num;
19303 +
19304 +       __u32 ip_proto[8];
19305 +       __u32 ip_type;
19306 +       struct acl_ip_label **ips;
19307 +       __u32 ip_num;
19308 +
19309 +       __u32 crashes;
19310 +       unsigned long expires;
19311 +
19312 +       struct acl_subject_label *parent_subject;
19313 +       struct gr_hash_struct *hash;
19314 +       struct acl_subject_label *prev;
19315 +       struct acl_subject_label *next;
19316 +
19317 +       struct acl_object_label **obj_hash;
19318 +       __u32 obj_hash_size;
19319 +       __u16 pax_flags;
19320 +};
19321 +
19322 +struct role_allowed_ip {
19323 +       __u32 addr;
19324 +       __u32 netmask;
19325 +
19326 +       struct role_allowed_ip *prev;
19327 +       struct role_allowed_ip *next;
19328 +};
19329 +
19330 +struct role_transition {
19331 +       char *rolename;
19332 +
19333 +       struct role_transition *prev;
19334 +       struct role_transition *next;
19335 +};
19336 +
19337 +struct acl_role_label {
19338 +       char *rolename;
19339 +       uid_t uidgid;
19340 +       __u16 roletype;
19341 +
19342 +       __u16 auth_attempts;
19343 +       unsigned long expires;
19344 +
19345 +       struct acl_subject_label *root_label;
19346 +       struct gr_hash_struct *hash;
19347 +
19348 +       struct acl_role_label *prev;
19349 +       struct acl_role_label *next;
19350 +
19351 +       struct role_transition *transitions;
19352 +       struct role_allowed_ip *allowed_ips;
19353 +       uid_t *domain_children;
19354 +       __u16 domain_child_num;
19355 +
19356 +       struct acl_subject_label **subj_hash;
19357 +       __u32 subj_hash_size;
19358 +};
19359 +
19360 +struct user_acl_role_db {
19361 +       struct acl_role_label **r_table;
19362 +       __u32 num_pointers;             /* Number of allocations to track */
19363 +       __u32 num_roles;                /* Number of roles */
19364 +       __u32 num_domain_children;      /* Number of domain children */
19365 +       __u32 num_subjects;             /* Number of subjects */
19366 +       __u32 num_objects;              /* Number of objects */
19367 +};
19368 +
19369 +struct acl_object_label {
19370 +       char *filename;
19371 +       ino_t inode;
19372 +       dev_t device;
19373 +       __u32 mode;
19374 +
19375 +       struct acl_subject_label *nested;
19376 +       struct acl_object_label *globbed;
19377 +
19378 +       /* next two structures not used */
19379 +
19380 +       struct acl_object_label *prev;
19381 +       struct acl_object_label *next;
19382 +};
19383 +
19384 +struct acl_ip_label {
19385 +       char *iface;
19386 +       __u32 addr;
19387 +       __u32 netmask;
19388 +       __u16 low, high;
19389 +       __u8 mode;
19390 +       __u32 type;
19391 +       __u32 proto[8];
19392 +
19393 +       /* next two structures not used */
19394 +
19395 +       struct acl_ip_label *prev;
19396 +       struct acl_ip_label *next;
19397 +};
19398 +
19399 +struct gr_arg {
19400 +       struct user_acl_role_db role_db;
19401 +       unsigned char pw[GR_PW_LEN];
19402 +       unsigned char salt[GR_SALT_LEN];
19403 +       unsigned char sum[GR_SHA_LEN];
19404 +       unsigned char sp_role[GR_SPROLE_LEN];
19405 +       struct sprole_pw *sprole_pws;
19406 +       dev_t segv_device;
19407 +       ino_t segv_inode;
19408 +       uid_t segv_uid;
19409 +       __u16 num_sprole_pws;
19410 +       __u16 mode;
19411 +};
19412 +
19413 +struct gr_arg_wrapper {
19414 +       struct gr_arg *arg;
19415 +       __u32 version;
19416 +       __u32 size;
19417 +};
19418 +
19419 +struct subject_map {
19420 +       struct acl_subject_label *user;
19421 +       struct acl_subject_label *kernel;
19422 +       struct subject_map *prev;
19423 +       struct subject_map *next;
19424 +};
19425 +
19426 +struct acl_subj_map_db {
19427 +       struct subject_map **s_hash;
19428 +       __u32 s_size;
19429 +};
19430 +
19431 +/* End Data Structures Section */
19432 +
19433 +/* Hash functions generated by empirical testing by Brad Spengler
19434 +   Makes good use of the low bits of the inode.  Generally 0-1 times
19435 +   in loop for successful match.  0-3 for unsuccessful match.
19436 +   Shift/add algorithm with modulus of table size and an XOR*/
19437 +
19438 +static __inline__ unsigned int
19439 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
19440 +{
19441 +       return (((uid << type) + (uid ^ type)) % sz);
19442 +}
19443 +
19444 + static __inline__ unsigned int
19445 +shash(const struct acl_subject_label *userp, const unsigned int sz)
19446 +{
19447 +       return ((const unsigned long)userp % sz);
19448 +}
19449 +
19450 +static __inline__ unsigned int
19451 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
19452 +{
19453 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
19454 +}
19455 +
19456 +static __inline__ unsigned int
19457 +nhash(const char *name, const __u16 len, const unsigned int sz)
19458 +{
19459 +       return full_name_hash(name, len) % sz;
19460 +}
19461 +
19462 +#define FOR_EACH_ROLE_START(role,iter) \
19463 +       role = NULL; \
19464 +       iter = 0; \
19465 +       while (iter < acl_role_set.r_size) { \
19466 +               if (role == NULL) \
19467 +                       role = acl_role_set.r_hash[iter]; \
19468 +               if (role == NULL) { \
19469 +                       iter++; \
19470 +                       continue; \
19471 +               }
19472 +
19473 +#define FOR_EACH_ROLE_END(role,iter) \
19474 +               role = role->next; \
19475 +               if (role == NULL) \
19476 +                       iter++; \
19477 +       }
19478 +
19479 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
19480 +       subj = NULL; \
19481 +       iter = 0; \
19482 +       while (iter < role->subj_hash_size) { \
19483 +               if (subj == NULL) \
19484 +                       subj = role->subj_hash[iter]; \
19485 +               if (subj == NULL) { \
19486 +                       iter++; \
19487 +                       continue; \
19488 +               }
19489 +
19490 +#define FOR_EACH_SUBJECT_END(subj,iter) \
19491 +               subj = subj->next; \
19492 +               if (subj == NULL) \
19493 +                       iter++; \
19494 +       }
19495 +
19496 +
19497 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
19498 +       subj = role->hash->first; \
19499 +       while (subj != NULL) {
19500 +
19501 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
19502 +               subj = subj->next; \
19503 +       }
19504 +
19505 +#endif
19506 +
19507 diff -urNp linux-2.6.16.12/include/linux/gralloc.h linux-2.6.16.12/include/linux/gralloc.h
19508 --- linux-2.6.16.12/include/linux/gralloc.h     1969-12-31 19:00:00.000000000 -0500
19509 +++ linux-2.6.16.12/include/linux/gralloc.h     2006-05-01 20:17:34.000000000 -0400
19510 @@ -0,0 +1,8 @@
19511 +#ifndef __GRALLOC_H
19512 +#define __GRALLOC_H
19513 +
19514 +void acl_free_all(void);
19515 +int acl_alloc_stack_init(unsigned long size);
19516 +void *acl_alloc(unsigned long len);
19517 +
19518 +#endif
19519 diff -urNp linux-2.6.16.12/include/linux/grdefs.h linux-2.6.16.12/include/linux/grdefs.h
19520 --- linux-2.6.16.12/include/linux/grdefs.h      1969-12-31 19:00:00.000000000 -0500
19521 +++ linux-2.6.16.12/include/linux/grdefs.h      2006-05-01 20:17:34.000000000 -0400
19522 @@ -0,0 +1,131 @@
19523 +#ifndef GRDEFS_H
19524 +#define GRDEFS_H
19525 +
19526 +/* Begin grsecurity status declarations */
19527 +
19528 +enum {
19529 +       GR_READY = 0x01,
19530 +       GR_STATUS_INIT = 0x00   // disabled state
19531 +};
19532 +
19533 +/* Begin  ACL declarations */
19534 +
19535 +/* Role flags */
19536 +
19537 +enum {
19538 +       GR_ROLE_USER = 0x0001,
19539 +       GR_ROLE_GROUP = 0x0002,
19540 +       GR_ROLE_DEFAULT = 0x0004,
19541 +       GR_ROLE_SPECIAL = 0x0008,
19542 +       GR_ROLE_AUTH = 0x0010,
19543 +       GR_ROLE_NOPW = 0x0020,
19544 +       GR_ROLE_GOD = 0x0040,
19545 +       GR_ROLE_LEARN = 0x0080,
19546 +       GR_ROLE_TPE = 0x0100,
19547 +       GR_ROLE_DOMAIN = 0x0200,
19548 +       GR_ROLE_PAM = 0x0400
19549 +};
19550 +
19551 +/* ACL Subject and Object mode flags */
19552 +enum {
19553 +       GR_DELETED = 0x80000000
19554 +};
19555 +
19556 +/* ACL Object-only mode flags */
19557 +enum {
19558 +       GR_READ         = 0x00000001,
19559 +       GR_APPEND       = 0x00000002,
19560 +       GR_WRITE        = 0x00000004,
19561 +       GR_EXEC         = 0x00000008,
19562 +       GR_FIND         = 0x00000010,
19563 +       GR_INHERIT      = 0x00000020,
19564 +       GR_SETID        = 0x00000040,
19565 +       GR_CREATE       = 0x00000080,
19566 +       GR_DELETE       = 0x00000100,
19567 +       GR_LINK         = 0x00000200,
19568 +       GR_AUDIT_READ   = 0x00000400,
19569 +       GR_AUDIT_APPEND = 0x00000800,
19570 +       GR_AUDIT_WRITE  = 0x00001000,
19571 +       GR_AUDIT_EXEC   = 0x00002000,
19572 +       GR_AUDIT_FIND   = 0x00004000,
19573 +       GR_AUDIT_INHERIT= 0x00008000,
19574 +       GR_AUDIT_SETID  = 0x00010000,
19575 +       GR_AUDIT_CREATE = 0x00020000,
19576 +       GR_AUDIT_DELETE = 0x00040000,
19577 +       GR_AUDIT_LINK   = 0x00080000,
19578 +       GR_PTRACERD     = 0x00100000,
19579 +       GR_NOPTRACE     = 0x00200000,
19580 +       GR_SUPPRESS     = 0x00400000,
19581 +       GR_NOLEARN      = 0x00800000
19582 +};
19583 +
19584 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
19585 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
19586 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
19587 +
19588 +/* ACL subject-only mode flags */
19589 +enum {
19590 +       GR_KILL         = 0x00000001,
19591 +       GR_VIEW         = 0x00000002,
19592 +       GR_PROTECTED    = 0x00000004,
19593 +       GR_LEARN        = 0x00000008,
19594 +       GR_OVERRIDE     = 0x00000010,
19595 +       /* just a placeholder, this mode is only used in userspace */
19596 +       GR_DUMMY        = 0x00000020,
19597 +       GR_PROTSHM      = 0x00000040,
19598 +       GR_KILLPROC     = 0x00000080,
19599 +       GR_KILLIPPROC   = 0x00000100,
19600 +       /* just a placeholder, this mode is only used in userspace */
19601 +       GR_NOTROJAN     = 0x00000200,
19602 +       GR_PROTPROCFD   = 0x00000400,
19603 +       GR_PROCACCT     = 0x00000800,
19604 +       GR_RELAXPTRACE  = 0x00001000,
19605 +       GR_NESTED       = 0x00002000,
19606 +       GR_INHERITLEARN = 0x00004000,
19607 +       GR_PROCFIND     = 0x00008000,
19608 +       GR_POVERRIDE    = 0x00010000,
19609 +       GR_KERNELAUTH   = 0x00020000,
19610 +};
19611 +
19612 +enum {
19613 +       GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
19614 +       GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
19615 +       GR_PAX_ENABLE_MPROTECT  = 0x0004,
19616 +       GR_PAX_ENABLE_RANDMMAP  = 0x0008,
19617 +       GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
19618 +       GR_PAX_DISABLE_SEGMEXEC = 0x8001,
19619 +       GR_PAX_DISABLE_PAGEEXEC = 0x8002,
19620 +       GR_PAX_DISABLE_MPROTECT = 0x8004,
19621 +       GR_PAX_DISABLE_RANDMMAP = 0x8008,
19622 +       GR_PAX_DISABLE_EMUTRAMP = 0x8010,
19623 +};
19624 +
19625 +enum {
19626 +       GR_ID_USER      = 0x01,
19627 +       GR_ID_GROUP     = 0x02,
19628 +};
19629 +
19630 +enum {
19631 +       GR_ID_ALLOW     = 0x01,
19632 +       GR_ID_DENY      = 0x02,
19633 +};
19634 +
19635 +#define GR_CRASH_RES   11
19636 +#define GR_UIDTABLE_MAX 500
19637 +
19638 +/* begin resource learning section */
19639 +enum {
19640 +       GR_RLIM_CPU_BUMP = 60,
19641 +       GR_RLIM_FSIZE_BUMP = 50000,
19642 +       GR_RLIM_DATA_BUMP = 10000,
19643 +       GR_RLIM_STACK_BUMP = 1000,
19644 +       GR_RLIM_CORE_BUMP = 10000,
19645 +       GR_RLIM_RSS_BUMP = 500000,
19646 +       GR_RLIM_NPROC_BUMP = 1,
19647 +       GR_RLIM_NOFILE_BUMP = 5,
19648 +       GR_RLIM_MEMLOCK_BUMP = 50000,
19649 +       GR_RLIM_AS_BUMP = 500000,
19650 +       GR_RLIM_LOCKS_BUMP = 2
19651 +};
19652 +
19653 +#endif
19654 diff -urNp linux-2.6.16.12/include/linux/grinternal.h linux-2.6.16.12/include/linux/grinternal.h
19655 --- linux-2.6.16.12/include/linux/grinternal.h  1969-12-31 19:00:00.000000000 -0500
19656 +++ linux-2.6.16.12/include/linux/grinternal.h  2006-05-01 20:17:34.000000000 -0400
19657 @@ -0,0 +1,210 @@
19658 +#ifndef __GRINTERNAL_H
19659 +#define __GRINTERNAL_H
19660 +
19661 +#ifdef CONFIG_GRKERNSEC
19662 +
19663 +#include <linux/fs.h>
19664 +#include <linux/gracl.h>
19665 +#include <linux/grdefs.h>
19666 +#include <linux/grmsg.h>
19667 +
19668 +extern void gr_add_learn_entry(const char *fmt, ...);
19669 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
19670 +                           const struct vfsmount *mnt);
19671 +extern __u32 gr_check_create(const struct dentry *new_dentry,
19672 +                            const struct dentry *parent,
19673 +                            const struct vfsmount *mnt, const __u32 mode);
19674 +extern int gr_check_protected_task(const struct task_struct *task);
19675 +extern __u32 to_gr_audit(const __u32 reqmode);
19676 +extern int gr_set_acls(const int type);
19677 +
19678 +extern int gr_acl_is_enabled(void);
19679 +extern char gr_roletype_to_char(void);
19680 +
19681 +extern void gr_handle_alertkill(struct task_struct *task);
19682 +extern char *gr_to_filename(const struct dentry *dentry,
19683 +                           const struct vfsmount *mnt);
19684 +extern char *gr_to_filename1(const struct dentry *dentry,
19685 +                           const struct vfsmount *mnt);
19686 +extern char *gr_to_filename2(const struct dentry *dentry,
19687 +                           const struct vfsmount *mnt);
19688 +extern char *gr_to_filename3(const struct dentry *dentry,
19689 +                           const struct vfsmount *mnt);
19690 +
19691 +extern int grsec_enable_link;
19692 +extern int grsec_enable_fifo;
19693 +extern int grsec_enable_execve;
19694 +extern int grsec_enable_shm;
19695 +extern int grsec_enable_execlog;
19696 +extern int grsec_enable_signal;
19697 +extern int grsec_enable_forkfail;
19698 +extern int grsec_enable_time;
19699 +extern int grsec_enable_chroot_shmat;
19700 +extern int grsec_enable_chroot_findtask;
19701 +extern int grsec_enable_chroot_mount;
19702 +extern int grsec_enable_chroot_double;
19703 +extern int grsec_enable_chroot_pivot;
19704 +extern int grsec_enable_chroot_chdir;
19705 +extern int grsec_enable_chroot_chmod;
19706 +extern int grsec_enable_chroot_mknod;
19707 +extern int grsec_enable_chroot_fchdir;
19708 +extern int grsec_enable_chroot_nice;
19709 +extern int grsec_enable_chroot_execlog;
19710 +extern int grsec_enable_chroot_caps;
19711 +extern int grsec_enable_chroot_sysctl;
19712 +extern int grsec_enable_chroot_unix;
19713 +extern int grsec_enable_tpe;
19714 +extern int grsec_tpe_gid;
19715 +extern int grsec_enable_tpe_all;
19716 +extern int grsec_enable_sidcaps;
19717 +extern int grsec_enable_randpid;
19718 +extern int grsec_enable_socket_all;
19719 +extern int grsec_socket_all_gid;
19720 +extern int grsec_enable_socket_client;
19721 +extern int grsec_socket_client_gid;
19722 +extern int grsec_enable_socket_server;
19723 +extern int grsec_socket_server_gid;
19724 +extern int grsec_audit_gid;
19725 +extern int grsec_enable_group;
19726 +extern int grsec_enable_audit_ipc;
19727 +extern int grsec_enable_audit_textrel;
19728 +extern int grsec_enable_mount;
19729 +extern int grsec_enable_chdir;
19730 +extern int grsec_lock;
19731 +
19732 +extern struct task_struct *child_reaper;
19733 +
19734 +extern spinlock_t grsec_alert_lock;
19735 +extern unsigned long grsec_alert_wtime;
19736 +extern unsigned long grsec_alert_fyet;
19737 +
19738 +extern spinlock_t grsec_audit_lock;
19739 +
19740 +extern rwlock_t grsec_exec_file_lock;
19741 +
19742 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
19743 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
19744 +                       tsk->exec_file->f_vfsmnt) : "/")
19745 +
19746 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
19747 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
19748 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
19749 +
19750 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
19751 +                       gr_to_filename(tsk->exec_file->f_dentry, \
19752 +                       tsk->exec_file->f_vfsmnt) : "/")
19753 +
19754 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
19755 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
19756 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
19757 +
19758 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
19759 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
19760 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
19761 +                         (tsk_a->fs->root->d_inode->i_ino != \
19762 +                         child_reaper->fs->root->d_inode->i_ino)))
19763 +
19764 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
19765 +                         (tsk_a->fs->root->d_inode->i_sb->s_dev == \
19766 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
19767 +                         (tsk_a->fs->root->d_inode->i_ino == \
19768 +                         tsk_b->fs->root->d_inode->i_ino))
19769 +
19770 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
19771 +                      task->pid, task->uid, \
19772 +                      task->euid, task->gid, task->egid, \
19773 +                      gr_parent_task_fullpath(task), \
19774 +                      task->parent->comm, task->parent->pid, \
19775 +                      task->parent->uid, task->parent->euid, \
19776 +                      task->parent->gid, task->parent->egid
19777 +
19778 +#define GR_CHROOT_CAPS ( \
19779 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
19780 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
19781 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
19782 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
19783 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
19784 +       CAP_TO_MASK(CAP_IPC_OWNER))
19785 +
19786 +#define security_learn(normal_msg,args...) \
19787 +({ \
19788 +       read_lock(&grsec_exec_file_lock); \
19789 +       gr_add_learn_entry(normal_msg "\n", ## args); \
19790 +       read_unlock(&grsec_exec_file_lock); \
19791 +})
19792 +
19793 +enum {
19794 +       GR_DO_AUDIT,
19795 +       GR_DONT_AUDIT,
19796 +       GR_DONT_AUDIT_GOOD
19797 +};
19798 +
19799 +enum {
19800 +       GR_TTYSNIFF,
19801 +       GR_RBAC,
19802 +       GR_RBAC_STR,
19803 +       GR_STR_RBAC,
19804 +       GR_RBAC_MODE2,
19805 +       GR_RBAC_MODE3,
19806 +       GR_FILENAME,
19807 +       GR_NOARGS,
19808 +       GR_ONE_INT,
19809 +       GR_ONE_INT_TWO_STR,
19810 +       GR_ONE_STR,
19811 +       GR_STR_INT,
19812 +       GR_TWO_INT,
19813 +       GR_THREE_INT,
19814 +       GR_FIVE_INT_TWO_STR,
19815 +       GR_TWO_STR,
19816 +       GR_THREE_STR,
19817 +       GR_FOUR_STR,
19818 +       GR_STR_FILENAME,
19819 +       GR_FILENAME_STR,
19820 +       GR_FILENAME_TWO_INT,
19821 +       GR_FILENAME_TWO_INT_STR,
19822 +       GR_TEXTREL,
19823 +       GR_PTRACE,
19824 +       GR_RESOURCE,
19825 +       GR_CAP,
19826 +       GR_SIG,
19827 +       GR_CRASH1,
19828 +       GR_CRASH2,
19829 +       GR_PSACCT
19830 +};
19831 +
19832 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
19833 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
19834 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
19835 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
19836 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
19837 +#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)
19838 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
19839 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
19840 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
19841 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
19842 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
19843 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
19844 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
19845 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
19846 +#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)
19847 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
19848 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
19849 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
19850 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
19851 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
19852 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
19853 +#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)
19854 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
19855 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
19856 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
19857 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
19858 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
19859 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
19860 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
19861 +#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)
19862 +
19863 +extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
19864 +
19865 +#endif
19866 +
19867 +#endif
19868 diff -urNp linux-2.6.16.12/include/linux/grmsg.h linux-2.6.16.12/include/linux/grmsg.h
19869 --- linux-2.6.16.12/include/linux/grmsg.h       1969-12-31 19:00:00.000000000 -0500
19870 +++ linux-2.6.16.12/include/linux/grmsg.h       2006-05-01 20:17:34.000000000 -0400
19871 @@ -0,0 +1,108 @@
19872 +#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"
19873 +#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"
19874 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
19875 +#define GR_STOPMOD_MSG "denied modification of module state by "
19876 +#define GR_IOPERM_MSG "denied use of ioperm() by "
19877 +#define GR_IOPL_MSG "denied use of iopl() by "
19878 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
19879 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
19880 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
19881 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
19882 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
19883 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
19884 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
19885 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
19886 +#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"
19887 +#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"
19888 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
19889 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
19890 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
19891 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
19892 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
19893 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
19894 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
19895 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
19896 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
19897 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
19898 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
19899 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
19900 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
19901 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
19902 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
19903 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
19904 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
19905 +#define GR_NPROC_MSG "denied overstep of process limit by "
19906 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
19907 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
19908 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
19909 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
19910 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
19911 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
19912 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
19913 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
19914 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
19915 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
19916 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
19917 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
19918 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
19919 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
19920 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
19921 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
19922 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
19923 +#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"
19924 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
19925 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
19926 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
19927 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
19928 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
19929 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
19930 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
19931 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
19932 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
19933 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
19934 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
19935 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
19936 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
19937 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
19938 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
19939 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
19940 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
19941 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
19942 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
19943 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
19944 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
19945 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
19946 +#define GR_NICE_CHROOT_MSG "denied priority change by "
19947 +#define GR_UNISIGLOG_MSG "signal %d sent to "
19948 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
19949 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
19950 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
19951 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
19952 +#define GR_TIME_MSG "time set by "
19953 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
19954 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
19955 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
19956 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
19957 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
19958 +#define GR_BIND_MSG "denied bind() by "
19959 +#define GR_CONNECT_MSG "denied connect() by "
19960 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
19961 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
19962 +#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"
19963 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
19964 +#define GR_CAP_ACL_MSG "use of %s denied for "
19965 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
19966 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
19967 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
19968 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
19969 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
19970 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
19971 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
19972 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
19973 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
19974 +#define GR_SEM_AUDIT_MSG "semaphore created by "
19975 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
19976 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
19977 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
19978 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
19979 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
19980 diff -urNp linux-2.6.16.12/include/linux/grsecurity.h linux-2.6.16.12/include/linux/grsecurity.h
19981 --- linux-2.6.16.12/include/linux/grsecurity.h  1969-12-31 19:00:00.000000000 -0500
19982 +++ linux-2.6.16.12/include/linux/grsecurity.h  2006-05-01 20:17:34.000000000 -0400
19983 @@ -0,0 +1,196 @@
19984 +#ifndef GR_SECURITY_H
19985 +#define GR_SECURITY_H
19986 +#include <linux/fs.h>
19987 +#include <linux/binfmts.h>
19988 +#include <linux/gracl.h>
19989 +
19990 +extern void gr_handle_brute_attach(struct task_struct *p);
19991 +extern void gr_handle_brute_check(void);
19992 +
19993 +extern char gr_roletype_to_char(void);
19994 +
19995 +extern int gr_check_user_change(int real, int effective, int fs);
19996 +extern int gr_check_group_change(int real, int effective, int fs);
19997 +
19998 +extern void gr_del_task_from_ip_table(struct task_struct *p);
19999 +
20000 +extern int gr_pid_is_chrooted(struct task_struct *p);
20001 +extern int gr_handle_chroot_nice(void);
20002 +extern int gr_handle_chroot_sysctl(const int op);
20003 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
20004 +                                       const int niceval);
20005 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
20006 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
20007 +                                  const struct vfsmount *mnt);
20008 +extern void gr_handle_chroot_caps(struct task_struct *task);
20009 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
20010 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
20011 +                                 const struct vfsmount *mnt, const int mode);
20012 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
20013 +                                 const struct vfsmount *mnt, const int mode);
20014 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
20015 +                                 const struct vfsmount *mnt,
20016 +                                 const char *dev_name);
20017 +extern int gr_handle_chroot_pivot(void);
20018 +extern int gr_handle_chroot_unix(const pid_t pid);
20019 +
20020 +extern int gr_handle_rawio(const struct inode *inode);
20021 +extern int gr_handle_nproc(void);
20022 +
20023 +extern void gr_handle_ioperm(void);
20024 +extern void gr_handle_iopl(void);
20025 +
20026 +extern int gr_tpe_allow(const struct file *file);
20027 +
20028 +extern int gr_random_pid(void);
20029 +
20030 +extern void gr_log_forkfail(const int retval);
20031 +extern void gr_log_timechange(void);
20032 +extern void gr_log_signal(const int sig, const struct task_struct *t);
20033 +extern void gr_log_chdir(const struct dentry *dentry,
20034 +                        const struct vfsmount *mnt);
20035 +extern void gr_log_chroot_exec(const struct dentry *dentry,
20036 +                              const struct vfsmount *mnt);
20037 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
20038 +extern void gr_log_remount(const char *devname, const int retval);
20039 +extern void gr_log_unmount(const char *devname, const int retval);
20040 +extern void gr_log_mount(const char *from, const char *to, const int retval);
20041 +extern void gr_log_msgget(const int ret, const int msgflg);
20042 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
20043 +extern void gr_log_semget(const int err, const int semflg);
20044 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
20045 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
20046 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
20047 +extern void gr_log_textrel(struct vm_area_struct *vma);
20048 +
20049 +extern int gr_handle_follow_link(const struct inode *parent,
20050 +                                const struct inode *inode,
20051 +                                const struct dentry *dentry,
20052 +                                const struct vfsmount *mnt);
20053 +extern int gr_handle_fifo(const struct dentry *dentry,
20054 +                         const struct vfsmount *mnt,
20055 +                         const struct dentry *dir, const int flag,
20056 +                         const int acc_mode);
20057 +extern int gr_handle_hardlink(const struct dentry *dentry,
20058 +                             const struct vfsmount *mnt,
20059 +                             struct inode *inode,
20060 +                             const int mode, const char *to);
20061 +
20062 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
20063 +extern int gr_is_capable_nolog(const int cap);
20064 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
20065 +                             const unsigned long wanted, const int gt);
20066 +extern void gr_copy_label(struct task_struct *tsk);
20067 +extern void gr_handle_crash(struct task_struct *task, const int sig);
20068 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
20069 +extern int gr_check_crash_uid(const uid_t uid);
20070 +extern int gr_check_protected_task(const struct task_struct *task);
20071 +extern int gr_acl_handle_mmap(const struct file *file,
20072 +                             const unsigned long prot);
20073 +extern int gr_acl_handle_mprotect(const struct file *file,
20074 +                                 const unsigned long prot);
20075 +extern int gr_check_hidden_task(const struct task_struct *tsk);
20076 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
20077 +                                   const struct vfsmount *mnt);
20078 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
20079 +                                const struct vfsmount *mnt);
20080 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
20081 +                                 const struct vfsmount *mnt, const int fmode);
20082 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
20083 +                                 const struct vfsmount *mnt, mode_t mode);
20084 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
20085 +                                const struct vfsmount *mnt, mode_t mode);
20086 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
20087 +                                const struct vfsmount *mnt);
20088 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
20089 +extern int gr_handle_proc_ptrace(struct task_struct *task);
20090 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
20091 +                                 const struct vfsmount *mnt);
20092 +extern int gr_check_crash_exec(const struct file *filp);
20093 +extern int gr_acl_is_enabled(void);
20094 +extern void gr_set_kernel_label(struct task_struct *task);
20095 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
20096 +                             const gid_t gid);
20097 +extern int gr_set_proc_label(const struct dentry *dentry,
20098 +                             const struct vfsmount *mnt);
20099 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
20100 +                                      const struct vfsmount *mnt);
20101 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
20102 +                               const struct vfsmount *mnt, const int fmode);
20103 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
20104 +                                const struct dentry *p_dentry,
20105 +                                const struct vfsmount *p_mnt, const int fmode,
20106 +                                const int imode);
20107 +extern void gr_handle_create(const struct dentry *dentry,
20108 +                            const struct vfsmount *mnt);
20109 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
20110 +                                const struct dentry *parent_dentry,
20111 +                                const struct vfsmount *parent_mnt,
20112 +                                const int mode);
20113 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
20114 +                                const struct dentry *parent_dentry,
20115 +                                const struct vfsmount *parent_mnt);
20116 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
20117 +                                const struct vfsmount *mnt);
20118 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
20119 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
20120 +                                 const struct vfsmount *mnt);
20121 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
20122 +                                  const struct dentry *parent_dentry,
20123 +                                  const struct vfsmount *parent_mnt,
20124 +                                  const char *from);
20125 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
20126 +                               const struct dentry *parent_dentry,
20127 +                               const struct vfsmount *parent_mnt,
20128 +                               const struct dentry *old_dentry,
20129 +                               const struct vfsmount *old_mnt, const char *to);
20130 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
20131 +                               struct dentry *parent_dentry,
20132 +                               const struct vfsmount *parent_mnt,
20133 +                               struct dentry *old_dentry,
20134 +                               struct inode *old_parent_inode,
20135 +                               struct vfsmount *old_mnt, const char *newname);
20136 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
20137 +                               struct dentry *old_dentry,
20138 +                               struct dentry *new_dentry,
20139 +                               struct vfsmount *mnt, const __u8 replace);
20140 +extern __u32 gr_check_link(const struct dentry *new_dentry,
20141 +                          const struct dentry *parent_dentry,
20142 +                          const struct vfsmount *parent_mnt,
20143 +                          const struct dentry *old_dentry,
20144 +                          const struct vfsmount *old_mnt);
20145 +extern int gr_acl_handle_filldir(const struct file *file, const char *name,
20146 +                                const unsigned int namelen, const ino_t ino);
20147 +
20148 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
20149 +                               const struct vfsmount *mnt);
20150 +extern void gr_acl_handle_exit(void);
20151 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
20152 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
20153 +extern __u32 gr_cap_rtnetlink(void);
20154 +
20155 +#ifdef CONFIG_SYSVIPC
20156 +extern void gr_shm_exit(struct task_struct *task);
20157 +#else
20158 +static inline void gr_shm_exit(struct task_struct *task)
20159 +{
20160 +       return;
20161 +}
20162 +#endif
20163 +
20164 +#ifdef CONFIG_GRKERNSEC
20165 +extern void gr_handle_mem_write(void);
20166 +extern void gr_handle_kmem_write(void);
20167 +extern void gr_handle_open_port(void);
20168 +extern int gr_handle_mem_mmap(const unsigned long offset,
20169 +                             struct vm_area_struct *vma);
20170 +
20171 +extern unsigned long pax_get_random_long(void);
20172 +#define get_random_long() pax_get_random_long()
20173 +
20174 +extern int grsec_enable_dmesg;
20175 +extern int grsec_enable_randsrc;
20176 +extern int grsec_enable_shm;
20177 +#endif
20178 +
20179 +#endif
20180 diff -urNp linux-2.6.16.12/include/linux/mman.h linux-2.6.16.12/include/linux/mman.h
20181 --- linux-2.6.16.12/include/linux/mman.h        2006-05-01 15:14:26.000000000 -0400
20182 +++ linux-2.6.16.12/include/linux/mman.h        2006-05-01 20:17:34.000000000 -0400
20183 @@ -59,6 +59,11 @@ static inline unsigned long
20184  calc_vm_flag_bits(unsigned long flags)
20185  {
20186         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
20187 +
20188 +#ifdef CONFIG_PAX_SEGMEXEC
20189 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
20190 +#endif
20191 +
20192                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
20193                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
20194                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
20195 diff -urNp linux-2.6.16.12/include/linux/mm.h linux-2.6.16.12/include/linux/mm.h
20196 --- linux-2.6.16.12/include/linux/mm.h  2006-05-01 15:14:26.000000000 -0400
20197 +++ linux-2.6.16.12/include/linux/mm.h  2006-05-01 20:17:34.000000000 -0400
20198 @@ -38,6 +38,7 @@ extern int sysctl_legacy_va_layout;
20199  #include <asm/pgtable.h>
20200  #include <asm/processor.h>
20201  #include <asm/atomic.h>
20202 +#include <asm/mman.h>
20203  
20204  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
20205  
20206 @@ -111,8 +112,43 @@ struct vm_area_struct {
20207  #ifdef CONFIG_NUMA
20208         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
20209  #endif
20210 +
20211 +       unsigned long vm_mirror;        /* PaX: mirror distance */
20212  };
20213  
20214 +#ifdef CONFIG_PAX_SOFTMODE
20215 +extern unsigned int pax_softmode;
20216 +#endif
20217 +
20218 +extern int pax_check_flags(unsigned long *);
20219 +
20220 +/* if tsk != current then task_lock must be held on it */
20221 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
20222 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
20223 +{
20224 +       if (likely(tsk->mm))
20225 +               return tsk->mm->pax_flags;
20226 +       else
20227 +               return 0UL;
20228 +}
20229 +
20230 +/* if tsk != current then task_lock must be held on it */
20231 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
20232 +{
20233 +       if (likely(tsk->mm)) {
20234 +               tsk->mm->pax_flags = flags;
20235 +               return 0;
20236 +       }
20237 +       return -EINVAL;
20238 +}
20239 +#endif
20240 +
20241 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20242 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
20243 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
20244 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
20245 +#endif
20246 +
20247  /*
20248   * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
20249   * disabled, then there's a single shared list of VMAs maintained by the
20250 @@ -167,6 +203,18 @@ extern unsigned int kobjsize(const void 
20251  #define VM_MAPPED_COPY 0x01000000      /* T if mapped copy of data (nommu mmap) */
20252  #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
20253  
20254 +#ifdef CONFIG_PAX_SEGMEXEC
20255 +#define VM_MIRROR      0x04000000      /* vma is mirroring another */
20256 +#endif
20257 +
20258 +#ifdef CONFIG_PAX_MPROTECT
20259 +#define VM_MAYNOTWRITE 0x08000000      /* vma cannot be granted VM_WRITE any more */
20260 +#endif
20261 +
20262 +#ifdef __VM_STACK_FLAGS
20263 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
20264 +#endif
20265 +
20266  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
20267  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
20268  #endif
20269 @@ -1056,5 +1104,11 @@ void drop_slab(void);
20270  extern int randomize_va_space;
20271  #endif
20272  
20273 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
20274 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
20275 +#else
20276 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
20277 +#endif
20278 +
20279  #endif /* __KERNEL__ */
20280  #endif /* _LINUX_MM_H */
20281 diff -urNp linux-2.6.16.12/include/linux/module.h linux-2.6.16.12/include/linux/module.h
20282 --- linux-2.6.16.12/include/linux/module.h      2006-05-01 15:14:26.000000000 -0400
20283 +++ linux-2.6.16.12/include/linux/module.h      2006-05-01 20:17:34.000000000 -0400
20284 @@ -263,16 +263,16 @@ struct module
20285         int (*init)(void);
20286  
20287         /* If this is non-NULL, vfree after init() returns */
20288 -       void *module_init;
20289 +       void *module_init_rx, *module_init_rw;
20290  
20291         /* Here is the actual code + data, vfree'd on unload. */
20292 -       void *module_core;
20293 +       void *module_core_rx, *module_core_rw;
20294  
20295         /* Here are the sizes of the init and core sections */
20296 -       unsigned long init_size, core_size;
20297 +       unsigned long init_size_rw, core_size_rw;
20298  
20299         /* The size of the executable code in each section.  */
20300 -       unsigned long init_text_size, core_text_size;
20301 +       unsigned long init_size_rx, core_size_rx;
20302  
20303         /* Arch-specific module values */
20304         struct mod_arch_specific arch;
20305 diff -urNp linux-2.6.16.12/include/linux/moduleloader.h linux-2.6.16.12/include/linux/moduleloader.h
20306 --- linux-2.6.16.12/include/linux/moduleloader.h        2006-05-01 15:14:26.000000000 -0400
20307 +++ linux-2.6.16.12/include/linux/moduleloader.h        2006-05-01 20:17:34.000000000 -0400
20308 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
20309     sections.  Returns NULL on failure. */
20310  void *module_alloc(unsigned long size);
20311  
20312 +#ifdef CONFIG_PAX_KERNEXEC
20313 +void *module_alloc_exec(unsigned long size);
20314 +#else
20315 +#define module_alloc_exec(x) module_alloc(x)
20316 +#endif
20317 +
20318  /* Free memory returned from module_alloc. */
20319  void module_free(struct module *mod, void *module_region);
20320  
20321 +#ifdef CONFIG_PAX_KERNEXEC
20322 +void module_free_exec(struct module *mod, void *module_region);
20323 +#else
20324 +#define module_free_exec(x, y) module_free(x, y)
20325 +#endif
20326 +
20327  /* Apply the given relocation to the (simplified) ELF.  Return -error
20328     or 0. */
20329  int apply_relocate(Elf_Shdr *sechdrs,
20330 diff -urNp linux-2.6.16.12/include/linux/random.h linux-2.6.16.12/include/linux/random.h
20331 --- linux-2.6.16.12/include/linux/random.h      2006-05-01 15:14:26.000000000 -0400
20332 +++ linux-2.6.16.12/include/linux/random.h      2006-05-01 20:17:34.000000000 -0400
20333 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
20334  extern u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
20335                                        __u16 sport, __u16 dport);
20336  
20337 +extern unsigned long pax_get_random_long(void);
20338 +
20339  #ifndef MODULE
20340  extern struct file_operations random_fops, urandom_fops;
20341  #endif
20342 diff -urNp linux-2.6.16.12/include/linux/sched.h linux-2.6.16.12/include/linux/sched.h
20343 --- linux-2.6.16.12/include/linux/sched.h       2006-05-01 15:14:26.000000000 -0400
20344 +++ linux-2.6.16.12/include/linux/sched.h       2006-05-01 20:17:34.000000000 -0400
20345 @@ -40,6 +40,7 @@
20346  #include <linux/auxvec.h>      /* For AT_VECTOR_SIZE */
20347  
20348  struct exec_domain;
20349 +struct linux_binprm;
20350  
20351  /*
20352   * cloning flags:
20353 @@ -355,8 +356,34 @@ struct mm_struct {
20354         /* aio bits */
20355         rwlock_t                ioctx_list_lock;
20356         struct kioctx           *ioctx_list;
20357 +
20358 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
20359 +       unsigned long pax_flags;
20360 +#endif
20361 +
20362 +#ifdef CONFIG_PAX_DLRESOLVE
20363 +       unsigned long call_dl_resolve;
20364 +#endif
20365 +
20366 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
20367 +       unsigned long call_syscall;
20368 +#endif
20369 +
20370 +#ifdef CONFIG_PAX_ASLR
20371 +       unsigned long delta_mmap;               /* randomized offset */
20372 +       unsigned long delta_exec;               /* randomized offset */
20373 +       unsigned long delta_stack;              /* randomized offset */
20374 +#endif
20375 +
20376  };
20377  
20378 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
20379 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
20380 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
20381 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
20382 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
20383 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
20384 +
20385  struct sighand_struct {
20386         atomic_t                count;
20387         struct k_sigaction      action[_NSIG];
20388 @@ -461,6 +488,15 @@ struct signal_struct {
20389         struct key *session_keyring;    /* keyring inherited over fork */
20390         struct key *process_keyring;    /* keyring private to this process */
20391  #endif
20392 +
20393 +#ifdef CONFIG_GRKERNSEC
20394 +       u32 curr_ip;
20395 +       u32 gr_saddr;
20396 +       u32 gr_daddr;
20397 +       u16 gr_sport;
20398 +       u16 gr_dport;
20399 +       u8 used_accept:1;
20400 +#endif
20401  };
20402  
20403  /* Context switch must be unlocked if interrupts are to be enabled */
20404 @@ -886,6 +912,16 @@ struct task_struct {
20405         nodemask_t mems_allowed;
20406         int cpuset_mems_generation;
20407  #endif
20408 +#ifdef CONFIG_GRKERNSEC
20409 +       /* grsecurity */
20410 +       struct acl_subject_label *acl;
20411 +       struct acl_role_label *role;
20412 +       struct file *exec_file;
20413 +       u16 acl_role_id;
20414 +       u8 acl_sp_role:1;
20415 +       u8 is_writable:1;
20416 +       u8 brute:1;
20417 +#endif
20418         atomic_t fs_excl;       /* holding fs exclusive resources */
20419         struct rcu_head rcu;
20420  };
20421 @@ -1402,6 +1442,12 @@ extern void arch_pick_mmap_layout(struct
20422  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
20423  {
20424         mm->mmap_base = TASK_UNMAPPED_BASE;
20425 +
20426 +#ifdef CONFIG_PAX_RANDMMAP
20427 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
20428 +               mm->mmap_base += mm->delta_mmap;
20429 +#endif
20430 +
20431         mm->get_unmapped_area = arch_get_unmapped_area;
20432         mm->unmap_area = arch_unmap_area;
20433  }
20434 diff -urNp linux-2.6.16.12/include/linux/shm.h linux-2.6.16.12/include/linux/shm.h
20435 --- linux-2.6.16.12/include/linux/shm.h 2006-05-01 15:14:26.000000000 -0400
20436 +++ linux-2.6.16.12/include/linux/shm.h 2006-05-01 20:17:34.000000000 -0400
20437 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
20438         pid_t                   shm_cprid;
20439         pid_t                   shm_lprid;
20440         struct user_struct      *mlock_user;
20441 +#ifdef CONFIG_GRKERNSEC
20442 +       time_t                  shm_createtime;
20443 +       pid_t                   shm_lapid;
20444 +#endif
20445  };
20446  
20447  /* shm_mode upper byte flags */
20448 diff -urNp linux-2.6.16.12/include/linux/sysctl.h linux-2.6.16.12/include/linux/sysctl.h
20449 --- linux-2.6.16.12/include/linux/sysctl.h      2006-05-01 15:14:26.000000000 -0400
20450 +++ linux-2.6.16.12/include/linux/sysctl.h      2006-05-01 20:17:34.000000000 -0400
20451 @@ -78,9 +78,21 @@
20452         INOTIFY_MAX_QUEUED_EVENTS=3     /* max queued events per instance */
20453  };
20454  
20455 +#ifdef CONFIG_PAX_SOFTMODE
20456 +enum {
20457 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
20458 +};
20459 +#endif
20460 +
20461  /* CTL_KERN names: */
20462  enum
20463  {
20464 +#ifdef CONFIG_GRKERNSEC
20465 +       KERN_GRSECURITY=98,     /* grsecurity */
20466 +#endif
20467 +#ifdef CONFIG_PAX_SOFTMODE
20468 +       KERN_PAX=99,            /* PaX control */
20469 +#endif
20470         KERN_OSTYPE=1,          /* string: system version */
20471         KERN_OSRELEASE=2,       /* string: system release */
20472         KERN_OSREV=3,           /* int: system revision */
20473 diff -urNp linux-2.6.16.12/init/Kconfig linux-2.6.16.12/init/Kconfig
20474 --- linux-2.6.16.12/init/Kconfig        2006-05-01 15:14:26.000000000 -0400
20475 +++ linux-2.6.16.12/init/Kconfig        2006-05-01 20:17:34.000000000 -0400
20476 @@ -257,6 +257,7 @@ menuconfig EMBEDDED
20477  config KALLSYMS
20478          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
20479          default y
20480 +        depends on !GRKERNSEC_HIDESYM
20481          help
20482            Say Y here to let the kernel print out symbolic crash information and
20483            symbolic stack backtraces. This increases the size of the kernel
20484 diff -urNp linux-2.6.16.12/init/main.c linux-2.6.16.12/init/main.c
20485 --- linux-2.6.16.12/init/main.c 2006-05-01 15:14:26.000000000 -0400
20486 +++ linux-2.6.16.12/init/main.c 2006-05-01 20:17:34.000000000 -0400
20487 @@ -100,6 +100,7 @@ static inline void mark_rodata_ro(void) 
20488  #ifdef CONFIG_TC
20489  extern void tc_init(void);
20490  #endif
20491 +extern void grsecurity_init(void);
20492  
20493  enum system_states system_state;
20494  EXPORT_SYMBOL(system_state);
20495 @@ -150,6 +151,15 @@ static int __init maxcpus(char *str)
20496  
20497  __setup("maxcpus=", maxcpus);
20498  
20499 +#ifdef CONFIG_PAX_SOFTMODE
20500 +static int __init setup_pax_softmode(char *str)
20501 +{
20502 +       get_option(&str, &pax_softmode);
20503 +       return 1;
20504 +}
20505 +__setup("pax_softmode=", setup_pax_softmode);
20506 +#endif
20507 +
20508  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
20509  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
20510  static const char *panic_later, *panic_param;
20511 @@ -701,6 +711,8 @@ static int init(void * unused)
20512                 prepare_namespace();
20513         }
20514  
20515 +       grsecurity_init();
20516 +
20517         /*
20518          * Ok, we have completed the initial bootup, and
20519          * we're essentially up and running. Get rid of the
20520 diff -urNp linux-2.6.16.12/ipc/msg.c linux-2.6.16.12/ipc/msg.c
20521 --- linux-2.6.16.12/ipc/msg.c   2006-05-01 15:14:26.000000000 -0400
20522 +++ linux-2.6.16.12/ipc/msg.c   2006-05-01 20:17:34.000000000 -0400
20523 @@ -28,6 +28,7 @@
20524  #include <linux/syscalls.h>
20525  #include <linux/audit.h>
20526  #include <linux/seq_file.h>
20527 +#include <linux/grsecurity.h>
20528  #include <asm/current.h>
20529  #include <asm/uaccess.h>
20530  #include "util.h"
20531 @@ -234,6 +235,9 @@ asmlinkage long sys_msgget (key_t key, i
20532                 msg_unlock(msq);
20533         }
20534         up(&msg_ids.sem);
20535 +
20536 +       gr_log_msgget(ret, msgflg);
20537 +
20538         return ret;
20539  }
20540  
20541 @@ -485,6 +489,8 @@ asmlinkage long sys_msgctl (int msqid, i
20542                 break;
20543         }
20544         case IPC_RMID:
20545 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
20546 +
20547                 freeque (msq, msqid); 
20548                 break;
20549         }
20550 diff -urNp linux-2.6.16.12/ipc/sem.c linux-2.6.16.12/ipc/sem.c
20551 --- linux-2.6.16.12/ipc/sem.c   2006-05-01 15:14:26.000000000 -0400
20552 +++ linux-2.6.16.12/ipc/sem.c   2006-05-01 20:17:34.000000000 -0400
20553 @@ -76,6 +76,7 @@
20554  #include <linux/capability.h>
20555  #include <linux/seq_file.h>
20556  #include <linux/vs_limit.h>
20557 +#include <linux/grsecurity.h>
20558  #include <asm/uaccess.h>
20559  #include "util.h"
20560  
20561 @@ -247,6 +248,9 @@ asmlinkage long sys_semget (key_t key, i
20562         }
20563  
20564         up(&sem_ids.sem);
20565 +
20566 +       gr_log_semget(err, semflg);
20567 +
20568         return err;
20569  }
20570  
20571 @@ -840,6 +844,8 @@ static int semctl_down(int semid, int se
20572  
20573         switch(cmd){
20574         case IPC_RMID:
20575 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
20576 +
20577                 freeary(sma, semid);
20578                 err = 0;
20579                 break;
20580 diff -urNp linux-2.6.16.12/ipc/shm.c linux-2.6.16.12/ipc/shm.c
20581 --- linux-2.6.16.12/ipc/shm.c   2006-05-01 15:14:26.000000000 -0400
20582 +++ linux-2.6.16.12/ipc/shm.c   2006-05-01 20:17:34.000000000 -0400
20583 @@ -32,6 +32,7 @@
20584  #include <linux/seq_file.h>
20585  #include <linux/vs_context.h>
20586  #include <linux/vs_limit.h>
20587 +#include <linux/grsecurity.h>
20588  
20589  #include <asm/uaccess.h>
20590  
20591 @@ -55,6 +56,14 @@ static void shm_close (struct vm_area_st
20592  static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
20593  #endif
20594  
20595 +#ifdef CONFIG_GRKERNSEC
20596 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
20597 +                          const time_t shm_createtime, const uid_t cuid,
20598 +                          const int shmid);
20599 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
20600 +                          const time_t shm_createtime);
20601 +#endif
20602 +
20603  size_t shm_ctlmax = SHMMAX;
20604  size_t         shm_ctlall = SHMALL;
20605  int    shm_ctlmni = SHMMNI;
20606 @@ -154,6 +163,17 @@ static void shm_close (struct vm_area_st
20607         shp->shm_lprid = current->tgid;
20608         shp->shm_dtim = get_seconds();
20609         shp->shm_nattch--;
20610 +#ifdef CONFIG_GRKERNSEC_SHM
20611 +       if (grsec_enable_shm) {
20612 +               if (shp->shm_nattch == 0) {
20613 +                       shp->shm_perm.mode |= SHM_DEST;
20614 +                       shm_destroy(shp);
20615 +               } else
20616 +                       shm_unlock(shp);
20617 +               up(&shm_ids.sem);
20618 +               return;
20619 +       }
20620 +#endif
20621         if(shp->shm_nattch == 0 &&
20622            shp->shm_perm.mode & SHM_DEST)
20623                 shm_destroy (shp);
20624 @@ -256,6 +276,9 @@ static int newseg (key_t key, int shmflg
20625         shp->shm_lprid = 0;
20626         shp->shm_atim = shp->shm_dtim = 0;
20627         shp->shm_ctim = get_seconds();
20628 +#ifdef CONFIG_GRKERNSEC
20629 +       shp->shm_createtime = get_seconds();
20630 +#endif
20631         shp->shm_segsz = size;
20632         shp->shm_nattch = 0;
20633         shp->id = shm_buildid(id,shp->shm_perm.seq);
20634 @@ -312,6 +335,8 @@ asmlinkage long sys_shmget (key_t key, s
20635         }
20636         up(&shm_ids.sem);
20637  
20638 +       gr_log_shmget(err, shmflg, size);
20639 +
20640         return err;
20641  }
20642  
20643 @@ -617,6 +642,8 @@ asmlinkage long sys_shmctl (int shmid, i
20644                 if (err)
20645                         goto out_unlock_up;
20646  
20647 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
20648 +
20649                 if (shp->shm_nattch){
20650                         shp->shm_perm.mode |= SHM_DEST;
20651                         /* Do not find it any more */
20652 @@ -761,9 +788,27 @@ long do_shmat(int shmid, char __user *sh
20653                 return err;
20654         }
20655                 
20656 +#ifdef CONFIG_GRKERNSEC
20657 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
20658 +                            shp->shm_perm.cuid, shmid)) {
20659 +               shm_unlock(shp);
20660 +               return -EACCES;
20661 +       }
20662 +
20663 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
20664 +               shm_unlock(shp);
20665 +               return -EACCES;
20666 +       }
20667 +#endif
20668 +
20669         file = shp->shm_file;
20670         size = i_size_read(file->f_dentry->d_inode);
20671         shp->shm_nattch++;
20672 +
20673 +#ifdef CONFIG_GRKERNSEC
20674 +       shp->shm_lapid = current->pid;
20675 +#endif
20676 +
20677         shm_unlock(shp);
20678  
20679         down_write(&current->mm->mmap_sem);
20680 @@ -933,3 +978,24 @@ static int sysvipc_shm_proc_show(struct 
20681                           shp->shm_ctim);
20682  }
20683  #endif
20684 +
20685 +void gr_shm_exit(struct task_struct *task)
20686 +{
20687 +#ifdef CONFIG_GRKERNSEC_SHM
20688 +       int i;
20689 +       struct shmid_kernel *shp;
20690 +
20691 +       if (!grsec_enable_shm)
20692 +               return;
20693 +
20694 +       for (i = 0; i <= shm_ids.max_id; i++) {
20695 +               shp = shm_get(i);
20696 +               if (shp && (shp->shm_cprid == task->pid) &&
20697 +                   (shp->shm_nattch <= 0)) {
20698 +                       shp->shm_perm.mode |= SHM_DEST;
20699 +                       shm_destroy(shp);
20700 +               }
20701 +       }
20702 +#endif
20703 +       return;
20704 +}
20705 diff -urNp linux-2.6.16.12/kernel/capability.c linux-2.6.16.12/kernel/capability.c
20706 --- linux-2.6.16.12/kernel/capability.c 2006-05-01 15:14:26.000000000 -0400
20707 +++ linux-2.6.16.12/kernel/capability.c 2006-05-01 20:17:34.000000000 -0400
20708 @@ -13,6 +13,7 @@
20709  #include <linux/security.h>
20710  #include <linux/syscalls.h>
20711  #include <linux/vs_pid.h>
20712 +#include <linux/grsecurity.h>
20713  #include <asm/uaccess.h>
20714  
20715  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
20716 diff -urNp linux-2.6.16.12/kernel/configs.c linux-2.6.16.12/kernel/configs.c
20717 --- linux-2.6.16.12/kernel/configs.c    2006-05-01 15:14:26.000000000 -0400
20718 +++ linux-2.6.16.12/kernel/configs.c    2006-05-01 20:17:34.000000000 -0400
20719 @@ -89,8 +89,16 @@ static int __init ikconfig_init(void)
20720         struct proc_dir_entry *entry;
20721  
20722         /* create the current config file */
20723 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
20724 +#ifdef CONFIG_GRKERNSEC_PROC_USER
20725 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
20726 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
20727 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
20728 +#endif
20729 +#else
20730         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
20731                                   &proc_root);
20732 +#endif
20733         if (!entry)
20734                 return -ENOMEM;
20735  
20736 diff -urNp linux-2.6.16.12/kernel/exit.c linux-2.6.16.12/kernel/exit.c
20737 --- linux-2.6.16.12/kernel/exit.c       2006-05-01 15:14:26.000000000 -0400
20738 +++ linux-2.6.16.12/kernel/exit.c       2006-05-01 20:17:34.000000000 -0400
20739 @@ -35,6 +35,11 @@
20740  #include <linux/vs_context.h>
20741  #include <linux/vs_network.h>
20742  #include <linux/vs_pid.h>
20743 +#include <linux/grsecurity.h>
20744 +
20745 +#ifdef CONFIG_GRKERNSEC
20746 +extern rwlock_t grsec_exec_file_lock;
20747 +#endif
20748  
20749  #include <asm/uaccess.h>
20750  #include <asm/unistd.h>
20751 @@ -238,6 +244,15 @@ static void reparent_to_init(void)
20752  {
20753         write_lock_irq(&tasklist_lock);
20754  
20755 +#ifdef CONFIG_GRKERNSEC
20756 +       write_lock(&grsec_exec_file_lock);
20757 +       if (current->exec_file) {
20758 +               fput(current->exec_file);
20759 +               current->exec_file = NULL;
20760 +       }
20761 +       write_unlock(&grsec_exec_file_lock);
20762 +#endif
20763 +
20764         ptrace_unlink(current);
20765         /* Reparent to init */
20766         REMOVE_LINKS(current);
20767 @@ -245,6 +259,8 @@ static void reparent_to_init(void)
20768         current->real_parent = child_reaper;
20769         SET_LINKS(current);
20770  
20771 +       gr_set_kernel_label(current);
20772 +
20773         /* Set the exit signal to SIGCHLD so we signal init on exit */
20774         current->exit_signal = SIGCHLD;
20775  
20776 @@ -341,6 +357,17 @@ void daemonize(const char *name, ...)
20777         vsnprintf(current->comm, sizeof(current->comm), name, args);
20778         va_end(args);
20779  
20780 +#ifdef CONFIG_GRKERNSEC
20781 +       write_lock(&grsec_exec_file_lock);
20782 +       if (current->exec_file) {
20783 +               fput(current->exec_file);
20784 +               current->exec_file = NULL;
20785 +       }
20786 +       write_unlock(&grsec_exec_file_lock);
20787 +#endif
20788 +
20789 +       gr_set_kernel_label(current);
20790 +
20791         /*
20792          * If we were started as result of loading a module, close all of the
20793          * user space pages.  We don't need them, and if we didn't close them
20794 @@ -863,9 +890,14 @@ fastcall NORET_TYPE void do_exit(long co
20795                 exit_itimers(tsk->signal);
20796                 acct_process(code);
20797         }
20798 +
20799 +       gr_acl_handle_psacct(tsk, code);
20800 +       gr_acl_handle_exit();
20801 +
20802         exit_mm(tsk);
20803  
20804         exit_sem(tsk);
20805 +       gr_shm_exit(tsk);
20806         __exit_files(tsk);
20807         __exit_fs(tsk);
20808         exit_namespace(tsk);
20809 diff -urNp linux-2.6.16.12/kernel/fork.c linux-2.6.16.12/kernel/fork.c
20810 --- linux-2.6.16.12/kernel/fork.c       2006-05-01 15:14:26.000000000 -0400
20811 +++ linux-2.6.16.12/kernel/fork.c       2006-05-01 20:17:34.000000000 -0400
20812 @@ -48,6 +48,7 @@
20813  #include <linux/vs_network.h>
20814  #include <linux/vs_limit.h>
20815  #include <linux/vs_memory.h>
20816 +#include <linux/grsecurity.h>
20817  
20818  #include <asm/pgtable.h>
20819  #include <asm/pgalloc.h>
20820 @@ -207,8 +208,8 @@ static inline int dup_mmap(struct mm_str
20821         mm->locked_vm = 0;
20822         mm->mmap = NULL;
20823         mm->mmap_cache = NULL;
20824 -       mm->free_area_cache = oldmm->mmap_base;
20825 -       mm->cached_hole_size = ~0UL;
20826 +       mm->free_area_cache = oldmm->free_area_cache;
20827 +       mm->cached_hole_size = oldmm->cached_hole_size;
20828         mm->map_count = 0;
20829         __set_mm_counter(mm, file_rss, 0);
20830         __set_mm_counter(mm, anon_rss, 0);
20831 @@ -333,7 +334,7 @@ static struct mm_struct * mm_init(struct
20832         spin_lock_init(&mm->page_table_lock);
20833         rwlock_init(&mm->ioctx_list_lock);
20834         mm->ioctx_list = NULL;
20835 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
20836 +       mm->free_area_cache = ~0UL;
20837         mm->cached_hole_size = ~0UL;
20838  
20839         if (likely(!mm_alloc_pgd(mm))) {
20840 @@ -1013,6 +1014,9 @@ static task_t *copy_process(unsigned lon
20841         if (!vx_nproc_avail(1))
20842                 goto bad_fork_cleanup_vm;
20843  
20844 +
20845 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
20846 +
20847         if (atomic_read(&p->user->processes) >=
20848                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
20849                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
20850 @@ -1122,6 +1126,8 @@ static task_t *copy_process(unsigned lon
20851         if (retval)
20852                 goto bad_fork_cleanup_namespace;
20853  
20854 +       gr_copy_label(p);
20855 +
20856         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
20857         /*
20858          * Clear TID on mm_release()?
20859 @@ -1321,6 +1327,8 @@ bad_fork_cleanup_count:
20860  bad_fork_free:
20861         free_task(p);
20862  fork_out:
20863 +       gr_log_forkfail(retval);
20864 +
20865         return ERR_PTR(retval);
20866  }
20867  
20868 @@ -1387,6 +1395,8 @@ long do_fork(unsigned long clone_flags,
20869                 return -EPERM;
20870         }
20871  
20872 +       gr_handle_brute_check();
20873 +
20874         if (unlikely(current->ptrace)) {
20875                 trace = fork_traceflag (clone_flags);
20876                 if (trace)
20877 diff -urNp linux-2.6.16.12/kernel/futex.c linux-2.6.16.12/kernel/futex.c
20878 --- linux-2.6.16.12/kernel/futex.c      2006-05-01 15:14:26.000000000 -0400
20879 +++ linux-2.6.16.12/kernel/futex.c      2006-05-01 20:17:34.000000000 -0400
20880 @@ -147,6 +147,11 @@ static int get_futex_key(unsigned long u
20881         struct page *page;
20882         int err;
20883  
20884 +#ifdef CONFIG_PAX_SEGMEXEC
20885 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (uaddr >= SEGMEXEC_TASK_SIZE))
20886 +               return -EFAULT;
20887 +#endif
20888 +
20889         /*
20890          * The futex address must be "naturally" aligned.
20891          */
20892 diff -urNp linux-2.6.16.12/kernel/kallsyms.c linux-2.6.16.12/kernel/kallsyms.c
20893 --- linux-2.6.16.12/kernel/kallsyms.c   2006-05-01 15:14:26.000000000 -0400
20894 +++ linux-2.6.16.12/kernel/kallsyms.c   2006-05-01 20:17:34.000000000 -0400
20895 @@ -301,7 +301,6 @@ static unsigned long get_ksymbol_core(st
20896  
20897  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
20898  {
20899 -       iter->name[0] = '\0';
20900         iter->nameoff = get_symbol_offset(new_pos);
20901         iter->pos = new_pos;
20902  }
20903 @@ -380,7 +379,7 @@ static int kallsyms_open(struct inode *i
20904         struct kallsym_iter *iter;
20905         int ret;
20906  
20907 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
20908 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
20909         if (!iter)
20910                 return -ENOMEM;
20911         reset_iter(iter, 0);
20912 @@ -411,7 +410,15 @@ static int __init kallsyms_init(void)
20913  {
20914         struct proc_dir_entry *entry;
20915  
20916 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
20917 +#ifdef CONFIG_GRKERNSEC_PROC_USER
20918 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
20919 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
20920 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
20921 +#endif
20922 +#else
20923         entry = create_proc_entry("kallsyms", 0444, NULL);
20924 +#endif
20925         if (entry)
20926                 entry->proc_fops = &kallsyms_operations;
20927         return 0;
20928 diff -urNp linux-2.6.16.12/kernel/kprobes.c linux-2.6.16.12/kernel/kprobes.c
20929 --- linux-2.6.16.12/kernel/kprobes.c    2006-05-01 15:14:26.000000000 -0400
20930 +++ linux-2.6.16.12/kernel/kprobes.c    2006-05-01 20:17:34.000000000 -0400
20931 @@ -106,7 +106,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
20932          * kernel image and loaded module images reside. This is required
20933          * so x86_64 can correctly handle the %rip-relative fixups.
20934          */
20935 -       kip->insns = module_alloc(PAGE_SIZE);
20936 +       kip->insns = module_alloc_exec(PAGE_SIZE);
20937         if (!kip->insns) {
20938                 kfree(kip);
20939                 return NULL;
20940 diff -urNp linux-2.6.16.12/kernel/module.c linux-2.6.16.12/kernel/module.c
20941 --- linux-2.6.16.12/kernel/module.c     2006-05-01 15:14:26.000000000 -0400
20942 +++ linux-2.6.16.12/kernel/module.c     2006-05-01 20:17:34.000000000 -0400
20943 @@ -39,10 +39,15 @@
20944  #include <linux/device.h>
20945  #include <linux/string.h>
20946  #include <linux/sched.h>
20947 +#include <linux/kallsyms.h>
20948  #include <asm/uaccess.h>
20949  #include <asm/semaphore.h>
20950  #include <asm/cacheflush.h>
20951  
20952 +#ifdef CONFIG_PAX_KERNEXEC
20953 +#include <asm/desc.h>
20954 +#endif
20955 +
20956  #if 0
20957  #define DEBUGP printk
20958  #else
20959 @@ -66,6 +71,8 @@ static LIST_HEAD(modules);
20960  static DECLARE_MUTEX(notify_mutex);
20961  static struct notifier_block * module_notify_list;
20962  
20963 +extern int gr_check_modstop(void);
20964 +
20965  int register_module_notifier(struct notifier_block * nb)
20966  {
20967         int err;
20968 @@ -576,6 +583,9 @@ sys_delete_module(const char __user *nam
20969         char name[MODULE_NAME_LEN];
20970         int ret, forced = 0;
20971  
20972 +       if (gr_check_modstop())
20973 +               return -EPERM;
20974 +
20975         if (!capable(CAP_SYS_MODULE))
20976                 return -EPERM;
20977  
20978 @@ -1178,13 +1188,15 @@ static void free_module(struct module *m
20979         module_unload_free(mod);
20980  
20981         /* This may be NULL, but that's OK */
20982 -       module_free(mod, mod->module_init);
20983 +       module_free(mod, mod->module_init_rw);
20984 +       module_free_exec(mod, mod->module_init_rx);
20985         kfree(mod->args);
20986         if (mod->percpu)
20987                 percpu_modfree(mod->percpu);
20988  
20989         /* Finally, free the core (containing the module structure) */
20990 -       module_free(mod, mod->module_core);
20991 +       module_free_exec(mod, mod->module_core_rx);
20992 +       module_free(mod, mod->module_core_rw);
20993  }
20994  
20995  void *__symbol_get(const char *symbol)
20996 @@ -1341,11 +1353,14 @@ static void layout_sections(struct modul
20997                             || strncmp(secstrings + s->sh_name,
20998                                        ".init", 5) == 0)
20999                                 continue;
21000 -                       s->sh_entsize = get_offset(&mod->core_size, s);
21001 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
21002 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
21003 +                       else
21004 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
21005                         DEBUGP("\t%s\n", secstrings + s->sh_name);
21006                 }
21007                 if (m == 0)
21008 -                       mod->core_text_size = mod->core_size;
21009 +                       mod->core_size_rx = mod->core_size_rx;
21010         }
21011  
21012         DEBUGP("Init section allocation order:\n");
21013 @@ -1359,12 +1374,15 @@ static void layout_sections(struct modul
21014                             || strncmp(secstrings + s->sh_name,
21015                                        ".init", 5) != 0)
21016                                 continue;
21017 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
21018 -                                        | INIT_OFFSET_MASK);
21019 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
21020 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
21021 +                       else
21022 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
21023 +                       s->sh_entsize |= INIT_OFFSET_MASK;
21024                         DEBUGP("\t%s\n", secstrings + s->sh_name);
21025                 }
21026                 if (m == 0)
21027 -                       mod->init_text_size = mod->init_size;
21028 +                       mod->init_size_rx = mod->init_size_rx;
21029         }
21030  }
21031  
21032 @@ -1545,6 +1563,10 @@ static struct module *load_module(void _
21033         struct exception_table_entry *extable;
21034         mm_segment_t old_fs;
21035  
21036 +#ifdef CONFIG_PAX_KERNEXEC
21037 +       unsigned long cr0;
21038 +#endif
21039 +
21040         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
21041                umod, len, uargs);
21042         if (len < sizeof(*hdr))
21043 @@ -1704,21 +1726,57 @@ static struct module *load_module(void _
21044         layout_sections(mod, hdr, sechdrs, secstrings);
21045  
21046         /* Do the allocs. */
21047 -       ptr = module_alloc(mod->core_size);
21048 +       ptr = module_alloc(mod->core_size_rw);
21049         if (!ptr) {
21050                 err = -ENOMEM;
21051                 goto free_percpu;
21052         }
21053 -       memset(ptr, 0, mod->core_size);
21054 -       mod->module_core = ptr;
21055 +       memset(ptr, 0, mod->core_size_rw);
21056 +       mod->module_core_rw = ptr;
21057 +
21058 +       ptr = module_alloc(mod->init_size_rw);
21059 +       if (!ptr && mod->init_size_rw) {
21060 +               err = -ENOMEM;
21061 +               goto free_core_rw;
21062 +       }
21063 +       memset(ptr, 0, mod->init_size_rw);
21064 +       mod->module_init_rw = ptr;
21065 +
21066 +       ptr = module_alloc_exec(mod->core_size_rx);
21067 +       if (!ptr) {
21068 +               err = -ENOMEM;
21069 +               goto free_init_rw;
21070 +       }
21071 +
21072 +#ifdef CONFIG_PAX_KERNEXEC
21073 +       pax_open_kernel(cr0);
21074 +#endif
21075 +
21076 +       memset(ptr, 0, mod->core_size_rx);
21077 +
21078 +#ifdef CONFIG_PAX_KERNEXEC
21079 +       pax_close_kernel(cr0);
21080 +#endif
21081 +
21082 +       mod->module_core_rx = ptr;
21083  
21084 -       ptr = module_alloc(mod->init_size);
21085 -       if (!ptr && mod->init_size) {
21086 +       ptr = module_alloc_exec(mod->init_size_rx);
21087 +       if (!ptr && mod->init_size_rx) {
21088                 err = -ENOMEM;
21089 -               goto free_core;
21090 +               goto free_core_rx;
21091         }
21092 -       memset(ptr, 0, mod->init_size);
21093 -       mod->module_init = ptr;
21094 +
21095 +#ifdef CONFIG_PAX_KERNEXEC
21096 +       pax_open_kernel(cr0);
21097 +#endif
21098 +
21099 +       memset(ptr, 0, mod->init_size_rx);
21100 +
21101 +#ifdef CONFIG_PAX_KERNEXEC
21102 +       pax_close_kernel(cr0);
21103 +#endif
21104 +
21105 +       mod->module_init_rx = ptr;
21106  
21107         /* Transfer each section which specifies SHF_ALLOC */
21108         DEBUGP("final section addresses:\n");
21109 @@ -1728,17 +1786,44 @@ static struct module *load_module(void _
21110                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
21111                         continue;
21112  
21113 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
21114 -                       dest = mod->module_init
21115 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
21116 -               else
21117 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
21118 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
21119 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
21120 +                               dest = mod->module_init_rw
21121 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
21122 +                       else
21123 +                               dest = mod->module_init_rx
21124 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
21125 +               } else {
21126 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
21127 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
21128 +                       else
21129 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
21130 +               }
21131  
21132 -               if (sechdrs[i].sh_type != SHT_NOBITS)
21133 -                       memcpy(dest, (void *)sechdrs[i].sh_addr,
21134 -                              sechdrs[i].sh_size);
21135 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
21136 +
21137 +#ifdef CONFIG_PAX_KERNEXEC
21138 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
21139 +                               pax_open_kernel(cr0);
21140 +#endif
21141 +
21142 +                       memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
21143 +
21144 +#ifdef CONFIG_PAX_KERNEXEC
21145 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
21146 +                               pax_close_kernel(cr0);
21147 +#endif
21148 +
21149 +               }
21150                 /* Update sh_addr to point to copy in image. */
21151 -               sechdrs[i].sh_addr = (unsigned long)dest;
21152 +
21153 +#ifdef CONFIG_PAX_KERNEXEC
21154 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
21155 +                       sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
21156 +               else
21157 +#endif
21158 +
21159 +                       sechdrs[i].sh_addr = (unsigned long)dest;
21160                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
21161         }
21162         /* Module has been moved. */
21163 @@ -1761,8 +1846,18 @@ static struct module *load_module(void _
21164  #endif
21165  
21166         /* Fix up syms, so that st_value is a pointer to location. */
21167 +
21168 +#ifdef CONFIG_PAX_KERNEXEC
21169 +       pax_open_kernel(cr0);
21170 +#endif
21171 +
21172         err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
21173                                mod);
21174 +
21175 +#ifdef CONFIG_PAX_KERNEXEC
21176 +       pax_close_kernel(cr0);
21177 +#endif
21178 +
21179         if (err < 0)
21180                 goto cleanup;
21181  
21182 @@ -1798,11 +1893,20 @@ static struct module *load_module(void _
21183                 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
21184                         continue;
21185  
21186 +#ifdef CONFIG_PAX_KERNEXEC
21187 +       pax_open_kernel(cr0);
21188 +#endif
21189 +
21190                 if (sechdrs[i].sh_type == SHT_REL)
21191                         err = apply_relocate(sechdrs, strtab, symindex, i,mod);
21192                 else if (sechdrs[i].sh_type == SHT_RELA)
21193                         err = apply_relocate_add(sechdrs, strtab, symindex, i,
21194                                                  mod);
21195 +
21196 +#ifdef CONFIG_PAX_KERNEXEC
21197 +       pax_close_kernel(cr0);
21198 +#endif
21199 +
21200                 if (err < 0)
21201                         goto cleanup;
21202         }
21203 @@ -1816,14 +1920,31 @@ static struct module *load_module(void _
21204         /* Set up and sort exception table */
21205         mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
21206         mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
21207 +
21208 +#ifdef CONFIG_PAX_KERNEXEC
21209 +       pax_open_kernel(cr0);
21210 +#endif
21211 +
21212         sort_extable(extable, extable + mod->num_exentries);
21213  
21214 +#ifdef CONFIG_PAX_KERNEXEC
21215 +       pax_close_kernel(cr0);
21216 +#endif
21217 +
21218         /* Finally, copy percpu area over. */
21219         percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
21220                        sechdrs[pcpuindex].sh_size);
21221  
21222 +#ifdef CONFIG_PAX_KERNEXEC
21223 +       pax_open_kernel(cr0);
21224 +#endif
21225 +
21226         add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
21227  
21228 +#ifdef CONFIG_PAX_KERNEXEC
21229 +       pax_close_kernel(cr0);
21230 +#endif
21231 +
21232         err = module_finalize(hdr, sechdrs, mod);
21233         if (err < 0)
21234                 goto cleanup;
21235 @@ -1837,12 +1958,12 @@ static struct module *load_module(void _
21236          * Do it before processing of module parameters, so the module
21237          * can provide parameter accessor functions of its own.
21238          */
21239 -       if (mod->module_init)
21240 -               flush_icache_range((unsigned long)mod->module_init,
21241 -                                  (unsigned long)mod->module_init
21242 -                                  + mod->init_size);
21243 -       flush_icache_range((unsigned long)mod->module_core,
21244 -                          (unsigned long)mod->module_core + mod->core_size);
21245 +       if (mod->module_init_rx)
21246 +               flush_icache_range((unsigned long)mod->module_init_rx,
21247 +                                  (unsigned long)mod->module_init_rx
21248 +                                  + mod->init_size_rx);
21249 +       flush_icache_range((unsigned long)mod->module_core_rx,
21250 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
21251  
21252         set_fs(old_fs);
21253  
21254 @@ -1890,9 +2011,13 @@ static struct module *load_module(void _
21255         module_arch_cleanup(mod);
21256   cleanup:
21257         module_unload_free(mod);
21258 -       module_free(mod, mod->module_init);
21259 - free_core:
21260 -       module_free(mod, mod->module_core);
21261 +       module_free_exec(mod, mod->module_init_rx);
21262 + free_core_rx:
21263 +       module_free_exec(mod, mod->module_core_rx);
21264 + free_init_rw:
21265 +       module_free(mod, mod->module_init_rw);
21266 + free_core_rw:
21267 +       module_free(mod, mod->module_core_rw);
21268   free_percpu:
21269         if (percpu)
21270                 percpu_modfree(percpu);
21271 @@ -1928,6 +2053,9 @@ sys_init_module(void __user *umod,
21272         struct module *mod;
21273         int ret = 0;
21274  
21275 +       if (gr_check_modstop())
21276 +               return -EPERM;
21277 +
21278         /* Must have permission */
21279         if (!capable(CAP_SYS_MODULE))
21280                 return -EPERM;
21281 @@ -1979,10 +2107,12 @@ sys_init_module(void __user *umod,
21282         mod->state = MODULE_STATE_LIVE;
21283         /* Drop initial reference. */
21284         module_put(mod);
21285 -       module_free(mod, mod->module_init);
21286 -       mod->module_init = NULL;
21287 -       mod->init_size = 0;
21288 -       mod->init_text_size = 0;
21289 +       module_free(mod, mod->module_init_rw);
21290 +       module_free_exec(mod, mod->module_init_rx);
21291 +       mod->module_init_rw = NULL;
21292 +       mod->module_init_rx = NULL;
21293 +       mod->init_size_rw = 0;
21294 +       mod->init_size_rx = 0;
21295         up(&module_mutex);
21296  
21297         return 0;
21298 @@ -2013,10 +2143,14 @@ static const char *get_ksymbol(struct mo
21299         unsigned long nextval;
21300  
21301         /* At worse, next value is at end of module */
21302 -       if (within(addr, mod->module_init, mod->init_size))
21303 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
21304 -       else 
21305 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
21306 +       if (within(addr, mod->module_init_rx, mod->init_size_rx))
21307 +               nextval = (unsigned long)mod->module_init_rw;
21308 +       else if (within(addr, mod->module_init_rw, mod->init_size_rw))
21309 +               nextval = (unsigned long)mod->module_core_rx;
21310 +       else if (within(addr, mod->module_core_rx, mod->core_size_rx))
21311 +               nextval = (unsigned long)mod->module_core_rw;
21312 +       else
21313 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
21314  
21315         /* Scan for closest preceeding symbol, and next symbol. (ELF
21316             starts real symbols at 1). */
21317 @@ -2057,8 +2191,10 @@ const char *module_address_lookup(unsign
21318         struct module *mod;
21319  
21320         list_for_each_entry(mod, &modules, list) {
21321 -               if (within(addr, mod->module_init, mod->init_size)
21322 -                   || within(addr, mod->module_core, mod->core_size)) {
21323 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
21324 +                   || within(addr, mod->module_init_rw, mod->init_size_rw)
21325 +                   || within(addr, mod->module_core_rx, mod->core_size_rx)
21326 +                   || within(addr, mod->module_core_rw, mod->core_size_rw)) {
21327                         *modname = mod->name;
21328                         return get_ksymbol(mod, addr, size, offset);
21329                 }
21330 @@ -2069,7 +2205,7 @@ const char *module_address_lookup(unsign
21331  struct module *module_get_kallsym(unsigned int symnum,
21332                                   unsigned long *value,
21333                                   char *type,
21334 -                                 char namebuf[128])
21335 +                                 char namebuf[KSYM_NAME_LEN+1])
21336  {
21337         struct module *mod;
21338  
21339 @@ -2080,7 +2216,7 @@ struct module *module_get_kallsym(unsign
21340                         *type = mod->symtab[symnum].st_info;
21341                         strncpy(namebuf,
21342                                 mod->strtab + mod->symtab[symnum].st_name,
21343 -                               127);
21344 +                               KSYM_NAME_LEN);
21345                         up(&module_mutex);
21346                         return mod;
21347                 }
21348 @@ -2157,7 +2293,7 @@ static int m_show(struct seq_file *m, vo
21349  {
21350         struct module *mod = list_entry(p, struct module, list);
21351         seq_printf(m, "%s %lu",
21352 -                  mod->name, mod->init_size + mod->core_size);
21353 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
21354         print_unload_info(m, mod);
21355  
21356         /* Informative for users. */
21357 @@ -2166,7 +2302,7 @@ static int m_show(struct seq_file *m, vo
21358                    mod->state == MODULE_STATE_COMING ? "Loading":
21359                    "Live");
21360         /* Used by oprofile and other similar tools. */
21361 -       seq_printf(m, " 0x%p", mod->module_core);
21362 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
21363  
21364         seq_printf(m, "\n");
21365         return 0;
21366 @@ -2214,9 +2350,13 @@ struct module *__module_text_address(uns
21367  {
21368         struct module *mod;
21369  
21370 +#ifdef CONFIG_PAX_KERNEXEC
21371 +       addr += __KERNEL_TEXT_OFFSET;
21372 +#endif
21373 +
21374         list_for_each_entry(mod, &modules, list)
21375 -               if (within(addr, mod->module_init, mod->init_text_size)
21376 -                   || within(addr, mod->module_core, mod->core_text_size))
21377 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
21378 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
21379                         return mod;
21380         return NULL;
21381  }
21382 diff -urNp linux-2.6.16.12/kernel/pid.c linux-2.6.16.12/kernel/pid.c
21383 --- linux-2.6.16.12/kernel/pid.c        2006-05-01 15:14:26.000000000 -0400
21384 +++ linux-2.6.16.12/kernel/pid.c        2006-05-01 20:17:34.000000000 -0400
21385 @@ -26,6 +26,7 @@
21386  #include <linux/init.h>
21387  #include <linux/bootmem.h>
21388  #include <linux/hash.h>
21389 +#include <linux/grsecurity.h>
21390  
21391  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
21392  static struct hlist_head *pid_hash[PIDTYPE_MAX];
21393 @@ -76,7 +77,9 @@ int alloc_pidmap(void)
21394         int i, offset, max_scan, pid, last = last_pid;
21395         pidmap_t *map;
21396  
21397 -       pid = last + 1;
21398 +       pid = gr_random_pid();
21399 +       if (!pid)
21400 +               pid = last_pid + 1;
21401         if (pid >= pid_max)
21402                 pid = RESERVED_PIDS;
21403         offset = pid & BITS_PER_PAGE_MASK;
21404 @@ -207,12 +210,18 @@ void fastcall detach_pid(task_t *task, e
21405  task_t *find_task_by_pid_type(int type, int nr)
21406  {
21407         struct pid *pid;
21408 +       task_t *task = NULL;
21409  
21410         pid = find_pid(type, nr);
21411         if (!pid)
21412                 return NULL;
21413  
21414 -       return pid_task(&pid->pid_list, type);
21415 +       task = pid_task(&pid->pid_list, type);
21416 +
21417 +       if (gr_pid_is_chrooted(task))
21418 +               return NULL;
21419 +
21420 +       return task;
21421  }
21422  
21423  EXPORT_SYMBOL(find_task_by_pid_type);
21424 diff -urNp linux-2.6.16.12/kernel/posix-cpu-timers.c linux-2.6.16.12/kernel/posix-cpu-timers.c
21425 --- linux-2.6.16.12/kernel/posix-cpu-timers.c   2006-05-01 15:14:26.000000000 -0400
21426 +++ linux-2.6.16.12/kernel/posix-cpu-timers.c   2006-05-01 20:17:34.000000000 -0400
21427 @@ -7,6 +7,7 @@
21428  #include <asm/uaccess.h>
21429  #include <linux/errno.h>
21430  #include <linux/vs_pid.h>
21431 +#include <linux/grsecurity.h>
21432  
21433  static int check_clock(const clockid_t which_clock)
21434  {
21435 @@ -1129,6 +1130,7 @@ static void check_process_timers(struct 
21436                         __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
21437                         return;
21438                 }
21439 +               gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
21440                 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
21441                         /*
21442                          * At the soft limit, send a SIGXCPU every second.
21443 diff -urNp linux-2.6.16.12/kernel/printk.c linux-2.6.16.12/kernel/printk.c
21444 --- linux-2.6.16.12/kernel/printk.c     2006-05-01 15:14:26.000000000 -0400
21445 +++ linux-2.6.16.12/kernel/printk.c     2006-05-01 20:17:34.000000000 -0400
21446 @@ -33,6 +33,7 @@
21447  #include <linux/syscalls.h>
21448  #include <linux/vs_context.h>
21449  #include <linux/vserver/cvirt.h>
21450 +#include <linux/grsecurity.h>
21451  
21452  #include <asm/uaccess.h>
21453  
21454 @@ -225,6 +226,11 @@ int do_syslog(int type, char __user *buf
21455         char c;
21456         int error;
21457  
21458 +#ifdef CONFIG_GRKERNSEC_DMESG
21459 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
21460 +               return -EPERM;
21461 +#endif
21462 +
21463         error = security_syslog(type);
21464         if (error)
21465                 return error;
21466 diff -urNp linux-2.6.16.12/kernel/ptrace.c linux-2.6.16.12/kernel/ptrace.c
21467 --- linux-2.6.16.12/kernel/ptrace.c     2006-05-01 15:14:26.000000000 -0400
21468 +++ linux-2.6.16.12/kernel/ptrace.c     2006-05-01 20:17:34.000000000 -0400
21469 @@ -19,6 +19,7 @@
21470  #include <linux/security.h>
21471  #include <linux/signal.h>
21472  #include <linux/vs_pid.h>
21473 +#include <linux/grsecurity.h>
21474  
21475  #include <asm/pgtable.h>
21476  #include <asm/uaccess.h>
21477 @@ -129,10 +130,10 @@ static int may_attach(struct task_struct
21478              (current->uid != task->uid) ||
21479              (current->gid != task->egid) ||
21480              (current->gid != task->sgid) ||
21481 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
21482 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
21483                 return -EPERM;
21484         smp_rmb();
21485 -       if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
21486 +       if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
21487                 return -EPERM;
21488  
21489         return security_ptrace(current, task);
21490 @@ -500,6 +501,11 @@ asmlinkage long sys_ptrace(long request,
21491         if (ret < 0)
21492                 goto out_put_task_struct;
21493  
21494 +       if (gr_handle_ptrace(child, request)) {
21495 +               ret = -EPERM;
21496 +               goto out_put_task_struct;
21497 +       }
21498 +
21499         ret = arch_ptrace(child, request, addr, data);
21500         if (ret < 0)
21501                 goto out_put_task_struct;
21502 diff -urNp linux-2.6.16.12/kernel/resource.c linux-2.6.16.12/kernel/resource.c
21503 --- linux-2.6.16.12/kernel/resource.c   2006-05-01 15:14:26.000000000 -0400
21504 +++ linux-2.6.16.12/kernel/resource.c   2006-05-01 20:17:34.000000000 -0400
21505 @@ -136,10 +136,27 @@ static int __init ioresources_init(void)
21506  {
21507         struct proc_dir_entry *entry;
21508  
21509 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
21510 +#ifdef CONFIG_GRKERNSEC_PROC_USER
21511 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
21512 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
21513 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
21514 +#endif
21515 +#else
21516         entry = create_proc_entry("ioports", 0, NULL);
21517 +#endif
21518         if (entry)
21519                 entry->proc_fops = &proc_ioports_operations;
21520 +
21521 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
21522 +#ifdef CONFIG_GRKERNSEC_PROC_USER
21523 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
21524 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
21525 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
21526 +#endif
21527 +#else
21528         entry = create_proc_entry("iomem", 0, NULL);
21529 +#endif
21530         if (entry)
21531                 entry->proc_fops = &proc_iomem_operations;
21532         return 0;
21533 diff -urNp linux-2.6.16.12/kernel/sched.c linux-2.6.16.12/kernel/sched.c
21534 --- linux-2.6.16.12/kernel/sched.c      2006-05-01 15:14:26.000000000 -0400
21535 +++ linux-2.6.16.12/kernel/sched.c      2006-05-01 20:17:34.000000000 -0400
21536 @@ -49,6 +49,7 @@
21537  #include <linux/syscalls.h>
21538  #include <linux/times.h>
21539  #include <linux/acct.h>
21540 +#include <linux/grsecurity.h>
21541  #include <asm/tlb.h>
21542  
21543  #include <asm/unistd.h>
21544 @@ -3613,7 +3614,8 @@ asmlinkage long sys_nice(int increment)
21545         if (nice > 19)
21546                 nice = 19;
21547  
21548 -       if (increment < 0 && !can_nice(current, nice))
21549 +       if (increment < 0 && (!can_nice(current, nice) ||
21550 +                             gr_handle_chroot_nice()))
21551                 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
21552  
21553         retval = security_task_setnice(current, nice);
21554 diff -urNp linux-2.6.16.12/kernel/signal.c linux-2.6.16.12/kernel/signal.c
21555 --- linux-2.6.16.12/kernel/signal.c     2006-05-01 15:14:26.000000000 -0400
21556 +++ linux-2.6.16.12/kernel/signal.c     2006-05-01 20:17:34.000000000 -0400
21557 @@ -27,6 +27,7 @@
21558  #include <linux/audit.h>
21559  #include <linux/capability.h>
21560  #include <linux/vs_pid.h>
21561 +#include <linux/grsecurity.h>
21562  #include <asm/param.h>
21563  #include <asm/uaccess.h>
21564  #include <asm/unistd.h>
21565 @@ -381,6 +382,7 @@ void __exit_signal(struct task_struct *t
21566                 }
21567                 if (tsk == sig->curr_target)
21568                         sig->curr_target = next_thread(tsk);
21569 +               gr_del_task_from_ip_table(tsk);
21570                 tsk->signal = NULL;
21571                 /*
21572                  * Accumulate here the counters for all threads but the
21573 @@ -687,11 +689,11 @@ static int check_kill_permission(int sig
21574                 (!is_si_special(info) && SI_FROMUSER(info)));
21575  
21576         error = -EPERM;
21577 -       if (user && ((sig != SIGCONT) ||
21578 +       if (user && ((((sig != SIGCONT) ||
21579                 (current->signal->session != t->signal->session))
21580             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
21581             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
21582 -           && !capable(CAP_KILL))
21583 +           && !capable(CAP_KILL)) || gr_handle_signal(t, sig)))
21584                 return error;
21585  
21586         error = -ESRCH;
21587 @@ -699,8 +701,10 @@ static int check_kill_permission(int sig
21588                 return error;
21589  
21590         error = security_task_kill(t, info, sig);
21591 -       if (!error)
21592 +       if (!error) {
21593                 audit_signal_info(sig, t); /* Let audit system see the signal */
21594 +               gr_log_signal(sig, t);
21595 +       }
21596         return error;
21597  }
21598  
21599 @@ -880,7 +884,7 @@ out_set:
21600         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
21601  
21602  
21603 -static int
21604 +int
21605  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
21606  {
21607         int ret = 0;
21608 @@ -926,6 +930,10 @@ force_sig_info(int sig, struct siginfo *
21609         }
21610         recalc_sigpending_tsk(t);
21611         ret = specific_send_sig_info(sig, info, t);
21612 +
21613 +       gr_log_signal(sig, t);
21614 +       gr_handle_crash(t, sig);
21615 +
21616         spin_unlock_irqrestore(&t->sighand->siglock, flags);
21617  
21618         return ret;
21619 diff -urNp linux-2.6.16.12/kernel/sys.c linux-2.6.16.12/kernel/sys.c
21620 --- linux-2.6.16.12/kernel/sys.c        2006-05-01 15:14:26.000000000 -0400
21621 +++ linux-2.6.16.12/kernel/sys.c        2006-05-01 20:17:34.000000000 -0400
21622 @@ -33,6 +33,7 @@
21623  #include <linux/cn_proc.h>
21624  #include <linux/vs_cvirt.h>
21625  #include <linux/vs_pid.h>
21626 +#include <linux/grsecurity.h>
21627  
21628  #include <linux/compat.h>
21629  #include <linux/syscalls.h>
21630 @@ -228,18 +229,37 @@ int unregister_reboot_notifier(struct no
21631  EXPORT_SYMBOL(unregister_reboot_notifier);
21632  
21633  #ifndef CONFIG_SECURITY
21634 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
21635 +extern int gr_is_capable_nolog(const int cap);
21636  int capable(int cap)
21637  {
21638         if (vx_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
21639                 return 0;
21640 -       if (vx_cap_raised(current->vx_info, current->cap_effective, cap)) {
21641 +       if (vx_cap_raised(current->vx_info, current->cap_effective, cap)
21642 +                       && gr_task_is_capable(current, cap)) {
21643                current->flags |= PF_SUPERPRIV;
21644                return 1;
21645          }
21646          return 0;
21647  }
21648 +int capable_nolog(int cap)
21649 +{
21650 +       if (vx_cap_raised(current->vx_info, current->cap_effective, cap)
21651 +                       && gr_is_capable_nolog(cap)) {
21652 +               current->flags |= PF_SUPERPRIV;
21653 +               return 1;
21654 +       }
21655 +       return 0;
21656 +}
21657  EXPORT_SYMBOL(capable);
21658 +#else
21659 +int capable_nolog(int cap)
21660 +{
21661 +       return capable(cap);
21662 +}
21663 +
21664  #endif
21665 +EXPORT_SYMBOL(capable_nolog);
21666  
21667  static int set_one_prio(struct task_struct *p, int niceval, int error)
21668  {
21669 @@ -257,6 +277,12 @@ static int set_one_prio(struct task_stru
21670                         error = -EACCES;
21671                 goto out;
21672         }
21673 +
21674 +       if (gr_handle_chroot_setpriority(p, niceval)) {
21675 +               error = -EACCES;
21676 +               goto out;
21677 +       }
21678 +
21679         no_nice = security_task_setnice(p, niceval);
21680         if (no_nice) {
21681                 error = no_nice;
21682 @@ -654,6 +680,9 @@ asmlinkage long sys_setregid(gid_t rgid,
21683         if (rgid != (gid_t) -1 ||
21684             (egid != (gid_t) -1 && egid != old_rgid))
21685                 current->sgid = new_egid;
21686 +
21687 +       gr_set_role_label(current, current->uid, new_rgid);
21688 +
21689         current->fsgid = new_egid;
21690         current->egid = new_egid;
21691         current->gid = new_rgid;
21692 @@ -683,6 +712,9 @@ asmlinkage long sys_setgid(gid_t gid)
21693                         current->mm->dumpable = suid_dumpable;
21694                         smp_wmb();
21695                 }
21696 +
21697 +               gr_set_role_label(current, current->uid, gid);
21698 +
21699                 current->gid = current->egid = current->sgid = current->fsgid = gid;
21700         }
21701         else if ((gid == current->gid) || (gid == current->sgid))
21702 @@ -724,6 +756,9 @@ static int set_user(uid_t new_ruid, int 
21703                 current->mm->dumpable = suid_dumpable;
21704                 smp_wmb();
21705         }
21706 +
21707 +       gr_set_role_label(current, new_ruid, current->gid);
21708 +
21709         current->uid = new_ruid;
21710         return 0;
21711  }
21712 @@ -827,6 +862,9 @@ asmlinkage long sys_setuid(uid_t uid)
21713         } else if ((uid != current->uid) && (uid != new_suid))
21714                 return -EPERM;
21715  
21716 +       if (gr_check_crash_uid(uid))
21717 +               return -EPERM;
21718 +
21719         if (old_euid != uid)
21720         {
21721                 current->mm->dumpable = suid_dumpable;
21722 @@ -932,8 +970,10 @@ asmlinkage long sys_setresgid(gid_t rgid
21723                 current->egid = egid;
21724         }
21725         current->fsgid = current->egid;
21726 -       if (rgid != (gid_t) -1)
21727 +       if (rgid != (gid_t) -1) {
21728 +               gr_set_role_label(current, current->uid, rgid);
21729                 current->gid = rgid;
21730 +       }
21731         if (sgid != (gid_t) -1)
21732                 current->sgid = sgid;
21733  
21734 diff -urNp linux-2.6.16.12/kernel/sysctl.c linux-2.6.16.12/kernel/sysctl.c
21735 --- linux-2.6.16.12/kernel/sysctl.c     2006-05-01 15:14:26.000000000 -0400
21736 +++ linux-2.6.16.12/kernel/sysctl.c     2006-05-01 20:17:34.000000000 -0400
21737 @@ -55,6 +55,14 @@ extern int proc_nr_files(ctl_table *tabl
21738                       void __user *buffer, size_t *lenp, loff_t *ppos);
21739  
21740  #if defined(CONFIG_SYSCTL)
21741 +#include <linux/grsecurity.h>
21742 +#include <linux/grinternal.h>
21743 +
21744 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
21745 +                             const void *newval);
21746 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
21747 +                               const int op);
21748 +extern int gr_handle_chroot_sysctl(const int op);
21749  
21750  /* External variables not in a header file. */
21751  extern int C_A_D;
21752 @@ -162,6 +170,22 @@ extern ctl_table inotify_table[];
21753  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
21754  int sysctl_legacy_va_layout;
21755  #endif
21756 +extern ctl_table grsecurity_table[];
21757 +
21758 +#ifdef CONFIG_PAX_SOFTMODE
21759 +static ctl_table pax_table[] = {
21760 +       {
21761 +               .ctl_name       = PAX_SOFTMODE,
21762 +               .procname       = "softmode",
21763 +               .data           = &pax_softmode,
21764 +               .maxlen         = sizeof(unsigned int),
21765 +               .mode           = 0600,
21766 +               .proc_handler   = &proc_dointvec,
21767 +       },
21768 +
21769 +       { .ctl_name = 0 }
21770 +};
21771 +#endif
21772  
21773  /* /proc declarations: */
21774  
21775 @@ -713,6 +737,25 @@ static ctl_table kern_table[] = {
21776                 .proc_handler   = &proc_dointvec,
21777         },
21778  #endif
21779 +
21780 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
21781 +       {
21782 +               .ctl_name       = KERN_GRSECURITY,
21783 +               .procname       = "grsecurity",
21784 +               .mode           = 0500,
21785 +               .child          = grsecurity_table,
21786 +       },
21787 +#endif
21788 +
21789 +#ifdef CONFIG_PAX_SOFTMODE
21790 +       {
21791 +               .ctl_name       = KERN_PAX,
21792 +               .procname       = "pax",
21793 +               .mode           = 0500,
21794 +               .child          = pax_table,
21795 +       },
21796 +#endif
21797 +
21798         { .ctl_name = 0 }
21799  };
21800  
21801 @@ -1211,6 +1254,10 @@ static int test_perm(int mode, int op)
21802  static inline int ctl_perm(ctl_table *table, int op)
21803  {
21804         int error;
21805 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
21806 +               return -EACCES;
21807 +       if (gr_handle_chroot_sysctl(op))
21808 +               return -EACCES;
21809         error = security_sysctl(table, op);
21810         if (error)
21811                 return error;
21812 @@ -1247,6 +1234,10 @@ repeat:
21813                                 table = table->child;
21814                                 goto repeat;
21815                         }
21816 +
21817 +                       if (!gr_handle_sysctl(table, oldval, newval))
21818 +                               return -EACCES;
21819 +
21820                         error = do_sysctl_strategy(table, name, nlen,
21821                                                    oldval, oldlenp,
21822                                                    newval, newlen, context);
21823 diff -urNp linux-2.6.16.12/kernel/time.c linux-2.6.16.12/kernel/time.c
21824 --- linux-2.6.16.12/kernel/time.c       2006-05-01 15:14:26.000000000 -0400
21825 +++ linux-2.6.16.12/kernel/time.c       2006-05-01 20:17:34.000000000 -0400
21826 @@ -36,6 +36,7 @@
21827  #include <linux/security.h>
21828  #include <linux/fs.h>
21829  #include <linux/module.h>
21830 +#include <linux/grsecurity.h>
21831  
21832  #include <asm/uaccess.h>
21833  #include <asm/unistd.h>
21834 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user 
21835                 return err;
21836  
21837         vx_settimeofday(&tv);
21838 +
21839 +       gr_log_timechange();
21840 +
21841         return 0;
21842  }
21843  
21844 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct 
21845                         return -EFAULT;
21846         }
21847  
21848 +       gr_log_timechange();
21849 +
21850         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
21851  }
21852  
21853 diff -urNp linux-2.6.16.12/Makefile linux-2.6.16.12/Makefile
21854 --- linux-2.6.16.12/Makefile    2006-05-01 15:14:26.000000000 -0400
21855 +++ linux-2.6.16.12/Makefile    2006-05-01 20:17:34.000000000 -0400
21856 @@ -556,7 +556,7 @@ export MODLIB
21857  
21858  
21859  ifeq ($(KBUILD_EXTMOD),)
21860 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
21861 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
21862  
21863  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
21864                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
21865 diff -urNp linux-2.6.16.12/mm/filemap.c linux-2.6.16.12/mm/filemap.c
21866 --- linux-2.6.16.12/mm/filemap.c        2006-05-01 15:14:26.000000000 -0400
21867 +++ linux-2.6.16.12/mm/filemap.c        2006-05-01 20:17:34.000000000 -0400
21868 @@ -29,6 +29,7 @@
21869  #include <linux/blkdev.h>
21870  #include <linux/security.h>
21871  #include <linux/syscalls.h>
21872 +#include <linux/grsecurity.h>
21873  #include "filemap.h"
21874  /*
21875   * FIXME: remove all knowledge of the buffer layer from the core VM
21876 @@ -1617,7 +1618,13 @@ int generic_file_mmap(struct file * file
21877         struct address_space *mapping = file->f_mapping;
21878  
21879         if (!mapping->a_ops->readpage)
21880 -               return -ENOEXEC;
21881 +               return -ENODEV;
21882 +
21883 +#ifdef CONFIG_PAX_PAGEEXEC
21884 +       if (vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC)
21885 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
21886 +#endif
21887 +
21888         file_accessed(file);
21889         vma->vm_ops = &generic_file_vm_ops;
21890         return 0;
21891 @@ -1852,6 +1859,7 @@ inline int generic_write_checks(struct f
21892                          *pos = i_size_read(inode);
21893  
21894                 if (limit != RLIM_INFINITY) {
21895 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
21896                         if (*pos >= limit) {
21897                                 send_sig(SIGXFSZ, current, 0);
21898                                 return -EFBIG;
21899 diff -urNp linux-2.6.16.12/mm/madvise.c linux-2.6.16.12/mm/madvise.c
21900 --- linux-2.6.16.12/mm/madvise.c        2006-05-01 15:14:26.000000000 -0400
21901 +++ linux-2.6.16.12/mm/madvise.c        2006-05-01 20:17:34.000000000 -0400
21902 @@ -15,9 +15,46 @@
21903   * We can potentially split a vm area into separate
21904   * areas, each area with its own behavior.
21905   */
21906 +
21907 +#ifdef CONFIG_PAX_SEGMEXEC
21908 +static long __madvise_behavior(struct vm_area_struct * vma,
21909 +                    struct vm_area_struct **prev,
21910 +                    unsigned long start, unsigned long end, int behavior);
21911 +
21912 +static long madvise_behavior(struct vm_area_struct * vma,
21913 +                    struct vm_area_struct **prev,
21914 +                    unsigned long start, unsigned long end, int behavior)
21915 +{
21916 +       if (vma->vm_flags & VM_MIRROR) {
21917 +               struct vm_area_struct * vma_m, * prev_m;
21918 +               unsigned long start_m, end_m;
21919 +               int error;
21920 +
21921 +               start_m = vma->vm_start + vma->vm_mirror;
21922 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
21923 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
21924 +                       start_m = start + vma->vm_mirror;
21925 +                       end_m = end + vma->vm_mirror;
21926 +                       error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
21927 +                       if (error)
21928 +                               return error;
21929 +               } else {
21930 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
21931 +                       return -ENOMEM;
21932 +               }
21933 +       }
21934 +
21935 +       return __madvise_behavior(vma, prev, start, end, behavior);
21936 +}
21937 +
21938 +static long __madvise_behavior(struct vm_area_struct * vma,
21939 +                    struct vm_area_struct **prev,
21940 +                    unsigned long start, unsigned long end, int behavior)
21941 +#else
21942  static long madvise_behavior(struct vm_area_struct * vma,
21943                      struct vm_area_struct **prev,
21944                      unsigned long start, unsigned long end, int behavior)
21945 +#endif
21946  {
21947         struct mm_struct * mm = vma->vm_mm;
21948         int error = 0;
21949 diff -urNp linux-2.6.16.12/mm/memory.c linux-2.6.16.12/mm/memory.c
21950 --- linux-2.6.16.12/mm/memory.c 2006-05-01 15:14:26.000000000 -0400
21951 +++ linux-2.6.16.12/mm/memory.c 2006-05-01 20:17:34.000000000 -0400
21952 @@ -48,6 +48,7 @@
21953  #include <linux/rmap.h>
21954  #include <linux/module.h>
21955  #include <linux/init.h>
21956 +#include <linux/grsecurity.h>
21957  
21958  #include <asm/pgalloc.h>
21959  #include <asm/uaccess.h>
21960 @@ -321,6 +322,11 @@ int __pte_alloc(struct mm_struct *mm, pm
21961  
21962  int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
21963  {
21964 +
21965 +#ifdef CONFIG_PAX_KERNEXEC
21966 +       unsigned long cr0;
21967 +#endif
21968 +
21969         pte_t *new = pte_alloc_one_kernel(&init_mm, address);
21970         if (!new)
21971                 return -ENOMEM;
21972 @@ -328,8 +334,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
21973         spin_lock(&init_mm.page_table_lock);
21974         if (pmd_present(*pmd))          /* Another has populated it */
21975                 pte_free_kernel(new);
21976 -       else
21977 +       else {
21978 +
21979 +#ifdef CONFIG_PAX_KERNEXEC
21980 +               pax_open_kernel(cr0);
21981 +#endif
21982 +
21983                 pmd_populate_kernel(&init_mm, pmd, new);
21984 +
21985 +#ifdef CONFIG_PAX_KERNEXEC
21986 +               pax_close_kernel(cr0);
21987 +#endif
21988 +
21989 +       }
21990         spin_unlock(&init_mm.page_table_lock);
21991         return 0;
21992  }
21993 @@ -1434,6 +1451,88 @@ static inline void cow_user_page(struct 
21994         copy_user_highpage(dst, src, va);
21995  }
21996  
21997 +#ifdef CONFIG_PAX_SEGMEXEC
21998 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
21999 + *
22000 + * the ptl of the lower mapped page is held on entry and is not released on exit
22001 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
22002 + */
22003 +static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
22004 +{
22005 +       struct mm_struct *mm = vma->vm_mm;
22006 +       unsigned long address_m, pfn_m;
22007 +       struct vm_area_struct * vma_m = NULL;
22008 +       pte_t * pte_m, entry_m;
22009 +       struct page * page_m = NULL;
22010 +
22011 +       address_m = vma->vm_start + vma->vm_mirror;
22012 +       vma_m = find_vma(mm, address_m);
22013 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
22014 +
22015 +       address_m = address + vma->vm_mirror;
22016 +       pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
22017 +
22018 +       if (pte_same(*pte, *pte_m)) {
22019 +               pte_unmap_nested(pte_m);
22020 +               return;
22021 +       }
22022 +
22023 +       if (pte_present(*pte_m)) {
22024 +               page_m = vm_normal_page(vma_m, address_m, *pte_m);
22025 +               if (page_m) {
22026 +                       flush_cache_page(vma_m, address_m, pfn_m);
22027 +                       flush_icache_page(vma_m, page_m);
22028 +               }
22029 +       }
22030 +
22031 +       if (pte_present(*pte_m))
22032 +               entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
22033 +       else
22034 +               entry_m = ptep_get_and_clear(mm, address_m, pte_m);
22035 +
22036 +       if (pte_none(entry_m)) {
22037 +       } else if (pte_present(entry_m)) {
22038 +               if (page_m) {
22039 +                       page_remove_rmap(page_m);
22040 +                       if (PageAnon(page_m))
22041 +                               dec_mm_counter(mm, anon_rss);
22042 +                       else
22043 +                               dec_mm_counter(mm, file_rss);
22044 +                       page_cache_release(page_m);
22045 +               }
22046 +       } else if (!pte_file(entry_m)) {
22047 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
22048 +       } else {
22049 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
22050 +                               address, vma->vm_start, address_m, vma_m->vm_start);
22051 +       }
22052 +
22053 +       pfn_m = pte_pfn(*pte);
22054 +       page_m = vm_normal_page(vma, address, *pte);
22055 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
22056 +       if (pte_write(*pte))
22057 +               entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
22058 +       if (page_m) {
22059 +               page_cache_get(page_m);
22060 +               /*
22061 +                * we can test PAGE_MAPPING_ANON without holding page_map_lock because
22062 +                * we hold the page table lock and have a reference to page_m
22063 +                */
22064 +               if (PageAnon(page_m)) {
22065 +                       page_add_anon_rmap(page_m, vma_m, address_m);
22066 +                       inc_mm_counter(mm, anon_rss);
22067 +               } else {
22068 +                       page_add_file_rmap(page_m);
22069 +                       inc_mm_counter(mm, file_rss);
22070 +               }
22071 +       }
22072 +       set_pte_at(mm, address_m, pte_m, entry_m);
22073 +       update_mmu_cache(vma_m, address_m, entry_m);
22074 +       lazy_mmu_prot_update(entry_m);
22075 +       pte_unmap_nested(pte_m);
22076 +}
22077 +#endif
22078 +
22079  /*
22080   * This routine handles present pages, when users try to write
22081   * to a shared page. It is done by copying the page to a new address
22082 @@ -1524,6 +1623,12 @@ gotten:
22083                 /* Free the old page.. */
22084                 new_page = old_page;
22085                 ret |= VM_FAULT_WRITE;
22086 +
22087 +#ifdef CONFIG_PAX_SEGMEXEC
22088 +               if (vma->vm_flags & VM_MIRROR)
22089 +                       pax_mirror_fault(vma, address, page_table);
22090 +#endif
22091 +
22092         }
22093         if (new_page)
22094                 page_cache_release(new_page);
22095 @@ -1774,6 +1879,7 @@ int vmtruncate(struct inode * inode, lof
22096  
22097  do_expand:
22098         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
22099 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
22100         if (limit != RLIM_INFINITY && offset > limit)
22101                 goto out_sig;
22102         if (offset > inode->i_sb->s_maxbytes)
22103 @@ -1967,6 +2073,12 @@ again:
22104         /* No need to invalidate - it was non-present before */
22105         update_mmu_cache(vma, address, pte);
22106         lazy_mmu_prot_update(pte);
22107 +
22108 +#ifdef CONFIG_PAX_SEGMEXEC
22109 +       if (vma->vm_flags & VM_MIRROR)
22110 +               pax_mirror_fault(vma, address, page_table);
22111 +#endif
22112 +
22113  unlock:
22114         pte_unmap_unlock(page_table, ptl);
22115  out:
22116 @@ -2031,6 +2143,12 @@ static int do_anonymous_page(struct mm_s
22117         /* No need to invalidate - it was non-present before */
22118         update_mmu_cache(vma, address, entry);
22119         lazy_mmu_prot_update(entry);
22120 +
22121 +#ifdef CONFIG_PAX_SEGMEXEC
22122 +       if (vma->vm_flags & VM_MIRROR)
22123 +               pax_mirror_fault(vma, address, page_table);
22124 +#endif
22125 +
22126  unlock:
22127         pte_unmap_unlock(page_table, ptl);
22128         return VM_FAULT_MINOR;
22129 @@ -2159,6 +2277,12 @@ retry:
22130         /* no need to invalidate: a not-present page shouldn't be cached */
22131         update_mmu_cache(vma, address, entry);
22132         lazy_mmu_prot_update(entry);
22133 +
22134 +#ifdef CONFIG_PAX_SEGMEXEC
22135 +       if (vma->vm_flags & VM_MIRROR)
22136 +               pax_mirror_fault(vma, address, page_table);
22137 +#endif
22138 +
22139  unlock:
22140         pte_unmap_unlock(page_table, ptl);
22141         return ret;
22142 @@ -2282,6 +2406,12 @@ static inline int handle_pte_fault(struc
22143                         flush_tlb_page(vma, address);
22144         }
22145  unlock:
22146 +
22147 +#ifdef CONFIG_PAX_SEGMEXEC
22148 +       if (vma->vm_flags & VM_MIRROR)
22149 +               pax_mirror_fault(vma, address, pte);
22150 +#endif
22151 +
22152         pte_unmap_unlock(pte, ptl);
22153         ret = VM_FAULT_MINOR;
22154  out:
22155 @@ -2307,6 +2437,49 @@ int __handle_mm_fault(struct mm_struct *
22156         if (unlikely(is_vm_hugetlb_page(vma)))
22157                 return hugetlb_fault(mm, vma, address, write_access);
22158  
22159 +#ifdef CONFIG_PAX_SEGMEXEC
22160 +       if (vma->vm_flags & VM_MIRROR) {
22161 +               unsigned long address_m;
22162 +               struct vm_area_struct * vma_m;
22163 +               pgd_t *pgd_m;
22164 +               pud_t *pud_m;
22165 +               pmd_t *pmd_m;
22166 +
22167 +               address_m = vma->vm_start + vma->vm_mirror;
22168 +               vma_m = find_vma(mm, address_m);
22169 +
22170 +               /* PaX: sanity checks */
22171 +               if (!vma_m) {
22172 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
22173 +                              address, vma, address_m, vma_m);
22174 +                       return VM_FAULT_SIGBUS;
22175 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
22176 +                       vma_m->vm_start != address_m ||
22177 +                       vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
22178 +               {
22179 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
22180 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
22181 +                       return VM_FAULT_SIGBUS;
22182 +               }
22183 +
22184 +               if (address_m < address) {
22185 +                       address += vma->vm_mirror;
22186 +                       vma = vma_m;
22187 +               }
22188 +
22189 +               address_m = address + vma->vm_mirror;
22190 +               pgd_m = pgd_offset(mm, address_m);
22191 +               pud_m = pud_alloc(mm, pgd_m, address_m);
22192 +               if (!pud_m)
22193 +                       return VM_FAULT_OOM;
22194 +               pmd_m = pmd_alloc(mm, pud_m, address_m);
22195 +               if (!pmd_m)
22196 +                       return VM_FAULT_OOM;
22197 +               if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
22198 +                       return VM_FAULT_OOM;
22199 +       }
22200 +#endif
22201 +
22202         pgd = pgd_offset(mm, address);
22203         pud = pud_alloc(mm, pgd, address);
22204         if (!pud)
22205 diff -urNp linux-2.6.16.12/mm/mempolicy.c linux-2.6.16.12/mm/mempolicy.c
22206 --- linux-2.6.16.12/mm/mempolicy.c      2006-05-01 15:14:26.000000000 -0400
22207 +++ linux-2.6.16.12/mm/mempolicy.c      2006-05-01 20:17:34.000000000 -0400
22208 @@ -356,6 +356,12 @@ check_range(struct mm_struct *mm, unsign
22209                         if (prev && prev->vm_end < vma->vm_start)
22210                                 return ERR_PTR(-EFAULT);
22211                 }
22212 +
22213 +#ifdef CONFIG_PAX_SEGMEXEC
22214 +               if (vma->vm_flags & VM_MIRROR)
22215 +                       return ERR_PTR(-EFAULT);
22216 +#endif
22217 +
22218                 if (!is_vm_hugetlb_page(vma) &&
22219                     ((flags & MPOL_MF_STRICT) ||
22220                      ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
22221 diff -urNp linux-2.6.16.12/mm/mlock.c linux-2.6.16.12/mm/mlock.c
22222 --- linux-2.6.16.12/mm/mlock.c  2006-05-01 15:14:26.000000000 -0400
22223 +++ linux-2.6.16.12/mm/mlock.c  2006-05-01 20:17:34.000000000 -0400
22224 @@ -11,14 +11,85 @@
22225  #include <linux/mempolicy.h>
22226  #include <linux/syscalls.h>
22227  #include <linux/vs_memory.h>
22228 +#include <linux/grsecurity.h>
22229  
22230 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
22231 +       unsigned long start, unsigned long end, unsigned int newflags);
22232  
22233  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
22234         unsigned long start, unsigned long end, unsigned int newflags)
22235  {
22236         struct mm_struct * mm = vma->vm_mm;
22237 -       pgoff_t pgoff;
22238         int pages;
22239 +       int ret;
22240 +
22241 +#ifdef CONFIG_PAX_SEGMEXEC
22242 +       struct vm_area_struct * vma_m = NULL, *prev_m;
22243 +       unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
22244 +
22245 +       if (vma->vm_flags & VM_MIRROR) {
22246 +               start_m = vma->vm_start + vma->vm_mirror;
22247 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
22248 +               if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
22249 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
22250 +                       return -ENOMEM;
22251 +               }
22252 +
22253 +               start_m = start + vma->vm_mirror;
22254 +               end_m = end + vma->vm_mirror;
22255 +               if (newflags & VM_LOCKED)
22256 +                       newflags_m = vma_m->vm_flags | VM_LOCKED;
22257 +               else
22258 +                       newflags_m = vma_m->vm_flags & ~VM_LOCKED;
22259 +               ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
22260 +               if (ret)
22261 +                       return ret;
22262 +       }
22263 +#endif
22264 +
22265 +       ret = __mlock_fixup(vma, prev, start, end, newflags);
22266 +       if (ret)
22267 +               return ret;
22268 +
22269 +       /*
22270 +        * vm_flags is protected by the mmap_sem held in write mode.
22271 +        * It's okay if try_to_unmap_one unmaps a page just after we
22272 +        * set VM_LOCKED, make_pages_present below will bring it back.
22273 +        */
22274 +       vma->vm_flags = newflags;
22275 +
22276 +#ifdef CONFIG_PAX_SEGMEXEC
22277 +       if (vma->vm_flags & VM_MIRROR)
22278 +               vma_m->vm_flags = newflags_m;
22279 +#endif
22280 +
22281 +       /*
22282 +        * Keep track of amount of locked VM.
22283 +        */
22284 +       pages = (end - start) >> PAGE_SHIFT;
22285 +       if (newflags & VM_LOCKED) {
22286 +               pages = -pages;
22287 +               if (!(newflags & VM_IO))
22288 +                       ret = make_pages_present(start, end);
22289 +       }
22290 +
22291 +       mm->locked_vm -= pages;
22292 +
22293 +#ifdef CONFIG_PAX_SEGMEXEC
22294 +       if (vma->vm_flags & VM_MIRROR)
22295 +               mm->locked_vm -= pages;
22296 +#endif
22297 +
22298 +       if (ret == -ENOMEM)
22299 +               ret = -EAGAIN;
22300 +       return ret;
22301 +}
22302 +
22303 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
22304 +       unsigned long start, unsigned long end, unsigned int newflags)
22305 +{
22306 +       struct mm_struct * mm = vma->vm_mm;
22307 +       pgoff_t pgoff;
22308         int ret = 0;
22309  
22310         if (newflags == vma->vm_flags) {
22311 @@ -31,7 +102,7 @@ static int mlock_fixup(struct vm_area_st
22312                           vma->vm_file, pgoff, vma_policy(vma));
22313         if (*prev) {
22314                 vma = *prev;
22315 -               goto success;
22316 +               goto out;
22317         }
22318  
22319         *prev = vma;
22320 @@ -42,31 +113,9 @@ static int mlock_fixup(struct vm_area_st
22321                         goto out;
22322         }
22323  
22324 -       if (end != vma->vm_end) {
22325 +       if (end != vma->vm_end)
22326                 ret = split_vma(mm, vma, end, 0);
22327 -               if (ret)
22328 -                       goto out;
22329 -       }
22330  
22331 -success:
22332 -       /*
22333 -        * vm_flags is protected by the mmap_sem held in write mode.
22334 -        * It's okay if try_to_unmap_one unmaps a page just after we
22335 -        * set VM_LOCKED, make_pages_present below will bring it back.
22336 -        */
22337 -       vma->vm_flags = newflags;
22338 -
22339 -       /*
22340 -        * Keep track of amount of locked VM.
22341 -        */
22342 -       pages = (end - start) >> PAGE_SHIFT;
22343 -       if (newflags & VM_LOCKED) {
22344 -               pages = -pages;
22345 -               if (!(newflags & VM_IO))
22346 -                       ret = make_pages_present(start, end);
22347 -       }
22348 -
22349 -       vx_vmlocked_sub(vma->vm_mm, pages);
22350  out:
22351         if (ret == -ENOMEM)
22352                 ret = -EAGAIN;
22353 @@ -85,6 +134,17 @@ static int do_mlock(unsigned long start,
22354                 return -EINVAL;
22355         if (end == start)
22356                 return 0;
22357 +
22358 +#ifdef CONFIG_PAX_SEGMEXEC
22359 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
22360 +               if (end > SEGMEXEC_TASK_SIZE)
22361 +                       return -EINVAL;
22362 +       } else
22363 +#endif
22364 +
22365 +       if (end > TASK_SIZE)
22366 +               return -EINVAL;
22367 +
22368         vma = find_vma_prev(current->mm, start, &prev);
22369         if (!vma || vma->vm_start > start)
22370                 return -ENOMEM;
22371 @@ -144,6 +204,7 @@ asmlinkage long sys_mlock(unsigned long 
22372         lock_limit >>= PAGE_SHIFT;
22373  
22374         /* check against resource limits */
22375 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
22376         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
22377                 error = do_mlock(start, len, 1);
22378  out:
22379 @@ -177,6 +238,16 @@ static int do_mlockall(int flags)
22380         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
22381                 unsigned int newflags;
22382  
22383 +#ifdef CONFIG_PAX_SEGMEXEC
22384 +               if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
22385 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
22386 +                               break;
22387 +               } else
22388 +#endif
22389 +
22390 +               if (vma->vm_end > TASK_SIZE)
22391 +                       break;
22392 +
22393                 newflags = vma->vm_flags | VM_LOCKED;
22394                 if (!(flags & MCL_CURRENT))
22395                         newflags &= ~VM_LOCKED;
22396 @@ -208,6 +279,7 @@ asmlinkage long sys_mlockall(int flags)
22397         ret = -ENOMEM;
22398         if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
22399                 goto out;
22400 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
22401         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
22402             capable(CAP_IPC_LOCK))
22403                 ret = do_mlockall(flags);
22404 diff -urNp linux-2.6.16.12/mm/mmap.c linux-2.6.16.12/mm/mmap.c
22405 --- linux-2.6.16.12/mm/mmap.c   2006-05-01 15:14:26.000000000 -0400
22406 +++ linux-2.6.16.12/mm/mmap.c   2006-05-01 20:17:34.000000000 -0400
22407 @@ -25,6 +25,7 @@
22408  #include <linux/mount.h>
22409  #include <linux/mempolicy.h>
22410  #include <linux/rmap.h>
22411 +#include <linux/grsecurity.h>
22412  
22413  #include <asm/uaccess.h>
22414  #include <asm/cacheflush.h>
22415 @@ -60,6 +61,8 @@ pgprot_t protection_map[16] = {
22416         __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
22417  };
22418  
22419 +EXPORT_SYMBOL(protection_map);
22420 +
22421  int sysctl_overcommit_memory = OVERCOMMIT_GUESS;  /* heuristic overcommit */
22422  int sysctl_overcommit_ratio = 50;      /* default is 50% */
22423  int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
22424 @@ -234,6 +237,7 @@ asmlinkage unsigned long sys_brk(unsigne
22425  
22426         /* Check against rlimit.. */
22427         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
22428 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
22429         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
22430                 goto out;
22431  
22432 @@ -612,11 +616,17 @@ again:                    remove_next = 1 + (end > next->
22433   * If the vma has a ->close operation then the driver probably needs to release
22434   * per-vma resources, so we don't attempt to merge those.
22435   */
22436 +#ifdef CONFIG_PAX_SEGMEXEC
22437 +#define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
22438 +#else
22439  #define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
22440 +#endif
22441  
22442  static inline int is_mergeable_vma(struct vm_area_struct *vma,
22443                         struct file *file, unsigned long vm_flags)
22444  {
22445 +       if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
22446 +               return 0;
22447         if (vma->vm_flags != vm_flags)
22448                 return 0;
22449         if (vma->vm_file != file)
22450 @@ -842,9 +852,6 @@ none:
22451  void vm_stat_account(struct mm_struct *mm, unsigned long flags,
22452                                                 struct file *file, long pages)
22453  {
22454 -       const unsigned long stack_flags
22455 -               = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
22456 -
22457  #ifdef CONFIG_HUGETLB
22458         if (flags & VM_HUGETLB) {
22459                 if (!(flags & VM_DONTCOPY))
22460 @@ -857,7 +864,7 @@ void vm_stat_account(struct mm_struct *m
22461                 mm->shared_vm += pages;
22462                 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
22463                         mm->exec_vm += pages;
22464 -       } else if (flags & stack_flags)
22465 +       } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
22466                 mm->stack_vm += pages;
22467         if (flags & (VM_RESERVED|VM_IO))
22468                 mm->reserved_vm += pages;
22469 @@ -868,10 +875,55 @@ void vm_stat_account(struct mm_struct *m
22470   * The caller must hold down_write(current->mm->mmap_sem).
22471   */
22472  
22473 +#ifdef CONFIG_PAX_SEGMEXEC
22474 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
22475 +                       unsigned long len, unsigned long prot,
22476 +                       unsigned long flags, unsigned long pgoff);
22477 +
22478  unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
22479                         unsigned long len, unsigned long prot,
22480                         unsigned long flags, unsigned long pgoff)
22481  {
22482 +       unsigned long ret = -EINVAL;
22483 +
22484 +       if (flags & MAP_MIRROR)
22485 +               return ret;
22486 +
22487 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
22488 +           (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
22489 +               return ret;
22490 +
22491 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
22492 +
22493 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
22494 +
22495 +#ifdef CONFIG_PAX_MPROTECT
22496 +           && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
22497 +#endif
22498 +
22499 +          )
22500 +       {
22501 +               unsigned long ret_m;
22502 +               prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
22503 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
22504 +               if (ret_m >= TASK_SIZE) {
22505 +                       do_munmap(current->mm, ret, len);
22506 +                       ret = ret_m;
22507 +               }
22508 +       }
22509 +
22510 +       return ret;
22511 +}
22512 +
22513 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
22514 +                       unsigned long len, unsigned long prot,
22515 +                       unsigned long flags, unsigned long pgoff)
22516 +#else
22517 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
22518 +                       unsigned long len, unsigned long prot,
22519 +                       unsigned long flags, unsigned long pgoff)
22520 +#endif
22521 +{
22522         struct mm_struct * mm = current->mm;
22523         struct vm_area_struct * vma, * prev;
22524         struct inode *inode;
22525 @@ -882,6 +934,28 @@ unsigned long do_mmap_pgoff(struct file 
22526         int accountable = 1;
22527         unsigned long charged = 0, reqprot = prot;
22528  
22529 +#ifdef CONFIG_PAX_SEGMEXEC
22530 +       struct vm_area_struct * vma_m = NULL;
22531 +
22532 +       if (flags & MAP_MIRROR) {
22533 +               /* PaX: sanity checks, to be removed when proved to be stable */
22534 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
22535 +                       return -EINVAL;
22536 +
22537 +               vma_m = find_vma(mm, pgoff);
22538 +
22539 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
22540 +                   vma_m->vm_start != pgoff ||
22541 +                   (vma_m->vm_flags & VM_SPECIAL) ||
22542 +                   (prot & PROT_WRITE))
22543 +                       return -EINVAL;
22544 +
22545 +               file = vma_m->vm_file;
22546 +               pgoff = vma_m->vm_pgoff;
22547 +               len = vma_m->vm_end - vma_m->vm_start;
22548 +       }
22549 +#endif
22550 +
22551         if (file) {
22552                 if (is_file_hugepages(file))
22553                         accountable = 0;
22554 @@ -922,7 +996,7 @@ unsigned long do_mmap_pgoff(struct file 
22555         /* Obtain the address to map to. we verify (or select) it and ensure
22556          * that it represents a valid section of the address space.
22557          */
22558 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
22559 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
22560         if (addr & ~PAGE_MASK)
22561                 return addr;
22562  
22563 @@ -933,6 +1007,24 @@ unsigned long do_mmap_pgoff(struct file 
22564         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
22565                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
22566  
22567 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
22568 +               vm_flags &= ~VM_MAYEXEC;
22569 +
22570 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22571 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22572 +
22573 +#ifdef CONFIG_PAX_MPROTECT
22574 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
22575 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
22576 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
22577 +                       else
22578 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
22579 +               }
22580 +#endif
22581 +
22582 +       }
22583 +#endif
22584 +
22585         if (flags & MAP_LOCKED) {
22586                 if (!can_do_mlock())
22587                         return -EPERM;
22588 @@ -945,6 +1037,7 @@ unsigned long do_mmap_pgoff(struct file 
22589                 locked += mm->locked_vm;
22590                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
22591                 lock_limit >>= PAGE_SHIFT;
22592 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
22593                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
22594                         return -EAGAIN;
22595         }
22596 @@ -992,6 +1085,11 @@ unsigned long do_mmap_pgoff(struct file 
22597                         /*
22598                          * Set pgoff according to addr for anon_vma.
22599                          */
22600 +
22601 +#ifdef CONFIG_PAX_SEGMEXEC
22602 +                       if (!(flags & MAP_MIRROR))
22603 +#endif
22604 +
22605                         pgoff = addr >> PAGE_SHIFT;
22606                         break;
22607                 default:
22608 @@ -1003,14 +1101,17 @@ unsigned long do_mmap_pgoff(struct file 
22609         if (error)
22610                 return error;
22611                 
22612 +       if (!gr_acl_handle_mmap(file, prot))
22613 +               return -EACCES;
22614 +
22615         /* Clear old maps */
22616         error = -ENOMEM;
22617 -munmap_back:
22618         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22619         if (vma && vma->vm_start < addr + len) {
22620                 if (do_munmap(mm, addr, len))
22621                         return -ENOMEM;
22622 -               goto munmap_back;
22623 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22624 +               BUG_ON(vma && vma->vm_start < addr + len);
22625         }
22626  
22627         /* Check against address space limit. */
22628 @@ -1059,6 +1160,13 @@ munmap_back:
22629         vma->vm_start = addr;
22630         vma->vm_end = addr + len;
22631         vma->vm_flags = vm_flags;
22632 +
22633 +#ifdef CONFIG_PAX_PAGEEXEC
22634 +       if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
22635 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
22636 +       else
22637 +#endif
22638 +
22639         vma->vm_page_prot = protection_map[vm_flags & 0x0f];
22640         vma->vm_pgoff = pgoff;
22641  
22642 @@ -1083,6 +1191,14 @@ munmap_back:
22643                         goto free_vma;
22644         }
22645  
22646 +#ifdef CONFIG_PAX_SEGMEXEC
22647 +       if (flags & MAP_MIRROR) {
22648 +               vma_m->vm_flags |= VM_MIRROR;
22649 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
22650 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
22651 +       }
22652 +#endif
22653 +
22654         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
22655          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
22656          * that memory reservation must be checked; but that reservation
22657 @@ -1118,6 +1234,7 @@ munmap_back:
22658  out:   
22659         vx_vmpages_add(mm, len >> PAGE_SHIFT);
22660         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
22661 +       track_exec_limit(mm, addr, addr + len, vm_flags);
22662         if (vm_flags & VM_LOCKED) {
22663                 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
22664                 make_pages_present(addr, addr + len);
22665 @@ -1172,6 +1289,10 @@ arch_get_unmapped_area(struct file *filp
22666         if (len > TASK_SIZE)
22667                 return -ENOMEM;
22668  
22669 +#ifdef CONFIG_PAX_RANDMMAP
22670 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
22671 +#endif
22672 +
22673         if (addr) {
22674                 addr = PAGE_ALIGN(addr);
22675                 vma = find_vma(mm, addr);
22676 @@ -1182,7 +1303,7 @@ arch_get_unmapped_area(struct file *filp
22677         if (len > mm->cached_hole_size) {
22678                 start_addr = addr = mm->free_area_cache;
22679         } else {
22680 -               start_addr = addr = TASK_UNMAPPED_BASE;
22681 +               start_addr = addr = mm->mmap_base;
22682                 mm->cached_hole_size = 0;
22683         }
22684  
22685 @@ -1194,9 +1315,8 @@ full_search:
22686                          * Start a new search - just in case we missed
22687                          * some holes.
22688                          */
22689 -                       if (start_addr != TASK_UNMAPPED_BASE) {
22690 -                               addr = TASK_UNMAPPED_BASE;
22691 -                               start_addr = addr;
22692 +                       if (start_addr != mm->mmap_base) {
22693 +                               start_addr = addr = mm->mmap_base;
22694                                 mm->cached_hole_size = 0;
22695                                 goto full_search;
22696                         }
22697 @@ -1221,7 +1341,7 @@ void arch_unmap_area(struct mm_struct *m
22698         /*
22699          * Is this a new hole at the lowest possible address?
22700          */
22701 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
22702 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
22703                 mm->free_area_cache = addr;
22704                 mm->cached_hole_size = ~0UL;
22705         }
22706 @@ -1239,12 +1359,16 @@ arch_get_unmapped_area_topdown(struct fi
22707  {
22708         struct vm_area_struct *vma;
22709         struct mm_struct *mm = current->mm;
22710 -       unsigned long addr = addr0;
22711 +       unsigned long base = mm->mmap_base, addr = addr0;
22712  
22713         /* requested length too big for entire address space */
22714         if (len > TASK_SIZE)
22715                 return -ENOMEM;
22716  
22717 +#ifdef CONFIG_PAX_RANDMMAP
22718 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
22719 +#endif
22720 +
22721         /* requesting a specific address */
22722         if (addr) {
22723                 addr = PAGE_ALIGN(addr);
22724 @@ -1302,13 +1426,21 @@ bottomup:
22725          * can happen with large stack limits and large mmap()
22726          * allocations.
22727          */
22728 +       mm->mmap_base = TASK_UNMAPPED_BASE;
22729 +
22730 +#ifdef CONFIG_PAX_RANDMMAP
22731 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
22732 +               mm->mmap_base += mm->delta_mmap;
22733 +#endif
22734 +
22735 +       mm->free_area_cache = mm->mmap_base;
22736         mm->cached_hole_size = ~0UL;
22737 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
22738         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
22739         /*
22740          * Restore the topdown base:
22741          */
22742 -       mm->free_area_cache = mm->mmap_base;
22743 +       mm->mmap_base = base;
22744 +       mm->free_area_cache = base;
22745         mm->cached_hole_size = ~0UL;
22746  
22747         return addr;
22748 @@ -1324,8 +1456,10 @@ void arch_unmap_area_topdown(struct mm_s
22749                 mm->free_area_cache = addr;
22750  
22751         /* dont allow allocations above current base */
22752 -       if (mm->free_area_cache > mm->mmap_base)
22753 +       if (mm->free_area_cache > mm->mmap_base) {
22754                 mm->free_area_cache = mm->mmap_base;
22755 +               mm->cached_hole_size = ~0UL;
22756 +       }
22757  }
22758  
22759  unsigned long
22760 @@ -1458,6 +1592,7 @@ static int acct_stack_growth(struct vm_a
22761                 return -ENOMEM;
22762  
22763         /* Stack limit test */
22764 +       gr_learn_resource(current, RLIMIT_STACK, size, 1);
22765         if (size > rlim[RLIMIT_STACK].rlim_cur)
22766                 return -ENOMEM;
22767  
22768 @@ -1467,6 +1602,7 @@ static int acct_stack_growth(struct vm_a
22769                 unsigned long limit;
22770                 locked = mm->locked_vm + grow;
22771                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
22772 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
22773                 if (locked > limit && !capable(CAP_IPC_LOCK))
22774                         return -ENOMEM;
22775         }
22776 @@ -1584,13 +1720,49 @@ int expand_stack(struct vm_area_struct *
22777         if (address < vma->vm_start) {
22778                 unsigned long size, grow;
22779  
22780 +#ifdef CONFIG_PAX_SEGMEXEC
22781 +               struct vm_area_struct *vma_m = NULL;
22782 +               unsigned long address_m = 0UL;
22783 +
22784 +               if (vma->vm_flags & VM_MIRROR) {
22785 +                       address_m = vma->vm_start + vma->vm_mirror;
22786 +                       vma_m = find_vma(vma->vm_mm, address_m);
22787 +                       if (!vma_m || vma_m->vm_start != address_m ||
22788 +                           !(vma_m->vm_flags & VM_MIRROR) ||
22789 +                           vma->vm_end - vma->vm_start !=
22790 +                           vma_m->vm_end - vma_m->vm_start ||
22791 +                           vma->anon_vma != vma_m->anon_vma) {
22792 +                               printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
22793 +                                      address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
22794 +                               anon_vma_unlock(vma);
22795 +                               return -EFAULT;
22796 +                       }
22797 +                       address_m = address + vma->vm_mirror;
22798 +               }
22799 +#endif
22800 +
22801                 size = vma->vm_end - address;
22802                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
22803  
22804 +#ifdef CONFIG_PAX_SEGMEXEC
22805 +               if (vma_m)
22806 +                       error = acct_stack_growth(vma, size, 2*grow);
22807 +               else
22808 +#endif
22809 +
22810                 error = acct_stack_growth(vma, size, grow);
22811                 if (!error) {
22812                         vma->vm_start = address;
22813                         vma->vm_pgoff -= grow;
22814 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
22815 +
22816 +#ifdef CONFIG_PAX_SEGMEXEC
22817 +                       if (vma_m) {
22818 +                               vma_m->vm_start = address_m;
22819 +                               vma_m->vm_pgoff -= grow;
22820 +                       }
22821 +#endif
22822 +
22823                 }
22824         }
22825         anon_vma_unlock(vma);
22826 @@ -1752,7 +1924,24 @@ int split_vma(struct mm_struct * mm, str
22827   * work.  This now handles partial unmappings.
22828   * Jeremy Fitzhardinge <jeremy@goop.org>
22829   */
22830 +#ifdef CONFIG_PAX_SEGMEXEC
22831 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
22832 +
22833 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22834 +{
22835 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
22836 +               int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
22837 +               if (ret)
22838 +                       return ret;
22839 +       }
22840 +
22841 +       return __do_munmap(mm, start, len);
22842 +}
22843 +
22844 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22845 +#else
22846  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22847 +#endif
22848  {
22849         unsigned long end;
22850         struct vm_area_struct *vma, *prev, *last;
22851 @@ -1806,6 +1995,8 @@ int do_munmap(struct mm_struct *mm, unsi
22852         /* Fix up all other VM information */
22853         remove_vma_list(mm, vma);
22854  
22855 +       track_exec_limit(mm, start, end, 0UL);
22856 +
22857         return 0;
22858  }
22859  
22860 @@ -1818,6 +2009,12 @@ asmlinkage long sys_munmap(unsigned long
22861  
22862         profile_munmap(addr);
22863  
22864 +#ifdef CONFIG_PAX_SEGMEXEC
22865 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
22866 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
22867 +               return -EINVAL;
22868 +#endif
22869 +
22870         down_write(&mm->mmap_sem);
22871         ret = do_munmap(mm, addr, len);
22872         up_write(&mm->mmap_sem);
22873 @@ -1839,11 +2036,35 @@ static inline void verify_mm_writelocked
22874   *  anonymous maps.  eventually we may be able to do some
22875   *  brk-specific accounting here.
22876   */
22877 +#ifdef CONFIG_PAX_SEGMEXEC
22878 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
22879 +
22880  unsigned long do_brk(unsigned long addr, unsigned long len)
22881  {
22882 +       unsigned long ret;
22883 +
22884 +       ret = __do_brk(addr, len);
22885 +       if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
22886 +               unsigned long ret_m;
22887 +
22888 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
22889 +               if (ret_m > TASK_SIZE) {
22890 +                       do_munmap(current->mm, addr, len);
22891 +                       ret = ret_m;
22892 +               }
22893 +       }
22894 +
22895 +       return ret;
22896 +}
22897 +
22898 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
22899 +#else
22900 +unsigned long do_brk(unsigned long addr, unsigned long len)
22901 +#endif
22902 +{
22903         struct mm_struct * mm = current->mm;
22904         struct vm_area_struct * vma, * prev;
22905 -       unsigned long flags;
22906 +       unsigned long flags, task_size = TASK_SIZE;
22907         struct rb_node ** rb_link, * rb_parent;
22908         pgoff_t pgoff = addr >> PAGE_SHIFT;
22909  
22910 @@ -1851,7 +2072,12 @@ unsigned long do_brk(unsigned long addr,
22911         if (!len)
22912                 return addr;
22913  
22914 -       if ((addr + len) > TASK_SIZE || (addr + len) < addr)
22915 +#ifdef CONFIG_PAX_SEGMEXEC
22916 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
22917 +               task_size = SEGMEXEC_TASK_SIZE;
22918 +#endif
22919 +
22920 +       if ((addr + len) > task_size || (addr + len) < addr)
22921                 return -EINVAL;
22922  
22923         /*
22924 @@ -1863,6 +2089,7 @@ unsigned long do_brk(unsigned long addr,
22925                 locked += mm->locked_vm;
22926                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
22927                 lock_limit >>= PAGE_SHIFT;
22928 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
22929                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
22930                         return -EAGAIN;
22931                 if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
22932 @@ -1878,12 +2105,12 @@ unsigned long do_brk(unsigned long addr,
22933         /*
22934          * Clear old maps.  this also does some error checking for us
22935          */
22936 - munmap_back:
22937         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22938         if (vma && vma->vm_start < addr + len) {
22939                 if (do_munmap(mm, addr, len))
22940                         return -ENOMEM;
22941 -               goto munmap_back;
22942 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22943 +               BUG_ON(vma && vma->vm_start < addr + len);
22944         }
22945  
22946         /* Check against address space limits *after* clearing old maps... */
22947 @@ -1899,6 +2126,18 @@ unsigned long do_brk(unsigned long addr,
22948  
22949         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
22950  
22951 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22952 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22953 +               flags &= ~VM_EXEC;
22954 +
22955 +#ifdef CONFIG_PAX_MPROTECT
22956 +               if (mm->pax_flags & MF_PAX_MPROTECT)
22957 +                       flags &= ~VM_MAYEXEC;
22958 +#endif
22959 +
22960 +       }
22961 +#endif
22962 +
22963         /* Can we just expand an old private anonymous mapping? */
22964         if (vma_merge(mm, prev, addr, addr + len, flags,
22965                                         NULL, NULL, pgoff, NULL))
22966 @@ -1919,6 +2158,13 @@ unsigned long do_brk(unsigned long addr,
22967         vma->vm_end = addr + len;
22968         vma->vm_pgoff = pgoff;
22969         vma->vm_flags = flags;
22970 +
22971 +#ifdef CONFIG_PAX_PAGEEXEC
22972 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
22973 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
22974 +       else
22975 +#endif
22976 +
22977         vma->vm_page_prot = protection_map[flags & 0x0f];
22978         vma_link(mm, vma, prev, rb_link, rb_parent);
22979  out:
22980 @@ -1927,6 +2173,7 @@ out:
22981                 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
22982                 make_pages_present(addr, addr + len);
22983         }
22984 +       track_exec_limit(mm, addr, addr + len, flags);
22985         return addr;
22986  }
22987  
22988 @@ -2066,7 +2313,7 @@ int may_expand_vm(struct mm_struct *mm, 
22989         unsigned long lim;
22990  
22991         lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
22992 -
22993 +       gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
22994         if (cur + npages > lim)
22995                 return 0;
22996         if (!vx_vmpages_avail(mm, npages))
22997 diff -urNp linux-2.6.16.12/mm/mprotect.c linux-2.6.16.12/mm/mprotect.c
22998 --- linux-2.6.16.12/mm/mprotect.c       2006-05-01 15:14:26.000000000 -0400
22999 +++ linux-2.6.16.12/mm/mprotect.c       2006-05-01 20:17:34.000000000 -0400
23000 @@ -19,11 +19,18 @@
23001  #include <linux/mempolicy.h>
23002  #include <linux/personality.h>
23003  #include <linux/syscalls.h>
23004 +#include <linux/grsecurity.h>
23005 +
23006 +#ifdef CONFIG_PAX_MPROTECT
23007 +#include <linux/elf.h>
23008 +#include <linux/fs.h>
23009 +#endif
23010  
23011  #include <asm/uaccess.h>
23012  #include <asm/pgtable.h>
23013  #include <asm/cacheflush.h>
23014  #include <asm/tlbflush.h>
23015 +#include <asm/mmu_context.h>
23016  
23017  static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
23018                 unsigned long addr, unsigned long end, pgprot_t newprot)
23019 @@ -98,6 +105,94 @@ static void change_protection(struct vm_
23020         flush_tlb_range(vma, start, end);
23021  }
23022  
23023 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
23024 +/* called while holding the mmap semaphor for writing */
23025 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
23026 +{
23027 +       struct vm_area_struct *vma = find_vma(mm, start);
23028 +
23029 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
23030 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
23031 +
23032 +}
23033 +
23034 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
23035 +{
23036 +       unsigned long oldlimit, newlimit = 0UL;
23037 +
23038 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
23039 +               return;
23040 +
23041 +       spin_lock(&mm->page_table_lock);
23042 +       oldlimit = mm->context.user_cs_limit;
23043 +       if ((prot & VM_EXEC) && oldlimit < end)
23044 +               /* USER_CS limit moved up */
23045 +               newlimit = end;
23046 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
23047 +               /* USER_CS limit moved down */
23048 +               newlimit = start;
23049 +
23050 +       if (newlimit) {
23051 +               mm->context.user_cs_limit = newlimit;
23052 +
23053 +#ifdef CONFIG_SMP
23054 +               wmb();
23055 +               cpus_clear(mm->context.cpu_user_cs_mask);
23056 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
23057 +#endif
23058 +
23059 +               set_user_cs(mm, smp_processor_id());
23060 +       }
23061 +       spin_unlock(&mm->page_table_lock);
23062 +       if (newlimit == end)
23063 +               establish_user_cs_limit(mm, oldlimit, end);
23064 +}
23065 +#endif
23066 +
23067 +#ifdef CONFIG_PAX_SEGMEXEC
23068 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
23069 +       unsigned long start, unsigned long end, unsigned int newflags);
23070 +
23071 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
23072 +       unsigned long start, unsigned long end, unsigned int newflags)
23073 +{
23074 +       if (vma->vm_flags & VM_MIRROR) {
23075 +               struct vm_area_struct * vma_m, * prev_m;
23076 +               unsigned long start_m, end_m;
23077 +               int error;
23078 +
23079 +               start_m = vma->vm_start + vma->vm_mirror;
23080 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
23081 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
23082 +                       start_m = start + vma->vm_mirror;
23083 +                       end_m = end + vma->vm_mirror;
23084 +
23085 +                       if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
23086 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
23087 +                       else
23088 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
23089 +                       if (error)
23090 +                               return error;
23091 +               } else {
23092 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
23093 +                       return -ENOMEM;
23094 +               }
23095 +       }
23096 +
23097 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
23098 +}
23099 +
23100 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
23101 +       unsigned long start, unsigned long end, unsigned int newflags)
23102 +{
23103 +       struct mm_struct * mm = vma->vm_mm;
23104 +       unsigned long oldflags = vma->vm_flags;
23105 +       long nrpages = (end - start) >> PAGE_SHIFT;
23106 +       unsigned long charged = 0;
23107 +       pgprot_t newprot;
23108 +       pgoff_t pgoff;
23109 +       int error;
23110 +#else
23111  static int
23112  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
23113         unsigned long start, unsigned long end, unsigned long newflags)
23114 @@ -114,6 +209,7 @@ mprotect_fixup(struct vm_area_struct *vm
23115                 *pprev = vma;
23116                 return 0;
23117         }
23118 +#endif
23119  
23120         /*
23121          * If we make a private mapping writable we increase our commit;
23122 @@ -132,6 +228,12 @@ mprotect_fixup(struct vm_area_struct *vm
23123                 }
23124         }
23125  
23126 +#ifdef CONFIG_PAX_PAGEEXEC
23127 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
23128 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
23129 +       else
23130 +#endif
23131 +
23132         newprot = protection_map[newflags & 0xf];
23133  
23134         /*
23135 @@ -176,6 +278,69 @@ fail:
23136         return error;
23137  }
23138  
23139 +#ifdef CONFIG_PAX_MPROTECT
23140 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
23141 + * therefore we'll grant them VM_MAYWRITE once during their life.
23142 + *
23143 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
23144 + * basis because we want to allow the common case and not the special ones.
23145 + */
23146 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
23147 +{
23148 +       struct elfhdr elf_h;
23149 +       struct elf_phdr elf_p, p_dyn;
23150 +       elf_dyn dyn;
23151 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
23152 +
23153 +#ifndef CONFIG_PAX_NOELFRELOCS
23154 +       if ((vma->vm_start != start) ||
23155 +           !vma->vm_file ||
23156 +           !(vma->vm_flags & VM_MAYEXEC) ||
23157 +           (vma->vm_flags & VM_MAYNOTWRITE))
23158 +#endif
23159 +
23160 +               return;
23161 +
23162 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
23163 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
23164 +
23165 +#ifdef CONFIG_PAX_ETEXECRELOCS
23166 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
23167 +#else
23168 +           elf_h.e_type != ET_DYN ||
23169 +#endif
23170 +
23171 +           !elf_check_arch(&elf_h) ||
23172 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
23173 +           elf_h.e_phnum > j)
23174 +               return;
23175 +
23176 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
23177 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
23178 +                       return;
23179 +               if (elf_p.p_type == PT_DYNAMIC) {
23180 +                       p_dyn = elf_p;
23181 +                       j = i;
23182 +               }
23183 +       }
23184 +       if (elf_h.e_phnum <= j)
23185 +               return;
23186 +
23187 +       i = 0UL;
23188 +       do {
23189 +               if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
23190 +                       return;
23191 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
23192 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
23193 +                       gr_log_textrel(vma);
23194 +                       return;
23195 +               }
23196 +               i++;
23197 +       } while (dyn.d_tag != DT_NULL);
23198 +       return;
23199 +}
23200 +#endif
23201 +
23202  asmlinkage long
23203  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
23204  {
23205 @@ -195,6 +360,17 @@ sys_mprotect(unsigned long start, size_t
23206         end = start + len;
23207         if (end <= start)
23208                 return -ENOMEM;
23209 +
23210 +#ifdef CONFIG_PAX_SEGMEXEC
23211 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
23212 +               if (end > SEGMEXEC_TASK_SIZE)
23213 +                       return -EINVAL;
23214 +       } else
23215 +#endif
23216 +
23217 +       if (end > TASK_SIZE)
23218 +               return -EINVAL;
23219 +
23220         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
23221                 return -EINVAL;
23222  
23223 @@ -235,6 +411,16 @@ sys_mprotect(unsigned long start, size_t
23224         if (start > vma->vm_start)
23225                 prev = vma;
23226  
23227 +#ifdef CONFIG_PAX_MPROTECT
23228 +       if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
23229 +               pax_handle_maywrite(vma, start);
23230 +#endif
23231 +
23232 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
23233 +               error = -EACCES;
23234 +               goto out;
23235 +       }
23236 +
23237         for (nstart = start ; ; ) {
23238                 unsigned long newflags;
23239  
23240 @@ -253,6 +439,12 @@ sys_mprotect(unsigned long start, size_t
23241                         goto out;
23242                 }
23243  
23244 +#ifdef CONFIG_PAX_MPROTECT
23245 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
23246 +               if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
23247 +                       newflags &= ~VM_MAYWRITE;
23248 +#endif
23249 +
23250                 error = security_file_mprotect(vma, reqprot, prot);
23251                 if (error)
23252                         goto out;
23253 @@ -276,6 +468,9 @@ sys_mprotect(unsigned long start, size_t
23254                         goto out;
23255                 }
23256         }
23257 +
23258 +       track_exec_limit(current->mm, start, end, vm_flags);
23259 +
23260  out:
23261         up_write(&current->mm->mmap_sem);
23262         return error;
23263 diff -urNp linux-2.6.16.12/mm/mremap.c linux-2.6.16.12/mm/mremap.c
23264 --- linux-2.6.16.12/mm/mremap.c 2006-05-01 15:14:26.000000000 -0400
23265 +++ linux-2.6.16.12/mm/mremap.c 2006-05-01 20:17:34.000000000 -0400
23266 @@ -107,6 +107,12 @@ static void move_ptes(struct vm_area_str
23267                 pte = ptep_clear_flush(vma, old_addr, old_pte);
23268                 /* ZERO_PAGE can be dependant on virtual addr */
23269                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
23270 +
23271 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
23272 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
23273 +                       pte_exprotect(pte);
23274 +#endif
23275 +
23276                 set_pte_at(mm, new_addr, new_pte, pte);
23277         }
23278  
23279 @@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
23280         struct vm_area_struct *vma;
23281         unsigned long ret = -EINVAL;
23282         unsigned long charged = 0;
23283 +       unsigned long task_size = TASK_SIZE;
23284  
23285         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
23286                 goto out;
23287 @@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
23288         if (!new_len)
23289                 goto out;
23290  
23291 +#ifdef CONFIG_PAX_SEGMEXEC
23292 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
23293 +               task_size = SEGMEXEC_TASK_SIZE;
23294 +#endif
23295 +
23296 +       if (new_len > task_size || addr > task_size-new_len ||
23297 +           old_len > task_size || addr > task_size-old_len)
23298 +               goto out;
23299 +
23300         /* new_addr is only valid if MREMAP_FIXED is specified */
23301         if (flags & MREMAP_FIXED) {
23302                 if (new_addr & ~PAGE_MASK)
23303 @@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
23304                 if (!(flags & MREMAP_MAYMOVE))
23305                         goto out;
23306  
23307 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
23308 +               if (new_addr > task_size - new_len)
23309                         goto out;
23310  
23311                 /* Check if the location we're moving into overlaps the
23312                  * old location at all, and fail if it does.
23313                  */
23314 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
23315 -                       goto out;
23316 -
23317 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
23318 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
23319                         goto out;
23320  
23321                 ret = do_munmap(mm, new_addr, new_len);
23322 @@ -322,6 +335,14 @@ unsigned long do_mremap(unsigned long ad
23323                 ret = -EINVAL;
23324                 goto out;
23325         }
23326 +
23327 +#ifdef CONFIG_PAX_SEGMEXEC
23328 +       if (vma->vm_flags & VM_MIRROR) {
23329 +               ret = -EINVAL;
23330 +               goto out;
23331 +       }
23332 +#endif
23333 +
23334         /* We can't remap across vm area boundaries */
23335         if (old_len > vma->vm_end - addr)
23336                 goto out;
23337 @@ -358,7 +379,7 @@ unsigned long do_mremap(unsigned long ad
23338         if (old_len == vma->vm_end - addr &&
23339             !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
23340             (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
23341 -               unsigned long max_addr = TASK_SIZE;
23342 +               unsigned long max_addr = task_size;
23343                 if (vma->vm_next)
23344                         max_addr = vma->vm_next->vm_start;
23345                 /* can we just expand the current mapping? */
23346 @@ -376,6 +397,7 @@ unsigned long do_mremap(unsigned long ad
23347                                                    addr + new_len);
23348                         }
23349                         ret = addr;
23350 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
23351                         goto out;
23352                 }
23353         }
23354 @@ -386,8 +408,8 @@ unsigned long do_mremap(unsigned long ad
23355          */
23356         ret = -ENOMEM;
23357         if (flags & MREMAP_MAYMOVE) {
23358 +               unsigned long map_flags = 0;
23359                 if (!(flags & MREMAP_FIXED)) {
23360 -                       unsigned long map_flags = 0;
23361                         if (vma->vm_flags & VM_MAYSHARE)
23362                                 map_flags |= MAP_SHARED;
23363  
23364 @@ -397,7 +419,12 @@ unsigned long do_mremap(unsigned long ad
23365                         if (new_addr & ~PAGE_MASK)
23366                                 goto out;
23367                 }
23368 +               map_flags = vma->vm_flags;
23369                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
23370 +               if (!(ret & ~PAGE_MASK)) {
23371 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
23372 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
23373 +               }
23374         }
23375  out:
23376         if (ret & ~PAGE_MASK)
23377 diff -urNp linux-2.6.16.12/mm/rmap.c linux-2.6.16.12/mm/rmap.c
23378 --- linux-2.6.16.12/mm/rmap.c   2006-05-01 15:14:26.000000000 -0400
23379 +++ linux-2.6.16.12/mm/rmap.c   2006-05-01 20:17:34.000000000 -0400
23380 @@ -109,6 +109,19 @@ int anon_vma_prepare(struct vm_area_stru
23381                         list_add(&vma->anon_vma_node, &anon_vma->head);
23382                         allocated = NULL;
23383                 }
23384 +
23385 +#ifdef CONFIG_PAX_SEGMEXEC
23386 +               if (vma->vm_flags & VM_MIRROR) {
23387 +                       struct vm_area_struct *vma_m;
23388 +
23389 +                       vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
23390 +                       BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
23391 +                       BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
23392 +                       vma_m->anon_vma = anon_vma;
23393 +                       __anon_vma_link(vma_m);
23394 +               }
23395 +#endif
23396 +
23397                 spin_unlock(&mm->page_table_lock);
23398  
23399                 if (locked)
23400 diff -urNp linux-2.6.16.12/mm/vmalloc.c linux-2.6.16.12/mm/vmalloc.c
23401 --- linux-2.6.16.12/mm/vmalloc.c        2006-05-01 15:14:26.000000000 -0400
23402 +++ linux-2.6.16.12/mm/vmalloc.c        2006-05-01 20:17:34.000000000 -0400
23403 @@ -193,6 +193,8 @@ struct vm_struct *__get_vm_area_node(uns
23404  
23405         write_lock(&vmlist_lock);
23406         for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
23407 +               if (addr > end - size)
23408 +                       goto out;
23409                 if ((unsigned long)tmp->addr < addr) {
23410                         if((unsigned long)tmp->addr + tmp->size >= addr)
23411                                 addr = ALIGN(tmp->size + 
23412 @@ -204,8 +206,6 @@ struct vm_struct *__get_vm_area_node(uns
23413                 if (size + addr <= (unsigned long)tmp->addr)
23414                         goto found;
23415                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
23416 -               if (addr > end - size)
23417 -                       goto out;
23418         }
23419  
23420  found:
23421 diff -urNp linux-2.6.16.12/net/ipv4/inet_connection_sock.c linux-2.6.16.12/net/ipv4/inet_connection_sock.c
23422 --- linux-2.6.16.12/net/ipv4/inet_connection_sock.c     2006-05-01 15:14:26.000000000 -0400
23423 +++ linux-2.6.16.12/net/ipv4/inet_connection_sock.c     2006-05-01 20:17:34.000000000 -0400
23424 @@ -16,6 +16,7 @@
23425  #include <linux/config.h>
23426  #include <linux/module.h>
23427  #include <linux/jhash.h>
23428 +#include <linux/grsecurity.h>
23429  
23430  #include <net/inet_connection_sock.h>
23431  #include <net/inet_hashtables.h>
23432 diff -urNp linux-2.6.16.12/net/ipv4/inet_hashtables.c linux-2.6.16.12/net/ipv4/inet_hashtables.c
23433 --- linux-2.6.16.12/net/ipv4/inet_hashtables.c  2006-05-01 15:14:26.000000000 -0400
23434 +++ linux-2.6.16.12/net/ipv4/inet_hashtables.c  2006-05-01 20:17:34.000000000 -0400
23435 @@ -19,11 +19,14 @@
23436  #include <linux/sched.h>
23437  #include <linux/slab.h>
23438  #include <linux/wait.h>
23439 +#include <linux/grsecurity.h>
23440  
23441  #include <net/inet_connection_sock.h>
23442  #include <net/inet_hashtables.h>
23443  #include <net/ip.h>
23444  
23445 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
23446 +
23447  /*
23448   * Allocate and initialize a new local port bind bucket.
23449   * The bindhash mutex for snum's hash chain must be held here.
23450 @@ -313,6 +316,8 @@ ok:
23451                 }
23452                 spin_unlock(&head->lock);
23453  
23454 +               gr_update_task_in_ip_table(current, inet_sk(sk));
23455 +
23456                 if (tw) {
23457                         inet_twsk_deschedule(tw, death_row);;
23458                         inet_twsk_put(tw);
23459 diff -urNp linux-2.6.16.12/net/ipv4/netfilter/ipt_stealth.c linux-2.6.16.12/net/ipv4/netfilter/ipt_stealth.c
23460 --- linux-2.6.16.12/net/ipv4/netfilter/ipt_stealth.c    1969-12-31 19:00:00.000000000 -0500
23461 +++ linux-2.6.16.12/net/ipv4/netfilter/ipt_stealth.c    2006-05-01 20:17:34.000000000 -0400
23462 @@ -0,0 +1,112 @@
23463 +/* Kernel module to add stealth support.
23464 + *
23465 + * Copyright (C) 2002,2005 Brad Spengler  <spender@grsecurity.net>
23466 + *
23467 + */
23468 +
23469 +#include <linux/kernel.h>
23470 +#include <linux/module.h>
23471 +#include <linux/skbuff.h>
23472 +#include <linux/net.h>
23473 +#include <linux/sched.h>
23474 +#include <linux/inet.h>
23475 +#include <linux/stddef.h>
23476 +
23477 +#include <net/ip.h>
23478 +#include <net/sock.h>
23479 +#include <net/tcp.h>
23480 +#include <net/udp.h>
23481 +#include <net/route.h>
23482 +#include <net/inet_common.h>
23483 +
23484 +#include <linux/netfilter_ipv4/ip_tables.h>
23485 +
23486 +MODULE_LICENSE("GPL");
23487 +
23488 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
23489 +
23490 +static int
23491 +match(const struct sk_buff *skb,
23492 +      const struct net_device *in,
23493 +      const struct net_device *out,
23494 +      const void *matchinfo,
23495 +      int offset,
23496 +      int *hotdrop)
23497 +{
23498 +       struct iphdr *ip = skb->nh.iph;
23499 +       struct tcphdr th;
23500 +       struct udphdr uh;
23501 +       struct sock *sk = NULL;
23502 +
23503 +       if (!ip || offset) return 0;
23504 +
23505 +       switch(ip->protocol) {
23506 +       case IPPROTO_TCP:
23507 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
23508 +                       *hotdrop = 1;
23509 +                       return 0;
23510 +               }
23511 +               if (!(th.syn && !th.ack)) return 0;
23512 +               sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);        
23513 +               break;
23514 +       case IPPROTO_UDP:
23515 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
23516 +                       *hotdrop = 1;
23517 +                       return 0;
23518 +               }
23519 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
23520 +               break;
23521 +       default:
23522 +               return 0;
23523 +       }
23524 +
23525 +       if(!sk) // port is being listened on, match this
23526 +               return 1;
23527 +       else {
23528 +               sock_put(sk);
23529 +               return 0;
23530 +       }
23531 +}
23532 +
23533 +/* Called when user tries to insert an entry of this type. */
23534 +static int
23535 +checkentry(const char *tablename,
23536 +           const struct ipt_ip *ip,
23537 +           void *matchinfo,
23538 +           unsigned int matchsize,
23539 +           unsigned int hook_mask)
23540 +{
23541 +        if (matchsize != IPT_ALIGN(0))
23542 +                return 0;
23543 +
23544 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
23545 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
23546 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
23547 +                       return 1;
23548 +
23549 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
23550 +
23551 +        return 0;
23552 +}
23553 +
23554 +
23555 +static struct ipt_match stealth_match = {
23556 +       .name = "stealth",
23557 +       .match = &match,
23558 +       .checkentry = &checkentry,
23559 +       .destroy = NULL,
23560 +       .me = THIS_MODULE
23561 +};
23562 +
23563 +static int __init init(void)
23564 +{
23565 +       return ipt_register_match(&stealth_match);
23566 +}
23567 +
23568 +static void __exit fini(void)
23569 +{
23570 +       ipt_unregister_match(&stealth_match);
23571 +}
23572 +
23573 +module_init(init);
23574 +module_exit(fini);
23575 diff -urNp linux-2.6.16.12/net/ipv4/netfilter/Kconfig linux-2.6.16.12/net/ipv4/netfilter/Kconfig
23576 --- linux-2.6.16.12/net/ipv4/netfilter/Kconfig  2006-05-01 15:14:26.000000000 -0400
23577 +++ linux-2.6.16.12/net/ipv4/netfilter/Kconfig  2006-05-01 20:17:34.000000000 -0400
23578 @@ -313,6 +313,21 @@ config IP_NF_MATCH_POLICY
23579  
23580           To compile it as a module, choose M here.  If unsure, say N.
23581  
23582 +config IP_NF_MATCH_STEALTH
23583 +       tristate "stealth match support"
23584 +       depends on IP_NF_IPTABLES
23585 +       help
23586 +         Enabling this option will drop all syn packets coming to unserved tcp
23587 +         ports as well as all packets coming to unserved udp ports.  If you
23588 +         are using your system to route any type of packets (ie. via NAT)
23589 +         you should put this module at the end of your ruleset, since it will
23590 +         drop packets that aren't going to ports that are listening on your
23591 +         machine itself, it doesn't take into account that the packet might be
23592 +         destined for someone on your internal network if you're using NAT for
23593 +         instance.
23594 +
23595 +         To compile it as a module, choose M here.  If unsure, say N.
23596 +
23597  # `filter', generic and specific targets
23598  config IP_NF_FILTER
23599         tristate "Packet filtering"
23600 diff -urNp linux-2.6.16.12/net/ipv4/netfilter/Makefile linux-2.6.16.12/net/ipv4/netfilter/Makefile
23601 --- linux-2.6.16.12/net/ipv4/netfilter/Makefile 2006-05-01 15:14:26.000000000 -0400
23602 +++ linux-2.6.16.12/net/ipv4/netfilter/Makefile 2006-05-01 20:17:34.000000000 -0400
23603 @@ -91,6 +91,7 @@ obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_
23604  obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
23605  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
23606  obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
23607 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
23608  
23609  # targets
23610  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
23611 diff -urNp linux-2.6.16.12/net/ipv4/tcp_ipv4.c linux-2.6.16.12/net/ipv4/tcp_ipv4.c
23612 --- linux-2.6.16.12/net/ipv4/tcp_ipv4.c 2006-05-01 15:14:26.000000000 -0400
23613 +++ linux-2.6.16.12/net/ipv4/tcp_ipv4.c 2006-05-01 20:17:34.000000000 -0400
23614 @@ -62,6 +62,7 @@
23615  #include <linux/jhash.h>
23616  #include <linux/init.h>
23617  #include <linux/times.h>
23618 +#include <linux/grsecurity.h>
23619  
23620  #include <net/icmp.h>
23621  #include <net/inet_hashtables.h>
23622 diff -urNp linux-2.6.16.12/net/ipv4/udp.c linux-2.6.16.12/net/ipv4/udp.c
23623 --- linux-2.6.16.12/net/ipv4/udp.c      2006-05-01 15:14:26.000000000 -0400
23624 +++ linux-2.6.16.12/net/ipv4/udp.c      2006-05-01 20:17:34.000000000 -0400
23625 @@ -102,6 +102,7 @@
23626  #include <linux/skbuff.h>
23627  #include <linux/proc_fs.h>
23628  #include <linux/seq_file.h>
23629 +#include <linux/grsecurity.h>
23630  #include <net/sock.h>
23631  #include <net/udp.h>
23632  #include <net/icmp.h>
23633 @@ -110,6 +111,12 @@
23634  #include <net/checksum.h>
23635  #include <net/xfrm.h>
23636  
23637 +extern int gr_search_udp_recvmsg(const struct sock *sk,
23638 +                                const struct sk_buff *skb);
23639 +extern int gr_search_udp_sendmsg(const struct sock *sk,
23640 +                                const struct sockaddr_in *addr);
23641 +
23642 +
23643  /*
23644   *     Snmp MIB for the UDP layer
23645   */
23646 @@ -270,8 +277,7 @@ static struct sock *udp_v4_lookup_longwa
23647         return result;
23648  }
23649  
23650 -static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
23651 -                                            u32 daddr, u16 dport, int dif)
23652 +struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
23653  {
23654         struct sock *sk;
23655  
23656 @@ -547,9 +553,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
23657                 dport = usin->sin_port;
23658                 if (dport == 0)
23659                         return -EINVAL;
23660 +
23661 +               if (!gr_search_udp_sendmsg(sk, usin))
23662 +                       return -EPERM;
23663         } else {
23664                 if (sk->sk_state != TCP_ESTABLISHED)
23665                         return -EDESTADDRREQ;
23666 +
23667 +               if (!gr_search_udp_sendmsg(sk, NULL))
23668 +                       return -EPERM;
23669 +
23670                 daddr = inet->daddr;
23671                 dport = inet->dport;
23672                 /* Open fast path for connected socket.
23673 @@ -812,6 +825,11 @@ try_again:
23674         if (!skb)
23675                 goto out;
23676    
23677 +       if (!gr_search_udp_recvmsg(sk, skb)) {
23678 +               err = -EPERM;
23679 +               goto out_free;
23680 +       }
23681 +
23682         copied = skb->len - sizeof(struct udphdr);
23683         if (copied > len) {
23684                 copied = len;
23685 diff -urNp linux-2.6.16.12/net/socket.c linux-2.6.16.12/net/socket.c
23686 --- linux-2.6.16.12/net/socket.c        2006-05-01 15:14:26.000000000 -0400
23687 +++ linux-2.6.16.12/net/socket.c        2006-05-01 20:17:34.000000000 -0400
23688 @@ -84,6 +84,7 @@
23689  #include <linux/compat.h>
23690  #include <linux/kmod.h>
23691  #include <linux/audit.h>
23692 +#include <linux/in.h>
23693  
23694  #ifdef CONFIG_NET_RADIO
23695  #include <linux/wireless.h>            /* Note : will define WIRELESS_EXT */
23696 @@ -98,6 +99,21 @@
23697  #include <linux/netfilter.h>
23698  #include <linux/vs_socket.h>
23699  
23700 +extern void gr_attach_curr_ip(const struct sock *sk);
23701 +extern int gr_handle_sock_all(const int family, const int type,
23702 +                             const int protocol);
23703 +extern int gr_handle_sock_server(const struct sockaddr *sck);
23704 +extern int gr_handle_sock_server_other(const struct socket *sck);
23705 +extern int gr_handle_sock_client(const struct sockaddr *sck);
23706 +extern int gr_search_connect(const struct socket * sock,
23707 +                            const struct sockaddr_in * addr);
23708 +extern int gr_search_bind(const struct socket * sock,
23709 +                          const struct sockaddr_in * addr);
23710 +extern int gr_search_listen(const struct socket * sock);
23711 +extern int gr_search_accept(const struct socket * sock);
23712 +extern int gr_search_socket(const int domain, const int type,
23713 +                           const int protocol);
23714 +
23715  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
23716  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
23717                          size_t size, loff_t pos);
23718 @@ -1223,6 +1239,16 @@ asmlinkage long sys_socket(int family, i
23719         int retval;
23720         struct socket *sock;
23721  
23722 +       if(!gr_search_socket(family, type, protocol)) {
23723 +               retval = -EACCES;
23724 +               goto out;
23725 +       }
23726 +
23727 +       if (gr_handle_sock_all(family, type, protocol)) {
23728 +               retval = -EACCES;
23729 +               goto out;
23730 +       }
23731 +
23732         retval = sock_create(family, type, protocol, &sock);
23733         if (retval < 0)
23734                 goto out;
23735 @@ -1321,11 +1347,23 @@ asmlinkage long sys_bind(int fd, struct 
23736  {
23737         struct socket *sock;
23738         char address[MAX_SOCK_ADDR];
23739 +       struct sockaddr *sck;
23740         int err;
23741  
23742         if((sock = sockfd_lookup(fd,&err))!=NULL)
23743         {
23744                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
23745 +                       sck = (struct sockaddr *)address;
23746 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck)) {
23747 +                               sockfd_put(sock);
23748 +                               return -EACCES;
23749 +                       }
23750 +
23751 +                       if (gr_handle_sock_server(sck)) {
23752 +                               sockfd_put(sock);
23753 +                               return -EACCES;
23754 +                       }
23755 +
23756                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
23757                         if (err) {
23758                                 sockfd_put(sock);
23759 @@ -1362,6 +1400,16 @@ asmlinkage long sys_listen(int fd, int b
23760                         return err;
23761                 }
23762  
23763 +               if (gr_handle_sock_server_other(sock)) {
23764 +                       sockfd_put(sock);
23765 +                       return -EPERM;
23766 +               }
23767 +
23768 +               if(!gr_search_listen(sock)) {
23769 +                       sockfd_put(sock);
23770 +                       return -EPERM;
23771 +               }
23772 +
23773                 err=sock->ops->listen(sock, backlog);
23774                 sockfd_put(sock);
23775         }
23776 @@ -1398,6 +1446,16 @@ asmlinkage long sys_accept(int fd, struc
23777         newsock->type = sock->type;
23778         newsock->ops = sock->ops;
23779  
23780 +       if (gr_handle_sock_server_other(sock)) {
23781 +               err = -EPERM;
23782 +               goto out_release;
23783 +       }
23784 +
23785 +       if(!gr_search_accept(sock)) {
23786 +               err = -EPERM;
23787 +               goto out_release;
23788 +       }
23789 +
23790         /*
23791          * We don't need try_module_get here, as the listening socket (sock)
23792          * has the protocol module (sock->ops->owner) held.
23793 @@ -1428,6 +1486,7 @@ asmlinkage long sys_accept(int fd, struc
23794                 goto out_release;
23795  
23796         security_socket_post_accept(sock, newsock);
23797 +       gr_attach_curr_ip(newsock->sk);
23798  
23799  out_put:
23800         sockfd_put(sock);
23801 @@ -1455,6 +1514,7 @@ asmlinkage long sys_connect(int fd, stru
23802  {
23803         struct socket *sock;
23804         char address[MAX_SOCK_ADDR];
23805 +       struct sockaddr *sck;
23806         int err;
23807  
23808         sock = sockfd_lookup(fd, &err);
23809 @@ -1464,6 +1524,18 @@ asmlinkage long sys_connect(int fd, stru
23810         if (err < 0)
23811                 goto out_put;
23812  
23813 +       sck = (struct sockaddr *)address;
23814 +
23815 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck)) {
23816 +               err = -EACCES;
23817 +               goto out_put;
23818 +       }
23819 +
23820 +       if (gr_handle_sock_client(sck)) {
23821 +               err = -EACCES;
23822 +               goto out_put;
23823 +       }
23824 +
23825         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
23826         if (err)
23827                 goto out_put;
23828 @@ -1717,6 +1789,7 @@ asmlinkage long sys_shutdown(int fd, int
23829                 err=sock->ops->shutdown(sock, how);
23830                 sockfd_put(sock);
23831         }
23832 +
23833         return err;
23834  }
23835  
23836 diff -urNp linux-2.6.16.12/net/unix/af_unix.c linux-2.6.16.12/net/unix/af_unix.c
23837 --- linux-2.6.16.12/net/unix/af_unix.c  2006-05-01 15:14:26.000000000 -0400
23838 +++ linux-2.6.16.12/net/unix/af_unix.c  2006-05-01 20:17:34.000000000 -0400
23839 @@ -120,6 +120,7 @@
23840  #include <linux/vs_context.h>
23841  #include <linux/vs_network.h>
23842  #include <linux/vs_limit.h>
23843 +#include <linux/grsecurity.h>
23844  
23845  int sysctl_unix_max_dgram_qlen = 10;
23846  
23847 @@ -685,6 +686,11 @@ static struct sock *unix_find_other(stru
23848                 if (err)
23849                         goto put_fail;
23850  
23851 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
23852 +                       err = -EACCES;
23853 +                       goto put_fail;
23854 +               }
23855 +
23856                 err = -ECONNREFUSED;
23857                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
23858                         goto put_fail;
23859 @@ -708,6 +714,13 @@ static struct sock *unix_find_other(stru
23860                 if (u) {
23861                         struct dentry *dentry;
23862                         dentry = unix_sk(u)->dentry;
23863 +
23864 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
23865 +                               err = -EPERM;
23866 +                               sock_put(u);
23867 +                               goto fail;
23868 +                       }
23869 +
23870                         if (dentry)
23871                                 touch_atime(unix_sk(u)->mnt, dentry);
23872                 } else
23873 @@ -786,9 +799,18 @@ static int unix_bind(struct socket *sock
23874                  */
23875                 mode = S_IFSOCK |
23876                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
23877 +
23878 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
23879 +                       err = -EACCES;
23880 +                       goto out_mknod_dput;
23881 +               }
23882 +
23883                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
23884                 if (err)
23885                         goto out_mknod_dput;
23886 +
23887 +               gr_handle_create(dentry, nd.mnt);
23888 +
23889                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
23890                 dput(nd.dentry);
23891                 nd.dentry = dentry;
23892 @@ -806,6 +828,10 @@ static int unix_bind(struct socket *sock
23893                         goto out_unlock;
23894                 }
23895  
23896 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23897 +               sk->sk_peercred.pid = current->pid;
23898 +#endif
23899 +
23900                 list = &unix_socket_table[addr->hash];
23901         } else {
23902                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
23903 diff -urNp linux-2.6.16.12/security/commoncap.c linux-2.6.16.12/security/commoncap.c
23904 --- linux-2.6.16.12/security/commoncap.c        2006-05-01 15:14:26.000000000 -0400
23905 +++ linux-2.6.16.12/security/commoncap.c        2006-05-01 20:17:34.000000000 -0400
23906 @@ -24,6 +24,7 @@
23907  #include <linux/ptrace.h>
23908  #include <linux/xattr.h>
23909  #include <linux/hugetlb.h>
23910 +#include <linux/grsecurity.h>
23911  
23912  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
23913  {
23914 @@ -45,7 +46,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
23915  int cap_capable (struct task_struct *tsk, int cap)
23916  {
23917         /* Derived from include/linux/sched.h:capable. */
23918 -       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
23919 +       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
23920 +               return 0;
23921 +       return -EPERM;
23922 +}
23923 +
23924 +int cap_capable_nolog (struct task_struct *tsk, int cap)
23925 +{
23926 +       /* Derived from include/linux/sched.h:capable. */
23927 +       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
23928                 return 0;
23929         return -EPERM;
23930  }
23931 @@ -61,7 +70,7 @@ int cap_ptrace (struct task_struct *pare
23932  {
23933         /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
23934         if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
23935 -           !capable(CAP_SYS_PTRACE))
23936 +           !capable_nolog(CAP_SYS_PTRACE))
23937                 return -EPERM;
23938         return 0;
23939  }
23940 @@ -165,8 +174,11 @@ void cap_bprm_apply_creds (struct linux_
23941                 }
23942         }
23943  
23944 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
23945 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
23946 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
23947 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
23948 +
23949 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
23950 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
23951  
23952         /* For init, we want to retain the capabilities set
23953          * in the init_task struct. Thus we skip the usual
23954 @@ -177,6 +189,8 @@ void cap_bprm_apply_creds (struct linux_
23955                     cap_intersect (new_permitted, bprm->cap_effective);
23956         }
23957  
23958 +       gr_handle_chroot_caps(current);
23959 +
23960         /* AUD: Audit candidate if current->cap_effective is set */
23961  
23962         current->keep_capabilities = 0;
23963 @@ -323,12 +337,13 @@ int cap_vm_enough_memory(long pages)
23964  {
23965         int cap_sys_admin = 0;
23966  
23967 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
23968 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
23969                 cap_sys_admin = 1;
23970         return __vm_enough_memory(pages, cap_sys_admin);
23971  }
23972  
23973  EXPORT_SYMBOL(cap_capable);
23974 +EXPORT_SYMBOL(cap_capable_nolog);
23975  EXPORT_SYMBOL(cap_settime);
23976  EXPORT_SYMBOL(cap_ptrace);
23977  EXPORT_SYMBOL(cap_capget);
23978 diff -urNp linux-2.6.16.12/security/dummy.c linux-2.6.16.12/security/dummy.c
23979 --- linux-2.6.16.12/security/dummy.c    2006-05-01 15:14:26.000000000 -0400
23980 +++ linux-2.6.16.12/security/dummy.c    2006-05-01 20:17:34.000000000 -0400
23981 @@ -29,6 +29,7 @@
23982  #include <linux/hugetlb.h>
23983  #include <linux/ptrace.h>
23984  #include <linux/file.h>
23985 +#include <linux/grsecurity.h>
23986  
23987  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
23988  {
23989 @@ -139,8 +140,11 @@ static void dummy_bprm_apply_creds (stru
23990                 }
23991         }
23992  
23993 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
23994 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
23995 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
23996 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
23997 +
23998 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
23999 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
24000  
24001         dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
24002  }
24003 diff -urNp linux-2.6.16.12/security/Kconfig linux-2.6.16.12/security/Kconfig
24004 --- linux-2.6.16.12/security/Kconfig    2006-05-01 15:14:26.000000000 -0400
24005 +++ linux-2.6.16.12/security/Kconfig    2006-05-01 20:17:34.000000000 -0400
24006 @@ -4,6 +4,408 @@
24007  
24008  menu "Security options"
24009  
24010 +menu "PaX"
24011 +
24012 +config PAX
24013 +       bool "Enable various PaX features"
24014 +       depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
24015 +       help
24016 +         This allows you to enable various PaX features.  PaX adds
24017 +         intrusion prevention mechanisms to the kernel that reduce
24018 +         the risks posed by exploitable memory corruption bugs.
24019 +
24020 +menu "PaX Control"
24021 +       depends on PAX
24022 +
24023 +config PAX_SOFTMODE
24024 +       bool 'Support soft mode'
24025 +       help
24026 +         Enabling this option will allow you to run PaX in soft mode, that
24027 +         is, PaX features will not be enforced by default, only on executables
24028 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
24029 +         is the only way to mark executables for soft mode use.
24030 +
24031 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
24032 +         line option on boot.  Furthermore you can control various PaX features
24033 +         at runtime via the entries in /proc/sys/kernel/pax.
24034 +
24035 +config PAX_EI_PAX
24036 +       bool 'Use legacy ELF header marking'
24037 +       help
24038 +         Enabling this option will allow you to control PaX features on
24039 +         a per executable basis via the 'chpax' utility available at
24040 +         http://pax.grsecurity.net/.  The control flags will be read from
24041 +         an otherwise reserved part of the ELF header.  This marking has
24042 +         numerous drawbacks (no support for soft-mode, toolchain does not
24043 +         know about the non-standard use of the ELF header) therefore it
24044 +         has been deprecated in favour of PT_PAX_FLAGS support.
24045 +
24046 +         If you have applications not marked by the PT_PAX_FLAGS ELF
24047 +         program header then you MUST enable this option otherwise they
24048 +         will not get any protection.
24049 +
24050 +         Note that if you enable PT_PAX_FLAGS marking support as well,
24051 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
24052 +
24053 +config PAX_PT_PAX_FLAGS
24054 +       bool 'Use ELF program header marking'
24055 +       help
24056 +         Enabling this option will allow you to control PaX features on
24057 +         a per executable basis via the 'paxctl' utility available at
24058 +         http://pax.grsecurity.net/.  The control flags will be read from
24059 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
24060 +         has the benefits of supporting both soft mode and being fully
24061 +         integrated into the toolchain (the binutils patch is available
24062 +         from http://pax.grsecurity.net).
24063 +
24064 +         If you have applications not marked by the PT_PAX_FLAGS ELF
24065 +         program header then you MUST enable the EI_PAX marking support
24066 +         otherwise they will not get any protection.
24067 +
24068 +         Note that if you enable the legacy EI_PAX marking support as well,
24069 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
24070 +
24071 +choice
24072 +       prompt 'MAC system integration'
24073 +       default PAX_HAVE_ACL_FLAGS
24074 +       help
24075 +         Mandatory Access Control systems have the option of controlling
24076 +         PaX flags on a per executable basis, choose the method supported
24077 +         by your particular system.
24078 +
24079 +         - "none": if your MAC system does not interact with PaX,
24080 +         - "direct": if your MAC system defines pax_set_flags() itself,
24081 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
24082 +
24083 +         NOTE: this option is for developers/integrators only.
24084 +
24085 +config PAX_NO_ACL_FLAGS
24086 +       bool 'none'
24087 +
24088 +config PAX_HAVE_ACL_FLAGS
24089 +       bool 'direct'
24090 +
24091 +config PAX_HOOK_ACL_FLAGS
24092 +       bool 'hook'
24093 +endchoice
24094 +
24095 +endmenu
24096 +
24097 +menu "Non-executable pages"
24098 +       depends on PAX
24099 +
24100 +config PAX_NOEXEC
24101 +       bool "Enforce non-executable pages"
24102 +       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)
24103 +       help
24104 +         By design some architectures do not allow for protecting memory
24105 +         pages against execution or even if they do, Linux does not make
24106 +         use of this feature.  In practice this means that if a page is
24107 +         readable (such as the stack or heap) it is also executable.
24108 +
24109 +         There is a well known exploit technique that makes use of this
24110 +         fact and a common programming mistake where an attacker can
24111 +         introduce code of his choice somewhere in the attacked program's
24112 +         memory (typically the stack or the heap) and then execute it.
24113 +
24114 +         If the attacked program was running with different (typically
24115 +         higher) privileges than that of the attacker, then he can elevate
24116 +         his own privilege level (e.g. get a root shell, write to files for
24117 +         which he does not have write access to, etc).
24118 +
24119 +         Enabling this option will let you choose from various features
24120 +         that prevent the injection and execution of 'foreign' code in
24121 +         a program.
24122 +
24123 +         This will also break programs that rely on the old behaviour and
24124 +         expect that dynamically allocated memory via the malloc() family
24125 +         of functions is executable (which it is not).  Notable examples
24126 +         are the XFree86 4.x server, the java runtime and wine.
24127 +
24128 +config PAX_PAGEEXEC
24129 +       bool "Paging based non-executable pages"
24130 +       depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
24131 +       select PAX_NOVSYSCALL if X86_32
24132 +       help
24133 +         This implementation is based on the paging feature of the CPU.
24134 +         On i386 and ppc there is a variable but usually low performance
24135 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
24136 +         and x86_64 there is no performance impact.
24137 +
24138 +config PAX_SEGMEXEC
24139 +       bool "Segmentation based non-executable pages"
24140 +       depends on PAX_NOEXEC && X86_32
24141 +       select PAX_NOVSYSCALL if X86_32
24142 +       help
24143 +         This implementation is based on the segmentation feature of the
24144 +         CPU and has little performance impact, however applications will
24145 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
24146 +
24147 +choice
24148 +       prompt "Default non-executable page method"
24149 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
24150 +       default PAX_DEFAULT_SEGMEXEC
24151 +       help
24152 +         Select the default non-executable page method applied to applications
24153 +         that do not select one themselves.
24154 +
24155 +config PAX_DEFAULT_PAGEEXEC
24156 +       bool "PAGEEXEC"
24157 +
24158 +config PAX_DEFAULT_SEGMEXEC
24159 +       bool "SEGMEXEC"
24160 +endchoice
24161 +
24162 +config PAX_EMUTRAMP
24163 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
24164 +       default y if PARISC || PPC32
24165 +       help
24166 +         There are some programs and libraries that for one reason or
24167 +         another attempt to execute special small code snippets from
24168 +         non-executable memory pages.  Most notable examples are the
24169 +         signal handler return code generated by the kernel itself and
24170 +         the GCC trampolines.
24171 +
24172 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
24173 +         such programs will no longer work under your kernel.
24174 +
24175 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
24176 +         utilities to enable trampoline emulation for the affected programs
24177 +         yet still have the protection provided by the non-executable pages.
24178 +
24179 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
24180 +         well, otherwise your system will not even boot.
24181 +
24182 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
24183 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
24184 +         for the affected files.
24185 +
24186 +         NOTE: enabling this feature *may* open up a loophole in the
24187 +         protection provided by non-executable pages that an attacker
24188 +         could abuse.  Therefore the best solution is to not have any
24189 +         files on your system that would require this option.  This can
24190 +         be achieved by not using libc5 (which relies on the kernel
24191 +         signal handler return code) and not using or rewriting programs
24192 +         that make use of the nested function implementation of GCC.
24193 +         Skilled users can just fix GCC itself so that it implements
24194 +         nested function calls in a way that does not interfere with PaX.
24195 +
24196 +config PAX_EMUSIGRT
24197 +       bool "Automatically emulate sigreturn trampolines"
24198 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
24199 +       default y
24200 +       help
24201 +         Enabling this option will have the kernel automatically detect
24202 +         and emulate signal return trampolines executing on the stack
24203 +         that would otherwise lead to task termination.
24204 +
24205 +         This solution is intended as a temporary one for users with
24206 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
24207 +         Modula-3 runtime, etc) or executables linked to such, basically
24208 +         everything that does not specify its own SA_RESTORER function in
24209 +         normal executable memory like glibc 2.1+ does.
24210 +
24211 +         On parisc and ppc you MUST enable this option, otherwise your
24212 +         system will not even boot.
24213 +
24214 +         NOTE: this feature cannot be disabled on a per executable basis
24215 +         and since it *does* open up a loophole in the protection provided
24216 +         by non-executable pages, the best solution is to not have any
24217 +         files on your system that would require this option.
24218 +
24219 +config PAX_MPROTECT
24220 +       bool "Restrict mprotect()"
24221 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
24222 +       help
24223 +         Enabling this option will prevent programs from
24224 +          - changing the executable status of memory pages that were
24225 +            not originally created as executable,
24226 +          - making read-only executable pages writable again,
24227 +          - creating executable pages from anonymous memory.
24228 +
24229 +         You should say Y here to complete the protection provided by
24230 +         the enforcement of non-executable pages.
24231 +
24232 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
24233 +         this feature on a per file basis.
24234 +
24235 +config PAX_NOELFRELOCS
24236 +       bool "Disallow ELF text relocations"
24237 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
24238 +       help
24239 +         Non-executable pages and mprotect() restrictions are effective
24240 +         in preventing the introduction of new executable code into an
24241 +         attacked task's address space.  There remain only two venues
24242 +         for this kind of attack: if the attacker can execute already
24243 +         existing code in the attacked task then he can either have it
24244 +         create and mmap() a file containing his code or have it mmap()
24245 +         an already existing ELF library that does not have position
24246 +         independent code in it and use mprotect() on it to make it
24247 +         writable and copy his code there.  While protecting against
24248 +         the former approach is beyond PaX, the latter can be prevented
24249 +         by having only PIC ELF libraries on one's system (which do not
24250 +         need to relocate their code).  If you are sure this is your case,
24251 +         then enable this option otherwise be careful as you may not even
24252 +         be able to boot or log on your system (for example, some PAM
24253 +         modules are erroneously compiled as non-PIC by default).
24254 +
24255 +         NOTE: if you are using dynamic ELF executables (as suggested
24256 +         when using ASLR) then you must have made sure that you linked
24257 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
24258 +         referenced there has already been updated to support this).
24259 +
24260 +config PAX_ETEXECRELOCS
24261 +       bool "Allow ELF ET_EXEC text relocations"
24262 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
24263 +       default y
24264 +       help
24265 +         On some architectures there are incorrectly created applications
24266 +         that require text relocations and would not work without enabling
24267 +         this option.  If you are an alpha, ia64 or parisc user, you should
24268 +         enable this option and disable it once you have made sure that
24269 +         none of your applications need it.
24270 +
24271 +config PAX_EMUPLT
24272 +       bool "Automatically emulate ELF PLT"
24273 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
24274 +       default y
24275 +       help
24276 +         Enabling this option will have the kernel automatically detect
24277 +         and emulate the Procedure Linkage Table entries in ELF files.
24278 +         On some architectures such entries are in writable memory, and
24279 +         become non-executable leading to task termination.  Therefore
24280 +         it is mandatory that you enable this option on alpha, parisc, ppc,
24281 +         sparc and sparc64, otherwise your system would not even boot.
24282 +
24283 +         NOTE: this feature *does* open up a loophole in the protection
24284 +         provided by the non-executable pages, therefore the proper
24285 +         solution is to modify the toolchain to produce a PLT that does
24286 +         not need to be writable.
24287 +
24288 +config PAX_DLRESOLVE
24289 +       bool
24290 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
24291 +       default y
24292 +
24293 +config PAX_SYSCALL
24294 +       bool
24295 +       depends on PAX_PAGEEXEC && PPC32
24296 +       default y
24297 +
24298 +config PAX_KERNEXEC
24299 +       bool "Enforce non-executable kernel pages"
24300 +       depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !DEBUG_RODATA
24301 +       help
24302 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
24303 +         that is, enabling this option will make it harder to inject
24304 +         and execute 'foreign' code in kernel memory itself.
24305 +
24306 +endmenu
24307 +
24308 +menu "Address Space Layout Randomization"
24309 +       depends on PAX
24310 +
24311 +config PAX_ASLR
24312 +       bool "Address Space Layout Randomization"
24313 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
24314 +       help
24315 +         Many if not most exploit techniques rely on the knowledge of
24316 +         certain addresses in the attacked program.  The following options
24317 +         will allow the kernel to apply a certain amount of randomization
24318 +         to specific parts of the program thereby forcing an attacker to
24319 +         guess them in most cases.  Any failed guess will most likely crash
24320 +         the attacked program which allows the kernel to detect such attempts
24321 +         and react on them.  PaX itself provides no reaction mechanisms,
24322 +         instead it is strongly encouraged that you make use of Nergal's
24323 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
24324 +         (http://www.grsecurity.net/) built-in crash detection features or
24325 +         develop one yourself.
24326 +
24327 +         By saying Y here you can choose to randomize the following areas:
24328 +          - top of the task's kernel stack
24329 +          - top of the task's userland stack
24330 +          - base address for mmap() requests that do not specify one
24331 +            (this includes all libraries)
24332 +          - base address of the main executable
24333 +
24334 +         It is strongly recommended to say Y here as address space layout
24335 +         randomization has negligible impact on performance yet it provides
24336 +         a very effective protection.
24337 +
24338 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
24339 +         this feature on a per file basis.
24340 +
24341 +config PAX_RANDKSTACK
24342 +       bool "Randomize kernel stack base"
24343 +       depends on PAX_ASLR && X86_TSC && X86_32
24344 +       help
24345 +         By saying Y here the kernel will randomize every task's kernel
24346 +         stack on every system call.  This will not only force an attacker
24347 +         to guess it but also prevent him from making use of possible
24348 +         leaked information about it.
24349 +
24350 +         Since the kernel stack is a rather scarce resource, randomization
24351 +         may cause unexpected stack overflows, therefore you should very
24352 +         carefully test your system.  Note that once enabled in the kernel
24353 +         configuration, this feature cannot be disabled on a per file basis.
24354 +
24355 +config PAX_RANDUSTACK
24356 +       bool "Randomize user stack base"
24357 +       depends on PAX_ASLR
24358 +       help
24359 +         By saying Y here the kernel will randomize every task's userland
24360 +         stack.  The randomization is done in two steps where the second
24361 +         one may apply a big amount of shift to the top of the stack and
24362 +         cause problems for programs that want to use lots of memory (more
24363 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
24364 +         For this reason the second step can be controlled by 'chpax' or
24365 +         'paxctl' on a per file basis.
24366 +
24367 +config PAX_RANDMMAP
24368 +       bool "Randomize mmap() base"
24369 +       depends on PAX_ASLR
24370 +       help
24371 +         By saying Y here the kernel will use a randomized base address for
24372 +         mmap() requests that do not specify one themselves.  As a result
24373 +         all dynamically loaded libraries will appear at random addresses
24374 +         and therefore be harder to exploit by a technique where an attacker
24375 +         attempts to execute library code for his purposes (e.g. spawn a
24376 +         shell from an exploited program that is running at an elevated
24377 +         privilege level).
24378 +
24379 +         Furthermore, if a program is relinked as a dynamic ELF file, its
24380 +         base address will be randomized as well, completing the full
24381 +         randomization of the address space layout.  Attacking such programs
24382 +         becomes a guess game.  You can find an example of doing this at
24383 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
24384 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
24385 +
24386 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
24387 +         feature on a per file basis.
24388 +
24389 +config PAX_NOVSYSCALL
24390 +       bool "Disable the vsyscall page"
24391 +       depends on PAX_ASLR && X86_32
24392 +       help
24393 +         The Linux 2.6 kernel introduced a new feature that speeds up or
24394 +         simplifies certain operations, such as system calls or returns
24395 +         from signal handlers.
24396 +
24397 +         Unfortunately the implementation also gives a powerful instrument
24398 +         into the hands of exploit writers: the so-called vsyscall page exists
24399 +         in every task at the same fixed address and it contains machine code
24400 +         that is very useful in performing the return-to-libc style attack.
24401 +
24402 +         Since this exploit technique cannot in general be protected against
24403 +         via kernel solutions, this option will allow you to disable the use
24404 +         of the vsyscall page and revert back to the old behaviour.
24405 +
24406 +endmenu
24407 +
24408 +endmenu
24409 +
24410 +source grsecurity/Kconfig
24411 +
24412  config KEYS
24413         bool "Enable access key retention support"
24414         help
24415 diff -urNp linux-2.6.16.12/security/security.c linux-2.6.16.12/security/security.c
24416 --- linux-2.6.16.12/security/security.c 2006-05-01 15:14:26.000000000 -0400
24417 +++ linux-2.6.16.12/security/security.c 2006-05-01 20:17:34.000000000 -0400
24418 @@ -204,4 +204,5 @@ EXPORT_SYMBOL_GPL(unregister_security);
24419  EXPORT_SYMBOL_GPL(mod_reg_security);
24420  EXPORT_SYMBOL_GPL(mod_unreg_security);
24421  EXPORT_SYMBOL(capable);
24422 +EXPORT_SYMBOL(capable_nolog);
24423  EXPORT_SYMBOL(security_ops);
This page took 1.790091 seconds and 3 git commands to generate.