]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.1.9-2.6.16.9.patch
BINFMT_COFF is off
[packages/kernel.git] / grsecurity-2.1.9-2.6.16.9.patch
1 diff -urNp linux-2.6.16.2/arch/alpha/kernel/module.c linux-2.6.16.2/arch/alpha/kernel/module.c
2 --- linux-2.6.16.2/arch/alpha/kernel/module.c   2006-04-07 12:56:47.000000000 -0400
3 +++ linux-2.6.16.2/arch/alpha/kernel/module.c   2006-04-09 21:23:54.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.2/arch/alpha/kernel/osf_sys.c linux-2.6.16.2/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.16.2/arch/alpha/kernel/osf_sys.c  2006-04-07 12:56:47.000000000 -0400
15 +++ linux-2.6.16.2/arch/alpha/kernel/osf_sys.c  2006-04-09 21:23:54.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.2/arch/alpha/kernel/ptrace.c linux-2.6.16.2/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.16.2/arch/alpha/kernel/ptrace.c   2006-04-07 12:56:47.000000000 -0400
40 +++ linux-2.6.16.2/arch/alpha/kernel/ptrace.c   2006-04-09 21:23:54.000000000 -0400
41 @@ -15,6 +15,7 @@
42  #include <linux/slab.h>
43  #include <linux/security.h>
44  #include <linux/signal.h>
45 +#include <linux/grsecurity.h>
46  
47  #include <asm/uaccess.h>
48  #include <asm/pgtable.h>
49 @@ -283,6 +284,9 @@ do_sys_ptrace(long request, long pid, lo
50                 goto out_notsk;
51         }
52  
53 +       if (gr_handle_ptrace(child, request))
54 +               goto out;
55 +
56         if (request == PTRACE_ATTACH) {
57                 ret = ptrace_attach(child);
58                 goto out;
59 diff -urNp linux-2.6.16.2/arch/alpha/mm/fault.c linux-2.6.16.2/arch/alpha/mm/fault.c
60 --- linux-2.6.16.2/arch/alpha/mm/fault.c        2006-04-07 12:56:47.000000000 -0400
61 +++ linux-2.6.16.2/arch/alpha/mm/fault.c        2006-04-09 21:23:54.000000000 -0400
62 @@ -25,6 +25,7 @@
63  #include <linux/smp_lock.h>
64  #include <linux/interrupt.h>
65  #include <linux/module.h>
66 +#include <linux/binfmts.h>
67  
68  #include <asm/system.h>
69  #include <asm/uaccess.h>
70 @@ -56,6 +57,124 @@ __load_new_mm_context(struct mm_struct *
71         __reload_thread(pcb);
72  }
73  
74 +#ifdef CONFIG_PAX_PAGEEXEC
75 +/*
76 + * PaX: decide what to do with offenders (regs->pc = fault address)
77 + *
78 + * returns 1 when task should be killed
79 + *         2 when patched PLT trampoline was detected
80 + *         3 when unpatched PLT trampoline was detected
81 + */
82 +static int pax_handle_fetch_fault(struct pt_regs *regs)
83 +{
84 +
85 +#ifdef CONFIG_PAX_EMUPLT
86 +       int err;
87 +
88 +       do { /* PaX: patched PLT emulation #1 */
89 +               unsigned int ldah, ldq, jmp;
90 +
91 +               err = get_user(ldah, (unsigned int *)regs->pc);
92 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
93 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
94 +
95 +               if (err)
96 +                       break;
97 +
98 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
99 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
100 +                   jmp == 0x6BFB0000U)
101 +               {
102 +                       unsigned long r27, addr;
103 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
104 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
105 +
106 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
107 +                       err = get_user(r27, (unsigned long*)addr);
108 +                       if (err)
109 +                               break;
110 +
111 +                       regs->r27 = r27;
112 +                       regs->pc = r27;
113 +                       return 2;
114 +               }
115 +       } while (0);
116 +
117 +       do { /* PaX: patched PLT emulation #2 */
118 +               unsigned int ldah, lda, br;
119 +
120 +               err = get_user(ldah, (unsigned int *)regs->pc);
121 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
122 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
123 +
124 +               if (err)
125 +                       break;
126 +
127 +               if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
128 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
129 +                   (br & 0xFFE00000U) == 0xC3E00000U)
130 +               {
131 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
132 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
133 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
134 +
135 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
136 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
137 +                       return 2;
138 +               }
139 +       } while (0);
140 +
141 +       do { /* PaX: unpatched PLT emulation */
142 +               unsigned int br;
143 +
144 +               err = get_user(br, (unsigned int *)regs->pc);
145 +
146 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
147 +                       unsigned int br2, ldq, nop, jmp;
148 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
149 +
150 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
151 +                       err = get_user(br2, (unsigned int *)addr);
152 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
153 +                       err |= get_user(nop, (unsigned int *)(addr+8));
154 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
155 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
156 +
157 +                       if (err)
158 +                               break;
159 +
160 +                       if (br2 == 0xC3600000U &&
161 +                           ldq == 0xA77B000CU &&
162 +                           nop == 0x47FF041FU &&
163 +                           jmp == 0x6B7B0000U)
164 +                       {
165 +                               regs->r28 = regs->pc+4;
166 +                               regs->r27 = addr+16;
167 +                               regs->pc = resolver;
168 +                               return 3;
169 +                       }
170 +               }
171 +       } while (0);
172 +#endif
173 +
174 +       return 1;
175 +}
176 +
177 +void pax_report_insns(void *pc, void *sp)
178 +{
179 +       unsigned long i;
180 +
181 +       printk(KERN_ERR "PAX: bytes at PC: ");
182 +       for (i = 0; i < 5; i++) {
183 +               unsigned int c;
184 +               if (get_user(c, (unsigned int*)pc+i))
185 +                       printk("???????? ");
186 +               else
187 +                       printk("%08x ", c);
188 +       }
189 +       printk("\n");
190 +}
191 +#endif
192  
193  /*
194   * This routine handles page faults.  It determines the address,
195 @@ -133,8 +252,29 @@ do_page_fault(unsigned long address, uns
196   good_area:
197         si_code = SEGV_ACCERR;
198         if (cause < 0) {
199 -               if (!(vma->vm_flags & VM_EXEC))
200 +               if (!(vma->vm_flags & VM_EXEC)) {
201 +
202 +#ifdef CONFIG_PAX_PAGEEXEC
203 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
204 +                               goto bad_area;
205 +
206 +                       up_read(&mm->mmap_sem);
207 +                       switch(pax_handle_fetch_fault(regs)) {
208 +
209 +#ifdef CONFIG_PAX_EMUPLT
210 +                       case 2:
211 +                       case 3:
212 +                               return;
213 +#endif
214 +
215 +                       }
216 +                       pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
217 +                       do_exit(SIGKILL);
218 +#else
219                         goto bad_area;
220 +#endif
221 +
222 +               }
223         } else if (!cause) {
224                 /* Allow reads even for write-only mappings */
225                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
226 diff -urNp linux-2.6.16.2/arch/arm/mm/mmap.c linux-2.6.16.2/arch/arm/mm/mmap.c
227 --- linux-2.6.16.2/arch/arm/mm/mmap.c   2006-04-07 12:56:47.000000000 -0400
228 +++ linux-2.6.16.2/arch/arm/mm/mmap.c   2006-04-09 21:23:54.000000000 -0400
229 @@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
230         if (len > TASK_SIZE)
231                 return -ENOMEM;
232  
233 +#ifdef CONFIG_PAX_RANDMMAP
234 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
235 +#endif
236 +
237         if (addr) {
238                 if (do_align)
239                         addr = COLOUR_ALIGN(addr, pgoff);
240 @@ -76,7 +80,7 @@ arch_get_unmapped_area(struct file *filp
241         if (len > mm->cached_hole_size) {
242                 start_addr = addr = mm->free_area_cache;
243         } else {
244 -               start_addr = addr = TASK_UNMAPPED_BASE;
245 +               start_addr = addr = mm->mmap_base;
246                 mm->cached_hole_size = 0;
247         }
248  
249 @@ -93,8 +97,8 @@ full_search:
250                          * Start a new search - just in case we missed
251                          * some holes.
252                          */
253 -                       if (start_addr != TASK_UNMAPPED_BASE) {
254 -                               start_addr = addr = TASK_UNMAPPED_BASE;
255 +                       if (start_addr != mm->mmap_base) {
256 +                               start_addr = addr = mm->mmap_base;
257                                 mm->cached_hole_size = 0;
258                                 goto full_search;
259                         }
260 diff -urNp linux-2.6.16.2/arch/i386/boot/compressed/head.S linux-2.6.16.2/arch/i386/boot/compressed/head.S
261 --- linux-2.6.16.2/arch/i386/boot/compressed/head.S     2006-04-07 12:56:47.000000000 -0400
262 +++ linux-2.6.16.2/arch/i386/boot/compressed/head.S     2006-04-09 21:23:54.000000000 -0400
263 @@ -39,11 +39,13 @@ startup_32:
264         movl %eax,%gs
265  
266         lss stack_start,%esp
267 +       movl 0x000000,%ecx
268         xorl %eax,%eax
269  1:     incl %eax               # check that A20 really IS enabled
270         movl %eax,0x000000      # loop forever if it isn't
271         cmpl %eax,0x100000
272         je 1b
273 +       movl %ecx,0x000000
274  
275  /*
276   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
277 diff -urNp linux-2.6.16.2/arch/i386/Kconfig linux-2.6.16.2/arch/i386/Kconfig
278 --- linux-2.6.16.2/arch/i386/Kconfig    2006-04-07 12:56:47.000000000 -0400
279 +++ linux-2.6.16.2/arch/i386/Kconfig    2006-04-09 21:23:54.000000000 -0400
280 @@ -963,7 +963,7 @@ endchoice
281  
282  config PCI_BIOS
283         bool
284 -       depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
285 +       depends on !X86_VISWS && PCI && PCI_GOBIOS
286         default y
287  
288  config PCI_DIRECT
289 diff -urNp linux-2.6.16.2/arch/i386/Kconfig.cpu linux-2.6.16.2/arch/i386/Kconfig.cpu
290 --- linux-2.6.16.2/arch/i386/Kconfig.cpu        2006-04-07 12:56:47.000000000 -0400
291 +++ linux-2.6.16.2/arch/i386/Kconfig.cpu        2006-04-09 21:23:54.000000000 -0400
292 @@ -251,7 +251,7 @@ config X86_PPRO_FENCE
293  
294  config X86_F00F_BUG
295         bool
296 -       depends on M586MMX || M586TSC || M586 || M486 || M386
297 +       depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
298         default y
299  
300  config X86_WP_WORKS_OK
301 @@ -281,7 +281,7 @@ config X86_CMPXCHG64
302  
303  config X86_ALIGNMENT_16
304         bool
305 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
306 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
307         default y
308  
309  config X86_GOOD_APIC
310 diff -urNp linux-2.6.16.2/arch/i386/Kconfig.debug linux-2.6.16.2/arch/i386/Kconfig.debug
311 --- linux-2.6.16.2/arch/i386/Kconfig.debug      2006-04-07 12:56:47.000000000 -0400
312 +++ linux-2.6.16.2/arch/i386/Kconfig.debug      2006-04-09 21:24:03.000000000 -0400
313 @@ -44,7 +44,7 @@ config DEBUG_PAGEALLOC
314  
315  config DEBUG_RODATA
316         bool "Write protect kernel read-only data structures"
317 -       depends on DEBUG_KERNEL
318 +       depends on DEBUG_KERNEL && 0
319         help
320           Mark the kernel read-only data as write-protected in the pagetables,
321           in order to catch accidental (and incorrect) writes to such const
322 diff -urNp linux-2.6.16.2/arch/i386/kernel/acpi/sleep.c linux-2.6.16.2/arch/i386/kernel/acpi/sleep.c
323 --- linux-2.6.16.2/arch/i386/kernel/acpi/sleep.c        2006-04-07 12:56:47.000000000 -0400
324 +++ linux-2.6.16.2/arch/i386/kernel/acpi/sleep.c        2006-04-09 21:23:54.000000000 -0400
325 @@ -10,6 +10,7 @@
326  #include <linux/dmi.h>
327  #include <asm/smp.h>
328  #include <asm/tlbflush.h>
329 +#include <asm/desc.h>
330  
331  /* address in low memory of the wakeup routine. */
332  unsigned long acpi_wakeup_address = 0;
333 @@ -24,11 +25,22 @@ static void init_low_mapping(pgd_t * pgd
334  {
335         int pgd_ofs = 0;
336  
337 +#ifdef CONFIG_PAX_KERNEXEC
338 +       unsigned long cr0;
339 +
340 +       pax_open_kernel(cr0);
341 +#endif
342 +
343         while ((pgd_ofs < pgd_limit)
344                && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
345                 set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD));
346                 pgd_ofs++, pgd++;
347         }
348 +
349 +#ifdef CONFIG_PAX_KERNEXEC
350 +       pax_close_kernel(cr0);
351 +#endif
352 +
353         flush_tlb_all();
354  }
355  
356 @@ -55,7 +67,18 @@ int acpi_save_state_mem(void)
357   */
358  void acpi_restore_state_mem(void)
359  {
360 +#ifdef CONFIG_PAX_KERNEXEC
361 +       unsigned long cr0;
362 +
363 +       pax_open_kernel(cr0);
364 +#endif
365 +
366         zap_low_mappings();
367 +
368 +#ifdef CONFIG_PAX_KERNEXEC
369 +       pax_close_kernel(cr0);
370 +#endif
371 +
372  }
373  
374  /**
375 diff -urNp linux-2.6.16.2/arch/i386/kernel/apic.c linux-2.6.16.2/arch/i386/kernel/apic.c
376 --- linux-2.6.16.2/arch/i386/kernel/apic.c      2006-04-07 12:56:47.000000000 -0400
377 +++ linux-2.6.16.2/arch/i386/kernel/apic.c      2006-04-09 21:23:54.000000000 -0400
378 @@ -1150,7 +1150,7 @@ inline void smp_local_timer_interrupt(st
379  {
380         profile_tick(CPU_PROFILING, regs);
381  #ifdef CONFIG_SMP
382 -       update_process_times(user_mode_vm(regs));
383 +       update_process_times(user_mode(regs));
384  #endif
385  
386         /*
387 diff -urNp linux-2.6.16.2/arch/i386/kernel/apm.c linux-2.6.16.2/arch/i386/kernel/apm.c
388 --- linux-2.6.16.2/arch/i386/kernel/apm.c       2006-04-07 12:56:47.000000000 -0400
389 +++ linux-2.6.16.2/arch/i386/kernel/apm.c       2006-04-09 21:23:54.000000000 -0400
390 @@ -589,9 +589,18 @@ static u8 apm_bios_call(u32 func, u32 eb
391         struct desc_struct      save_desc_40;
392         struct desc_struct      *gdt;
393  
394 +#ifdef CONFIG_PAX_KERNEXEC
395 +       unsigned long           cr0;
396 +#endif
397 +
398         cpus = apm_save_cpus();
399         
400         cpu = get_cpu();
401 +
402 +#ifdef CONFIG_PAX_KERNEXEC
403 +       pax_open_kernel(cr0);
404 +#endif
405 +
406         gdt = get_cpu_gdt_table(cpu);
407         save_desc_40 = gdt[0x40 / 8];
408         gdt[0x40 / 8] = bad_bios_desc;
409 @@ -603,6 +612,11 @@ static u8 apm_bios_call(u32 func, u32 eb
410         APM_DO_RESTORE_SEGS;
411         local_irq_restore(flags);
412         gdt[0x40 / 8] = save_desc_40;
413 +
414 +#ifdef CONFIG_PAX_KERNEXEC
415 +       pax_close_kernel(cr0);
416 +#endif
417 +
418         put_cpu();
419         apm_restore_cpus(cpus);
420         
421 @@ -633,9 +647,18 @@ static u8 apm_bios_call_simple(u32 func,
422         struct desc_struct      save_desc_40;
423         struct desc_struct      *gdt;
424  
425 +#ifdef CONFIG_PAX_KERNEXEC
426 +       unsigned long           cr0;
427 +#endif
428 +
429         cpus = apm_save_cpus();
430         
431         cpu = get_cpu();
432 +
433 +#ifdef CONFIG_PAX_KERNEXEC
434 +       pax_open_kernel(cr0);
435 +#endif
436 +
437         gdt = get_cpu_gdt_table(cpu);
438         save_desc_40 = gdt[0x40 / 8];
439         gdt[0x40 / 8] = bad_bios_desc;
440 @@ -647,6 +670,11 @@ static u8 apm_bios_call_simple(u32 func,
441         APM_DO_RESTORE_SEGS;
442         local_irq_restore(flags);
443         gdt[0x40 / 8] = save_desc_40;
444 +
445 +#ifdef CONFIG_PAX_KERNEXEC
446 +       pax_close_kernel(cr0);
447 +#endif
448 +
449         put_cpu();
450         apm_restore_cpus(cpus);
451         return error;
452 diff -urNp linux-2.6.16.2/arch/i386/kernel/asm-offsets.c linux-2.6.16.2/arch/i386/kernel/asm-offsets.c
453 --- linux-2.6.16.2/arch/i386/kernel/asm-offsets.c       2006-04-07 12:56:47.000000000 -0400
454 +++ linux-2.6.16.2/arch/i386/kernel/asm-offsets.c       2006-04-09 21:23:54.000000000 -0400
455 @@ -68,5 +68,6 @@ void foo(void)
456                  sizeof(struct tss_struct));
457  
458         DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
459 +       DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
460         DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
461  }
462 diff -urNp linux-2.6.16.2/arch/i386/kernel/cpu/common.c linux-2.6.16.2/arch/i386/kernel/cpu/common.c
463 --- linux-2.6.16.2/arch/i386/kernel/cpu/common.c        2006-04-07 12:56:47.000000000 -0400
464 +++ linux-2.6.16.2/arch/i386/kernel/cpu/common.c        2006-04-09 21:23:54.000000000 -0400
465 @@ -4,7 +4,6 @@
466  #include <linux/smp.h>
467  #include <linux/module.h>
468  #include <linux/percpu.h>
469 -#include <linux/bootmem.h>
470  #include <asm/semaphore.h>
471  #include <asm/processor.h>
472  #include <asm/i387.h>
473 @@ -19,9 +18,6 @@
474  
475  #include "cpu.h"
476  
477 -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
478 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
479 -
480  DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
481  EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
482  
483 @@ -387,6 +383,10 @@ void __devinit identify_cpu(struct cpuin
484         if (this_cpu->c_init)
485                 this_cpu->c_init(c);
486  
487 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
488 +       clear_bit(X86_FEATURE_SEP, c->x86_capability);
489 +#endif
490 +
491         /* Disable the PN if appropriate */
492         squash_the_stupid_serial_number(c);
493  
494 @@ -573,11 +573,10 @@ void __init early_cpu_init(void)
495  void __devinit cpu_init(void)
496  {
497         int cpu = smp_processor_id();
498 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
499 +       struct tss_struct * t = init_tss + cpu;
500         struct thread_struct *thread = &current->thread;
501 -       struct desc_struct *gdt;
502 +       struct desc_struct *gdt = get_cpu_gdt_table(cpu);
503         __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
504 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
505  
506         if (cpu_test_and_set(cpu, cpu_initialized)) {
507                 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
508 @@ -595,29 +594,11 @@ void __devinit cpu_init(void)
509         }
510  
511         /*
512 -        * This is a horrible hack to allocate the GDT.  The problem
513 -        * is that cpu_init() is called really early for the boot CPU
514 -        * (and hence needs bootmem) but much later for the secondary
515 -        * CPUs, when bootmem will have gone away
516 -        */
517 -       if (NODE_DATA(0)->bdata->node_bootmem_map) {
518 -               gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
519 -               /* alloc_bootmem_pages panics on failure, so no check */
520 -               memset(gdt, 0, PAGE_SIZE);
521 -       } else {
522 -               gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
523 -               if (unlikely(!gdt)) {
524 -                       printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
525 -                       for (;;)
526 -                               local_irq_enable();
527 -               }
528 -       }
529 -
530 -       /*
531          * Initialize the per-CPU GDT with the boot GDT,
532          * and set up the GDT descriptor:
533          */
534 -       memcpy(gdt, cpu_gdt_table, GDT_SIZE);
535 +       if (cpu)
536 +               memcpy(gdt, cpu_gdt_table, GDT_SIZE);
537  
538         /* Set up GDT entry for 16bit stack */
539         *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
540 @@ -625,10 +606,10 @@ void __devinit cpu_init(void)
541                 ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
542                 (CPU_16BIT_STACK_SIZE - 1);
543  
544 -       cpu_gdt_descr->size = GDT_SIZE - 1;
545 -       cpu_gdt_descr->address = (unsigned long)gdt;
546 +       cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
547 +       cpu_gdt_descr[cpu].address = (unsigned long)gdt;
548  
549 -       load_gdt(cpu_gdt_descr);
550 +       load_gdt(&cpu_gdt_descr[cpu]);
551         load_idt(&idt_descr);
552  
553         /*
554 @@ -643,7 +624,7 @@ void __devinit cpu_init(void)
555         load_esp0(t, thread);
556         set_tss_desc(cpu,t);
557         load_TR_desc();
558 -       load_LDT(&init_mm.context);
559 +       _load_LDT(&init_mm.context);
560  
561  #ifdef CONFIG_DOUBLEFAULT
562         /* Set up doublefault TSS pointer in the GDT */
563 diff -urNp linux-2.6.16.2/arch/i386/kernel/doublefault.c linux-2.6.16.2/arch/i386/kernel/doublefault.c
564 --- linux-2.6.16.2/arch/i386/kernel/doublefault.c       2006-04-07 12:56:47.000000000 -0400
565 +++ linux-2.6.16.2/arch/i386/kernel/doublefault.c       2006-04-09 21:23:54.000000000 -0400
566 @@ -11,7 +11,7 @@
567  
568  #define DOUBLEFAULT_STACKSIZE (1024)
569  static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
570 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
571 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
572  
573  #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
574  
575 diff -urNp linux-2.6.16.2/arch/i386/kernel/efi.c linux-2.6.16.2/arch/i386/kernel/efi.c
576 --- linux-2.6.16.2/arch/i386/kernel/efi.c       2006-04-07 12:56:47.000000000 -0400
577 +++ linux-2.6.16.2/arch/i386/kernel/efi.c       2006-04-09 21:23:54.000000000 -0400
578 @@ -64,82 +64,58 @@ extern void * boot_ioremap(unsigned long
579  
580  static unsigned long efi_rt_eflags;
581  static DEFINE_SPINLOCK(efi_rt_lock);
582 -static pgd_t efi_bak_pg_dir_pointer[2];
583 +static pgd_t __initdata efi_bak_pg_dir_pointer[4];
584  
585 -static void efi_call_phys_prelog(void)
586 +static void __init efi_call_phys_prelog(void)
587  {
588 -       unsigned long cr4;
589 -       unsigned long temp;
590 -       struct Xgt_desc_struct *cpu_gdt_descr;
591 -
592         spin_lock(&efi_rt_lock);
593         local_irq_save(efi_rt_eflags);
594  
595 -       cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
596 +       efi_bak_pg_dir_pointer[0] = swapper_pg_dir[0];
597 +       swapper_pg_dir[0] = swapper_pg_dir[USER_PTRS_PER_PGD];
598  
599 -       /*
600 -        * If I don't have PSE, I should just duplicate two entries in page
601 -        * directory. If I have PSE, I just need to duplicate one entry in
602 -        * page directory.
603 -        */
604 -       cr4 = read_cr4();
605 -
606 -       if (cr4 & X86_CR4_PSE) {
607 -               efi_bak_pg_dir_pointer[0].pgd =
608 -                   swapper_pg_dir[pgd_index(0)].pgd;
609 -               swapper_pg_dir[0].pgd =
610 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
611 -       } else {
612 -               efi_bak_pg_dir_pointer[0].pgd =
613 -                   swapper_pg_dir[pgd_index(0)].pgd;
614 -               efi_bak_pg_dir_pointer[1].pgd =
615 -                   swapper_pg_dir[pgd_index(0x400000)].pgd;
616 -               swapper_pg_dir[pgd_index(0)].pgd =
617 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
618 -               temp = PAGE_OFFSET + 0x400000;
619 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
620 -                   swapper_pg_dir[pgd_index(temp)].pgd;
621 -       }
622 +#ifndef CONFIG_X86_PAE
623 +       efi_bak_pg_dir_pointer[1] = swapper_pg_dir[1];
624 +       swapper_pg_dir[1] = swapper_pg_dir[USER_PTRS_PER_PGD+1];
625 +       efi_bak_pg_dir_pointer[2] = swapper_pg_dir[2];
626 +       swapper_pg_dir[2] = swapper_pg_dir[USER_PTRS_PER_PGD+2];
627 +       efi_bak_pg_dir_pointer[3] = swapper_pg_dir[3];
628 +       swapper_pg_dir[3] = swapper_pg_dir[USER_PTRS_PER_PGD+3];
629 +#endif
630  
631         /*
632          * After the lock is released, the original page table is restored.
633          */
634 -       local_flush_tlb();
635 +       __flush_tlb_all();
636  
637 -       cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
638 -       load_gdt(cpu_gdt_descr);
639 +       cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
640 +       load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
641  }
642  
643 -static void efi_call_phys_epilog(void)
644 +static void __init efi_call_phys_epilog(void)
645  {
646 -       unsigned long cr4;
647 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
648 -
649 -       cpu_gdt_descr->address = __va(cpu_gdt_descr->address);
650 -       load_gdt(cpu_gdt_descr);
651 +       cpu_gdt_descr[0].address =
652 +               (unsigned long) __va(cpu_gdt_descr[0].address);
653 +       load_gdt(&cpu_gdt_descr[0]);
654  
655 -       cr4 = read_cr4();
656 +       swapper_pg_dir[0] = efi_bak_pg_dir_pointer[0];
657  
658 -       if (cr4 & X86_CR4_PSE) {
659 -               swapper_pg_dir[pgd_index(0)].pgd =
660 -                   efi_bak_pg_dir_pointer[0].pgd;
661 -       } else {
662 -               swapper_pg_dir[pgd_index(0)].pgd =
663 -                   efi_bak_pg_dir_pointer[0].pgd;
664 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
665 -                   efi_bak_pg_dir_pointer[1].pgd;
666 -       }
667 +#ifndef CONFIG_X86_PAE
668 +       swapper_pg_dir[1] = efi_bak_pg_dir_pointer[1];
669 +       swapper_pg_dir[2] = efi_bak_pg_dir_pointer[2];
670 +       swapper_pg_dir[3] = efi_bak_pg_dir_pointer[3];
671 +#endif
672  
673         /*
674          * After the lock is released, the original page table is restored.
675          */
676 -       local_flush_tlb();
677 +       __flush_tlb_all();
678  
679         local_irq_restore(efi_rt_eflags);
680         spin_unlock(&efi_rt_lock);
681  }
682  
683 -static efi_status_t
684 +static efi_status_t __init
685  phys_efi_set_virtual_address_map(unsigned long memory_map_size,
686                                  unsigned long descriptor_size,
687                                  u32 descriptor_version,
688 @@ -155,7 +131,7 @@ phys_efi_set_virtual_address_map(unsigne
689         return status;
690  }
691  
692 -static efi_status_t
693 +static efi_status_t __init
694  phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
695  {
696         efi_status_t status;
697 diff -urNp linux-2.6.16.2/arch/i386/kernel/efi_stub.S linux-2.6.16.2/arch/i386/kernel/efi_stub.S
698 --- linux-2.6.16.2/arch/i386/kernel/efi_stub.S  2006-04-07 12:56:47.000000000 -0400
699 +++ linux-2.6.16.2/arch/i386/kernel/efi_stub.S  2006-04-09 21:23:54.000000000 -0400
700 @@ -7,6 +7,7 @@
701  
702  #include <linux/config.h>
703  #include <linux/linkage.h>
704 +#include <linux/init.h>
705  #include <asm/page.h>
706  #include <asm/pgtable.h>
707  
708 @@ -22,7 +23,7 @@
709   * service functions will comply with gcc calling convention, too.
710   */
711  
712 -.text
713 +__INIT
714  ENTRY(efi_call_phys)
715         /*
716          * 0. The function can only be called in Linux kernel. So CS has been
717 @@ -38,9 +39,7 @@ ENTRY(efi_call_phys)
718          * The mapping of lower virtual memory has been created in prelog and
719          * epilog.
720          */
721 -       movl    $1f, %edx
722 -       subl    $__PAGE_OFFSET, %edx
723 -       jmp     *%edx
724 +       jmp     1f-__PAGE_OFFSET
725  1:
726  
727         /*
728 @@ -49,14 +48,8 @@ ENTRY(efi_call_phys)
729          * parameter 2, ..., param n. To make things easy, we save the return
730          * address of efi_call_phys in a global variable.
731          */
732 -       popl    %edx
733 -       movl    %edx, saved_return_addr
734 -       /* get the function pointer into ECX*/
735 -       popl    %ecx
736 -       movl    %ecx, efi_rt_function_ptr
737 -       movl    $2f, %edx
738 -       subl    $__PAGE_OFFSET, %edx
739 -       pushl   %edx
740 +       popl    (saved_return_addr)
741 +       popl    (efi_rt_function_ptr)
742  
743         /*
744          * 3. Clear PG bit in %CR0.
745 @@ -75,9 +68,8 @@ ENTRY(efi_call_phys)
746         /*
747          * 5. Call the physical function.
748          */
749 -       jmp     *%ecx
750 +       call    *(efi_rt_function_ptr-__PAGE_OFFSET)
751  
752 -2:
753         /*
754          * 6. After EFI runtime service returns, control will return to
755          * following instruction. We'd better readjust stack pointer first.
756 @@ -87,37 +79,29 @@ ENTRY(efi_call_phys)
757         /*
758          * 7. Restore PG bit
759          */
760 -       movl    %cr0, %edx
761 -       orl     $0x80000000, %edx
762 -       movl    %edx, %cr0
763 -       jmp     1f
764 -1:
765         /*
766          * 8. Now restore the virtual mode from flat mode by
767          * adding EIP with PAGE_OFFSET.
768          */
769 -       movl    $1f, %edx
770 -       jmp     *%edx
771 +       movl    %cr0, %edx
772 +       orl     $0x80000000, %edx
773 +       movl    %edx, %cr0
774 +       jmp     1f+__PAGE_OFFSET
775  1:
776  
777         /*
778          * 9. Balance the stack. And because EAX contain the return value,
779          * we'd better not clobber it.
780          */
781 -       leal    efi_rt_function_ptr, %edx
782 -       movl    (%edx), %ecx
783 -       pushl   %ecx
784 +       pushl   (efi_rt_function_ptr)
785  
786         /*
787 -        * 10. Push the saved return address onto the stack and return.
788 +        * 10. Return to the saved return address.
789          */
790 -       leal    saved_return_addr, %edx
791 -       movl    (%edx), %ecx
792 -       pushl   %ecx
793 -       ret
794 +       jmpl    *(saved_return_addr)
795  .previous
796  
797 -.data
798 +__INITDATA
799  saved_return_addr:
800         .long 0
801  efi_rt_function_ptr:
802 diff -urNp linux-2.6.16.2/arch/i386/kernel/entry.S linux-2.6.16.2/arch/i386/kernel/entry.S
803 --- linux-2.6.16.2/arch/i386/kernel/entry.S     2006-04-07 12:56:47.000000000 -0400
804 +++ linux-2.6.16.2/arch/i386/kernel/entry.S     2006-04-09 21:24:03.000000000 -0400
805 @@ -82,7 +82,7 @@ VM_MASK               = 0x00020000
806  #define resume_kernel          restore_nocheck
807  #endif
808  
809 -#define SAVE_ALL \
810 +#define __SAVE_ALL \
811         cld; \
812         pushl %es; \
813         pushl %ds; \
814 @@ -97,6 +97,18 @@ VM_MASK              = 0x00020000
815         movl %edx, %ds; \
816         movl %edx, %es;
817  
818 +#ifdef CONFIG_PAX_KERNEXEC
819 +#define SAVE_ALL \
820 +       __SAVE_ALL \
821 +       movl %cr0, %edx; \
822 +       movl %edx, %esi; \
823 +       orl $0x10000, %edx; \
824 +       xorl %edx, %esi; \
825 +       movl %edx, %cr0;
826 +#else
827 +#define SAVE_ALL __SAVE_ALL
828 +#endif
829 +
830  #define RESTORE_INT_REGS \
831         popl %ebx;      \
832         popl %ecx;      \
833 @@ -146,7 +158,19 @@ ret_from_intr:
834         movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
835         movb CS(%esp), %al
836         testl $(VM_MASK | 3), %eax
837 +
838 +#ifdef CONFIG_PAX_KERNEXEC
839 +       jnz resume_userspace
840 +
841 +       movl %cr0, %edx
842 +       xorl %esi, %edx
843 +       movl %edx, %cr0
844 +       jmp resume_kernel
845 +#else
846         jz resume_kernel
847 +#endif
848 +
849 +
850  ENTRY(resume_userspace)
851         cli                             # make sure we don't miss an interrupt
852                                         # setting need_resched or sigpending
853 @@ -213,6 +237,13 @@ sysenter_past_esp:
854         movl TI_flags(%ebp), %ecx
855         testw $_TIF_ALLWORK_MASK, %cx
856         jne syscall_exit_work
857 +
858 +#ifdef CONFIG_PAX_RANDKSTACK
859 +       pushl %eax
860 +       call pax_randomize_kstack
861 +       popl %eax
862 +#endif
863 +
864  /* if something modifies registers it must also disable sysexit */
865         movl EIP(%esp), %edx
866         movl OLDESP(%esp), %ecx
867 @@ -243,6 +274,10 @@ syscall_exit:
868         testw $_TIF_ALLWORK_MASK, %cx   # current->work
869         jne syscall_exit_work
870  
871 +#ifdef CONFIG_PAX_RANDKSTACK
872 +       call pax_randomize_kstack
873 +#endif
874 +
875  restore_all:
876         movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
877         # Warning: OLDSS(%esp) contains the wrong/random values if we
878 @@ -398,7 +433,7 @@ syscall_badsys:
879   * Build the entry stubs and pointer table with
880   * some assembler magic.
881   */
882 -.data
883 +.section .rodata,"a",@progbits
884  ENTRY(interrupt)
885  .text
886  
887 @@ -408,7 +443,7 @@ ENTRY(irq_entries_start)
888         ALIGN
889  1:     pushl $vector-256
890         jmp common_interrupt
891 -.data
892 +.section .rodata,"a",@progbits
893         .long 1b
894  .text
895  vector=vector+1
896 @@ -459,6 +494,15 @@ error_code:
897         movl %ecx, %ds
898         movl %ecx, %es
899         movl %esp,%eax                  # pt_regs pointer
900 +
901 +#ifdef CONFIG_PAX_KERNEXEC
902 +       movl %cr0, %ecx
903 +       movl %ecx, %esi
904 +       orl $0x10000, %ecx
905 +       xorl %ecx, %esi
906 +       movl %ecx, %cr0
907 +#endif
908 +
909         call *%edi
910         jmp ret_from_exception
911  
912 @@ -554,6 +598,13 @@ nmi_stack_correct:
913         xorl %edx,%edx          # zero error code
914         movl %esp,%eax          # pt_regs pointer
915         call do_nmi
916 +
917 +#ifdef CONFIG_PAX_KERNEXEC
918 +       movl %cr0, %edx
919 +       xorl %esi, %edx
920 +       movl %edx, %cr0
921 +#endif
922 +
923         jmp restore_all
924  
925  nmi_stack_fixup:
926 @@ -584,6 +635,13 @@ nmi_16bit_stack:
927         FIXUP_ESPFIX_STACK              # %eax == %esp
928         xorl %edx,%edx                  # zero error code
929         call do_nmi
930 +
931 +#ifdef CONFIG_PAX_KERNEXEC
932 +       movl %cr0, %edx
933 +       xorl %esi, %edx
934 +       movl %edx, %cr0
935 +#endif
936 +
937         RESTORE_REGS
938         lss 12+4(%esp), %esp            # back to 16bit stack
939  1:     iret
940 @@ -659,7 +717,6 @@ ENTRY(spurious_interrupt_bug)
941         pushl $do_spurious_interrupt_bug
942         jmp error_code
943  
944 -.section .rodata,"a"
945  #include "syscall_table.S"
946  
947  syscall_table_size=(.-sys_call_table)
948 diff -urNp linux-2.6.16.2/arch/i386/kernel/head.S linux-2.6.16.2/arch/i386/kernel/head.S
949 --- linux-2.6.16.2/arch/i386/kernel/head.S      2006-04-07 12:56:47.000000000 -0400
950 +++ linux-2.6.16.2/arch/i386/kernel/head.S      2006-04-09 21:23:54.000000000 -0400
951 @@ -48,6 +48,12 @@
952  
953  
954  /*
955 + * Real beginning of normal "text" segment
956 + */
957 +ENTRY(stext)
958 +ENTRY(_stext)
959 +
960 +/*
961   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
962   * %esi points to the real-mode code as a 32-bit pointer.
963   * CS and DS must be 4 GB flat segments, but we don't depend on
964 @@ -67,6 +73,19 @@ ENTRY(startup_32)
965         movl %eax,%fs
966         movl %eax,%gs
967  
968 +#ifdef CONFIG_PAX_KERNEXEC
969 +       movl $ __KERNEL_TEXT_OFFSET,%eax
970 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
971 +       rorl $16,%eax
972 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
973 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
974 +
975 +       movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
976 +       movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
977 +       rorl $16,%eax
978 +       movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
979 +#endif
980 +
981  /*
982   * Clear BSS first so that there are no surprises...
983   * No need to cld as DF is already clear from cld above...
984 @@ -114,24 +133,42 @@ ENTRY(startup_32)
985   * Warning: don't use %esi or the stack in this code.  However, %esp
986   * can be used as a GPR if you really need it...
987   */
988 -page_pde_offset = (__PAGE_OFFSET >> 20);
989 -
990 +#ifdef CONFIG_X86_PAE
991 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
992 +#else
993 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
994 +#endif
995         movl $(pg0 - __PAGE_OFFSET), %edi
996 +#ifdef CONFIG_X86_PAE
997 +       movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
998 +#else
999         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1000 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
1001 +#endif
1002 +       movl $0x063, %eax                       /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1003  10:
1004 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
1005 +       leal 0x063(%edi),%ecx                   /* Create PDE entry */
1006         movl %ecx,(%edx)                        /* Store identity PDE entry */
1007         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
1008 +#ifdef CONFIG_X86_PAE
1009 +       movl $0,4(%edx)
1010 +       movl $0,page_pde_offset+4(%edx)
1011 +       addl $8,%edx
1012 +       movl $512, %ecx
1013 +#else
1014         addl $4,%edx
1015         movl $1024, %ecx
1016 +#endif
1017  11:
1018         stosl
1019 +#ifdef CONFIG_X86_PAE
1020 +       movl $0,(%edi)
1021 +       addl $4,%edi
1022 +#endif
1023         addl $0x1000,%eax
1024         loop 11b
1025         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1026 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1027 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1028 +       /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1029 +       leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1030         cmpl %ebp,%eax
1031         jb 10b
1032         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1033 @@ -154,6 +191,11 @@ ENTRY(startup_32_smp)
1034         movl %eax,%fs
1035         movl %eax,%gs
1036  
1037 +       /* This is a secondary processor (AP) */
1038 +       xorl %ebx,%ebx
1039 +       incl %ebx
1040 +#endif /* CONFIG_SMP */
1041 +
1042  /*
1043   *     New page tables may be in 4Mbyte page mode and may
1044   *     be using the global pages. 
1045 @@ -169,26 +211,27 @@ ENTRY(startup_32_smp)
1046   *     not yet offset PAGE_OFFSET..
1047   */
1048  #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1049 +3:
1050         movl cr4_bits,%edx
1051         andl %edx,%edx
1052 -       jz 6f
1053 +       jz 5f
1054         movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
1055         orl %edx,%eax
1056         movl %eax,%cr4
1057  
1058 -       btl $5, %eax            # check if PAE is enabled
1059 -       jnc 6f
1060 +#ifdef CONFIG_X86_PAE
1061 +       movl %ebx,%edi
1062  
1063         /* Check if extended functions are implemented */
1064         movl $0x80000000, %eax
1065         cpuid
1066         cmpl $0x80000000, %eax
1067 -       jbe 6f
1068 +       jbe 4f
1069         mov $0x80000001, %eax
1070         cpuid
1071         /* Execute Disable bit supported? */
1072         btl $20, %edx
1073 -       jnc 6f
1074 +       jnc 4f
1075  
1076         /* Setup EFER (Extended Feature Enable Register) */
1077         movl $0xc0000080, %ecx
1078 @@ -197,14 +240,12 @@ ENTRY(startup_32_smp)
1079         btsl $11, %eax
1080         /* Make changes effective */
1081         wrmsr
1082 +       btsl $63,__supported_pte_mask-__PAGE_OFFSET
1083  
1084 -6:
1085 -       /* This is a secondary processor (AP) */
1086 -       xorl %ebx,%ebx
1087 -       incl %ebx
1088 -
1089 -3:
1090 -#endif /* CONFIG_SMP */
1091 +4:
1092 +       movl %edi,%ebx
1093 +#endif
1094 +5:
1095  
1096  /*
1097   * Enable paging
1098 @@ -229,9 +270,7 @@ ENTRY(startup_32_smp)
1099  
1100  #ifdef CONFIG_SMP
1101         andl %ebx,%ebx
1102 -       jz  1f                          /* Initial CPU cleans BSS */
1103 -       jmp checkCPUtype
1104 -1:
1105 +       jnz checkCPUtype        /* Initial CPU cleans BSS */
1106  #endif /* CONFIG_SMP */
1107  
1108  /*
1109 @@ -412,32 +451,50 @@ ignore_int:
1110  #endif
1111         iret
1112  
1113 -/*
1114 - * Real beginning of normal "text" segment
1115 - */
1116 -ENTRY(stext)
1117 -ENTRY(_stext)
1118 -
1119 -/*
1120 - * BSS section
1121 - */
1122 -.section ".bss.page_aligned","w"
1123 +.section .swapper_pg_dir,"a",@progbits
1124  ENTRY(swapper_pg_dir)
1125 +#ifdef CONFIG_X86_PAE
1126 +       .long swapper_pm_dir-__PAGE_OFFSET+1
1127 +       .long 0
1128 +       .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1129 +       .long 0
1130 +       .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1131 +       .long 0
1132 +       .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1133 +       .long 0
1134 +#else
1135         .fill 1024,4,0
1136 +#endif
1137 +
1138 +#ifdef CONFIG_X86_PAE
1139 +.section .swapper_pm_dir,"a",@progbits
1140 +ENTRY(swapper_pm_dir)
1141 +       .fill 512,8,0
1142 +       .fill 512,8,0
1143 +       .fill 512,8,0
1144 +       .fill 512,8,0
1145 +#endif
1146 +
1147 +.section .empty_zero_page,"a",@progbits
1148  ENTRY(empty_zero_page)
1149         .fill 4096,1,0
1150  
1151  /*
1152 - * This starts the data section.
1153 - */
1154 -.data
1155 + * The IDT has to be page-aligned to simplify the Pentium
1156 + * F0 0F bug workaround.. We have a special link segment
1157 + * for this.
1158 + */
1159 +.section .idt,"a",@progbits
1160 +ENTRY(idt_table)
1161 +       .fill 256,8,0
1162 +
1163 +.section .rodata,"a",@progbits
1164 +ready: .byte 0
1165  
1166  ENTRY(stack_start)
1167 -       .long init_thread_union+THREAD_SIZE
1168 +       .long init_thread_union+THREAD_SIZE-8
1169         .long __BOOT_DS
1170  
1171 -ready: .byte 0
1172 -
1173  int_msg:
1174         .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
1175  
1176 @@ -479,8 +536,8 @@ cpu_gdt_descr:
1177         .align L1_CACHE_BYTES
1178  ENTRY(boot_gdt_table)
1179         .fill GDT_ENTRY_BOOT_CS,8,0
1180 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
1181 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
1182 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
1183 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
1184  
1185  /*
1186   * The Global Descriptor Table contains 28 quadwords, per-CPU.
1187 @@ -500,10 +557,10 @@ ENTRY(cpu_gdt_table)
1188         .quad 0x0000000000000000        /* 0x53 reserved */
1189         .quad 0x0000000000000000        /* 0x5b reserved */
1190  
1191 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1192 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1193 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1194 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1195 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
1196 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
1197 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
1198 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
1199  
1200         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
1201         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
1202 @@ -513,24 +570,30 @@ ENTRY(cpu_gdt_table)
1203          * They code segments and data segments have fixed 64k limits,
1204          * the transfer segment sizes are set at run time.
1205          */
1206 -       .quad 0x00409a000000ffff        /* 0x90 32-bit code */
1207 -       .quad 0x00009a000000ffff        /* 0x98 16-bit code */
1208 -       .quad 0x000092000000ffff        /* 0xa0 16-bit data */
1209 -       .quad 0x0000920000000000        /* 0xa8 16-bit data */
1210 -       .quad 0x0000920000000000        /* 0xb0 16-bit data */
1211 +       .quad 0x00409b000000ffff        /* 0x90 32-bit code */
1212 +       .quad 0x00009b000000ffff        /* 0x98 16-bit code */
1213 +       .quad 0x000093000000ffff        /* 0xa0 16-bit data */
1214 +       .quad 0x0000930000000000        /* 0xa8 16-bit data */
1215 +       .quad 0x0000930000000000        /* 0xb0 16-bit data */
1216  
1217         /*
1218          * The APM segments have byte granularity and their bases
1219          * are set at run time.  All have 64k limits.
1220          */
1221 -       .quad 0x00409a000000ffff        /* 0xb8 APM CS    code */
1222 -       .quad 0x00009a000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1223 -       .quad 0x004092000000ffff        /* 0xc8 APM DS    data */
1224 +       .quad 0x00409b000000ffff        /* 0xb8 APM CS    code */
1225 +       .quad 0x00009b000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
1226 +       .quad 0x004093000000ffff        /* 0xc8 APM DS    data */
1227  
1228 -       .quad 0x0000920000000000        /* 0xd0 - ESPFIX 16-bit SS */
1229 +       .quad 0x0000930000000000        /* 0xd0 - ESPFIX 16-bit SS */
1230         .quad 0x0000000000000000        /* 0xd8 - unused */
1231         .quad 0x0000000000000000        /* 0xe0 - unused */
1232         .quad 0x0000000000000000        /* 0xe8 - unused */
1233         .quad 0x0000000000000000        /* 0xf0 - unused */
1234         .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
1235  
1236 +       /* Be sure this is zeroed to avoid false validations in Xen */
1237 +       .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
1238 +
1239 +#ifdef CONFIG_SMP
1240 +       .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
1241 +#endif
1242 diff -urNp linux-2.6.16.2/arch/i386/kernel/i386_ksyms.c linux-2.6.16.2/arch/i386/kernel/i386_ksyms.c
1243 --- linux-2.6.16.2/arch/i386/kernel/i386_ksyms.c        2006-04-07 12:56:47.000000000 -0400
1244 +++ linux-2.6.16.2/arch/i386/kernel/i386_ksyms.c        2006-04-09 21:23:54.000000000 -0400
1245 @@ -3,6 +3,8 @@
1246  #include <asm/checksum.h>
1247  #include <asm/desc.h>
1248  
1249 +EXPORT_SYMBOL_GPL(cpu_gdt_descr);
1250 +
1251  EXPORT_SYMBOL(__down_failed);
1252  EXPORT_SYMBOL(__down_failed_interruptible);
1253  EXPORT_SYMBOL(__down_failed_trylock);
1254 diff -urNp linux-2.6.16.2/arch/i386/kernel/init_task.c linux-2.6.16.2/arch/i386/kernel/init_task.c
1255 --- linux-2.6.16.2/arch/i386/kernel/init_task.c 2006-04-07 12:56:47.000000000 -0400
1256 +++ linux-2.6.16.2/arch/i386/kernel/init_task.c 2006-04-09 21:23:54.000000000 -0400
1257 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
1258   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
1259   * no more per-task TSS's.
1260   */ 
1261 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
1262 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
1263  
1264 diff -urNp linux-2.6.16.2/arch/i386/kernel/ioport.c linux-2.6.16.2/arch/i386/kernel/ioport.c
1265 --- linux-2.6.16.2/arch/i386/kernel/ioport.c    2006-04-07 12:56:47.000000000 -0400
1266 +++ linux-2.6.16.2/arch/i386/kernel/ioport.c    2006-04-09 21:23:54.000000000 -0400
1267 @@ -16,6 +16,7 @@
1268  #include <linux/stddef.h>
1269  #include <linux/slab.h>
1270  #include <linux/thread_info.h>
1271 +#include <linux/grsecurity.h>
1272  
1273  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
1274  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
1275 @@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
1276  
1277         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
1278                 return -EINVAL;
1279 +#ifdef CONFIG_GRKERNSEC_IO
1280 +       if (turn_on) {
1281 +               gr_handle_ioperm();
1282 +#else
1283         if (turn_on && !capable(CAP_SYS_RAWIO))
1284 +#endif
1285                 return -EPERM;
1286 -
1287 +#ifdef CONFIG_GRKERNSEC_IO
1288 +       }
1289 +#endif
1290         /*
1291          * If it's the first ioperm() call in this thread's lifetime, set the
1292          * IO bitmap up. ioperm() is much less timing critical than clone(),
1293 @@ -88,7 +96,7 @@ asmlinkage long sys_ioperm(unsigned long
1294          * because the ->io_bitmap_max value must match the bitmap
1295          * contents:
1296          */
1297 -       tss = &per_cpu(init_tss, get_cpu());
1298 +       tss = init_tss + get_cpu();
1299  
1300         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
1301  
1302 @@ -142,8 +150,13 @@ asmlinkage long sys_iopl(unsigned long u
1303                 return -EINVAL;
1304         /* Trying to gain more privileges? */
1305         if (level > old) {
1306 +#ifdef CONFIG_GRKERNSEC_IO
1307 +               gr_handle_iopl();
1308 +               return -EPERM;
1309 +#else
1310                 if (!capable(CAP_SYS_RAWIO))
1311                         return -EPERM;
1312 +#endif
1313         }
1314         t->iopl = level << 12;
1315         regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
1316 diff -urNp linux-2.6.16.2/arch/i386/kernel/irq.c linux-2.6.16.2/arch/i386/kernel/irq.c
1317 --- linux-2.6.16.2/arch/i386/kernel/irq.c       2006-04-07 12:56:47.000000000 -0400
1318 +++ linux-2.6.16.2/arch/i386/kernel/irq.c       2006-04-09 21:23:54.000000000 -0400
1319 @@ -91,7 +91,7 @@ fastcall unsigned int do_IRQ(struct pt_r
1320                 int arg1, arg2, ebx;
1321  
1322                 /* build the stack frame on the IRQ stack */
1323 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1324 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1325                 irqctx->tinfo.task = curctx->tinfo.task;
1326                 irqctx->tinfo.previous_esp = current_stack_pointer;
1327  
1328 @@ -119,10 +119,10 @@ fastcall unsigned int do_IRQ(struct pt_r
1329   * gcc's 3.0 and earlier don't handle that correctly.
1330   */
1331  static char softirq_stack[NR_CPUS * THREAD_SIZE]
1332 -               __attribute__((__aligned__(THREAD_SIZE)));
1333 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1334  
1335  static char hardirq_stack[NR_CPUS * THREAD_SIZE]
1336 -               __attribute__((__aligned__(THREAD_SIZE)));
1337 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1338  
1339  /*
1340   * allocate per-cpu stacks for hardirq and for softirq processing
1341 @@ -182,7 +182,7 @@ asmlinkage void do_softirq(void)
1342                 irqctx->tinfo.previous_esp = current_stack_pointer;
1343  
1344                 /* build the stack frame on the softirq stack */
1345 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1346 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1347  
1348                 asm volatile(
1349                         "       xchgl   %%ebx,%%esp     \n"
1350 diff -urNp linux-2.6.16.2/arch/i386/kernel/ldt.c linux-2.6.16.2/arch/i386/kernel/ldt.c
1351 --- linux-2.6.16.2/arch/i386/kernel/ldt.c       2006-04-07 12:56:47.000000000 -0400
1352 +++ linux-2.6.16.2/arch/i386/kernel/ldt.c       2006-04-09 21:23:54.000000000 -0400
1353 @@ -103,6 +103,19 @@ int init_new_context(struct task_struct 
1354                 retval = copy_ldt(&mm->context, &old_mm->context);
1355                 up(&old_mm->context.sem);
1356         }
1357 +
1358 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1359 +       if (!mm->context.user_cs_limit) {
1360 +               mm->context.user_cs_base = 0UL;
1361 +               mm->context.user_cs_limit = ~0UL;
1362 +
1363 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
1364 +               cpus_clear(mm->context.cpu_user_cs_mask);
1365 +#endif
1366 +
1367 +       }
1368 +#endif
1369 +
1370         return retval;
1371  }
1372  
1373 @@ -160,7 +173,7 @@ static int read_default_ldt(void __user 
1374  {
1375         int err;
1376         unsigned long size;
1377 -       void *address;
1378 +       const void *address;
1379  
1380         err = 0;
1381         address = &default_ldt[0];
1382 @@ -215,6 +228,13 @@ static int write_ldt(void __user * ptr, 
1383                 }
1384         }
1385  
1386 +#ifdef CONFIG_PAX_SEGMEXEC
1387 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
1388 +               error = -EINVAL;
1389 +               goto out_unlock;
1390 +       }
1391 +#endif
1392 +
1393         entry_1 = LDT_entry_a(&ldt_info);
1394         entry_2 = LDT_entry_b(&ldt_info);
1395         if (oldmode)
1396 diff -urNp linux-2.6.16.2/arch/i386/kernel/module.c linux-2.6.16.2/arch/i386/kernel/module.c
1397 --- linux-2.6.16.2/arch/i386/kernel/module.c    2006-04-07 12:56:47.000000000 -0400
1398 +++ linux-2.6.16.2/arch/i386/kernel/module.c    2006-04-09 21:23:54.000000000 -0400
1399 @@ -21,6 +21,7 @@
1400  #include <linux/fs.h>
1401  #include <linux/string.h>
1402  #include <linux/kernel.h>
1403 +#include <asm/desc.h>
1404  
1405  #if 0
1406  #define DEBUGP printk
1407 @@ -32,9 +33,30 @@ void *module_alloc(unsigned long size)
1408  {
1409         if (size == 0)
1410                 return NULL;
1411 +
1412 +#ifdef CONFIG_PAX_KERNEXEC
1413 +       return vmalloc(size);
1414 +#else
1415         return vmalloc_exec(size);
1416 +#endif
1417 +
1418  }
1419  
1420 +#ifdef CONFIG_PAX_KERNEXEC
1421 +void *module_alloc_exec(unsigned long size)
1422 +{
1423 +       struct vm_struct *area;
1424 +
1425 +       if (size == 0)
1426 +               return NULL;
1427 +
1428 +       area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
1429 +       if (area)
1430 +               return area->addr;
1431 +
1432 +       return NULL;
1433 +}
1434 +#endif
1435  
1436  /* Free memory returned from module_alloc */
1437  void module_free(struct module *mod, void *module_region)
1438 @@ -44,6 +66,45 @@ void module_free(struct module *mod, voi
1439             table entries. */
1440  }
1441  
1442 +#ifdef CONFIG_PAX_KERNEXEC
1443 +void module_free_exec(struct module *mod, void *module_region)
1444 +{
1445 +       struct vm_struct **p, *tmp;
1446 +
1447 +       if (!module_region)
1448 +               return;
1449 +
1450 +       if ((PAGE_SIZE-1) & (unsigned long)module_region) {
1451 +               printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
1452 +               WARN_ON(1);
1453 +               return;
1454 +       }
1455 +
1456 +       write_lock(&vmlist_lock);
1457 +       for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
1458 +                if (tmp->addr == module_region)
1459 +                       break;
1460 +
1461 +       if (tmp) {
1462 +               unsigned long cr0;
1463 +
1464 +               pax_open_kernel(cr0);
1465 +               memset(tmp->addr, 0xCC, tmp->size);
1466 +               pax_close_kernel(cr0);
1467 +
1468 +               *p = tmp->next;
1469 +               kfree(tmp);
1470 +       }
1471 +       write_unlock(&vmlist_lock);
1472 +
1473 +       if (!tmp) {
1474 +               printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
1475 +                               module_region);
1476 +               WARN_ON(1);
1477 +       }
1478 +}
1479 +#endif
1480 +
1481  /* We don't need anything special. */
1482  int module_frob_arch_sections(Elf_Ehdr *hdr,
1483                               Elf_Shdr *sechdrs,
1484 @@ -62,14 +123,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1485         unsigned int i;
1486         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
1487         Elf32_Sym *sym;
1488 -       uint32_t *location;
1489 +       uint32_t *plocation, location;
1490  
1491         DEBUGP("Applying relocate section %u to %u\n", relsec,
1492                sechdrs[relsec].sh_info);
1493         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
1494                 /* This is where to make the change */
1495 -               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
1496 -                       + rel[i].r_offset;
1497 +               plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
1498 +               location = (uint32_t)plocation;
1499 +               if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
1500 +                       plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
1501                 /* This is the symbol it is referring to.  Note that all
1502                    undefined symbols have been resolved.  */
1503                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
1504 @@ -78,11 +141,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1505                 switch (ELF32_R_TYPE(rel[i].r_info)) {
1506                 case R_386_32:
1507                         /* We add the value into the location given */
1508 -                       *location += sym->st_value;
1509 +                       *plocation += sym->st_value;
1510                         break;
1511                 case R_386_PC32:
1512                         /* Add the value, subtract its postition */
1513 -                       *location += sym->st_value - (uint32_t)location;
1514 +                       *plocation += sym->st_value - location;
1515                         break;
1516                 default:
1517                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
1518 diff -urNp linux-2.6.16.2/arch/i386/kernel/process.c linux-2.6.16.2/arch/i386/kernel/process.c
1519 --- linux-2.6.16.2/arch/i386/kernel/process.c   2006-04-07 12:56:47.000000000 -0400
1520 +++ linux-2.6.16.2/arch/i386/kernel/process.c   2006-04-09 21:23:54.000000000 -0400
1521 @@ -374,7 +374,7 @@ void exit_thread(void)
1522         /* The process may have allocated an io port bitmap... nuke it. */
1523         if (unlikely(NULL != t->io_bitmap_ptr)) {
1524                 int cpu = get_cpu();
1525 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
1526 +               struct tss_struct *tss = init_tss + cpu;
1527  
1528                 kfree(t->io_bitmap_ptr);
1529                 t->io_bitmap_ptr = NULL;
1530 @@ -394,6 +394,9 @@ void flush_thread(void)
1531  {
1532         struct task_struct *tsk = current;
1533  
1534 +       __asm__("mov %0,%%fs\n"
1535 +               "mov %0,%%gs\n"
1536 +               : : "r" (0) : "memory");
1537         memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
1538         memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
1539         /*
1540 @@ -426,7 +429,7 @@ int copy_thread(int nr, unsigned long cl
1541         struct task_struct *tsk;
1542         int err;
1543  
1544 -       childregs = task_pt_regs(p);
1545 +       childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
1546         *childregs = *regs;
1547         childregs->eax = 0;
1548         childregs->esp = esp;
1549 @@ -469,6 +472,11 @@ int copy_thread(int nr, unsigned long cl
1550                 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1551                         goto out;
1552  
1553 +#ifdef CONFIG_PAX_SEGMEXEC
1554 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1555 +                       goto out;
1556 +#endif
1557 +
1558                 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
1559                 desc->a = LDT_entry_a(&info);
1560                 desc->b = LDT_entry_b(&info);
1561 @@ -633,7 +641,11 @@ struct task_struct fastcall * __switch_t
1562         struct thread_struct *prev = &prev_p->thread,
1563                                  *next = &next_p->thread;
1564         int cpu = smp_processor_id();
1565 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1566 +       struct tss_struct *tss = init_tss + cpu;
1567 +
1568 +#ifdef CONFIG_PAX_KERNEXEC
1569 +       unsigned long cr0;
1570 +#endif
1571  
1572         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
1573  
1574 @@ -656,11 +668,19 @@ struct task_struct fastcall * __switch_t
1575         savesegment(fs, prev->fs);
1576         savesegment(gs, prev->gs);
1577  
1578 +#ifdef CONFIG_PAX_KERNEXEC
1579 +       pax_open_kernel(cr0);
1580 +#endif
1581 +
1582         /*
1583          * Load the per-thread Thread-Local Storage descriptor.
1584          */
1585         load_TLS(next, cpu);
1586  
1587 +#ifdef CONFIG_PAX_KERNEXEC
1588 +       pax_close_kernel(cr0);
1589 +#endif
1590 +
1591         /*
1592          * Restore %fs and %gs if needed.
1593          *
1594 @@ -815,8 +835,18 @@ asmlinkage int sys_set_thread_area(struc
1595         struct desc_struct *desc;
1596         int cpu, idx;
1597  
1598 +#ifdef CONFIG_PAX_KERNEXEC
1599 +       unsigned long cr0;
1600 +#endif
1601 +
1602         if (copy_from_user(&info, u_info, sizeof(info)))
1603                 return -EFAULT;
1604 +
1605 +#ifdef CONFIG_PAX_SEGMEXEC
1606 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1607 +               return -EINVAL;
1608 +#endif
1609 +
1610         idx = info.entry_number;
1611  
1612         /*
1613 @@ -848,8 +878,17 @@ asmlinkage int sys_set_thread_area(struc
1614                 desc->a = LDT_entry_a(&info);
1615                 desc->b = LDT_entry_b(&info);
1616         }
1617 +
1618 +#ifdef CONFIG_PAX_KERNEXEC
1619 +       pax_open_kernel(cr0);
1620 +#endif
1621 +
1622         load_TLS(t, cpu);
1623  
1624 +#ifdef CONFIG_PAX_KERNEXEC
1625 +       pax_close_kernel(cr0);
1626 +#endif
1627 +
1628         put_cpu();
1629  
1630         return 0;
1631 @@ -905,9 +944,27 @@ asmlinkage int sys_get_thread_area(struc
1632         return 0;
1633  }
1634  
1635 -unsigned long arch_align_stack(unsigned long sp)
1636 +#ifdef CONFIG_PAX_RANDKSTACK
1637 +asmlinkage void pax_randomize_kstack(void)
1638  {
1639 -       if (randomize_va_space)
1640 -               sp -= get_random_int() % 8192;
1641 -       return sp & ~0xf;
1642 +       struct tss_struct *tss = init_tss + smp_processor_id();
1643 +       unsigned long time;
1644 +
1645 +       if (!randomize_va_space)
1646 +               return;
1647 +
1648 +       rdtscl(time);
1649 +
1650 +       /* P4 seems to return a 0 LSB, ignore it */
1651 +#ifdef CONFIG_MPENTIUM4
1652 +       time &= 0x1EUL;
1653 +       time <<= 2;
1654 +#else
1655 +       time &= 0xFUL;
1656 +       time <<= 3;
1657 +#endif
1658 +
1659 +       tss->esp0 ^= time;
1660 +       current->thread.esp0 = tss->esp0;
1661  }
1662 +#endif
1663 diff -urNp linux-2.6.16.2/arch/i386/kernel/ptrace.c linux-2.6.16.2/arch/i386/kernel/ptrace.c
1664 --- linux-2.6.16.2/arch/i386/kernel/ptrace.c    2006-04-07 12:56:47.000000000 -0400
1665 +++ linux-2.6.16.2/arch/i386/kernel/ptrace.c    2006-04-09 21:23:54.000000000 -0400
1666 @@ -17,6 +17,7 @@
1667  #include <linux/audit.h>
1668  #include <linux/seccomp.h>
1669  #include <linux/signal.h>
1670 +#include <linux/grsecurity.h>
1671  
1672  #include <asm/uaccess.h>
1673  #include <asm/pgtable.h>
1674 @@ -342,6 +343,11 @@ ptrace_set_thread_area(struct task_struc
1675         if (copy_from_user(&info, user_desc, sizeof(info)))
1676                 return -EFAULT;
1677  
1678 +#ifdef CONFIG_PAX_SEGMEXEC
1679 +       if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1680 +               return -EINVAL;
1681 +#endif
1682 +
1683         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1684                 return -EINVAL;
1685  
1686 @@ -432,6 +438,17 @@ long arch_ptrace(struct task_struct *chi
1687                           if(addr == (long) &dummy->u_debugreg[5]) break;
1688                           if(addr < (long) &dummy->u_debugreg[4] &&
1689                              ((unsigned long) data) >= TASK_SIZE-3) break;
1690 +
1691 +#ifdef CONFIG_GRKERNSEC
1692 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
1693 +                            addr <= (long) &dummy->u_debugreg[3]){
1694 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
1695 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
1696 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
1697 +                               if((type & 1) && (data & align))
1698 +                                       break;
1699 +                         }
1700 +#endif
1701                           
1702                           /* Sanity-check data. Take one half-byte at once with
1703                            * check = (val >> (16 + 4*i)) & 0xf. It contains the
1704 @@ -645,7 +662,7 @@ void send_sigtrap(struct task_struct *ts
1705         info.si_code = TRAP_BRKPT;
1706  
1707         /* User-mode eip? */
1708 -       info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
1709 +       info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
1710  
1711         /* Send us the fakey SIGTRAP */
1712         force_sig_info(SIGTRAP, &info, tsk);
1713 diff -urNp linux-2.6.16.2/arch/i386/kernel/reboot.c linux-2.6.16.2/arch/i386/kernel/reboot.c
1714 --- linux-2.6.16.2/arch/i386/kernel/reboot.c    2006-04-07 12:56:47.000000000 -0400
1715 +++ linux-2.6.16.2/arch/i386/kernel/reboot.c    2006-04-09 21:23:54.000000000 -0400
1716 @@ -138,18 +138,18 @@ core_initcall(reboot_init);
1717     doesn't work with at least one type of 486 motherboard.  It is easy
1718     to stop this code working; hence the copious comments. */
1719  
1720 -static unsigned long long
1721 +static const unsigned long long
1722  real_mode_gdt_entries [3] =
1723  {
1724         0x0000000000000000ULL,  /* Null descriptor */
1725 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
1726 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
1727 +       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
1728 +       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
1729  };
1730  
1731  static struct
1732  {
1733         unsigned short       size __attribute__ ((packed));
1734 -       unsigned long long * base __attribute__ ((packed));
1735 +       const unsigned long long * base __attribute__ ((packed));
1736  }
1737  real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
1738  real_mode_idt = { 0x3ff, NULL },
1739 @@ -203,6 +203,10 @@ void machine_real_restart(unsigned char 
1740  {
1741         unsigned long flags;
1742  
1743 +#ifdef CONFIG_PAX_KERNEXEC
1744 +       unsigned long cr0;
1745 +#endif
1746 +
1747         local_irq_disable();
1748  
1749         /* Write zero to CMOS register number 0x0f, which the BIOS POST
1750 @@ -223,9 +227,17 @@ void machine_real_restart(unsigned char 
1751            from the kernel segment.  This assumes the kernel segment starts at
1752            virtual address PAGE_OFFSET. */
1753  
1754 +#ifdef CONFIG_PAX_KERNEXEC
1755 +       pax_open_kernel(cr0);
1756 +#endif
1757 +
1758         memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
1759                 sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
1760  
1761 +#ifdef CONFIG_PAX_KERNEXEC
1762 +       pax_close_kernel(cr0);
1763 +#endif
1764 +
1765         /*
1766          * Use `swapper_pg_dir' as our page directory.
1767          */
1768 diff -urNp linux-2.6.16.2/arch/i386/kernel/setup.c linux-2.6.16.2/arch/i386/kernel/setup.c
1769 --- linux-2.6.16.2/arch/i386/kernel/setup.c     2006-04-07 12:56:47.000000000 -0400
1770 +++ linux-2.6.16.2/arch/i386/kernel/setup.c     2006-04-09 21:23:54.000000000 -0400
1771 @@ -60,6 +60,7 @@
1772  #include <asm/io.h>
1773  #include "setup_arch_pre.h"
1774  #include <bios_ebda.h>
1775 +#include <asm/desc.h>
1776  
1777  /* Forward Declaration. */
1778  void __init find_max_pfn(void);
1779 @@ -86,7 +87,11 @@ struct cpuinfo_x86 new_cpu_data __initda
1780  struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
1781  EXPORT_SYMBOL(boot_cpu_data);
1782  
1783 +#ifdef CONFIG_X86_PAE
1784 +unsigned long mmu_cr4_features = X86_CR4_PAE;
1785 +#else
1786  unsigned long mmu_cr4_features;
1787 +#endif
1788  
1789  #ifdef CONFIG_ACPI
1790         int acpi_disabled = 0;
1791 @@ -1444,12 +1449,22 @@ void apply_alternatives(void *start, voi
1792         struct alt_instr *a; 
1793         int diff, i, k;
1794          unsigned char **noptable = intel_nops; 
1795 +
1796 +#ifdef CONFIG_PAX_KERNEXEC
1797 +       unsigned long cr0;
1798 +#endif
1799 +
1800         for (i = 0; noptypes[i].cpuid >= 0; i++) { 
1801                 if (boot_cpu_has(noptypes[i].cpuid)) { 
1802                         noptable = noptypes[i].noptable;
1803                         break;
1804                 }
1805         } 
1806 +
1807 +#ifdef CONFIG_PAX_KERNEXEC
1808 +       pax_open_kernel(cr0);
1809 +#endif
1810 +
1811         for (a = start; (void *)a < end; a++) { 
1812                 if (!boot_cpu_has(a->cpuid))
1813                         continue;
1814 @@ -1464,6 +1479,11 @@ void apply_alternatives(void *start, voi
1815                         memcpy(a->instr + i, noptable[k], k); 
1816                 } 
1817         }
1818 +
1819 +#ifdef CONFIG_PAX_KERNEXEC
1820 +       pax_close_kernel(cr0);
1821 +#endif
1822 +
1823  } 
1824  
1825  void __init alternative_instructions(void)
1826 @@ -1542,14 +1562,14 @@ void __init setup_arch(char **cmdline_p)
1827  
1828         if (!MOUNT_ROOT_RDONLY)
1829                 root_mountflags &= ~MS_RDONLY;
1830 -       init_mm.start_code = (unsigned long) _text;
1831 -       init_mm.end_code = (unsigned long) _etext;
1832 +       init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
1833 +       init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
1834         init_mm.end_data = (unsigned long) _edata;
1835         init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
1836  
1837 -       code_resource.start = virt_to_phys(_text);
1838 -       code_resource.end = virt_to_phys(_etext)-1;
1839 -       data_resource.start = virt_to_phys(_etext);
1840 +       code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
1841 +       code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
1842 +       data_resource.start = virt_to_phys(_data);
1843         data_resource.end = virt_to_phys(_edata)-1;
1844  
1845         parse_cmdline_early(cmdline_p);
1846 diff -urNp linux-2.6.16.2/arch/i386/kernel/signal.c linux-2.6.16.2/arch/i386/kernel/signal.c
1847 --- linux-2.6.16.2/arch/i386/kernel/signal.c    2006-04-07 12:56:47.000000000 -0400
1848 +++ linux-2.6.16.2/arch/i386/kernel/signal.c    2006-04-09 21:23:54.000000000 -0400
1849 @@ -350,7 +350,17 @@ static int setup_frame(int sig, struct k
1850                         goto give_sigsegv;
1851         }
1852  
1853 +#ifdef CONFIG_PAX_NOVSYSCALL
1854 +       restorer = frame->retcode;
1855 +#else
1856         restorer = &__kernel_sigreturn;
1857 +
1858 +#ifdef CONFIG_PAX_SEGMEXEC
1859 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
1860 +               restorer -= SEGMEXEC_TASK_SIZE;
1861 +#endif
1862 +#endif
1863 +
1864         if (ka->sa.sa_flags & SA_RESTORER)
1865                 restorer = ka->sa.sa_restorer;
1866  
1867 @@ -446,7 +456,18 @@ static int setup_rt_frame(int sig, struc
1868                 goto give_sigsegv;
1869  
1870         /* Set up to return from userspace.  */
1871 +
1872 +#ifdef CONFIG_PAX_NOVSYSCALL
1873 +       restorer = frame->retcode;
1874 +#else
1875         restorer = &__kernel_rt_sigreturn;
1876 +
1877 +#ifdef CONFIG_PAX_SEGMEXEC
1878 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
1879 +               restorer -= SEGMEXEC_TASK_SIZE;
1880 +#endif
1881 +#endif
1882 +
1883         if (ka->sa.sa_flags & SA_RESTORER)
1884                 restorer = ka->sa.sa_restorer;
1885         err |= __put_user(restorer, &frame->pretcode);
1886 @@ -579,7 +600,7 @@ static void fastcall do_signal(struct pt
1887          * before reaching here, so testing against kernel
1888          * CS suffices.
1889          */
1890 -       if (!user_mode(regs))
1891 +       if (!user_mode_novm(regs))
1892                 return;
1893  
1894         if (try_to_freeze())
1895 diff -urNp linux-2.6.16.2/arch/i386/kernel/syscall_table.S linux-2.6.16.2/arch/i386/kernel/syscall_table.S
1896 --- linux-2.6.16.2/arch/i386/kernel/syscall_table.S     2006-04-07 12:56:47.000000000 -0400
1897 +++ linux-2.6.16.2/arch/i386/kernel/syscall_table.S     2006-04-09 21:23:54.000000000 -0400
1898 @@ -1,3 +1,4 @@
1899 +.section .rodata,"a",@progbits
1900  ENTRY(sys_call_table)
1901         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
1902         .long sys_exit
1903 diff -urNp linux-2.6.16.2/arch/i386/kernel/sysenter.c linux-2.6.16.2/arch/i386/kernel/sysenter.c
1904 --- linux-2.6.16.2/arch/i386/kernel/sysenter.c  2006-04-07 12:56:47.000000000 -0400
1905 +++ linux-2.6.16.2/arch/i386/kernel/sysenter.c  2006-04-09 21:23:54.000000000 -0400
1906 @@ -24,7 +24,7 @@ extern asmlinkage void sysenter_entry(vo
1907  void enable_sep_cpu(void)
1908  {
1909         int cpu = get_cpu();
1910 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
1911 +       struct tss_struct *tss = init_tss + cpu;
1912  
1913         if (!boot_cpu_has(X86_FEATURE_SEP)) {
1914                 put_cpu();
1915 @@ -48,6 +48,7 @@ extern const char vsyscall_sysenter_star
1916  
1917  int __init sysenter_setup(void)
1918  {
1919 +#ifndef CONFIG_PAX_NOVSYSCALL
1920         void *page = (void *)get_zeroed_page(GFP_ATOMIC);
1921  
1922         __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
1923 @@ -62,6 +63,7 @@ int __init sysenter_setup(void)
1924         memcpy(page,
1925                &vsyscall_sysenter_start,
1926                &vsyscall_sysenter_end - &vsyscall_sysenter_start);
1927 +#endif
1928  
1929         return 0;
1930  }
1931 diff -urNp linux-2.6.16.2/arch/i386/kernel/sys_i386.c linux-2.6.16.2/arch/i386/kernel/sys_i386.c
1932 --- linux-2.6.16.2/arch/i386/kernel/sys_i386.c  2006-04-07 12:56:47.000000000 -0400
1933 +++ linux-2.6.16.2/arch/i386/kernel/sys_i386.c  2006-04-09 21:23:54.000000000 -0400
1934 @@ -106,6 +106,191 @@ out:
1935         return err;
1936  }
1937  
1938 +unsigned long
1939 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
1940 +               unsigned long len, unsigned long pgoff, unsigned long flags)
1941 +{
1942 +       struct mm_struct *mm = current->mm;
1943 +       struct vm_area_struct *vma;
1944 +       unsigned long start_addr, task_size = TASK_SIZE;
1945 +
1946 +#ifdef CONFIG_PAX_SEGMEXEC
1947 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
1948 +               task_size = SEGMEXEC_TASK_SIZE;
1949 +#endif
1950 +
1951 +       if (len > task_size)
1952 +               return -ENOMEM;
1953 +
1954 +#ifdef CONFIG_PAX_RANDMMAP
1955 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
1956 +#endif
1957 +
1958 +       if (addr) {
1959 +               addr = PAGE_ALIGN(addr);
1960 +               vma = find_vma(mm, addr);
1961 +               if (task_size - len >= addr &&
1962 +                   (!vma || addr + len <= vma->vm_start))
1963 +                       return addr;
1964 +       }
1965 +       if (len > mm->cached_hole_size) {
1966 +               start_addr = addr = mm->free_area_cache;
1967 +       } else {
1968 +               start_addr = addr = mm->mmap_base;
1969 +               mm->cached_hole_size = 0;
1970 +       }
1971 +
1972 +#ifdef CONFIG_PAX_PAGEEXEC
1973 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
1974 +               start_addr = 0x00110000UL;
1975 +
1976 +#ifdef CONFIG_PAX_RANDMMAP
1977 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
1978 +                       start_addr += mm->delta_mmap & 0x03FFFFFFUL;
1979 +#endif
1980 +
1981 +               if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
1982 +                       start_addr = addr = mm->mmap_base;
1983 +               else
1984 +                       addr = start_addr;
1985 +       }
1986 +#endif
1987 +
1988 +full_search:
1989 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
1990 +               /* At this point:  (!vma || addr < vma->vm_end). */
1991 +               if (task_size - len < addr) {
1992 +                       /*
1993 +                        * Start a new search - just in case we missed
1994 +                        * some holes.
1995 +                        */
1996 +                       if (start_addr != mm->mmap_base) {
1997 +                               start_addr = addr = mm->mmap_base;
1998 +                               mm->cached_hole_size = 0;
1999 +                               goto full_search;
2000 +                       }
2001 +                       return -ENOMEM;
2002 +               }
2003 +               if (!vma || addr + len <= vma->vm_start) {
2004 +                       /*
2005 +                        * Remember the place where we stopped the search:
2006 +                        */
2007 +                       mm->free_area_cache = addr + len;
2008 +                       return addr;
2009 +               }
2010 +               if (addr + mm->cached_hole_size < vma->vm_start)
2011 +                       mm->cached_hole_size = vma->vm_start - addr;
2012 +               addr = vma->vm_end;
2013 +               if (mm->start_brk <= addr && addr < mm->mmap_base) {
2014 +                       start_addr = addr = mm->mmap_base;
2015 +                       goto full_search;
2016 +               }
2017 +       }
2018 +}
2019 +
2020 +unsigned long
2021 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
2022 +                         const unsigned long len, const unsigned long pgoff,
2023 +                         const unsigned long flags)
2024 +{
2025 +       struct vm_area_struct *vma;
2026 +       struct mm_struct *mm = current->mm;
2027 +       unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
2028 +
2029 +#ifdef CONFIG_PAX_SEGMEXEC
2030 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
2031 +               task_size = SEGMEXEC_TASK_SIZE;
2032 +#endif
2033 +
2034 +       /* requested length too big for entire address space */
2035 +       if (len > task_size)
2036 +               return -ENOMEM;
2037 +
2038 +#ifdef CONFIG_PAX_PAGEEXEC
2039 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
2040 +               goto bottomup;
2041 +#endif
2042 +
2043 +#ifdef CONFIG_PAX_RANDMMAP
2044 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2045 +#endif
2046 +
2047 +       /* requesting a specific address */
2048 +       if (addr) {
2049 +               addr = PAGE_ALIGN(addr);
2050 +               vma = find_vma(mm, addr);
2051 +               if (task_size - len >= addr &&
2052 +                               (!vma || addr + len <= vma->vm_start))
2053 +                       return addr;
2054 +       }
2055 +
2056 +       /* check if free_area_cache is useful for us */
2057 +       if (len <= mm->cached_hole_size) {
2058 +               mm->cached_hole_size = 0;
2059 +               mm->free_area_cache = mm->mmap_base;
2060 +       }
2061 +
2062 +       /* either no address requested or can't fit in requested address hole */
2063 +       addr = mm->free_area_cache;
2064 +
2065 +       /* make sure it can fit in the remaining address space */
2066 +       if (addr > len) {
2067 +               vma = find_vma(mm, addr-len);
2068 +               if (!vma || addr <= vma->vm_start)
2069 +                       /* remember the address as a hint for next time */
2070 +                       return (mm->free_area_cache = addr-len);
2071 +       }
2072 +
2073 +       if (mm->mmap_base < len)
2074 +               goto bottomup;
2075 +
2076 +       addr = mm->mmap_base-len;
2077 +
2078 +       do {
2079 +               /*
2080 +                * Lookup failure means no vma is above this address,
2081 +                * else if new region fits below vma->vm_start,
2082 +                * return with success:
2083 +                */
2084 +               vma = find_vma(mm, addr);
2085 +               if (!vma || addr+len <= vma->vm_start)
2086 +                       /* remember the address as a hint for next time */
2087 +                       return (mm->free_area_cache = addr);
2088 +
2089 +               /* remember the largest hole we saw so far */
2090 +               if (addr + mm->cached_hole_size < vma->vm_start)
2091 +                       mm->cached_hole_size = vma->vm_start - addr;
2092 +
2093 +               /* try just below the current vma->vm_start */
2094 +               addr = vma->vm_start-len;
2095 +       } while (len < vma->vm_start);
2096 +
2097 +bottomup:
2098 +       /*
2099 +        * A failed mmap() very likely causes application failure,
2100 +        * so fall back to the bottom-up function here. This scenario
2101 +        * can happen with large stack limits and large mmap()
2102 +        * allocations.
2103 +        */
2104 +       mm->mmap_base = TASK_UNMAPPED_BASE;
2105 +
2106 +#ifdef CONFIG_PAX_RANDMMAP
2107 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
2108 +               mm->mmap_base += mm->delta_mmap;
2109 +#endif
2110 +
2111 +       mm->free_area_cache = mm->mmap_base;
2112 +       mm->cached_hole_size = ~0UL;
2113 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
2114 +       /*
2115 +        * Restore the topdown base:
2116 +        */
2117 +       mm->mmap_base = base;
2118 +       mm->free_area_cache = base;
2119 +       mm->cached_hole_size = ~0UL;
2120 +
2121 +       return addr;
2122 +}
2123  
2124  struct sel_arg_struct {
2125         unsigned long n;
2126 diff -urNp linux-2.6.16.2/arch/i386/kernel/traps.c linux-2.6.16.2/arch/i386/kernel/traps.c
2127 --- linux-2.6.16.2/arch/i386/kernel/traps.c     2006-04-07 12:56:47.000000000 -0400
2128 +++ linux-2.6.16.2/arch/i386/kernel/traps.c     2006-04-09 21:23:54.000000000 -0400
2129 @@ -28,6 +28,7 @@
2130  #include <linux/utsname.h>
2131  #include <linux/kprobes.h>
2132  #include <linux/kexec.h>
2133 +#include <linux/binfmts.h>
2134  
2135  #ifdef CONFIG_EISA
2136  #include <linux/ioport.h>
2137 @@ -58,18 +59,13 @@
2138  
2139  asmlinkage int system_call(void);
2140  
2141 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2142 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2143                 { 0, 0 }, { 0, 0 } };
2144  
2145  /* Do we ignore FPU interrupts ? */
2146  char ignore_fpu_irq = 0;
2147  
2148 -/*
2149 - * The IDT has to be page-aligned to simplify the Pentium
2150 - * F0 0F bug workaround.. We have a special link segment
2151 - * for this.
2152 - */
2153 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
2154 +extern struct desc_struct idt_table[256];
2155  
2156  asmlinkage void divide_error(void);
2157  asmlinkage void debug(void);
2158 @@ -125,18 +121,22 @@ static inline unsigned long print_contex
2159                                 char *log_lvl)
2160  {
2161         unsigned long addr;
2162 +       int i = kstack_depth_to_print;
2163  
2164  #ifdef CONFIG_FRAME_POINTER
2165         while (valid_stack_ptr(tinfo, (void *)ebp)) {
2166                 addr = *(unsigned long *)(ebp + 4);
2167                 print_addr_and_symbol(addr, log_lvl);
2168                 ebp = *(unsigned long *)ebp;
2169 +               --i;
2170         }
2171  #else
2172         while (valid_stack_ptr(tinfo, stack)) {
2173                 addr = *stack++;
2174 -               if (__kernel_text_address(addr))
2175 +               if (__kernel_text_address(addr)) {
2176                         print_addr_and_symbol(addr, log_lvl);
2177 +                       --i;
2178 +               }
2179         }
2180  #endif
2181         return ebp;
2182 @@ -266,7 +266,7 @@ void show_registers(struct pt_regs *regs
2183  
2184                 printk(KERN_EMERG "Code: ");
2185  
2186 -               eip = (u8 __user *)regs->eip - 43;
2187 +               eip = (u8 __user *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
2188                 for (i = 0; i < 64; i++, eip++) {
2189                         unsigned char c;
2190  
2191 @@ -274,7 +274,7 @@ void show_registers(struct pt_regs *regs
2192                                 printk(" Bad EIP value.");
2193                                 break;
2194                         }
2195 -                       if (eip == (u8 __user *)regs->eip)
2196 +                       if (eip == (u8 __user *)regs->eip + __KERNEL_TEXT_OFFSET)
2197                                 printk("<%02x> ", c);
2198                         else
2199                                 printk("%02x ", c);
2200 @@ -291,7 +291,7 @@ static void handle_BUG(struct pt_regs *r
2201         char c;
2202         unsigned long eip;
2203  
2204 -       eip = regs->eip;
2205 +       eip = regs->eip + __KERNEL_TEXT_OFFSET;
2206  
2207         if (eip < PAGE_OFFSET)
2208                 goto no_bug;
2209 @@ -390,7 +390,7 @@ void die(const char * str, struct pt_reg
2210  
2211  static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
2212  {
2213 -       if (!user_mode_vm(regs))
2214 +       if (!user_mode(regs))
2215                 die(str, regs, err);
2216  }
2217  
2218 @@ -408,7 +408,7 @@ static void __kprobes do_trap(int trapnr
2219                 goto trap_signal;
2220         }
2221  
2222 -       if (!user_mode(regs))
2223 +       if (!user_mode_novm(regs))
2224                 goto kernel_trap;
2225  
2226         trap_signal: {
2227 @@ -496,7 +496,7 @@ fastcall void __kprobes do_general_prote
2228                                               long error_code)
2229  {
2230         int cpu = get_cpu();
2231 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2232 +       struct tss_struct *tss = &init_tss[cpu];
2233         struct thread_struct *thread = &current->thread;
2234  
2235         /*
2236 @@ -532,9 +532,25 @@ fastcall void __kprobes do_general_prote
2237         if (regs->eflags & VM_MASK)
2238                 goto gp_in_vm86;
2239  
2240 -       if (!user_mode(regs))
2241 +       if (!user_mode_novm(regs))
2242                 goto gp_in_kernel;
2243  
2244 +#ifdef CONFIG_PAX_PAGEEXEC
2245 +       if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
2246 +               struct mm_struct *mm = current->mm;
2247 +               unsigned long limit;
2248 +
2249 +               down_write(&mm->mmap_sem);
2250 +               limit = mm->context.user_cs_limit;
2251 +               if (limit < TASK_SIZE) {
2252 +                       track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
2253 +                       up_write(&mm->mmap_sem);
2254 +                       return;
2255 +               }
2256 +               up_write(&mm->mmap_sem);
2257 +       }
2258 +#endif
2259 +
2260         current->thread.error_code = error_code;
2261         current->thread.trap_no = 13;
2262         force_sig(SIGSEGV, current);
2263 @@ -550,6 +566,13 @@ gp_in_kernel:
2264                 if (notify_die(DIE_GPF, "general protection fault", regs,
2265                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
2266                         return;
2267 +
2268 +#ifdef CONFIG_PAX_KERNEXEC
2269 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
2270 +                       die("PAX: suspicious general protection fault", regs, error_code);
2271 +               else
2272 +#endif
2273 +
2274                 die("general protection fault", regs, error_code);
2275         }
2276  }
2277 @@ -775,7 +798,7 @@ fastcall void __kprobes do_debug(struct 
2278                  * check for kernel mode by just checking the CPL
2279                  * of CS.
2280                  */
2281 -               if (!user_mode(regs))
2282 +               if (!user_mode_novm(regs))
2283                         goto clear_TF_reenable;
2284         }
2285  
2286 @@ -1065,7 +1088,19 @@ do { \
2287   */
2288  void set_intr_gate(unsigned int n, void *addr)
2289  {
2290 +
2291 +#ifdef CONFIG_PAX_KERNEXEC
2292 +       unsigned long cr0;
2293 +
2294 +       pax_open_kernel(cr0);
2295 +#endif
2296 +
2297         _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
2298 +
2299 +#ifdef CONFIG_PAX_KERNEXEC
2300 +       pax_close_kernel(cr0);
2301 +#endif
2302 +
2303  }
2304  
2305  /*
2306 diff -urNp linux-2.6.16.2/arch/i386/kernel/vm86.c linux-2.6.16.2/arch/i386/kernel/vm86.c
2307 --- linux-2.6.16.2/arch/i386/kernel/vm86.c      2006-04-07 12:56:47.000000000 -0400
2308 +++ linux-2.6.16.2/arch/i386/kernel/vm86.c      2006-04-09 21:23:54.000000000 -0400
2309 @@ -122,7 +122,7 @@ struct pt_regs * fastcall save_v86_state
2310                 do_exit(SIGSEGV);
2311         }
2312  
2313 -       tss = &per_cpu(init_tss, get_cpu());
2314 +       tss = init_tss + get_cpu();
2315         current->thread.esp0 = current->thread.saved_esp0;
2316         current->thread.sysenter_cs = __KERNEL_CS;
2317         load_esp0(tss, &current->thread);
2318 @@ -295,7 +295,7 @@ static void do_sys_vm86(struct kernel_vm
2319         savesegment(fs, tsk->thread.saved_fs);
2320         savesegment(gs, tsk->thread.saved_gs);
2321  
2322 -       tss = &per_cpu(init_tss, get_cpu());
2323 +       tss = init_tss + get_cpu();
2324         tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
2325         if (cpu_has_sep)
2326                 tsk->thread.sysenter_cs = 0;
2327 diff -urNp linux-2.6.16.2/arch/i386/kernel/vmlinux.lds.S linux-2.6.16.2/arch/i386/kernel/vmlinux.lds.S
2328 --- linux-2.6.16.2/arch/i386/kernel/vmlinux.lds.S       2006-04-07 12:56:47.000000000 -0400
2329 +++ linux-2.6.16.2/arch/i386/kernel/vmlinux.lds.S       2006-04-09 21:23:54.000000000 -0400
2330 @@ -4,9 +4,18 @@
2331  
2332  #define LOAD_OFFSET __PAGE_OFFSET
2333  
2334 +#include <linux/config.h>
2335 +
2336  #include <asm-generic/vmlinux.lds.h>
2337  #include <asm/thread_info.h>
2338  #include <asm/page.h>
2339 +#include <asm/segment.h>
2340 +
2341 +#ifdef CONFIG_X86_PAE
2342 +#define PMD_SHIFT 21
2343 +#else
2344 +#define PMD_SHIFT 22
2345 +#endif
2346  
2347  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2348  OUTPUT_ARCH(i386)
2349 @@ -15,67 +24,17 @@ jiffies = jiffies_64;
2350  SECTIONS
2351  {
2352    . = __KERNEL_START;
2353 -  phys_startup_32 = startup_32 - LOAD_OFFSET;
2354 -  /* read-only */
2355 -  _text = .;                   /* Text and read-only data */
2356 -  .text : AT(ADDR(.text) - LOAD_OFFSET) {
2357 -       *(.text)
2358 -       SCHED_TEXT
2359 -       LOCK_TEXT
2360 -       KPROBES_TEXT
2361 -       *(.fixup)
2362 -       *(.gnu.warning)
2363 -       } = 0x9090
2364 -
2365 -  _etext = .;                  /* End of text section */
2366 -
2367 -  . = ALIGN(16);               /* Exception table */
2368 -  __start___ex_table = .;
2369 -  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2370 -  __stop___ex_table = .;
2371 -
2372 -  RODATA
2373 +  phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
2374  
2375 -  /* writeable */
2376 -  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2377 -       *(.data)
2378 -       CONSTRUCTORS
2379 +  .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
2380 +       BYTE(0xEA) /* jmp far */
2381 +       LONG(phys_startup_32)
2382 +       SHORT(__BOOT_CS)
2383         }
2384  
2385 -  . = ALIGN(4096);
2386 -  __nosave_begin = .;
2387 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2388 -  . = ALIGN(4096);
2389 -  __nosave_end = .;
2390 -
2391 -  . = ALIGN(4096);
2392 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
2393 -       *(.data.idt)
2394 -  }
2395 -
2396 -  . = ALIGN(32);
2397 -  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2398 -       *(.data.cacheline_aligned)
2399 -  }
2400 -
2401 -  /* rarely changed data like cpu maps */
2402 -  . = ALIGN(32);
2403 -  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2404 -  _edata = .;                  /* End of data section */
2405 -
2406 -  . = ALIGN(THREAD_SIZE);      /* init_task */
2407 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2408 -       *(.data.init_task)
2409 -  }
2410 -
2411    /* will be freed after init */
2412    . = ALIGN(4096);             /* Init code and data */
2413    __init_begin = .;
2414 -  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
2415 -       _sinittext = .;
2416 -       *(.init.text)
2417 -       _einittext = .;
2418 -  }
2419    .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
2420    . = ALIGN(16);
2421    __setup_start = .;
2422 @@ -107,9 +66,7 @@ SECTIONS
2423    .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
2424         *(.altinstr_replacement)
2425    }
2426 -  /* .exit.text is discard at runtime, not link time, to deal with references
2427 -     from .altinstructions and .eh_frame */
2428 -  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
2429 +
2430    .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
2431    . = ALIGN(4096);
2432    __initramfs_start = .;
2433 @@ -119,10 +76,108 @@ SECTIONS
2434    __per_cpu_start = .;
2435    .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
2436    __per_cpu_end = .;
2437 +
2438 +  /* read-only */
2439 +
2440    . = ALIGN(4096);
2441 -  __init_end = .;
2442 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2443 +       _sinittext = .;
2444 +       *(.init.text)
2445 +       _einittext = .;
2446 +  }
2447 +
2448 +  /* .exit.text is discard at runtime, not link time, to deal with references
2449 +     from .altinstructions and .eh_frame */
2450 +  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
2451 +
2452 +#ifdef CONFIG_PAX_KERNEXEC
2453 +  .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2454 +       . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
2455 +       BYTE(0)
2456 +  }
2457 +#else
2458 +  . = ALIGN(4096);
2459 +#endif
2460 +
2461 +  __init_end = . + __KERNEL_TEXT_OFFSET;
2462    /* freed after init ends here */
2463 -       
2464 +
2465 +  _text = .;                   /* Text and read-only data */
2466 +  .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
2467 +       *(.text)
2468 +       SCHED_TEXT
2469 +       LOCK_TEXT
2470 +       KPROBES_TEXT
2471 +       *(.fixup)
2472 +       *(.gnu.warning)
2473 +       } = 0x9090
2474 +
2475 +  _etext = .;                  /* End of text section */
2476 +  . += __KERNEL_TEXT_OFFSET;
2477 +  . = ALIGN(16);               /* Exception table */
2478 +  __start___ex_table = .;
2479 +  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
2480 +  __stop___ex_table = .;
2481 +
2482 +  . = ALIGN(4096);
2483 +  .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
2484 +       *(.empty_zero_page)
2485 +
2486 +#ifdef CONFIG_X86_PAE
2487 +       *(.swapper_pm_dir)
2488 +#endif
2489 +
2490 +       *(.swapper_pg_dir)
2491 +       *(.idt)
2492 +       }
2493 +
2494 +  RODATA
2495 +
2496 +#ifdef CONFIG_PAX_KERNEXEC
2497 +  . = ALIGN(4096);
2498 +  MODULES_VADDR = .;
2499 +
2500 +  .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
2501 +       . += (4 * 1024 * 1024);
2502 +       . = ALIGN(1 << PMD_SHIFT) - 1;
2503 +       BYTE(0)
2504 +  }
2505 +
2506 +  MODULES_END = .;
2507 +#else
2508 +  . = ALIGN(32);
2509 +#endif
2510 +
2511 +  /* writeable */
2512 +  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
2513 +       _data = .;
2514 +       *(.data)
2515 +       CONSTRUCTORS
2516 +       }
2517 +
2518 +  . = ALIGN(4096);
2519 +  __nosave_begin = .;
2520 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
2521 +  . = ALIGN(4096);
2522 +  __nosave_end = .;
2523 +
2524 +  . = ALIGN(32);
2525 +  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
2526 +       *(.data.cacheline_aligned)
2527 +  }
2528 +
2529 +  /* rarely changed data like cpu maps */
2530 +  . = ALIGN(32);
2531 +  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
2532 +
2533 +  . = ALIGN(THREAD_SIZE);      /* init_task */
2534 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
2535 +       *(.data.init_task)
2536 +  }
2537 +
2538 +  _edata = .;                  /* End of data section */
2539 +
2540 +  . = ALIGN(4096);
2541    __bss_start = .;             /* BSS */
2542    .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
2543         *(.bss.page_aligned)
2544 diff -urNp linux-2.6.16.2/arch/i386/mach-voyager/voyager_smp.c linux-2.6.16.2/arch/i386/mach-voyager/voyager_smp.c
2545 --- linux-2.6.16.2/arch/i386/mach-voyager/voyager_smp.c 2006-04-07 12:56:47.000000000 -0400
2546 +++ linux-2.6.16.2/arch/i386/mach-voyager/voyager_smp.c 2006-04-09 21:23:54.000000000 -0400
2547 @@ -1295,7 +1295,7 @@ smp_local_timer_interrupt(struct pt_regs
2548                                                 per_cpu(prof_counter, cpu);
2549                 }
2550  
2551 -               update_process_times(user_mode_vm(regs));
2552 +               update_process_times(user_mode(regs));
2553         }
2554  
2555         if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
2556 diff -urNp linux-2.6.16.2/arch/i386/mm/boot_ioremap.c linux-2.6.16.2/arch/i386/mm/boot_ioremap.c
2557 --- linux-2.6.16.2/arch/i386/mm/boot_ioremap.c  2006-04-07 12:56:47.000000000 -0400
2558 +++ linux-2.6.16.2/arch/i386/mm/boot_ioremap.c  2006-04-09 21:23:54.000000000 -0400
2559 @@ -8,53 +8,37 @@
2560   */
2561  
2562  
2563 -/*
2564 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
2565 - * keeps that from happenning.  If anyone has a better way, I'm listening.
2566 - *
2567 - * boot_pte_t is defined only if this all works correctly
2568 - */
2569 -
2570  #include <linux/config.h>
2571 -#undef CONFIG_X86_PAE
2572  #include <asm/page.h>
2573  #include <asm/pgtable.h>
2574  #include <asm/tlbflush.h>
2575  #include <linux/init.h>
2576  #include <linux/stddef.h>
2577  
2578 -/* 
2579 - * I'm cheating here.  It is known that the two boot PTE pages are 
2580 - * allocated next to each other.  I'm pretending that they're just
2581 - * one big array. 
2582 - */
2583 -
2584 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
2585 -#define boot_pte_index(address) \
2586 -            (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
2587 -
2588 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
2589 -{
2590 -       boot_pte_t* boot_pg = (boot_pte_t*)pg0;
2591 -       return &boot_pg[boot_pte_index((unsigned long)address)];
2592 -}
2593  
2594  /*
2595   * This is only for a caller who is clever enough to page-align
2596   * phys_addr and virtual_source, and who also has a preference
2597   * about which virtual address from which to steal ptes
2598   */
2599 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
2600 -                   void* virtual_source)
2601 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned int nrpages,
2602 +                   char* virtual_source)
2603  {
2604 -       boot_pte_t* pte;
2605 -       int i;
2606 -       char *vaddr = virtual_source;
2607 +       pgd_t *pgd;
2608 +       pud_t *pud;
2609 +       pmd_t *pmd;
2610 +       pte_t* pte;
2611 +       unsigned int i;
2612 +       unsigned long vaddr = (unsigned long)virtual_source;
2613 +
2614 +       pgd = pgd_offset_k(vaddr);
2615 +       pud = pud_offset(pgd, vaddr);
2616 +       pmd = pmd_offset(pud, vaddr);
2617 +       pte = pte_offset_kernel(pmd, vaddr);
2618  
2619 -       pte = boot_vaddr_to_pte(virtual_source);
2620         for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
2621                 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
2622 -               __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
2623 +               __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
2624         }
2625  }
2626  
2627 diff -urNp linux-2.6.16.2/arch/i386/mm/extable.c linux-2.6.16.2/arch/i386/mm/extable.c
2628 --- linux-2.6.16.2/arch/i386/mm/extable.c       2006-04-07 12:56:47.000000000 -0400
2629 +++ linux-2.6.16.2/arch/i386/mm/extable.c       2006-04-09 21:23:54.000000000 -0400
2630 @@ -12,7 +12,7 @@ int fixup_exception(struct pt_regs *regs
2631         const struct exception_table_entry *fixup;
2632  
2633  #ifdef CONFIG_PNPBIOS
2634 -       if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
2635 +       if (unlikely(regs->xcs == (GDT_ENTRY_PNPBIOS_BASE << 3)))
2636         {
2637                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
2638                 extern u32 pnp_bios_is_utter_crap;
2639 diff -urNp linux-2.6.16.2/arch/i386/mm/fault.c linux-2.6.16.2/arch/i386/mm/fault.c
2640 --- linux-2.6.16.2/arch/i386/mm/fault.c 2006-04-07 12:56:47.000000000 -0400
2641 +++ linux-2.6.16.2/arch/i386/mm/fault.c 2006-04-09 21:23:54.000000000 -0400
2642 @@ -22,6 +22,9 @@
2643  #include <linux/highmem.h>
2644  #include <linux/module.h>
2645  #include <linux/kprobes.h>
2646 +#include <linux/unistd.h>
2647 +#include <linux/compiler.h>
2648 +#include <linux/binfmts.h>
2649  
2650  #include <asm/system.h>
2651  #include <asm/uaccess.h>
2652 @@ -82,11 +85,13 @@ static inline unsigned long get_segment_
2653  
2654         /* Unlikely, but must come before segment checks. */
2655         if (unlikely((regs->eflags & VM_MASK) != 0))
2656 -               return eip + (seg << 4);
2657 +               return (eip & 0xFFFF) + (seg << 4);
2658         
2659         /* By far the most common cases. */
2660 -       if (likely(seg == __USER_CS || seg == __KERNEL_CS))
2661 +       if (likely(seg == __USER_CS))
2662                 return eip;
2663 +       if (likely(seg == __KERNEL_CS))
2664 +               return eip + __KERNEL_TEXT_OFFSET;
2665  
2666         /* Check the segment exists, is within the current LDT/GDT size,
2667            that kernel/user (ring 0..3) has the appropriate privilege,
2668 @@ -108,7 +113,7 @@ static inline unsigned long get_segment_
2669                 desc = (void *)desc + (seg & ~7);
2670         } else {
2671                 /* Must disable preemption while reading the GDT. */
2672 -               desc = (u32 *)get_cpu_gdt_table(get_cpu());
2673 +               desc = (u32 *)get_cpu_gdt_table(get_cpu());
2674                 desc = (void *)desc + (seg & ~7);
2675         }
2676  
2677 @@ -214,6 +219,30 @@ static noinline void force_sig_info_faul
2678  
2679  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
2680  
2681 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2682 +static int pax_handle_fetch_fault(struct pt_regs *regs);
2683 +#endif
2684 +
2685 +#ifdef CONFIG_PAX_PAGEEXEC
2686 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
2687 +{
2688 +       pgd_t *pgd;
2689 +       pud_t *pud;
2690 +       pmd_t *pmd;
2691 +
2692 +       pgd = pgd_offset(mm, address);
2693 +       if (!pgd_present(*pgd))
2694 +               return NULL;
2695 +       pud = pud_offset(pgd, address);
2696 +       if (!pud_present(*pud))
2697 +               return NULL;
2698 +       pmd = pmd_offset(pud, address);
2699 +       if (!pmd_present(*pmd))
2700 +               return NULL;
2701 +       return pmd;
2702 +}
2703 +#endif
2704 +
2705  /*
2706   * This routine handles page faults.  It determines the address,
2707   * and the problem, and then passes it off to one of the appropriate
2708 @@ -231,9 +260,15 @@ fastcall void __kprobes do_page_fault(st
2709         struct mm_struct *mm;
2710         struct vm_area_struct * vma;
2711         unsigned long address;
2712 -       unsigned long page;
2713         int write, si_code;
2714  
2715 +#ifdef CONFIG_PAX_PAGEEXEC
2716 +       pmd_t *pmd;
2717 +       pte_t *pte;
2718 +       spinlock_t *ptl;
2719 +       unsigned char pte_mask;
2720 +#endif
2721 +
2722         /* get the address */
2723          address = read_cr2();
2724  
2725 @@ -245,6 +280,7 @@ fastcall void __kprobes do_page_fault(st
2726                 local_irq_enable();
2727  
2728         tsk = current;
2729 +       mm = tsk->mm;
2730  
2731         si_code = SEGV_MAPERR;
2732  
2733 @@ -271,14 +307,12 @@ fastcall void __kprobes do_page_fault(st
2734                 goto bad_area_nosemaphore;
2735         } 
2736  
2737 -       mm = tsk->mm;
2738 -
2739         /*
2740          * If we're in an interrupt, have no user context or are running in an
2741          * atomic region then we must not take the fault..
2742          */
2743         if (in_atomic() || !mm)
2744 -               goto bad_area_nosemaphore;
2745 +               goto bad_area_nopax;
2746  
2747         /* When running in the kernel we expect faults to occur only to
2748          * addresses in user space.  All other faults represent errors in the
2749 @@ -298,10 +332,98 @@ fastcall void __kprobes do_page_fault(st
2750         if (!down_read_trylock(&mm->mmap_sem)) {
2751                 if ((error_code & 4) == 0 &&
2752                     !search_exception_tables(regs->eip))
2753 -                       goto bad_area_nosemaphore;
2754 +                       goto bad_area_nopax;
2755                 down_read(&mm->mmap_sem);
2756         }
2757  
2758 +#ifdef CONFIG_PAX_PAGEEXEC
2759 +       if (unlikely((error_code & 5) != 5 ||
2760 +                    (regs->eflags & X86_EFLAGS_VM) ||
2761 +                    !(mm->pax_flags & MF_PAX_PAGEEXEC)))
2762 +               goto not_pax_fault;
2763 +
2764 +       /* PaX: it's our fault, let's handle it if we can */
2765 +
2766 +       /* PaX: take a look at read faults before acquiring any locks */
2767 +       if (unlikely(!(error_code & 2) && (regs->eip == address))) {
2768 +               /* instruction fetch attempt from a protected page in user mode */
2769 +               up_read(&mm->mmap_sem);
2770 +               switch (pax_handle_fetch_fault(regs)) {
2771 +
2772 +#ifdef CONFIG_PAX_EMUTRAMP
2773 +               case 2:
2774 +                       return;
2775 +#endif
2776 +
2777 +               }
2778 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2779 +               do_exit(SIGKILL);
2780 +       }
2781 +
2782 +       pmd = pax_get_pmd(mm, address);
2783 +       if (unlikely(!pmd))
2784 +               goto not_pax_fault;
2785 +
2786 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
2787 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
2788 +               pte_unmap_unlock(pte, ptl);
2789 +               goto not_pax_fault;
2790 +       }
2791 +
2792 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
2793 +               /* write attempt to a protected page in user mode */
2794 +               pte_unmap_unlock(pte, ptl);
2795 +               goto not_pax_fault;
2796 +       }
2797 +
2798 +#ifdef CONFIG_SMP
2799 +       if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
2800 +#else
2801 +       if (likely(address > get_limit(regs->xcs)))
2802 +#endif
2803 +       {
2804 +               set_pte(pte, pte_mkread(*pte));
2805 +               __flush_tlb_one(address);
2806 +               pte_unmap_unlock(pte, ptl);
2807 +               up_read(&mm->mmap_sem);
2808 +               return;
2809 +       }
2810 +
2811 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
2812 +
2813 +       /*
2814 +        * PaX: fill DTLB with user rights and retry
2815 +        */
2816 +       __asm__ __volatile__ (
2817 +               "orb %2,%1\n"
2818 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
2819 +/*
2820 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
2821 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
2822 + * page fault when examined during a TLB load attempt. this is true not only
2823 + * for PTEs holding a non-present entry but also present entries that will
2824 + * raise a page fault (such as those set up by PaX, or the copy-on-write
2825 + * mechanism). in effect it means that we do *not* need to flush the TLBs
2826 + * for our target pages since their PTEs are simply not in the TLBs at all.
2827 +
2828 + * the best thing in omitting it is that we gain around 15-20% speed in the
2829 + * fast path of the page fault handler and can get rid of tracing since we
2830 + * can no longer flush unintended entries.
2831 + */
2832 +               "invlpg %0\n"
2833 +#endif
2834 +               "testb $0,%0\n"
2835 +               "xorb %3,%1\n"
2836 +               :
2837 +               : "m" (*(char*)address), "m" (*(char*)pte), "q" (pte_mask), "i" (_PAGE_USER)
2838 +               : "memory", "cc");
2839 +       pte_unmap_unlock(pte, ptl);
2840 +       up_read(&mm->mmap_sem);
2841 +       return;
2842 +
2843 +not_pax_fault:
2844 +#endif
2845 +
2846         vma = find_vma(mm, address);
2847         if (!vma)
2848                 goto bad_area;
2849 @@ -387,6 +509,37 @@ bad_area:
2850         up_read(&mm->mmap_sem);
2851  
2852  bad_area_nosemaphore:
2853 +
2854 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2855 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
2856 +
2857 +#ifdef CONFIG_PAX_PAGEEXEC
2858 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
2859 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2860 +                       do_exit(SIGKILL);
2861 +               }
2862 +#endif
2863 +
2864 +#ifdef CONFIG_PAX_SEGMEXEC
2865 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
2866 +
2867 +                       switch (pax_handle_fetch_fault(regs)) {
2868 +
2869 +#ifdef CONFIG_PAX_EMUTRAMP
2870 +                       case 2:
2871 +                               return;
2872 +#endif
2873 +
2874 +                       }
2875 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
2876 +                       do_exit(SIGKILL);
2877 +               }
2878 +#endif
2879 +
2880 +       }
2881 +#endif
2882 +
2883 +bad_area_nopax:
2884         /* User mode accesses just cause a SIGSEGV */
2885         if (error_code & 4) {
2886                 /* 
2887 @@ -450,28 +603,53 @@ no_context:
2888  #endif
2889         if (address < PAGE_SIZE)
2890                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
2891 +
2892 +#ifdef CONFIG_PAX_KERNEXEC
2893 +#ifdef CONFIG_MODULES
2894 +       else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
2895 +#else
2896 +       else if (init_mm.start_code <= address && address < init_mm.end_code)
2897 +#endif
2898 +               if (tsk->signal->curr_ip)
2899 +                       printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
2900 +                                        NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
2901 +               else
2902 +                       printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
2903 +                                        tsk->comm, tsk->pid, tsk->uid, tsk->euid);
2904 +#endif
2905 +
2906         else
2907                 printk(KERN_ALERT "Unable to handle kernel paging request");
2908         printk(" at virtual address %08lx\n",address);
2909         printk(KERN_ALERT " printing eip:\n");
2910         printk("%08lx\n", regs->eip);
2911 -       page = read_cr3();
2912 -       page = ((unsigned long *) __va(page))[address >> 22];
2913 -       printk(KERN_ALERT "*pde = %08lx\n", page);
2914 -       /*
2915 -        * We must not directly access the pte in the highpte
2916 -        * case, the page table might be allocated in highmem.
2917 -        * And lets rather not kmap-atomic the pte, just in case
2918 -        * it's allocated already.
2919 -        */
2920 +       {
2921 +               unsigned long index = pgd_index(address);
2922 +               pgd_t *pgd;
2923 +               pud_t *pud;
2924 +               pmd_t *pmd;
2925 +               pte_t *pte;
2926 +
2927 +               pgd = index + (pgd_t *)__va(read_cr3());
2928 +               printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
2929 +               if (pgd_present(*pgd)) {
2930 +                       pud = pud_offset(pgd, address);
2931 +                       pmd = pmd_offset(pud, address);
2932 +                       printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
2933 +                       /*
2934 +                        * We must not directly access the pte in the highpte
2935 +                        * case, the page table might be allocated in highmem.
2936 +                        * And lets rather not kmap-atomic the pte, just in case
2937 +                        * it's allocated already.
2938 +                        */
2939  #ifndef CONFIG_HIGHPTE
2940 -       if (page & 1) {
2941 -               page &= PAGE_MASK;
2942 -               address &= 0x003ff000;
2943 -               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
2944 -               printk(KERN_ALERT "*pte = %08lx\n", page);
2945 -       }
2946 +                       if (pmd_present(*pmd) && !pmd_large(*pmd)) {
2947 +                               pte = pte_offset_kernel(pmd, address);
2948 +                               printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
2949 +                       }
2950  #endif
2951 +               }
2952 +       }
2953         tsk->thread.cr2 = address;
2954         tsk->thread.trap_no = 14;
2955         tsk->thread.error_code = error_code;
2956 @@ -521,7 +699,7 @@ vmalloc_fault:
2957                  * Do _not_ use "tsk" here. We might be inside
2958                  * an interrupt in the middle of a task switch..
2959                  */
2960 -               int index = pgd_index(address);
2961 +               unsigned long index = pgd_index(address);
2962                 unsigned long pgd_paddr;
2963                 pgd_t *pgd, *pgd_k;
2964                 pud_t *pud, *pud_k;
2965 @@ -558,3 +736,105 @@ vmalloc_fault:
2966                 return;
2967         }
2968  }
2969 +
2970 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2971 +/*
2972 + * PaX: decide what to do with offenders (regs->eip = fault address)
2973 + *
2974 + * returns 1 when task should be killed
2975 + *         2 when gcc trampoline was detected
2976 + */
2977 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2978 +{
2979 +
2980 +#ifdef CONFIG_PAX_EMUTRAMP
2981 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
2982 +       int err;
2983 +#endif
2984 +
2985 +       if (regs->eflags & X86_EFLAGS_VM)
2986 +               return 1;
2987 +
2988 +#ifdef CONFIG_PAX_EMUTRAMP
2989 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
2990 +               return 1;
2991 +
2992 +       do { /* PaX: gcc trampoline emulation #1 */
2993 +               unsigned char mov1, mov2;
2994 +               unsigned short jmp;
2995 +               unsigned long addr1, addr2;
2996 +
2997 +               err = get_user(mov1, (unsigned char __user *)regs->eip);
2998 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
2999 +               err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
3000 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
3001 +               err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
3002 +
3003 +               if (err)
3004 +                       break;
3005 +
3006 +               if ((mov1 & 0xF8) == 0xB8 &&
3007 +                   (mov2 & 0xF8) == 0xB8 &&
3008 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
3009 +                   (jmp & 0xF8FF) == 0xE0FF &&
3010 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07))
3011 +               {
3012 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
3013 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
3014 +                       regs->eip = addr2;
3015 +                       return 2;
3016 +               }
3017 +       } while (0);
3018 +
3019 +       do { /* PaX: gcc trampoline emulation #2 */
3020 +               unsigned char mov, jmp;
3021 +               unsigned long addr1, addr2;
3022 +
3023 +               err = get_user(mov, (unsigned char __user *)regs->eip);
3024 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
3025 +               err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
3026 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
3027 +
3028 +               if (err)
3029 +                       break;
3030 +
3031 +               if ((mov & 0xF8) == 0xB8 &&
3032 +                   jmp == 0xE9)
3033 +               {
3034 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
3035 +                       regs->eip += addr2 + 10;
3036 +                       return 2;
3037 +               }
3038 +       } while (0);
3039 +#endif
3040 +
3041 +       return 1; /* PaX in action */
3042 +}
3043 +#endif
3044 +
3045 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
3046 +void pax_report_insns(void *pc, void *sp)
3047 +{
3048 +       long i;
3049 +
3050 +       printk(KERN_ERR "PAX: bytes at PC: ");
3051 +       for (i = 0; i < 20; i++) {
3052 +               unsigned char c;
3053 +               if (get_user(c, (unsigned char __user *)pc+i))
3054 +                       printk("?? ");
3055 +               else
3056 +                       printk("%02x ", c);
3057 +       }
3058 +       printk("\n");
3059 +
3060 +       printk(KERN_ERR "PAX: bytes at SP-4: ");
3061 +       for (i = -1; i < 20; i++) {
3062 +               unsigned long c;
3063 +               if (get_user(c, (unsigned long __user *)sp+i))
3064 +                       printk("???????? ");
3065 +               else
3066 +                       printk("%08lx ", c);
3067 +       }
3068 +       printk("\n");
3069 +}
3070 +#endif
3071 diff -urNp linux-2.6.16.2/arch/i386/mm/hugetlbpage.c linux-2.6.16.2/arch/i386/mm/hugetlbpage.c
3072 --- linux-2.6.16.2/arch/i386/mm/hugetlbpage.c   2006-04-07 12:56:47.000000000 -0400
3073 +++ linux-2.6.16.2/arch/i386/mm/hugetlbpage.c   2006-04-09 21:23:54.000000000 -0400
3074 @@ -133,7 +133,12 @@ static unsigned long hugetlb_get_unmappe
3075  {
3076         struct mm_struct *mm = current->mm;
3077         struct vm_area_struct *vma;
3078 -       unsigned long start_addr;
3079 +       unsigned long start_addr, task_size = TASK_SIZE;
3080 +
3081 +#ifdef CONFIG_PAX_SEGMEXEC
3082 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
3083 +               task_size = SEGMEXEC_TASK_SIZE;
3084 +#endif
3085  
3086         if (len > mm->cached_hole_size) {
3087                 start_addr = mm->free_area_cache;
3088 @@ -147,7 +152,7 @@ full_search:
3089  
3090         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3091                 /* At this point:  (!vma || addr < vma->vm_end). */
3092 -               if (TASK_SIZE - len < addr) {
3093 +               if (task_size - len < addr) {
3094                         /*
3095                          * Start a new search - just in case we missed
3096                          * some holes.
3097 @@ -175,9 +180,8 @@ static unsigned long hugetlb_get_unmappe
3098  {
3099         struct mm_struct *mm = current->mm;
3100         struct vm_area_struct *vma, *prev_vma;
3101 -       unsigned long base = mm->mmap_base, addr = addr0;
3102 +       unsigned long base = mm->mmap_base, addr;
3103         unsigned long largest_hole = mm->cached_hole_size;
3104 -       int first_time = 1;
3105  
3106         /* don't allow allocations above current base */
3107         if (mm->free_area_cache > base)
3108 @@ -187,7 +191,7 @@ static unsigned long hugetlb_get_unmappe
3109                 largest_hole = 0;
3110                 mm->free_area_cache  = base;
3111         }
3112 -try_again:
3113 +
3114         /* make sure it can fit in the remaining address space */
3115         if (mm->free_area_cache < len)
3116                 goto fail;
3117 @@ -229,16 +233,6 @@ try_again:
3118  
3119  fail:
3120         /*
3121 -        * if hint left us with no space for the requested
3122 -        * mapping then try again:
3123 -        */
3124 -       if (first_time) {
3125 -               mm->free_area_cache = base;
3126 -               largest_hole = 0;
3127 -               first_time = 0;
3128 -               goto try_again;
3129 -       }
3130 -       /*
3131          * A failed mmap() very likely causes application failure,
3132          * so fall back to the bottom-up function here. This scenario
3133          * can happen with large stack limits and large mmap()
3134 @@ -264,16 +258,23 @@ hugetlb_get_unmapped_area(struct file *f
3135  {
3136         struct mm_struct *mm = current->mm;
3137         struct vm_area_struct *vma;
3138 +       unsigned long task_size = TASK_SIZE;
3139  
3140         if (len & ~HPAGE_MASK)
3141                 return -EINVAL;
3142 -       if (len > TASK_SIZE)
3143 +
3144 +#ifdef CONFIG_PAX_SEGMEXEC
3145 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
3146 +               task_size = SEGMEXEC_TASK_SIZE;
3147 +#endif
3148 +
3149 +       if (len > task_size || addr > task_size - len)
3150                 return -ENOMEM;
3151  
3152         if (addr) {
3153                 addr = ALIGN(addr, HPAGE_SIZE);
3154                 vma = find_vma(mm, addr);
3155 -               if (TASK_SIZE - len >= addr &&
3156 +               if (task_size - len >= addr &&
3157                     (!vma || addr + len <= vma->vm_start))
3158                         return addr;
3159         }
3160 diff -urNp linux-2.6.16.2/arch/i386/mm/init.c linux-2.6.16.2/arch/i386/mm/init.c
3161 --- linux-2.6.16.2/arch/i386/mm/init.c  2006-04-07 12:56:47.000000000 -0400
3162 +++ linux-2.6.16.2/arch/i386/mm/init.c  2006-04-09 21:23:54.000000000 -0400
3163 @@ -41,6 +41,7 @@
3164  #include <asm/tlb.h>
3165  #include <asm/tlbflush.h>
3166  #include <asm/sections.h>
3167 +#include <asm/desc.h>
3168  
3169  unsigned int __VMALLOC_RESERVE = 128 << 20;
3170  
3171 @@ -50,30 +51,6 @@ unsigned long highstart_pfn, highend_pfn
3172  static int noinline do_test_wp_bit(void);
3173  
3174  /*
3175 - * Creates a middle page table and puts a pointer to it in the
3176 - * given global directory entry. This only returns the gd entry
3177 - * in non-PAE compilation mode, since the middle layer is folded.
3178 - */
3179 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
3180 -{
3181 -       pud_t *pud;
3182 -       pmd_t *pmd_table;
3183 -               
3184 -#ifdef CONFIG_X86_PAE
3185 -       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
3186 -       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
3187 -       pud = pud_offset(pgd, 0);
3188 -       if (pmd_table != pmd_offset(pud, 0)) 
3189 -               BUG();
3190 -#else
3191 -       pud = pud_offset(pgd, 0);
3192 -       pmd_table = pmd_offset(pud, 0);
3193 -#endif
3194 -
3195 -       return pmd_table;
3196 -}
3197 -
3198 -/*
3199   * Create a page table and place a pointer to it in a middle page
3200   * directory entry.
3201   */
3202 @@ -81,7 +58,11 @@ static pte_t * __init one_page_table_ini
3203  {
3204         if (pmd_none(*pmd)) {
3205                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
3206 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
3207 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
3208 +#else
3209                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
3210 +#endif
3211                 if (page_table != pte_offset_kernel(pmd, 0))
3212                         BUG();  
3213  
3214 @@ -116,8 +97,6 @@ static void __init page_table_range_init
3215         pgd = pgd_base + pgd_idx;
3216  
3217         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
3218 -               if (pgd_none(*pgd)) 
3219 -                       one_md_table_init(pgd);
3220                 pud = pud_offset(pgd, vaddr);
3221                 pmd = pmd_offset(pud, vaddr);
3222                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
3223 @@ -130,11 +109,22 @@ static void __init page_table_range_init
3224         }
3225  }
3226  
3227 -static inline int is_kernel_text(unsigned long addr)
3228 +static inline int is_kernel_text(unsigned long start, unsigned long end)
3229  {
3230 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
3231 -               return 1;
3232 -       return 0;
3233 +       unsigned long etext;
3234 +
3235 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
3236 +       etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
3237 +#else
3238 +       etext = (unsigned long)&_etext;
3239 +#endif
3240 +
3241 +       if ((start > etext + __KERNEL_TEXT_OFFSET ||
3242 +            end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
3243 +           (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
3244 +            end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
3245 +               return 0;
3246 +       return 1;
3247  }
3248  
3249  /*
3250 @@ -146,26 +136,24 @@ static void __init kernel_physical_mappi
3251  {
3252         unsigned long pfn;
3253         pgd_t *pgd;
3254 +       pud_t *pud;
3255         pmd_t *pmd;
3256         pte_t *pte;
3257 -       int pgd_idx, pmd_idx, pte_ofs;
3258 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
3259  
3260         pgd_idx = pgd_index(PAGE_OFFSET);
3261         pgd = pgd_base + pgd_idx;
3262         pfn = 0;
3263  
3264 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
3265 -               pmd = one_md_table_init(pgd);
3266 -               if (pfn >= max_low_pfn)
3267 -                       continue;
3268 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
3269 +               pud = pud_offset(pgd, 0);
3270 +               pmd = pmd_offset(pud, 0);
3271                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
3272 -                       unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
3273 +                       unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
3274  
3275                         /* Map with big pages if possible, otherwise create normal page tables. */
3276                         if (cpu_has_pse) {
3277 -                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
3278 -
3279 -                               if (is_kernel_text(address) || is_kernel_text(address2))
3280 +                               if (is_kernel_text(address, address + PMD_SIZE))
3281                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
3282                                 else
3283                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
3284 @@ -174,7 +162,7 @@ static void __init kernel_physical_mappi
3285                                 pte = one_page_table_init(pmd);
3286  
3287                                 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
3288 -                                               if (is_kernel_text(address))
3289 +                                               if (is_kernel_text(address, address + PAGE_SIZE))
3290                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
3291                                                 else
3292                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
3293 @@ -341,13 +329,6 @@ static void __init pagetable_init (void)
3294         unsigned long vaddr;
3295         pgd_t *pgd_base = swapper_pg_dir;
3296  
3297 -#ifdef CONFIG_X86_PAE
3298 -       int i;
3299 -       /* Init entries of the first-level page table to the zero page */
3300 -       for (i = 0; i < PTRS_PER_PGD; i++)
3301 -               set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
3302 -#endif
3303 -
3304         /* Enable PSE if available */
3305         if (cpu_has_pse) {
3306                 set_in_cr4(X86_CR4_PSE);
3307 @@ -371,17 +352,6 @@ static void __init pagetable_init (void)
3308         page_table_range_init(vaddr, 0, pgd_base);
3309  
3310         permanent_kmaps_init(pgd_base);
3311 -
3312 -#ifdef CONFIG_X86_PAE
3313 -       /*
3314 -        * Add low memory identity-mappings - SMP needs it when
3315 -        * starting up on an AP from real-mode. In the non-PAE
3316 -        * case we already have these mappings through head.S.
3317 -        * All user-space mappings are explicitly cleared after
3318 -        * SMP startup.
3319 -        */
3320 -       set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
3321 -#endif
3322  }
3323  
3324  #ifdef CONFIG_SOFTWARE_SUSPEND
3325 @@ -423,7 +393,6 @@ void zap_low_mappings (void)
3326         flush_tlb_all();
3327  }
3328  
3329 -static int disable_nx __initdata = 0;
3330  u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
3331  
3332  /*
3333 @@ -437,11 +406,9 @@ u64 __supported_pte_mask __read_mostly =
3334  void __init noexec_setup(const char *str)
3335  {
3336         if (!strncmp(str, "on",2) && cpu_has_nx) {
3337 -               __supported_pte_mask |= _PAGE_NX;
3338 -               disable_nx = 0;
3339 +               nx_enabled = 1;
3340         } else if (!strncmp(str,"off",3)) {
3341 -               disable_nx = 1;
3342 -               __supported_pte_mask &= ~_PAGE_NX;
3343 +               nx_enabled = 0;
3344         }
3345  }
3346  
3347 @@ -450,17 +417,13 @@ int nx_enabled = 0;
3348  
3349  static void __init set_nx(void)
3350  {
3351 -       unsigned int v[4], l, h;
3352 +       if (!nx_enabled && cpu_has_nx) {
3353 +               unsigned l, h;
3354  
3355 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
3356 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
3357 -               if ((v[3] & (1 << 20)) && !disable_nx) {
3358 -                       rdmsr(MSR_EFER, l, h);
3359 -                       l |= EFER_NX;
3360 -                       wrmsr(MSR_EFER, l, h);
3361 -                       nx_enabled = 1;
3362 -                       __supported_pte_mask |= _PAGE_NX;
3363 -               }
3364 +               __supported_pte_mask &= ~_PAGE_NX;
3365 +               rdmsr(MSR_EFER, l, h);
3366 +               l &= ~EFER_NX;
3367 +               wrmsr(MSR_EFER, l, h);
3368         }
3369  }
3370  
3371 @@ -512,14 +475,6 @@ void __init paging_init(void)
3372  
3373         load_cr3(swapper_pg_dir);
3374  
3375 -#ifdef CONFIG_X86_PAE
3376 -       /*
3377 -        * We will bail out later - printk doesn't work right now so
3378 -        * the user would just see a hanging kernel.
3379 -        */
3380 -       if (cpu_has_pae)
3381 -               set_in_cr4(X86_CR4_PAE);
3382 -#endif
3383         __flush_tlb_all();
3384  
3385         kmap_init();
3386 @@ -611,7 +566,7 @@ void __init mem_init(void)
3387         set_highmem_pages_init(bad_ppro);
3388  
3389         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
3390 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
3391 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
3392         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
3393  
3394         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
3395 @@ -628,10 +583,6 @@ void __init mem_init(void)
3396                 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
3397                );
3398  
3399 -#ifdef CONFIG_X86_PAE
3400 -       if (!cpu_has_pae)
3401 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
3402 -#endif
3403         if (boot_cpu_data.wp_works_ok < 0)
3404                 test_wp_bit();
3405  
3406 @@ -724,6 +675,36 @@ void free_initmem(void)
3407  {
3408         unsigned long addr;
3409  
3410 +#ifdef CONFIG_PAX_KERNEXEC
3411 +       /* PaX: limit KERNEL_CS to actual size */
3412 +       unsigned long limit;
3413 +       int cpu;
3414 +       pgd_t *pgd;
3415 +       pud_t *pud;
3416 +       pmd_t *pmd;
3417 +
3418 +#ifdef CONFIG_MODULES
3419 +       limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
3420 +#else
3421 +       limit = (unsigned long)&_etext;
3422 +#endif
3423 +       limit = (limit - 1UL) >> PAGE_SHIFT;
3424 +
3425 +       for (cpu = 0; cpu < NR_CPUS; cpu++) {
3426 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
3427 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b = (get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
3428 +       }
3429 +
3430 +       /* PaX: make KERNEL_CS read-only */
3431 +       for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
3432 +               pgd = pgd_offset_k(addr);
3433 +               pud = pud_offset(pgd, addr);
3434 +               pmd = pmd_offset(pud, addr);
3435 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
3436 +       }
3437 +       flush_tlb_all();
3438 +#endif
3439 +
3440         addr = (unsigned long)(&__init_begin);
3441         for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
3442                 ClearPageReserved(virt_to_page(addr));
3443 diff -urNp linux-2.6.16.2/arch/i386/mm/mmap.c linux-2.6.16.2/arch/i386/mm/mmap.c
3444 --- linux-2.6.16.2/arch/i386/mm/mmap.c  2006-04-07 12:56:47.000000000 -0400
3445 +++ linux-2.6.16.2/arch/i386/mm/mmap.c  2006-04-09 21:23:54.000000000 -0400
3446 @@ -34,12 +34,18 @@
3447   * Leave an at least ~128 MB hole.
3448   */
3449  #define MIN_GAP (128*1024*1024)
3450 -#define MAX_GAP (TASK_SIZE/6*5)
3451 +#define MAX_GAP (task_size/6*5)
3452  
3453  static inline unsigned long mmap_base(struct mm_struct *mm)
3454  {
3455         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
3456         unsigned long random_factor = 0;
3457 +       unsigned long task_size = TASK_SIZE;
3458 +
3459 +#ifdef CONFIG_PAX_SEGMEXEC
3460 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
3461 +               task_size = SEGMEXEC_TASK_SIZE;
3462 +#endif
3463  
3464         if (current->flags & PF_RANDOMIZE)
3465                 random_factor = get_random_int() % (1024*1024);
3466 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
3467         else if (gap > MAX_GAP)
3468                 gap = MAX_GAP;
3469  
3470 -       return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
3471 +       return PAGE_ALIGN(task_size - gap - random_factor);
3472  }
3473  
3474  /*
3475 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
3476                         (current->personality & ADDR_COMPAT_LAYOUT) ||
3477                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
3478                 mm->mmap_base = TASK_UNMAPPED_BASE;
3479 +
3480 +#ifdef CONFIG_PAX_RANDMMAP
3481 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
3482 +                       mm->mmap_base += mm->delta_mmap;
3483 +#endif
3484 +
3485                 mm->get_unmapped_area = arch_get_unmapped_area;
3486                 mm->unmap_area = arch_unmap_area;
3487         } else {
3488                 mm->mmap_base = mmap_base(mm);
3489 +
3490 +#ifdef CONFIG_PAX_RANDMMAP
3491 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
3492 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3493 +#endif
3494 +
3495                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3496                 mm->unmap_area = arch_unmap_area_topdown;
3497         }
3498 diff -urNp linux-2.6.16.2/arch/i386/mm/pageattr.c linux-2.6.16.2/arch/i386/mm/pageattr.c
3499 --- linux-2.6.16.2/arch/i386/mm/pageattr.c      2006-04-07 12:56:47.000000000 -0400
3500 +++ linux-2.6.16.2/arch/i386/mm/pageattr.c      2006-04-09 21:23:54.000000000 -0400
3501 @@ -14,6 +14,7 @@
3502  #include <asm/tlbflush.h>
3503  #include <asm/pgalloc.h>
3504  #include <asm/sections.h>
3505 +#include <asm/desc.h>
3506  
3507  static DEFINE_SPINLOCK(cpa_lock);
3508  static struct list_head df_list = LIST_HEAD_INIT(df_list);
3509 @@ -77,7 +78,18 @@ static void set_pmd_pte(pte_t *kpte, uns
3510         struct page *page;
3511         unsigned long flags;
3512  
3513 +#ifdef CONFIG_PAX_KERNEXEC
3514 +       unsigned long cr0;
3515 +
3516 +       pax_open_kernel(cr0);
3517 +#endif
3518 +
3519         set_pte_atomic(kpte, pte);      /* change init_mm */
3520 +
3521 +#ifdef CONFIG_PAX_KERNEXEC
3522 +       pax_close_kernel(cr0);
3523 +#endif
3524 +
3525         if (PTRS_PER_PMD > 1)
3526                 return;
3527  
3528 @@ -104,7 +116,7 @@ static inline void revert_page(struct pa
3529         pte_t *linear;
3530  
3531         ref_prot =
3532 -       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
3533 +       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
3534                 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
3535  
3536         linear = (pte_t *)
3537 @@ -136,7 +148,7 @@ __change_page_attr(struct page *page, pg
3538                         struct page *split;
3539  
3540                         ref_prot =
3541 -                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
3542 +                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
3543                                 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
3544                         split = split_large_page(address, prot, ref_prot);
3545                         if (!split)
3546 diff -urNp linux-2.6.16.2/arch/i386/oprofile/backtrace.c linux-2.6.16.2/arch/i386/oprofile/backtrace.c
3547 --- linux-2.6.16.2/arch/i386/oprofile/backtrace.c       2006-04-07 12:56:47.000000000 -0400
3548 +++ linux-2.6.16.2/arch/i386/oprofile/backtrace.c       2006-04-09 21:23:54.000000000 -0400
3549 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
3550         head = (struct frame_head *)regs->ebp;
3551  #endif
3552  
3553 -       if (!user_mode_vm(regs)) {
3554 +       if (!user_mode(regs)) {
3555                 while (depth-- && valid_kernel_stack(head, regs))
3556                         head = dump_kernel_backtrace(head);
3557                 return;
3558 diff -urNp linux-2.6.16.2/arch/i386/power/cpu.c linux-2.6.16.2/arch/i386/power/cpu.c
3559 --- linux-2.6.16.2/arch/i386/power/cpu.c        2006-04-07 12:56:47.000000000 -0400
3560 +++ linux-2.6.16.2/arch/i386/power/cpu.c        2006-04-09 21:23:54.000000000 -0400
3561 @@ -62,7 +62,7 @@ static void do_fpu_end(void)
3562  static void fix_processor_context(void)
3563  {
3564         int cpu = smp_processor_id();
3565 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
3566 +       struct tss_struct * t = init_tss + cpu;
3567  
3568         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. */
3569  
3570 @@ -92,7 +92,7 @@ void __restore_processor_state(struct sa
3571         write_cr4(ctxt->cr4);
3572         write_cr3(ctxt->cr3);
3573         write_cr2(ctxt->cr2);
3574 -       write_cr2(ctxt->cr0);
3575 +       write_cr0(ctxt->cr0);
3576  
3577         /*
3578          * now restore the descriptor tables to their proper values
3579 diff -urNp linux-2.6.16.2/arch/ia64/ia32/binfmt_elf32.c linux-2.6.16.2/arch/ia64/ia32/binfmt_elf32.c
3580 --- linux-2.6.16.2/arch/ia64/ia32/binfmt_elf32.c        2006-04-07 12:56:47.000000000 -0400
3581 +++ linux-2.6.16.2/arch/ia64/ia32/binfmt_elf32.c        2006-04-09 21:23:54.000000000 -0400
3582 @@ -43,6 +43,17 @@ static void elf32_set_personality (void)
3583  
3584  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
3585  
3586 +#ifdef CONFIG_PAX_ASLR
3587 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
3588 +
3589 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
3590 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
3591 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
3592 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
3593 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
3594 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
3595 +#endif
3596 +
3597  /* Ugly but avoids duplication */
3598  #include "../../../fs/binfmt_elf.c"
3599  
3600 diff -urNp linux-2.6.16.2/arch/ia64/ia32/ia32priv.h linux-2.6.16.2/arch/ia64/ia32/ia32priv.h
3601 --- linux-2.6.16.2/arch/ia64/ia32/ia32priv.h    2006-04-07 12:56:47.000000000 -0400
3602 +++ linux-2.6.16.2/arch/ia64/ia32/ia32priv.h    2006-04-09 21:23:54.000000000 -0400
3603 @@ -305,7 +305,14 @@ struct old_linux32_dirent {
3604  #define ELF_DATA       ELFDATA2LSB
3605  #define ELF_ARCH       EM_386
3606  
3607 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
3608 +#ifdef CONFIG_PAX_RANDUSTACK
3609 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
3610 +#else
3611 +#define __IA32_DELTA_STACK     0UL
3612 +#endif
3613 +
3614 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
3615 +
3616  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
3617  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
3618  
3619 diff -urNp linux-2.6.16.2/arch/ia64/kernel/module.c linux-2.6.16.2/arch/ia64/kernel/module.c
3620 --- linux-2.6.16.2/arch/ia64/kernel/module.c    2006-04-07 12:56:47.000000000 -0400
3621 +++ linux-2.6.16.2/arch/ia64/kernel/module.c    2006-04-09 21:23:54.000000000 -0400
3622 @@ -322,7 +322,7 @@ module_alloc (unsigned long size)
3623  void
3624  module_free (struct module *mod, void *module_region)
3625  {
3626 -       if (mod->arch.init_unw_table && module_region == mod->module_init) {
3627 +       if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
3628                 unw_remove_unwind_table(mod->arch.init_unw_table);
3629                 mod->arch.init_unw_table = NULL;
3630         }
3631 @@ -500,15 +500,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
3632  }
3633  
3634  static inline int
3635 +in_init_rx (const struct module *mod, uint64_t addr)
3636 +{
3637 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
3638 +}
3639 +
3640 +static inline int
3641 +in_init_rw (const struct module *mod, uint64_t addr)
3642 +{
3643 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
3644 +}
3645 +
3646 +static inline int
3647  in_init (const struct module *mod, uint64_t addr)
3648  {
3649 -       return addr - (uint64_t) mod->module_init < mod->init_size;
3650 +       return in_init_rx(mod, value) || in_init_rw(mod, value);
3651 +}
3652 +
3653 +static inline int
3654 +in_core_rx (const struct module *mod, uint64_t addr)
3655 +{
3656 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
3657 +}
3658 +
3659 +static inline int
3660 +in_core_rw (const struct module *mod, uint64_t addr)
3661 +{
3662 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
3663  }
3664  
3665  static inline int
3666  in_core (const struct module *mod, uint64_t addr)
3667  {
3668 -       return addr - (uint64_t) mod->module_core < mod->core_size;
3669 +       return in_core_rx(mod, value) || in_core_rw(mod, value);
3670  }
3671  
3672  static inline int
3673 @@ -692,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_
3674                 break;
3675  
3676               case RV_BDREL:
3677 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
3678 +               if (in_init_rx(mod, val))
3679 +                       val -= (uint64_t) mod->module_init_rx;
3680 +               else if (in_init_rw(mod, val))
3681 +                       val -= (uint64_t) mod->module_init_rw;
3682 +               else if (in_core_rx(mod, val))
3683 +                       val -= (uint64_t) mod->module_core_rx;
3684 +               else if (in_core_rw(mod, val))
3685 +                       val -= (uint64_t) mod->module_core_rw;
3686                 break;
3687  
3688               case RV_LTV:
3689 @@ -826,15 +857,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
3690                  *     addresses have been selected...
3691                  */
3692                 uint64_t gp;
3693 -               if (mod->core_size > MAX_LTOFF)
3694 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
3695                         /*
3696                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
3697                          * at the end of the module.
3698                          */
3699 -                       gp = mod->core_size - MAX_LTOFF / 2;
3700 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
3701                 else
3702 -                       gp = mod->core_size / 2;
3703 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
3704 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
3705 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
3706                 mod->arch.gp = gp;
3707                 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
3708         }
3709 diff -urNp linux-2.6.16.2/arch/ia64/kernel/ptrace.c linux-2.6.16.2/arch/ia64/kernel/ptrace.c
3710 --- linux-2.6.16.2/arch/ia64/kernel/ptrace.c    2006-04-07 12:56:47.000000000 -0400
3711 +++ linux-2.6.16.2/arch/ia64/kernel/ptrace.c    2006-04-09 21:23:54.000000000 -0400
3712 @@ -18,6 +18,7 @@
3713  #include <linux/security.h>
3714  #include <linux/audit.h>
3715  #include <linux/signal.h>
3716 +#include <linux/grsecurity.h>
3717  
3718  #include <asm/pgtable.h>
3719  #include <asm/processor.h>
3720 @@ -1447,6 +1448,9 @@ sys_ptrace (long request, pid_t pid, uns
3721         if (pid == 1)           /* no messing around with init! */
3722                 goto out_tsk;
3723  
3724 +       if (gr_handle_ptrace(child, request))
3725 +               goto out_tsk;
3726 +
3727         if (request == PTRACE_ATTACH) {
3728                 ret = ptrace_attach(child);
3729                 goto out_tsk;
3730 diff -urNp linux-2.6.16.2/arch/ia64/kernel/sys_ia64.c linux-2.6.16.2/arch/ia64/kernel/sys_ia64.c
3731 --- linux-2.6.16.2/arch/ia64/kernel/sys_ia64.c  2006-04-07 12:56:47.000000000 -0400
3732 +++ linux-2.6.16.2/arch/ia64/kernel/sys_ia64.c  2006-04-09 21:23:54.000000000 -0400
3733 @@ -38,6 +38,13 @@ arch_get_unmapped_area (struct file *fil
3734         if (REGION_NUMBER(addr) == RGN_HPAGE)
3735                 addr = 0;
3736  #endif
3737 +
3738 +#ifdef CONFIG_PAX_RANDMMAP
3739 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
3740 +               addr = mm->free_area_cache;
3741 +       else
3742 +#endif
3743 +
3744         if (!addr)
3745                 addr = mm->free_area_cache;
3746  
3747 @@ -56,9 +63,9 @@ arch_get_unmapped_area (struct file *fil
3748         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3749                 /* At this point:  (!vma || addr < vma->vm_end). */
3750                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
3751 -                       if (start_addr != TASK_UNMAPPED_BASE) {
3752 +                       if (start_addr != mm->mmap_base) {
3753                                 /* Start a new search --- just in case we missed some holes.  */
3754 -                               addr = TASK_UNMAPPED_BASE;
3755 +                               addr = mm->mmap_base;
3756                                 goto full_search;
3757                         }
3758                         return -ENOMEM;
3759 diff -urNp linux-2.6.16.2/arch/ia64/mm/fault.c linux-2.6.16.2/arch/ia64/mm/fault.c
3760 --- linux-2.6.16.2/arch/ia64/mm/fault.c 2006-04-07 12:56:47.000000000 -0400
3761 +++ linux-2.6.16.2/arch/ia64/mm/fault.c 2006-04-09 21:23:54.000000000 -0400
3762 @@ -10,6 +10,7 @@
3763  #include <linux/smp_lock.h>
3764  #include <linux/interrupt.h>
3765  #include <linux/kprobes.h>
3766 +#include <linux/binfmts.h>
3767  
3768  #include <asm/pgtable.h>
3769  #include <asm/processor.h>
3770 @@ -51,6 +52,23 @@ mapped_kernel_page_is_present (unsigned 
3771         return pte_present(pte);
3772  }
3773  
3774 +#ifdef CONFIG_PAX_PAGEEXEC
3775 +void pax_report_insns(void *pc, void *sp)
3776 +{
3777 +       unsigned long i;
3778 +
3779 +       printk(KERN_ERR "PAX: bytes at PC: ");
3780 +       for (i = 0; i < 8; i++) {
3781 +               unsigned int c;
3782 +               if (get_user(c, (unsigned int*)pc+i))
3783 +                       printk("???????? ");
3784 +               else
3785 +                       printk("%08x ", c);
3786 +       }
3787 +       printk("\n");
3788 +}
3789 +#endif
3790 +
3791  void __kprobes
3792  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
3793  {
3794 @@ -113,9 +131,23 @@ ia64_do_page_fault (unsigned long addres
3795                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
3796                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
3797  
3798 -       if ((vma->vm_flags & mask) != mask)
3799 +       if ((vma->vm_flags & mask) != mask) {
3800 +
3801 +#ifdef CONFIG_PAX_PAGEEXEC
3802 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
3803 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
3804 +                               goto bad_area;
3805 +
3806 +                       up_read(&mm->mmap_sem);
3807 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
3808 +                       do_exit(SIGKILL);
3809 +               }
3810 +#endif
3811 +
3812                 goto bad_area;
3813  
3814 +       }
3815 +
3816    survive:
3817         /*
3818          * If for any reason at all we couldn't handle the fault, make
3819 diff -urNp linux-2.6.16.2/arch/ia64/mm/init.c linux-2.6.16.2/arch/ia64/mm/init.c
3820 --- linux-2.6.16.2/arch/ia64/mm/init.c  2006-04-07 12:56:47.000000000 -0400
3821 +++ linux-2.6.16.2/arch/ia64/mm/init.c  2006-04-09 21:23:54.000000000 -0400
3822 @@ -20,8 +20,8 @@
3823  #include <linux/swap.h>
3824  #include <linux/proc_fs.h>
3825  #include <linux/bitops.h>
3826 +#include <linux/a.out.h>
3827  
3828 -#include <asm/a.out.h>
3829  #include <asm/dma.h>
3830  #include <asm/ia32.h>
3831  #include <asm/io.h>
3832 diff -urNp linux-2.6.16.2/arch/mips/kernel/binfmt_elfn32.c linux-2.6.16.2/arch/mips/kernel/binfmt_elfn32.c
3833 --- linux-2.6.16.2/arch/mips/kernel/binfmt_elfn32.c     2006-04-07 12:56:47.000000000 -0400
3834 +++ linux-2.6.16.2/arch/mips/kernel/binfmt_elfn32.c     2006-04-09 21:23:54.000000000 -0400
3835 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
3836  #undef ELF_ET_DYN_BASE
3837  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
3838  
3839 +#ifdef CONFIG_PAX_ASLR
3840 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
3841 +
3842 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
3843 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3844 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
3845 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3846 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
3847 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3848 +#endif
3849 +
3850  #include <asm/processor.h>
3851  #include <linux/module.h>
3852  #include <linux/elfcore.h>
3853 diff -urNp linux-2.6.16.2/arch/mips/kernel/binfmt_elfo32.c linux-2.6.16.2/arch/mips/kernel/binfmt_elfo32.c
3854 --- linux-2.6.16.2/arch/mips/kernel/binfmt_elfo32.c     2006-04-07 12:56:47.000000000 -0400
3855 +++ linux-2.6.16.2/arch/mips/kernel/binfmt_elfo32.c     2006-04-09 21:23:54.000000000 -0400
3856 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
3857  #undef ELF_ET_DYN_BASE
3858  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
3859  
3860 +#ifdef CONFIG_PAX_ASLR
3861 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
3862 +
3863 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
3864 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3865 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
3866 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3867 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
3868 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
3869 +#endif
3870 +
3871  #include <asm/processor.h>
3872  #include <linux/module.h>
3873  #include <linux/elfcore.h>
3874 diff -urNp linux-2.6.16.2/arch/mips/kernel/syscall.c linux-2.6.16.2/arch/mips/kernel/syscall.c
3875 --- linux-2.6.16.2/arch/mips/kernel/syscall.c   2006-04-07 12:56:47.000000000 -0400
3876 +++ linux-2.6.16.2/arch/mips/kernel/syscall.c   2006-04-09 21:23:54.000000000 -0400
3877 @@ -89,6 +89,11 @@ unsigned long arch_get_unmapped_area(str
3878         do_color_align = 0;
3879         if (filp || (flags & MAP_SHARED))
3880                 do_color_align = 1;
3881 +
3882 +#ifdef CONFIG_PAX_RANDMMAP
3883 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3884 +#endif
3885 +
3886         if (addr) {
3887                 if (do_color_align)
3888                         addr = COLOUR_ALIGN(addr, pgoff);
3889 @@ -99,7 +104,7 @@ unsigned long arch_get_unmapped_area(str
3890                     (!vmm || addr + len <= vmm->vm_start))
3891                         return addr;
3892         }
3893 -       addr = TASK_UNMAPPED_BASE;
3894 +       addr = current->mm->mmap_base;
3895         if (do_color_align)
3896                 addr = COLOUR_ALIGN(addr, pgoff);
3897         else
3898 diff -urNp linux-2.6.16.2/arch/mips/mm/fault.c linux-2.6.16.2/arch/mips/mm/fault.c
3899 --- linux-2.6.16.2/arch/mips/mm/fault.c 2006-04-07 12:56:47.000000000 -0400
3900 +++ linux-2.6.16.2/arch/mips/mm/fault.c 2006-04-09 21:23:54.000000000 -0400
3901 @@ -27,6 +27,23 @@
3902  #include <asm/ptrace.h>
3903  #include <asm/highmem.h>               /* For VMALLOC_END */
3904  
3905 +#ifdef CONFIG_PAX_PAGEEXEC
3906 +void pax_report_insns(void *pc)
3907 +{
3908 +       unsigned long i;
3909 +
3910 +       printk(KERN_ERR "PAX: bytes at PC: ");
3911 +       for (i = 0; i < 5; i++) {
3912 +               unsigned int c;
3913 +               if (get_user(c, (unsigned int*)pc+i))
3914 +                       printk("???????? ");
3915 +               else
3916 +                       printk("%08x ", c);
3917 +       }
3918 +       printk("\n");
3919 +}
3920 +#endif
3921 +
3922  /*
3923   * This routine handles page faults.  It determines the address,
3924   * and the problem, and then passes it off to one of the appropriate
3925 diff -urNp linux-2.6.16.2/arch/parisc/kernel/module.c linux-2.6.16.2/arch/parisc/kernel/module.c
3926 --- linux-2.6.16.2/arch/parisc/kernel/module.c  2006-04-07 12:56:47.000000000 -0400
3927 +++ linux-2.6.16.2/arch/parisc/kernel/module.c  2006-04-09 21:23:54.000000000 -0400
3928 @@ -72,16 +72,38 @@
3929  
3930  /* three functions to determine where in the module core
3931   * or init pieces the location is */
3932 +static inline int is_init_rx(struct module *me, void *loc)
3933 +{
3934 +       return (loc >= me->module_init_rx &&
3935 +               loc < (me->module_init_rx + me->init_size_rx));
3936 +}
3937 +
3938 +static inline int is_init_rw(struct module *me, void *loc)
3939 +{
3940 +       return (loc >= me->module_init_rw &&
3941 +               loc < (me->module_init_rw + me->init_size_rw));
3942 +}
3943 +
3944  static inline int is_init(struct module *me, void *loc)
3945  {
3946 -       return (loc >= me->module_init &&
3947 -               loc <= (me->module_init + me->init_size));
3948 +       return is_init_rx(me, loc) || is_init_rw(me, loc);
3949 +}
3950 +
3951 +static inline int is_core_rx(struct module *me, void *loc)
3952 +{
3953 +       return (loc >= me->module_core_rx &&
3954 +               loc < (me->module_core_rx + me->core_size_rx));
3955 +}
3956 +
3957 +static inline int is_core_rw(struct module *me, void *loc)
3958 +{
3959 +       return (loc >= me->module_core_rw &&
3960 +               loc < (me->module_core_rw + me->core_size_rw));
3961  }
3962  
3963  static inline int is_core(struct module *me, void *loc)
3964  {
3965 -       return (loc >= me->module_core &&
3966 -               loc <= (me->module_core + me->core_size));
3967 +       return is_core_rx(me, loc) || is_core_rw(me, loc);
3968  }
3969  
3970  static inline int is_local(struct module *me, void *loc)
3971 @@ -289,21 +311,21 @@ int module_frob_arch_sections(CONST Elf_
3972         }
3973  
3974         /* align things a bit */
3975 -       me->core_size = ALIGN(me->core_size, 16);
3976 -       me->arch.got_offset = me->core_size;
3977 -       me->core_size += gots * sizeof(struct got_entry);
3978 -
3979 -       me->core_size = ALIGN(me->core_size, 16);
3980 -       me->arch.fdesc_offset = me->core_size;
3981 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
3982 -
3983 -       me->core_size = ALIGN(me->core_size, 16);
3984 -       me->arch.stub_offset = me->core_size;
3985 -       me->core_size += stubs * sizeof(struct stub_entry);
3986 -
3987 -       me->init_size = ALIGN(me->init_size, 16);
3988 -       me->arch.init_stub_offset = me->init_size;
3989 -       me->init_size += init_stubs * sizeof(struct stub_entry);
3990 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
3991 +       me->arch.got_offset = me->core_size_rw;
3992 +       me->core_size_rw += gots * sizeof(struct got_entry);
3993 +
3994 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
3995 +       me->arch.fdesc_offset = me->core_size_rw;
3996 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
3997 +
3998 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
3999 +       me->arch.stub_offset = me->core_size_rx;
4000 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
4001 +
4002 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
4003 +       me->arch.init_stub_offset = me->init_size_rx;
4004 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
4005  
4006         me->arch.got_max = gots;
4007         me->arch.fdesc_max = fdescs;
4008 @@ -323,7 +345,7 @@ static Elf64_Word get_got(struct module 
4009  
4010         BUG_ON(value == 0);
4011  
4012 -       got = me->module_core + me->arch.got_offset;
4013 +       got = me->module_core_rw + me->arch.got_offset;
4014         for (i = 0; got[i].addr; i++)
4015                 if (got[i].addr == value)
4016                         goto out;
4017 @@ -341,7 +363,7 @@ static Elf64_Word get_got(struct module 
4018  #ifdef __LP64__
4019  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
4020  {
4021 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
4022 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
4023  
4024         if (!value) {
4025                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
4026 @@ -359,7 +381,7 @@ static Elf_Addr get_fdesc(struct module 
4027  
4028         /* Create new one */
4029         fdesc->addr = value;
4030 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
4031 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
4032         return (Elf_Addr)fdesc;
4033  }
4034  #endif /* __LP64__ */
4035 @@ -373,12 +395,12 @@ static Elf_Addr get_stub(struct module *
4036         if(init_section) {
4037                 i = me->arch.init_stub_count++;
4038                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
4039 -               stub = me->module_init + me->arch.init_stub_offset + 
4040 +               stub = me->module_init_rx + me->arch.init_stub_offset + 
4041                         i * sizeof(struct stub_entry);
4042         } else {
4043                 i = me->arch.stub_count++;
4044                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
4045 -               stub = me->module_core + me->arch.stub_offset + 
4046 +               stub = me->module_core_rx + me->arch.stub_offset + 
4047                         i * sizeof(struct stub_entry);
4048         }
4049  
4050 @@ -721,7 +743,7 @@ register_unwind_table(struct module *me,
4051  
4052         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
4053         end = table + sechdrs[me->arch.unwind_section].sh_size;
4054 -       gp = (Elf_Addr)me->module_core + me->arch.got_offset;
4055 +       gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
4056  
4057         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
4058                me->arch.unwind_section, table, end, gp);
4059 diff -urNp linux-2.6.16.2/arch/parisc/kernel/ptrace.c linux-2.6.16.2/arch/parisc/kernel/ptrace.c
4060 --- linux-2.6.16.2/arch/parisc/kernel/ptrace.c  2006-04-07 12:56:47.000000000 -0400
4061 +++ linux-2.6.16.2/arch/parisc/kernel/ptrace.c  2006-04-09 21:23:54.000000000 -0400
4062 @@ -18,6 +18,7 @@
4063  #include <linux/security.h>
4064  #include <linux/compat.h>
4065  #include <linux/signal.h>
4066 +#include <linux/grsecurity.h>
4067  
4068  #include <asm/uaccess.h>
4069  #include <asm/pgtable.h>
4070 diff -urNp linux-2.6.16.2/arch/parisc/kernel/sys_parisc.c linux-2.6.16.2/arch/parisc/kernel/sys_parisc.c
4071 --- linux-2.6.16.2/arch/parisc/kernel/sys_parisc.c      2006-04-07 12:56:47.000000000 -0400
4072 +++ linux-2.6.16.2/arch/parisc/kernel/sys_parisc.c      2006-04-09 21:23:54.000000000 -0400
4073 @@ -105,7 +105,7 @@ unsigned long arch_get_unmapped_area(str
4074         if (len > TASK_SIZE)
4075                 return -ENOMEM;
4076         if (!addr)
4077 -               addr = TASK_UNMAPPED_BASE;
4078 +               addr = current->mm->mmap_base;
4079  
4080         if (filp) {
4081                 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
4082 diff -urNp linux-2.6.16.2/arch/parisc/kernel/traps.c linux-2.6.16.2/arch/parisc/kernel/traps.c
4083 --- linux-2.6.16.2/arch/parisc/kernel/traps.c   2006-04-07 12:56:47.000000000 -0400
4084 +++ linux-2.6.16.2/arch/parisc/kernel/traps.c   2006-04-09 21:23:54.000000000 -0400
4085 @@ -711,9 +711,7 @@ void handle_interruption(int code, struc
4086  
4087                         down_read(&current->mm->mmap_sem);
4088                         vma = find_vma(current->mm,regs->iaoq[0]);
4089 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
4090 -                               && (vma->vm_flags & VM_EXEC)) {
4091 -
4092 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
4093                                 fault_address = regs->iaoq[0];
4094                                 fault_space = regs->iasq[0];
4095  
4096 diff -urNp linux-2.6.16.2/arch/parisc/mm/fault.c linux-2.6.16.2/arch/parisc/mm/fault.c
4097 --- linux-2.6.16.2/arch/parisc/mm/fault.c       2006-04-07 12:56:47.000000000 -0400
4098 +++ linux-2.6.16.2/arch/parisc/mm/fault.c       2006-04-09 21:23:54.000000000 -0400
4099 @@ -16,6 +16,8 @@
4100  #include <linux/sched.h>
4101  #include <linux/interrupt.h>
4102  #include <linux/module.h>
4103 +#include <linux/unistd.h>
4104 +#include <linux/binfmts.h>
4105  
4106  #include <asm/uaccess.h>
4107  #include <asm/traps.h>
4108 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
4109  static unsigned long
4110  parisc_acctyp(unsigned long code, unsigned int inst)
4111  {
4112 -       if (code == 6 || code == 16)
4113 +       if (code == 6 || code == 7 || code == 16)
4114             return VM_EXEC;
4115  
4116         switch (inst & 0xf0000000) {
4117 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
4118                         }
4119  #endif
4120  
4121 +#ifdef CONFIG_PAX_PAGEEXEC
4122 +/*
4123 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
4124 + *
4125 + * returns 1 when task should be killed
4126 + *         2 when rt_sigreturn trampoline was detected
4127 + *         3 when unpatched PLT trampoline was detected
4128 + */
4129 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4130 +{
4131 +
4132 +#ifdef CONFIG_PAX_EMUPLT
4133 +       int err;
4134 +
4135 +       do { /* PaX: unpatched PLT emulation */
4136 +               unsigned int bl, depwi;
4137 +
4138 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
4139 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
4140 +
4141 +               if (err)
4142 +                       break;
4143 +
4144 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
4145 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
4146 +
4147 +                       err = get_user(ldw, (unsigned int*)addr);
4148 +                       err |= get_user(bv, (unsigned int*)(addr+4));
4149 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
4150 +
4151 +                       if (err)
4152 +                               break;
4153 +
4154 +                       if (ldw == 0x0E801096U &&
4155 +                           bv == 0xEAC0C000U &&
4156 +                           ldw2 == 0x0E881095U)
4157 +                       {
4158 +                               unsigned int resolver, map;
4159 +
4160 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
4161 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
4162 +                               if (err)
4163 +                                       break;
4164 +
4165 +                               regs->gr[20] = instruction_pointer(regs)+8;
4166 +                               regs->gr[21] = map;
4167 +                               regs->gr[22] = resolver;
4168 +                               regs->iaoq[0] = resolver | 3UL;
4169 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
4170 +                               return 3;
4171 +                       }
4172 +               }
4173 +       } while (0);
4174 +#endif
4175 +
4176 +#ifdef CONFIG_PAX_EMUTRAMP
4177 +
4178 +#ifndef CONFIG_PAX_EMUSIGRT
4179 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
4180 +               return 1;
4181 +#endif
4182 +
4183 +       do { /* PaX: rt_sigreturn emulation */
4184 +               unsigned int ldi1, ldi2, bel, nop;
4185 +
4186 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
4187 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
4188 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
4189 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
4190 +
4191 +               if (err)
4192 +                       break;
4193 +
4194 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
4195 +                   ldi2 == 0x3414015AU &&
4196 +                   bel == 0xE4008200U &&
4197 +                   nop == 0x08000240U)
4198 +               {
4199 +                       regs->gr[25] = (ldi1 & 2) >> 1;
4200 +                       regs->gr[20] = __NR_rt_sigreturn;
4201 +                       regs->gr[31] = regs->iaoq[1] + 16;
4202 +                       regs->sr[0] = regs->iasq[1];
4203 +                       regs->iaoq[0] = 0x100UL;
4204 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
4205 +                       regs->iasq[0] = regs->sr[2];
4206 +                       regs->iasq[1] = regs->sr[2];
4207 +                       return 2;
4208 +               }
4209 +       } while (0);
4210 +#endif
4211 +
4212 +       return 1;
4213 +}
4214 +
4215 +void pax_report_insns(void *pc, void *sp)
4216 +{
4217 +       unsigned long i;
4218 +
4219 +       printk(KERN_ERR "PAX: bytes at PC: ");
4220 +       for (i = 0; i < 5; i++) {
4221 +               unsigned int c;
4222 +               if (get_user(c, (unsigned int*)pc+i))
4223 +                       printk("???????? ");
4224 +               else
4225 +                       printk("%08x ", c);
4226 +       }
4227 +       printk("\n");
4228 +}
4229 +#endif
4230 +
4231  void do_page_fault(struct pt_regs *regs, unsigned long code,
4232                               unsigned long address)
4233  {
4234 @@ -168,8 +280,33 @@ good_area:
4235  
4236         acc_type = parisc_acctyp(code,regs->iir);
4237  
4238 -       if ((vma->vm_flags & acc_type) != acc_type)
4239 +       if ((vma->vm_flags & acc_type) != acc_type) {
4240 +
4241 +#ifdef CONFIG_PAX_PAGEEXEC
4242 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
4243 +                   (address & ~3UL) == instruction_pointer(regs))
4244 +               {
4245 +                       up_read(&mm->mmap_sem);
4246 +                       switch(pax_handle_fetch_fault(regs)) {
4247 +
4248 +#ifdef CONFIG_PAX_EMUPLT
4249 +                       case 3:
4250 +                               return;
4251 +#endif
4252 +
4253 +#ifdef CONFIG_PAX_EMUTRAMP
4254 +                       case 2:
4255 +                               return;
4256 +#endif
4257 +
4258 +                       }
4259 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
4260 +                       do_exit(SIGKILL);
4261 +               }
4262 +#endif
4263 +
4264                 goto bad_area;
4265 +       }
4266  
4267         /*
4268          * If for any reason at all we couldn't handle the fault, make
4269 diff -urNp linux-2.6.16.2/arch/powerpc/mm/fault.c linux-2.6.16.2/arch/powerpc/mm/fault.c
4270 --- linux-2.6.16.2/arch/powerpc/mm/fault.c      2006-04-07 12:56:47.000000000 -0400
4271 +++ linux-2.6.16.2/arch/powerpc/mm/fault.c      2006-04-09 21:23:54.000000000 -0400
4272 @@ -31,6 +31,7 @@
4273  #include <linux/highmem.h>
4274  #include <linux/module.h>
4275  #include <linux/kprobes.h>
4276 +#include <linux/binfmts.h>
4277  
4278  #include <asm/page.h>
4279  #include <asm/pgtable.h>
4280 @@ -105,6 +106,38 @@ static void do_dabr(struct pt_regs *regs
4281  }
4282  #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
4283  
4284 +#ifdef CONFIG_PAX_PAGEEXEC
4285 +/*
4286 + * PaX: decide what to do with offenders (regs->nip = fault address)
4287 + *
4288 + * returns 1 when task should be killed
4289 + */
4290 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4291 +{
4292 +
4293 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
4294 +       int err;
4295 +#endif
4296 +
4297 +       return 1;
4298 +}
4299 +
4300 +void pax_report_insns(void *pc, void *sp)
4301 +{
4302 +       unsigned long i;
4303 +
4304 +       printk(KERN_ERR "PAX: bytes at PC: ");
4305 +       for (i = 0; i < 5; i++) {
4306 +               unsigned int c;
4307 +               if (get_user(c, (unsigned int*)pc+i))
4308 +                       printk("???????? ");
4309 +               else
4310 +                       printk("%08x ", c);
4311 +       }
4312 +       printk("\n");
4313 +}
4314 +#endif
4315 +
4316  /*
4317   * For 600- and 800-family processors, the error_code parameter is DSISR
4318   * for a data fault, SRR1 for an instruction fault. For 400-family processors
4319 @@ -333,6 +366,19 @@ bad_area:
4320  bad_area_nosemaphore:
4321         /* User mode accesses cause a SIGSEGV */
4322         if (user_mode(regs)) {
4323 +
4324 +#ifdef CONFIG_PAX_PAGEEXEC
4325 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
4326 +                       if (is_exec && (error_code & DSISR_PROTFAULT)) {
4327 +                               switch (pax_handle_fetch_fault(regs)) {
4328 +                               }
4329 +
4330 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
4331 +                               do_exit(SIGKILL);
4332 +                       }
4333 +               }
4334 +#endif
4335 +
4336                 _exception(SIGSEGV, regs, code, address);
4337                 return 0;
4338         }
4339 diff -urNp linux-2.6.16.2/arch/powerpc/mm/mmap.c linux-2.6.16.2/arch/powerpc/mm/mmap.c
4340 --- linux-2.6.16.2/arch/powerpc/mm/mmap.c       2006-04-07 12:56:47.000000000 -0400
4341 +++ linux-2.6.16.2/arch/powerpc/mm/mmap.c       2006-04-09 21:23:54.000000000 -0400
4342 @@ -76,10 +76,22 @@ void arch_pick_mmap_layout(struct mm_str
4343          */
4344         if (mmap_is_legacy()) {
4345                 mm->mmap_base = TASK_UNMAPPED_BASE;
4346 +
4347 +#ifdef CONFIG_PAX_RANDMMAP
4348 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
4349 +                       mm->mmap_base += mm->delta_mmap;
4350 +#endif
4351 +
4352                 mm->get_unmapped_area = arch_get_unmapped_area;
4353                 mm->unmap_area = arch_unmap_area;
4354         } else {
4355                 mm->mmap_base = mmap_base();
4356 +
4357 +#ifdef CONFIG_PAX_RANDMMAP
4358 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
4359 +                       mm->mmap_base -= mm->delta_mmap;
4360 +#endif
4361 +
4362                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4363                 mm->unmap_area = arch_unmap_area_topdown;
4364         }
4365 diff -urNp linux-2.6.16.2/arch/ppc/kernel/module.c linux-2.6.16.2/arch/ppc/kernel/module.c
4366 --- linux-2.6.16.2/arch/ppc/kernel/module.c     2006-04-07 12:56:47.000000000 -0400
4367 +++ linux-2.6.16.2/arch/ppc/kernel/module.c     2006-04-09 21:23:54.000000000 -0400
4368 @@ -164,8 +164,8 @@ static uint32_t do_plt_call(void *locati
4369  
4370         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
4371         /* Init, or core PLT? */
4372 -       if (location >= mod->module_core
4373 -           && location < mod->module_core + mod->core_size)
4374 +       if (location >= mod->module_core_rx
4375 +           && location < mod->module_core_rx + mod->core_size_rx)
4376                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
4377         else
4378                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
4379 diff -urNp linux-2.6.16.2/arch/ppc/mm/fault.c linux-2.6.16.2/arch/ppc/mm/fault.c
4380 --- linux-2.6.16.2/arch/ppc/mm/fault.c  2006-04-07 12:56:47.000000000 -0400
4381 +++ linux-2.6.16.2/arch/ppc/mm/fault.c  2006-04-09 21:23:54.000000000 -0400
4382 @@ -28,6 +28,11 @@
4383  #include <linux/interrupt.h>
4384  #include <linux/highmem.h>
4385  #include <linux/module.h>
4386 +#include <linux/slab.h>
4387 +#include <linux/pagemap.h>
4388 +#include <linux/compiler.h>
4389 +#include <linux/binfmts.h>
4390 +#include <linux/unistd.h>
4391  
4392  #include <asm/page.h>
4393  #include <asm/pgtable.h>
4394 @@ -51,6 +56,364 @@ unsigned long pte_misses;   /* updated by 
4395  unsigned long pte_errors;      /* updated by do_page_fault() */
4396  unsigned int probingmem;
4397  
4398 +#ifdef CONFIG_PAX_EMUSIGRT
4399 +void pax_syscall_close(struct vm_area_struct * vma)
4400 +{
4401 +       vma->vm_mm->call_syscall = 0UL;
4402 +}
4403 +
4404 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
4405 +{
4406 +       struct page* page;
4407 +       unsigned int *kaddr;
4408 +
4409 +       page = alloc_page(GFP_HIGHUSER);
4410 +       if (!page)
4411 +               return NOPAGE_OOM;
4412 +
4413 +       kaddr = kmap(page);
4414 +       memset(kaddr, 0, PAGE_SIZE);
4415 +       kaddr[0] = 0x44000002U; /* sc */
4416 +       __flush_dcache_icache(kaddr);
4417 +       kunmap(page);
4418 +       if (type)
4419 +               *type = VM_FAULT_MAJOR;
4420 +       return page;
4421 +}
4422 +
4423 +static struct vm_operations_struct pax_vm_ops = {
4424 +       .close = pax_syscall_close,
4425 +       .nopage = pax_syscall_nopage,
4426 +};
4427 +
4428 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4429 +{
4430 +       int ret;
4431 +
4432 +       memset(vma, 0, sizeof(*vma));
4433 +       vma->vm_mm = current->mm;
4434 +       vma->vm_start = addr;
4435 +       vma->vm_end = addr + PAGE_SIZE;
4436 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4437 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
4438 +       vma->vm_ops = &pax_vm_ops;
4439 +
4440 +       ret = insert_vm_struct(current->mm, vma);
4441 +       if (ret)
4442 +               return ret;
4443 +
4444 +       ++current->mm->total_vm;
4445 +       return 0;
4446 +}
4447 +#endif
4448 +
4449 +#ifdef CONFIG_PAX_PAGEEXEC
4450 +/*
4451 + * PaX: decide what to do with offenders (regs->nip = fault address)
4452 + *
4453 + * returns 1 when task should be killed
4454 + *         2 when patched GOT trampoline was detected
4455 + *         3 when patched PLT trampoline was detected
4456 + *         4 when unpatched PLT trampoline was detected
4457 + *         5 when sigreturn trampoline was detected
4458 + *         7 when rt_sigreturn trampoline was detected
4459 + */
4460 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4461 +{
4462 +
4463 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
4464 +       int err;
4465 +#endif
4466 +
4467 +#ifdef CONFIG_PAX_EMUPLT
4468 +       do { /* PaX: patched GOT emulation */
4469 +               unsigned int blrl;
4470 +
4471 +               err = get_user(blrl, (unsigned int*)regs->nip);
4472 +
4473 +               if (!err && blrl == 0x4E800021U) {
4474 +                       unsigned long temp = regs->nip;
4475 +
4476 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
4477 +                       regs->link = temp + 4UL;
4478 +                       return 2;
4479 +               }
4480 +       } while (0);
4481 +
4482 +       do { /* PaX: patched PLT emulation #1 */
4483 +               unsigned int b;
4484 +
4485 +               err = get_user(b, (unsigned int *)regs->nip);
4486 +
4487 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
4488 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
4489 +                       return 3;
4490 +               }
4491 +       } while (0);
4492 +
4493 +       do { /* PaX: unpatched PLT emulation #1 */
4494 +               unsigned int li, b;
4495 +
4496 +               err = get_user(li, (unsigned int *)regs->nip);
4497 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
4498 +
4499 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
4500 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
4501 +                       unsigned long addr = b | 0xFC000000UL;
4502 +
4503 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
4504 +                       err = get_user(rlwinm, (unsigned int*)addr);
4505 +                       err |= get_user(add, (unsigned int*)(addr+4));
4506 +                       err |= get_user(li2, (unsigned int*)(addr+8));
4507 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
4508 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
4509 +                       err |= get_user(li3, (unsigned int*)(addr+20));
4510 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
4511 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
4512 +
4513 +                       if (err)
4514 +                               break;
4515 +
4516 +                       if (rlwinm == 0x556C083CU &&
4517 +                           add == 0x7D6C5A14U &&
4518 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
4519 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
4520 +                           mtctr == 0x7D8903A6U &&
4521 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
4522 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
4523 +                           bctr == 0x4E800420U)
4524 +                       {
4525 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4526 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4527 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
4528 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4529 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
4530 +                               regs->nip = regs->ctr;
4531 +                               return 4;
4532 +                       }
4533 +               }
4534 +       } while (0);
4535 +
4536 +#if 0
4537 +       do { /* PaX: unpatched PLT emulation #2 */
4538 +               unsigned int lis, lwzu, b, bctr;
4539 +
4540 +               err = get_user(lis, (unsigned int *)regs->nip);
4541 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
4542 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
4543 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
4544 +
4545 +               if (err)
4546 +                       break;
4547 +
4548 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
4549 +                   (lwzu & 0xU) == 0xU &&
4550 +                   (b & 0xFC000003U) == 0x48000000U &&
4551 +                   bctr == 0x4E800420U)
4552 +               {
4553 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
4554 +                       unsigned long addr = b | 0xFC000000UL;
4555 +
4556 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
4557 +                       err = get_user(addis, (unsigned int*)addr);
4558 +                       err |= get_user(addi, (unsigned int*)(addr+4));
4559 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
4560 +                       err |= get_user(add, (unsigned int*)(addr+12));
4561 +                       err |= get_user(li2, (unsigned int*)(addr+16));
4562 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
4563 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
4564 +                       err |= get_user(li3, (unsigned int*)(addr+28));
4565 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
4566 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
4567 +
4568 +                       if (err)
4569 +                               break;
4570 +
4571 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
4572 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
4573 +                           rlwinm == 0x556C083CU &&
4574 +                           add == 0x7D6C5A14U &&
4575 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
4576 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
4577 +                           mtctr == 0x7D8903A6U &&
4578 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
4579 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
4580 +                           bctr == 0x4E800420U)
4581 +                       {
4582 +                               regs->gpr[PT_R11] = 
4583 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4584 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4585 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
4586 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4587 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
4588 +                               regs->nip = regs->ctr;
4589 +                               return 4;
4590 +                       }
4591 +               }
4592 +       } while (0);
4593 +#endif
4594 +
4595 +       do { /* PaX: unpatched PLT emulation #3 */
4596 +               unsigned int li, b;
4597 +
4598 +               err = get_user(li, (unsigned int *)regs->nip);
4599 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
4600 +
4601 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
4602 +                       unsigned int addis, lwz, mtctr, bctr;
4603 +                       unsigned long addr = b | 0xFC000000UL;
4604 +
4605 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
4606 +                       err = get_user(addis, (unsigned int*)addr);
4607 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
4608 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
4609 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
4610 +
4611 +                       if (err)
4612 +                               break;
4613 +
4614 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
4615 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
4616 +                           mtctr == 0x7D6903A6U &&
4617 +                           bctr == 0x4E800420U)
4618 +                       {
4619 +                               unsigned int r11;
4620 +
4621 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4622 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
4623 +
4624 +                               err = get_user(r11, (unsigned int*)addr);
4625 +                               if (err)
4626 +                                       break;
4627 +
4628 +                               regs->gpr[PT_R11] = r11;
4629 +                               regs->ctr = r11;
4630 +                               regs->nip = r11;
4631 +                               return 4;
4632 +                       }
4633 +               }
4634 +       } while (0);
4635 +#endif
4636 +
4637 +#ifdef CONFIG_PAX_EMUSIGRT
4638 +       do { /* PaX: sigreturn emulation */
4639 +               unsigned int li, sc;
4640 +
4641 +               err = get_user(li, (unsigned int *)regs->nip);
4642 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
4643 +
4644 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
4645 +                       struct vm_area_struct *vma;
4646 +                       unsigned long call_syscall;
4647 +
4648 +                       down_read(&current->mm->mmap_sem);
4649 +                       call_syscall = current->mm->call_syscall;
4650 +                       up_read(&current->mm->mmap_sem);
4651 +                       if (likely(call_syscall))
4652 +                               goto emulate;
4653 +
4654 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4655 +
4656 +                       down_write(&current->mm->mmap_sem);
4657 +                       if (current->mm->call_syscall) {
4658 +                               call_syscall = current->mm->call_syscall;
4659 +                               up_write(&current->mm->mmap_sem);
4660 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
4661 +                               goto emulate;
4662 +                       }
4663 +
4664 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4665 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
4666 +                               up_write(&current->mm->mmap_sem);
4667 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
4668 +                               return 1;
4669 +                       }
4670 +
4671 +                       if (pax_insert_vma(vma, call_syscall)) {
4672 +                               up_write(&current->mm->mmap_sem);
4673 +                               kmem_cache_free(vm_area_cachep, vma);
4674 +                               return 1;
4675 +                       }
4676 +
4677 +                       current->mm->call_syscall = call_syscall;
4678 +                       up_write(&current->mm->mmap_sem);
4679 +
4680 +emulate:
4681 +                       regs->gpr[PT_R0] = __NR_sigreturn;
4682 +                       regs->nip = call_syscall;
4683 +                       return 5;
4684 +               }
4685 +       } while (0);
4686 +
4687 +       do { /* PaX: rt_sigreturn emulation */
4688 +               unsigned int li, sc;
4689 +
4690 +               err = get_user(li, (unsigned int *)regs->nip);
4691 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
4692 +
4693 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
4694 +                       struct vm_area_struct *vma;
4695 +                       unsigned int call_syscall;
4696 +
4697 +                       down_read(&current->mm->mmap_sem);
4698 +                       call_syscall = current->mm->call_syscall;
4699 +                       up_read(&current->mm->mmap_sem);
4700 +                       if (likely(call_syscall))
4701 +                               goto rt_emulate;
4702 +
4703 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4704 +
4705 +                       down_write(&current->mm->mmap_sem);
4706 +                       if (current->mm->call_syscall) {
4707 +                               call_syscall = current->mm->call_syscall;
4708 +                               up_write(&current->mm->mmap_sem);
4709 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
4710 +                               goto rt_emulate;
4711 +                       }
4712 +
4713 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4714 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
4715 +                               up_write(&current->mm->mmap_sem);
4716 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
4717 +                               return 1;
4718 +                       }
4719 +
4720 +                       if (pax_insert_vma(vma, call_syscall)) {
4721 +                               up_write(&current->mm->mmap_sem);
4722 +                               kmem_cache_free(vm_area_cachep, vma);
4723 +                               return 1;
4724 +                       }
4725 +
4726 +                       current->mm->call_syscall = call_syscall;
4727 +                       up_write(&current->mm->mmap_sem);
4728 +
4729 +rt_emulate:
4730 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
4731 +                       regs->nip = call_syscall;
4732 +                       return 6;
4733 +               }
4734 +       } while (0);
4735 +#endif
4736 +
4737 +       return 1;
4738 +}
4739 +
4740 +void pax_report_insns(void *pc, void *sp)
4741 +{
4742 +       unsigned long i;
4743 +
4744 +       printk(KERN_ERR "PAX: bytes at PC: ");
4745 +       for (i = 0; i < 5; i++) {
4746 +               unsigned int c;
4747 +               if (get_user(c, (unsigned int*)pc+i))
4748 +                       printk("???????? ");
4749 +               else
4750 +                       printk("%08x ", c);
4751 +       }
4752 +       printk("\n");
4753 +}
4754 +#endif
4755 +
4756  /*
4757   * Check whether the instruction at regs->nip is a store using
4758   * an update addressing form which will update r1.
4759 @@ -111,7 +474,7 @@ int do_page_fault(struct pt_regs *regs, 
4760          * indicate errors in DSISR but can validly be set in SRR1.
4761          */
4762         if (TRAP(regs) == 0x400)
4763 -               error_code &= 0x48200000;
4764 +               error_code &= 0x58200000;
4765         else
4766                 is_write = error_code & 0x02000000;
4767  #endif /* CONFIG_4xx || CONFIG_BOOKE */
4768 @@ -205,15 +568,14 @@ good_area:
4769         } else if (TRAP(regs) == 0x400) {
4770                 pte_t *ptep;
4771  
4772 -#if 0
4773 +#if 1
4774                 /* It would be nice to actually enforce the VM execute
4775                    permission on CPUs which can do so, but far too
4776                    much stuff in userspace doesn't get the permissions
4777                    right, so we let any page be executed for now. */
4778                 if (! (vma->vm_flags & VM_EXEC))
4779                         goto bad_area;
4780 -#endif
4781 -
4782 +#else
4783                 /* Since 4xx/Book-E supports per-page execute permission,
4784                  * we lazily flush dcache to icache. */
4785                 ptep = NULL;
4786 @@ -233,6 +595,7 @@ good_area:
4787                 if (ptep != NULL)
4788                         pte_unmap(ptep);
4789  #endif
4790 +#endif
4791         /* a read */
4792         } else {
4793                 /* protection fault */
4794 @@ -278,6 +641,33 @@ bad_area:
4795  
4796         /* User mode accesses cause a SIGSEGV */
4797         if (user_mode(regs)) {
4798 +
4799 +#ifdef CONFIG_PAX_PAGEEXEC
4800 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
4801 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
4802 +                               switch (pax_handle_fetch_fault(regs)) {
4803 +
4804 +#ifdef CONFIG_PAX_EMUPLT
4805 +                               case 2:
4806 +                               case 3:
4807 +                               case 4:
4808 +                                       return 0;
4809 +#endif
4810 +
4811 +#ifdef CONFIG_PAX_EMUSIGRT
4812 +                               case 5:
4813 +                               case 6:
4814 +                                       return 0;
4815 +#endif
4816 +
4817 +                               }
4818 +
4819 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
4820 +                               do_exit(SIGKILL);
4821 +                       }
4822 +               }
4823 +#endif
4824 +
4825                 _exception(SIGSEGV, regs, code, address);
4826                 return 0;
4827         }
4828 diff -urNp linux-2.6.16.2/arch/s390/kernel/module.c linux-2.6.16.2/arch/s390/kernel/module.c
4829 --- linux-2.6.16.2/arch/s390/kernel/module.c    2006-04-07 12:56:47.000000000 -0400
4830 +++ linux-2.6.16.2/arch/s390/kernel/module.c    2006-04-09 21:23:54.000000000 -0400
4831 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
4832  
4833         /* Increase core size by size of got & plt and set start
4834            offsets for got and plt. */
4835 -       me->core_size = ALIGN(me->core_size, 4);
4836 -       me->arch.got_offset = me->core_size;
4837 -       me->core_size += me->arch.got_size;
4838 -       me->arch.plt_offset = me->core_size;
4839 -       me->core_size += me->arch.plt_size;
4840 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
4841 +       me->arch.got_offset = me->core_size_rw;
4842 +       me->core_size_rw += me->arch.got_size;
4843 +       me->arch.plt_offset = me->core_size_rx;
4844 +       me->core_size_rx += me->arch.plt_size;
4845         return 0;
4846  }
4847  
4848 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4849                 if (info->got_initialized == 0) {
4850                         Elf_Addr *gotent;
4851  
4852 -                       gotent = me->module_core + me->arch.got_offset +
4853 +                       gotent = me->module_core_rw + me->arch.got_offset +
4854                                 info->got_offset;
4855                         *gotent = val;
4856                         info->got_initialized = 1;
4857 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4858                 else if (r_type == R_390_GOTENT ||
4859                          r_type == R_390_GOTPLTENT)
4860                         *(unsigned int *) loc =
4861 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
4862 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
4863                 else if (r_type == R_390_GOT64 ||
4864                          r_type == R_390_GOTPLT64)
4865                         *(unsigned long *) loc = val;
4866 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4867         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
4868                 if (info->plt_initialized == 0) {
4869                         unsigned int *ip;
4870 -                       ip = me->module_core + me->arch.plt_offset +
4871 +                       ip = me->module_core_rx + me->arch.plt_offset +
4872                                 info->plt_offset;
4873  #ifndef CONFIG_64BIT
4874                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
4875 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4876                         val = me->arch.plt_offset - me->arch.got_offset +
4877                                 info->plt_offset + rela->r_addend;
4878                 else
4879 -                       val =  (Elf_Addr) me->module_core +
4880 +                       val =  (Elf_Addr) me->module_core_rx +
4881                                 me->arch.plt_offset + info->plt_offset + 
4882                                 rela->r_addend - loc;
4883                 if (r_type == R_390_PLT16DBL)
4884 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4885         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
4886         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
4887                 val = val + rela->r_addend -
4888 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
4889 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
4890                 if (r_type == R_390_GOTOFF16)
4891                         *(unsigned short *) loc = val;
4892                 else if (r_type == R_390_GOTOFF32)
4893 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4894                 break;
4895         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
4896         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
4897 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
4898 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
4899                         rela->r_addend - loc;
4900                 if (r_type == R_390_GOTPC)
4901                         *(unsigned int *) loc = val;
4902 diff -urNp linux-2.6.16.2/arch/sparc/kernel/ptrace.c linux-2.6.16.2/arch/sparc/kernel/ptrace.c
4903 --- linux-2.6.16.2/arch/sparc/kernel/ptrace.c   2006-04-07 12:56:47.000000000 -0400
4904 +++ linux-2.6.16.2/arch/sparc/kernel/ptrace.c   2006-04-09 21:23:54.000000000 -0400
4905 @@ -19,6 +19,7 @@
4906  #include <linux/smp_lock.h>
4907  #include <linux/security.h>
4908  #include <linux/signal.h>
4909 +#include <linux/grsecurity.h>
4910  
4911  #include <asm/pgtable.h>
4912  #include <asm/system.h>
4913 @@ -300,6 +301,11 @@ asmlinkage void do_ptrace(struct pt_regs
4914                 goto out;
4915         }
4916  
4917 +       if (gr_handle_ptrace(child, request)) {
4918 +               pt_error_return(regs, EPERM);
4919 +               goto out_tsk;
4920 +       }
4921 +
4922         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
4923             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
4924                 if (ptrace_attach(child)) {
4925 diff -urNp linux-2.6.16.2/arch/sparc/kernel/sys_sparc.c linux-2.6.16.2/arch/sparc/kernel/sys_sparc.c
4926 --- linux-2.6.16.2/arch/sparc/kernel/sys_sparc.c        2006-04-07 12:56:47.000000000 -0400
4927 +++ linux-2.6.16.2/arch/sparc/kernel/sys_sparc.c        2006-04-09 21:23:54.000000000 -0400
4928 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
4929         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
4930                 return -ENOMEM;
4931         if (!addr)
4932 -               addr = TASK_UNMAPPED_BASE;
4933 +               addr = current->mm->mmap_base;
4934  
4935         if (flags & MAP_SHARED)
4936                 addr = COLOUR_ALIGN(addr);
4937 diff -urNp linux-2.6.16.2/arch/sparc/Makefile linux-2.6.16.2/arch/sparc/Makefile
4938 --- linux-2.6.16.2/arch/sparc/Makefile  2006-04-07 12:56:47.000000000 -0400
4939 +++ linux-2.6.16.2/arch/sparc/Makefile  2006-04-09 21:23:54.000000000 -0400
4940 @@ -34,7 +34,7 @@ libs-y += arch/sparc/prom/ arch/sparc/li
4941  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
4942  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
4943  CORE_Y         := $(core-y)
4944 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
4945 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
4946  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
4947  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
4948  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
4949 diff -urNp linux-2.6.16.2/arch/sparc/mm/fault.c linux-2.6.16.2/arch/sparc/mm/fault.c
4950 --- linux-2.6.16.2/arch/sparc/mm/fault.c        2006-04-07 12:56:47.000000000 -0400
4951 +++ linux-2.6.16.2/arch/sparc/mm/fault.c        2006-04-09 21:23:54.000000000 -0400
4952 @@ -21,6 +21,10 @@
4953  #include <linux/smp_lock.h>
4954  #include <linux/interrupt.h>
4955  #include <linux/module.h>
4956 +#include <linux/slab.h>
4957 +#include <linux/pagemap.h>
4958 +#include <linux/compiler.h>
4959 +#include <linux/binfmts.h>
4960  
4961  #include <asm/system.h>
4962  #include <asm/page.h>
4963 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
4964         return safe_compute_effective_address(regs, insn);
4965  }
4966  
4967 +#ifdef CONFIG_PAX_PAGEEXEC
4968 +void pax_emuplt_close(struct vm_area_struct * vma)
4969 +{
4970 +       vma->vm_mm->call_dl_resolve = 0UL;
4971 +}
4972 +
4973 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
4974 +{
4975 +       struct page* page;
4976 +       unsigned int *kaddr;
4977 +
4978 +       page = alloc_page(GFP_HIGHUSER);
4979 +       if (!page)
4980 +               return NOPAGE_OOM;
4981 +
4982 +       kaddr = kmap(page);
4983 +       memset(kaddr, 0, PAGE_SIZE);
4984 +       kaddr[0] = 0x9DE3BFA8U; /* save */
4985 +       flush_dcache_page(page);
4986 +       kunmap(page);
4987 +       if (type)
4988 +               *type = VM_FAULT_MAJOR;
4989 +
4990 +       return page;
4991 +}
4992 +
4993 +static struct vm_operations_struct pax_vm_ops = {
4994 +       .close = pax_emuplt_close,
4995 +       .nopage = pax_emuplt_nopage,
4996 +};
4997 +
4998 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4999 +{
5000 +       int ret;
5001 +
5002 +       memset(vma, 0, sizeof(*vma));
5003 +       vma->vm_mm = current->mm;
5004 +       vma->vm_start = addr;
5005 +       vma->vm_end = addr + PAGE_SIZE;
5006 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
5007 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
5008 +       vma->vm_ops = &pax_vm_ops;
5009 +
5010 +       ret = insert_vm_struct(current->mm, vma);
5011 +       if (ret)
5012 +               return ret;
5013 +
5014 +       ++current->mm->total_vm;
5015 +       return 0;
5016 +}
5017 +
5018 +/*
5019 + * PaX: decide what to do with offenders (regs->pc = fault address)
5020 + *
5021 + * returns 1 when task should be killed
5022 + *         2 when patched PLT trampoline was detected
5023 + *         3 when unpatched PLT trampoline was detected
5024 + */
5025 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5026 +{
5027 +
5028 +#ifdef CONFIG_PAX_EMUPLT
5029 +       int err;
5030 +
5031 +       do { /* PaX: patched PLT emulation #1 */
5032 +               unsigned int sethi1, sethi2, jmpl;
5033 +
5034 +               err = get_user(sethi1, (unsigned int*)regs->pc);
5035 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
5036 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
5037 +
5038 +               if (err)
5039 +                       break;
5040 +
5041 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5042 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
5043 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
5044 +               {
5045 +                       unsigned int addr;
5046 +
5047 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
5048 +                       addr = regs->u_regs[UREG_G1];
5049 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
5050 +                       regs->pc = addr;
5051 +                       regs->npc = addr+4;
5052 +                       return 2;
5053 +               }
5054 +       } while (0);
5055 +
5056 +       { /* PaX: patched PLT emulation #2 */
5057 +               unsigned int ba;
5058 +
5059 +               err = get_user(ba, (unsigned int*)regs->pc);
5060 +
5061 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
5062 +                       unsigned int addr;
5063 +
5064 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
5065 +                       regs->pc = addr;
5066 +                       regs->npc = addr+4;
5067 +                       return 2;
5068 +               }
5069 +       }
5070 +
5071 +       do { /* PaX: patched PLT emulation #3 */
5072 +               unsigned int sethi, jmpl, nop;
5073 +
5074 +               err = get_user(sethi, (unsigned int*)regs->pc);
5075 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
5076 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
5077 +
5078 +               if (err)
5079 +                       break;
5080 +
5081 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5082 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
5083 +                   nop == 0x01000000U)
5084 +               {
5085 +                       unsigned int addr;
5086 +
5087 +                       addr = (sethi & 0x003FFFFFU) << 10;
5088 +                       regs->u_regs[UREG_G1] = addr;
5089 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
5090 +                       regs->pc = addr;
5091 +                       regs->npc = addr+4;
5092 +                       return 2;
5093 +               }
5094 +       } while (0);
5095 +
5096 +       do { /* PaX: unpatched PLT emulation step 1 */
5097 +               unsigned int sethi, ba, nop;
5098 +
5099 +               err = get_user(sethi, (unsigned int*)regs->pc);
5100 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
5101 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
5102 +
5103 +               if (err)
5104 +                       break;
5105 +
5106 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5107 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
5108 +                   nop == 0x01000000U)
5109 +               {
5110 +                       unsigned int addr, save, call;
5111 +
5112 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
5113 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
5114 +                       else
5115 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
5116 +
5117 +                       err = get_user(save, (unsigned int*)addr);
5118 +                       err |= get_user(call, (unsigned int*)(addr+4));
5119 +                       err |= get_user(nop, (unsigned int*)(addr+8));
5120 +                       if (err)
5121 +                               break;
5122 +
5123 +                       if (save == 0x9DE3BFA8U &&
5124 +                           (call & 0xC0000000U) == 0x40000000U &&
5125 +                           nop == 0x01000000U)
5126 +                       {
5127 +                               struct vm_area_struct *vma;
5128 +                               unsigned long call_dl_resolve;
5129 +
5130 +                               down_read(&current->mm->mmap_sem);
5131 +                               call_dl_resolve = current->mm->call_dl_resolve;
5132 +                               up_read(&current->mm->mmap_sem);
5133 +                               if (likely(call_dl_resolve))
5134 +                                       goto emulate;
5135 +
5136 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5137 +
5138 +                               down_write(&current->mm->mmap_sem);
5139 +                               if (current->mm->call_dl_resolve) {
5140 +                                       call_dl_resolve = current->mm->call_dl_resolve;
5141 +                                       up_write(&current->mm->mmap_sem);
5142 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
5143 +                                       goto emulate;
5144 +                               }
5145 +
5146 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5147 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
5148 +                                       up_write(&current->mm->mmap_sem);
5149 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
5150 +                                       return 1;
5151 +                               }
5152 +
5153 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
5154 +                                       up_write(&current->mm->mmap_sem);
5155 +                                       kmem_cache_free(vm_area_cachep, vma);
5156 +                                       return 1;
5157 +                               }
5158 +
5159 +                               current->mm->call_dl_resolve = call_dl_resolve;
5160 +                               up_write(&current->mm->mmap_sem);
5161 +
5162 +emulate:
5163 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5164 +                               regs->pc = call_dl_resolve;
5165 +                               regs->npc = addr+4;
5166 +                               return 3;
5167 +                       }
5168 +               }
5169 +       } while (0);
5170 +
5171 +       do { /* PaX: unpatched PLT emulation step 2 */
5172 +               unsigned int save, call, nop;
5173 +
5174 +               err = get_user(save, (unsigned int*)(regs->pc-4));
5175 +               err |= get_user(call, (unsigned int*)regs->pc);
5176 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
5177 +               if (err)
5178 +                       break;
5179 +
5180 +               if (save == 0x9DE3BFA8U &&
5181 +                   (call & 0xC0000000U) == 0x40000000U &&
5182 +                   nop == 0x01000000U)
5183 +               {
5184 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
5185 +
5186 +                       regs->u_regs[UREG_RETPC] = regs->pc;
5187 +                       regs->pc = dl_resolve;
5188 +                       regs->npc = dl_resolve+4;
5189 +                       return 3;
5190 +               }
5191 +       } while (0);
5192 +#endif
5193 +
5194 +       return 1;
5195 +}
5196 +
5197 +void pax_report_insns(void *pc, void *sp)
5198 +{
5199 +       unsigned long i;
5200 +
5201 +       printk(KERN_ERR "PAX: bytes at PC: ");
5202 +       for (i = 0; i < 5; i++) {
5203 +               unsigned int c;
5204 +               if (get_user(c, (unsigned int*)pc+i))
5205 +                       printk("???????? ");
5206 +               else
5207 +                       printk("%08x ", c);
5208 +       }
5209 +       printk("\n");
5210 +}
5211 +#endif
5212 +
5213  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
5214                                unsigned long address)
5215  {
5216 @@ -280,6 +530,24 @@ good_area:
5217                 if(!(vma->vm_flags & VM_WRITE))
5218                         goto bad_area;
5219         } else {
5220 +
5221 +#ifdef CONFIG_PAX_PAGEEXEC
5222 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
5223 +                       up_read(&mm->mmap_sem);
5224 +                       switch (pax_handle_fetch_fault(regs)) {
5225 +
5226 +#ifdef CONFIG_PAX_EMUPLT
5227 +                       case 2:
5228 +                       case 3:
5229 +                               return;
5230 +#endif
5231 +
5232 +                       }
5233 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
5234 +                       do_exit(SIGKILL);
5235 +               }
5236 +#endif
5237 +
5238                 /* Allow reads even for write-only mappings */
5239                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
5240                         goto bad_area;
5241 diff -urNp linux-2.6.16.2/arch/sparc/mm/init.c linux-2.6.16.2/arch/sparc/mm/init.c
5242 --- linux-2.6.16.2/arch/sparc/mm/init.c 2006-04-07 12:56:47.000000000 -0400
5243 +++ linux-2.6.16.2/arch/sparc/mm/init.c 2006-04-09 21:23:54.000000000 -0400
5244 @@ -333,17 +333,17 @@ void __init paging_init(void)
5245  
5246         /* Initialize the protection map with non-constant, MMU dependent values. */
5247         protection_map[0] = PAGE_NONE;
5248 -       protection_map[1] = PAGE_READONLY;
5249 -       protection_map[2] = PAGE_COPY;
5250 -       protection_map[3] = PAGE_COPY;
5251 +       protection_map[1] = PAGE_READONLY_NOEXEC;
5252 +       protection_map[2] = PAGE_COPY_NOEXEC;
5253 +       protection_map[3] = PAGE_COPY_NOEXEC;
5254         protection_map[4] = PAGE_READONLY;
5255         protection_map[5] = PAGE_READONLY;
5256         protection_map[6] = PAGE_COPY;
5257         protection_map[7] = PAGE_COPY;
5258         protection_map[8] = PAGE_NONE;
5259 -       protection_map[9] = PAGE_READONLY;
5260 -       protection_map[10] = PAGE_SHARED;
5261 -       protection_map[11] = PAGE_SHARED;
5262 +       protection_map[9] = PAGE_READONLY_NOEXEC;
5263 +       protection_map[10] = PAGE_SHARED_NOEXEC;
5264 +       protection_map[11] = PAGE_SHARED_NOEXEC;
5265         protection_map[12] = PAGE_READONLY;
5266         protection_map[13] = PAGE_READONLY;
5267         protection_map[14] = PAGE_SHARED;
5268 diff -urNp linux-2.6.16.2/arch/sparc/mm/srmmu.c linux-2.6.16.2/arch/sparc/mm/srmmu.c
5269 --- linux-2.6.16.2/arch/sparc/mm/srmmu.c        2006-04-07 12:56:47.000000000 -0400
5270 +++ linux-2.6.16.2/arch/sparc/mm/srmmu.c        2006-04-09 21:23:54.000000000 -0400
5271 @@ -2148,6 +2148,13 @@ void __init ld_mmu_srmmu(void)
5272         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
5273         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
5274         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
5275 +
5276 +#ifdef CONFIG_PAX_PAGEEXEC
5277 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
5278 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
5279 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
5280 +#endif
5281 +
5282         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
5283         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
5284         pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
5285 diff -urNp linux-2.6.16.2/arch/sparc64/kernel/ptrace.c linux-2.6.16.2/arch/sparc64/kernel/ptrace.c
5286 --- linux-2.6.16.2/arch/sparc64/kernel/ptrace.c 2006-04-07 12:56:47.000000000 -0400
5287 +++ linux-2.6.16.2/arch/sparc64/kernel/ptrace.c 2006-04-09 21:23:54.000000000 -0400
5288 @@ -22,6 +22,7 @@
5289  #include <linux/seccomp.h>
5290  #include <linux/audit.h>
5291  #include <linux/signal.h>
5292 +#include <linux/grsecurity.h>
5293  
5294  #include <asm/asi.h>
5295  #include <asm/pgtable.h>
5296 @@ -210,6 +211,11 @@ asmlinkage void do_ptrace(struct pt_regs
5297                 goto out;
5298         }
5299  
5300 +       if (gr_handle_ptrace(child, (long)request)) {
5301 +               pt_error_return(regs, EPERM);
5302 +               goto out_tsk;
5303 +       }
5304 +
5305         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
5306             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
5307                 if (ptrace_attach(child)) {
5308 diff -urNp linux-2.6.16.2/arch/sparc64/kernel/sys_sparc.c linux-2.6.16.2/arch/sparc64/kernel/sys_sparc.c
5309 --- linux-2.6.16.2/arch/sparc64/kernel/sys_sparc.c      2006-04-07 12:56:47.000000000 -0400
5310 +++ linux-2.6.16.2/arch/sparc64/kernel/sys_sparc.c      2006-04-09 21:23:54.000000000 -0400
5311 @@ -72,6 +72,10 @@ unsigned long arch_get_unmapped_area(str
5312         if (filp || (flags & MAP_SHARED))
5313                 do_color_align = 1;
5314  
5315 +#ifdef CONFIG_PAX_RANDMMAP
5316 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5317 +#endif
5318 +
5319         if (addr) {
5320                 if (do_color_align)
5321                         addr = COLOUR_ALIGN(addr, pgoff);
5322 @@ -86,7 +90,7 @@ unsigned long arch_get_unmapped_area(str
5323  
5324         if (len <= mm->cached_hole_size) {
5325                 mm->cached_hole_size = 0;
5326 -               mm->free_area_cache = TASK_UNMAPPED_BASE;
5327 +               mm->free_area_cache = mm->mmap_base;
5328         }
5329         start_addr = addr = mm->free_area_cache;
5330  
5331 @@ -105,8 +109,8 @@ full_search:
5332                         vma = find_vma(mm, PAGE_OFFSET);
5333                 }
5334                 if (task_size < addr) {
5335 -                       if (start_addr != TASK_UNMAPPED_BASE) {
5336 -                               start_addr = addr = TASK_UNMAPPED_BASE;
5337 +                       if (start_addr != mm->mmap_base) {
5338 +                               start_addr = addr = mm->mmap_base;
5339                                 mm->cached_hole_size = 0;
5340                                 goto full_search;
5341                         }
5342 diff -urNp linux-2.6.16.2/arch/sparc64/mm/fault.c linux-2.6.16.2/arch/sparc64/mm/fault.c
5343 --- linux-2.6.16.2/arch/sparc64/mm/fault.c      2006-04-07 12:56:47.000000000 -0400
5344 +++ linux-2.6.16.2/arch/sparc64/mm/fault.c      2006-04-09 21:23:54.000000000 -0400
5345 @@ -19,6 +19,10 @@
5346  #include <linux/init.h>
5347  #include <linux/interrupt.h>
5348  #include <linux/kprobes.h>
5349 +#include <linux/slab.h>
5350 +#include <linux/pagemap.h>
5351 +#include <linux/compiler.h>
5352 +#include <linux/binfmts.h>
5353  
5354  #include <asm/page.h>
5355  #include <asm/pgtable.h>
5356 @@ -251,6 +255,369 @@ cannot_handle:
5357         unhandled_fault (address, current, regs);
5358  }
5359  
5360 +#ifdef CONFIG_PAX_PAGEEXEC
5361 +#ifdef CONFIG_PAX_EMUPLT
5362 +static void pax_emuplt_close(struct vm_area_struct * vma)
5363 +{
5364 +       vma->vm_mm->call_dl_resolve = 0UL;
5365 +}
5366 +
5367 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
5368 +{
5369 +       struct page* page;
5370 +       unsigned int *kaddr;
5371 +
5372 +       page = alloc_page(GFP_HIGHUSER);
5373 +       if (!page)
5374 +               return NOPAGE_OOM;
5375 +
5376 +       kaddr = kmap(page);
5377 +       memset(kaddr, 0, PAGE_SIZE);
5378 +       kaddr[0] = 0x9DE3BFA8U; /* save */
5379 +       flush_dcache_page(page);
5380 +       kunmap(page);
5381 +       if (type)
5382 +               *type = VM_FAULT_MAJOR;
5383 +       return page;
5384 +}
5385 +
5386 +static struct vm_operations_struct pax_vm_ops = {
5387 +       .close = pax_emuplt_close,
5388 +       .nopage = pax_emuplt_nopage,
5389 +};
5390 +
5391 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
5392 +{
5393 +       int ret;
5394 +
5395 +       memset(vma, 0, sizeof(*vma));
5396 +       vma->vm_mm = current->mm;
5397 +       vma->vm_start = addr;
5398 +       vma->vm_end = addr + PAGE_SIZE;
5399 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
5400 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
5401 +       vma->vm_ops = &pax_vm_ops;
5402 +
5403 +       ret = insert_vm_struct(current->mm, vma);
5404 +       if (ret)
5405 +               return ret;
5406 +
5407 +       ++current->mm->total_vm;
5408 +       return 0;
5409 +}
5410 +#endif
5411 +
5412 +/*
5413 + * PaX: decide what to do with offenders (regs->tpc = fault address)
5414 + *
5415 + * returns 1 when task should be killed
5416 + *         2 when patched PLT trampoline was detected
5417 + *         3 when unpatched PLT trampoline was detected
5418 + */
5419 +static int pax_handle_fetch_fault(struct pt_regs *regs)
5420 +{
5421 +
5422 +#ifdef CONFIG_PAX_EMUPLT
5423 +       int err;
5424 +
5425 +       do { /* PaX: patched PLT emulation #1 */
5426 +               unsigned int sethi1, sethi2, jmpl;
5427 +
5428 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
5429 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
5430 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
5431 +
5432 +               if (err)
5433 +                       break;
5434 +
5435 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5436 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
5437 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
5438 +               {
5439 +                       unsigned long addr;
5440 +
5441 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
5442 +                       addr = regs->u_regs[UREG_G1];
5443 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
5444 +                       regs->tpc = addr;
5445 +                       regs->tnpc = addr+4;
5446 +                       return 2;
5447 +               }
5448 +       } while (0);
5449 +
5450 +       { /* PaX: patched PLT emulation #2 */
5451 +               unsigned int ba;
5452 +
5453 +               err = get_user(ba, (unsigned int*)regs->tpc);
5454 +
5455 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
5456 +                       unsigned long addr;
5457 +
5458 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
5459 +                       regs->tpc = addr;
5460 +                       regs->tnpc = addr+4;
5461 +                       return 2;
5462 +               }
5463 +       }
5464 +
5465 +       do { /* PaX: patched PLT emulation #3 */
5466 +               unsigned int sethi, jmpl, nop;
5467 +
5468 +               err = get_user(sethi, (unsigned int*)regs->tpc);
5469 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
5470 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
5471 +
5472 +               if (err)
5473 +                       break;
5474 +
5475 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5476 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
5477 +                   nop == 0x01000000U)
5478 +               {
5479 +                       unsigned long addr;
5480 +
5481 +                       addr = (sethi & 0x003FFFFFU) << 10;
5482 +                       regs->u_regs[UREG_G1] = addr;
5483 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
5484 +                       regs->tpc = addr;
5485 +                       regs->tnpc = addr+4;
5486 +                       return 2;
5487 +               }
5488 +       } while (0);
5489 +
5490 +       do { /* PaX: patched PLT emulation #4 */
5491 +               unsigned int mov1, call, mov2;
5492 +
5493 +               err = get_user(mov1, (unsigned int*)regs->tpc);
5494 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
5495 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
5496 +
5497 +               if (err)
5498 +                       break;
5499 +
5500 +               if (mov1 == 0x8210000FU &&
5501 +                   (call & 0xC0000000U) == 0x40000000U &&
5502 +                   mov2 == 0x9E100001U)
5503 +               {
5504 +                       unsigned long addr;
5505 +
5506 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
5507 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5508 +                       regs->tpc = addr;
5509 +                       regs->tnpc = addr+4;
5510 +                       return 2;
5511 +               }
5512 +       } while (0);
5513 +
5514 +       do { /* PaX: patched PLT emulation #5 */
5515 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
5516 +
5517 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
5518 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
5519 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
5520 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
5521 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
5522 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
5523 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
5524 +
5525 +               if (err)
5526 +                       break;
5527 +
5528 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5529 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
5530 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
5531 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
5532 +                   sllx == 0x83287020 &&
5533 +                   jmpl == 0x81C04005U &&
5534 +                   nop == 0x01000000U)
5535 +               {
5536 +                       unsigned long addr;
5537 +
5538 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
5539 +                       regs->u_regs[UREG_G1] <<= 32;
5540 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
5541 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
5542 +                       regs->tpc = addr;
5543 +                       regs->tnpc = addr+4;
5544 +                       return 2;
5545 +               }
5546 +       } while (0);
5547 +
5548 +       do { /* PaX: patched PLT emulation #6 */
5549 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
5550 +
5551 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
5552 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
5553 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
5554 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
5555 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
5556 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
5557 +
5558 +               if (err)
5559 +                       break;
5560 +
5561 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
5562 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
5563 +                   sllx == 0x83287020 &&
5564 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
5565 +                   jmpl == 0x81C04005U &&
5566 +                   nop == 0x01000000U)
5567 +               {
5568 +                       unsigned long addr;
5569 +
5570 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
5571 +                       regs->u_regs[UREG_G1] <<= 32;
5572 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
5573 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
5574 +                       regs->tpc = addr;
5575 +                       regs->tnpc = addr+4;
5576 +                       return 2;
5577 +               }
5578 +       } while (0);
5579 +
5580 +       do { /* PaX: patched PLT emulation #7 */
5581 +               unsigned int sethi, ba, nop;
5582 +
5583 +               err = get_user(sethi, (unsigned int*)regs->tpc);
5584 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
5585 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
5586 +
5587 +               if (err)
5588 +                       break;
5589 +
5590 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5591 +                   (ba & 0xFFF00000U) == 0x30600000U &&
5592 +                   nop == 0x01000000U)
5593 +               {
5594 +                       unsigned long addr;
5595 +
5596 +                       addr = (sethi & 0x003FFFFFU) << 10;
5597 +                       regs->u_regs[UREG_G1] = addr;
5598 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
5599 +                       regs->tpc = addr;
5600 +                       regs->tnpc = addr+4;
5601 +                       return 2;
5602 +               }
5603 +       } while (0);
5604 +
5605 +       do { /* PaX: unpatched PLT emulation step 1 */
5606 +               unsigned int sethi, ba, nop;
5607 +
5608 +               err = get_user(sethi, (unsigned int*)regs->tpc);
5609 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
5610 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
5611 +
5612 +               if (err)
5613 +                       break;
5614 +
5615 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
5616 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
5617 +                   nop == 0x01000000U)
5618 +               {
5619 +                       unsigned long addr;
5620 +                       unsigned int save, call;
5621 +
5622 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
5623 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
5624 +                       else
5625 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
5626 +
5627 +                       err = get_user(save, (unsigned int*)addr);
5628 +                       err |= get_user(call, (unsigned int*)(addr+4));
5629 +                       err |= get_user(nop, (unsigned int*)(addr+8));
5630 +                       if (err)
5631 +                               break;
5632 +
5633 +                       if (save == 0x9DE3BFA8U &&
5634 +                           (call & 0xC0000000U) == 0x40000000U &&
5635 +                           nop == 0x01000000U)
5636 +                       {
5637 +                               struct vm_area_struct *vma;
5638 +                               unsigned long call_dl_resolve;
5639 +
5640 +                               down_read(&current->mm->mmap_sem);
5641 +                               call_dl_resolve = current->mm->call_dl_resolve;
5642 +                               up_read(&current->mm->mmap_sem);
5643 +                               if (likely(call_dl_resolve))
5644 +                                       goto emulate;
5645 +
5646 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5647 +
5648 +                               down_write(&current->mm->mmap_sem);
5649 +                               if (current->mm->call_dl_resolve) {
5650 +                                       call_dl_resolve = current->mm->call_dl_resolve;
5651 +                                       up_write(&current->mm->mmap_sem);
5652 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
5653 +                                       goto emulate;
5654 +                               }
5655 +
5656 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
5657 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
5658 +                                       up_write(&current->mm->mmap_sem);
5659 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
5660 +                                       return 1;
5661 +                               }
5662 +
5663 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
5664 +                                       up_write(&current->mm->mmap_sem);
5665 +                                       kmem_cache_free(vm_area_cachep, vma);
5666 +                                       return 1;
5667 +                               }
5668 +
5669 +                               current->mm->call_dl_resolve = call_dl_resolve;
5670 +                               up_write(&current->mm->mmap_sem);
5671 +
5672 +emulate:
5673 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
5674 +                               regs->tpc = call_dl_resolve;
5675 +                               regs->tnpc = addr+4;
5676 +                               return 3;
5677 +                       }
5678 +               }
5679 +       } while (0);
5680 +
5681 +       do { /* PaX: unpatched PLT emulation step 2 */
5682 +               unsigned int save, call, nop;
5683 +
5684 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
5685 +               err |= get_user(call, (unsigned int*)regs->tpc);
5686 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
5687 +               if (err)
5688 +                       break;
5689 +
5690 +               if (save == 0x9DE3BFA8U &&
5691 +                   (call & 0xC0000000U) == 0x40000000U &&
5692 +                   nop == 0x01000000U)
5693 +               {
5694 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5695 +
5696 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
5697 +                       regs->tpc = dl_resolve;
5698 +                       regs->tnpc = dl_resolve+4;
5699 +                       return 3;
5700 +               }
5701 +       } while (0);
5702 +#endif
5703 +
5704 +       return 1;
5705 +}
5706 +
5707 +void pax_report_insns(void *pc, void *sp)
5708 +{
5709 +       unsigned long i;
5710 +
5711 +       printk(KERN_ERR "PAX: bytes at PC: ");
5712 +       for (i = 0; i < 5; i++) {
5713 +               unsigned int c;
5714 +               if (get_user(c, (unsigned int*)pc+i))
5715 +                       printk("???????? ");
5716 +               else
5717 +                       printk("%08x ", c);
5718 +       }
5719 +       printk("\n");
5720 +}
5721 +#endif
5722 +
5723  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
5724  {
5725         struct mm_struct *mm = current->mm;
5726 @@ -293,8 +660,10 @@ asmlinkage void __kprobes do_sparc64_fau
5727                 goto intr_or_no_mm;
5728  
5729         if (test_thread_flag(TIF_32BIT)) {
5730 -               if (!(regs->tstate & TSTATE_PRIV))
5731 +               if (!(regs->tstate & TSTATE_PRIV)) {
5732                         regs->tpc &= 0xffffffff;
5733 +                       regs->tnpc &= 0xffffffff;
5734 +               }
5735                 address &= 0xffffffff;
5736         }
5737  
5738 @@ -311,6 +680,29 @@ asmlinkage void __kprobes do_sparc64_fau
5739         if (!vma)
5740                 goto bad_area;
5741  
5742 +#ifdef CONFIG_PAX_PAGEEXEC
5743 +       /* PaX: detect ITLB misses on non-exec pages */
5744 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
5745 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
5746 +       {
5747 +               if (address != regs->tpc)
5748 +                       goto good_area;
5749 +
5750 +               up_read(&mm->mmap_sem);
5751 +               switch (pax_handle_fetch_fault(regs)) {
5752 +
5753 +#ifdef CONFIG_PAX_EMUPLT
5754 +               case 2:
5755 +               case 3:
5756 +                       return;
5757 +#endif
5758 +
5759 +               }
5760 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
5761 +               do_exit(SIGKILL);
5762 +       }
5763 +#endif
5764 +
5765         /* Pure DTLB misses do not tell us whether the fault causing
5766          * load/store/atomic was a write or not, it only says that there
5767          * was no match.  So in such a case we (carefully) read the
5768 diff -urNp linux-2.6.16.2/arch/v850/kernel/module.c linux-2.6.16.2/arch/v850/kernel/module.c
5769 --- linux-2.6.16.2/arch/v850/kernel/module.c    2006-04-07 12:56:47.000000000 -0400
5770 +++ linux-2.6.16.2/arch/v850/kernel/module.c    2006-04-09 21:23:54.000000000 -0400
5771 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
5772         tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
5773  
5774         /* Init, or core PLT? */
5775 -       if (location >= mod->module_core
5776 -           && location < mod->module_core + mod->core_size)
5777 +       if (location >= mod->module_core_rx
5778 +           && location < mod->module_core_rx + mod->core_size_rx)
5779                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
5780         else
5781                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
5782 diff -urNp linux-2.6.16.2/arch/x86_64/boot/compressed/head.S linux-2.6.16.2/arch/x86_64/boot/compressed/head.S
5783 --- linux-2.6.16.2/arch/x86_64/boot/compressed/head.S   2006-04-07 12:56:47.000000000 -0400
5784 +++ linux-2.6.16.2/arch/x86_64/boot/compressed/head.S   2006-04-09 21:23:54.000000000 -0400
5785 @@ -41,11 +41,13 @@ startup_32:
5786         movl %eax,%gs
5787  
5788         lss stack_start,%esp
5789 +       movl 0x000000,%ecx
5790         xorl %eax,%eax
5791  1:     incl %eax               # check that A20 really IS enabled
5792         movl %eax,0x000000      # loop forever if it isn't
5793         cmpl %eax,0x100000
5794         je 1b
5795 +       movl %ecx,0x000000
5796  
5797  /*
5798   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
5799 diff -urNp linux-2.6.16.2/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.16.2/arch/x86_64/ia32/ia32_binfmt.c
5800 --- linux-2.6.16.2/arch/x86_64/ia32/ia32_binfmt.c       2006-04-07 12:56:47.000000000 -0400
5801 +++ linux-2.6.16.2/arch/x86_64/ia32/ia32_binfmt.c       2006-04-09 21:23:54.000000000 -0400
5802 @@ -186,6 +186,17 @@ struct elf_prpsinfo
5803  //#include <asm/ia32.h>
5804  #include <linux/elf.h>
5805  
5806 +#ifdef CONFIG_PAX_ASLR
5807 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
5808 +
5809 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
5810 +#define PAX_DELTA_MMAP_LEN(tsk)                16
5811 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
5812 +#define PAX_DELTA_EXEC_LEN(tsk)                16
5813 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
5814 +#define PAX_DELTA_STACK_LEN(tsk)       16
5815 +#endif
5816 +
5817  typedef struct user_i387_ia32_struct elf_fpregset_t;
5818  typedef struct user32_fxsr_struct elf_fpxregset_t;
5819  
5820 diff -urNp linux-2.6.16.2/arch/x86_64/ia32/mmap32.c linux-2.6.16.2/arch/x86_64/ia32/mmap32.c
5821 --- linux-2.6.16.2/arch/x86_64/ia32/mmap32.c    2006-04-07 12:56:47.000000000 -0400
5822 +++ linux-2.6.16.2/arch/x86_64/ia32/mmap32.c    2006-04-09 21:23:54.000000000 -0400
5823 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
5824                         (current->personality & ADDR_COMPAT_LAYOUT) ||
5825                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
5826                 mm->mmap_base = TASK_UNMAPPED_BASE;
5827 +
5828 +#ifdef CONFIG_PAX_RANDMMAP
5829 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5830 +                       mm->mmap_base += mm->delta_mmap;
5831 +#endif
5832 +
5833                 mm->get_unmapped_area = arch_get_unmapped_area;
5834                 mm->unmap_area = arch_unmap_area;
5835         } else {
5836                 mm->mmap_base = mmap_base(mm);
5837 +
5838 +#ifdef CONFIG_PAX_RANDMMAP
5839 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
5840 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
5841 +#endif
5842 +
5843                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
5844                 mm->unmap_area = arch_unmap_area_topdown;
5845         }
5846 diff -urNp linux-2.6.16.2/arch/x86_64/kernel/process.c linux-2.6.16.2/arch/x86_64/kernel/process.c
5847 --- linux-2.6.16.2/arch/x86_64/kernel/process.c 2006-04-07 12:56:47.000000000 -0400
5848 +++ linux-2.6.16.2/arch/x86_64/kernel/process.c 2006-04-09 21:23:54.000000000 -0400
5849 @@ -835,9 +835,3 @@ int dump_task_regs(struct task_struct *t
5850         return 1;
5851  }
5852  
5853 -unsigned long arch_align_stack(unsigned long sp)
5854 -{
5855 -       if (randomize_va_space)
5856 -               sp -= get_random_int() % 8192;
5857 -       return sp & ~0xf;
5858 -}
5859 diff -urNp linux-2.6.16.2/arch/x86_64/kernel/ptrace.c linux-2.6.16.2/arch/x86_64/kernel/ptrace.c
5860 --- linux-2.6.16.2/arch/x86_64/kernel/ptrace.c  2006-04-07 12:56:47.000000000 -0400
5861 +++ linux-2.6.16.2/arch/x86_64/kernel/ptrace.c  2006-04-09 21:23:54.000000000 -0400
5862 @@ -19,6 +19,7 @@
5863  #include <linux/audit.h>
5864  #include <linux/seccomp.h>
5865  #include <linux/signal.h>
5866 +#include <linux/grsecurity.h>
5867  
5868  #include <asm/uaccess.h>
5869  #include <asm/pgtable.h>
5870 diff -urNp linux-2.6.16.2/arch/x86_64/kernel/setup64.c linux-2.6.16.2/arch/x86_64/kernel/setup64.c
5871 --- linux-2.6.16.2/arch/x86_64/kernel/setup64.c 2006-04-07 12:56:47.000000000 -0400
5872 +++ linux-2.6.16.2/arch/x86_64/kernel/setup64.c 2006-04-09 21:23:54.000000000 -0400
5873 @@ -38,7 +38,6 @@ struct desc_ptr idt_descr = { 256 * 16, 
5874  char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
5875  
5876  unsigned long __supported_pte_mask __read_mostly = ~0UL;
5877 -static int do_not_nx __cpuinitdata = 0;
5878  
5879  /* noexec=on|off
5880  Control non executable mappings for 64bit processes.
5881 @@ -50,16 +49,14 @@ int __init nonx_setup(char *str)
5882  {
5883         if (!strncmp(str, "on", 2)) {
5884                  __supported_pte_mask |= _PAGE_NX; 
5885 -               do_not_nx = 0; 
5886         } else if (!strncmp(str, "off", 3)) {
5887 -               do_not_nx = 1;
5888                 __supported_pte_mask &= ~_PAGE_NX;
5889          }
5890         return 0;
5891  } 
5892  __setup("noexec=", nonx_setup);        /* parsed early actually */
5893  
5894 -int force_personality32 = READ_IMPLIES_EXEC;
5895 +int force_personality32;
5896  
5897  /* noexec32=on|off
5898  Control non executable heap for 32bit processes.
5899 @@ -173,7 +170,7 @@ void __cpuinit check_efer(void)
5900         unsigned long efer;
5901  
5902         rdmsrl(MSR_EFER, efer); 
5903 -        if (!(efer & EFER_NX) || do_not_nx) { 
5904 +        if (!(efer & EFER_NX)) { 
5905                  __supported_pte_mask &= ~_PAGE_NX; 
5906          }       
5907  }
5908 diff -urNp linux-2.6.16.2/arch/x86_64/kernel/sys_x86_64.c linux-2.6.16.2/arch/x86_64/kernel/sys_x86_64.c
5909 --- linux-2.6.16.2/arch/x86_64/kernel/sys_x86_64.c      2006-04-07 12:56:47.000000000 -0400
5910 +++ linux-2.6.16.2/arch/x86_64/kernel/sys_x86_64.c      2006-04-09 21:23:54.000000000 -0400
5911 @@ -65,8 +65,8 @@ out:
5912         return error;
5913  }
5914  
5915 -static void find_start_end(unsigned long flags, unsigned long *begin,
5916 -                          unsigned long *end)
5917 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
5918 +                          unsigned long *begin, unsigned long *end)
5919  {
5920         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
5921                 /* This is usually used needed to map code in small
5922 @@ -79,7 +79,7 @@ static void find_start_end(unsigned long
5923                 *begin = 0x40000000; 
5924                 *end = 0x80000000;              
5925         } else {
5926 -               *begin = TASK_UNMAPPED_BASE;
5927 +               *begin = mm->mmap_base;
5928                 *end = TASK_SIZE; 
5929         }
5930  } 
5931 @@ -93,11 +93,15 @@ arch_get_unmapped_area(struct file *filp
5932         unsigned long start_addr;
5933         unsigned long begin, end;
5934         
5935 -       find_start_end(flags, &begin, &end); 
5936 +       find_start_end(mm, flags, &begin, &end); 
5937  
5938         if (len > end)
5939                 return -ENOMEM;
5940  
5941 +#ifdef CONFIG_PAX_RANDMMAP
5942 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5943 +#endif
5944 +
5945         if (addr) {
5946                 addr = PAGE_ALIGN(addr);
5947                 vma = find_vma(mm, addr);
5948 diff -urNp linux-2.6.16.2/arch/x86_64/mm/fault.c linux-2.6.16.2/arch/x86_64/mm/fault.c
5949 --- linux-2.6.16.2/arch/x86_64/mm/fault.c       2006-04-07 12:56:47.000000000 -0400
5950 +++ linux-2.6.16.2/arch/x86_64/mm/fault.c       2006-04-09 21:23:54.000000000 -0400
5951 @@ -24,6 +24,7 @@
5952  #include <linux/compiler.h>
5953  #include <linux/module.h>
5954  #include <linux/kprobes.h>
5955 +#include <linux/binfmts.h>
5956  
5957  #include <asm/system.h>
5958  #include <asm/uaccess.h>
5959 @@ -292,6 +293,33 @@ static int vmalloc_fault(unsigned long a
5960         return 0;
5961  }
5962  
5963 +#ifdef CONFIG_PAX_PAGEEXEC
5964 +void pax_report_insns(void *pc, void *sp)
5965 +{
5966 +       long i;
5967 +
5968 +       printk(KERN_ERR "PAX: bytes at PC: ");
5969 +       for (i = 0; i < 20; i++) {
5970 +               unsigned char c;
5971 +               if (get_user(c, (unsigned char __user *)pc+i))
5972 +                       printk("?? ");
5973 +               else
5974 +                       printk("%02x ", c);
5975 +       }
5976 +       printk("\n");
5977 +
5978 +       printk(KERN_ERR "PAX: bytes at SP-8: ");
5979 +       for (i = -1; i < 10; i++) {
5980 +               unsigned long c;
5981 +               if (get_user(c, (unsigned long __user *)sp+i))
5982 +                       printk("???????????????? ");
5983 +               else
5984 +                       printk("%016lx ", c);
5985 +       }
5986 +       printk("\n");
5987 +}
5988 +#endif
5989 +
5990  int page_fault_trace = 0;
5991  int exception_trace = 1;
5992  
5993 @@ -416,6 +444,8 @@ asmlinkage void __kprobes do_page_fault(
5994  good_area:
5995         info.si_code = SEGV_ACCERR;
5996         write = 0;
5997 +       if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
5998 +               goto bad_area;
5999         switch (error_code & (PF_PROT|PF_WRITE)) {
6000                 default:        /* 3: write, present */
6001                         /* fall through */
6002 @@ -482,7 +512,14 @@ bad_area_nosemaphore:
6003                                         tsk->comm, tsk->pid, address, regs->rip,
6004                                         regs->rsp, error_code);
6005                 }
6006 -       
6007 +
6008 +#ifdef CONFIG_PAX_PAGEEXEC
6009 +               if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
6010 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
6011 +                       do_exit(SIGKILL);
6012 +               }
6013 +#endif
6014 +
6015                 tsk->thread.cr2 = address;
6016                 /* Kernel addresses are always protection faults */
6017                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
6018 diff -urNp linux-2.6.16.2/arch/x86_64/mm/mmap.c linux-2.6.16.2/arch/x86_64/mm/mmap.c
6019 --- linux-2.6.16.2/arch/x86_64/mm/mmap.c        2006-04-07 12:56:47.000000000 -0400
6020 +++ linux-2.6.16.2/arch/x86_64/mm/mmap.c        2006-04-09 21:23:54.000000000 -0400
6021 @@ -24,6 +24,12 @@ void arch_pick_mmap_layout(struct mm_str
6022                 unsigned rnd = get_random_int() & 0xfffffff;
6023                 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
6024         }
6025 +
6026 +#ifdef CONFIG_PAX_RANDMMAP
6027 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
6028 +               mm->mmap_base += mm->delta_mmap;
6029 +#endif
6030 +
6031         mm->get_unmapped_area = arch_get_unmapped_area;
6032         mm->unmap_area = arch_unmap_area;
6033  }
6034 diff -urNp linux-2.6.16.2/drivers/char/agp/frontend.c linux-2.6.16.2/drivers/char/agp/frontend.c
6035 --- linux-2.6.16.2/drivers/char/agp/frontend.c  2006-04-07 12:56:47.000000000 -0400
6036 +++ linux-2.6.16.2/drivers/char/agp/frontend.c  2006-04-09 21:23:54.000000000 -0400
6037 @@ -841,7 +841,7 @@ static int agpioc_reserve_wrap(struct ag
6038         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
6039                 return -EFAULT;
6040  
6041 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
6042 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
6043                 return -EFAULT;
6044  
6045         client = agp_find_client_by_pid(reserve.pid);
6046 diff -urNp linux-2.6.16.2/drivers/char/keyboard.c linux-2.6.16.2/drivers/char/keyboard.c
6047 --- linux-2.6.16.2/drivers/char/keyboard.c      2006-04-07 12:56:47.000000000 -0400
6048 +++ linux-2.6.16.2/drivers/char/keyboard.c      2006-04-09 21:23:54.000000000 -0400
6049 @@ -607,6 +607,16 @@ static void k_spec(struct vc_data *vc, u
6050              kbd->kbdmode == VC_MEDIUMRAW) &&
6051              value != KVAL(K_SAK))
6052                 return;         /* SAK is allowed even in raw mode */
6053 +
6054 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
6055 +       {
6056 +               void *func = fn_handler[value];
6057 +               if (func == fn_show_state || func == fn_show_ptregs ||
6058 +                   func == fn_show_mem)
6059 +                       return;
6060 +       }
6061 +#endif
6062 +
6063         fn_handler[value](vc, regs);
6064  }
6065  
6066 diff -urNp linux-2.6.16.2/drivers/char/mem.c linux-2.6.16.2/drivers/char/mem.c
6067 --- linux-2.6.16.2/drivers/char/mem.c   2006-04-07 12:56:47.000000000 -0400
6068 +++ linux-2.6.16.2/drivers/char/mem.c   2006-04-09 21:23:54.000000000 -0400
6069 @@ -27,6 +27,7 @@
6070  #include <linux/crash_dump.h>
6071  #include <linux/backing-dev.h>
6072  #include <linux/bootmem.h>
6073 +#include <linux/grsecurity.h>
6074  
6075  #include <asm/uaccess.h>
6076  #include <asm/io.h>
6077 @@ -35,6 +36,10 @@
6078  # include <linux/efi.h>
6079  #endif
6080  
6081 +#ifdef CONFIG_GRKERNSEC
6082 +extern struct file_operations grsec_fops;
6083 +#endif
6084 +
6085  /*
6086   * Architectures vary in how they handle caching for addresses
6087   * outside of main memory.
6088 @@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f
6089         if (!valid_phys_addr_range(p, &count))
6090                 return -EFAULT;
6091  
6092 +#ifdef CONFIG_GRKERNSEC_KMEM
6093 +       gr_handle_mem_write();
6094 +       return -EPERM;
6095 +#endif
6096 +
6097         written = 0;
6098  
6099  #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
6100 @@ -258,6 +268,11 @@ static int mmap_mem(struct file * file, 
6101                                                  size,
6102                                                  vma->vm_page_prot);
6103  
6104 +#ifdef CONFIG_GRKERNSEC_KMEM
6105 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
6106 +               return -EPERM;
6107 +#endif
6108 +
6109         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
6110         if (remap_pfn_range(vma,
6111                             vma->vm_start,
6112 @@ -487,6 +502,11 @@ static ssize_t write_kmem(struct file * 
6113         ssize_t written;
6114         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
6115  
6116 +#ifdef CONFIG_GRKERNSEC_KMEM
6117 +       gr_handle_kmem_write();
6118 +       return -EPERM;
6119 +#endif
6120 +
6121         if (p < (unsigned long) high_memory) {
6122  
6123                 wrote = count;
6124 @@ -613,7 +633,23 @@ static inline size_t read_zero_pagealign
6125                         count = size;
6126  
6127                 zap_page_range(vma, addr, count, NULL);
6128 -               zeromap_page_range(vma, addr, count, PAGE_COPY);
6129 +               zeromap_page_range(vma, addr, count, vma->vm_page_prot);
6130 +
6131 +#ifdef CONFIG_PAX_SEGMEXEC
6132 +               if (vma->vm_flags & VM_MIRROR) {
6133 +                       unsigned long addr_m;
6134 +                       struct vm_area_struct * vma_m;
6135 +
6136 +                       addr_m = vma->vm_start + vma->vm_mirror;
6137 +                       vma_m = find_vma(mm, addr_m);
6138 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
6139 +                               addr_m = addr + vma->vm_mirror;
6140 +                               zap_page_range(vma_m, addr_m, count, NULL);
6141 +                       } else
6142 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
6143 +                                      addr, vma->vm_start);
6144 +               }
6145 +#endif
6146  
6147                 size -= count;
6148                 buf += count;
6149 @@ -762,6 +798,16 @@ static loff_t memory_lseek(struct file *
6150  
6151  static int open_port(struct inode * inode, struct file * filp)
6152  {
6153 +#ifdef CONFIG_GRKERNSEC_KMEM
6154 +       gr_handle_open_port();
6155 +       return -EPERM;
6156 +#endif
6157 +
6158 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
6159 +}
6160 +
6161 +static int open_mem(struct inode * inode, struct file * filp)
6162 +{
6163         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
6164  }
6165  
6166 @@ -769,7 +815,6 @@ static int open_port(struct inode * inod
6167  #define full_lseek      null_lseek
6168  #define write_zero     write_null
6169  #define read_full       read_zero
6170 -#define open_mem       open_port
6171  #define open_kmem      open_mem
6172  #define open_oldmem    open_mem
6173  
6174 @@ -891,6 +936,11 @@ static int memory_open(struct inode * in
6175                         filp->f_op = &oldmem_fops;
6176                         break;
6177  #endif
6178 +#ifdef CONFIG_GRKERNSEC
6179 +               case 13:
6180 +                       filp->f_op = &grsec_fops;
6181 +                       break;
6182 +#endif
6183                 default:
6184                         return -ENXIO;
6185         }
6186 @@ -923,6 +973,9 @@ static const struct {
6187  #ifdef CONFIG_CRASH_DUMP
6188         {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
6189  #endif
6190 +#ifdef CONFIG_GRKERNSEC
6191 +       {13,"grsec",    S_IRUSR | S_IWUGO,          &grsec_fops},
6192 +#endif
6193  };
6194  
6195  static struct class *mem_class;
6196 diff -urNp linux-2.6.16.2/drivers/char/random.c linux-2.6.16.2/drivers/char/random.c
6197 --- linux-2.6.16.2/drivers/char/random.c        2006-04-07 12:56:47.000000000 -0400
6198 +++ linux-2.6.16.2/drivers/char/random.c        2006-04-09 21:23:54.000000000 -0400
6199 @@ -249,8 +249,13 @@
6200  /*
6201   * Configuration information
6202   */
6203 +#ifdef CONFIG_GRKERNSEC_RANDNET
6204 +#define INPUT_POOL_WORDS 256
6205 +#define OUTPUT_POOL_WORDS 64
6206 +#else
6207  #define INPUT_POOL_WORDS 128
6208  #define OUTPUT_POOL_WORDS 32
6209 +#endif
6210  #define SEC_XFER_SIZE 512
6211  
6212  /*
6213 @@ -1659,3 +1664,25 @@ randomize_range(unsigned long start, uns
6214                 return 0;
6215         return PAGE_ALIGN(get_random_int() % range + start);
6216  }
6217 +
6218 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
6219 +unsigned long pax_get_random_long(void)
6220 +{
6221 +       static time_t   rekey_time;
6222 +       static __u32    secret[12];
6223 +       time_t          t;
6224 +
6225 +       /*
6226 +        * Pick a random secret every REKEY_INTERVAL seconds.
6227 +        */
6228 +       t = get_seconds();
6229 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
6230 +               rekey_time = t;
6231 +               get_random_bytes(secret, sizeof(secret));
6232 +       }
6233 +
6234 +       secret[1] = half_md4_transform(secret+8, secret);
6235 +       secret[0] = half_md4_transform(secret+8, secret);
6236 +       return *(unsigned long *)secret;
6237 +}
6238 +#endif
6239 diff -urNp linux-2.6.16.2/drivers/char/vt_ioctl.c linux-2.6.16.2/drivers/char/vt_ioctl.c
6240 --- linux-2.6.16.2/drivers/char/vt_ioctl.c      2006-04-07 12:56:47.000000000 -0400
6241 +++ linux-2.6.16.2/drivers/char/vt_ioctl.c      2006-04-09 21:23:54.000000000 -0400
6242 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
6243         case KDSKBENT:
6244                 if (!perm)
6245                         return -EPERM;
6246 +
6247 +#ifdef CONFIG_GRKERNSEC
6248 +               if (!capable(CAP_SYS_TTY_CONFIG))
6249 +                       return -EPERM;
6250 +#endif
6251 +
6252                 if (!i && v == K_NOSUCHMAP) {
6253                         /* disallocate map */
6254                         key_map = key_maps[s];
6255 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
6256                         goto reterr;
6257                 }
6258  
6259 +#ifdef CONFIG_GRKERNSEC
6260 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
6261 +                       ret = -EPERM;
6262 +                       goto reterr;
6263 +               }
6264 +#endif
6265 +
6266                 q = func_table[i];
6267                 first_free = funcbufptr + (funcbufsize - funcbufleft);
6268                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
6269 diff -urNp linux-2.6.16.2/drivers/ieee1394/ohci1394.c linux-2.6.16.2/drivers/ieee1394/ohci1394.c
6270 --- linux-2.6.16.2/drivers/ieee1394/ohci1394.c  2006-04-07 12:56:47.000000000 -0400
6271 +++ linux-2.6.16.2/drivers/ieee1394/ohci1394.c  2006-04-09 21:23:54.000000000 -0400
6272 @@ -162,9 +162,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
6273  printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
6274  
6275  /* Module Parameters */
6276 -static int phys_dma = 1;
6277 +static int phys_dma = 0;
6278  module_param(phys_dma, int, 0644);
6279 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
6280 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
6281  
6282  static void dma_trm_tasklet(unsigned long data);
6283  static void dma_trm_reset(struct dma_trm_ctx *d);
6284 diff -urNp linux-2.6.16.2/drivers/mtd/devices/doc2001.c linux-2.6.16.2/drivers/mtd/devices/doc2001.c
6285 --- linux-2.6.16.2/drivers/mtd/devices/doc2001.c        2006-04-07 12:56:47.000000000 -0400
6286 +++ linux-2.6.16.2/drivers/mtd/devices/doc2001.c        2006-04-09 21:23:54.000000000 -0400
6287 @@ -423,6 +423,8 @@ static int doc_read_ecc (struct mtd_info
6288         /* Don't allow read past end of device */
6289         if (from >= this->totlen)
6290                 return -EINVAL;
6291 +       if (!len)
6292 +               return -EINVAL;
6293  
6294         /* Don't allow a single read to cross a 512-byte block boundary */
6295         if (from + len > ((from | 0x1ff) + 1))
6296 diff -urNp linux-2.6.16.2/drivers/net/wan/sdla_ppp.c linux-2.6.16.2/drivers/net/wan/sdla_ppp.c
6297 --- linux-2.6.16.2/drivers/net/wan/sdla_ppp.c   2006-04-07 12:56:47.000000000 -0400
6298 +++ linux-2.6.16.2/drivers/net/wan/sdla_ppp.c   2006-04-09 21:23:54.000000000 -0400
6299 @@ -451,7 +451,7 @@ static int update(struct wan_device *wan
6300         sdla_t* card = wandev->private;
6301         struct net_device* dev;
6302          volatile ppp_private_area_t *ppp_priv_area;
6303 -       ppp_flags_t *flags = card->flags;
6304 +       ppp_flags_t *flags;
6305         unsigned long timeout;
6306  
6307         /* sanity checks */
6308 @@ -475,6 +475,7 @@ static int update(struct wan_device *wan
6309         
6310         ppp_priv_area->update_comms_stats = 2;
6311         ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
6312 +       flags = card->flags;
6313         flags->imask |= PPP_INTR_TIMER; 
6314         
6315         /* wait a maximum of 1 second for the statistics to be updated */ 
6316 diff -urNp linux-2.6.16.2/drivers/pci/proc.c linux-2.6.16.2/drivers/pci/proc.c
6317 --- linux-2.6.16.2/drivers/pci/proc.c   2006-04-07 12:56:47.000000000 -0400
6318 +++ linux-2.6.16.2/drivers/pci/proc.c   2006-04-09 21:23:54.000000000 -0400
6319 @@ -569,7 +569,15 @@ static struct file_operations proc_pci_o
6320  
6321  static void legacy_proc_init(void)
6322  {
6323 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6324 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6325 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR, NULL);
6326 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6327 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
6328 +#endif
6329 +#else
6330         struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
6331 +#endif
6332         if (entry)
6333                 entry->proc_fops = &proc_pci_operations;
6334  }
6335 @@ -598,7 +606,15 @@ static int __init pci_proc_init(void)
6336  {
6337         struct proc_dir_entry *entry;
6338         struct pci_dev *dev = NULL;
6339 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6340 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6341 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
6342 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6343 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
6344 +#endif
6345 +#else
6346         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
6347 +#endif
6348         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
6349         if (entry)
6350                 entry->proc_fops = &proc_bus_pci_dev_operations;
6351 diff -urNp linux-2.6.16.2/drivers/pnp/pnpbios/bioscalls.c linux-2.6.16.2/drivers/pnp/pnpbios/bioscalls.c
6352 --- linux-2.6.16.2/drivers/pnp/pnpbios/bioscalls.c      2006-04-07 12:56:47.000000000 -0400
6353 +++ linux-2.6.16.2/drivers/pnp/pnpbios/bioscalls.c      2006-04-09 21:23:54.000000000 -0400
6354 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
6355  set_limit(gdt[(selname) >> 3], size); \
6356  } while(0)
6357  
6358 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
6359 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
6360  
6361  /*
6362   * At some point we want to use this stack frame pointer to unwind
6363 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
6364         struct desc_struct save_desc_40;
6365         int cpu;
6366  
6367 +#ifdef CONFIG_PAX_KERNEXEC
6368 +       unsigned long cr0;
6369 +#endif
6370 +
6371         /*
6372          * PnP BIOSes are generally not terribly re-entrant.
6373          * Also, don't rely on them to save everything correctly.
6374 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
6375         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
6376         spin_lock_irqsave(&pnp_bios_lock, flags);
6377  
6378 +#ifdef CONFIG_PAX_KERNEXEC
6379 +       pax_open_kernel(cr0);
6380 +#endif
6381 +
6382         /* The lock prevents us bouncing CPU here */
6383         if (ts1_size)
6384                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
6385 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
6386                   "i" (0)
6387                 : "memory"
6388         );
6389 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
6390  
6391         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
6392 +
6393 +#ifdef CONFIG_PAX_KERNEXEC
6394 +       pax_close_kernel(cr0);
6395 +#endif
6396 +
6397 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
6398         put_cpu();
6399  
6400         /* If we get here and this is set then the PnP BIOS faulted on us. */
6401 diff -urNp linux-2.6.16.2/drivers/scsi/libata-scsi.c linux-2.6.16.2/drivers/scsi/libata-scsi.c
6402 --- linux-2.6.16.2/drivers/scsi/libata-scsi.c   2006-04-07 12:56:47.000000000 -0400
6403 +++ linux-2.6.16.2/drivers/scsi/libata-scsi.c   2006-04-09 21:23:54.000000000 -0400
6404 @@ -1553,7 +1553,7 @@ unsigned int ata_scsiop_inq_80(struct at
6405         return 0;
6406  }
6407  
6408 -static const char * const inq_83_str = "Linux ATA-SCSI simulator";
6409 +static const char inq_83_str[] = "Linux ATA-SCSI simulator";
6410  
6411  /**
6412   *     ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
6413 @@ -1572,13 +1572,13 @@ unsigned int ata_scsiop_inq_83(struct at
6414                               unsigned int buflen)
6415  {
6416         rbuf[1] = 0x83;                 /* this page code */
6417 -       rbuf[3] = 4 + strlen(inq_83_str);       /* page len */
6418 +       rbuf[3] = 3 + sizeof(inq_83_str);       /* page len */
6419  
6420         /* our one and only identification descriptor (vendor-specific) */
6421 -       if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) {
6422 +       if (buflen >= (sizeof(inq_83_str) + 4 + 4 - 1)) {
6423                 rbuf[4 + 0] = 2;        /* code set: ASCII */
6424 -               rbuf[4 + 3] = strlen(inq_83_str);
6425 -               memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str));
6426 +               rbuf[4 + 3] = sizeof(inq_83_str)-1;
6427 +               memcpy(rbuf + 4 + 4, inq_83_str, sizeof(inq_83_str)-1);
6428         }
6429  
6430         return 0;
6431 diff -urNp linux-2.6.16.2/drivers/video/vesafb.c linux-2.6.16.2/drivers/video/vesafb.c
6432 --- linux-2.6.16.2/drivers/video/vesafb.c       2006-04-07 12:56:47.000000000 -0400
6433 +++ linux-2.6.16.2/drivers/video/vesafb.c       2006-04-09 21:23:54.000000000 -0400
6434 @@ -251,7 +251,7 @@ static int __init vesafb_probe(struct pl
6435                 size_remap = size_total;
6436         vesafb_fix.smem_len = size_remap;
6437  
6438 -#ifndef __i386__
6439 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
6440         screen_info.vesapm_seg = 0;
6441  #endif
6442  
6443 diff -urNp linux-2.6.16.2/fs/binfmt_aout.c linux-2.6.16.2/fs/binfmt_aout.c
6444 --- linux-2.6.16.2/fs/binfmt_aout.c     2006-04-07 12:56:47.000000000 -0400
6445 +++ linux-2.6.16.2/fs/binfmt_aout.c     2006-04-09 21:23:54.000000000 -0400
6446 @@ -24,6 +24,7 @@
6447  #include <linux/binfmts.h>
6448  #include <linux/personality.h>
6449  #include <linux/init.h>
6450 +#include <linux/grsecurity.h>
6451  
6452  #include <asm/system.h>
6453  #include <asm/uaccess.h>
6454 @@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
6455  /* If the size of the dump file exceeds the rlimit, then see what would happen
6456     if we wrote the stack, but not the data area.  */
6457  #ifdef __sparc__
6458 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
6459         if ((dump.u_dsize+dump.u_ssize) >
6460             current->signal->rlim[RLIMIT_CORE].rlim_cur)
6461                 dump.u_dsize = 0;
6462  #else
6463 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
6464         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
6465             current->signal->rlim[RLIMIT_CORE].rlim_cur)
6466                 dump.u_dsize = 0;
6467 @@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
6468  
6469  /* Make sure we have enough room to write the stack and data areas. */
6470  #ifdef __sparc__
6471 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
6472         if ((dump.u_ssize) >
6473             current->signal->rlim[RLIMIT_CORE].rlim_cur)
6474                 dump.u_ssize = 0;
6475  #else
6476 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
6477         if ((dump.u_ssize+1) * PAGE_SIZE >
6478             current->signal->rlim[RLIMIT_CORE].rlim_cur)
6479                 dump.u_ssize = 0;
6480 @@ -287,6 +292,8 @@ static int load_aout_binary(struct linux
6481         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
6482         if (rlim >= RLIM_INFINITY)
6483                 rlim = ~0;
6484 +
6485 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
6486         if (ex.a_data + ex.a_bss > rlim)
6487                 return -ENOMEM;
6488  
6489 @@ -319,6 +326,28 @@ static int load_aout_binary(struct linux
6490         current->mm->mmap = NULL;
6491         compute_creds(bprm);
6492         current->flags &= ~PF_FORKNOEXEC;
6493 +
6494 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
6495 +       current->mm->pax_flags = 0UL;
6496 +#endif
6497 +
6498 +#ifdef CONFIG_PAX_PAGEEXEC
6499 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
6500 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
6501 +
6502 +#ifdef CONFIG_PAX_EMUTRAMP
6503 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
6504 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
6505 +#endif
6506 +
6507 +#ifdef CONFIG_PAX_MPROTECT
6508 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
6509 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
6510 +#endif
6511 +
6512 +       }
6513 +#endif
6514 +
6515  #ifdef __sparc__
6516         if (N_MAGIC(ex) == NMAGIC) {
6517                 loff_t pos = fd_offset;
6518 @@ -414,7 +443,7 @@ static int load_aout_binary(struct linux
6519  
6520                 down_write(&current->mm->mmap_sem);
6521                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
6522 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
6523 +                               PROT_READ | PROT_WRITE,
6524                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
6525                                 fd_offset + ex.a_text);
6526                 up_write(&current->mm->mmap_sem);
6527 diff -urNp linux-2.6.16.2/fs/binfmt_elf.c linux-2.6.16.2/fs/binfmt_elf.c
6528 --- linux-2.6.16.2/fs/binfmt_elf.c      2006-04-07 12:56:47.000000000 -0400
6529 +++ linux-2.6.16.2/fs/binfmt_elf.c      2006-04-09 21:23:54.000000000 -0400
6530 @@ -38,11 +38,16 @@
6531  #include <linux/security.h>
6532  #include <linux/syscalls.h>
6533  #include <linux/random.h>
6534 +#include <linux/grsecurity.h>
6535  
6536  #include <asm/uaccess.h>
6537  #include <asm/param.h>
6538  #include <asm/page.h>
6539  
6540 +#ifdef CONFIG_PAX_SEGMEXEC
6541 +#include <asm/desc.h>
6542 +#endif
6543 +
6544  #include <linux/elf.h>
6545  
6546  static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
6547 @@ -90,6 +95,8 @@ static struct linux_binfmt elf_format = 
6548  
6549  static int set_brk(unsigned long start, unsigned long end)
6550  {
6551 +       unsigned long e = end;
6552 +
6553         start = ELF_PAGEALIGN(start);
6554         end = ELF_PAGEALIGN(end);
6555         if (end > start) {
6556 @@ -100,7 +107,7 @@ static int set_brk(unsigned long start, 
6557                 if (BAD_ADDR(addr))
6558                         return addr;
6559         }
6560 -       current->mm->start_brk = current->mm->brk = end;
6561 +       current->mm->start_brk = current->mm->brk = e;
6562         return 0;
6563  }
6564  
6565 @@ -316,10 +323,9 @@ static unsigned long load_elf_interp(str
6566  {
6567         struct elf_phdr *elf_phdata;
6568         struct elf_phdr *eppnt;
6569 -       unsigned long load_addr = 0;
6570 -       int load_addr_set = 0;
6571 +       unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
6572         unsigned long last_bss = 0, elf_bss = 0;
6573 -       unsigned long error = ~0UL;
6574 +       unsigned long error = -EINVAL;
6575         int retval, i, size;
6576  
6577         /* First of all, some simple consistency checks */
6578 @@ -358,59 +364,80 @@ static unsigned long load_elf_interp(str
6579                 goto out_close;
6580         }
6581  
6582 +#ifdef CONFIG_PAX_SEGMEXEC
6583 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6584 +               task_size = SEGMEXEC_TASK_SIZE;
6585 +#endif
6586 +
6587         eppnt = elf_phdata;
6588 +       min_addr = task_size;
6589 +       max_addr = 0;
6590 +       error = -ENOMEM;
6591 +
6592         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
6593 -         if (eppnt->p_type == PT_LOAD) {
6594 -           int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
6595 -           int elf_prot = 0;
6596 -           unsigned long vaddr = 0;
6597 -           unsigned long k, map_addr;
6598 -
6599 -           if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
6600 -           if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
6601 -           if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
6602 -           vaddr = eppnt->p_vaddr;
6603 -           if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
6604 -               elf_type |= MAP_FIXED;
6605 -
6606 -           map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
6607 -           error = map_addr;
6608 -           if (BAD_ADDR(map_addr))
6609 -               goto out_close;
6610 -
6611 -           if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
6612 -               load_addr = map_addr - ELF_PAGESTART(vaddr);
6613 -               load_addr_set = 1;
6614 -           }
6615 -
6616 -           /*
6617 -            * Check to see if the section's size will overflow the
6618 -            * allowed task size. Note that p_filesz must always be
6619 -            * <= p_memsize so it is only necessary to check p_memsz.
6620 -            */
6621 -           k = load_addr + eppnt->p_vaddr;
6622 -           if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz ||
6623 -               eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
6624 -               error = -ENOMEM;
6625 +               if (eppnt->p_type != PT_LOAD)
6626 +                       continue;
6627 +
6628 +               /*
6629 +                * Check to see if the section's size will overflow the
6630 +                * allowed task size. Note that p_filesz must always be
6631 +                * <= p_memsize so it is only necessary to check p_memsz.
6632 +                */
6633 +               if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
6634 +                       goto out_close;
6635 +
6636 +               if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
6637 +                       min_addr = ELF_PAGESTART(eppnt->p_vaddr);
6638 +               if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
6639 +                       max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
6640 +       }
6641 +       if (min_addr >= max_addr)
6642                 goto out_close;
6643 -           }
6644  
6645 -           /*
6646 -            * Find the end of the file mapping for this phdr, and keep
6647 -            * track of the largest address we see for this.
6648 -            */
6649 -           k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
6650 -           if (k > elf_bss)
6651 -               elf_bss = k;
6652 -
6653 -           /*
6654 -            * Do the same thing for the memory mapping - between
6655 -            * elf_bss and last_bss is the bss section.
6656 -            */
6657 -           k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
6658 -           if (k > last_bss)
6659 -               last_bss = k;
6660 -         }
6661 +       eppnt = elf_phdata;
6662 +       for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
6663 +               int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
6664 +               int elf_prot = 0;
6665 +               unsigned long vaddr;
6666 +               unsigned long k, map_addr;
6667 +
6668 +               if (eppnt->p_type != PT_LOAD)
6669 +                       continue;
6670 +
6671 +               if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
6672 +               if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
6673 +               if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
6674 +               vaddr = eppnt->p_vaddr;
6675 +
6676 +               if (!load_addr && interp_elf_ex->e_type == ET_DYN) {
6677 +                       load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
6678 +
6679 +                       if (load_addr > task_size)
6680 +                               goto out_close;
6681 +
6682 +                       load_addr -= min_addr;
6683 +               }
6684 +
6685 +               map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
6686 +               error = map_addr;
6687 +               if (BAD_ADDR(map_addr))
6688 +                       goto out_close;
6689 +
6690 +               /*
6691 +                * Find the end of the file mapping for this phdr, and keep
6692 +                * track of the largest address we see for this.
6693 +                */
6694 +               k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
6695 +               if (k > elf_bss)
6696 +                       elf_bss = k;
6697 +
6698 +               /*
6699 +                * Do the same thing for the memory mapping - between
6700 +                * elf_bss and last_bss is the bss section.
6701 +                */
6702 +               k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
6703 +               if (k > last_bss)
6704 +                       last_bss = k;
6705         }
6706  
6707         /*
6708 @@ -447,7 +474,7 @@ out:
6709  static unsigned long load_aout_interp(struct exec * interp_ex,
6710                              struct file * interpreter)
6711  {
6712 -       unsigned long text_data, elf_entry = ~0UL;
6713 +       unsigned long text_data, elf_entry = -EINVAL;
6714         char __user * addr;
6715         loff_t offset;
6716  
6717 @@ -491,6 +518,180 @@ out:
6718         return elf_entry;
6719  }
6720  
6721 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
6722 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
6723 +{
6724 +       unsigned long pax_flags = 0UL;
6725 +
6726 +#ifdef CONFIG_PAX_PAGEEXEC
6727 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
6728 +               pax_flags |= MF_PAX_PAGEEXEC;
6729 +#endif
6730 +
6731 +#ifdef CONFIG_PAX_SEGMEXEC
6732 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
6733 +               pax_flags |= MF_PAX_SEGMEXEC;
6734 +#endif
6735 +
6736 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
6737 +       if (pax_flags & MF_PAX_PAGEEXEC)
6738 +               pax_flags &= ~MF_PAX_SEGMEXEC;
6739 +#endif
6740 +
6741 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
6742 +       if (pax_flags & MF_PAX_SEGMEXEC)
6743 +               pax_flags &= ~MF_PAX_PAGEEXEC;
6744 +#endif
6745 +
6746 +#ifdef CONFIG_PAX_EMUTRAMP
6747 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
6748 +               pax_flags |= MF_PAX_EMUTRAMP;
6749 +#endif
6750 +
6751 +#ifdef CONFIG_PAX_MPROTECT
6752 +       if (elf_phdata->p_flags & PF_MPROTECT)
6753 +               pax_flags |= MF_PAX_MPROTECT;
6754 +#endif
6755 +
6756 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
6757 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
6758 +               pax_flags |= MF_PAX_RANDMMAP;
6759 +#endif
6760 +
6761 +       return pax_flags;
6762 +}
6763 +#endif
6764 +
6765 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
6766 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
6767 +{
6768 +       unsigned long pax_flags = 0UL;
6769 +
6770 +#ifdef CONFIG_PAX_PAGEEXEC
6771 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
6772 +               pax_flags |= MF_PAX_PAGEEXEC;
6773 +#endif
6774 +
6775 +#ifdef CONFIG_PAX_SEGMEXEC
6776 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
6777 +               pax_flags |= MF_PAX_SEGMEXEC;
6778 +#endif
6779 +
6780 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
6781 +       if (pax_flags & MF_PAX_PAGEEXEC)
6782 +               pax_flags &= ~MF_PAX_SEGMEXEC;
6783 +#endif
6784 +
6785 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
6786 +       if (pax_flags & MF_PAX_SEGMEXEC)
6787 +               pax_flags &= ~MF_PAX_PAGEEXEC;
6788 +#endif
6789 +
6790 +#ifdef CONFIG_PAX_EMUTRAMP
6791 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
6792 +               pax_flags |= MF_PAX_EMUTRAMP;
6793 +#endif
6794 +
6795 +#ifdef CONFIG_PAX_MPROTECT
6796 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
6797 +               pax_flags |= MF_PAX_MPROTECT;
6798 +#endif
6799 +
6800 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
6801 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
6802 +               pax_flags |= MF_PAX_RANDMMAP;
6803 +#endif
6804 +
6805 +       return pax_flags;
6806 +}
6807 +#endif
6808 +
6809 +#ifdef CONFIG_PAX_EI_PAX
6810 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
6811 +{
6812 +       unsigned long pax_flags = 0UL;
6813 +
6814 +#ifdef CONFIG_PAX_PAGEEXEC
6815 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
6816 +               pax_flags |= MF_PAX_PAGEEXEC;
6817 +#endif
6818 +
6819 +#ifdef CONFIG_PAX_SEGMEXEC
6820 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
6821 +               pax_flags |= MF_PAX_SEGMEXEC;
6822 +#endif
6823 +
6824 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
6825 +       if (pax_flags & MF_PAX_PAGEEXEC)
6826 +               pax_flags &= ~MF_PAX_SEGMEXEC;
6827 +#endif
6828 +
6829 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
6830 +       if (pax_flags & MF_PAX_SEGMEXEC)
6831 +               pax_flags &= ~MF_PAX_PAGEEXEC;
6832 +#endif
6833 +
6834 +#ifdef CONFIG_PAX_EMUTRAMP
6835 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
6836 +               pax_flags |= MF_PAX_EMUTRAMP;
6837 +#endif
6838 +
6839 +#ifdef CONFIG_PAX_MPROTECT
6840 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
6841 +               pax_flags |= MF_PAX_MPROTECT;
6842 +#endif
6843 +
6844 +#ifdef CONFIG_PAX_ASLR
6845 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
6846 +               pax_flags |= MF_PAX_RANDMMAP;
6847 +#endif
6848 +
6849 +       return pax_flags;
6850 +}
6851 +#endif
6852 +
6853 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
6854 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
6855 +{
6856 +       unsigned long pax_flags = 0UL;
6857 +
6858 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
6859 +       unsigned long i;
6860 +#endif
6861 +
6862 +#ifdef CONFIG_PAX_EI_PAX
6863 +       pax_flags = pax_parse_ei_pax(elf_ex);
6864 +#endif
6865 +
6866 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
6867 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
6868 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
6869 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
6870 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
6871 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
6872 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
6873 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
6874 +                               return -EINVAL;
6875 +
6876 +#ifdef CONFIG_PAX_SOFTMODE
6877 +                       if (pax_softmode)
6878 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
6879 +                       else
6880 +#endif
6881 +
6882 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
6883 +                       break;
6884 +               }
6885 +#endif
6886 +
6887 +       if (0 > pax_check_flags(&pax_flags))
6888 +               return -EINVAL;
6889 +
6890 +       current->mm->pax_flags = pax_flags;
6891 +       return 0;
6892 +}
6893 +#endif
6894 +
6895  /*
6896   * These are the functions used to load ELF style executables and shared
6897   * libraries.  There is no binary dependent code anywhere else.
6898 @@ -522,7 +723,7 @@ static int load_elf_binary(struct linux_
6899         char * elf_interpreter = NULL;
6900         unsigned int interpreter_type = INTERPRETER_NONE;
6901         unsigned char ibcs2_interpreter = 0;
6902 -       unsigned long error;
6903 +       unsigned long error = 0;
6904         struct elf_phdr * elf_ppnt, *elf_phdata;
6905         unsigned long elf_bss, elf_brk;
6906         int elf_exec_fileno;
6907 @@ -540,6 +741,7 @@ static int load_elf_binary(struct linux_
6908                 struct elfhdr interp_elf_ex;
6909                 struct exec interp_ex;
6910         } *loc;
6911 +       unsigned long task_size = TASK_SIZE;
6912  
6913         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
6914         if (!loc) {
6915 @@ -765,14 +967,88 @@ static int load_elf_binary(struct linux_
6916         current->mm->end_code = 0;
6917         current->mm->mmap = NULL;
6918         current->flags &= ~PF_FORKNOEXEC;
6919 +
6920 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
6921 +       current->mm->pax_flags = 0UL;
6922 +#endif
6923 +
6924 +#ifdef CONFIG_PAX_DLRESOLVE
6925 +       current->mm->call_dl_resolve = 0UL;
6926 +#endif
6927 +
6928 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
6929 +       current->mm->call_syscall = 0UL;
6930 +#endif
6931 +
6932 +#ifdef CONFIG_PAX_ASLR
6933 +       current->mm->delta_mmap = 0UL;
6934 +       current->mm->delta_exec = 0UL;
6935 +       current->mm->delta_stack = 0UL;
6936 +#endif
6937 +
6938         current->mm->def_flags = def_flags;
6939  
6940 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
6941 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
6942 +               send_sig(SIGKILL, current, 0);
6943 +               goto out_free_dentry;
6944 +       }
6945 +#endif
6946 +
6947 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
6948 +       pax_set_initial_flags(bprm);
6949 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
6950 +       if (pax_set_initial_flags_func)
6951 +               (pax_set_initial_flags_func)(bprm);
6952 +#endif
6953 +
6954 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
6955 +       if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
6956 +               current->mm->context.user_cs_limit = PAGE_SIZE;
6957 +#endif
6958 +
6959 +#ifdef CONFIG_PAX_SEGMEXEC
6960 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
6961 +               int cpu = get_cpu();
6962 +
6963 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
6964 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
6965 +               set_user_cs(current->mm, cpu);
6966 +               put_cpu();
6967 +               task_size = SEGMEXEC_TASK_SIZE;
6968 +       }
6969 +#endif
6970 +
6971 +#ifdef CONFIG_PAX_ASLR
6972 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
6973 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
6974 +
6975 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
6976 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
6977 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
6978 +       }
6979 +#endif
6980 +
6981 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6982 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
6983 +               executable_stack = EXSTACK_DEFAULT;
6984 +#endif
6985 +
6986         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
6987            may depend on the personality.  */
6988         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
6989 +
6990 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6991 +       if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
6992 +#endif
6993 +
6994         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
6995                 current->personality |= READ_IMPLIES_EXEC;
6996  
6997 +#ifdef CONFIG_PAX_ASLR
6998 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
6999 +#endif
7000 +
7001         if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
7002                 current->flags |= PF_RANDOMIZE;
7003         arch_pick_mmap_layout(current->mm);
7004 @@ -844,6 +1120,15 @@ static int load_elf_binary(struct linux_
7005                            base, as well as whatever program they might try to exec.  This
7006                            is because the brk will follow the loader, and is not movable.  */
7007                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
7008 +
7009 +#ifdef CONFIG_PAX_RANDMMAP
7010 +                       /* PaX: randomize base address at the default exe base if requested */
7011 +                       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
7012 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
7013 +                               elf_flags |= MAP_FIXED;
7014 +                       }
7015 +#endif
7016 +
7017                 }
7018  
7019                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
7020 @@ -871,9 +1156,9 @@ static int load_elf_binary(struct linux_
7021                  * allowed task size. Note that p_filesz must always be
7022                  * <= p_memsz so it is only necessary to check p_memsz.
7023                  */
7024 -               if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
7025 -                   elf_ppnt->p_memsz > TASK_SIZE ||
7026 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
7027 +               if (k > task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
7028 +                   elf_ppnt->p_memsz > task_size ||
7029 +                   task_size - elf_ppnt->p_memsz < k) {
7030                         /* set_brk can never work.  Avoid overflows.  */
7031                         send_sig(SIGKILL, current, 0);
7032                         goto out_free_dentry;
7033 @@ -900,6 +1185,12 @@ static int load_elf_binary(struct linux_
7034         start_data += load_bias;
7035         end_data += load_bias;
7036  
7037 +#ifdef CONFIG_PAX_RANDMMAP
7038 +       if (randomize_va_space)
7039 +               elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
7040 +#undef pax_delta_mask
7041 +#endif
7042 +
7043         /* Calling set_brk effectively mmaps the pages that we need
7044          * for the bss and break sections.  We must do this before
7045          * mapping in the interpreter, to make sure it doesn't wind
7046 @@ -928,7 +1219,7 @@ static int load_elf_binary(struct linux_
7047                         printk(KERN_ERR "Unable to load interpreter %.128s\n",
7048                                 elf_interpreter);
7049                         force_sig(SIGSEGV, current);
7050 -                       retval = -ENOEXEC; /* Nobody gets to see this, but.. */
7051 +                       retval = elf_entry; /* Nobody gets to see this, but.. */
7052                         goto out_free_dentry;
7053                 }
7054                 reloc_func_desc = interp_load_addr;
7055 @@ -1152,7 +1443,7 @@ static int dump_seek(struct file *file, 
7056   *
7057   * I think we should skip something. But I am not sure how. H.J.
7058   */
7059 -static int maydump(struct vm_area_struct *vma)
7060 +static int maydump(struct vm_area_struct *vma, long signr)
7061  {
7062         /* Do not dump I/O mapped devices or special mappings */
7063         if (vma->vm_flags & (VM_IO | VM_RESERVED))
7064 @@ -1163,7 +1454,7 @@ static int maydump(struct vm_area_struct
7065                 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
7066  
7067         /* If it hasn't been written to, don't write it out */
7068 -       if (!vma->anon_vma)
7069 +       if (signr != SIGKILL && !vma->anon_vma)
7070                 return 0;
7071  
7072         return 1;
7073 @@ -1217,8 +1508,11 @@ static int writenote(struct memelfnote *
7074  #undef DUMP_SEEK
7075  
7076  #define DUMP_WRITE(addr, nr)   \
7077 +       do { \
7078 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
7079         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
7080 -               goto end_coredump;
7081 +               goto end_coredump; \
7082 +       } while (0);
7083  #define DUMP_SEEK(off) \
7084         if (!dump_seek(file, (off))) \
7085                 goto end_coredump;
7086 @@ -1569,7 +1863,7 @@ static int elf_core_dump(long signr, str
7087                 phdr.p_offset = offset;
7088                 phdr.p_vaddr = vma->vm_start;
7089                 phdr.p_paddr = 0;
7090 -               phdr.p_filesz = maydump(vma) ? sz : 0;
7091 +               phdr.p_filesz = maydump(vma, signr) ? sz : 0;
7092                 phdr.p_memsz = sz;
7093                 offset += phdr.p_filesz;
7094                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
7095 @@ -1602,7 +1896,7 @@ static int elf_core_dump(long signr, str
7096         for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
7097                 unsigned long addr;
7098  
7099 -               if (!maydump(vma))
7100 +               if (!maydump(vma, signr))
7101                         continue;
7102  
7103                 for (addr = vma->vm_start;
7104 @@ -1621,6 +1915,7 @@ static int elf_core_dump(long signr, str
7105                                         void *kaddr;
7106                                         flush_cache_page(vma, addr, page_to_pfn(page));
7107                                         kaddr = kmap(page);
7108 +                                       gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
7109                                         if ((size += PAGE_SIZE) > limit ||
7110                                             !dump_write(file, kaddr,
7111                                             PAGE_SIZE)) {
7112 diff -urNp linux-2.6.16.2/fs/binfmt_flat.c linux-2.6.16.2/fs/binfmt_flat.c
7113 --- linux-2.6.16.2/fs/binfmt_flat.c     2006-04-07 12:56:47.000000000 -0400
7114 +++ linux-2.6.16.2/fs/binfmt_flat.c     2006-04-09 21:23:54.000000000 -0400
7115 @@ -541,7 +541,9 @@ static int load_flat_file(struct linux_b
7116                                 realdatastart = (unsigned long) -ENOMEM;
7117                         printk("Unable to allocate RAM for process data, errno %d\n",
7118                                         (int)-datapos);
7119 +                       down_write(&current->mm->mmap_sem);
7120                         do_munmap(current->mm, textpos, text_len);
7121 +                       up_write(&current->mm->mmap_sem);
7122                         return realdatastart;
7123                 }
7124                 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
7125 @@ -562,8 +564,10 @@ static int load_flat_file(struct linux_b
7126                 }
7127                 if (result >= (unsigned long)-4096) {
7128                         printk("Unable to read data+bss, errno %d\n", (int)-result);
7129 +                       down_write(&current->mm->mmap_sem);
7130                         do_munmap(current->mm, textpos, text_len);
7131                         do_munmap(current->mm, realdatastart, data_len + extra);
7132 +                       up_write(&current->mm->mmap_sem);
7133                         return result;
7134                 }
7135  
7136 @@ -625,8 +629,10 @@ static int load_flat_file(struct linux_b
7137                 }
7138                 if (result >= (unsigned long)-4096) {
7139                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
7140 +                       down_write(&current->mm->mmap_sem);
7141                         do_munmap(current->mm, textpos, text_len + data_len + extra +
7142                                 MAX_SHARED_LIBS * sizeof(unsigned long));
7143 +                       up_write(&current->mm->mmap_sem);
7144                         return result;
7145                 }
7146         }
7147 diff -urNp linux-2.6.16.2/fs/binfmt_misc.c linux-2.6.16.2/fs/binfmt_misc.c
7148 --- linux-2.6.16.2/fs/binfmt_misc.c     2006-04-07 12:56:47.000000000 -0400
7149 +++ linux-2.6.16.2/fs/binfmt_misc.c     2006-04-09 21:23:54.000000000 -0400
7150 @@ -112,9 +112,11 @@ static int load_misc_binary(struct linux
7151         struct files_struct *files = NULL;
7152  
7153         retval = -ENOEXEC;
7154 -       if (!enabled)
7155 +       if (!enabled || bprm->misc)
7156                 goto _ret;
7157  
7158 +       bprm->misc++;
7159 +
7160         /* to keep locking time low, we copy the interpreter string */
7161         read_lock(&entries_lock);
7162         fmt = check_file(bprm);
7163 diff -urNp linux-2.6.16.2/fs/buffer.c linux-2.6.16.2/fs/buffer.c
7164 --- linux-2.6.16.2/fs/buffer.c  2006-04-07 12:56:47.000000000 -0400
7165 +++ linux-2.6.16.2/fs/buffer.c  2006-04-09 21:23:54.000000000 -0400
7166 @@ -42,6 +42,7 @@
7167  #include <linux/bitops.h>
7168  #include <linux/mpage.h>
7169  #include <linux/bit_spinlock.h>
7170 +#include <linux/grsecurity.h>
7171  
7172  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
7173  static void invalidate_bh_lrus(void);
7174 @@ -2166,6 +2167,7 @@ static int __generic_cont_expand(struct 
7175  
7176         err = -EFBIG;
7177          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
7178 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
7179         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
7180                 send_sig(SIGXFSZ, current, 0);
7181                 goto out;
7182 diff -urNp linux-2.6.16.2/fs/compat.c linux-2.6.16.2/fs/compat.c
7183 --- linux-2.6.16.2/fs/compat.c  2006-04-07 12:56:47.000000000 -0400
7184 +++ linux-2.6.16.2/fs/compat.c  2006-04-09 21:23:54.000000000 -0400
7185 @@ -46,6 +46,7 @@
7186  #include <linux/rwsem.h>
7187  #include <linux/acct.h>
7188  #include <linux/mm.h>
7189 +#include <linux/grsecurity.h>
7190  
7191  #include <net/sock.h>          /* siocdevprivate_ioctl */
7192  
7193 @@ -1472,6 +1473,11 @@ int compat_do_execve(char * filename,
7194         struct file *file;
7195         int retval;
7196         int i;
7197 +#ifdef CONFIG_GRKERNSEC
7198 +       struct file *old_exec_file;
7199 +       struct acl_subject_label *old_acl;
7200 +       struct rlimit old_rlim[RLIM_NLIMITS];
7201 +#endif
7202  
7203         retval = -ENOMEM;
7204         bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
7205 @@ -1490,6 +1496,15 @@ int compat_do_execve(char * filename,
7206         bprm->file = file;
7207         bprm->filename = filename;
7208         bprm->interp = filename;
7209 +
7210 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
7211 +       retval = -EAGAIN;
7212 +       if (gr_handle_nproc())
7213 +               goto out_file;
7214 +       retval = -EACCES;
7215 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
7216 +               goto out_file;
7217 +
7218         bprm->mm = mm_alloc();
7219         retval = -ENOMEM;
7220         if (!bprm->mm)
7221 @@ -1528,10 +1543,39 @@ int compat_do_execve(char * filename,
7222         if (retval < 0)
7223                 goto out;
7224  
7225 +       if (!gr_tpe_allow(file)) {
7226 +               retval = -EACCES;
7227 +               goto out;
7228 +       }
7229 +
7230 +       if (gr_check_crash_exec(file)) {
7231 +               retval = -EACCES;
7232 +               goto out;
7233 +       }
7234 +
7235 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
7236 +
7237 +       gr_handle_exec_args(bprm, (char __user * __user *)argv);
7238 +
7239 +#ifdef CONFIG_GRKERNSEC
7240 +       old_acl = current->acl;
7241 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
7242 +       old_exec_file = current->exec_file;
7243 +       get_file(file);
7244 +       current->exec_file = file;
7245 +#endif
7246 +
7247 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
7248 +
7249         retval = search_binary_handler(bprm, regs);
7250         if (retval >= 0) {
7251                 free_arg_pages(bprm);
7252  
7253 +#ifdef CONFIG_GRKERNSEC
7254 +               if (old_exec_file)
7255 +                       fput(old_exec_file);
7256 +#endif
7257 +
7258                 /* execve success */
7259                 security_bprm_free(bprm);
7260                 acct_update_integrals(current);
7261 @@ -1539,6 +1583,13 @@ int compat_do_execve(char * filename,
7262                 return retval;
7263         }
7264  
7265 +#ifdef CONFIG_GRKERNSEC
7266 +       current->acl = old_acl;
7267 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
7268 +       fput(current->exec_file);
7269 +       current->exec_file = old_exec_file;
7270 +#endif
7271 +
7272  out:
7273         /* Something went wrong, return the inode and free the argument pages*/
7274         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
7275 diff -urNp linux-2.6.16.2/fs/dcache.c linux-2.6.16.2/fs/dcache.c
7276 --- linux-2.6.16.2/fs/dcache.c  2006-04-07 12:56:47.000000000 -0400
7277 +++ linux-2.6.16.2/fs/dcache.c  2006-04-09 21:23:54.000000000 -0400
7278 @@ -1360,7 +1360,7 @@ already_unhashed:
7279   *
7280   * "buflen" should be positive. Caller holds the dcache_lock.
7281   */
7282 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
7283 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
7284                         struct dentry *root, struct vfsmount *rootmnt,
7285                         char *buffer, int buflen)
7286  {
7287 diff -urNp linux-2.6.16.2/fs/exec.c linux-2.6.16.2/fs/exec.c
7288 --- linux-2.6.16.2/fs/exec.c    2006-04-07 12:56:47.000000000 -0400
7289 +++ linux-2.6.16.2/fs/exec.c    2006-04-09 21:23:54.000000000 -0400
7290 @@ -49,6 +49,8 @@
7291  #include <linux/rmap.h>
7292  #include <linux/acct.h>
7293  #include <linux/cn_proc.h>
7294 +#include <linux/random.h>
7295 +#include <linux/grsecurity.h>
7296  
7297  #include <asm/uaccess.h>
7298  #include <asm/mmu_context.h>
7299 @@ -67,6 +69,15 @@ EXPORT_SYMBOL(suid_dumpable);
7300  static struct linux_binfmt *formats;
7301  static DEFINE_RWLOCK(binfmt_lock);
7302  
7303 +#ifdef CONFIG_PAX_SOFTMODE
7304 +unsigned int pax_softmode;
7305 +#endif
7306 +
7307 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
7308 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
7309 +EXPORT_SYMBOL(pax_set_initial_flags_func);
7310 +#endif
7311 +
7312  int register_binfmt(struct linux_binfmt * fmt)
7313  {
7314         struct linux_binfmt ** tmp = &formats;
7315 @@ -312,6 +323,10 @@ void install_arg_page(struct vm_area_str
7316         if (unlikely(anon_vma_prepare(vma)))
7317                 goto out;
7318  
7319 +#ifdef CONFIG_PAX_SEGMEXEC
7320 +       if (page_count(page) == 1)
7321 +#endif
7322 +
7323         flush_dcache_page(page);
7324         pte = get_locked_pte(mm, address, &ptl);
7325         if (!pte)
7326 @@ -321,9 +336,21 @@ void install_arg_page(struct vm_area_str
7327                 goto out;
7328         }
7329         inc_mm_counter(mm, anon_rss);
7330 +
7331 +#ifdef CONFIG_PAX_SEGMEXEC
7332 +       if (page_count(page) == 1)
7333 +#endif
7334 +
7335         lru_cache_add_active(page);
7336         set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
7337                                         page, vma->vm_page_prot))));
7338 +
7339 +#ifdef CONFIG_PAX_SEGMEXEC
7340 +       if (page_count(page) != 1)
7341 +               page_add_anon_rmap(page, vma, address);
7342 +       else
7343 +#endif
7344 +
7345         page_add_new_anon_rmap(page, vma, address);
7346         pte_unmap_unlock(pte, ptl);
7347  
7348 @@ -346,6 +373,10 @@ int setup_arg_pages(struct linux_binprm 
7349         int i, ret;
7350         long arg_size;
7351  
7352 +#ifdef CONFIG_PAX_SEGMEXEC
7353 +       struct vm_area_struct *mpnt_m = NULL;
7354 +#endif
7355 +
7356  #ifdef CONFIG_STACK_GROWSUP
7357         /* Move the argument and environment strings to the bottom of the
7358          * stack space.
7359 @@ -410,6 +441,18 @@ int setup_arg_pages(struct linux_binprm 
7360  
7361         memset(mpnt, 0, sizeof(*mpnt));
7362  
7363 +#ifdef CONFIG_PAX_SEGMEXEC
7364 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
7365 +               mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7366 +               if (!mpnt_m) {
7367 +                       kmem_cache_free(vm_area_cachep, mpnt);
7368 +                       return -ENOMEM;
7369 +               }
7370 +
7371 +               memset(mpnt_m, 0, sizeof(*mpnt_m));
7372 +       }
7373 +#endif
7374 +
7375         down_write(&mm->mmap_sem);
7376         {
7377                 mpnt->vm_mm = mm;
7378 @@ -430,13 +473,50 @@ int setup_arg_pages(struct linux_binprm 
7379                 else
7380                         mpnt->vm_flags = VM_STACK_FLAGS;
7381                 mpnt->vm_flags |= mm->def_flags;
7382 +
7383 +#ifdef CONFIG_PAX_PAGEEXEC
7384 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
7385 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & 0x7];
7386 +               else
7387 +#endif
7388 +
7389                 mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
7390                 if ((ret = insert_vm_struct(mm, mpnt))) {
7391                         up_write(&mm->mmap_sem);
7392                         kmem_cache_free(vm_area_cachep, mpnt);
7393 +
7394 +#ifdef CONFIG_PAX_SEGMEXEC
7395 +                       if (mpnt_m)
7396 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
7397 +#endif
7398 +
7399                         return ret;
7400                 }
7401                 mm->stack_vm = mm->total_vm = vma_pages(mpnt);
7402 +
7403 +#ifdef CONFIG_PAX_SEGMEXEC
7404 +               if (mpnt_m) {
7405 +                       *mpnt_m = *mpnt;
7406 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
7407 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
7408 +                               mpnt_m->vm_page_prot = PAGE_NONE;
7409 +                       }
7410 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
7411 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
7412 +                       if ((ret = insert_vm_struct(mm, mpnt_m))) {
7413 +                               up_write(&mm->mmap_sem);
7414 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
7415 +                               return ret;
7416 +                       }
7417 +                       mpnt_m->vm_flags |= VM_MIRROR;
7418 +                       mpnt->vm_flags |= VM_MIRROR;
7419 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
7420 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
7421 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
7422 +                       mm->total_vm += vma_pages(mpnt_m);
7423 +               }
7424 +#endif
7425 +
7426         }
7427  
7428         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
7429 @@ -444,6 +524,14 @@ int setup_arg_pages(struct linux_binprm 
7430                 if (page) {
7431                         bprm->page[i] = NULL;
7432                         install_arg_page(mpnt, page, stack_base);
7433 +
7434 +#ifdef CONFIG_PAX_SEGMEXEC
7435 +                       if (mpnt_m) {
7436 +                               page_cache_get(page);
7437 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
7438 +                       }
7439 +#endif
7440 +
7441                 }
7442                 stack_base += PAGE_SIZE;
7443         }
7444 @@ -1141,6 +1229,11 @@ int do_execve(char * filename,
7445         struct file *file;
7446         int retval;
7447         int i;
7448 +#ifdef CONFIG_GRKERNSEC
7449 +       struct file *old_exec_file;
7450 +       struct acl_subject_label *old_acl;
7451 +       struct rlimit old_rlim[RLIM_NLIMITS];
7452 +#endif
7453  
7454         retval = -ENOMEM;
7455         bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
7456 @@ -1153,10 +1246,29 @@ int do_execve(char * filename,
7457         if (IS_ERR(file))
7458                 goto out_kfree;
7459  
7460 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
7461 +
7462 +       if (gr_handle_nproc()) {
7463 +               allow_write_access(file);
7464 +               fput(file);
7465 +               return -EAGAIN;
7466 +       }
7467 +
7468 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
7469 +               allow_write_access(file);
7470 +               fput(file);
7471 +               return -EACCES;
7472 +       }
7473 +
7474         sched_exec();
7475  
7476         bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
7477  
7478 +#ifdef CONFIG_PAX_RANDUSTACK
7479 +       if (randomize_va_space)
7480 +               bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
7481 +#endif
7482 +
7483         bprm->file = file;
7484         bprm->filename = filename;
7485         bprm->interp = filename;
7486 @@ -1198,8 +1310,38 @@ int do_execve(char * filename,
7487         if (retval < 0)
7488                 goto out;
7489  
7490 +       if (!gr_tpe_allow(file)) {
7491 +               retval = -EACCES;
7492 +               goto out;
7493 +       }
7494 +
7495 +       if (gr_check_crash_exec(file)) {
7496 +               retval = -EACCES;
7497 +               goto out;
7498 +       }
7499 +
7500 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
7501 +
7502 +       gr_handle_exec_args(bprm, argv);
7503 +
7504 +#ifdef CONFIG_GRKERNSEC
7505 +       old_acl = current->acl;
7506 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
7507 +       old_exec_file = current->exec_file;
7508 +       get_file(file);
7509 +       current->exec_file = file;
7510 +#endif
7511 +
7512 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
7513 +       if (retval < 0)
7514 +               goto out_fail;
7515 +
7516         retval = search_binary_handler(bprm,regs);
7517         if (retval >= 0) {
7518 +#ifdef CONFIG_GRKERNSEC
7519 +               if (old_exec_file)
7520 +                       fput(old_exec_file);
7521 +#endif
7522                 free_arg_pages(bprm);
7523  
7524                 /* execve success */
7525 @@ -1209,6 +1351,14 @@ int do_execve(char * filename,
7526                 return retval;
7527         }
7528  
7529 +out_fail:
7530 +#ifdef CONFIG_GRKERNSEC
7531 +       current->acl = old_acl;
7532 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
7533 +       fput(current->exec_file);
7534 +       current->exec_file = old_exec_file;
7535 +#endif
7536 +
7537  out:
7538         /* Something went wrong, return the inode and free the argument pages*/
7539         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
7540 @@ -1369,6 +1519,114 @@ static void format_corename(char *corena
7541         *out_ptr = 0;
7542  }
7543  
7544 +int pax_check_flags(unsigned long * flags)
7545 +{
7546 +       int retval = 0;
7547 +
7548 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
7549 +       if (*flags & MF_PAX_SEGMEXEC)
7550 +       {
7551 +               *flags &= ~MF_PAX_SEGMEXEC;
7552 +               retval = -EINVAL;
7553 +       }
7554 +#endif
7555 +
7556 +       if ((*flags & MF_PAX_PAGEEXEC)
7557 +
7558 +#ifdef CONFIG_PAX_PAGEEXEC
7559 +           &&  (*flags & MF_PAX_SEGMEXEC)
7560 +#endif
7561 +
7562 +          )
7563 +       {
7564 +               *flags &= ~MF_PAX_PAGEEXEC;
7565 +               retval = -EINVAL;
7566 +       }
7567 +
7568 +       if ((*flags & MF_PAX_MPROTECT)
7569 +
7570 +#ifdef CONFIG_PAX_MPROTECT
7571 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
7572 +#endif
7573 +
7574 +          )
7575 +       {
7576 +               *flags &= ~MF_PAX_MPROTECT;
7577 +               retval = -EINVAL;
7578 +       }
7579 +
7580 +       if ((*flags & MF_PAX_EMUTRAMP)
7581 +
7582 +#ifdef CONFIG_PAX_EMUTRAMP
7583 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
7584 +#endif
7585 +
7586 +          )
7587 +       {
7588 +               *flags &= ~MF_PAX_EMUTRAMP;
7589 +               retval = -EINVAL;
7590 +       }
7591 +
7592 +       return retval;
7593 +}
7594 +
7595 +EXPORT_SYMBOL(pax_check_flags);
7596 +
7597 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7598 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
7599 +{
7600 +       struct task_struct *tsk = current;
7601 +       struct mm_struct *mm = current->mm;
7602 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
7603 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
7604 +       char* path_exec=NULL;
7605 +       char* path_fault=NULL;
7606 +       unsigned long start=0UL, end=0UL, offset=0UL;
7607 +
7608 +       if (buffer_exec && buffer_fault) {
7609 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
7610 +
7611 +               down_read(&mm->mmap_sem);
7612 +               vma = mm->mmap;
7613 +               while (vma && (!vma_exec || !vma_fault)) {
7614 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
7615 +                               vma_exec = vma;
7616 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
7617 +                               vma_fault = vma;
7618 +                       vma = vma->vm_next;
7619 +               }
7620 +               if (vma_exec) {
7621 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
7622 +                       if (IS_ERR(path_exec))
7623 +                               path_exec = "<path too long>";
7624 +               }
7625 +               if (vma_fault) {
7626 +                       start = vma_fault->vm_start;
7627 +                       end = vma_fault->vm_end;
7628 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
7629 +                       if (vma_fault->vm_file) {
7630 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
7631 +                               if (IS_ERR(path_fault))
7632 +                                       path_fault = "<path too long>";
7633 +                       } else
7634 +                               path_fault = "<anonymous mapping>";
7635 +               }
7636 +               up_read(&mm->mmap_sem);
7637 +       }
7638 +       if (tsk->signal->curr_ip)
7639 +               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);
7640 +       else
7641 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
7642 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
7643 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
7644 +                       tsk->uid, tsk->euid, pc, sp);
7645 +       free_page((unsigned long)buffer_exec);
7646 +       free_page((unsigned long)buffer_fault);
7647 +       pax_report_insns(pc, sp);
7648 +       do_coredump(SIGKILL, SIGKILL, regs);
7649 +}
7650 +#endif
7651 +
7652  static void zap_threads (struct mm_struct *mm)
7653  {
7654         struct task_struct *g, *p;
7655 @@ -1486,6 +1744,10 @@ int do_coredump(long signr, int exit_cod
7656          */
7657         clear_thread_flag(TIF_SIGPENDING);
7658  
7659 +       if (signr == SIGKILL || signr == SIGILL)
7660 +               gr_handle_brute_attach(current);
7661 +
7662 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
7663         if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
7664                 goto fail_unlock;
7665  
7666 diff -urNp linux-2.6.16.2/fs/fcntl.c linux-2.6.16.2/fs/fcntl.c
7667 --- linux-2.6.16.2/fs/fcntl.c   2006-04-07 12:56:47.000000000 -0400
7668 +++ linux-2.6.16.2/fs/fcntl.c   2006-04-09 21:23:54.000000000 -0400
7669 @@ -18,6 +18,7 @@
7670  #include <linux/ptrace.h>
7671  #include <linux/signal.h>
7672  #include <linux/rcupdate.h>
7673 +#include <linux/grsecurity.h>
7674  
7675  #include <asm/poll.h>
7676  #include <asm/siginfo.h>
7677 @@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
7678         struct fdtable *fdt;
7679  
7680         error = -EINVAL;
7681 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
7682         if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
7683                 goto out;
7684  
7685 @@ -83,6 +85,7 @@ repeat:
7686         }
7687         
7688         error = -EMFILE;
7689 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
7690         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
7691                 goto out;
7692  
7693 @@ -142,6 +145,8 @@ asmlinkage long sys_dup2(unsigned int ol
7694         struct files_struct * files = current->files;
7695         struct fdtable *fdt;
7696  
7697 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
7698 +
7699         spin_lock(&files->file_lock);
7700         if (!(file = fcheck(oldfd)))
7701                 goto out_unlock;
7702 @@ -428,7 +433,8 @@ static inline int sigio_perm(struct task
7703         return (((fown->euid == 0) ||
7704                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
7705                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
7706 -               !security_file_send_sigiotask(p, fown, sig));
7707 +               !security_file_send_sigiotask(p, fown, sig) &&
7708 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
7709  }
7710  
7711  static void send_sigio_to_task(struct task_struct *p,
7712 diff -urNp linux-2.6.16.2/fs/Kconfig linux-2.6.16.2/fs/Kconfig
7713 --- linux-2.6.16.2/fs/Kconfig   2006-04-07 12:56:47.000000000 -0400
7714 +++ linux-2.6.16.2/fs/Kconfig   2006-04-09 21:23:54.000000000 -0400
7715 @@ -794,7 +794,7 @@ config PROC_FS
7716  
7717  config PROC_KCORE
7718         bool "/proc/kcore support" if !ARM
7719 -       depends on PROC_FS && MMU
7720 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
7721  
7722  config PROC_VMCORE
7723          bool "/proc/vmcore support (EXPERIMENTAL)"
7724 diff -urNp linux-2.6.16.2/fs/namei.c linux-2.6.16.2/fs/namei.c
7725 --- linux-2.6.16.2/fs/namei.c   2006-04-07 12:56:47.000000000 -0400
7726 +++ linux-2.6.16.2/fs/namei.c   2006-04-09 21:23:54.000000000 -0400
7727 @@ -32,6 +32,7 @@
7728  #include <linux/file.h>
7729  #include <linux/fcntl.h>
7730  #include <linux/namei.h>
7731 +#include <linux/grsecurity.h>
7732  #include <asm/namei.h>
7733  #include <asm/uaccess.h>
7734  
7735 @@ -608,6 +609,13 @@ static inline int do_follow_link(struct 
7736         err = security_inode_follow_link(path->dentry, nd);
7737         if (err)
7738                 goto loop;
7739 +
7740 +       if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
7741 +                                 path->dentry->d_inode, path->dentry, nd->mnt)) {
7742 +               err = -EACCES;
7743 +               goto loop;
7744 +       }
7745 +
7746         current->link_count++;
7747         current->total_link_count++;
7748         nd->depth++;
7749 @@ -951,11 +959,18 @@ return_reval:
7750                                 break;
7751                 }
7752  return_base:
7753 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
7754 +                       path_release(nd);
7755 +                       return -ENOENT;
7756 +               }
7757                 return 0;
7758  out_dput:
7759                 dput_path(&next, nd);
7760                 break;
7761         }
7762 +       if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
7763 +               err = -ENOENT;
7764 +
7765         path_release(nd);
7766  return_err:
7767         return err;
7768 @@ -1596,6 +1611,17 @@ int open_namei(int dfd, const char *path
7769                                          nd, flag);
7770                 if (error)
7771                         return error;
7772 +
7773 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
7774 +                       error = -EPERM;
7775 +                       goto exit;
7776 +               }
7777 +
7778 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
7779 +                       error = -EACCES;
7780 +                       goto exit;
7781 +               }
7782 +
7783                 goto ok;
7784         }
7785  
7786 @@ -1630,9 +1656,16 @@ do_last:
7787  
7788         /* Negative dentry, just create the file */
7789         if (!path.dentry->d_inode) {
7790 +               if (!gr_acl_handle_creat(path.dentry, nd->dentry, nd->mnt, flag, mode)) {
7791 +                       error = -EACCES;
7792 +                       mutex_unlock(&dir->d_inode->i_mutex);
7793 +                       goto exit_dput;
7794 +               }
7795                 if (!IS_POSIXACL(dir->d_inode))
7796                         mode &= ~current->fs->umask;
7797                 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
7798 +               if (!error)
7799 +                       gr_handle_create(path.dentry, nd->mnt);
7800                 mutex_unlock(&dir->d_inode->i_mutex);
7801                 dput(nd->dentry);
7802                 nd->dentry = path.dentry;
7803 @@ -1647,6 +1680,23 @@ do_last:
7804         /*
7805          * It already exists.
7806          */
7807 +
7808 +       if (gr_handle_rawio(path.dentry->d_inode)) {
7809 +               mutex_unlock(&dir->d_inode->i_mutex);
7810 +               error = -EPERM;
7811 +               goto exit_dput;
7812 +       }
7813 +       if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
7814 +               mutex_unlock(&dir->d_inode->i_mutex);
7815 +               error = -EACCES;
7816 +               goto exit_dput;
7817 +       }
7818 +       if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
7819 +               mutex_unlock(&dir->d_inode->i_mutex);
7820 +               error = -EACCES;
7821 +               goto exit_dput;
7822 +       }
7823 +
7824         mutex_unlock(&dir->d_inode->i_mutex);
7825  
7826         error = -EEXIST;
7827 @@ -1700,6 +1750,13 @@ do_link:
7828         error = security_inode_follow_link(path.dentry, nd);
7829         if (error)
7830                 goto exit_dput;
7831 +
7832 +       if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
7833 +                                 path.dentry, nd->mnt)) {
7834 +               error = -EACCES;
7835 +               goto exit_dput;
7836 +       }
7837 +
7838         error = __do_follow_link(&path, nd);
7839         if (error)
7840                 return error;
7841 @@ -1820,6 +1877,22 @@ asmlinkage long sys_mknodat(int dfd, con
7842         if (!IS_POSIXACL(nd.dentry->d_inode))
7843                 mode &= ~current->fs->umask;
7844         if (!IS_ERR(dentry)) {
7845 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
7846 +                       error = -EPERM;
7847 +                       dput(dentry);
7848 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
7849 +                       path_release(&nd);
7850 +                       goto out;
7851 +               }
7852 +
7853 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
7854 +                       error = -EACCES;
7855 +                       dput(dentry);
7856 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
7857 +                       path_release(&nd);
7858 +                       goto out;
7859 +               }
7860 +
7861                 switch (mode & S_IFMT) {
7862                 case 0: case S_IFREG:
7863                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
7864 @@ -1837,6 +1910,10 @@ asmlinkage long sys_mknodat(int dfd, con
7865                 default:
7866                         error = -EINVAL;
7867                 }
7868 +
7869 +               if (!error)
7870 +                       gr_handle_create(dentry, nd.mnt);
7871 +
7872                 dput(dentry);
7873         }
7874         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7875 @@ -1891,9 +1968,19 @@ asmlinkage long sys_mkdirat(int dfd, con
7876                 dentry = lookup_create(&nd, 1);
7877                 error = PTR_ERR(dentry);
7878                 if (!IS_ERR(dentry)) {
7879 +                       error = 0;
7880                         if (!IS_POSIXACL(nd.dentry->d_inode))
7881                                 mode &= ~current->fs->umask;
7882 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
7883 +
7884 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
7885 +                               error = -EACCES;
7886 +
7887 +                       if (!error)
7888 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
7889 +
7890 +                       if (!error)
7891 +                               gr_handle_create(dentry, nd.mnt);
7892 +
7893                         dput(dentry);
7894                 }
7895                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7896 @@ -1977,6 +2064,8 @@ static long do_rmdir(int dfd, const char
7897         char * name;
7898         struct dentry *dentry;
7899         struct nameidata nd;
7900 +       ino_t saved_ino = 0;
7901 +       dev_t saved_dev = 0;
7902  
7903         name = getname(pathname);
7904         if(IS_ERR(name))
7905 @@ -2001,7 +2090,21 @@ static long do_rmdir(int dfd, const char
7906         dentry = lookup_hash(&nd);
7907         error = PTR_ERR(dentry);
7908         if (!IS_ERR(dentry)) {
7909 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
7910 +               error = 0;
7911 +               if (dentry->d_inode) {
7912 +                       if (dentry->d_inode->i_nlink <= 1) {
7913 +                               saved_ino = dentry->d_inode->i_ino;
7914 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
7915 +                       }
7916 +
7917 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
7918 +                               error = -EACCES;
7919 +               }
7920 +
7921 +               if (!error)
7922 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry);
7923 +               if (!error && (saved_dev || saved_ino))
7924 +                       gr_handle_delete(saved_ino, saved_dev);
7925                 dput(dentry);
7926         }
7927         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7928 @@ -2060,6 +2163,8 @@ static long do_unlinkat(int dfd, const c
7929         struct dentry *dentry;
7930         struct nameidata nd;
7931         struct inode *inode = NULL;
7932 +       ino_t saved_ino = 0;
7933 +       dev_t saved_dev = 0;
7934  
7935         name = getname(pathname);
7936         if(IS_ERR(name))
7937 @@ -2075,13 +2180,26 @@ static long do_unlinkat(int dfd, const c
7938         dentry = lookup_hash(&nd);
7939         error = PTR_ERR(dentry);
7940         if (!IS_ERR(dentry)) {
7941 +               error = 0;
7942                 /* Why not before? Because we want correct error value */
7943                 if (nd.last.name[nd.last.len])
7944                         goto slashes;
7945                 inode = dentry->d_inode;
7946 -               if (inode)
7947 +               if (inode) {
7948 +                       if (inode->i_nlink <= 1) {
7949 +                               saved_ino = inode->i_ino;
7950 +                               saved_dev = inode->i_sb->s_dev;
7951 +                       }
7952 +
7953 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
7954 +                               error = -EACCES;
7955 +
7956                         atomic_inc(&inode->i_count);
7957 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
7958 +               }
7959 +               if (!error)
7960 +                       error = vfs_unlink(nd.dentry->d_inode, dentry);
7961 +               if (!error && (saved_ino || saved_dev))
7962 +                       gr_handle_delete(saved_ino, saved_dev);
7963         exit2:
7964                 dput(dentry);
7965         }
7966 @@ -2159,7 +2277,15 @@ asmlinkage long sys_symlinkat(const char
7967                 dentry = lookup_create(&nd, 0);
7968                 error = PTR_ERR(dentry);
7969                 if (!IS_ERR(dentry)) {
7970 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
7971 +                       error = 0;
7972 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
7973 +                               error = -EACCES;
7974 +
7975 +                       if (!error)
7976 +                               error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
7977 +
7978 +                       if (!error)
7979 +                               gr_handle_create(dentry, nd.mnt);
7980                         dput(dentry);
7981                 }
7982                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7983 @@ -2251,7 +2377,20 @@ asmlinkage long sys_linkat(int olddfd, c
7984         new_dentry = lookup_create(&nd, 0);
7985         error = PTR_ERR(new_dentry);
7986         if (!IS_ERR(new_dentry)) {
7987 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
7988 +               error = 0;
7989 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
7990 +                                      old_nd.dentry->d_inode,
7991 +                                      old_nd.dentry->d_inode->i_mode, to))
7992 +                       error = -EPERM;
7993 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
7994 +                                       old_nd.dentry, old_nd.mnt, to))
7995 +                       error = -EACCES;
7996 +               if (!error)
7997 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
7998 +
7999 +               if (!error)
8000 +                       gr_handle_create(new_dentry, nd.mnt);
8001 +
8002                 dput(new_dentry);
8003         }
8004         mutex_unlock(&nd.dentry->d_inode->i_mutex);
8005 @@ -2477,8 +2616,16 @@ static int do_rename(int olddfd, const c
8006         if (new_dentry == trap)
8007                 goto exit5;
8008  
8009 -       error = vfs_rename(old_dir->d_inode, old_dentry,
8010 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
8011 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
8012 +                                    newname);
8013 +
8014 +       if (!error)
8015 +               error = vfs_rename(old_dir->d_inode, old_dentry,
8016                                    new_dir->d_inode, new_dentry);
8017 +       if (!error)
8018 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
8019 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
8020  exit5:
8021         dput(new_dentry);
8022  exit4:
8023 diff -urNp linux-2.6.16.2/fs/namespace.c linux-2.6.16.2/fs/namespace.c
8024 --- linux-2.6.16.2/fs/namespace.c       2006-04-07 12:56:47.000000000 -0400
8025 +++ linux-2.6.16.2/fs/namespace.c       2006-04-09 21:23:54.000000000 -0400
8026 @@ -23,6 +23,8 @@
8027  #include <linux/namei.h>
8028  #include <linux/security.h>
8029  #include <linux/mount.h>
8030 +#include <linux/sched.h>
8031 +#include <linux/grsecurity.h>
8032  #include <asm/uaccess.h>
8033  #include <asm/unistd.h>
8034  #include "pnode.h"
8035 @@ -562,6 +564,8 @@ static int do_umount(struct vfsmount *mn
8036                         DQUOT_OFF(sb);
8037                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
8038                         unlock_kernel();
8039 +
8040 +                       gr_log_remount(mnt->mnt_devname, retval);
8041                 }
8042                 up_write(&sb->s_umount);
8043                 return retval;
8044 @@ -582,6 +586,9 @@ static int do_umount(struct vfsmount *mn
8045                 security_sb_umount_busy(mnt);
8046         up_write(&namespace_sem);
8047         release_mounts(&umount_list);
8048 +
8049 +       gr_log_unmount(mnt->mnt_devname, retval);
8050 +
8051         return retval;
8052  }
8053  
8054 @@ -1308,6 +1315,11 @@ long do_mount(char *dev_name, char *dir_
8055         if (retval)
8056                 goto dput_out;
8057  
8058 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
8059 +               retval = -EPERM;
8060 +               goto dput_out;
8061 +       }
8062 +
8063         if (flags & MS_REMOUNT)
8064                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
8065                                     data_page);
8066 @@ -1322,6 +1334,9 @@ long do_mount(char *dev_name, char *dir_
8067                                       dev_name, data_page);
8068  dput_out:
8069         path_release(&nd);
8070 +
8071 +       gr_log_mount(dev_name, dir_name, retval);
8072 +
8073         return retval;
8074  }
8075  
8076 @@ -1574,6 +1589,9 @@ asmlinkage long sys_pivot_root(const cha
8077         if (!capable(CAP_SYS_ADMIN))
8078                 return -EPERM;
8079  
8080 +       if (gr_handle_chroot_pivot())
8081 +               return -EPERM;
8082 +
8083         lock_kernel();
8084  
8085         error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
8086 diff -urNp linux-2.6.16.2/fs/open.c linux-2.6.16.2/fs/open.c
8087 --- linux-2.6.16.2/fs/open.c    2006-04-07 12:56:47.000000000 -0400
8088 +++ linux-2.6.16.2/fs/open.c    2006-04-09 21:23:54.000000000 -0400
8089 @@ -27,6 +27,7 @@
8090  #include <linux/pagemap.h>
8091  #include <linux/syscalls.h>
8092  #include <linux/rcupdate.h>
8093 +#include <linux/grsecurity.h>
8094  
8095  #include <asm/unistd.h>
8096  
8097 @@ -206,6 +207,9 @@ int do_truncate(struct dentry *dentry, l
8098         if (length < 0)
8099                 return -EINVAL;
8100  
8101 +       if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
8102 +               return -EACCES;
8103 +
8104         newattrs.ia_size = length;
8105         newattrs.ia_valid = ATTR_SIZE | time_attrs;
8106         if (filp) {
8107 @@ -400,6 +404,12 @@ asmlinkage long sys_utime(char __user * 
8108                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
8109                         goto dput_and_out;
8110         }
8111 +
8112 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
8113 +               error = -EACCES;
8114 +               goto dput_and_out;
8115 +       }
8116 +
8117         mutex_lock(&inode->i_mutex);
8118         error = notify_change(nd.dentry, &newattrs);
8119         mutex_unlock(&inode->i_mutex);
8120 @@ -453,6 +463,12 @@ long do_utimes(int dfd, char __user *fil
8121                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
8122                         goto dput_and_out;
8123         }
8124 +
8125 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
8126 +               error = -EACCES;
8127 +               goto dput_and_out;
8128 +       }
8129 +
8130         mutex_lock(&inode->i_mutex);
8131         error = notify_change(nd.dentry, &newattrs);
8132         mutex_unlock(&inode->i_mutex);
8133 @@ -519,6 +535,10 @@ asmlinkage long sys_faccessat(int dfd, c
8134                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
8135                    && !special_file(nd.dentry->d_inode->i_mode))
8136                         res = -EROFS;
8137 +
8138 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
8139 +                       res = -EACCES;
8140 +
8141                 path_release(&nd);
8142         }
8143  
8144 @@ -547,6 +567,8 @@ asmlinkage long sys_chdir(const char __u
8145         if (error)
8146                 goto dput_and_out;
8147  
8148 +       gr_log_chdir(nd.dentry, nd.mnt);
8149 +
8150         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
8151  
8152  dput_and_out:
8153 @@ -577,6 +599,13 @@ asmlinkage long sys_fchdir(unsigned int 
8154                 goto out_putf;
8155  
8156         error = file_permission(file, MAY_EXEC);
8157 +
8158 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
8159 +               error = -EPERM;
8160 +
8161 +       if (!error)
8162 +               gr_log_chdir(dentry, mnt);
8163 +
8164         if (!error)
8165                 set_fs_pwd(current->fs, mnt, dentry);
8166  out_putf:
8167 @@ -602,8 +631,16 @@ asmlinkage long sys_chroot(const char __
8168         if (!capable(CAP_SYS_CHROOT))
8169                 goto dput_and_out;
8170  
8171 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
8172 +               goto dput_and_out;
8173 +
8174         set_fs_root(current->fs, nd.mnt, nd.dentry);
8175         set_fs_altroot();
8176 +
8177 +       gr_handle_chroot_caps(current);
8178 +
8179 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
8180 +
8181         error = 0;
8182  dput_and_out:
8183         path_release(&nd);
8184 @@ -632,9 +669,22 @@ asmlinkage long sys_fchmod(unsigned int 
8185         err = -EPERM;
8186         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
8187                 goto out_putf;
8188 +
8189 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
8190 +               err = -EACCES;
8191 +               goto out_putf;
8192 +       }
8193 +
8194         mutex_lock(&inode->i_mutex);
8195         if (mode == (mode_t) -1)
8196                 mode = inode->i_mode;
8197 +
8198 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
8199 +               err = -EPERM;
8200 +               mutex_unlock(&inode->i_mutex);
8201 +               goto out_putf;
8202 +       }
8203 +
8204         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
8205         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
8206         err = notify_change(dentry, &newattrs);
8207 @@ -667,9 +717,21 @@ asmlinkage long sys_fchmodat(int dfd, co
8208         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
8209                 goto dput_and_out;
8210  
8211 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
8212 +               error = -EACCES;
8213 +               goto dput_and_out;
8214 +       };
8215 +
8216         mutex_lock(&inode->i_mutex);
8217         if (mode == (mode_t) -1)
8218                 mode = inode->i_mode;
8219 +
8220 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
8221 +               error = -EACCES;
8222 +               mutex_unlock(&inode->i_mutex);
8223 +               goto dput_and_out;
8224 +       }
8225 +
8226         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
8227         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
8228         error = notify_change(nd.dentry, &newattrs);
8229 @@ -686,7 +748,7 @@ asmlinkage long sys_chmod(const char __u
8230         return sys_fchmodat(AT_FDCWD, filename, mode);
8231  }
8232  
8233 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
8234 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
8235  {
8236         struct inode * inode;
8237         int error;
8238 @@ -703,6 +765,12 @@ static int chown_common(struct dentry * 
8239         error = -EPERM;
8240         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
8241                 goto out;
8242 +
8243 +       if (!gr_acl_handle_chown(dentry, mnt)) {
8244 +               error = -EACCES;
8245 +               goto out;
8246 +       }
8247 +
8248         newattrs.ia_valid =  ATTR_CTIME;
8249         if (user != (uid_t) -1) {
8250                 newattrs.ia_valid |= ATTR_UID;
8251 @@ -728,7 +796,7 @@ asmlinkage long sys_chown(const char __u
8252  
8253         error = user_path_walk(filename, &nd);
8254         if (!error) {
8255 -               error = chown_common(nd.dentry, user, group);
8256 +               error = chown_common(nd.dentry, user, group, nd.mnt);
8257                 path_release(&nd);
8258         }
8259         return error;
8260 @@ -747,7 +815,7 @@ asmlinkage long sys_fchownat(int dfd, co
8261         follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
8262         error = __user_walk_fd(dfd, filename, follow, &nd);
8263         if (!error) {
8264 -               error = chown_common(nd.dentry, user, group);
8265 +               error = chown_common(nd.dentry, user, group, nd.mnt);
8266                 path_release(&nd);
8267         }
8268  out:
8269 @@ -761,7 +829,7 @@ asmlinkage long sys_lchown(const char __
8270  
8271         error = user_path_walk_link(filename, &nd);
8272         if (!error) {
8273 -               error = chown_common(nd.dentry, user, group);
8274 +               error = chown_common(nd.dentry, user, group, nd.mnt);
8275                 path_release(&nd);
8276         }
8277         return error;
8278 @@ -775,7 +843,8 @@ asmlinkage long sys_fchown(unsigned int 
8279  
8280         file = fget(fd);
8281         if (file) {
8282 -               error = chown_common(file->f_dentry, user, group);
8283 +               error = chown_common(file->f_dentry, user,
8284 +                                    group, file->f_vfsmnt);
8285                 fput(file);
8286         }
8287         return error;
8288 @@ -979,6 +1048,7 @@ repeat:
8289          * N.B. For clone tasks sharing a files structure, this test
8290          * will limit the total number of files that can be opened.
8291          */
8292 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
8293         if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
8294                 goto out;
8295  
8296 diff -urNp linux-2.6.16.2/fs/proc/array.c linux-2.6.16.2/fs/proc/array.c
8297 --- linux-2.6.16.2/fs/proc/array.c      2006-04-07 12:56:47.000000000 -0400
8298 +++ linux-2.6.16.2/fs/proc/array.c      2006-04-09 21:23:54.000000000 -0400
8299 @@ -293,6 +293,21 @@ static inline char *task_cap(struct task
8300                             cap_t(p->cap_effective));
8301  }
8302  
8303 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
8304 +static inline char *task_pax(struct task_struct *p, char *buffer)
8305 +{
8306 +       if (p->mm)
8307 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
8308 +                               p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
8309 +                               p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
8310 +                               p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
8311 +                               p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
8312 +                               p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
8313 +       else
8314 +               return buffer + sprintf(buffer, "PaX:\t-----\n");
8315 +}
8316 +#endif
8317 +
8318  int proc_pid_status(struct task_struct *task, char * buffer)
8319  {
8320         char * orig = buffer;
8321 @@ -311,9 +326,20 @@ int proc_pid_status(struct task_struct *
8322  #if defined(CONFIG_S390)
8323         buffer = task_show_regs(task, buffer);
8324  #endif
8325 +
8326 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
8327 +       buffer = task_pax(task, buffer);
8328 +#endif
8329 +
8330         return buffer - orig;
8331  }
8332  
8333 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8334 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
8335 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
8336 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
8337 +#endif
8338 +
8339  static int do_task_stat(struct task_struct *task, char * buffer, int whole)
8340  {
8341         unsigned long vsize, eip, esp, wchan = ~0UL;
8342 @@ -400,6 +426,19 @@ static int do_task_stat(struct task_stru
8343                 stime = task->stime;
8344         }
8345  
8346 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8347 +       if (PAX_RAND_FLAGS(mm)) {
8348 +               eip = 0;
8349 +               esp = 0;
8350 +               wchan = 0;
8351 +       }
8352 +#endif
8353 +#ifdef CONFIG_GRKERNSEC_HIDESYM
8354 +       wchan = 0;
8355 +       eip =0;
8356 +       esp =0;
8357 +#endif
8358 +
8359         /* scale priority and nice values from timeslices to -20..20 */
8360         /* to make it look like a "normal" Unix priority/nice value  */
8361         priority = task_prio(task);
8362 @@ -440,9 +479,15 @@ static int do_task_stat(struct task_stru
8363                 vsize,
8364                 mm ? get_mm_rss(mm) : 0,
8365                 rsslim,
8366 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8367 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
8368 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
8369 +               PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
8370 +#else
8371                 mm ? mm->start_code : 0,
8372                 mm ? mm->end_code : 0,
8373                 mm ? mm->start_stack : 0,
8374 +#endif
8375                 esp,
8376                 eip,
8377                 /* The signal information here is obsolete.
8378 @@ -488,3 +533,14 @@ int proc_pid_statm(struct task_struct *t
8379         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
8380                        size, resident, shared, text, lib, data, 0);
8381  }
8382 +
8383 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8384 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
8385 +{
8386 +       int len;
8387 +
8388 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
8389 +       return len;
8390 +}
8391 +#endif
8392 +
8393 diff -urNp linux-2.6.16.2/fs/proc/base.c linux-2.6.16.2/fs/proc/base.c
8394 --- linux-2.6.16.2/fs/proc/base.c       2006-04-07 12:56:47.000000000 -0400
8395 +++ linux-2.6.16.2/fs/proc/base.c       2006-04-09 21:23:54.000000000 -0400
8396 @@ -72,6 +72,7 @@
8397  #include <linux/cpuset.h>
8398  #include <linux/audit.h>
8399  #include <linux/poll.h>
8400 +#include <linux/grsecurity.h>
8401  #include "internal.h"
8402  
8403  /*
8404 @@ -124,6 +125,9 @@ enum pid_directory_inos {
8405  #ifdef CONFIG_AUDITSYSCALL
8406         PROC_TGID_LOGINUID,
8407  #endif
8408 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8409 +       PROC_TGID_IPADDR,
8410 +#endif
8411         PROC_TGID_OOM_SCORE,
8412         PROC_TGID_OOM_ADJUST,
8413         PROC_TID_INO,
8414 @@ -201,6 +205,9 @@ static struct pid_entry tgid_base_stuff[
8415         E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
8416         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
8417         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
8418 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8419 +       E(PROC_TGID_IPADDR,     "ipaddr",  S_IFREG|S_IRUSR),
8420 +#endif
8421  #ifdef CONFIG_MMU
8422         E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
8423  #endif
8424 @@ -403,7 +410,7 @@ static int proc_task_root_link(struct in
8425         (task->parent == current && \
8426         (task->ptrace & PT_PTRACED) && \
8427          (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
8428 -        security_ptrace(current,task) == 0))
8429 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
8430  
8431  static int proc_pid_environ(struct task_struct *task, char * buffer)
8432  {
8433 @@ -581,9 +588,25 @@ static int proc_check_root(struct inode 
8434  
8435  static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
8436  {
8437 +       int ret = -EACCES;
8438 +       struct task_struct *task;
8439 +
8440         if (generic_permission(inode, mask, NULL) != 0)
8441 -               return -EACCES;
8442 -       return proc_check_root(inode);
8443 +               goto out;
8444 +
8445 +       ret = proc_check_root(inode);
8446 +       if (ret)
8447 +               goto out;
8448 +
8449 +       task = proc_task(inode);
8450 +
8451 +       if (!task)
8452 +               goto out;
8453 +
8454 +       ret = gr_acl_handle_procpidmem(task);
8455 +
8456 +out:
8457 +       return ret;
8458  }
8459  
8460  static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd)
8461 @@ -1330,6 +1353,9 @@ static struct inode *proc_pid_make_inode
8462                 inode->i_uid = task->euid;
8463                 inode->i_gid = task->egid;
8464         }
8465 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8466 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
8467 +#endif
8468         security_task_to_inode(task, inode);
8469  
8470  out:
8471 @@ -1358,7 +1384,9 @@ static int pid_revalidate(struct dentry 
8472         if (pid_alive(task)) {
8473                 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
8474                         inode->i_uid = task->euid;
8475 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
8476                         inode->i_gid = task->egid;
8477 +#endif
8478                 } else {
8479                         inode->i_uid = 0;
8480                         inode->i_gid = 0;
8481 @@ -1681,6 +1709,12 @@ static struct dentry *proc_pident_lookup
8482                         inode->i_fop = &proc_info_file_operations;
8483                         ei->op.proc_read = proc_pid_status;
8484                         break;
8485 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8486 +               case PROC_TGID_IPADDR:
8487 +                       inode->i_fop = &proc_info_file_operations;
8488 +                       ei->op.proc_read = proc_pid_ipaddr;
8489 +                       break;
8490 +#endif
8491                 case PROC_TID_STAT:
8492                         inode->i_fop = &proc_info_file_operations;
8493                         ei->op.proc_read = proc_tid_stat;
8494 @@ -1985,6 +2019,22 @@ struct dentry *proc_pid_lookup(struct in
8495         if (!task)
8496                 goto out;
8497  
8498 +       if (gr_check_hidden_task(task)) {
8499 +               put_task_struct(task);
8500 +               goto out;
8501 +       }
8502 +
8503 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8504 +       if (current->uid && (task->uid != current->uid)
8505 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8506 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
8507 +#endif
8508 +       ) {
8509 +               put_task_struct(task);
8510 +               goto out;
8511 +       }
8512 +#endif
8513 +
8514         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
8515  
8516  
8517 @@ -1992,7 +2042,15 @@ struct dentry *proc_pid_lookup(struct in
8518                 put_task_struct(task);
8519                 goto out;
8520         }
8521 +
8522 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8523 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
8524 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8525 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
8526 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
8527 +#else
8528         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
8529 +#endif
8530         inode->i_op = &proc_tgid_base_inode_operations;
8531         inode->i_fop = &proc_tgid_base_operations;
8532         inode->i_flags|=S_IMMUTABLE;
8533 @@ -2084,6 +2142,9 @@ out:
8534  static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
8535  {
8536         struct task_struct *p;
8537 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8538 +       struct task_struct *tmp = current;
8539 +#endif
8540         int nr_tgids = 0;
8541  
8542         index--;
8543 @@ -2104,6 +2165,18 @@ static int get_tgid_list(int index, unsi
8544                 int tgid = p->pid;
8545                 if (!pid_alive(p))
8546                         continue;
8547 +               if (gr_pid_is_chrooted(p))
8548 +                       continue;
8549 +               if (gr_check_hidden_task(p))
8550 +                       continue;
8551 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8552 +               if (tmp->uid && (p->uid != tmp->uid)
8553 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8554 +                   && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
8555 +#endif
8556 +               )
8557 +                       continue;
8558 +#endif
8559                 if (--index >= 0)
8560                         continue;
8561                 tgids[nr_tgids] = tgid;
8562 diff -urNp linux-2.6.16.2/fs/proc/inode.c linux-2.6.16.2/fs/proc/inode.c
8563 --- linux-2.6.16.2/fs/proc/inode.c      2006-04-07 12:56:47.000000000 -0400
8564 +++ linux-2.6.16.2/fs/proc/inode.c      2006-04-09 21:23:54.000000000 -0400
8565 @@ -168,7 +168,11 @@ struct inode *proc_get_inode(struct supe
8566                 if (de->mode) {
8567                         inode->i_mode = de->mode;
8568                         inode->i_uid = de->uid;
8569 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
8570 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
8571 +#else
8572                         inode->i_gid = de->gid;
8573 +#endif
8574                 }
8575                 if (de->size)
8576                         inode->i_size = de->size;
8577 diff -urNp linux-2.6.16.2/fs/proc/internal.h linux-2.6.16.2/fs/proc/internal.h
8578 --- linux-2.6.16.2/fs/proc/internal.h   2006-04-07 12:56:47.000000000 -0400
8579 +++ linux-2.6.16.2/fs/proc/internal.h   2006-04-09 21:23:54.000000000 -0400
8580 @@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
8581  extern int proc_tgid_stat(struct task_struct *, char *);
8582  extern int proc_pid_status(struct task_struct *, char *);
8583  extern int proc_pid_statm(struct task_struct *, char *);
8584 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
8585 +extern int proc_pid_ipaddr(struct task_struct*,char*);
8586 +#endif
8587  
8588  void free_proc_entry(struct proc_dir_entry *de);
8589  
8590 diff -urNp linux-2.6.16.2/fs/proc/proc_misc.c linux-2.6.16.2/fs/proc/proc_misc.c
8591 --- linux-2.6.16.2/fs/proc/proc_misc.c  2006-04-07 12:56:47.000000000 -0400
8592 +++ linux-2.6.16.2/fs/proc/proc_misc.c  2006-04-09 21:23:54.000000000 -0400
8593 @@ -708,6 +708,8 @@ void create_seq_entry(char *name, mode_t
8594  void __init proc_misc_init(void)
8595  {
8596         struct proc_dir_entry *entry;
8597 +       int gr_mode = 0;
8598 +
8599         static struct {
8600                 char *name;
8601                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
8602 @@ -723,7 +725,9 @@ void __init proc_misc_init(void)
8603                 {"stram",       stram_read_proc},
8604  #endif
8605                 {"filesystems", filesystems_read_proc},
8606 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
8607                 {"cmdline",     cmdline_read_proc},
8608 +#endif
8609                 {"locks",       locks_read_proc},
8610                 {"execdomains", execdomains_read_proc},
8611                 {NULL,}
8612 @@ -731,31 +735,49 @@ void __init proc_misc_init(void)
8613         for (p = simple_ones; p->name; p++)
8614                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
8615  
8616 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8617 +       gr_mode = S_IRUSR;
8618 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8619 +       gr_mode = S_IRUSR | S_IRGRP;
8620 +#endif
8621 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8622 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
8623 +#endif
8624 +
8625         proc_symlink("mounts", NULL, "self/mounts");
8626  
8627         /* And now for trickier ones */
8628         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
8629         if (entry)
8630                 entry->proc_fops = &proc_kmsg_operations;
8631 +
8632 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8633 +       create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
8634 +#else
8635         create_seq_entry("devices", 0, &proc_devinfo_operations);
8636 +#endif
8637         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
8638         create_seq_entry("partitions", 0, &proc_partitions_operations);
8639         create_seq_entry("stat", 0, &proc_stat_operations);
8640         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
8641  #ifdef CONFIG_SLAB
8642 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8643 +       create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
8644 +#else
8645         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
8646  #endif
8647 +#endif
8648         create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
8649         create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
8650         create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
8651         create_seq_entry("diskstats", 0, &proc_diskstats_operations);
8652  #ifdef CONFIG_MODULES
8653 -       create_seq_entry("modules", 0, &proc_modules_operations);
8654 +       create_seq_entry("modules", gr_mode, &proc_modules_operations);
8655  #endif
8656  #ifdef CONFIG_SCHEDSTATS
8657         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
8658  #endif
8659 -#ifdef CONFIG_PROC_KCORE
8660 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
8661         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
8662         if (proc_root_kcore) {
8663                 proc_root_kcore->proc_fops = &proc_kcore_operations;
8664 diff -urNp linux-2.6.16.2/fs/proc/root.c linux-2.6.16.2/fs/proc/root.c
8665 --- linux-2.6.16.2/fs/proc/root.c       2006-04-07 12:56:47.000000000 -0400
8666 +++ linux-2.6.16.2/fs/proc/root.c       2006-04-09 21:23:54.000000000 -0400
8667 @@ -53,7 +53,13 @@ void __init proc_root_init(void)
8668                 return;
8669         }
8670         proc_misc_init();
8671 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8672 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
8673 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8674 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
8675 +#else
8676         proc_net = proc_mkdir("net", NULL);
8677 +#endif
8678         proc_net_stat = proc_mkdir("net/stat", NULL);
8679  
8680  #ifdef CONFIG_SYSVIPC
8681 @@ -77,7 +83,15 @@ void __init proc_root_init(void)
8682  #ifdef CONFIG_PROC_DEVICETREE
8683         proc_device_tree_init();
8684  #endif
8685 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
8686 +#ifdef CONFIG_GRKERNSEC_PROC_USER
8687 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
8688 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
8689 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
8690 +#endif
8691 +#else
8692         proc_bus = proc_mkdir("bus", NULL);
8693 +#endif
8694  }
8695  
8696  static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
8697 diff -urNp linux-2.6.16.2/fs/proc/task_mmu.c linux-2.6.16.2/fs/proc/task_mmu.c
8698 --- linux-2.6.16.2/fs/proc/task_mmu.c   2006-04-07 12:56:47.000000000 -0400
8699 +++ linux-2.6.16.2/fs/proc/task_mmu.c   2006-04-09 21:23:54.000000000 -0400
8700 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
8701                 "VmStk:\t%8lu kB\n"
8702                 "VmExe:\t%8lu kB\n"
8703                 "VmLib:\t%8lu kB\n"
8704 -               "VmPTE:\t%8lu kB\n",
8705 -               hiwater_vm << (PAGE_SHIFT-10),
8706 +               "VmPTE:\t%8lu kB\n"
8707 +
8708 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8709 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
8710 +#endif
8711 +
8712 +               ,hiwater_vm << (PAGE_SHIFT-10),
8713                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
8714                 mm->locked_vm << (PAGE_SHIFT-10),
8715                 hiwater_rss << (PAGE_SHIFT-10),
8716                 total_rss << (PAGE_SHIFT-10),
8717                 data << (PAGE_SHIFT-10),
8718                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
8719 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
8720 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
8721 +
8722 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
8723 +               , mm->context.user_cs_base, mm->context.user_cs_limit
8724 +#endif
8725 +
8726 +       );
8727 +
8728         return buffer;
8729  }
8730  
8731 @@ -118,6 +130,12 @@ struct mem_size_stats
8732         unsigned long private_dirty;
8733  };
8734  
8735 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8736 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
8737 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
8738 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
8739 +#endif
8740 +
8741  static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
8742  {
8743         struct task_struct *task = m->private;
8744 @@ -136,13 +154,30 @@ static int show_map_internal(struct seq_
8745         }
8746  
8747         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
8748 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8749 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
8750 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
8751 +#else
8752                         vma->vm_start,
8753                         vma->vm_end,
8754 +#endif
8755 +
8756 +#if 0
8757 +                       flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
8758 +                       flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
8759 +                       flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
8760 +#else
8761                         flags & VM_READ ? 'r' : '-',
8762                         flags & VM_WRITE ? 'w' : '-',
8763                         flags & VM_EXEC ? 'x' : '-',
8764 +#endif
8765 +
8766                         flags & VM_MAYSHARE ? 's' : 'p',
8767 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8768 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
8769 +#else
8770                         vma->vm_pgoff << PAGE_SHIFT,
8771 +#endif
8772                         MAJOR(dev), MINOR(dev), ino, &len);
8773  
8774         /*
8775 @@ -154,13 +189,13 @@ static int show_map_internal(struct seq_
8776                 seq_path(m, file->f_vfsmnt, file->f_dentry, "\n");
8777         } else {
8778                 if (mm) {
8779 -                       if (vma->vm_start <= mm->start_brk &&
8780 -                                               vma->vm_end >= mm->brk) {
8781 +                       if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
8782                                 pad_len_spaces(m, len);
8783                                 seq_puts(m, "[heap]");
8784                         } else {
8785 -                               if (vma->vm_start <= mm->start_stack &&
8786 -                                       vma->vm_end >= mm->start_stack) {
8787 +                               if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
8788 +                                   (vma->vm_start <= mm->start_stack &&
8789 +                                       vma->vm_end >= mm->start_stack)) {
8790  
8791                                         pad_len_spaces(m, len);
8792                                         seq_puts(m, "[stack]");
8793 @@ -173,7 +208,25 @@ static int show_map_internal(struct seq_
8794         }
8795         seq_putc(m, '\n');
8796  
8797 -       if (mss)
8798 +       
8799 +       if (mss) {
8800 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
8801 +           if (PAX_RAND_FLAGS(mm))
8802 +               seq_printf(m,
8803 +                          "Size:          %8lu kB\n"
8804 +                          "Rss:           %8lu kB\n"
8805 +                          "Shared_Clean:  %8lu kB\n"
8806 +                          "Shared_Dirty:  %8lu kB\n"
8807 +                          "Private_Clean: %8lu kB\n"
8808 +                          "Private_Dirty: %8lu kB\n",
8809 +                          0UL,
8810 +                          0UL,
8811 +                          0UL,
8812 +                          0UL,
8813 +                          0UL,
8814 +                          0UL);
8815 +           else
8816 +#endif
8817                 seq_printf(m,
8818                            "Size:          %8lu kB\n"
8819                            "Rss:           %8lu kB\n"
8820 @@ -187,6 +240,7 @@ static int show_map_internal(struct seq_
8821                            mss->shared_dirty  >> 10,
8822                            mss->private_clean >> 10,
8823                            mss->private_dirty >> 10);
8824 +       }
8825  
8826         if (m->count < m->size)  /* vma is copied successfully */
8827                 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
8828 diff -urNp linux-2.6.16.2/fs/readdir.c linux-2.6.16.2/fs/readdir.c
8829 --- linux-2.6.16.2/fs/readdir.c 2006-04-07 12:56:47.000000000 -0400
8830 +++ linux-2.6.16.2/fs/readdir.c 2006-04-09 21:23:54.000000000 -0400
8831 @@ -16,6 +16,8 @@
8832  #include <linux/security.h>
8833  #include <linux/syscalls.h>
8834  #include <linux/unistd.h>
8835 +#include <linux/namei.h>
8836 +#include <linux/grsecurity.h>
8837  
8838  #include <asm/uaccess.h>
8839  
8840 @@ -65,6 +67,7 @@ struct old_linux_dirent {
8841  
8842  struct readdir_callback {
8843         struct old_linux_dirent __user * dirent;
8844 +       struct file * file;
8845         int result;
8846  };
8847  
8848 @@ -76,6 +79,10 @@ static int fillonedir(void * __buf, cons
8849  
8850         if (buf->result)
8851                 return -EINVAL;
8852 +
8853 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8854 +               return 0;
8855 +
8856         buf->result++;
8857         dirent = buf->dirent;
8858         if (!access_ok(VERIFY_WRITE, dirent,
8859 @@ -107,6 +114,7 @@ asmlinkage long old_readdir(unsigned int
8860  
8861         buf.result = 0;
8862         buf.dirent = dirent;
8863 +       buf.file = file;
8864  
8865         error = vfs_readdir(file, fillonedir, &buf);
8866         if (error >= 0)
8867 @@ -133,6 +141,7 @@ struct linux_dirent {
8868  struct getdents_callback {
8869         struct linux_dirent __user * current_dir;
8870         struct linux_dirent __user * previous;
8871 +       struct file * file;
8872         int count;
8873         int error;
8874  };
8875 @@ -147,6 +156,10 @@ static int filldir(void * __buf, const c
8876         buf->error = -EINVAL;   /* only used if we fail.. */
8877         if (reclen > buf->count)
8878                 return -EINVAL;
8879 +
8880 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8881 +               return 0;
8882 +
8883         dirent = buf->previous;
8884         if (dirent) {
8885                 if (__put_user(offset, &dirent->d_off))
8886 @@ -191,6 +204,7 @@ asmlinkage long sys_getdents(unsigned in
8887  
8888         buf.current_dir = dirent;
8889         buf.previous = NULL;
8890 +       buf.file = file;
8891         buf.count = count;
8892         buf.error = 0;
8893  
8894 @@ -217,6 +231,7 @@ out:
8895  struct getdents_callback64 {
8896         struct linux_dirent64 __user * current_dir;
8897         struct linux_dirent64 __user * previous;
8898 +       struct file * file;
8899         int count;
8900         int error;
8901  };
8902 @@ -231,6 +246,10 @@ static int filldir64(void * __buf, const
8903         buf->error = -EINVAL;   /* only used if we fail.. */
8904         if (reclen > buf->count)
8905                 return -EINVAL;
8906 +
8907 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
8908 +               return 0;
8909 +
8910         dirent = buf->previous;
8911         if (dirent) {
8912                 if (__put_user(offset, &dirent->d_off))
8913 @@ -277,6 +296,7 @@ asmlinkage long sys_getdents64(unsigned 
8914  
8915         buf.current_dir = dirent;
8916         buf.previous = NULL;
8917 +       buf.file = file;
8918         buf.count = count;
8919         buf.error = 0;
8920  
8921 diff -urNp linux-2.6.16.2/fs/xfs/linux-2.6/xfs_file.c linux-2.6.16.2/fs/xfs/linux-2.6/xfs_file.c
8922 --- linux-2.6.16.2/fs/xfs/linux-2.6/xfs_file.c  2006-04-07 12:56:47.000000000 -0400
8923 +++ linux-2.6.16.2/fs/xfs/linux-2.6/xfs_file.c  2006-04-09 21:23:54.000000000 -0400
8924 @@ -413,6 +413,11 @@ linvfs_file_mmap(
8925         vattr_t         va = { .va_mask = XFS_AT_UPDATIME };
8926         int             error;
8927  
8928 +#ifdef CONFIG_PAX_PAGEEXEC
8929 +       if (vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC)
8930 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
8931 +#endif
8932 +
8933         vma->vm_ops = &linvfs_file_vm_ops;
8934  
8935  #ifdef CONFIG_XFS_DMAPI
8936 diff -urNp linux-2.6.16.2/grsecurity/gracl_alloc.c linux-2.6.16.2/grsecurity/gracl_alloc.c
8937 --- linux-2.6.16.2/grsecurity/gracl_alloc.c     1969-12-31 19:00:00.000000000 -0500
8938 +++ linux-2.6.16.2/grsecurity/gracl_alloc.c     2006-04-09 21:23:54.000000000 -0400
8939 @@ -0,0 +1,91 @@
8940 +#include <linux/kernel.h>
8941 +#include <linux/mm.h>
8942 +#include <linux/slab.h>
8943 +#include <linux/vmalloc.h>
8944 +#include <linux/gracl.h>
8945 +#include <linux/grsecurity.h>
8946 +
8947 +static unsigned long alloc_stack_next = 1;
8948 +static unsigned long alloc_stack_size = 1;
8949 +static void **alloc_stack;
8950 +
8951 +static __inline__ int
8952 +alloc_pop(void)
8953 +{
8954 +       if (alloc_stack_next == 1)
8955 +               return 0;
8956 +
8957 +       kfree(alloc_stack[alloc_stack_next - 2]);
8958 +
8959 +       alloc_stack_next--;
8960 +
8961 +       return 1;
8962 +}
8963 +
8964 +static __inline__ void
8965 +alloc_push(void *buf)
8966 +{
8967 +       if (alloc_stack_next >= alloc_stack_size)
8968 +               BUG();
8969 +
8970 +       alloc_stack[alloc_stack_next - 1] = buf;
8971 +
8972 +       alloc_stack_next++;
8973 +
8974 +       return;
8975 +}
8976 +
8977 +void *
8978 +acl_alloc(unsigned long len)
8979 +{
8980 +       void *ret;
8981 +
8982 +       if (len > PAGE_SIZE)
8983 +               BUG();
8984 +
8985 +       ret = kmalloc(len, GFP_KERNEL);
8986 +
8987 +       if (ret)
8988 +               alloc_push(ret);
8989 +
8990 +       return ret;
8991 +}
8992 +
8993 +void
8994 +acl_free_all(void)
8995 +{
8996 +       if (gr_acl_is_enabled() || !alloc_stack)
8997 +               return;
8998 +
8999 +       while (alloc_pop()) ;
9000 +
9001 +       if (alloc_stack) {
9002 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
9003 +                       kfree(alloc_stack);
9004 +               else
9005 +                       vfree(alloc_stack);
9006 +       }
9007 +
9008 +       alloc_stack = NULL;
9009 +       alloc_stack_size = 1;
9010 +       alloc_stack_next = 1;
9011 +
9012 +       return;
9013 +}
9014 +
9015 +int
9016 +acl_alloc_stack_init(unsigned long size)
9017 +{
9018 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
9019 +               alloc_stack =
9020 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
9021 +       else
9022 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
9023 +
9024 +       alloc_stack_size = size;
9025 +
9026 +       if (!alloc_stack)
9027 +               return 0;
9028 +       else
9029 +               return 1;
9030 +}
9031 diff -urNp linux-2.6.16.2/grsecurity/gracl.c linux-2.6.16.2/grsecurity/gracl.c
9032 --- linux-2.6.16.2/grsecurity/gracl.c   1969-12-31 19:00:00.000000000 -0500
9033 +++ linux-2.6.16.2/grsecurity/gracl.c   2006-04-09 21:23:54.000000000 -0400
9034 @@ -0,0 +1,3532 @@
9035 +#include <linux/kernel.h>
9036 +#include <linux/module.h>
9037 +#include <linux/sched.h>
9038 +#include <linux/mm.h>
9039 +#include <linux/file.h>
9040 +#include <linux/fs.h>
9041 +#include <linux/namei.h>
9042 +#include <linux/mount.h>
9043 +#include <linux/tty.h>
9044 +#include <linux/proc_fs.h>
9045 +#include <linux/smp_lock.h>
9046 +#include <linux/slab.h>
9047 +#include <linux/vmalloc.h>
9048 +#include <linux/types.h>
9049 +#include <linux/capability.h>
9050 +#include <linux/sysctl.h>
9051 +#include <linux/netdevice.h>
9052 +#include <linux/ptrace.h>
9053 +#include <linux/gracl.h>
9054 +#include <linux/gralloc.h>
9055 +#include <linux/grsecurity.h>
9056 +#include <linux/grinternal.h>
9057 +#include <linux/percpu.h>
9058 +
9059 +#include <asm/uaccess.h>
9060 +#include <asm/errno.h>
9061 +#include <asm/mman.h>
9062 +
9063 +static struct acl_role_db acl_role_set;
9064 +static struct name_db name_set;
9065 +static struct inodev_db inodev_set;
9066 +
9067 +/* for keeping track of userspace pointers used for subjects, so we
9068 +   can share references in the kernel as well
9069 +*/
9070 +
9071 +static struct dentry *real_root;
9072 +static struct vfsmount *real_root_mnt;
9073 +
9074 +static struct acl_subj_map_db subj_map_set;
9075 +
9076 +static struct acl_role_label *default_role;
9077 +
9078 +static u16 acl_sp_role_value;
9079 +
9080 +extern char *gr_shared_page[4];
9081 +static DECLARE_MUTEX(gr_dev_sem);
9082 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
9083 +
9084 +struct gr_arg *gr_usermode;
9085 +
9086 +static unsigned int gr_status = GR_STATUS_INIT;
9087 +
9088 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
9089 +extern void gr_clear_learn_entries(void);
9090 +
9091 +#ifdef CONFIG_GRKERNSEC_RESLOG
9092 +extern void gr_log_resource(const struct task_struct *task,
9093 +                           const int res, const unsigned long wanted, const int gt);
9094 +#endif
9095 +
9096 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
9097 +                        struct dentry *root, struct vfsmount *rootmnt,
9098 +                        char *buffer, int buflen);
9099 +
9100 +unsigned char *gr_system_salt;
9101 +unsigned char *gr_system_sum;
9102 +
9103 +static struct sprole_pw **acl_special_roles = NULL;
9104 +static __u16 num_sprole_pws = 0;
9105 +
9106 +static struct acl_role_label *kernel_role = NULL;
9107 +
9108 +static unsigned int gr_auth_attempts = 0;
9109 +static unsigned long gr_auth_expires = 0UL;
9110 +
9111 +extern int gr_init_uidset(void);
9112 +extern void gr_free_uidset(void);
9113 +extern void gr_remove_uid(uid_t uid);
9114 +extern int gr_find_uid(uid_t uid);
9115 +
9116 +__inline__ int
9117 +gr_acl_is_enabled(void)
9118 +{
9119 +       return (gr_status & GR_READY);
9120 +}
9121 +
9122 +char gr_roletype_to_char(void)
9123 +{
9124 +       switch (current->role->roletype &
9125 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
9126 +                GR_ROLE_SPECIAL)) {
9127 +       case GR_ROLE_DEFAULT:
9128 +               return 'D';
9129 +       case GR_ROLE_USER:
9130 +               return 'U';
9131 +       case GR_ROLE_GROUP:
9132 +               return 'G';
9133 +       case GR_ROLE_SPECIAL:
9134 +               return 'S';
9135 +       }
9136 +
9137 +       return 'X';
9138 +}
9139 +
9140 +__inline__ int
9141 +gr_acl_tpe_check(void)
9142 +{
9143 +       if (unlikely(!(gr_status & GR_READY)))
9144 +               return 0;
9145 +       if (current->role->roletype & GR_ROLE_TPE)
9146 +               return 1;
9147 +       else
9148 +               return 0;
9149 +}
9150 +
9151 +int
9152 +gr_handle_rawio(const struct inode *inode)
9153 +{
9154 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
9155 +       if (inode && S_ISBLK(inode->i_mode) &&
9156 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
9157 +           !capable(CAP_SYS_RAWIO))
9158 +               return 1;
9159 +#endif
9160 +       return 0;
9161 +}
9162 +
9163 +static int
9164 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
9165 +{
9166 +       int i;
9167 +       unsigned long *l1;
9168 +       unsigned long *l2;
9169 +       unsigned char *c1;
9170 +       unsigned char *c2;
9171 +       int num_longs;
9172 +
9173 +       if (likely(lena != lenb))
9174 +               return 0;
9175 +
9176 +       l1 = (unsigned long *)a;
9177 +       l2 = (unsigned long *)b;
9178 +
9179 +       num_longs = lena / sizeof(unsigned long);
9180 +
9181 +       for (i = num_longs; i--; l1++, l2++) {
9182 +               if (unlikely(*l1 != *l2))
9183 +                       return 0;
9184 +       }
9185 +
9186 +       c1 = (unsigned char *) l1;
9187 +       c2 = (unsigned char *) l2;
9188 +
9189 +       i = lena - (num_longs * sizeof(unsigned long)); 
9190 +
9191 +       for (; i--; c1++, c2++) {
9192 +               if (unlikely(*c1 != *c2))
9193 +                       return 0;
9194 +       }
9195 +
9196 +       return 1;
9197 +}
9198 +               
9199 +static char *
9200 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
9201 +              struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
9202 +{
9203 +       char *end = buf + buflen;
9204 +       char *retval;
9205 +       int namelen = 0;
9206 +
9207 +       *--end = '\0';
9208 +
9209 +       retval = end - 1;
9210 +       *retval = '/';
9211 +
9212 +       if (dentry == root && vfsmnt == rootmnt)
9213 +               return retval;
9214 +       if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
9215 +               namelen = strlen(dentry->d_name.name);
9216 +               buflen -= namelen;
9217 +               if (buflen < 2)
9218 +                       goto err;
9219 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
9220 +                       buflen--;
9221 +       }
9222 +
9223 +       retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
9224 +       if (unlikely(IS_ERR(retval)))
9225 +err:
9226 +               retval = strcpy(buf, "<path too long>");
9227 +       else if (namelen != 0) {
9228 +               end = buf + buflen - 1; // accounts for null termination
9229 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
9230 +                       *end++ = '/'; // accounted for above with buflen--
9231 +               memcpy(end, dentry->d_name.name, namelen);
9232 +       }
9233 +
9234 +       return retval;
9235 +}
9236 +
9237 +static char *
9238 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
9239 +               char *buf, int buflen)
9240 +{
9241 +       char *res;
9242 +
9243 +       /* we can use real_root, real_root_mnt, because this is only called
9244 +          by the RBAC system */
9245 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
9246 +
9247 +       return res;
9248 +}
9249 +
9250 +static char *
9251 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
9252 +           char *buf, int buflen)
9253 +{
9254 +       char *res;
9255 +       struct dentry *root;
9256 +       struct vfsmount *rootmnt;
9257 +
9258 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
9259 +       read_lock(&child_reaper->fs->lock);
9260 +       root = dget(child_reaper->fs->root);
9261 +       rootmnt = mntget(child_reaper->fs->rootmnt);
9262 +       read_unlock(&child_reaper->fs->lock);
9263 +
9264 +       spin_lock(&dcache_lock);
9265 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
9266 +       spin_unlock(&dcache_lock);
9267 +
9268 +       dput(root);
9269 +       mntput(rootmnt);
9270 +       return res;
9271 +}
9272 +
9273 +static char *
9274 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
9275 +{
9276 +       char *ret;
9277 +       spin_lock(&dcache_lock);
9278 +       ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
9279 +                            PAGE_SIZE);
9280 +       spin_unlock(&dcache_lock);
9281 +       return ret;
9282 +}
9283 +
9284 +char *
9285 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
9286 +{
9287 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
9288 +                            PAGE_SIZE);
9289 +}
9290 +
9291 +char *
9292 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
9293 +{
9294 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
9295 +                          PAGE_SIZE);
9296 +}
9297 +
9298 +char *
9299 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
9300 +{
9301 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
9302 +                          PAGE_SIZE);
9303 +}
9304 +
9305 +char *
9306 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
9307 +{
9308 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
9309 +                          PAGE_SIZE);
9310 +}
9311 +
9312 +char *
9313 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
9314 +{
9315 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
9316 +                          PAGE_SIZE);
9317 +}
9318 +
9319 +__inline__ __u32
9320 +to_gr_audit(const __u32 reqmode)
9321 +{
9322 +       /* masks off auditable permission flags, then shifts them to create
9323 +          auditing flags, and adds the special case of append auditing if
9324 +          we're requesting write */
9325 +       return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
9326 +}
9327 +
9328 +struct acl_subject_label *
9329 +lookup_subject_map(const struct acl_subject_label *userp)
9330 +{
9331 +       unsigned int index = shash(userp, subj_map_set.s_size);
9332 +       struct subject_map *match;
9333 +
9334 +       match = subj_map_set.s_hash[index];
9335 +
9336 +       while (match && match->user != userp)
9337 +               match = match->next;
9338 +
9339 +       if (match != NULL)
9340 +               return match->kernel;
9341 +       else
9342 +               return NULL;
9343 +}
9344 +
9345 +static void
9346 +insert_subj_map_entry(struct subject_map *subjmap)
9347 +{
9348 +       unsigned int index = shash(subjmap->user, subj_map_set.s_size);
9349 +       struct subject_map **curr;
9350 +
9351 +       subjmap->prev = NULL;
9352 +
9353 +       curr = &subj_map_set.s_hash[index];
9354 +       if (*curr != NULL)
9355 +               (*curr)->prev = subjmap;
9356 +
9357 +       subjmap->next = *curr;
9358 +       *curr = subjmap;
9359 +
9360 +       return;
9361 +}
9362 +
9363 +static struct acl_role_label *
9364 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
9365 +                     const gid_t gid)
9366 +{
9367 +       unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
9368 +       struct acl_role_label *match;
9369 +       struct role_allowed_ip *ipp;
9370 +       unsigned int x;
9371 +
9372 +       match = acl_role_set.r_hash[index];
9373 +
9374 +       while (match) {
9375 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
9376 +                       for (x = 0; x < match->domain_child_num; x++) {
9377 +                               if (match->domain_children[x] == uid)
9378 +                                       goto found;
9379 +                       }
9380 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
9381 +                       break;
9382 +               match = match->next;
9383 +       }
9384 +found:
9385 +       if (match == NULL) {
9386 +             try_group:
9387 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
9388 +               match = acl_role_set.r_hash[index];
9389 +
9390 +               while (match) {
9391 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
9392 +                               for (x = 0; x < match->domain_child_num; x++) {
9393 +                                       if (match->domain_children[x] == gid)
9394 +                                               goto found2;
9395 +                               }
9396 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
9397 +                               break;
9398 +                       match = match->next;
9399 +               }
9400 +found2:
9401 +               if (match == NULL)
9402 +                       match = default_role;
9403 +               if (match->allowed_ips == NULL)
9404 +                       return match;
9405 +               else {
9406 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
9407 +                               if (likely
9408 +                                   ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
9409 +                                    (ntohl(ipp->addr) & ipp->netmask)))
9410 +                                       return match;
9411 +                       }
9412 +                       match = default_role;
9413 +               }
9414 +       } else if (match->allowed_ips == NULL) {
9415 +               return match;
9416 +       } else {
9417 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
9418 +                       if (likely
9419 +                           ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
9420 +                            (ntohl(ipp->addr) & ipp->netmask)))
9421 +                               return match;
9422 +               }
9423 +               goto try_group;
9424 +       }
9425 +
9426 +       return match;
9427 +}
9428 +
9429 +struct acl_subject_label *
9430 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
9431 +                     const struct acl_role_label *role)
9432 +{
9433 +       unsigned int index = fhash(ino, dev, role->subj_hash_size);
9434 +       struct acl_subject_label *match;
9435 +
9436 +       match = role->subj_hash[index];
9437 +
9438 +       while (match && (match->inode != ino || match->device != dev ||
9439 +              (match->mode & GR_DELETED))) {
9440 +               match = match->next;
9441 +       }
9442 +
9443 +       if (match && !(match->mode & GR_DELETED))
9444 +               return match;
9445 +       else
9446 +               return NULL;
9447 +}
9448 +
9449 +static struct acl_object_label *
9450 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
9451 +                    const struct acl_subject_label *subj)
9452 +{
9453 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
9454 +       struct acl_object_label *match;
9455 +
9456 +       match = subj->obj_hash[index];
9457 +
9458 +       while (match && (match->inode != ino || match->device != dev ||
9459 +              (match->mode & GR_DELETED))) {
9460 +               match = match->next;
9461 +       }
9462 +
9463 +       if (match && !(match->mode & GR_DELETED))
9464 +               return match;
9465 +       else
9466 +               return NULL;
9467 +}
9468 +
9469 +static struct acl_object_label *
9470 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
9471 +                    const struct acl_subject_label *subj)
9472 +{
9473 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
9474 +       struct acl_object_label *match;
9475 +
9476 +       match = subj->obj_hash[index];
9477 +
9478 +       while (match && (match->inode != ino || match->device != dev ||
9479 +              !(match->mode & GR_DELETED))) {
9480 +               match = match->next;
9481 +       }
9482 +
9483 +       if (match && (match->mode & GR_DELETED))
9484 +               return match;
9485 +
9486 +       match = subj->obj_hash[index];
9487 +
9488 +       while (match && (match->inode != ino || match->device != dev ||
9489 +              (match->mode & GR_DELETED))) {
9490 +               match = match->next;
9491 +       }
9492 +
9493 +       if (match && !(match->mode & GR_DELETED))
9494 +               return match;
9495 +       else
9496 +               return NULL;
9497 +}
9498 +
9499 +static struct name_entry *
9500 +lookup_name_entry(const char *name)
9501 +{
9502 +       unsigned int len = strlen(name);
9503 +       unsigned int key = full_name_hash(name, len);
9504 +       unsigned int index = key % name_set.n_size;
9505 +       struct name_entry *match;
9506 +
9507 +       match = name_set.n_hash[index];
9508 +
9509 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
9510 +               match = match->next;
9511 +
9512 +       return match;
9513 +}
9514 +
9515 +static struct inodev_entry *
9516 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
9517 +{
9518 +       unsigned int index = fhash(ino, dev, inodev_set.i_size);
9519 +       struct inodev_entry *match;
9520 +
9521 +       match = inodev_set.i_hash[index];
9522 +
9523 +       while (match && (match->nentry->inode != ino || match->nentry->device != dev))
9524 +               match = match->next;
9525 +
9526 +       return match;
9527 +}
9528 +
9529 +static void
9530 +insert_inodev_entry(struct inodev_entry *entry)
9531 +{
9532 +       unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
9533 +                                   inodev_set.i_size);
9534 +       struct inodev_entry **curr;
9535 +
9536 +       entry->prev = NULL;
9537 +
9538 +       curr = &inodev_set.i_hash[index];
9539 +       if (*curr != NULL)
9540 +               (*curr)->prev = entry;
9541 +       
9542 +       entry->next = *curr;
9543 +       *curr = entry;
9544 +
9545 +       return;
9546 +}
9547 +
9548 +static void
9549 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
9550 +{
9551 +       unsigned int index =
9552 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
9553 +       struct acl_role_label **curr;
9554 +
9555 +       role->prev = NULL;
9556 +
9557 +       curr = &acl_role_set.r_hash[index];
9558 +       if (*curr != NULL)
9559 +               (*curr)->prev = role;
9560 +
9561 +       role->next = *curr;
9562 +       *curr = role;
9563 +
9564 +       return;
9565 +}
9566 +
9567 +static void
9568 +insert_acl_role_label(struct acl_role_label *role)
9569 +{
9570 +       int i;
9571 +
9572 +       if (role->roletype & GR_ROLE_DOMAIN) {
9573 +               for (i = 0; i < role->domain_child_num; i++)
9574 +                       __insert_acl_role_label(role, role->domain_children[i]);
9575 +       } else
9576 +               __insert_acl_role_label(role, role->uidgid);
9577 +}
9578 +                                       
9579 +static int
9580 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
9581 +{
9582 +       struct name_entry **curr, *nentry;
9583 +       struct inodev_entry *ientry;
9584 +       unsigned int len = strlen(name);
9585 +       unsigned int key = full_name_hash(name, len);
9586 +       unsigned int index = key % name_set.n_size;
9587 +
9588 +       curr = &name_set.n_hash[index];
9589 +
9590 +       while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
9591 +               curr = &((*curr)->next);
9592 +
9593 +       if (*curr != NULL)
9594 +               return 1;
9595 +
9596 +       nentry = acl_alloc(sizeof (struct name_entry));
9597 +       if (nentry == NULL)
9598 +               return 0;
9599 +       ientry = acl_alloc(sizeof (struct inodev_entry));
9600 +       if (ientry == NULL)
9601 +               return 0;
9602 +       ientry->nentry = nentry;
9603 +
9604 +       nentry->key = key;
9605 +       nentry->name = name;
9606 +       nentry->inode = inode;
9607 +       nentry->device = device;
9608 +       nentry->len = len;
9609 +
9610 +       nentry->prev = NULL;
9611 +       curr = &name_set.n_hash[index];
9612 +       if (*curr != NULL)
9613 +               (*curr)->prev = nentry;
9614 +       nentry->next = *curr;
9615 +       *curr = nentry;
9616 +
9617 +       /* insert us into the table searchable by inode/dev */
9618 +       insert_inodev_entry(ientry);
9619 +
9620 +       return 1;
9621 +}
9622 +
9623 +static void
9624 +insert_acl_obj_label(struct acl_object_label *obj,
9625 +                    struct acl_subject_label *subj)
9626 +{
9627 +       unsigned int index =
9628 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
9629 +       struct acl_object_label **curr;
9630 +
9631 +       
9632 +       obj->prev = NULL;
9633 +
9634 +       curr = &subj->obj_hash[index];
9635 +       if (*curr != NULL)
9636 +               (*curr)->prev = obj;
9637 +
9638 +       obj->next = *curr;
9639 +       *curr = obj;
9640 +
9641 +       return;
9642 +}
9643 +
9644 +static void
9645 +insert_acl_subj_label(struct acl_subject_label *obj,
9646 +                     struct acl_role_label *role)
9647 +{
9648 +       unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
9649 +       struct acl_subject_label **curr;
9650 +
9651 +       obj->prev = NULL;
9652 +
9653 +       curr = &role->subj_hash[index];
9654 +       if (*curr != NULL)
9655 +               (*curr)->prev = obj;
9656 +
9657 +       obj->next = *curr;
9658 +       *curr = obj;
9659 +
9660 +       return;
9661 +}
9662 +
9663 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
9664 +
9665 +static void *
9666 +create_table(__u32 * len, int elementsize)
9667 +{
9668 +       unsigned int table_sizes[] = {
9669 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
9670 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
9671 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
9672 +               268435399, 536870909, 1073741789, 2147483647
9673 +       };
9674 +       void *newtable = NULL;
9675 +       unsigned int pwr = 0;
9676 +
9677 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
9678 +              table_sizes[pwr] <= *len)
9679 +               pwr++;
9680 +
9681 +       if (table_sizes[pwr] <= *len)
9682 +               return newtable;
9683 +
9684 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
9685 +               newtable =
9686 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
9687 +       else
9688 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
9689 +
9690 +       *len = table_sizes[pwr];
9691 +
9692 +       return newtable;
9693 +}
9694 +
9695 +static int
9696 +init_variables(const struct gr_arg *arg)
9697 +{
9698 +       unsigned int stacksize;
9699 +
9700 +       subj_map_set.s_size = arg->role_db.num_subjects;
9701 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
9702 +       name_set.n_size = arg->role_db.num_objects;
9703 +       inodev_set.i_size = arg->role_db.num_objects;
9704 +
9705 +       if (!subj_map_set.s_size || !acl_role_set.r_size ||
9706 +           !name_set.n_size || !inodev_set.i_size)
9707 +               return 1;
9708 +
9709 +       if (!gr_init_uidset())
9710 +               return 1;
9711 +
9712 +       /* set up the stack that holds allocation info */
9713 +
9714 +       stacksize = arg->role_db.num_pointers + 5;
9715 +
9716 +       if (!acl_alloc_stack_init(stacksize))
9717 +               return 1;
9718 +
9719 +       /* grab reference for the real root dentry and vfsmount */
9720 +       read_lock(&child_reaper->fs->lock);
9721 +       real_root_mnt = mntget(child_reaper->fs->rootmnt);
9722 +       real_root = dget(child_reaper->fs->root);
9723 +       read_unlock(&child_reaper->fs->lock);
9724 +       
9725 +
9726 +       subj_map_set.s_hash =
9727 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
9728 +       acl_role_set.r_hash =
9729 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
9730 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
9731 +       inodev_set.i_hash =
9732 +           (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
9733 +
9734 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
9735 +           !name_set.n_hash || !inodev_set.i_hash)
9736 +               return 1;
9737 +
9738 +       memset(subj_map_set.s_hash, 0,
9739 +              sizeof(struct subject_map *) * subj_map_set.s_size);
9740 +       memset(acl_role_set.r_hash, 0,
9741 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
9742 +       memset(name_set.n_hash, 0,
9743 +              sizeof (struct name_entry *) * name_set.n_size);
9744 +       memset(inodev_set.i_hash, 0,
9745 +              sizeof (struct inodev_entry *) * inodev_set.i_size);
9746 +
9747 +       return 0;
9748 +}
9749 +
9750 +/* free information not needed after startup
9751 +   currently contains user->kernel pointer mappings for subjects
9752 +*/
9753 +
9754 +static void
9755 +free_init_variables(void)
9756 +{
9757 +       __u32 i;
9758 +
9759 +       if (subj_map_set.s_hash) {
9760 +               for (i = 0; i < subj_map_set.s_size; i++) {
9761 +                       if (subj_map_set.s_hash[i]) {
9762 +                               kfree(subj_map_set.s_hash[i]);
9763 +                               subj_map_set.s_hash[i] = NULL;
9764 +                       }
9765 +               }
9766 +
9767 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
9768 +                   PAGE_SIZE)
9769 +                       kfree(subj_map_set.s_hash);
9770 +               else
9771 +                       vfree(subj_map_set.s_hash);
9772 +       }
9773 +
9774 +       return;
9775 +}
9776 +
9777 +static void
9778 +free_variables(void)
9779 +{
9780 +       struct acl_subject_label *s;
9781 +       struct acl_role_label *r;
9782 +       struct task_struct *task, *task2;
9783 +       unsigned int i, x;
9784 +
9785 +       gr_clear_learn_entries();
9786 +
9787 +       read_lock(&tasklist_lock);
9788 +       do_each_thread(task2, task) {
9789 +               task->acl_sp_role = 0;
9790 +               task->acl_role_id = 0;
9791 +               task->acl = NULL;
9792 +               task->role = NULL;
9793 +       } while_each_thread(task2, task);
9794 +       read_unlock(&tasklist_lock);
9795 +
9796 +       /* release the reference to the real root dentry and vfsmount */
9797 +       if (real_root)
9798 +               dput(real_root);
9799 +       real_root = NULL;
9800 +       if (real_root_mnt)
9801 +               mntput(real_root_mnt);
9802 +       real_root_mnt = NULL;
9803 +
9804 +       /* free all object hash tables */
9805 +
9806 +       FOR_EACH_ROLE_START(r, i)
9807 +               if (r->subj_hash == NULL)
9808 +                       break;
9809 +               FOR_EACH_SUBJECT_START(r, s, x)
9810 +                       if (s->obj_hash == NULL)
9811 +                               break;
9812 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
9813 +                               kfree(s->obj_hash);
9814 +                       else
9815 +                               vfree(s->obj_hash);
9816 +               FOR_EACH_SUBJECT_END(s, x)
9817 +               FOR_EACH_NESTED_SUBJECT_START(r, s)
9818 +                       if (s->obj_hash == NULL)
9819 +                               break;
9820 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
9821 +                               kfree(s->obj_hash);
9822 +                       else
9823 +                               vfree(s->obj_hash);
9824 +               FOR_EACH_NESTED_SUBJECT_END(s)
9825 +               if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
9826 +                       kfree(r->subj_hash);
9827 +               else
9828 +                       vfree(r->subj_hash);
9829 +       FOR_EACH_ROLE_END(r,i)
9830 +
9831 +       acl_free_all();
9832 +
9833 +       if (acl_role_set.r_hash) {
9834 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
9835 +                   PAGE_SIZE)
9836 +                       kfree(acl_role_set.r_hash);
9837 +               else
9838 +                       vfree(acl_role_set.r_hash);
9839 +       }
9840 +       if (name_set.n_hash) {
9841 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
9842 +                   PAGE_SIZE)
9843 +                       kfree(name_set.n_hash);
9844 +               else
9845 +                       vfree(name_set.n_hash);
9846 +       }
9847 +
9848 +       if (inodev_set.i_hash) {
9849 +               if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
9850 +                   PAGE_SIZE)
9851 +                       kfree(inodev_set.i_hash);
9852 +               else
9853 +                       vfree(inodev_set.i_hash);
9854 +       }
9855 +
9856 +       gr_free_uidset();
9857 +
9858 +       memset(&name_set, 0, sizeof (struct name_db));
9859 +       memset(&inodev_set, 0, sizeof (struct inodev_db));
9860 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
9861 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
9862 +
9863 +       default_role = NULL;
9864 +
9865 +       return;
9866 +}
9867 +
9868 +static __u32
9869 +count_user_objs(struct acl_object_label *userp)
9870 +{
9871 +       struct acl_object_label o_tmp;
9872 +       __u32 num = 0;
9873 +
9874 +       while (userp) {
9875 +               if (copy_from_user(&o_tmp, userp,
9876 +                                  sizeof (struct acl_object_label)))
9877 +                       break;
9878 +
9879 +               userp = o_tmp.prev;
9880 +               num++;
9881 +       }
9882 +
9883 +       return num;
9884 +}
9885 +
9886 +static struct acl_subject_label *
9887 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
9888 +
9889 +static int
9890 +copy_user_glob(struct acl_object_label *obj)
9891 +{
9892 +       struct acl_object_label *g_tmp, **guser;
9893 +       unsigned int len;
9894 +       char *tmp;
9895 +
9896 +       if (obj->globbed == NULL)
9897 +               return 0;
9898 +
9899 +       guser = &obj->globbed;
9900 +       while (*guser) {
9901 +               g_tmp = (struct acl_object_label *)
9902 +                       acl_alloc(sizeof (struct acl_object_label));
9903 +               if (g_tmp == NULL)
9904 +                       return -ENOMEM;
9905 +
9906 +               if (copy_from_user(g_tmp, *guser,
9907 +                                  sizeof (struct acl_object_label)))
9908 +                       return -EFAULT;
9909 +
9910 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
9911 +
9912 +               if (!len || len >= PATH_MAX)
9913 +                       return -EINVAL;
9914 +
9915 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
9916 +                       return -ENOMEM;
9917 +
9918 +               if (copy_from_user(tmp, g_tmp->filename, len))
9919 +                       return -EFAULT;
9920 +
9921 +               g_tmp->filename = tmp;
9922 +
9923 +               *guser = g_tmp;
9924 +               guser = &(g_tmp->next);
9925 +       }
9926 +
9927 +       return 0;
9928 +}
9929 +
9930 +static int
9931 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
9932 +              struct acl_role_label *role)
9933 +{
9934 +       struct acl_object_label *o_tmp;
9935 +       unsigned int len;
9936 +       int ret;
9937 +       char *tmp;
9938 +
9939 +       while (userp) {
9940 +               if ((o_tmp = (struct acl_object_label *)
9941 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
9942 +                       return -ENOMEM;
9943 +
9944 +               if (copy_from_user(o_tmp, userp,
9945 +                                  sizeof (struct acl_object_label)))
9946 +                       return -EFAULT;
9947 +
9948 +               userp = o_tmp->prev;
9949 +
9950 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
9951 +
9952 +               if (!len || len >= PATH_MAX)
9953 +                       return -EINVAL;
9954 +
9955 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
9956 +                       return -ENOMEM;
9957 +
9958 +               if (copy_from_user(tmp, o_tmp->filename, len))
9959 +                       return -EFAULT;
9960 +
9961 +               o_tmp->filename = tmp;
9962 +
9963 +               insert_acl_obj_label(o_tmp, subj);
9964 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
9965 +                                      o_tmp->device))
9966 +                       return -ENOMEM;
9967 +
9968 +               ret = copy_user_glob(o_tmp);
9969 +               if (ret)
9970 +                       return ret;
9971 +
9972 +               if (o_tmp->nested) {
9973 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
9974 +                       if (IS_ERR(o_tmp->nested))
9975 +                               return PTR_ERR(o_tmp->nested);
9976 +
9977 +                       /* insert into nested subject list */
9978 +                       o_tmp->nested->next = role->hash->first;
9979 +                       role->hash->first = o_tmp->nested;
9980 +               }
9981 +       }
9982 +
9983 +       return 0;
9984 +}
9985 +
9986 +static __u32
9987 +count_user_subjs(struct acl_subject_label *userp)
9988 +{
9989 +       struct acl_subject_label s_tmp;
9990 +       __u32 num = 0;
9991 +
9992 +       while (userp) {
9993 +               if (copy_from_user(&s_tmp, userp,
9994 +                                  sizeof (struct acl_subject_label)))
9995 +                       break;
9996 +
9997 +               userp = s_tmp.prev;
9998 +               /* do not count nested subjects against this count, since
9999 +                  they are not included in the hash table, but are
10000 +                  attached to objects.  We have already counted
10001 +                  the subjects in userspace for the allocation 
10002 +                  stack
10003 +               */
10004 +               if (!(s_tmp.mode & GR_NESTED))
10005 +                       num++;
10006 +       }
10007 +
10008 +       return num;
10009 +}
10010 +
10011 +static int
10012 +copy_user_allowedips(struct acl_role_label *rolep)
10013 +{
10014 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
10015 +
10016 +       ruserip = rolep->allowed_ips;
10017 +
10018 +       while (ruserip) {
10019 +               rlast = rtmp;
10020 +
10021 +               if ((rtmp = (struct role_allowed_ip *)
10022 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
10023 +                       return -ENOMEM;
10024 +
10025 +               if (copy_from_user(rtmp, ruserip,
10026 +                                  sizeof (struct role_allowed_ip)))
10027 +                       return -EFAULT;
10028 +
10029 +               ruserip = rtmp->prev;
10030 +
10031 +               if (!rlast) {
10032 +                       rtmp->prev = NULL;
10033 +                       rolep->allowed_ips = rtmp;
10034 +               } else {
10035 +                       rlast->next = rtmp;
10036 +                       rtmp->prev = rlast;
10037 +               }
10038 +
10039 +               if (!ruserip)
10040 +                       rtmp->next = NULL;
10041 +       }
10042 +
10043 +       return 0;
10044 +}
10045 +
10046 +static int
10047 +copy_user_transitions(struct acl_role_label *rolep)
10048 +{
10049 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
10050 +       
10051 +       unsigned int len;
10052 +       char *tmp;
10053 +
10054 +       rusertp = rolep->transitions;
10055 +
10056 +       while (rusertp) {
10057 +               rlast = rtmp;
10058 +
10059 +               if ((rtmp = (struct role_transition *)
10060 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
10061 +                       return -ENOMEM;
10062 +
10063 +               if (copy_from_user(rtmp, rusertp,
10064 +                                  sizeof (struct role_transition)))
10065 +                       return -EFAULT;
10066 +
10067 +               rusertp = rtmp->prev;
10068 +
10069 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
10070 +
10071 +               if (!len || len >= GR_SPROLE_LEN)
10072 +                       return -EINVAL;
10073 +
10074 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
10075 +                       return -ENOMEM;
10076 +
10077 +               if (copy_from_user(tmp, rtmp->rolename, len))
10078 +                       return -EFAULT;
10079 +
10080 +               rtmp->rolename = tmp;
10081 +
10082 +               if (!rlast) {
10083 +                       rtmp->prev = NULL;
10084 +                       rolep->transitions = rtmp;
10085 +               } else {
10086 +                       rlast->next = rtmp;
10087 +                       rtmp->prev = rlast;
10088 +               }
10089 +
10090 +               if (!rusertp)
10091 +                       rtmp->next = NULL;
10092 +       }
10093 +
10094 +       return 0;
10095 +}
10096 +
10097 +static struct acl_subject_label *
10098 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
10099 +{
10100 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
10101 +       unsigned int len;
10102 +       char *tmp;
10103 +       __u32 num_objs;
10104 +       struct acl_ip_label **i_tmp, *i_utmp2;
10105 +       struct gr_hash_struct ghash;
10106 +       struct subject_map *subjmap;
10107 +       unsigned int i_num;
10108 +       int err;
10109 +
10110 +       s_tmp = lookup_subject_map(userp);
10111 +
10112 +       /* we've already copied this subject into the kernel, just return
10113 +          the reference to it, and don't copy it over again
10114 +       */
10115 +       if (s_tmp)
10116 +               return(s_tmp);
10117 +
10118 +       if ((s_tmp = (struct acl_subject_label *)
10119 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
10120 +               return ERR_PTR(-ENOMEM);
10121 +
10122 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
10123 +       if (subjmap == NULL)
10124 +               return ERR_PTR(-ENOMEM);
10125 +
10126 +       subjmap->user = userp;
10127 +       subjmap->kernel = s_tmp;
10128 +       insert_subj_map_entry(subjmap);
10129 +
10130 +       if (copy_from_user(s_tmp, userp,
10131 +                          sizeof (struct acl_subject_label)))
10132 +               return ERR_PTR(-EFAULT);
10133 +
10134 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
10135 +
10136 +       if (!len || len >= PATH_MAX)
10137 +               return ERR_PTR(-EINVAL);
10138 +
10139 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
10140 +               return ERR_PTR(-ENOMEM);
10141 +
10142 +       if (copy_from_user(tmp, s_tmp->filename, len))
10143 +               return ERR_PTR(-EFAULT);
10144 +
10145 +       s_tmp->filename = tmp;
10146 +
10147 +       if (!strcmp(s_tmp->filename, "/"))
10148 +               role->root_label = s_tmp;
10149 +
10150 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
10151 +               return ERR_PTR(-EFAULT);
10152 +
10153 +       /* copy user and group transition tables */
10154 +
10155 +       if (s_tmp->user_trans_num) {
10156 +               uid_t *uidlist;
10157 +
10158 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
10159 +               if (uidlist == NULL)
10160 +                       return ERR_PTR(-ENOMEM);
10161 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
10162 +                       return ERR_PTR(-EFAULT);
10163 +
10164 +               s_tmp->user_transitions = uidlist;
10165 +       }
10166 +
10167 +       if (s_tmp->group_trans_num) {
10168 +               gid_t *gidlist;
10169 +
10170 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
10171 +               if (gidlist == NULL)
10172 +                       return ERR_PTR(-ENOMEM);
10173 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
10174 +                       return ERR_PTR(-EFAULT);
10175 +
10176 +               s_tmp->group_transitions = gidlist;
10177 +       }
10178 +
10179 +       /* set up object hash table */
10180 +       num_objs = count_user_objs(ghash.first);
10181 +
10182 +       s_tmp->obj_hash_size = num_objs;
10183 +       s_tmp->obj_hash =
10184 +           (struct acl_object_label **)
10185 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
10186 +
10187 +       if (!s_tmp->obj_hash)
10188 +               return ERR_PTR(-ENOMEM);
10189 +
10190 +       memset(s_tmp->obj_hash, 0,
10191 +              s_tmp->obj_hash_size *
10192 +              sizeof (struct acl_object_label *));
10193 +
10194 +       /* add in objects */
10195 +       err = copy_user_objs(ghash.first, s_tmp, role);
10196 +
10197 +       if (err)
10198 +               return ERR_PTR(err);
10199 +
10200 +       /* set pointer for parent subject */
10201 +       if (s_tmp->parent_subject) {
10202 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
10203 +
10204 +               if (IS_ERR(s_tmp2))
10205 +                       return s_tmp2;
10206 +
10207 +               s_tmp->parent_subject = s_tmp2;
10208 +       }
10209 +
10210 +       /* add in ip acls */
10211 +
10212 +       if (!s_tmp->ip_num) {
10213 +               s_tmp->ips = NULL;
10214 +               goto insert;
10215 +       }
10216 +
10217 +       i_tmp =
10218 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
10219 +                                              sizeof (struct
10220 +                                                      acl_ip_label *));
10221 +
10222 +       if (!i_tmp)
10223 +               return ERR_PTR(-ENOMEM);
10224 +
10225 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
10226 +               *(i_tmp + i_num) =
10227 +                   (struct acl_ip_label *)
10228 +                   acl_alloc(sizeof (struct acl_ip_label));
10229 +               if (!*(i_tmp + i_num))
10230 +                       return ERR_PTR(-ENOMEM);
10231 +
10232 +               if (copy_from_user
10233 +                   (&i_utmp2, s_tmp->ips + i_num,
10234 +                    sizeof (struct acl_ip_label *)))
10235 +                       return ERR_PTR(-EFAULT);
10236 +
10237 +               if (copy_from_user
10238 +                   (*(i_tmp + i_num), i_utmp2,
10239 +                    sizeof (struct acl_ip_label)))
10240 +                       return ERR_PTR(-EFAULT);
10241 +               
10242 +               if ((*(i_tmp + i_num))->iface == NULL)
10243 +                       continue;
10244 +
10245 +               len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
10246 +               if (!len || len >= IFNAMSIZ)
10247 +                       return ERR_PTR(-EINVAL);
10248 +               tmp = acl_alloc(len);
10249 +               if (tmp == NULL)
10250 +                       return ERR_PTR(-ENOMEM);
10251 +               if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
10252 +                       return ERR_PTR(-EFAULT);
10253 +               (*(i_tmp + i_num))->iface = tmp;
10254 +       }
10255 +
10256 +       s_tmp->ips = i_tmp;
10257 +
10258 +insert:
10259 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
10260 +                              s_tmp->device))
10261 +               return ERR_PTR(-ENOMEM);
10262 +
10263 +       return s_tmp;
10264 +}
10265 +
10266 +static int
10267 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
10268 +{
10269 +       struct acl_subject_label s_pre;
10270 +       struct acl_subject_label * ret;
10271 +       int err;
10272 +
10273 +       while (userp) {
10274 +               if (copy_from_user(&s_pre, userp,
10275 +                                  sizeof (struct acl_subject_label)))
10276 +                       return -EFAULT;
10277 +               
10278 +               /* do not add nested subjects here, add
10279 +                  while parsing objects
10280 +               */
10281 +
10282 +               if (s_pre.mode & GR_NESTED) {
10283 +                       userp = s_pre.prev;
10284 +                       continue;
10285 +               }
10286 +
10287 +               ret = do_copy_user_subj(userp, role);
10288 +
10289 +               err = PTR_ERR(ret);
10290 +               if (IS_ERR(ret))
10291 +                       return err;
10292 +
10293 +               insert_acl_subj_label(ret, role);
10294 +
10295 +               userp = s_pre.prev;
10296 +       }
10297 +
10298 +       return 0;
10299 +}
10300 +
10301 +static int
10302 +copy_user_acl(struct gr_arg *arg)
10303 +{
10304 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
10305 +       struct sprole_pw *sptmp;
10306 +       struct gr_hash_struct *ghash;
10307 +       uid_t *domainlist;
10308 +       unsigned int r_num;
10309 +       unsigned int len;
10310 +       char *tmp;
10311 +       int err = 0;
10312 +       __u16 i;
10313 +       __u32 num_subjs;
10314 +
10315 +       /* we need a default and kernel role */
10316 +       if (arg->role_db.num_roles < 2)
10317 +               return -EINVAL;
10318 +
10319 +       /* copy special role authentication info from userspace */
10320 +
10321 +       num_sprole_pws = arg->num_sprole_pws;
10322 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
10323 +
10324 +       if (!acl_special_roles) {
10325 +               err = -ENOMEM;
10326 +               goto cleanup;
10327 +       }
10328 +
10329 +       for (i = 0; i < num_sprole_pws; i++) {
10330 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
10331 +               if (!sptmp) {
10332 +                       err = -ENOMEM;
10333 +                       goto cleanup;
10334 +               }
10335 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
10336 +                                  sizeof (struct sprole_pw))) {
10337 +                       err = -EFAULT;
10338 +                       goto cleanup;
10339 +               }
10340 +
10341 +               len =
10342 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
10343 +
10344 +               if (!len || len >= GR_SPROLE_LEN) {
10345 +                       err = -EINVAL;
10346 +                       goto cleanup;
10347 +               }
10348 +
10349 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
10350 +                       err = -ENOMEM;
10351 +                       goto cleanup;
10352 +               }
10353 +
10354 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
10355 +                       err = -EFAULT;
10356 +                       goto cleanup;
10357 +               }
10358 +
10359 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10360 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
10361 +#endif
10362 +               sptmp->rolename = tmp;
10363 +               acl_special_roles[i] = sptmp;
10364 +       }
10365 +
10366 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
10367 +
10368 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
10369 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
10370 +
10371 +               if (!r_tmp) {
10372 +                       err = -ENOMEM;
10373 +                       goto cleanup;
10374 +               }
10375 +
10376 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
10377 +                                  sizeof (struct acl_role_label *))) {
10378 +                       err = -EFAULT;
10379 +                       goto cleanup;
10380 +               }
10381 +
10382 +               if (copy_from_user(r_tmp, r_utmp2,
10383 +                                  sizeof (struct acl_role_label))) {
10384 +                       err = -EFAULT;
10385 +                       goto cleanup;
10386 +               }
10387 +
10388 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
10389 +
10390 +               if (!len || len >= PATH_MAX) {
10391 +                       err = -EINVAL;
10392 +                       goto cleanup;
10393 +               }
10394 +
10395 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
10396 +                       err = -ENOMEM;
10397 +                       goto cleanup;
10398 +               }
10399 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
10400 +                       err = -EFAULT;
10401 +                       goto cleanup;
10402 +               }
10403 +               r_tmp->rolename = tmp;
10404 +
10405 +               if (!strcmp(r_tmp->rolename, "default")
10406 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
10407 +                       default_role = r_tmp;
10408 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
10409 +                       kernel_role = r_tmp;
10410 +               }
10411 +
10412 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
10413 +                       err = -ENOMEM;
10414 +                       goto cleanup;
10415 +               }
10416 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
10417 +                       err = -EFAULT;
10418 +                       goto cleanup;
10419 +               }
10420 +
10421 +               r_tmp->hash = ghash;
10422 +
10423 +               num_subjs = count_user_subjs(r_tmp->hash->first);
10424 +
10425 +               r_tmp->subj_hash_size = num_subjs;
10426 +               r_tmp->subj_hash =
10427 +                   (struct acl_subject_label **)
10428 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
10429 +
10430 +               if (!r_tmp->subj_hash) {
10431 +                       err = -ENOMEM;
10432 +                       goto cleanup;
10433 +               }
10434 +
10435 +               err = copy_user_allowedips(r_tmp);
10436 +               if (err)
10437 +                       goto cleanup;
10438 +
10439 +               /* copy domain info */
10440 +               if (r_tmp->domain_children != NULL) {
10441 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
10442 +                       if (domainlist == NULL) {
10443 +                               err = -ENOMEM;
10444 +                               goto cleanup;
10445 +                       }
10446 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
10447 +                               err = -EFAULT;
10448 +                               goto cleanup;
10449 +                       }
10450 +                       r_tmp->domain_children = domainlist;
10451 +               }
10452 +
10453 +               err = copy_user_transitions(r_tmp);
10454 +               if (err)
10455 +                       goto cleanup;
10456 +
10457 +               memset(r_tmp->subj_hash, 0,
10458 +                      r_tmp->subj_hash_size *
10459 +                      sizeof (struct acl_subject_label *));
10460 +
10461 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
10462 +
10463 +               if (err)
10464 +                       goto cleanup;
10465 +
10466 +               /* set nested subject list to null */
10467 +               r_tmp->hash->first = NULL;
10468 +
10469 +               insert_acl_role_label(r_tmp);
10470 +       }
10471 +
10472 +       goto return_err;
10473 +      cleanup:
10474 +       free_variables();
10475 +      return_err:
10476 +       return err;
10477 +
10478 +}
10479 +
10480 +static int
10481 +gracl_init(struct gr_arg *args)
10482 +{
10483 +       int error = 0;
10484 +
10485 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
10486 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
10487 +
10488 +       if (init_variables(args)) {
10489 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
10490 +               error = -ENOMEM;
10491 +               free_variables();
10492 +               goto out;
10493 +       }
10494 +
10495 +       error = copy_user_acl(args);
10496 +       free_init_variables();
10497 +       if (error) {
10498 +               free_variables();
10499 +               goto out;
10500 +       }
10501 +
10502 +       if ((error = gr_set_acls(0))) {
10503 +               free_variables();
10504 +               goto out;
10505 +       }
10506 +
10507 +       gr_status |= GR_READY;
10508 +      out:
10509 +       return error;
10510 +}
10511 +
10512 +/* derived from glibc fnmatch() 0: match, 1: no match*/
10513 +
10514 +static int
10515 +glob_match(const char *p, const char *n)
10516 +{
10517 +       char c;
10518 +
10519 +       while ((c = *p++) != '\0') {
10520 +       switch (c) {
10521 +               case '?':
10522 +                       if (*n == '\0')
10523 +                               return 1;
10524 +                       else if (*n == '/')
10525 +                               return 1;
10526 +                       break;
10527 +               case '\\':
10528 +                       if (*n != c)
10529 +                               return 1;
10530 +                       break;
10531 +               case '*':
10532 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
10533 +                               if (*n == '/')
10534 +                                       return 1;
10535 +                               else if (c == '?') {
10536 +                                       if (*n == '\0')
10537 +                                               return 1;
10538 +                                       else
10539 +                                               ++n;
10540 +                               }
10541 +                       }
10542 +                       if (c == '\0') {
10543 +                               return 0;
10544 +                       } else {
10545 +                               const char *endp;
10546 +
10547 +                               if ((endp = strchr(n, '/')) == NULL)
10548 +                                       endp = n + strlen(n);
10549 +
10550 +                               if (c == '[') {
10551 +                                       for (--p; n < endp; ++n)
10552 +                                               if (!glob_match(p, n))
10553 +                                                       return 0;
10554 +                               } else if (c == '/') {
10555 +                                       while (*n != '\0' && *n != '/')
10556 +                                               ++n;
10557 +                                       if (*n == '/' && !glob_match(p, n + 1))
10558 +                                               return 0;
10559 +                               } else {
10560 +                                       for (--p; n < endp; ++n)
10561 +                                               if (*n == c && !glob_match(p, n))
10562 +                                                       return 0;
10563 +                               }
10564 +
10565 +                               return 1;
10566 +                       }
10567 +               case '[':
10568 +                       {
10569 +                       int not;
10570 +                       char cold;
10571 +
10572 +                       if (*n == '\0' || *n == '/')
10573 +                               return 1;
10574 +
10575 +                       not = (*p == '!' || *p == '^');
10576 +                       if (not)
10577 +                               ++p;
10578 +
10579 +                       c = *p++;
10580 +                       for (;;) {
10581 +                               unsigned char fn = (unsigned char)*n;
10582 +
10583 +                               if (c == '\0')
10584 +                                       return 1;
10585 +                               else {
10586 +                                       if (c == fn)
10587 +                                               goto matched;
10588 +                                       cold = c;
10589 +                                       c = *p++;
10590 +
10591 +                                       if (c == '-' && *p != ']') {
10592 +                                               unsigned char cend = *p++;
10593 +
10594 +                                               if (cend == '\0')
10595 +                                                       return 1;
10596 +
10597 +                                               if (cold <= fn && fn <= cend)
10598 +                                                       goto matched;
10599 +
10600 +                                               c = *p++;
10601 +                                       }
10602 +                               }
10603 +
10604 +                               if (c == ']')
10605 +                                       break;
10606 +                       }
10607 +                       if (!not)
10608 +                               return 1;
10609 +                       break;
10610 +               matched:
10611 +                       while (c != ']') {
10612 +                               if (c == '\0')
10613 +                                       return 1;
10614 +
10615 +                               c = *p++;
10616 +                       }
10617 +                       if (not)
10618 +                               return 1;
10619 +               }
10620 +               break;
10621 +       default:
10622 +               if (c != *n)
10623 +                       return 1;
10624 +       }
10625 +
10626 +       ++n;
10627 +       }
10628 +
10629 +       if (*n == '\0')
10630 +               return 0;
10631 +
10632 +       if (*n == '/')
10633 +               return 0;
10634 +
10635 +       return 1;
10636 +}
10637 +
10638 +static struct acl_object_label *
10639 +chk_glob_label(struct acl_object_label *globbed,
10640 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
10641 +{
10642 +       struct acl_object_label *tmp;
10643 +
10644 +       if (*path == NULL)
10645 +               *path = gr_to_filename_nolock(dentry, mnt);
10646 +
10647 +       tmp = globbed;
10648 +
10649 +       while (tmp) {
10650 +               if (!glob_match(tmp->filename, *path))
10651 +                       return tmp;
10652 +               tmp = tmp->next;
10653 +       }
10654 +
10655 +       return NULL;
10656 +}
10657 +
10658 +static struct acl_object_label *
10659 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
10660 +           const ino_t curr_ino, const dev_t curr_dev,
10661 +           const struct acl_subject_label *subj, char **path)
10662 +{
10663 +       struct acl_subject_label *tmpsubj;
10664 +       struct acl_object_label *retval;
10665 +       struct acl_object_label *retval2;
10666 +
10667 +       tmpsubj = (struct acl_subject_label *) subj;
10668 +       read_lock(&gr_inode_lock);
10669 +       do {
10670 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
10671 +               if (retval) {
10672 +                       if (retval->globbed) {
10673 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
10674 +                                               (struct vfsmount *)orig_mnt, path);
10675 +                               if (retval2)
10676 +                                       retval = retval2;
10677 +                       }
10678 +                       break;
10679 +               }
10680 +       } while ((tmpsubj = tmpsubj->parent_subject));
10681 +       read_unlock(&gr_inode_lock);
10682 +
10683 +       return retval;
10684 +}
10685 +
10686 +static __inline__ struct acl_object_label *
10687 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
10688 +           const struct dentry *curr_dentry,
10689 +           const struct acl_subject_label *subj, char **path)
10690 +{
10691 +       return __full_lookup(orig_dentry, orig_mnt,
10692 +                            curr_dentry->d_inode->i_ino, 
10693 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
10694 +}
10695 +
10696 +static struct acl_object_label *
10697 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10698 +             const struct acl_subject_label *subj, char *path)
10699 +{
10700 +       struct dentry *dentry = (struct dentry *) l_dentry;
10701 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
10702 +       struct acl_object_label *retval;
10703 +
10704 +       spin_lock(&dcache_lock);
10705 +
10706 +       for (;;) {
10707 +               if (dentry == real_root && mnt == real_root_mnt)
10708 +                       break;
10709 +
10710 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
10711 +                       if (mnt->mnt_parent == mnt)
10712 +                               break;
10713 +
10714 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10715 +                       if (retval != NULL)
10716 +                               goto out;
10717 +
10718 +                       dentry = mnt->mnt_mountpoint;
10719 +                       mnt = mnt->mnt_parent;
10720 +                       continue;
10721 +               }
10722 +
10723 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10724 +               if (retval != NULL)
10725 +                       goto out;
10726 +
10727 +               dentry = dentry->d_parent;
10728 +       }
10729 +
10730 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
10731 +
10732 +       if (retval == NULL)
10733 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
10734 +out:
10735 +       spin_unlock(&dcache_lock);
10736 +       return retval;
10737 +}
10738 +
10739 +static __inline__ struct acl_object_label *
10740 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10741 +             const struct acl_subject_label *subj)
10742 +{
10743 +       char *path = NULL;
10744 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
10745 +}
10746 +
10747 +static __inline__ struct acl_object_label *
10748 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10749 +                    const struct acl_subject_label *subj, char *path)
10750 +{
10751 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
10752 +}
10753 +
10754 +static struct acl_subject_label *
10755 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
10756 +              const struct acl_role_label *role)
10757 +{
10758 +       struct dentry *dentry = (struct dentry *) l_dentry;
10759 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
10760 +       struct acl_subject_label *retval;
10761 +
10762 +       spin_lock(&dcache_lock);
10763 +
10764 +       for (;;) {
10765 +               if (dentry == real_root && mnt == real_root_mnt)
10766 +                       break;
10767 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
10768 +                       if (mnt->mnt_parent == mnt)
10769 +                               break;
10770 +
10771 +                       read_lock(&gr_inode_lock);
10772 +                       retval =
10773 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
10774 +                                               dentry->d_inode->i_sb->s_dev, role);
10775 +                       read_unlock(&gr_inode_lock);
10776 +                       if (retval != NULL)
10777 +                               goto out;
10778 +
10779 +                       dentry = mnt->mnt_mountpoint;
10780 +                       mnt = mnt->mnt_parent;
10781 +                       continue;
10782 +               }
10783 +
10784 +               read_lock(&gr_inode_lock);
10785 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
10786 +                                         dentry->d_inode->i_sb->s_dev, role);
10787 +               read_unlock(&gr_inode_lock);
10788 +               if (retval != NULL)
10789 +                       goto out;
10790 +
10791 +               dentry = dentry->d_parent;
10792 +       }
10793 +
10794 +       read_lock(&gr_inode_lock);
10795 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
10796 +                                 dentry->d_inode->i_sb->s_dev, role);
10797 +       read_unlock(&gr_inode_lock);
10798 +
10799 +       if (unlikely(retval == NULL)) {
10800 +               read_lock(&gr_inode_lock);
10801 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
10802 +                                         real_root->d_inode->i_sb->s_dev, role);
10803 +               read_unlock(&gr_inode_lock);
10804 +       }
10805 +out:
10806 +       spin_unlock(&dcache_lock);
10807 +
10808 +       return retval;
10809 +}
10810 +
10811 +static void
10812 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
10813 +{
10814 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
10815 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
10816 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
10817 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
10818 +
10819 +       return;
10820 +}
10821 +
10822 +static void
10823 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
10824 +                      const unsigned int effective, const unsigned int fs)
10825 +{
10826 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
10827 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
10828 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
10829 +                      type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
10830 +
10831 +       return;
10832 +}
10833 +
10834 +__u32
10835 +gr_check_link(const struct dentry * new_dentry,
10836 +             const struct dentry * parent_dentry,
10837 +             const struct vfsmount * parent_mnt,
10838 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
10839 +{
10840 +       struct acl_object_label *obj;
10841 +       __u32 oldmode, newmode;
10842 +       __u32 needmode;
10843 +
10844 +       if (unlikely(!(gr_status & GR_READY)))
10845 +               return (GR_CREATE | GR_LINK);
10846 +
10847 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
10848 +       oldmode = obj->mode;
10849 +
10850 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
10851 +               oldmode |= (GR_CREATE | GR_LINK);
10852 +
10853 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
10854 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
10855 +               needmode |= GR_SETID | GR_AUDIT_SETID;
10856 +
10857 +       newmode =
10858 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
10859 +                           oldmode | needmode);
10860 +
10861 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
10862 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
10863 +                             GR_INHERIT | GR_AUDIT_INHERIT);
10864 +
10865 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
10866 +               goto bad;
10867 +
10868 +       if ((oldmode & needmode) != needmode)
10869 +               goto bad;
10870 +
10871 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
10872 +       if ((newmode & needmode) != needmode)
10873 +               goto bad;
10874 +
10875 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
10876 +               return newmode;
10877 +bad:
10878 +       needmode = oldmode;
10879 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
10880 +               needmode |= GR_SETID;
10881 +       
10882 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
10883 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
10884 +               return (GR_CREATE | GR_LINK);
10885 +       } else if (newmode & GR_SUPPRESS)
10886 +               return GR_SUPPRESS;
10887 +       else
10888 +               return 0;
10889 +}
10890 +
10891 +__u32
10892 +gr_search_file(const struct dentry * dentry, const __u32 mode,
10893 +              const struct vfsmount * mnt)
10894 +{
10895 +       __u32 retval = mode;
10896 +       struct acl_subject_label *curracl;
10897 +       struct acl_object_label *currobj;
10898 +
10899 +       if (unlikely(!(gr_status & GR_READY)))
10900 +               return (mode & ~GR_AUDITS);
10901 +
10902 +       curracl = current->acl;
10903 +
10904 +       currobj = chk_obj_label(dentry, mnt, curracl);
10905 +       retval = currobj->mode & mode;
10906 +
10907 +       if (unlikely
10908 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
10909 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
10910 +               __u32 new_mode = mode;
10911 +
10912 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10913 +
10914 +               retval = new_mode;
10915 +
10916 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
10917 +                       new_mode |= GR_INHERIT;
10918 +
10919 +               if (!(mode & GR_NOLEARN))
10920 +                       gr_log_learn(current, dentry, mnt, new_mode);
10921 +       }
10922 +
10923 +       return retval;
10924 +}
10925 +
10926 +__u32
10927 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
10928 +               const struct vfsmount * mnt, const __u32 mode)
10929 +{
10930 +       struct name_entry *match;
10931 +       struct acl_object_label *matchpo;
10932 +       struct acl_subject_label *curracl;
10933 +       char *path;
10934 +       __u32 retval;
10935 +
10936 +       if (unlikely(!(gr_status & GR_READY)))
10937 +               return (mode & ~GR_AUDITS);
10938 +
10939 +       preempt_disable();
10940 +       path = gr_to_filename_rbac(new_dentry, mnt);
10941 +       match = lookup_name_entry(path);
10942 +
10943 +       if (!match)
10944 +               goto check_parent;
10945 +
10946 +       curracl = current->acl;
10947 +
10948 +       read_lock(&gr_inode_lock);
10949 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
10950 +       read_unlock(&gr_inode_lock);
10951 +
10952 +       if (matchpo) {
10953 +               if ((matchpo->mode & mode) !=
10954 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
10955 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
10956 +                       __u32 new_mode = mode;
10957 +
10958 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10959 +
10960 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
10961 +
10962 +                       preempt_enable();
10963 +                       return new_mode;
10964 +               }
10965 +               preempt_enable();
10966 +               return (matchpo->mode & mode);
10967 +       }
10968 +
10969 +      check_parent:
10970 +       curracl = current->acl;
10971 +
10972 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
10973 +       retval = matchpo->mode & mode;
10974 +
10975 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
10976 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
10977 +               __u32 new_mode = mode;
10978 +
10979 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10980 +
10981 +               gr_log_learn(current, new_dentry, mnt, new_mode);
10982 +               preempt_enable();
10983 +               return new_mode;
10984 +       }
10985 +
10986 +       preempt_enable();
10987 +       return retval;
10988 +}
10989 +
10990 +int
10991 +gr_check_hidden_task(const struct task_struct *task)
10992 +{
10993 +       if (unlikely(!(gr_status & GR_READY)))
10994 +               return 0;
10995 +
10996 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
10997 +               return 1;
10998 +
10999 +       return 0;
11000 +}
11001 +
11002 +int
11003 +gr_check_protected_task(const struct task_struct *task)
11004 +{
11005 +       if (unlikely(!(gr_status & GR_READY) || !task))
11006 +               return 0;
11007 +
11008 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
11009 +           task->acl != current->acl)
11010 +               return 1;
11011 +
11012 +       return 0;
11013 +}
11014 +
11015 +void
11016 +gr_copy_label(struct task_struct *tsk)
11017 +{
11018 +       tsk->signal->used_accept = 0;
11019 +       tsk->acl_sp_role = 0;
11020 +       tsk->acl_role_id = current->acl_role_id;
11021 +       tsk->acl = current->acl;
11022 +       tsk->role = current->role;
11023 +       tsk->signal->curr_ip = current->signal->curr_ip;
11024 +       if (current->exec_file)
11025 +               get_file(current->exec_file);
11026 +       tsk->exec_file = current->exec_file;
11027 +       tsk->is_writable = current->is_writable;
11028 +       if (unlikely(current->signal->used_accept))
11029 +               current->signal->curr_ip = 0;
11030 +
11031 +       return;
11032 +}
11033 +
11034 +static void
11035 +gr_set_proc_res(struct task_struct *task)
11036 +{
11037 +       struct acl_subject_label *proc;
11038 +       unsigned short i;
11039 +
11040 +       proc = task->acl;
11041 +
11042 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
11043 +               return;
11044 +
11045 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
11046 +               if (!(proc->resmask & (1 << i)))
11047 +                       continue;
11048 +
11049 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
11050 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
11051 +       }
11052 +
11053 +       return;
11054 +}
11055 +
11056 +int
11057 +gr_check_user_change(int real, int effective, int fs)
11058 +{
11059 +       unsigned int i;
11060 +       __u16 num;
11061 +       uid_t *uidlist;
11062 +       int curuid;
11063 +       int realok = 0;
11064 +       int effectiveok = 0;
11065 +       int fsok = 0;
11066 +
11067 +       if (unlikely(!(gr_status & GR_READY)))
11068 +               return 0;
11069 +
11070 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
11071 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
11072 +
11073 +       num = current->acl->user_trans_num;
11074 +       uidlist = current->acl->user_transitions;
11075 +
11076 +       if (uidlist == NULL)
11077 +               return 0;
11078 +
11079 +       if (real == -1)
11080 +               realok = 1;
11081 +       if (effective == -1)
11082 +               effectiveok = 1;
11083 +       if (fs == -1)
11084 +               fsok = 1;
11085 +
11086 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
11087 +               for (i = 0; i < num; i++) {
11088 +                       curuid = (int)uidlist[i];
11089 +                       if (real == curuid)
11090 +                               realok = 1;
11091 +                       if (effective == curuid)
11092 +                               effectiveok = 1;
11093 +                       if (fs == curuid)
11094 +                               fsok = 1;
11095 +               }
11096 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
11097 +               for (i = 0; i < num; i++) {
11098 +                       curuid = (int)uidlist[i];
11099 +                       if (real == curuid)
11100 +                               break;
11101 +                       if (effective == curuid)
11102 +                               break;
11103 +                       if (fs == curuid)
11104 +                               break;
11105 +               }
11106 +               /* not in deny list */
11107 +               if (i == num) {
11108 +                       realok = 1;
11109 +                       effectiveok = 1;
11110 +                       fsok = 1;
11111 +               }
11112 +       }
11113 +
11114 +       if (realok && effectiveok && fsok)
11115 +               return 0;
11116 +       else {
11117 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
11118 +               return 1;
11119 +       }
11120 +}
11121 +
11122 +int
11123 +gr_check_group_change(int real, int effective, int fs)
11124 +{
11125 +       unsigned int i;
11126 +       __u16 num;
11127 +       gid_t *gidlist;
11128 +       int curgid;
11129 +       int realok = 0;
11130 +       int effectiveok = 0;
11131 +       int fsok = 0;
11132 +
11133 +       if (unlikely(!(gr_status & GR_READY)))
11134 +               return 0;
11135 +
11136 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
11137 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
11138 +
11139 +       num = current->acl->group_trans_num;
11140 +       gidlist = current->acl->group_transitions;
11141 +
11142 +       if (gidlist == NULL)
11143 +               return 0;
11144 +
11145 +       if (real == -1)
11146 +               realok = 1;
11147 +       if (effective == -1)
11148 +               effectiveok = 1;
11149 +       if (fs == -1)
11150 +               fsok = 1;
11151 +
11152 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
11153 +               for (i = 0; i < num; i++) {
11154 +                       curgid = (int)gidlist[i];
11155 +                       if (real == curgid)
11156 +                               realok = 1;
11157 +                       if (effective == curgid)
11158 +                               effectiveok = 1;
11159 +                       if (fs == curgid)
11160 +                               fsok = 1;
11161 +               }
11162 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
11163 +               for (i = 0; i < num; i++) {
11164 +                       curgid = (int)gidlist[i];
11165 +                       if (real == curgid)
11166 +                               break;
11167 +                       if (effective == curgid)
11168 +                               break;
11169 +                       if (fs == curgid)
11170 +                               break;
11171 +               }
11172 +               /* not in deny list */
11173 +               if (i == num) {
11174 +                       realok = 1;
11175 +                       effectiveok = 1;
11176 +                       fsok = 1;
11177 +               }
11178 +       }
11179 +
11180 +       if (realok && effectiveok && fsok)
11181 +               return 0;
11182 +       else {
11183 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
11184 +               return 1;
11185 +       }
11186 +}
11187 +
11188 +void
11189 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
11190 +{
11191 +       struct acl_role_label *role = task->role;
11192 +       struct acl_subject_label *subj = NULL;
11193 +       struct acl_object_label *obj;
11194 +       struct file *filp;
11195 +
11196 +       if (unlikely(!(gr_status & GR_READY)))
11197 +               return;
11198 +
11199 +       filp = task->exec_file;
11200 +
11201 +       /* kernel process, we'll give them the kernel role */
11202 +       if (unlikely(!filp)) {
11203 +               task->role = kernel_role;
11204 +               task->acl = kernel_role->root_label;
11205 +               return;
11206 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
11207 +               role = lookup_acl_role_label(task, uid, gid);
11208 +
11209 +       /* perform subject lookup in possibly new role
11210 +          we can use this result below in the case where role == task->role
11211 +       */
11212 +       subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
11213 +
11214 +       /* if we changed uid/gid, but result in the same role
11215 +          and are using inheritance, don't lose the inherited subject
11216 +          if current subject is other than what normal lookup
11217 +          would result in, we arrived via inheritance, don't
11218 +          lose subject
11219 +       */
11220 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
11221 +                                  (subj == task->acl)))
11222 +               task->acl = subj;
11223 +
11224 +       task->role = role;
11225 +
11226 +       task->is_writable = 0;
11227 +
11228 +       /* ignore additional mmap checks for processes that are writable 
11229 +          by the default ACL */
11230 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
11231 +       if (unlikely(obj->mode & GR_WRITE))
11232 +               task->is_writable = 1;
11233 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
11234 +       if (unlikely(obj->mode & GR_WRITE))
11235 +               task->is_writable = 1;
11236 +
11237 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11238 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
11239 +#endif
11240 +
11241 +       gr_set_proc_res(task);
11242 +
11243 +       return;
11244 +}
11245 +
11246 +int
11247 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
11248 +{
11249 +       struct task_struct *task = current;
11250 +       struct acl_subject_label *newacl;
11251 +       struct acl_object_label *obj;
11252 +       __u32 retmode;
11253 +
11254 +       if (unlikely(!(gr_status & GR_READY)))
11255 +               return 0;
11256 +
11257 +       newacl = chk_subj_label(dentry, mnt, task->role);
11258 +
11259 +       task_lock(task);
11260 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
11261 +            GR_POVERRIDE) && (task->acl != newacl) &&
11262 +            !(task->role->roletype & GR_ROLE_GOD) &&
11263 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
11264 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
11265 +           (atomic_read(&task->fs->count) > 1 ||
11266 +            atomic_read(&task->files->count) > 1 ||
11267 +            atomic_read(&task->sighand->count) > 1)) {
11268 +                task_unlock(task);
11269 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
11270 +               return -EACCES;
11271 +       }
11272 +       task_unlock(task);
11273 +
11274 +       obj = chk_obj_label(dentry, mnt, task->acl);
11275 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
11276 +
11277 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
11278 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
11279 +               if (obj->nested)
11280 +                       task->acl = obj->nested;
11281 +               else
11282 +                       task->acl = newacl;
11283 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
11284 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
11285 +
11286 +       task->is_writable = 0;
11287 +
11288 +       /* ignore additional mmap checks for processes that are writable 
11289 +          by the default ACL */
11290 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
11291 +       if (unlikely(obj->mode & GR_WRITE))
11292 +               task->is_writable = 1;
11293 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
11294 +       if (unlikely(obj->mode & GR_WRITE))
11295 +               task->is_writable = 1;
11296 +
11297 +       gr_set_proc_res(task);
11298 +
11299 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11300 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
11301 +#endif
11302 +       return 0;
11303 +}
11304 +
11305 +static void
11306 +do_handle_delete(const ino_t ino, const dev_t dev)
11307 +{
11308 +       struct acl_object_label *matchpo;
11309 +       struct acl_subject_label *matchps;
11310 +       struct acl_subject_label *subj;
11311 +       struct acl_role_label *role;
11312 +       unsigned int i, x;
11313 +
11314 +       FOR_EACH_ROLE_START(role, i)
11315 +               FOR_EACH_SUBJECT_START(role, subj, x)
11316 +                       if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
11317 +                               matchpo->mode |= GR_DELETED;
11318 +               FOR_EACH_SUBJECT_END(subj,x)
11319 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
11320 +                       if (subj->inode == ino && subj->device == dev)
11321 +                               subj->mode |= GR_DELETED;
11322 +               FOR_EACH_NESTED_SUBJECT_END(subj)
11323 +               if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
11324 +                       matchps->mode |= GR_DELETED;
11325 +       FOR_EACH_ROLE_END(role,i)
11326 +
11327 +       return;
11328 +}
11329 +
11330 +void
11331 +gr_handle_delete(const ino_t ino, const dev_t dev)
11332 +{
11333 +       if (unlikely(!(gr_status & GR_READY)))
11334 +               return;
11335 +
11336 +       write_lock(&gr_inode_lock);
11337 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
11338 +               do_handle_delete(ino, dev);
11339 +       write_unlock(&gr_inode_lock);
11340 +
11341 +       return;
11342 +}
11343 +
11344 +static void
11345 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
11346 +                    const ino_t newinode, const dev_t newdevice,
11347 +                    struct acl_subject_label *subj)
11348 +{
11349 +       unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
11350 +       struct acl_object_label *match;
11351 +
11352 +       match = subj->obj_hash[index];
11353 +
11354 +       while (match && (match->inode != oldinode ||
11355 +              match->device != olddevice ||
11356 +              !(match->mode & GR_DELETED)))
11357 +               match = match->next;
11358 +
11359 +       if (match && (match->inode == oldinode)
11360 +           && (match->device == olddevice)
11361 +           && (match->mode & GR_DELETED)) {
11362 +               if (match->prev == NULL) {
11363 +                       subj->obj_hash[index] = match->next;
11364 +                       if (match->next != NULL)
11365 +                               match->next->prev = NULL;
11366 +               } else {
11367 +                       match->prev->next = match->next;
11368 +                       if (match->next != NULL)
11369 +                               match->next->prev = match->prev;
11370 +               }
11371 +               match->prev = NULL;
11372 +               match->next = NULL;
11373 +               match->inode = newinode;
11374 +               match->device = newdevice;
11375 +               match->mode &= ~GR_DELETED;
11376 +
11377 +               insert_acl_obj_label(match, subj);
11378 +       }
11379 +
11380 +       return;
11381 +}
11382 +
11383 +static void
11384 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
11385 +                     const ino_t newinode, const dev_t newdevice,
11386 +                     struct acl_role_label *role)
11387 +{
11388 +       unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
11389 +       struct acl_subject_label *match;
11390 +
11391 +       match = role->subj_hash[index];
11392 +
11393 +       while (match && (match->inode != oldinode ||
11394 +              match->device != olddevice ||
11395 +              !(match->mode & GR_DELETED)))
11396 +               match = match->next;
11397 +
11398 +       if (match && (match->inode == oldinode)
11399 +           && (match->device == olddevice)
11400 +           && (match->mode & GR_DELETED)) {
11401 +               if (match->prev == NULL) {
11402 +                       role->subj_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->inode = newinode;
11413 +               match->device = newdevice;
11414 +               match->mode &= ~GR_DELETED;
11415 +
11416 +               insert_acl_subj_label(match, role);
11417 +       }
11418 +
11419 +       return;
11420 +}
11421 +
11422 +static void
11423 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
11424 +                   const ino_t newinode, const dev_t newdevice)
11425 +{
11426 +       unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
11427 +       struct inodev_entry *match;
11428 +
11429 +       match = inodev_set.i_hash[index];
11430 +
11431 +       while (match && (match->nentry->inode != oldinode ||
11432 +              match->nentry->device != olddevice))
11433 +               match = match->next;
11434 +
11435 +       if (match && (match->nentry->inode == oldinode)
11436 +           && (match->nentry->device == olddevice)) {
11437 +               if (match->prev == NULL) {
11438 +                       inodev_set.i_hash[index] = match->next;
11439 +                       if (match->next != NULL)
11440 +                               match->next->prev = NULL;
11441 +               } else {
11442 +                       match->prev->next = match->next;
11443 +                       if (match->next != NULL)
11444 +                               match->next->prev = match->prev;
11445 +               }
11446 +               match->prev = NULL;
11447 +               match->next = NULL;
11448 +               match->nentry->inode = newinode;
11449 +               match->nentry->device = newdevice;
11450 +
11451 +               insert_inodev_entry(match);
11452 +       }
11453 +
11454 +       return;
11455 +}
11456 +
11457 +static void
11458 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
11459 +                const struct vfsmount *mnt)
11460 +{
11461 +       struct acl_subject_label *subj;
11462 +       struct acl_role_label *role;
11463 +       unsigned int i, x;
11464 +
11465 +       FOR_EACH_ROLE_START(role, i)
11466 +               update_acl_subj_label(matchn->inode, matchn->device,
11467 +                                     dentry->d_inode->i_ino,
11468 +                                     dentry->d_inode->i_sb->s_dev, role);
11469 +
11470 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
11471 +                       if ((subj->inode == dentry->d_inode->i_ino) &&
11472 +                           (subj->device == dentry->d_inode->i_sb->s_dev)) {
11473 +                               subj->inode = dentry->d_inode->i_ino;
11474 +                               subj->device = dentry->d_inode->i_sb->s_dev;
11475 +                       }
11476 +               FOR_EACH_NESTED_SUBJECT_END(subj)
11477 +               FOR_EACH_SUBJECT_START(role, subj, x)
11478 +                       update_acl_obj_label(matchn->inode, matchn->device,
11479 +                                            dentry->d_inode->i_ino,
11480 +                                            dentry->d_inode->i_sb->s_dev, subj);
11481 +               FOR_EACH_SUBJECT_END(subj,x)
11482 +       FOR_EACH_ROLE_END(role,i)
11483 +
11484 +       update_inodev_entry(matchn->inode, matchn->device,
11485 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
11486 +
11487 +       return;
11488 +}
11489 +
11490 +void
11491 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
11492 +{
11493 +       struct name_entry *matchn;
11494 +
11495 +       if (unlikely(!(gr_status & GR_READY)))
11496 +               return;
11497 +
11498 +       preempt_disable();
11499 +       matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
11500 +
11501 +       if (unlikely((unsigned long)matchn)) {
11502 +               write_lock(&gr_inode_lock);
11503 +               do_handle_create(matchn, dentry, mnt);
11504 +               write_unlock(&gr_inode_lock);
11505 +       }
11506 +       preempt_enable();
11507 +
11508 +       return;
11509 +}
11510 +
11511 +void
11512 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
11513 +                struct dentry *old_dentry,
11514 +                struct dentry *new_dentry,
11515 +                struct vfsmount *mnt, const __u8 replace)
11516 +{
11517 +       struct name_entry *matchn;
11518 +
11519 +       if (unlikely(!(gr_status & GR_READY)))
11520 +               return;
11521 +
11522 +       preempt_disable();
11523 +       matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
11524 +
11525 +       /* we wouldn't have to check d_inode if it weren't for
11526 +          NFS silly-renaming
11527 +        */
11528 +
11529 +       write_lock(&gr_inode_lock);
11530 +       if (unlikely(replace && new_dentry->d_inode)) {
11531 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
11532 +                                       new_dentry->d_inode->i_sb->s_dev) &&
11533 +                   (old_dentry->d_inode->i_nlink <= 1)))
11534 +                       do_handle_delete(new_dentry->d_inode->i_ino,
11535 +                                        new_dentry->d_inode->i_sb->s_dev);
11536 +       }
11537 +
11538 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
11539 +                               old_dentry->d_inode->i_sb->s_dev) &&
11540 +           (old_dentry->d_inode->i_nlink <= 1)))
11541 +               do_handle_delete(old_dentry->d_inode->i_ino,
11542 +                                old_dentry->d_inode->i_sb->s_dev);
11543 +
11544 +       if (unlikely((unsigned long)matchn))
11545 +               do_handle_create(matchn, old_dentry, mnt);
11546 +
11547 +       write_unlock(&gr_inode_lock);
11548 +       preempt_enable();
11549 +
11550 +       return;
11551 +}
11552 +
11553 +static int
11554 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
11555 +                        unsigned char **sum)
11556 +{
11557 +       struct acl_role_label *r;
11558 +       struct role_allowed_ip *ipp;
11559 +       struct role_transition *trans;
11560 +       unsigned int i;
11561 +       int found = 0;
11562 +
11563 +       /* check transition table */
11564 +
11565 +       for (trans = current->role->transitions; trans; trans = trans->next) {
11566 +               if (!strcmp(rolename, trans->rolename)) {
11567 +                       found = 1;
11568 +                       break;
11569 +               }
11570 +       }
11571 +
11572 +       if (!found)
11573 +               return 0;
11574 +
11575 +       /* handle special roles that do not require authentication
11576 +          and check ip */
11577 +
11578 +       FOR_EACH_ROLE_START(r, i)
11579 +               if (!strcmp(rolename, r->rolename) &&
11580 +                   (r->roletype & GR_ROLE_SPECIAL)) {
11581 +                       found = 0;
11582 +                       if (r->allowed_ips != NULL) {
11583 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
11584 +                                       if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
11585 +                                            (ntohl(ipp->addr) & ipp->netmask))
11586 +                                               found = 1;
11587 +                               }
11588 +                       } else
11589 +                               found = 2;
11590 +                       if (!found)
11591 +                               return 0;
11592 +
11593 +                       if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
11594 +                           ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
11595 +                               *salt = NULL;
11596 +                               *sum = NULL;
11597 +                               return 1;
11598 +                       }
11599 +               }
11600 +       FOR_EACH_ROLE_END(r,i)
11601 +
11602 +       for (i = 0; i < num_sprole_pws; i++) {
11603 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
11604 +                       *salt = acl_special_roles[i]->salt;
11605 +                       *sum = acl_special_roles[i]->sum;
11606 +                       return 1;
11607 +               }
11608 +       }
11609 +
11610 +       return 0;
11611 +}
11612 +
11613 +static void
11614 +assign_special_role(char *rolename)
11615 +{
11616 +       struct acl_object_label *obj;
11617 +       struct acl_role_label *r;
11618 +       struct acl_role_label *assigned = NULL;
11619 +       struct task_struct *tsk;
11620 +       struct file *filp;
11621 +       unsigned int i;
11622 +
11623 +       FOR_EACH_ROLE_START(r, i)
11624 +               if (!strcmp(rolename, r->rolename) &&
11625 +                   (r->roletype & GR_ROLE_SPECIAL))
11626 +                       assigned = r;
11627 +       FOR_EACH_ROLE_END(r,i)
11628 +
11629 +       if (!assigned)
11630 +               return;
11631 +
11632 +       read_lock(&tasklist_lock);
11633 +       read_lock(&grsec_exec_file_lock);
11634 +
11635 +       tsk = current->parent;
11636 +       if (tsk == NULL)
11637 +               goto out_unlock;
11638 +
11639 +       filp = tsk->exec_file;
11640 +       if (filp == NULL)
11641 +               goto out_unlock;
11642 +
11643 +       tsk->is_writable = 0;
11644 +
11645 +       tsk->acl_sp_role = 1;
11646 +       tsk->acl_role_id = ++acl_sp_role_value;
11647 +       tsk->role = assigned;
11648 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
11649 +
11650 +       /* ignore additional mmap checks for processes that are writable 
11651 +          by the default ACL */
11652 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
11653 +       if (unlikely(obj->mode & GR_WRITE))
11654 +               tsk->is_writable = 1;
11655 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
11656 +       if (unlikely(obj->mode & GR_WRITE))
11657 +               tsk->is_writable = 1;
11658 +
11659 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
11660 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
11661 +#endif
11662 +
11663 +out_unlock:
11664 +       read_unlock(&grsec_exec_file_lock);
11665 +       read_unlock(&tasklist_lock);
11666 +       return;
11667 +}
11668 +
11669 +int gr_check_secure_terminal(struct task_struct *task)
11670 +{
11671 +       struct task_struct *p, *p2, *p3;
11672 +       struct files_struct *files;
11673 +       struct fdtable *fdt;
11674 +       struct file *our_file = NULL, *file;
11675 +       int i;
11676 +
11677 +       if (task->signal->tty == NULL)
11678 +               return 1;
11679 +
11680 +       files = get_files_struct(task);
11681 +       if (files != NULL) {
11682 +               rcu_read_lock();
11683 +               fdt = files_fdtable(files);
11684 +               for (i=0; i < fdt->max_fds; i++) {
11685 +                       file = fcheck_files(files, i);
11686 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
11687 +                               get_file(file);
11688 +                               our_file = file;
11689 +                       }
11690 +               }
11691 +               rcu_read_unlock();
11692 +               put_files_struct(files);
11693 +       }
11694 +
11695 +       if (our_file == NULL)
11696 +               return 1;
11697 +
11698 +       read_lock(&tasklist_lock);
11699 +       do_each_thread(p2, p) {
11700 +               files = get_files_struct(p);
11701 +               if (files == NULL ||
11702 +                   (p->signal && p->signal->tty == task->signal->tty)) {
11703 +                       if (files != NULL)
11704 +                               put_files_struct(files);
11705 +                       continue;
11706 +               }
11707 +               rcu_read_lock();
11708 +               fdt = files_fdtable(files);
11709 +               for (i=0; i < fdt->max_fds; i++) {
11710 +                       file = fcheck_files(files, i);
11711 +                       if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
11712 +                           file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
11713 +                               p3 = task;
11714 +                               while (p3->pid > 0) {
11715 +                                       if (p3 == p)
11716 +                                               break;
11717 +                                       p3 = p3->parent;
11718 +                               }
11719 +                               if (p3 == p)
11720 +                                       break;
11721 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
11722 +                               gr_handle_alertkill(p);
11723 +                               rcu_read_unlock();
11724 +                               put_files_struct(files);
11725 +                               read_unlock(&tasklist_lock);
11726 +                               fput(our_file);
11727 +                               return 0;
11728 +                       }
11729 +               }
11730 +               rcu_read_unlock();
11731 +               put_files_struct(files);
11732 +       } while_each_thread(p2, p);
11733 +       read_unlock(&tasklist_lock);
11734 +
11735 +       fput(our_file);
11736 +       return 1;
11737 +}
11738 +
11739 +ssize_t
11740 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
11741 +{
11742 +       struct gr_arg_wrapper uwrap;
11743 +       unsigned char *sprole_salt;
11744 +       unsigned char *sprole_sum;
11745 +       int error = sizeof (struct gr_arg_wrapper);
11746 +       int error2 = 0;
11747 +
11748 +       down(&gr_dev_sem);
11749 +
11750 +       if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
11751 +               error = -EPERM;
11752 +               goto out;
11753 +       }
11754 +
11755 +       if (count != sizeof (struct gr_arg_wrapper)) {
11756 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
11757 +               error = -EINVAL;
11758 +               goto out;
11759 +       }
11760 +
11761 +       
11762 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
11763 +               gr_auth_expires = 0;
11764 +               gr_auth_attempts = 0;
11765 +       }
11766 +
11767 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
11768 +               error = -EFAULT;
11769 +               goto out;
11770 +       }
11771 +
11772 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
11773 +               error = -EINVAL;
11774 +               goto out;
11775 +       }
11776 +
11777 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
11778 +               error = -EFAULT;
11779 +               goto out;
11780 +       }
11781 +
11782 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
11783 +           gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
11784 +           time_after(gr_auth_expires, get_seconds())) {
11785 +               error = -EBUSY;
11786 +               goto out;
11787 +       }
11788 +
11789 +       /* if non-root trying to do anything other than use a special role,
11790 +          do not attempt authentication, do not count towards authentication
11791 +          locking
11792 +        */
11793 +
11794 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
11795 +           gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
11796 +           current->uid) {
11797 +               error = -EPERM;
11798 +               goto out;
11799 +       }
11800 +
11801 +       /* ensure pw and special role name are null terminated */
11802 +
11803 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
11804 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
11805 +
11806 +       /* Okay. 
11807 +        * We have our enough of the argument structure..(we have yet
11808 +        * to copy_from_user the tables themselves) . Copy the tables
11809 +        * only if we need them, i.e. for loading operations. */
11810 +
11811 +       switch (gr_usermode->mode) {
11812 +       case STATUS:
11813 +                       if (gr_status & GR_READY) {
11814 +                               error = 1;
11815 +                               if (!gr_check_secure_terminal(current))
11816 +                                       error = 3;
11817 +                       } else
11818 +                               error = 2;
11819 +                       goto out;
11820 +       case SHUTDOWN:
11821 +               if ((gr_status & GR_READY)
11822 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11823 +                       gr_status &= ~GR_READY;
11824 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
11825 +                       free_variables();
11826 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
11827 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
11828 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
11829 +               } else if (gr_status & GR_READY) {
11830 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
11831 +                       error = -EPERM;
11832 +               } else {
11833 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
11834 +                       error = -EAGAIN;
11835 +               }
11836 +               break;
11837 +       case ENABLE:
11838 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
11839 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
11840 +               else {
11841 +                       if (gr_status & GR_READY)
11842 +                               error = -EAGAIN;
11843 +                       else
11844 +                               error = error2;
11845 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
11846 +               }
11847 +               break;
11848 +       case RELOAD:
11849 +               if (!(gr_status & GR_READY)) {
11850 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
11851 +                       error = -EAGAIN;
11852 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11853 +                       lock_kernel();
11854 +                       gr_status &= ~GR_READY;
11855 +                       free_variables();
11856 +                       if (!(error2 = gracl_init(gr_usermode))) {
11857 +                               unlock_kernel();
11858 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
11859 +                       } else {
11860 +                               unlock_kernel();
11861 +                               error = error2;
11862 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
11863 +                       }
11864 +               } else {
11865 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
11866 +                       error = -EPERM;
11867 +               }
11868 +               break;
11869 +       case SEGVMOD:
11870 +               if (unlikely(!(gr_status & GR_READY))) {
11871 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
11872 +                       error = -EAGAIN;
11873 +                       break;
11874 +               }
11875 +
11876 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
11877 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
11878 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
11879 +                               struct acl_subject_label *segvacl;
11880 +                               segvacl =
11881 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
11882 +                                                         gr_usermode->segv_device,
11883 +                                                         current->role);
11884 +                               if (segvacl) {
11885 +                                       segvacl->crashes = 0;
11886 +                                       segvacl->expires = 0;
11887 +                               }
11888 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
11889 +                               gr_remove_uid(gr_usermode->segv_uid);
11890 +                       }
11891 +               } else {
11892 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
11893 +                       error = -EPERM;
11894 +               }
11895 +               break;
11896 +       case SPROLE:
11897 +       case SPROLEPAM:
11898 +               if (unlikely(!(gr_status & GR_READY))) {
11899 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
11900 +                       error = -EAGAIN;
11901 +                       break;
11902 +               }
11903 +
11904 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
11905 +                       current->role->expires = 0;
11906 +                       current->role->auth_attempts = 0;
11907 +               }
11908 +
11909 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
11910 +                   time_after(current->role->expires, get_seconds())) {
11911 +                       error = -EBUSY;
11912 +                       goto out;
11913 +               }
11914 +
11915 +               if (lookup_special_role_auth
11916 +                   (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
11917 +                   && ((!sprole_salt && !sprole_sum)
11918 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
11919 +                       char *p = "";
11920 +                       assign_special_role(gr_usermode->sp_role);
11921 +                       read_lock(&tasklist_lock);
11922 +                       if (current->parent)
11923 +                               p = current->parent->role->rolename;
11924 +                       read_unlock(&tasklist_lock);
11925 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
11926 +                                       p, acl_sp_role_value);
11927 +               } else {
11928 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
11929 +                       error = -EPERM;
11930 +                       if(!(current->role->auth_attempts++))
11931 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
11932 +
11933 +                       goto out;
11934 +               }
11935 +               break;
11936 +       case UNSPROLE:
11937 +               if (unlikely(!(gr_status & GR_READY))) {
11938 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
11939 +                       error = -EAGAIN;
11940 +                       break;
11941 +               }
11942 +
11943 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
11944 +                       char *p = "";
11945 +                       int i = 0;
11946 +
11947 +                       read_lock(&tasklist_lock);
11948 +                       if (current->parent) {
11949 +                               p = current->parent->role->rolename;
11950 +                               i = current->parent->acl_role_id;
11951 +                       }
11952 +                       read_unlock(&tasklist_lock);
11953 +
11954 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
11955 +                       gr_set_acls(1);
11956 +               } else {
11957 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
11958 +                       error = -EPERM;
11959 +                       goto out;
11960 +               }
11961 +               break;
11962 +       default:
11963 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
11964 +               error = -EINVAL;
11965 +               break;
11966 +       }
11967 +
11968 +       if (error != -EPERM)
11969 +               goto out;
11970 +
11971 +       if(!(gr_auth_attempts++))
11972 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
11973 +
11974 +      out:
11975 +       up(&gr_dev_sem);
11976 +       return error;
11977 +}
11978 +
11979 +int
11980 +gr_set_acls(const int type)
11981 +{
11982 +       struct acl_object_label *obj;
11983 +       struct task_struct *task, *task2;
11984 +       struct file *filp;
11985 +       struct acl_role_label *role = current->role;
11986 +       __u16 acl_role_id = current->acl_role_id;
11987 +
11988 +       read_lock(&tasklist_lock);
11989 +       read_lock(&grsec_exec_file_lock);
11990 +       do_each_thread(task2, task) {
11991 +               /* check to see if we're called from the exit handler,
11992 +                  if so, only replace ACLs that have inherited the admin
11993 +                  ACL */
11994 +
11995 +               if (type && (task->role != role ||
11996 +                            task->acl_role_id != acl_role_id))
11997 +                       continue;
11998 +
11999 +               task->acl_role_id = 0;
12000 +               task->acl_sp_role = 0;
12001 +
12002 +               if ((filp = task->exec_file)) {
12003 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
12004 +
12005 +                       task->acl =
12006 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
12007 +                                          task->role);
12008 +                       if (task->acl) {
12009 +                               struct acl_subject_label *curr;
12010 +                               curr = task->acl;
12011 +
12012 +                               task->is_writable = 0;
12013 +                               /* ignore additional mmap checks for processes that are writable 
12014 +                                  by the default ACL */
12015 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
12016 +                               if (unlikely(obj->mode & GR_WRITE))
12017 +                                       task->is_writable = 1;
12018 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
12019 +                               if (unlikely(obj->mode & GR_WRITE))
12020 +                                       task->is_writable = 1;
12021 +
12022 +                               gr_set_proc_res(task);
12023 +
12024 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
12025 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
12026 +#endif
12027 +                       } else {
12028 +                               read_unlock(&grsec_exec_file_lock);
12029 +                               read_unlock(&tasklist_lock);
12030 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
12031 +                               return 1;
12032 +                       }
12033 +               } else {
12034 +                       // it's a kernel process
12035 +                       task->role = kernel_role;
12036 +                       task->acl = kernel_role->root_label;
12037 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
12038 +                       task->acl->mode &= ~GR_PROCFIND;
12039 +#endif
12040 +               }
12041 +       } while_each_thread(task2, task);
12042 +       read_unlock(&grsec_exec_file_lock);
12043 +       read_unlock(&tasklist_lock);
12044 +       return 0;
12045 +}
12046 +
12047 +void
12048 +gr_learn_resource(const struct task_struct *task,
12049 +                 const int res, const unsigned long wanted, const int gt)
12050 +{
12051 +       struct acl_subject_label *acl;
12052 +
12053 +       if (unlikely((gr_status & GR_READY) &&
12054 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
12055 +               goto skip_reslog;
12056 +
12057 +#ifdef CONFIG_GRKERNSEC_RESLOG
12058 +       gr_log_resource(task, res, wanted, gt);
12059 +#endif
12060 +      skip_reslog:
12061 +
12062 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
12063 +               return;
12064 +
12065 +       acl = task->acl;
12066 +
12067 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
12068 +                  !(acl->resmask & (1 << (unsigned short) res))))
12069 +               return;
12070 +
12071 +       if (wanted >= acl->res[res].rlim_cur) {
12072 +               unsigned long res_add;
12073 +
12074 +               res_add = wanted;
12075 +               switch (res) {
12076 +               case RLIMIT_CPU:
12077 +                       res_add += GR_RLIM_CPU_BUMP;
12078 +                       break;
12079 +               case RLIMIT_FSIZE:
12080 +                       res_add += GR_RLIM_FSIZE_BUMP;
12081 +                       break;
12082 +               case RLIMIT_DATA:
12083 +                       res_add += GR_RLIM_DATA_BUMP;
12084 +                       break;
12085 +               case RLIMIT_STACK:
12086 +                       res_add += GR_RLIM_STACK_BUMP;
12087 +                       break;
12088 +               case RLIMIT_CORE:
12089 +                       res_add += GR_RLIM_CORE_BUMP;
12090 +                       break;
12091 +               case RLIMIT_RSS:
12092 +                       res_add += GR_RLIM_RSS_BUMP;
12093 +                       break;
12094 +               case RLIMIT_NPROC:
12095 +                       res_add += GR_RLIM_NPROC_BUMP;
12096 +                       break;
12097 +               case RLIMIT_NOFILE:
12098 +                       res_add += GR_RLIM_NOFILE_BUMP;
12099 +                       break;
12100 +               case RLIMIT_MEMLOCK:
12101 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
12102 +                       break;
12103 +               case RLIMIT_AS:
12104 +                       res_add += GR_RLIM_AS_BUMP;
12105 +                       break;
12106 +               case RLIMIT_LOCKS:
12107 +                       res_add += GR_RLIM_LOCKS_BUMP;
12108 +                       break;
12109 +               }
12110 +
12111 +               acl->res[res].rlim_cur = res_add;
12112 +
12113 +               if (wanted > acl->res[res].rlim_max)
12114 +                       acl->res[res].rlim_max = res_add;
12115 +
12116 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
12117 +                              task->role->roletype, acl->filename,
12118 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
12119 +                              "", (unsigned long) res);
12120 +       }
12121 +
12122 +       return;
12123 +}
12124 +
12125 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
12126 +void
12127 +pax_set_initial_flags(struct linux_binprm *bprm)
12128 +{
12129 +       struct task_struct *task = current;
12130 +        struct acl_subject_label *proc;
12131 +       unsigned long flags;
12132 +
12133 +        if (unlikely(!(gr_status & GR_READY)))
12134 +                return;
12135 +
12136 +       flags = pax_get_flags(task);
12137 +
12138 +        proc = task->acl;
12139 +
12140 +       if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
12141 +               flags &= ~MF_PAX_PAGEEXEC;
12142 +       if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
12143 +               flags &= ~MF_PAX_SEGMEXEC;
12144 +       if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
12145 +               flags &= ~MF_PAX_RANDMMAP;
12146 +       if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
12147 +               flags &= ~MF_PAX_EMUTRAMP;
12148 +       if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
12149 +               flags &= ~MF_PAX_MPROTECT;
12150 +
12151 +       if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
12152 +               flags |= MF_PAX_PAGEEXEC;
12153 +       if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
12154 +               flags |= MF_PAX_SEGMEXEC;
12155 +       if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
12156 +               flags |= MF_PAX_RANDMMAP;
12157 +       if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
12158 +               flags |= MF_PAX_EMUTRAMP;
12159 +       if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
12160 +               flags |= MF_PAX_MPROTECT;
12161 +
12162 +       pax_set_flags(task, flags);
12163 +
12164 +        return;
12165 +}
12166 +#endif
12167 +
12168 +#ifdef CONFIG_SYSCTL
12169 +extern struct proc_dir_entry *proc_sys_root;
12170 +
12171 +/* the following function is called under the BKL */
12172 +
12173 +__u32
12174 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
12175 +                const void *newval)
12176 +{
12177 +       struct proc_dir_entry *tmp;
12178 +       struct nameidata nd;
12179 +       const char *proc_sys = "/proc/sys";
12180 +       char *path;
12181 +       struct acl_object_label *obj;
12182 +       unsigned short len = 0, pos = 0, depth = 0, i;
12183 +       __u32 err = 0;
12184 +       __u32 mode = 0;
12185 +
12186 +       if (unlikely(!(gr_status & GR_READY)))
12187 +               return 1;
12188 +
12189 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
12190 +
12191 +       if (oldval)
12192 +               mode |= GR_READ;
12193 +       if (newval)
12194 +               mode |= GR_WRITE;
12195 +
12196 +       /* convert the requested sysctl entry into a pathname */
12197 +
12198 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
12199 +               len += strlen(tmp->name);
12200 +               len++;
12201 +               depth++;
12202 +       }
12203 +
12204 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
12205 +               return 0;       /* deny */
12206 +
12207 +       memset(path, 0, PAGE_SIZE);
12208 +
12209 +       memcpy(path, proc_sys, strlen(proc_sys));
12210 +
12211 +       pos += strlen(proc_sys);
12212 +
12213 +       for (; depth > 0; depth--) {
12214 +               path[pos] = '/';
12215 +               pos++;
12216 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
12217 +                    tmp = tmp->parent) {
12218 +                       if (depth == i) {
12219 +                               memcpy(path + pos, tmp->name,
12220 +                                      strlen(tmp->name));
12221 +                               pos += strlen(tmp->name);
12222 +                       }
12223 +                       i++;
12224 +               }
12225 +       }
12226 +
12227 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
12228 +
12229 +       if (err)
12230 +               goto out;
12231 +
12232 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
12233 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
12234 +
12235 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
12236 +                    ((err & mode) != mode))) {
12237 +               __u32 new_mode = mode;
12238 +
12239 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
12240 +
12241 +               err = new_mode;
12242 +               gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
12243 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
12244 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
12245 +                              path, (mode & GR_READ) ? " reading" : "",
12246 +                              (mode & GR_WRITE) ? " writing" : "");
12247 +               err = 0;
12248 +       } else if ((err & mode) != mode) {
12249 +               err = 0;
12250 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
12251 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
12252 +                              path, (mode & GR_READ) ? " reading" : "",
12253 +                              (mode & GR_WRITE) ? " writing" : "");
12254 +       }
12255 +
12256 +       path_release(&nd);
12257 +
12258 +      out:
12259 +       return err;
12260 +}
12261 +#endif
12262 +
12263 +int
12264 +gr_handle_proc_ptrace(struct task_struct *task)
12265 +{
12266 +       struct file *filp;
12267 +       struct task_struct *tmp = task;
12268 +       struct task_struct *curtemp = current;
12269 +       __u32 retmode;
12270 +
12271 +       if (unlikely(!(gr_status & GR_READY)))
12272 +               return 0;
12273 +
12274 +       read_lock(&tasklist_lock);
12275 +       read_lock(&grsec_exec_file_lock);
12276 +       filp = task->exec_file;
12277 +
12278 +       while (tmp->pid > 0) {
12279 +               if (tmp == curtemp)
12280 +                       break;
12281 +               tmp = tmp->parent;
12282 +       }
12283 +
12284 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
12285 +               read_unlock(&grsec_exec_file_lock);
12286 +               read_unlock(&tasklist_lock);
12287 +               return 1;
12288 +       }
12289 +
12290 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
12291 +       read_unlock(&grsec_exec_file_lock);
12292 +       read_unlock(&tasklist_lock);
12293 +
12294 +       if (retmode & GR_NOPTRACE)
12295 +               return 1;
12296 +
12297 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
12298 +           && (current->acl != task->acl || (current->acl != current->role->root_label
12299 +           && current->pid != task->pid)))
12300 +               return 1;
12301 +
12302 +       return 0;
12303 +}
12304 +
12305 +int
12306 +gr_handle_ptrace(struct task_struct *task, const long request)
12307 +{
12308 +       struct task_struct *tmp = task;
12309 +       struct task_struct *curtemp = current;
12310 +       __u32 retmode;
12311 +
12312 +       if (unlikely(!(gr_status & GR_READY)))
12313 +               return 0;
12314 +
12315 +       read_lock(&tasklist_lock);
12316 +       while (tmp->pid > 0) {
12317 +               if (tmp == curtemp)
12318 +                       break;
12319 +               tmp = tmp->parent;
12320 +       }
12321 +
12322 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
12323 +               read_unlock(&tasklist_lock);
12324 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12325 +               return 1;
12326 +       }
12327 +       read_unlock(&tasklist_lock);
12328 +
12329 +       read_lock(&grsec_exec_file_lock);
12330 +       if (unlikely(!task->exec_file)) {
12331 +               read_unlock(&grsec_exec_file_lock);
12332 +               return 0;
12333 +       }
12334 +
12335 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
12336 +       read_unlock(&grsec_exec_file_lock);
12337 +
12338 +       if (retmode & GR_NOPTRACE) {
12339 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12340 +               return 1;
12341 +       }
12342 +               
12343 +       if (retmode & GR_PTRACERD) {
12344 +               switch (request) {
12345 +               case PTRACE_POKETEXT:
12346 +               case PTRACE_POKEDATA:
12347 +               case PTRACE_POKEUSR:
12348 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
12349 +               case PTRACE_SETREGS:
12350 +               case PTRACE_SETFPREGS:
12351 +#endif
12352 +#ifdef CONFIG_X86
12353 +               case PTRACE_SETFPXREGS:
12354 +#endif
12355 +#ifdef CONFIG_ALTIVEC
12356 +               case PTRACE_SETVRREGS:
12357 +#endif
12358 +                       return 1;
12359 +               default:
12360 +                       return 0;
12361 +               }
12362 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
12363 +                  !(current->role->roletype & GR_ROLE_GOD) &&
12364 +                  (current->acl != task->acl)) {
12365 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
12366 +               return 1;
12367 +       }
12368 +
12369 +       return 0;
12370 +}
12371 +
12372 +static int is_writable_mmap(const struct file *filp)
12373 +{
12374 +       struct task_struct *task = current;
12375 +       struct acl_object_label *obj, *obj2;
12376 +
12377 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
12378 +           !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
12379 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
12380 +               obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
12381 +                                    task->role->root_label);
12382 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
12383 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
12384 +                       return 1;
12385 +               }
12386 +       }
12387 +       return 0;
12388 +}
12389 +
12390 +int
12391 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
12392 +{
12393 +       __u32 mode;
12394 +
12395 +       if (unlikely(!file || !(prot & PROT_EXEC)))
12396 +               return 1;
12397 +
12398 +       if (is_writable_mmap(file))
12399 +               return 0;
12400 +
12401 +       mode =
12402 +           gr_search_file(file->f_dentry,
12403 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
12404 +                          file->f_vfsmnt);
12405 +
12406 +       if (!gr_tpe_allow(file))
12407 +               return 0;
12408 +
12409 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
12410 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12411 +               return 0;
12412 +       } else if (unlikely(!(mode & GR_EXEC))) {
12413 +               return 0;
12414 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
12415 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12416 +               return 1;
12417 +       }
12418 +
12419 +       return 1;
12420 +}
12421 +
12422 +int
12423 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
12424 +{
12425 +       __u32 mode;
12426 +
12427 +       if (unlikely(!file || !(prot & PROT_EXEC)))
12428 +               return 1;
12429 +
12430 +       if (is_writable_mmap(file))
12431 +               return 0;
12432 +
12433 +       mode =
12434 +           gr_search_file(file->f_dentry,
12435 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
12436 +                          file->f_vfsmnt);
12437 +
12438 +       if (!gr_tpe_allow(file))
12439 +               return 0;
12440 +
12441 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
12442 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12443 +               return 0;
12444 +       } else if (unlikely(!(mode & GR_EXEC))) {
12445 +               return 0;
12446 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
12447 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
12448 +               return 1;
12449 +       }
12450 +
12451 +       return 1;
12452 +}
12453 +
12454 +void
12455 +gr_acl_handle_psacct(struct task_struct *task, const long code)
12456 +{
12457 +       unsigned long runtime;
12458 +       unsigned long cputime;
12459 +       unsigned int wday, cday;
12460 +       __u8 whr, chr;
12461 +       __u8 wmin, cmin;
12462 +       __u8 wsec, csec;
12463 +
12464 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
12465 +                    !(task->acl->mode & GR_PROCACCT)))
12466 +               return;
12467 +
12468 +       runtime = xtime.tv_sec - task->start_time.tv_sec;
12469 +       wday = runtime / (3600 * 24);
12470 +       runtime -= wday * (3600 * 24);
12471 +       whr = runtime / 3600;
12472 +       runtime -= whr * 3600;
12473 +       wmin = runtime / 60;
12474 +       runtime -= wmin * 60;
12475 +       wsec = runtime;
12476 +
12477 +       cputime = (task->utime + task->stime) / HZ;
12478 +       cday = cputime / (3600 * 24);
12479 +       cputime -= cday * (3600 * 24);
12480 +       chr = cputime / 3600;
12481 +       cputime -= chr * 3600;
12482 +       cmin = cputime / 60;
12483 +       cputime -= cmin * 60;
12484 +       csec = cputime;
12485 +
12486 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
12487 +
12488 +       return;
12489 +}
12490 +
12491 +void gr_set_kernel_label(struct task_struct *task)
12492 +{
12493 +       if (gr_status & GR_READY) {
12494 +               task->role = kernel_role;
12495 +               task->acl = kernel_role->root_label;
12496 +       }
12497 +       return;
12498 +}
12499 +
12500 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
12501 +{
12502 +       struct task_struct *task = current;
12503 +       struct dentry *dentry = file->f_dentry;
12504 +       struct vfsmount *mnt = file->f_vfsmnt;
12505 +       struct acl_object_label *obj, *tmp;
12506 +       struct acl_subject_label *subj;
12507 +       unsigned int bufsize;
12508 +       int is_not_root;
12509 +       char *path;
12510 +
12511 +       if (unlikely(!(gr_status & GR_READY)))
12512 +               return 1;
12513 +
12514 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
12515 +               return 1;
12516 +
12517 +       subj = task->acl;
12518 +       do {
12519 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
12520 +               if (obj != NULL)
12521 +                       return (obj->mode & GR_FIND) ? 1 : 0;
12522 +       } while ((subj = subj->parent_subject));
12523 +       
12524 +       obj = chk_obj_label(dentry, mnt, task->acl);
12525 +       if (obj->globbed == NULL)
12526 +               return (obj->mode & GR_FIND) ? 1 : 0;
12527 +
12528 +       is_not_root = ((obj->filename[0] == '/') &&
12529 +                  (obj->filename[1] == '\0')) ? 0 : 1;
12530 +       bufsize = PAGE_SIZE - namelen - is_not_root;
12531 +
12532 +       /* check bufsize > PAGE_SIZE || bufsize == 0 */
12533 +       if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
12534 +               return 1;
12535 +
12536 +       preempt_disable();
12537 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
12538 +                          bufsize);
12539 +
12540 +       bufsize = strlen(path);
12541 +
12542 +       /* if base is "/", don't append an additional slash */
12543 +       if (is_not_root)
12544 +               *(path + bufsize) = '/';
12545 +       memcpy(path + bufsize + is_not_root, name, namelen);
12546 +       *(path + bufsize + namelen + is_not_root) = '\0';
12547 +
12548 +       tmp = obj->globbed;
12549 +       while (tmp) {
12550 +               if (!glob_match(tmp->filename, path)) {
12551 +                       preempt_enable();
12552 +                       return (tmp->mode & GR_FIND) ? 1 : 0;
12553 +               }
12554 +               tmp = tmp->next;
12555 +       }
12556 +       preempt_enable();
12557 +       return (obj->mode & GR_FIND) ? 1 : 0;
12558 +}
12559 +
12560 +EXPORT_SYMBOL(gr_learn_resource);
12561 +EXPORT_SYMBOL(gr_set_kernel_label);
12562 +#ifdef CONFIG_SECURITY
12563 +EXPORT_SYMBOL(gr_check_user_change);
12564 +EXPORT_SYMBOL(gr_check_group_change);
12565 +#endif
12566 +
12567 diff -urNp linux-2.6.16.2/grsecurity/gracl_cap.c linux-2.6.16.2/grsecurity/gracl_cap.c
12568 --- linux-2.6.16.2/grsecurity/gracl_cap.c       1969-12-31 19:00:00.000000000 -0500
12569 +++ linux-2.6.16.2/grsecurity/gracl_cap.c       2006-04-09 21:23:54.000000000 -0400
12570 @@ -0,0 +1,110 @@
12571 +#include <linux/kernel.h>
12572 +#include <linux/module.h>
12573 +#include <linux/sched.h>
12574 +#include <linux/capability.h>
12575 +#include <linux/gracl.h>
12576 +#include <linux/grsecurity.h>
12577 +#include <linux/grinternal.h>
12578 +
12579 +static const char *captab_log[] = {
12580 +       "CAP_CHOWN",
12581 +       "CAP_DAC_OVERRIDE",
12582 +       "CAP_DAC_READ_SEARCH",
12583 +       "CAP_FOWNER",
12584 +       "CAP_FSETID",
12585 +       "CAP_KILL",
12586 +       "CAP_SETGID",
12587 +       "CAP_SETUID",
12588 +       "CAP_SETPCAP",
12589 +       "CAP_LINUX_IMMUTABLE",
12590 +       "CAP_NET_BIND_SERVICE",
12591 +       "CAP_NET_BROADCAST",
12592 +       "CAP_NET_ADMIN",
12593 +       "CAP_NET_RAW",
12594 +       "CAP_IPC_LOCK",
12595 +       "CAP_IPC_OWNER",
12596 +       "CAP_SYS_MODULE",
12597 +       "CAP_SYS_RAWIO",
12598 +       "CAP_SYS_CHROOT",
12599 +       "CAP_SYS_PTRACE",
12600 +       "CAP_SYS_PACCT",
12601 +       "CAP_SYS_ADMIN",
12602 +       "CAP_SYS_BOOT",
12603 +       "CAP_SYS_NICE",
12604 +       "CAP_SYS_RESOURCE",
12605 +       "CAP_SYS_TIME",
12606 +       "CAP_SYS_TTY_CONFIG",
12607 +       "CAP_MKNOD",
12608 +       "CAP_LEASE"
12609 +};
12610 +
12611 +EXPORT_SYMBOL(gr_task_is_capable);
12612 +
12613 +int
12614 +gr_task_is_capable(struct task_struct *task, const int cap)
12615 +{
12616 +       struct acl_subject_label *curracl;
12617 +       __u32 cap_drop = 0, cap_mask = 0;
12618 +
12619 +       if (!gr_acl_is_enabled())
12620 +               return 1;
12621 +
12622 +       curracl = task->acl;
12623 +
12624 +       cap_drop = curracl->cap_lower;
12625 +       cap_mask = curracl->cap_mask;
12626 +
12627 +       while ((curracl = curracl->parent_subject)) {
12628 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
12629 +                       cap_drop |= curracl->cap_lower & (1 << cap);
12630 +               cap_mask |= curracl->cap_mask;
12631 +       }
12632 +
12633 +       if (!cap_raised(cap_drop, cap))
12634 +               return 1;
12635 +
12636 +       curracl = task->acl;
12637 +
12638 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
12639 +           && cap_raised(task->cap_effective, cap)) {
12640 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
12641 +                              task->role->roletype, task->uid,
12642 +                              task->gid, task->exec_file ?
12643 +                              gr_to_filename(task->exec_file->f_dentry,
12644 +                              task->exec_file->f_vfsmnt) : curracl->filename,
12645 +                              curracl->filename, 0UL,
12646 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
12647 +               return 1;
12648 +       }
12649 +
12650 +       if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
12651 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
12652 +
12653 +       return 0;
12654 +}
12655 +
12656 +int
12657 +gr_is_capable_nolog(const int cap)
12658 +{
12659 +       struct acl_subject_label *curracl;
12660 +       __u32 cap_drop = 0, cap_mask = 0;
12661 +
12662 +       if (!gr_acl_is_enabled())
12663 +               return 1;
12664 +
12665 +       curracl = current->acl;
12666 +
12667 +       cap_drop = curracl->cap_lower;
12668 +       cap_mask = curracl->cap_mask;
12669 +
12670 +       while ((curracl = curracl->parent_subject)) {
12671 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
12672 +               cap_mask |= curracl->cap_mask;
12673 +       }
12674 +
12675 +       if (!cap_raised(cap_drop, cap))
12676 +               return 1;
12677 +
12678 +       return 0;
12679 +}
12680 +
12681 diff -urNp linux-2.6.16.2/grsecurity/gracl_fs.c linux-2.6.16.2/grsecurity/gracl_fs.c
12682 --- linux-2.6.16.2/grsecurity/gracl_fs.c        1969-12-31 19:00:00.000000000 -0500
12683 +++ linux-2.6.16.2/grsecurity/gracl_fs.c        2006-04-09 21:23:54.000000000 -0400
12684 @@ -0,0 +1,423 @@
12685 +#include <linux/kernel.h>
12686 +#include <linux/sched.h>
12687 +#include <linux/types.h>
12688 +#include <linux/fs.h>
12689 +#include <linux/file.h>
12690 +#include <linux/stat.h>
12691 +#include <linux/grsecurity.h>
12692 +#include <linux/grinternal.h>
12693 +#include <linux/gracl.h>
12694 +
12695 +__u32
12696 +gr_acl_handle_hidden_file(const struct dentry * dentry,
12697 +                         const struct vfsmount * mnt)
12698 +{
12699 +       __u32 mode;
12700 +
12701 +       if (unlikely(!dentry->d_inode))
12702 +               return GR_FIND;
12703 +
12704 +       mode =
12705 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
12706 +
12707 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
12708 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
12709 +               return mode;
12710 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
12711 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
12712 +               return 0;
12713 +       } else if (unlikely(!(mode & GR_FIND)))
12714 +               return 0;
12715 +
12716 +       return GR_FIND;
12717 +}
12718 +
12719 +__u32
12720 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12721 +                  const int fmode)
12722 +{
12723 +       __u32 reqmode = GR_FIND;
12724 +       __u32 mode;
12725 +
12726 +       if (unlikely(!dentry->d_inode))
12727 +               return reqmode;
12728 +
12729 +       if (unlikely(fmode & O_APPEND))
12730 +               reqmode |= GR_APPEND;
12731 +       else if (unlikely(fmode & FMODE_WRITE))
12732 +               reqmode |= GR_WRITE;
12733 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
12734 +               reqmode |= GR_READ;
12735 +
12736 +       mode =
12737 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
12738 +                          mnt);
12739 +
12740 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12741 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
12742 +                              reqmode & GR_READ ? " reading" : "",
12743 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12744 +                              GR_APPEND ? " appending" : "");
12745 +               return reqmode;
12746 +       } else
12747 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12748 +       {
12749 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
12750 +                              reqmode & GR_READ ? " reading" : "",
12751 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12752 +                              GR_APPEND ? " appending" : "");
12753 +               return 0;
12754 +       } else if (unlikely((mode & reqmode) != reqmode))
12755 +               return 0;
12756 +
12757 +       return reqmode;
12758 +}
12759 +
12760 +__u32
12761 +gr_acl_handle_creat(const struct dentry * dentry,
12762 +                   const struct dentry * p_dentry,
12763 +                   const struct vfsmount * p_mnt, const int fmode,
12764 +                   const int imode)
12765 +{
12766 +       __u32 reqmode = GR_WRITE | GR_CREATE;
12767 +       __u32 mode;
12768 +
12769 +       if (unlikely(fmode & O_APPEND))
12770 +               reqmode |= GR_APPEND;
12771 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
12772 +               reqmode |= GR_READ;
12773 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
12774 +               reqmode |= GR_SETID;
12775 +
12776 +       mode =
12777 +           gr_check_create(dentry, p_dentry, p_mnt,
12778 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
12779 +
12780 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12781 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
12782 +                              reqmode & GR_READ ? " reading" : "",
12783 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12784 +                              GR_APPEND ? " appending" : "");
12785 +               return reqmode;
12786 +       } else
12787 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12788 +       {
12789 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
12790 +                              reqmode & GR_READ ? " reading" : "",
12791 +                              reqmode & GR_WRITE ? " writing" : reqmode &
12792 +                              GR_APPEND ? " appending" : "");
12793 +               return 0;
12794 +       } else if (unlikely((mode & reqmode) != reqmode))
12795 +               return 0;
12796 +
12797 +       return reqmode;
12798 +}
12799 +
12800 +__u32
12801 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
12802 +                    const int fmode)
12803 +{
12804 +       __u32 mode, reqmode = GR_FIND;
12805 +
12806 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
12807 +               reqmode |= GR_EXEC;
12808 +       if (fmode & S_IWOTH)
12809 +               reqmode |= GR_WRITE;
12810 +       if (fmode & S_IROTH)
12811 +               reqmode |= GR_READ;
12812 +
12813 +       mode =
12814 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
12815 +                          mnt);
12816 +
12817 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
12818 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
12819 +                              reqmode & GR_READ ? " reading" : "",
12820 +                              reqmode & GR_WRITE ? " writing" : "",
12821 +                              reqmode & GR_EXEC ? " executing" : "");
12822 +               return reqmode;
12823 +       } else
12824 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
12825 +       {
12826 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
12827 +                              reqmode & GR_READ ? " reading" : "",
12828 +                              reqmode & GR_WRITE ? " writing" : "",
12829 +                              reqmode & GR_EXEC ? " executing" : "");
12830 +               return 0;
12831 +       } else if (unlikely((mode & reqmode) != reqmode))
12832 +               return 0;
12833 +
12834 +       return reqmode;
12835 +}
12836 +
12837 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
12838 +{
12839 +       __u32 mode;
12840 +
12841 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
12842 +
12843 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
12844 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
12845 +               return mode;
12846 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
12847 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
12848 +               return 0;
12849 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
12850 +               return 0;
12851 +
12852 +       return (reqmode);
12853 +}
12854 +
12855 +__u32
12856 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
12857 +{
12858 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
12859 +}
12860 +
12861 +__u32
12862 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
12863 +{
12864 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
12865 +}
12866 +
12867 +__u32
12868 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
12869 +{
12870 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
12871 +}
12872 +
12873 +__u32
12874 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
12875 +{
12876 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
12877 +}
12878 +
12879 +__u32
12880 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
12881 +                    mode_t mode)
12882 +{
12883 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
12884 +               return 1;
12885 +
12886 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
12887 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
12888 +                                  GR_FCHMOD_ACL_MSG);
12889 +       } else {
12890 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
12891 +       }
12892 +}
12893 +
12894 +__u32
12895 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
12896 +                   mode_t mode)
12897 +{
12898 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
12899 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
12900 +                                  GR_CHMOD_ACL_MSG);
12901 +       } else {
12902 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
12903 +       }
12904 +}
12905 +
12906 +__u32
12907 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
12908 +{
12909 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
12910 +}
12911 +
12912 +__u32
12913 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
12914 +{
12915 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
12916 +}
12917 +
12918 +__u32
12919 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
12920 +{
12921 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
12922 +                          GR_UNIXCONNECT_ACL_MSG);
12923 +}
12924 +
12925 +/* hardlinks require at minimum create permission,
12926 +   any additional privilege required is based on the
12927 +   privilege of the file being linked to
12928 +*/
12929 +__u32
12930 +gr_acl_handle_link(const struct dentry * new_dentry,
12931 +                  const struct dentry * parent_dentry,
12932 +                  const struct vfsmount * parent_mnt,
12933 +                  const struct dentry * old_dentry,
12934 +                  const struct vfsmount * old_mnt, const char *to)
12935 +{
12936 +       __u32 mode;
12937 +       __u32 needmode = GR_CREATE | GR_LINK;
12938 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
12939 +
12940 +       mode =
12941 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
12942 +                         old_mnt);
12943 +
12944 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
12945 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
12946 +               return mode;
12947 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
12948 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
12949 +               return 0;
12950 +       } else if (unlikely((mode & needmode) != needmode))
12951 +               return 0;
12952 +
12953 +       return 1;
12954 +}
12955 +
12956 +__u32
12957 +gr_acl_handle_symlink(const struct dentry * new_dentry,
12958 +                     const struct dentry * parent_dentry,
12959 +                     const struct vfsmount * parent_mnt, const char *from)
12960 +{
12961 +       __u32 needmode = GR_WRITE | GR_CREATE;
12962 +       __u32 mode;
12963 +
12964 +       mode =
12965 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
12966 +                           GR_CREATE | GR_AUDIT_CREATE |
12967 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
12968 +
12969 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
12970 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
12971 +               return mode;
12972 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
12973 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
12974 +               return 0;
12975 +       } else if (unlikely((mode & needmode) != needmode))
12976 +               return 0;
12977 +
12978 +       return (GR_WRITE | GR_CREATE);
12979 +}
12980 +
12981 +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)
12982 +{
12983 +       __u32 mode;
12984 +
12985 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
12986 +
12987 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
12988 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
12989 +               return mode;
12990 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
12991 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
12992 +               return 0;
12993 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
12994 +               return 0;
12995 +
12996 +       return (reqmode);
12997 +}
12998 +
12999 +__u32
13000 +gr_acl_handle_mknod(const struct dentry * new_dentry,
13001 +                   const struct dentry * parent_dentry,
13002 +                   const struct vfsmount * parent_mnt,
13003 +                   const int mode)
13004 +{
13005 +       __u32 reqmode = GR_WRITE | GR_CREATE;
13006 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
13007 +               reqmode |= GR_SETID;
13008 +
13009 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
13010 +                                 reqmode, GR_MKNOD_ACL_MSG);
13011 +}
13012 +
13013 +__u32
13014 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
13015 +                   const struct dentry *parent_dentry,
13016 +                   const struct vfsmount *parent_mnt)
13017 +{
13018 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
13019 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
13020 +}
13021 +
13022 +#define RENAME_CHECK_SUCCESS(old, new) \
13023 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
13024 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
13025 +
13026 +int
13027 +gr_acl_handle_rename(struct dentry *new_dentry,
13028 +                    struct dentry *parent_dentry,
13029 +                    const struct vfsmount *parent_mnt,
13030 +                    struct dentry *old_dentry,
13031 +                    struct inode *old_parent_inode,
13032 +                    struct vfsmount *old_mnt, const char *newname)
13033 +{
13034 +       __u32 comp1, comp2;
13035 +       int error = 0;
13036 +
13037 +       if (unlikely(!gr_acl_is_enabled()))
13038 +               return 0;
13039 +
13040 +       if (!new_dentry->d_inode) {
13041 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
13042 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
13043 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
13044 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
13045 +                                      GR_DELETE | GR_AUDIT_DELETE |
13046 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
13047 +                                      GR_SUPPRESS, old_mnt);
13048 +       } else {
13049 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
13050 +                                      GR_CREATE | GR_DELETE |
13051 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
13052 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
13053 +                                      GR_SUPPRESS, parent_mnt);
13054 +               comp2 =
13055 +                   gr_search_file(old_dentry,
13056 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
13057 +                                  GR_DELETE | GR_AUDIT_DELETE |
13058 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
13059 +       }
13060 +
13061 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
13062 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
13063 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
13064 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
13065 +                && !(comp2 & GR_SUPPRESS)) {
13066 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
13067 +               error = -EACCES;
13068 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
13069 +               error = -EACCES;
13070 +
13071 +       return error;
13072 +}
13073 +
13074 +void
13075 +gr_acl_handle_exit(void)
13076 +{
13077 +       u16 id;
13078 +       char *rolename;
13079 +       struct file *exec_file;
13080 +
13081 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
13082 +               id = current->acl_role_id;
13083 +               rolename = current->role->rolename;
13084 +               gr_set_acls(1);
13085 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
13086 +       }
13087 +
13088 +       write_lock(&grsec_exec_file_lock);
13089 +       exec_file = current->exec_file;
13090 +       current->exec_file = NULL;
13091 +       write_unlock(&grsec_exec_file_lock);
13092 +
13093 +       if (exec_file)
13094 +               fput(exec_file);
13095 +}
13096 +
13097 +int
13098 +gr_acl_handle_procpidmem(const struct task_struct *task)
13099 +{
13100 +       if (unlikely(!gr_acl_is_enabled()))
13101 +               return 0;
13102 +
13103 +       if (task->acl->mode & GR_PROTPROCFD)
13104 +               return -EACCES;
13105 +
13106 +       return 0;
13107 +}
13108 diff -urNp linux-2.6.16.2/grsecurity/gracl_ip.c linux-2.6.16.2/grsecurity/gracl_ip.c
13109 --- linux-2.6.16.2/grsecurity/gracl_ip.c        1969-12-31 19:00:00.000000000 -0500
13110 +++ linux-2.6.16.2/grsecurity/gracl_ip.c        2006-04-09 21:23:54.000000000 -0400
13111 @@ -0,0 +1,313 @@
13112 +#include <linux/kernel.h>
13113 +#include <asm/uaccess.h>
13114 +#include <asm/errno.h>
13115 +#include <net/sock.h>
13116 +#include <linux/file.h>
13117 +#include <linux/fs.h>
13118 +#include <linux/net.h>
13119 +#include <linux/in.h>
13120 +#include <linux/skbuff.h>
13121 +#include <linux/ip.h>
13122 +#include <linux/udp.h>
13123 +#include <linux/smp_lock.h>
13124 +#include <linux/types.h>
13125 +#include <linux/sched.h>
13126 +#include <linux/netdevice.h>
13127 +#include <linux/inetdevice.h>
13128 +#include <linux/gracl.h>
13129 +#include <linux/grsecurity.h>
13130 +#include <linux/grinternal.h>
13131 +
13132 +#define GR_BIND        0x01
13133 +#define GR_CONNECT     0x02
13134 +#define GR_INVERT      0x04
13135 +
13136 +static const char * gr_protocols[256] = {
13137 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
13138 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
13139 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
13140 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
13141 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
13142 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
13143 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
13144 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
13145 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
13146 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
13147 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
13148 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
13149 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
13150 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
13151 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
13152 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
13153 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
13154 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
13155 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
13156 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
13157 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
13158 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
13159 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
13160 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
13161 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
13162 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
13163 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
13164 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
13165 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
13166 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
13167 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
13168 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
13169 +       };
13170 +
13171 +static const char * gr_socktypes[11] = {
13172 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
13173 +       "unknown:7", "unknown:8", "unknown:9", "packet"
13174 +       };
13175 +
13176 +const char *
13177 +gr_proto_to_name(unsigned char proto)
13178 +{
13179 +       return gr_protocols[proto];
13180 +}
13181 +
13182 +const char *
13183 +gr_socktype_to_name(unsigned char type)
13184 +{
13185 +       return gr_socktypes[type];
13186 +}
13187 +
13188 +int
13189 +gr_search_socket(const int domain, const int type, const int protocol)
13190 +{
13191 +       struct acl_subject_label *curr;
13192 +
13193 +       if (unlikely(!gr_acl_is_enabled()))
13194 +               goto exit;
13195 +
13196 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
13197 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
13198 +               goto exit;      // let the kernel handle it
13199 +
13200 +       curr = current->acl;
13201 +
13202 +       if (!curr->ips)
13203 +               goto exit;
13204 +
13205 +       if ((curr->ip_type & (1 << type)) &&
13206 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
13207 +               goto exit;
13208 +
13209 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
13210 +               /* we don't place acls on raw sockets , and sometimes
13211 +                  dgram/ip sockets are opened for ioctl and not
13212 +                  bind/connect, so we'll fake a bind learn log */
13213 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
13214 +                       __u32 fakeip = 0;
13215 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13216 +                                      current->role->roletype, current->uid,
13217 +                                      current->gid, current->exec_file ?
13218 +                                      gr_to_filename(current->exec_file->f_dentry,
13219 +                                      current->exec_file->f_vfsmnt) :
13220 +                                      curr->filename, curr->filename,
13221 +                                      NIPQUAD(fakeip), 0, type,
13222 +                                      protocol, GR_CONNECT, 
13223 +NIPQUAD(current->signal->curr_ip));
13224 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
13225 +                       __u32 fakeip = 0;
13226 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13227 +                                      current->role->roletype, current->uid,
13228 +                                      current->gid, current->exec_file ?
13229 +                                      gr_to_filename(current->exec_file->f_dentry,
13230 +                                      current->exec_file->f_vfsmnt) :
13231 +                                      curr->filename, curr->filename,
13232 +                                      NIPQUAD(fakeip), 0, type,
13233 +                                      protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
13234 +               }
13235 +               /* we'll log when they use connect or bind */
13236 +               goto exit;
13237 +       }
13238 +
13239 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
13240 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
13241 +
13242 +       return 0;
13243 +      exit:
13244 +       return 1;
13245 +}
13246 +
13247 +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)
13248 +{
13249 +       if ((ip->mode & mode) &&
13250 +           (ip_port >= ip->low) &&
13251 +           (ip_port <= ip->high) &&
13252 +           ((ntohl(ip_addr) & our_netmask) ==
13253 +            (ntohl(our_addr) & our_netmask))
13254 +           && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
13255 +           && (ip->type & (1 << type))) {
13256 +               if (ip->mode & GR_INVERT)
13257 +                       return 2; // specifically denied
13258 +               else
13259 +                       return 1; // allowed
13260 +       }
13261 +
13262 +       return 0; // not specifically allowed, may continue parsing
13263 +}
13264 +
13265 +static int
13266 +gr_search_connectbind(const int mode, const struct sock *sk,
13267 +                     const struct sockaddr_in *addr, const int type)
13268 +{
13269 +       char iface[IFNAMSIZ] = {0};
13270 +       struct acl_subject_label *curr;
13271 +       struct acl_ip_label *ip;
13272 +       struct net_device *dev;
13273 +       struct in_device *idev;
13274 +       unsigned long i;
13275 +       int ret;
13276 +       __u32 ip_addr = 0;
13277 +       __u32 our_addr;
13278 +       __u32 our_netmask;
13279 +       char *p;
13280 +       __u16 ip_port = 0;
13281 +
13282 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
13283 +               return 1;
13284 +
13285 +       curr = current->acl;
13286 +
13287 +       if (!curr->ips)
13288 +               return 1;
13289 +
13290 +       ip_addr = addr->sin_addr.s_addr;
13291 +       ip_port = ntohs(addr->sin_port);
13292 +
13293 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
13294 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
13295 +                              current->role->roletype, current->uid,
13296 +                              current->gid, current->exec_file ?
13297 +                              gr_to_filename(current->exec_file->f_dentry,
13298 +                              current->exec_file->f_vfsmnt) :
13299 +                              curr->filename, curr->filename,
13300 +                              NIPQUAD(ip_addr), ip_port, type,
13301 +                              sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
13302 +               return 1;
13303 +       }
13304 +
13305 +       for (i = 0; i < curr->ip_num; i++) {
13306 +               ip = *(curr->ips + i);
13307 +               if (ip->iface != NULL) {
13308 +                       strncpy(iface, ip->iface, IFNAMSIZ - 1);
13309 +                       p = strchr(iface, ':');
13310 +                       if (p != NULL)
13311 +                               *p = '\0';
13312 +                       dev = dev_get_by_name(iface);
13313 +                       if (dev == NULL)
13314 +                               continue;
13315 +                       idev = in_dev_get(dev);
13316 +                       if (idev == NULL) {
13317 +                               dev_put(dev);
13318 +                               continue;
13319 +                       }
13320 +                       rcu_read_lock();
13321 +                       for_ifa(idev) {
13322 +                               if (!strcmp(ip->iface, ifa->ifa_label)) {
13323 +                                       our_addr = ifa->ifa_address;
13324 +                                       our_netmask = 0xffffffff;
13325 +                                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
13326 +                                       if (ret == 1) {
13327 +                                               rcu_read_unlock();
13328 +                                               in_dev_put(idev);
13329 +                                               dev_put(dev);
13330 +                                               return 1;
13331 +                                       } else if (ret == 2) {
13332 +                                               rcu_read_unlock();
13333 +                                               in_dev_put(idev);
13334 +                                               dev_put(dev);
13335 +                                               goto denied;
13336 +                                       }
13337 +                               }
13338 +                       } endfor_ifa(idev);
13339 +                       rcu_read_unlock();
13340 +                       in_dev_put(idev);
13341 +                       dev_put(dev);
13342 +               } else {
13343 +                       our_addr = ip->addr;
13344 +                       our_netmask = ip->netmask;
13345 +                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
13346 +                       if (ret == 1)
13347 +                               return 1;
13348 +                       else if (ret == 2)
13349 +                               goto denied;
13350 +               }
13351 +       }
13352 +
13353 +denied:
13354 +       if (mode == GR_BIND)
13355 +               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));
13356 +       else if (mode == GR_CONNECT)
13357 +               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));
13358 +
13359 +       return 0;
13360 +}
13361 +
13362 +int
13363 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
13364 +{
13365 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
13366 +}
13367 +
13368 +int
13369 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
13370 +{
13371 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
13372 +}
13373 +
13374 +int gr_search_listen(const struct socket *sock)
13375 +{
13376 +       struct sock *sk = sock->sk;
13377 +       struct sockaddr_in addr;
13378 +
13379 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
13380 +       addr.sin_port = inet_sk(sk)->sport;
13381 +
13382 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
13383 +}
13384 +
13385 +int gr_search_accept(const struct socket *sock)
13386 +{
13387 +       struct sock *sk = sock->sk;
13388 +       struct sockaddr_in addr;
13389 +
13390 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
13391 +       addr.sin_port = inet_sk(sk)->sport;
13392 +
13393 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
13394 +}
13395 +
13396 +int
13397 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
13398 +{
13399 +       if (addr)
13400 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
13401 +       else {
13402 +               struct sockaddr_in sin;
13403 +               const struct inet_sock *inet = inet_sk(sk);
13404 +
13405 +               sin.sin_addr.s_addr = inet->daddr;
13406 +               sin.sin_port = inet->dport;
13407 +
13408 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
13409 +       }
13410 +}
13411 +
13412 +int
13413 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
13414 +{
13415 +       struct sockaddr_in sin;
13416 +
13417 +       if (unlikely(skb->len < sizeof (struct udphdr)))
13418 +               return 1;       // skip this packet
13419 +
13420 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
13421 +       sin.sin_port = skb->h.uh->source;
13422 +
13423 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
13424 +}
13425 diff -urNp linux-2.6.16.2/grsecurity/gracl_learn.c linux-2.6.16.2/grsecurity/gracl_learn.c
13426 --- linux-2.6.16.2/grsecurity/gracl_learn.c     1969-12-31 19:00:00.000000000 -0500
13427 +++ linux-2.6.16.2/grsecurity/gracl_learn.c     2006-04-09 21:23:54.000000000 -0400
13428 @@ -0,0 +1,204 @@
13429 +#include <linux/kernel.h>
13430 +#include <linux/mm.h>
13431 +#include <linux/sched.h>
13432 +#include <linux/poll.h>
13433 +#include <linux/smp_lock.h>
13434 +#include <linux/string.h>
13435 +#include <linux/file.h>
13436 +#include <linux/types.h>
13437 +#include <linux/vmalloc.h>
13438 +#include <linux/grinternal.h>
13439 +
13440 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
13441 +                                  size_t count, loff_t *ppos);
13442 +extern int gr_acl_is_enabled(void);
13443 +
13444 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
13445 +static int gr_learn_attached;
13446 +
13447 +/* use a 512k buffer */
13448 +#define LEARN_BUFFER_SIZE (512 * 1024)
13449 +
13450 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
13451 +static DECLARE_MUTEX(gr_learn_user_sem);
13452 +
13453 +/* we need to maintain two buffers, so that the kernel context of grlearn
13454 +   uses a semaphore around the userspace copying, and the other kernel contexts
13455 +   use a spinlock when copying into the buffer, since they cannot sleep
13456 +*/
13457 +static char *learn_buffer;
13458 +static char *learn_buffer_user;
13459 +static int learn_buffer_len;
13460 +static int learn_buffer_user_len;
13461 +
13462 +static ssize_t
13463 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
13464 +{
13465 +       DECLARE_WAITQUEUE(wait, current);
13466 +       ssize_t retval = 0;
13467 +
13468 +       add_wait_queue(&learn_wait, &wait);
13469 +       set_current_state(TASK_INTERRUPTIBLE);
13470 +       do {
13471 +               down(&gr_learn_user_sem);
13472 +               spin_lock(&gr_learn_lock);
13473 +               if (learn_buffer_len)
13474 +                       break;
13475 +               spin_unlock(&gr_learn_lock);
13476 +               up(&gr_learn_user_sem);
13477 +               if (file->f_flags & O_NONBLOCK) {
13478 +                       retval = -EAGAIN;
13479 +                       goto out;
13480 +               }
13481 +               if (signal_pending(current)) {
13482 +                       retval = -ERESTARTSYS;
13483 +                       goto out;
13484 +               }
13485 +
13486 +               schedule();
13487 +       } while (1);
13488 +
13489 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
13490 +       learn_buffer_user_len = learn_buffer_len;
13491 +       retval = learn_buffer_len;
13492 +       learn_buffer_len = 0;
13493 +
13494 +       spin_unlock(&gr_learn_lock);
13495 +
13496 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
13497 +               retval = -EFAULT;
13498 +
13499 +       up(&gr_learn_user_sem);
13500 +out:
13501 +       set_current_state(TASK_RUNNING);
13502 +       remove_wait_queue(&learn_wait, &wait);
13503 +       return retval;
13504 +}
13505 +
13506 +static unsigned int
13507 +poll_learn(struct file * file, poll_table * wait)
13508 +{
13509 +       poll_wait(file, &learn_wait, wait);
13510 +
13511 +       if (learn_buffer_len)
13512 +               return (POLLIN | POLLRDNORM);
13513 +
13514 +       return 0;
13515 +}
13516 +
13517 +void
13518 +gr_clear_learn_entries(void)
13519 +{
13520 +       char *tmp;
13521 +
13522 +       down(&gr_learn_user_sem);
13523 +       if (learn_buffer != NULL) {
13524 +               spin_lock(&gr_learn_lock);
13525 +               tmp = learn_buffer;
13526 +               learn_buffer = NULL;
13527 +               spin_unlock(&gr_learn_lock);
13528 +               vfree(learn_buffer);
13529 +       }
13530 +       if (learn_buffer_user != NULL) {
13531 +               vfree(learn_buffer_user);
13532 +               learn_buffer_user = NULL;
13533 +       }
13534 +       learn_buffer_len = 0;
13535 +       up(&gr_learn_user_sem);
13536 +
13537 +       return;
13538 +}
13539 +
13540 +void
13541 +gr_add_learn_entry(const char *fmt, ...)
13542 +{
13543 +       va_list args;
13544 +       unsigned int len;
13545 +
13546 +       if (!gr_learn_attached)
13547 +               return;
13548 +
13549 +       spin_lock(&gr_learn_lock);
13550 +
13551 +       /* leave a gap at the end so we know when it's "full" but don't have to
13552 +          compute the exact length of the string we're trying to append
13553 +       */
13554 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
13555 +               spin_unlock(&gr_learn_lock);
13556 +               wake_up_interruptible(&learn_wait);
13557 +               return;
13558 +       }
13559 +       if (learn_buffer == NULL) {
13560 +               spin_unlock(&gr_learn_lock);
13561 +               return;
13562 +       }
13563 +
13564 +       va_start(args, fmt);
13565 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
13566 +       va_end(args);
13567 +
13568 +       learn_buffer_len += len + 1;
13569 +
13570 +       spin_unlock(&gr_learn_lock);
13571 +       wake_up_interruptible(&learn_wait);
13572 +
13573 +       return;
13574 +}
13575 +
13576 +static int
13577 +open_learn(struct inode *inode, struct file *file)
13578 +{
13579 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
13580 +               return -EBUSY;
13581 +       if (file->f_mode & FMODE_READ) {
13582 +               down(&gr_learn_user_sem);
13583 +               if (learn_buffer == NULL)
13584 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
13585 +               if (learn_buffer_user == NULL)
13586 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
13587 +               if (learn_buffer == NULL)
13588 +                       return -ENOMEM;
13589 +               if (learn_buffer_user == NULL)
13590 +                       return -ENOMEM;
13591 +               learn_buffer_len = 0;
13592 +               learn_buffer_user_len = 0;
13593 +               gr_learn_attached = 1;
13594 +               up(&gr_learn_user_sem);
13595 +       }
13596 +       return 0;
13597 +}
13598 +
13599 +static int
13600 +close_learn(struct inode *inode, struct file *file)
13601 +{
13602 +       char *tmp;
13603 +
13604 +       if (file->f_mode & FMODE_READ) {
13605 +               down(&gr_learn_user_sem);
13606 +               if (learn_buffer != NULL) {
13607 +                       spin_lock(&gr_learn_lock);
13608 +                       tmp = learn_buffer;
13609 +                       learn_buffer = NULL;
13610 +                       spin_unlock(&gr_learn_lock);
13611 +                       vfree(tmp);
13612 +               }
13613 +               if (learn_buffer_user != NULL) {
13614 +                       vfree(learn_buffer_user);
13615 +                       learn_buffer_user = NULL;
13616 +               }
13617 +               learn_buffer_len = 0;
13618 +               learn_buffer_user_len = 0;
13619 +               gr_learn_attached = 0;
13620 +               up(&gr_learn_user_sem);
13621 +       }
13622 +
13623 +       return 0;
13624 +}
13625 +               
13626 +struct file_operations grsec_fops = {
13627 +       .read           = read_learn,
13628 +       .write          = write_grsec_handler,
13629 +       .open           = open_learn,
13630 +       .release        = close_learn,
13631 +       .poll           = poll_learn,
13632 +};
13633 diff -urNp linux-2.6.16.2/grsecurity/gracl_res.c linux-2.6.16.2/grsecurity/gracl_res.c
13634 --- linux-2.6.16.2/grsecurity/gracl_res.c       1969-12-31 19:00:00.000000000 -0500
13635 +++ linux-2.6.16.2/grsecurity/gracl_res.c       2006-04-09 21:23:54.000000000 -0400
13636 @@ -0,0 +1,42 @@
13637 +#include <linux/kernel.h>
13638 +#include <linux/sched.h>
13639 +#include <linux/gracl.h>
13640 +#include <linux/grinternal.h>
13641 +
13642 +static const char *restab_log[] = {
13643 +       [RLIMIT_CPU] = "RLIMIT_CPU",
13644 +       [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
13645 +       [RLIMIT_DATA] = "RLIMIT_DATA",
13646 +       [RLIMIT_STACK] = "RLIMIT_STACK",
13647 +       [RLIMIT_CORE] = "RLIMIT_CORE",
13648 +       [RLIMIT_RSS] = "RLIMIT_RSS",
13649 +       [RLIMIT_NPROC] = "RLIMIT_NPROC",
13650 +       [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
13651 +       [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
13652 +       [RLIMIT_AS] = "RLIMIT_AS",
13653 +       [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
13654 +       [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
13655 +};
13656 +
13657 +void
13658 +gr_log_resource(const struct task_struct *task,
13659 +               const int res, const unsigned long wanted, const int gt)
13660 +{
13661 +       if (res == RLIMIT_NPROC && 
13662 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
13663 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
13664 +               return;
13665 +       else if (res == RLIMIT_MEMLOCK &&
13666 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
13667 +               return;
13668 +
13669 +       preempt_disable();
13670 +
13671 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
13672 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
13673 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
13674 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
13675 +       preempt_enable_no_resched();
13676 +
13677 +       return;
13678 +}
13679 diff -urNp linux-2.6.16.2/grsecurity/gracl_segv.c linux-2.6.16.2/grsecurity/gracl_segv.c
13680 --- linux-2.6.16.2/grsecurity/gracl_segv.c      1969-12-31 19:00:00.000000000 -0500
13681 +++ linux-2.6.16.2/grsecurity/gracl_segv.c      2006-04-09 21:23:54.000000000 -0400
13682 @@ -0,0 +1,295 @@
13683 +#include <linux/kernel.h>
13684 +#include <linux/mm.h>
13685 +#include <asm/uaccess.h>
13686 +#include <asm/errno.h>
13687 +#include <asm/mman.h>
13688 +#include <net/sock.h>
13689 +#include <linux/file.h>
13690 +#include <linux/fs.h>
13691 +#include <linux/net.h>
13692 +#include <linux/in.h>
13693 +#include <linux/smp_lock.h>
13694 +#include <linux/slab.h>
13695 +#include <linux/types.h>
13696 +#include <linux/sched.h>
13697 +#include <linux/timer.h>
13698 +#include <linux/gracl.h>
13699 +#include <linux/grsecurity.h>
13700 +#include <linux/grinternal.h>
13701 +
13702 +static struct crash_uid *uid_set;
13703 +static unsigned short uid_used;
13704 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
13705 +extern rwlock_t gr_inode_lock;
13706 +extern struct acl_subject_label *
13707 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
13708 +                             struct acl_role_label *role);
13709 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
13710 +
13711 +int
13712 +gr_init_uidset(void)
13713 +{
13714 +       uid_set =
13715 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
13716 +       uid_used = 0;
13717 +
13718 +       return uid_set ? 1 : 0;
13719 +}
13720 +
13721 +void
13722 +gr_free_uidset(void)
13723 +{
13724 +       if (uid_set)
13725 +               kfree(uid_set);
13726 +
13727 +       return;
13728 +}
13729 +
13730 +int
13731 +gr_find_uid(const uid_t uid)
13732 +{
13733 +       struct crash_uid *tmp = uid_set;
13734 +       uid_t buid;
13735 +       int low = 0, high = uid_used - 1, mid;
13736 +
13737 +       while (high >= low) {
13738 +               mid = (low + high) >> 1;
13739 +               buid = tmp[mid].uid;
13740 +               if (buid == uid)
13741 +                       return mid;
13742 +               if (buid > uid)
13743 +                       high = mid - 1;
13744 +               if (buid < uid)
13745 +                       low = mid + 1;
13746 +       }
13747 +
13748 +       return -1;
13749 +}
13750 +
13751 +static __inline__ void
13752 +gr_insertsort(void)
13753 +{
13754 +       unsigned short i, j;
13755 +       struct crash_uid index;
13756 +
13757 +       for (i = 1; i < uid_used; i++) {
13758 +               index = uid_set[i];
13759 +               j = i;
13760 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
13761 +                       uid_set[j] = uid_set[j - 1];
13762 +                       j--;
13763 +               }
13764 +               uid_set[j] = index;
13765 +       }
13766 +
13767 +       return;
13768 +}
13769 +
13770 +static __inline__ void
13771 +gr_insert_uid(const uid_t uid, const unsigned long expires)
13772 +{
13773 +       int loc;
13774 +
13775 +       if (uid_used == GR_UIDTABLE_MAX)
13776 +               return;
13777 +
13778 +       loc = gr_find_uid(uid);
13779 +
13780 +       if (loc >= 0) {
13781 +               uid_set[loc].expires = expires;
13782 +               return;
13783 +       }
13784 +
13785 +       uid_set[uid_used].uid = uid;
13786 +       uid_set[uid_used].expires = expires;
13787 +       uid_used++;
13788 +
13789 +       gr_insertsort();
13790 +
13791 +       return;
13792 +}
13793 +
13794 +void
13795 +gr_remove_uid(const unsigned short loc)
13796 +{
13797 +       unsigned short i;
13798 +
13799 +       for (i = loc + 1; i < uid_used; i++)
13800 +               uid_set[i - 1] = uid_set[i];
13801 +
13802 +       uid_used--;
13803 +
13804 +       return;
13805 +}
13806 +
13807 +int
13808 +gr_check_crash_uid(const uid_t uid)
13809 +{
13810 +       int loc;
13811 +       int ret = 0;
13812 +
13813 +       if (unlikely(!gr_acl_is_enabled()))
13814 +               return 0;
13815 +
13816 +       spin_lock(&gr_uid_lock);
13817 +       loc = gr_find_uid(uid);
13818 +
13819 +       if (loc < 0)
13820 +               goto out_unlock;
13821 +
13822 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
13823 +               gr_remove_uid(loc);
13824 +       else
13825 +               ret = 1;
13826 +
13827 +out_unlock:
13828 +       spin_unlock(&gr_uid_lock);
13829 +       return ret;
13830 +}
13831 +
13832 +static __inline__ int
13833 +proc_is_setxid(const struct task_struct *task)
13834 +{
13835 +       if (task->uid != task->euid || task->uid != task->suid ||
13836 +           task->uid != task->fsuid)
13837 +               return 1;
13838 +       if (task->gid != task->egid || task->gid != task->sgid ||
13839 +           task->gid != task->fsgid)
13840 +               return 1;
13841 +
13842 +       return 0;
13843 +}
13844 +static __inline__ int
13845 +gr_fake_force_sig(int sig, struct task_struct *t)
13846 +{
13847 +       unsigned long int flags;
13848 +       int ret;
13849 +
13850 +       spin_lock_irqsave(&t->sighand->siglock, flags);
13851 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
13852 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
13853 +               sigdelset(&t->blocked, sig);
13854 +               recalc_sigpending_tsk(t);
13855 +       }
13856 +       ret = specific_send_sig_info(sig, (void*)1L, t);
13857 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
13858 +
13859 +       return ret;
13860 +}
13861 +
13862 +void
13863 +gr_handle_crash(struct task_struct *task, const int sig)
13864 +{
13865 +       struct acl_subject_label *curr;
13866 +       struct acl_subject_label *curr2;
13867 +       struct task_struct *tsk, *tsk2;
13868 +
13869 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
13870 +               return;
13871 +
13872 +       if (unlikely(!gr_acl_is_enabled()))
13873 +               return;
13874 +
13875 +       curr = task->acl;
13876 +
13877 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
13878 +               return;
13879 +
13880 +       if (time_before_eq(curr->expires, get_seconds())) {
13881 +               curr->expires = 0;
13882 +               curr->crashes = 0;
13883 +       }
13884 +
13885 +       curr->crashes++;
13886 +
13887 +       if (!curr->expires)
13888 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
13889 +
13890 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
13891 +           time_after(curr->expires, get_seconds())) {
13892 +               if (task->uid && proc_is_setxid(task)) {
13893 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
13894 +                       spin_lock(&gr_uid_lock);
13895 +                       gr_insert_uid(task->uid, curr->expires);
13896 +                       spin_unlock(&gr_uid_lock);
13897 +                       curr->expires = 0;
13898 +                       curr->crashes = 0;
13899 +                       read_lock(&tasklist_lock);
13900 +                       do_each_thread(tsk2, tsk) {
13901 +                               if (tsk != task && tsk->uid == task->uid)
13902 +                                       gr_fake_force_sig(SIGKILL, tsk);
13903 +                       } while_each_thread(tsk2, tsk);
13904 +                       read_unlock(&tasklist_lock);
13905 +               } else {
13906 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
13907 +                       read_lock(&tasklist_lock);
13908 +                       do_each_thread(tsk2, tsk) {
13909 +                               if (likely(tsk != task)) {
13910 +                                       curr2 = tsk->acl;
13911 +
13912 +                                       if (curr2->device == curr->device &&
13913 +                                           curr2->inode == curr->inode)
13914 +                                               gr_fake_force_sig(SIGKILL, tsk);
13915 +                               }
13916 +                       } while_each_thread(tsk2, tsk);
13917 +                       read_unlock(&tasklist_lock);
13918 +               }
13919 +       }
13920 +
13921 +       return;
13922 +}
13923 +
13924 +int
13925 +gr_check_crash_exec(const struct file *filp)
13926 +{
13927 +       struct acl_subject_label *curr;
13928 +
13929 +       if (unlikely(!gr_acl_is_enabled()))
13930 +               return 0;
13931 +
13932 +       read_lock(&gr_inode_lock);
13933 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
13934 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
13935 +                                    current->role);
13936 +       read_unlock(&gr_inode_lock);
13937 +
13938 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
13939 +           (!curr->crashes && !curr->expires))
13940 +               return 0;
13941 +
13942 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
13943 +           time_after(curr->expires, get_seconds()))
13944 +               return 1;
13945 +       else if (time_before_eq(curr->expires, get_seconds())) {
13946 +               curr->crashes = 0;
13947 +               curr->expires = 0;
13948 +       }
13949 +
13950 +       return 0;
13951 +}
13952 +
13953 +void
13954 +gr_handle_alertkill(struct task_struct *task)
13955 +{
13956 +       struct acl_subject_label *curracl;
13957 +       __u32 curr_ip;
13958 +       struct task_struct *p, *p2;
13959 +
13960 +       if (unlikely(!gr_acl_is_enabled()))
13961 +               return;
13962 +
13963 +       curracl = task->acl;
13964 +       curr_ip = task->signal->curr_ip;
13965 +
13966 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
13967 +               read_lock(&tasklist_lock);
13968 +               do_each_thread(p2, p) {
13969 +                       if (p->signal->curr_ip == curr_ip)
13970 +                               gr_fake_force_sig(SIGKILL, p);
13971 +               } while_each_thread(p2, p);
13972 +               read_unlock(&tasklist_lock);
13973 +       } else if (curracl->mode & GR_KILLPROC)
13974 +               gr_fake_force_sig(SIGKILL, task);
13975 +
13976 +       return;
13977 +}
13978 diff -urNp linux-2.6.16.2/grsecurity/gracl_shm.c linux-2.6.16.2/grsecurity/gracl_shm.c
13979 --- linux-2.6.16.2/grsecurity/gracl_shm.c       1969-12-31 19:00:00.000000000 -0500
13980 +++ linux-2.6.16.2/grsecurity/gracl_shm.c       2006-04-09 21:23:54.000000000 -0400
13981 @@ -0,0 +1,33 @@
13982 +#include <linux/kernel.h>
13983 +#include <linux/mm.h>
13984 +#include <linux/sched.h>
13985 +#include <linux/file.h>
13986 +#include <linux/ipc.h>
13987 +#include <linux/gracl.h>
13988 +#include <linux/grsecurity.h>
13989 +#include <linux/grinternal.h>
13990 +
13991 +int
13992 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
13993 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
13994 +{
13995 +       struct task_struct *task;
13996 +
13997 +       if (!gr_acl_is_enabled())
13998 +               return 1;
13999 +
14000 +       task = find_task_by_pid(shm_cprid);
14001 +
14002 +       if (unlikely(!task))
14003 +               task = find_task_by_pid(shm_lapid);
14004 +
14005 +       if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
14006 +                             (task->pid == shm_lapid)) &&
14007 +                    (task->acl->mode & GR_PROTSHM) &&
14008 +                    (task->acl != current->acl))) {
14009 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
14010 +               return 0;
14011 +       }
14012 +
14013 +       return 1;
14014 +}
14015 diff -urNp linux-2.6.16.2/grsecurity/grsec_chdir.c linux-2.6.16.2/grsecurity/grsec_chdir.c
14016 --- linux-2.6.16.2/grsecurity/grsec_chdir.c     1969-12-31 19:00:00.000000000 -0500
14017 +++ linux-2.6.16.2/grsecurity/grsec_chdir.c     2006-04-09 21:23:54.000000000 -0400
14018 @@ -0,0 +1,19 @@
14019 +#include <linux/kernel.h>
14020 +#include <linux/sched.h>
14021 +#include <linux/fs.h>
14022 +#include <linux/file.h>
14023 +#include <linux/grsecurity.h>
14024 +#include <linux/grinternal.h>
14025 +
14026 +void
14027 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
14028 +{
14029 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
14030 +       if ((grsec_enable_chdir && grsec_enable_group &&
14031 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
14032 +                                             !grsec_enable_group)) {
14033 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
14034 +       }
14035 +#endif
14036 +       return;
14037 +}
14038 diff -urNp linux-2.6.16.2/grsecurity/grsec_chroot.c linux-2.6.16.2/grsecurity/grsec_chroot.c
14039 --- linux-2.6.16.2/grsecurity/grsec_chroot.c    1969-12-31 19:00:00.000000000 -0500
14040 +++ linux-2.6.16.2/grsecurity/grsec_chroot.c    2006-04-09 21:23:54.000000000 -0400
14041 @@ -0,0 +1,332 @@
14042 +#include <linux/kernel.h>
14043 +#include <linux/module.h>
14044 +#include <linux/sched.h>
14045 +#include <linux/file.h>
14046 +#include <linux/fs.h>
14047 +#include <linux/mount.h>
14048 +#include <linux/types.h>
14049 +#include <linux/grinternal.h>
14050 +
14051 +int
14052 +gr_handle_chroot_unix(const pid_t pid)
14053 +{
14054 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
14055 +       struct pid *spid = NULL;
14056 +
14057 +       if (unlikely(!grsec_enable_chroot_unix))
14058 +               return 1;
14059 +
14060 +       if (likely(!proc_is_chrooted(current)))
14061 +               return 1;
14062 +
14063 +       read_lock(&tasklist_lock);
14064 +
14065 +       spid = find_pid(PIDTYPE_PID, pid);
14066 +       if (spid) {
14067 +               struct task_struct *p;
14068 +               p = pid_task(&spid->pid_list, PIDTYPE_PID);
14069 +               task_lock(p);
14070 +               if (unlikely(!have_same_root(current, p))) {
14071 +                       task_unlock(p);
14072 +                       read_unlock(&tasklist_lock);
14073 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
14074 +                       return 0;
14075 +               }
14076 +               task_unlock(p);
14077 +       }
14078 +       read_unlock(&tasklist_lock);
14079 +#endif
14080 +       return 1;
14081 +}
14082 +
14083 +int
14084 +gr_handle_chroot_nice(void)
14085 +{
14086 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
14087 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
14088 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
14089 +               return -EPERM;
14090 +       }
14091 +#endif
14092 +       return 0;
14093 +}
14094 +
14095 +int
14096 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
14097 +{
14098 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
14099 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
14100 +                       && proc_is_chrooted(current)) {
14101 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
14102 +               return -EACCES;
14103 +       }
14104 +#endif
14105 +       return 0;
14106 +}
14107 +
14108 +int
14109 +gr_handle_chroot_rawio(const struct inode *inode)
14110 +{
14111 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14112 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
14113 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
14114 +               return 1;
14115 +#endif
14116 +       return 0;
14117 +}
14118 +
14119 +int
14120 +gr_pid_is_chrooted(struct task_struct *p)
14121 +{
14122 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
14123 +       if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !p)
14124 +               return 0;
14125 +
14126 +       task_lock(p);
14127 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
14128 +           !have_same_root(current, p)) {
14129 +               task_unlock(p);
14130 +               return 1;
14131 +       }
14132 +       task_unlock(p);
14133 +#endif
14134 +       return 0;
14135 +}
14136 +
14137 +EXPORT_SYMBOL(gr_pid_is_chrooted);
14138 +
14139 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
14140 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
14141 +{
14142 +       struct dentry *dentry = (struct dentry *)u_dentry;
14143 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
14144 +       struct dentry *realroot;
14145 +       struct vfsmount *realrootmnt;
14146 +       struct dentry *currentroot;
14147 +       struct vfsmount *currentmnt;
14148 +       int ret = 1;
14149 +
14150 +       read_lock(&child_reaper->fs->lock);
14151 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
14152 +       realroot = dget(child_reaper->fs->root);
14153 +       read_unlock(&child_reaper->fs->lock);
14154 +
14155 +       read_lock(&current->fs->lock);
14156 +       currentmnt = mntget(current->fs->rootmnt);
14157 +       currentroot = dget(current->fs->root);
14158 +       read_unlock(&current->fs->lock);
14159 +
14160 +       spin_lock(&dcache_lock);
14161 +       for (;;) {
14162 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
14163 +                    || (dentry == currentroot && mnt == currentmnt)))
14164 +                       break;
14165 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
14166 +                       if (mnt->mnt_parent == mnt)
14167 +                               break;
14168 +                       dentry = mnt->mnt_mountpoint;
14169 +                       mnt = mnt->mnt_parent;
14170 +                       continue;
14171 +               }
14172 +               dentry = dentry->d_parent;
14173 +       }
14174 +       spin_unlock(&dcache_lock);
14175 +
14176 +       dput(currentroot);
14177 +       mntput(currentmnt);
14178 +
14179 +       /* access is outside of chroot */
14180 +       if (dentry == realroot && mnt == realrootmnt)
14181 +               ret = 0;
14182 +
14183 +       dput(realroot);
14184 +       mntput(realrootmnt);
14185 +       return ret;
14186 +}
14187 +#endif
14188 +
14189 +int
14190 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
14191 +{
14192 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
14193 +       if (!grsec_enable_chroot_fchdir)
14194 +               return 1;
14195 +
14196 +       if (!proc_is_chrooted(current))
14197 +               return 1;
14198 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
14199 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
14200 +               return 0;
14201 +       }
14202 +#endif
14203 +       return 1;
14204 +}
14205 +
14206 +int
14207 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
14208 +               const time_t shm_createtime)
14209 +{
14210 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
14211 +       struct pid *pid = NULL;
14212 +       time_t starttime;
14213 +
14214 +       if (unlikely(!grsec_enable_chroot_shmat))
14215 +               return 1;
14216 +
14217 +       if (likely(!proc_is_chrooted(current)))
14218 +               return 1;
14219 +
14220 +       read_lock(&tasklist_lock);
14221 +
14222 +       pid = find_pid(PIDTYPE_PID, shm_cprid);
14223 +       if (pid) {
14224 +               struct task_struct *p;
14225 +               p = pid_task(&pid->pid_list, PIDTYPE_PID);
14226 +               task_lock(p);
14227 +               starttime = p->start_time.tv_sec;
14228 +               if (unlikely(!have_same_root(current, p) &&
14229 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
14230 +                       task_unlock(p);
14231 +                       read_unlock(&tasklist_lock);
14232 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
14233 +                       return 0;
14234 +               }
14235 +               task_unlock(p);
14236 +       } else {
14237 +               pid = find_pid(PIDTYPE_PID, shm_lapid);
14238 +               if (pid) {
14239 +                       struct task_struct *p;
14240 +                       p = pid_task(&pid->pid_list, PIDTYPE_PID);
14241 +                       task_lock(p);
14242 +                       if (unlikely(!have_same_root(current, p))) {
14243 +                               task_unlock(p);
14244 +                               read_unlock(&tasklist_lock);
14245 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
14246 +                               return 0;
14247 +                       }
14248 +                       task_unlock(p);
14249 +               }
14250 +       }
14251 +
14252 +       read_unlock(&tasklist_lock);
14253 +#endif
14254 +       return 1;
14255 +}
14256 +
14257 +void
14258 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
14259 +{
14260 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
14261 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
14262 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
14263 +#endif
14264 +       return;
14265 +}
14266 +
14267 +int
14268 +gr_handle_chroot_mknod(const struct dentry *dentry,
14269 +                      const struct vfsmount *mnt, const int mode)
14270 +{
14271 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
14272 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
14273 +           proc_is_chrooted(current)) {
14274 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
14275 +               return -EPERM;
14276 +       }
14277 +#endif
14278 +       return 0;
14279 +}
14280 +
14281 +int
14282 +gr_handle_chroot_mount(const struct dentry *dentry,
14283 +                      const struct vfsmount *mnt, const char *dev_name)
14284 +{
14285 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
14286 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
14287 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
14288 +               return -EPERM;
14289 +       }
14290 +#endif
14291 +       return 0;
14292 +}
14293 +
14294 +int
14295 +gr_handle_chroot_pivot(void)
14296 +{
14297 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
14298 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
14299 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
14300 +               return -EPERM;
14301 +       }
14302 +#endif
14303 +       return 0;
14304 +}
14305 +
14306 +int
14307 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
14308 +{
14309 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
14310 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
14311 +           !gr_is_outside_chroot(dentry, mnt)) {
14312 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
14313 +               return -EPERM;
14314 +       }
14315 +#endif
14316 +       return 0;
14317 +}
14318 +
14319 +void
14320 +gr_handle_chroot_caps(struct task_struct *task)
14321 +{
14322 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14323 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
14324 +               task->cap_permitted =
14325 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
14326 +               task->cap_inheritable =
14327 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
14328 +               task->cap_effective =
14329 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
14330 +       }
14331 +#endif
14332 +       return;
14333 +}
14334 +
14335 +int
14336 +gr_handle_chroot_sysctl(const int op)
14337 +{
14338 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
14339 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
14340 +           && (op & 002))
14341 +               return -EACCES;
14342 +#endif
14343 +       return 0;
14344 +}
14345 +
14346 +void
14347 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
14348 +{
14349 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
14350 +       if (grsec_enable_chroot_chdir)
14351 +               set_fs_pwd(current->fs, mnt, dentry);
14352 +#endif
14353 +       return;
14354 +}
14355 +
14356 +int
14357 +gr_handle_chroot_chmod(const struct dentry *dentry,
14358 +                      const struct vfsmount *mnt, const int mode)
14359 +{
14360 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
14361 +       if (grsec_enable_chroot_chmod &&
14362 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
14363 +           proc_is_chrooted(current)) {
14364 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
14365 +               return -EPERM;
14366 +       }
14367 +#endif
14368 +       return 0;
14369 +}
14370 +
14371 +#ifdef CONFIG_SECURITY
14372 +EXPORT_SYMBOL(gr_handle_chroot_caps);
14373 +#endif
14374 diff -urNp linux-2.6.16.2/grsecurity/grsec_disabled.c linux-2.6.16.2/grsecurity/grsec_disabled.c
14375 --- linux-2.6.16.2/grsecurity/grsec_disabled.c  1969-12-31 19:00:00.000000000 -0500
14376 +++ linux-2.6.16.2/grsecurity/grsec_disabled.c  2006-04-09 21:23:54.000000000 -0400
14377 @@ -0,0 +1,418 @@
14378 +#include <linux/kernel.h>
14379 +#include <linux/module.h>
14380 +#include <linux/config.h>
14381 +#include <linux/sched.h>
14382 +#include <linux/file.h>
14383 +#include <linux/fs.h>
14384 +#include <linux/kdev_t.h>
14385 +#include <linux/net.h>
14386 +#include <linux/in.h>
14387 +#include <linux/ip.h>
14388 +#include <linux/skbuff.h>
14389 +#include <linux/sysctl.h>
14390 +
14391 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14392 +void
14393 +pax_set_initial_flags(struct linux_binprm *bprm)
14394 +{
14395 +       return;
14396 +}
14397 +#endif
14398 +
14399 +#ifdef CONFIG_SYSCTL
14400 +__u32
14401 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
14402 +{
14403 +       return mode;
14404 +}
14405 +#endif
14406 +
14407 +int
14408 +gr_acl_is_enabled(void)
14409 +{
14410 +       return 0;
14411 +}
14412 +
14413 +int
14414 +gr_handle_rawio(const struct inode *inode)
14415 +{
14416 +       return 0;
14417 +}
14418 +
14419 +void
14420 +gr_acl_handle_psacct(struct task_struct *task, const long code)
14421 +{
14422 +       return;
14423 +}
14424 +
14425 +int
14426 +gr_handle_ptrace(struct task_struct *task, const long request)
14427 +{
14428 +       return 0;
14429 +}
14430 +
14431 +int
14432 +gr_handle_proc_ptrace(struct task_struct *task)
14433 +{
14434 +       return 0;
14435 +}
14436 +
14437 +void
14438 +gr_learn_resource(const struct task_struct *task,
14439 +                 const int res, const unsigned long wanted, const int gt)
14440 +{
14441 +       return;
14442 +}
14443 +
14444 +int
14445 +gr_set_acls(const int type)
14446 +{
14447 +       return 0;
14448 +}
14449 +
14450 +int
14451 +gr_check_hidden_task(const struct task_struct *tsk)
14452 +{
14453 +       return 0;
14454 +}
14455 +
14456 +int
14457 +gr_check_protected_task(const struct task_struct *task)
14458 +{
14459 +       return 0;
14460 +}
14461 +
14462 +void
14463 +gr_copy_label(struct task_struct *tsk)
14464 +{
14465 +       return;
14466 +}
14467 +
14468 +void
14469 +gr_set_pax_flags(struct task_struct *task)
14470 +{
14471 +       return;
14472 +}
14473 +
14474 +int
14475 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
14476 +{
14477 +       return 0;
14478 +}
14479 +
14480 +void
14481 +gr_handle_delete(const ino_t ino, const dev_t dev)
14482 +{
14483 +       return;
14484 +}
14485 +
14486 +void
14487 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
14488 +{
14489 +       return;
14490 +}
14491 +
14492 +void
14493 +gr_handle_crash(struct task_struct *task, const int sig)
14494 +{
14495 +       return;
14496 +}
14497 +
14498 +int
14499 +gr_check_crash_exec(const struct file *filp)
14500 +{
14501 +       return 0;
14502 +}
14503 +
14504 +int
14505 +gr_check_crash_uid(const uid_t uid)
14506 +{
14507 +       return 0;
14508 +}
14509 +
14510 +void
14511 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
14512 +                struct dentry *old_dentry,
14513 +                struct dentry *new_dentry,
14514 +                struct vfsmount *mnt, const __u8 replace)
14515 +{
14516 +       return;
14517 +}
14518 +
14519 +int
14520 +gr_search_socket(const int family, const int type, const int protocol)
14521 +{
14522 +       return 1;
14523 +}
14524 +
14525 +int
14526 +gr_search_connectbind(const int mode, const struct socket *sock,
14527 +                     const struct sockaddr_in *addr)
14528 +{
14529 +       return 1;
14530 +}
14531 +
14532 +int
14533 +gr_task_is_capable(struct task_struct *task, const int cap)
14534 +{
14535 +       return 1;
14536 +}
14537 +
14538 +int
14539 +gr_is_capable_nolog(const int cap)
14540 +{
14541 +       return 1;
14542 +}
14543 +
14544 +void
14545 +gr_handle_alertkill(struct task_struct *task)
14546 +{
14547 +       return;
14548 +}
14549 +
14550 +__u32
14551 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
14552 +{
14553 +       return 1;
14554 +}
14555 +
14556 +__u32
14557 +gr_acl_handle_hidden_file(const struct dentry * dentry,
14558 +                         const struct vfsmount * mnt)
14559 +{
14560 +       return 1;
14561 +}
14562 +
14563 +__u32
14564 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
14565 +                  const int fmode)
14566 +{
14567 +       return 1;
14568 +}
14569 +
14570 +__u32
14571 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
14572 +{
14573 +       return 1;
14574 +}
14575 +
14576 +__u32
14577 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
14578 +{
14579 +       return 1;
14580 +}
14581 +
14582 +int
14583 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
14584 +                  unsigned int *vm_flags)
14585 +{
14586 +       return 1;
14587 +}
14588 +
14589 +__u32
14590 +gr_acl_handle_truncate(const struct dentry * dentry,
14591 +                      const struct vfsmount * mnt)
14592 +{
14593 +       return 1;
14594 +}
14595 +
14596 +__u32
14597 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
14598 +{
14599 +       return 1;
14600 +}
14601 +
14602 +__u32
14603 +gr_acl_handle_access(const struct dentry * dentry,
14604 +                    const struct vfsmount * mnt, const int fmode)
14605 +{
14606 +       return 1;
14607 +}
14608 +
14609 +__u32
14610 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
14611 +                    mode_t mode)
14612 +{
14613 +       return 1;
14614 +}
14615 +
14616 +__u32
14617 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
14618 +                   mode_t mode)
14619 +{
14620 +       return 1;
14621 +}
14622 +
14623 +__u32
14624 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
14625 +{
14626 +       return 1;
14627 +}
14628 +
14629 +void
14630 +grsecurity_init(void)
14631 +{
14632 +       return;
14633 +}
14634 +
14635 +__u32
14636 +gr_acl_handle_mknod(const struct dentry * new_dentry,
14637 +                   const struct dentry * parent_dentry,
14638 +                   const struct vfsmount * parent_mnt,
14639 +                   const int mode)
14640 +{
14641 +       return 1;
14642 +}
14643 +
14644 +__u32
14645 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
14646 +                   const struct dentry * parent_dentry,
14647 +                   const struct vfsmount * parent_mnt)
14648 +{
14649 +       return 1;
14650 +}
14651 +
14652 +__u32
14653 +gr_acl_handle_symlink(const struct dentry * new_dentry,
14654 +                     const struct dentry * parent_dentry,
14655 +                     const struct vfsmount * parent_mnt, const char *from)
14656 +{
14657 +       return 1;
14658 +}
14659 +
14660 +__u32
14661 +gr_acl_handle_link(const struct dentry * new_dentry,
14662 +                  const struct dentry * parent_dentry,
14663 +                  const struct vfsmount * parent_mnt,
14664 +                  const struct dentry * old_dentry,
14665 +                  const struct vfsmount * old_mnt, const char *to)
14666 +{
14667 +       return 1;
14668 +}
14669 +
14670 +int
14671 +gr_acl_handle_rename(const struct dentry *new_dentry,
14672 +                    const struct dentry *parent_dentry,
14673 +                    const struct vfsmount *parent_mnt,
14674 +                    const struct dentry *old_dentry,
14675 +                    const struct inode *old_parent_inode,
14676 +                    const struct vfsmount *old_mnt, const char *newname)
14677 +{
14678 +       return 0;
14679 +}
14680 +
14681 +int
14682 +gr_acl_handle_filldir(const struct file *file, const char *name,
14683 +                     const int namelen, const ino_t ino)
14684 +{
14685 +       return 1;
14686 +}
14687 +
14688 +int
14689 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
14690 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
14691 +{
14692 +       return 1;
14693 +}
14694 +
14695 +int
14696 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
14697 +{
14698 +       return 1;
14699 +}
14700 +
14701 +int
14702 +gr_search_accept(const struct socket *sock)
14703 +{
14704 +       return 1;
14705 +}
14706 +
14707 +int
14708 +gr_search_listen(const struct socket *sock)
14709 +{
14710 +       return 1;
14711 +}
14712 +
14713 +int
14714 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
14715 +{
14716 +       return 1;
14717 +}
14718 +
14719 +__u32
14720 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
14721 +{
14722 +       return 1;
14723 +}
14724 +
14725 +__u32
14726 +gr_acl_handle_creat(const struct dentry * dentry,
14727 +                   const struct dentry * p_dentry,
14728 +                   const struct vfsmount * p_mnt, const int fmode,
14729 +                   const int imode)
14730 +{
14731 +       return 1;
14732 +}
14733 +
14734 +void
14735 +gr_acl_handle_exit(void)
14736 +{
14737 +       return;
14738 +}
14739 +
14740 +int
14741 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
14742 +{
14743 +       return 1;
14744 +}
14745 +
14746 +void
14747 +gr_set_role_label(const uid_t uid, const gid_t gid)
14748 +{
14749 +       return;
14750 +}
14751 +
14752 +int
14753 +gr_acl_handle_procpidmem(const struct task_struct *task)
14754 +{
14755 +       return 0;
14756 +}
14757 +
14758 +int
14759 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
14760 +{
14761 +       return 1;
14762 +}
14763 +
14764 +int
14765 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
14766 +{
14767 +       return 1;
14768 +}
14769 +
14770 +void
14771 +gr_set_kernel_label(struct task_struct *task)
14772 +{
14773 +       return;
14774 +}
14775 +
14776 +int
14777 +gr_check_user_change(int real, int effective, int fs)
14778 +{
14779 +       return 0;
14780 +}
14781 +
14782 +int
14783 +gr_check_group_change(int real, int effective, int fs)
14784 +{
14785 +       return 0;
14786 +}
14787 +
14788 +
14789 +EXPORT_SYMBOL(gr_task_is_capable);
14790 +EXPORT_SYMBOL(gr_learn_resource);
14791 +EXPORT_SYMBOL(gr_set_kernel_label);
14792 +#ifdef CONFIG_SECURITY
14793 +EXPORT_SYMBOL(gr_check_user_change);
14794 +EXPORT_SYMBOL(gr_check_group_change);
14795 +#endif
14796 diff -urNp linux-2.6.16.2/grsecurity/grsec_exec.c linux-2.6.16.2/grsecurity/grsec_exec.c
14797 --- linux-2.6.16.2/grsecurity/grsec_exec.c      1969-12-31 19:00:00.000000000 -0500
14798 +++ linux-2.6.16.2/grsecurity/grsec_exec.c      2006-04-09 21:23:54.000000000 -0400
14799 @@ -0,0 +1,88 @@
14800 +#include <linux/kernel.h>
14801 +#include <linux/sched.h>
14802 +#include <linux/file.h>
14803 +#include <linux/binfmts.h>
14804 +#include <linux/smp_lock.h>
14805 +#include <linux/fs.h>
14806 +#include <linux/types.h>
14807 +#include <linux/grdefs.h>
14808 +#include <linux/grinternal.h>
14809 +#include <linux/capability.h>
14810 +
14811 +#include <asm/uaccess.h>
14812 +
14813 +#ifdef CONFIG_GRKERNSEC_EXECLOG
14814 +static char gr_exec_arg_buf[132];
14815 +static DECLARE_MUTEX(gr_exec_arg_sem);
14816 +#endif
14817 +
14818 +int
14819 +gr_handle_nproc(void)
14820 +{
14821 +#ifdef CONFIG_GRKERNSEC_EXECVE
14822 +       if (grsec_enable_execve && current->user &&
14823 +           (atomic_read(&current->user->processes) >
14824 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
14825 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
14826 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
14827 +               return -EAGAIN;
14828 +       }
14829 +#endif
14830 +       return 0;
14831 +}
14832 +
14833 +void
14834 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
14835 +{
14836 +#ifdef CONFIG_GRKERNSEC_EXECLOG
14837 +       char *grarg = gr_exec_arg_buf;
14838 +       unsigned int i, x, execlen = 0;
14839 +       char c;
14840 +
14841 +       if (!((grsec_enable_execlog && grsec_enable_group &&
14842 +              in_group_p(grsec_audit_gid))
14843 +             || (grsec_enable_execlog && !grsec_enable_group)))
14844 +               return;
14845 +
14846 +       down(&gr_exec_arg_sem);
14847 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
14848 +
14849 +       if (unlikely(argv == NULL))
14850 +               goto log;
14851 +
14852 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
14853 +               const char __user *p;
14854 +               unsigned int len;
14855 +
14856 +               if (copy_from_user(&p, argv + i, sizeof(p)))
14857 +                       goto log;
14858 +               if (!p)
14859 +                       goto log;
14860 +               len = strnlen_user(p, 128 - execlen);
14861 +               if (len > 128 - execlen)
14862 +                       len = 128 - execlen;
14863 +               else if (len > 0)
14864 +                       len--;
14865 +               if (copy_from_user(grarg + execlen, p, len))
14866 +                       goto log;
14867 +
14868 +               /* rewrite unprintable characters */
14869 +               for (x = 0; x < len; x++) {
14870 +                       c = *(grarg + execlen + x);
14871 +                       if (c < 32 || c > 126)
14872 +                               *(grarg + execlen + x) = ' ';
14873 +               }
14874 +
14875 +               execlen += len;
14876 +               *(grarg + execlen) = ' ';
14877 +               *(grarg + execlen + 1) = '\0';
14878 +               execlen++;
14879 +       }
14880 +
14881 +      log:
14882 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
14883 +                       bprm->file->f_vfsmnt, grarg);
14884 +       up(&gr_exec_arg_sem);
14885 +#endif
14886 +       return;
14887 +}
14888 diff -urNp linux-2.6.16.2/grsecurity/grsec_fifo.c linux-2.6.16.2/grsecurity/grsec_fifo.c
14889 --- linux-2.6.16.2/grsecurity/grsec_fifo.c      1969-12-31 19:00:00.000000000 -0500
14890 +++ linux-2.6.16.2/grsecurity/grsec_fifo.c      2006-04-09 21:23:54.000000000 -0400
14891 @@ -0,0 +1,22 @@
14892 +#include <linux/kernel.h>
14893 +#include <linux/sched.h>
14894 +#include <linux/fs.h>
14895 +#include <linux/file.h>
14896 +#include <linux/grinternal.h>
14897 +
14898 +int
14899 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
14900 +              const struct dentry *dir, const int flag, const int acc_mode)
14901 +{
14902 +#ifdef CONFIG_GRKERNSEC_FIFO
14903 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
14904 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
14905 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
14906 +           (current->fsuid != dentry->d_inode->i_uid)) {
14907 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
14908 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
14909 +               return -EACCES;
14910 +       }
14911 +#endif
14912 +       return 0;
14913 +}
14914 diff -urNp linux-2.6.16.2/grsecurity/grsec_fork.c linux-2.6.16.2/grsecurity/grsec_fork.c
14915 --- linux-2.6.16.2/grsecurity/grsec_fork.c      1969-12-31 19:00:00.000000000 -0500
14916 +++ linux-2.6.16.2/grsecurity/grsec_fork.c      2006-04-09 21:23:54.000000000 -0400
14917 @@ -0,0 +1,14 @@
14918 +#include <linux/kernel.h>
14919 +#include <linux/sched.h>
14920 +#include <linux/grsecurity.h>
14921 +#include <linux/grinternal.h>
14922 +
14923 +void
14924 +gr_log_forkfail(const int retval)
14925 +{
14926 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
14927 +       if (grsec_enable_forkfail)
14928 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
14929 +#endif
14930 +       return;
14931 +}
14932 diff -urNp linux-2.6.16.2/grsecurity/grsec_init.c linux-2.6.16.2/grsecurity/grsec_init.c
14933 --- linux-2.6.16.2/grsecurity/grsec_init.c      1969-12-31 19:00:00.000000000 -0500
14934 +++ linux-2.6.16.2/grsecurity/grsec_init.c      2006-04-09 21:23:54.000000000 -0400
14935 @@ -0,0 +1,232 @@
14936 +#include <linux/kernel.h>
14937 +#include <linux/sched.h>
14938 +#include <linux/mm.h>
14939 +#include <linux/smp_lock.h>
14940 +#include <linux/gracl.h>
14941 +#include <linux/slab.h>
14942 +#include <linux/vmalloc.h>
14943 +#include <linux/percpu.h>
14944 +
14945 +int grsec_enable_shm;
14946 +int grsec_enable_link;
14947 +int grsec_enable_dmesg;
14948 +int grsec_enable_fifo;
14949 +int grsec_enable_execve;
14950 +int grsec_enable_execlog;
14951 +int grsec_enable_signal;
14952 +int grsec_enable_forkfail;
14953 +int grsec_enable_time;
14954 +int grsec_enable_audit_textrel;
14955 +int grsec_enable_group;
14956 +int grsec_audit_gid;
14957 +int grsec_enable_chdir;
14958 +int grsec_enable_audit_ipc;
14959 +int grsec_enable_mount;
14960 +int grsec_enable_chroot_findtask;
14961 +int grsec_enable_chroot_mount;
14962 +int grsec_enable_chroot_shmat;
14963 +int grsec_enable_chroot_fchdir;
14964 +int grsec_enable_chroot_double;
14965 +int grsec_enable_chroot_pivot;
14966 +int grsec_enable_chroot_chdir;
14967 +int grsec_enable_chroot_chmod;
14968 +int grsec_enable_chroot_mknod;
14969 +int grsec_enable_chroot_nice;
14970 +int grsec_enable_chroot_execlog;
14971 +int grsec_enable_chroot_caps;
14972 +int grsec_enable_chroot_sysctl;
14973 +int grsec_enable_chroot_unix;
14974 +int grsec_enable_tpe;
14975 +int grsec_tpe_gid;
14976 +int grsec_enable_tpe_all;
14977 +int grsec_enable_randpid;
14978 +int grsec_enable_socket_all;
14979 +int grsec_socket_all_gid;
14980 +int grsec_enable_socket_client;
14981 +int grsec_socket_client_gid;
14982 +int grsec_enable_socket_server;
14983 +int grsec_socket_server_gid;
14984 +int grsec_lock;
14985 +
14986 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
14987 +unsigned long grsec_alert_wtime = 0;
14988 +unsigned long grsec_alert_fyet = 0;
14989 +
14990 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
14991 +
14992 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
14993 +
14994 +char *gr_shared_page[4];
14995 +
14996 +char *gr_alert_log_fmt;
14997 +char *gr_audit_log_fmt;
14998 +char *gr_alert_log_buf;
14999 +char *gr_audit_log_buf;
15000 +
15001 +extern struct gr_arg *gr_usermode;
15002 +extern unsigned char *gr_system_salt;
15003 +extern unsigned char *gr_system_sum;
15004 +
15005 +void
15006 +grsecurity_init(void)
15007 +{
15008 +       int j;
15009 +       /* create the per-cpu shared pages */
15010 +
15011 +       preempt_disable();
15012 +       for (j = 0; j < 4; j++) {
15013 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
15014 +               if (gr_shared_page[j] == NULL) {
15015 +                       panic("Unable to allocate grsecurity shared page");
15016 +                       return;
15017 +               }
15018 +       }
15019 +       preempt_enable();
15020 +
15021 +       /* allocate log buffers */
15022 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
15023 +       if (!gr_alert_log_fmt) {
15024 +               panic("Unable to allocate grsecurity alert log format buffer");
15025 +               return;
15026 +       }
15027 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
15028 +       if (!gr_audit_log_fmt) {
15029 +               panic("Unable to allocate grsecurity audit log format buffer");
15030 +               return;
15031 +       }
15032 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
15033 +       if (!gr_alert_log_buf) {
15034 +               panic("Unable to allocate grsecurity alert log buffer");
15035 +               return;
15036 +       }
15037 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
15038 +       if (!gr_audit_log_buf) {
15039 +               panic("Unable to allocate grsecurity audit log buffer");
15040 +               return;
15041 +       }
15042 +
15043 +       /* allocate memory for authentication structure */
15044 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
15045 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
15046 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
15047 +
15048 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
15049 +               panic("Unable to allocate grsecurity authentication structure");
15050 +               return;
15051 +       }
15052 +
15053 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
15054 +#ifndef CONFIG_GRKERNSEC_SYSCTL
15055 +       grsec_lock = 1;
15056 +#endif
15057 +#ifdef CONFIG_GRKERNSEC_SHM
15058 +       grsec_enable_shm = 1;
15059 +#endif
15060 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
15061 +       grsec_enable_audit_textrel = 1;
15062 +#endif
15063 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
15064 +       grsec_enable_group = 1;
15065 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
15066 +#endif
15067 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
15068 +       grsec_enable_chdir = 1;
15069 +#endif
15070 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15071 +       grsec_enable_audit_ipc = 1;
15072 +#endif
15073 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15074 +       grsec_enable_mount = 1;
15075 +#endif
15076 +#ifdef CONFIG_GRKERNSEC_LINK
15077 +       grsec_enable_link = 1;
15078 +#endif
15079 +#ifdef CONFIG_GRKERNSEC_DMESG
15080 +       grsec_enable_dmesg = 1;
15081 +#endif
15082 +#ifdef CONFIG_GRKERNSEC_FIFO
15083 +       grsec_enable_fifo = 1;
15084 +#endif
15085 +#ifdef CONFIG_GRKERNSEC_EXECVE
15086 +       grsec_enable_execve = 1;
15087 +#endif
15088 +#ifdef CONFIG_GRKERNSEC_EXECLOG
15089 +       grsec_enable_execlog = 1;
15090 +#endif
15091 +#ifdef CONFIG_GRKERNSEC_SIGNAL
15092 +       grsec_enable_signal = 1;
15093 +#endif
15094 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
15095 +       grsec_enable_forkfail = 1;
15096 +#endif
15097 +#ifdef CONFIG_GRKERNSEC_TIME
15098 +       grsec_enable_time = 1;
15099 +#endif
15100 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
15101 +       grsec_enable_chroot_findtask = 1;
15102 +#endif
15103 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
15104 +       grsec_enable_chroot_unix = 1;
15105 +#endif
15106 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
15107 +       grsec_enable_chroot_mount = 1;
15108 +#endif
15109 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
15110 +       grsec_enable_chroot_fchdir = 1;
15111 +#endif
15112 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
15113 +       grsec_enable_chroot_shmat = 1;
15114 +#endif
15115 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
15116 +       grsec_enable_chroot_double = 1;
15117 +#endif
15118 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
15119 +       grsec_enable_chroot_pivot = 1;
15120 +#endif
15121 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
15122 +       grsec_enable_chroot_chdir = 1;
15123 +#endif
15124 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
15125 +       grsec_enable_chroot_chmod = 1;
15126 +#endif
15127 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
15128 +       grsec_enable_chroot_mknod = 1;
15129 +#endif
15130 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
15131 +       grsec_enable_chroot_nice = 1;
15132 +#endif
15133 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
15134 +       grsec_enable_chroot_execlog = 1;
15135 +#endif
15136 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
15137 +       grsec_enable_chroot_caps = 1;
15138 +#endif
15139 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
15140 +       grsec_enable_chroot_sysctl = 1;
15141 +#endif
15142 +#ifdef CONFIG_GRKERNSEC_TPE
15143 +       grsec_enable_tpe = 1;
15144 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
15145 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
15146 +       grsec_enable_tpe_all = 1;
15147 +#endif
15148 +#endif
15149 +#ifdef CONFIG_GRKERNSEC_RANDPID
15150 +       grsec_enable_randpid = 1;
15151 +#endif
15152 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
15153 +       grsec_enable_socket_all = 1;
15154 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
15155 +#endif
15156 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
15157 +       grsec_enable_socket_client = 1;
15158 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
15159 +#endif
15160 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
15161 +       grsec_enable_socket_server = 1;
15162 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
15163 +#endif
15164 +#endif
15165 +
15166 +       return;
15167 +}
15168 diff -urNp linux-2.6.16.2/grsecurity/grsec_ipc.c linux-2.6.16.2/grsecurity/grsec_ipc.c
15169 --- linux-2.6.16.2/grsecurity/grsec_ipc.c       1969-12-31 19:00:00.000000000 -0500
15170 +++ linux-2.6.16.2/grsecurity/grsec_ipc.c       2006-04-09 21:23:54.000000000 -0400
15171 @@ -0,0 +1,81 @@
15172 +#include <linux/kernel.h>
15173 +#include <linux/sched.h>
15174 +#include <linux/types.h>
15175 +#include <linux/ipc.h>
15176 +#include <linux/grsecurity.h>
15177 +#include <linux/grinternal.h>
15178 +
15179 +void
15180 +gr_log_msgget(const int ret, const int msgflg)
15181 +{
15182 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15183 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15184 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15185 +                                         !grsec_enable_group)) && (ret >= 0)
15186 +           && (msgflg & IPC_CREAT))
15187 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
15188 +#endif
15189 +       return;
15190 +}
15191 +
15192 +void
15193 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
15194 +{
15195 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15196 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15197 +            grsec_enable_audit_ipc) ||
15198 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15199 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
15200 +#endif
15201 +       return;
15202 +}
15203 +
15204 +void
15205 +gr_log_semget(const int err, const int semflg)
15206 +{
15207 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15208 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15209 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15210 +                                         !grsec_enable_group)) && (err >= 0)
15211 +           && (semflg & IPC_CREAT))
15212 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
15213 +#endif
15214 +       return;
15215 +}
15216 +
15217 +void
15218 +gr_log_semrm(const uid_t uid, const uid_t cuid)
15219 +{
15220 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15221 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15222 +            grsec_enable_audit_ipc) ||
15223 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15224 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
15225 +#endif
15226 +       return;
15227 +}
15228 +
15229 +void
15230 +gr_log_shmget(const int err, const int shmflg, const size_t size)
15231 +{
15232 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15233 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15234 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
15235 +                                         !grsec_enable_group)) && (err >= 0)
15236 +           && (shmflg & IPC_CREAT))
15237 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
15238 +#endif
15239 +       return;
15240 +}
15241 +
15242 +void
15243 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
15244 +{
15245 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
15246 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
15247 +            grsec_enable_audit_ipc) ||
15248 +           (grsec_enable_audit_ipc && !grsec_enable_group))
15249 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
15250 +#endif
15251 +       return;
15252 +}
15253 diff -urNp linux-2.6.16.2/grsecurity/grsec_link.c linux-2.6.16.2/grsecurity/grsec_link.c
15254 --- linux-2.6.16.2/grsecurity/grsec_link.c      1969-12-31 19:00:00.000000000 -0500
15255 +++ linux-2.6.16.2/grsecurity/grsec_link.c      2006-04-09 21:23:54.000000000 -0400
15256 @@ -0,0 +1,39 @@
15257 +#include <linux/kernel.h>
15258 +#include <linux/sched.h>
15259 +#include <linux/fs.h>
15260 +#include <linux/file.h>
15261 +#include <linux/grinternal.h>
15262 +
15263 +int
15264 +gr_handle_follow_link(const struct inode *parent,
15265 +                     const struct inode *inode,
15266 +                     const struct dentry *dentry, const struct vfsmount *mnt)
15267 +{
15268 +#ifdef CONFIG_GRKERNSEC_LINK
15269 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
15270 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
15271 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
15272 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
15273 +               return -EACCES;
15274 +       }
15275 +#endif
15276 +       return 0;
15277 +}
15278 +
15279 +int
15280 +gr_handle_hardlink(const struct dentry *dentry,
15281 +                  const struct vfsmount *mnt,
15282 +                  struct inode *inode, const int mode, const char *to)
15283 +{
15284 +#ifdef CONFIG_GRKERNSEC_LINK
15285 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
15286 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
15287 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
15288 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
15289 +           !capable(CAP_FOWNER) && current->uid) {
15290 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
15291 +               return -EPERM;
15292 +       }
15293 +#endif
15294 +       return 0;
15295 +}
15296 diff -urNp linux-2.6.16.2/grsecurity/grsec_log.c linux-2.6.16.2/grsecurity/grsec_log.c
15297 --- linux-2.6.16.2/grsecurity/grsec_log.c       1969-12-31 19:00:00.000000000 -0500
15298 +++ linux-2.6.16.2/grsecurity/grsec_log.c       2006-04-09 21:23:54.000000000 -0400
15299 @@ -0,0 +1,265 @@
15300 +#include <linux/kernel.h>
15301 +#include <linux/sched.h>
15302 +#include <linux/file.h>
15303 +#include <linux/tty.h>
15304 +#include <linux/fs.h>
15305 +#include <linux/grinternal.h>
15306 +
15307 +#define BEGIN_LOCKS(x) \
15308 +       read_lock(&tasklist_lock); \
15309 +       read_lock(&grsec_exec_file_lock); \
15310 +       if (x != GR_DO_AUDIT) \
15311 +               spin_lock(&grsec_alert_lock); \
15312 +       else \
15313 +               spin_lock(&grsec_audit_lock)
15314 +
15315 +#define END_LOCKS(x) \
15316 +       if (x != GR_DO_AUDIT) \
15317 +               spin_unlock(&grsec_alert_lock); \
15318 +       else \
15319 +               spin_unlock(&grsec_audit_lock); \
15320 +       read_unlock(&grsec_exec_file_lock); \
15321 +       read_unlock(&tasklist_lock); \
15322 +       if (x == GR_DONT_AUDIT) \
15323 +               gr_handle_alertkill(current)
15324 +
15325 +enum {
15326 +       FLOODING,
15327 +       NO_FLOODING
15328 +};
15329 +
15330 +extern char *gr_alert_log_fmt;
15331 +extern char *gr_audit_log_fmt;
15332 +extern char *gr_alert_log_buf;
15333 +extern char *gr_audit_log_buf;
15334 +
15335 +static int gr_log_start(int audit)
15336 +{
15337 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
15338 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
15339 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15340 +
15341 +       if (audit == GR_DO_AUDIT)
15342 +               goto set_fmt;
15343 +
15344 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
15345 +               grsec_alert_wtime = jiffies;
15346 +               grsec_alert_fyet = 0;
15347 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
15348 +               grsec_alert_fyet++;
15349 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
15350 +               grsec_alert_wtime = jiffies;
15351 +               grsec_alert_fyet++;
15352 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
15353 +               return FLOODING;
15354 +       } else return FLOODING;
15355 +
15356 +set_fmt:
15357 +       memset(buf, 0, PAGE_SIZE);
15358 +       if (current->signal->curr_ip && gr_acl_is_enabled()) {
15359 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
15360 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
15361 +       } else if (current->signal->curr_ip) {
15362 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
15363 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
15364 +       } else if (gr_acl_is_enabled()) {
15365 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
15366 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
15367 +       } else {
15368 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
15369 +               strcpy(buf, fmt);
15370 +       }
15371 +
15372 +       return NO_FLOODING;
15373 +}
15374 +
15375 +static void gr_log_middle(int audit, const char *msg, va_list ap)
15376 +{
15377 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15378 +       unsigned int len = strlen(buf);
15379 +
15380 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
15381 +
15382 +       return;
15383 +}
15384 +
15385 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
15386 +{
15387 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15388 +       unsigned int len = strlen(buf);
15389 +       va_list ap;
15390 +
15391 +       va_start(ap, msg);
15392 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
15393 +       va_end(ap);
15394 +
15395 +       return;
15396 +}
15397 +
15398 +static void gr_log_end(int audit)
15399 +{
15400 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
15401 +       unsigned int len = strlen(buf);
15402 +
15403 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
15404 +       printk("%s\n", buf);
15405 +
15406 +       return;
15407 +}
15408 +
15409 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
15410 +{
15411 +       int logtype;
15412 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
15413 +       char *str1, *str2, *str3;
15414 +       int num1, num2;
15415 +       unsigned long ulong1, ulong2;
15416 +       struct dentry *dentry;
15417 +       struct vfsmount *mnt;
15418 +       struct file *file;
15419 +       struct task_struct *task;
15420 +       va_list ap;
15421 +
15422 +       BEGIN_LOCKS(audit);
15423 +       logtype = gr_log_start(audit);
15424 +       if (logtype == FLOODING) {
15425 +               END_LOCKS(audit);
15426 +               return;
15427 +       }
15428 +       va_start(ap, argtypes);
15429 +       switch (argtypes) {
15430 +       case GR_TTYSNIFF:
15431 +               task = va_arg(ap, struct task_struct *);
15432 +               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);
15433 +               break;
15434 +       case GR_RBAC:
15435 +               dentry = va_arg(ap, struct dentry *);
15436 +               mnt = va_arg(ap, struct vfsmount *);
15437 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
15438 +               break;
15439 +       case GR_RBAC_STR:
15440 +               dentry = va_arg(ap, struct dentry *);
15441 +               mnt = va_arg(ap, struct vfsmount *);
15442 +               str1 = va_arg(ap, char *);
15443 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
15444 +               break;
15445 +       case GR_STR_RBAC:
15446 +               str1 = va_arg(ap, char *);
15447 +               dentry = va_arg(ap, struct dentry *);
15448 +               mnt = va_arg(ap, struct vfsmount *);
15449 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
15450 +               break;
15451 +       case GR_RBAC_MODE2:
15452 +               dentry = va_arg(ap, struct dentry *);
15453 +               mnt = va_arg(ap, struct vfsmount *);
15454 +               str1 = va_arg(ap, char *);
15455 +               str2 = va_arg(ap, char *);
15456 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
15457 +               break;
15458 +       case GR_RBAC_MODE3:
15459 +               dentry = va_arg(ap, struct dentry *);
15460 +               mnt = va_arg(ap, struct vfsmount *);
15461 +               str1 = va_arg(ap, char *);
15462 +               str2 = va_arg(ap, char *);
15463 +               str3 = va_arg(ap, char *);
15464 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
15465 +               break;
15466 +       case GR_FILENAME:
15467 +               dentry = va_arg(ap, struct dentry *);
15468 +               mnt = va_arg(ap, struct vfsmount *);
15469 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
15470 +               break;
15471 +       case GR_STR_FILENAME:
15472 +               str1 = va_arg(ap, char *);
15473 +               dentry = va_arg(ap, struct dentry *);
15474 +               mnt = va_arg(ap, struct vfsmount *);
15475 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
15476 +               break;
15477 +       case GR_FILENAME_STR:
15478 +               dentry = va_arg(ap, struct dentry *);
15479 +               mnt = va_arg(ap, struct vfsmount *);
15480 +               str1 = va_arg(ap, char *);
15481 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
15482 +               break;
15483 +       case GR_FILENAME_TWO_INT:
15484 +               dentry = va_arg(ap, struct dentry *);
15485 +               mnt = va_arg(ap, struct vfsmount *);
15486 +               num1 = va_arg(ap, int);
15487 +               num2 = va_arg(ap, int);
15488 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
15489 +               break;
15490 +       case GR_FILENAME_TWO_INT_STR:
15491 +               dentry = va_arg(ap, struct dentry *);
15492 +               mnt = va_arg(ap, struct vfsmount *);
15493 +               num1 = va_arg(ap, int);
15494 +               num2 = va_arg(ap, int);
15495 +               str1 = va_arg(ap, char *);
15496 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
15497 +               break;
15498 +       case GR_TEXTREL:
15499 +               file = va_arg(ap, struct file *);
15500 +               ulong1 = va_arg(ap, unsigned long);
15501 +               ulong2 = va_arg(ap, unsigned long);
15502 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
15503 +               break;
15504 +       case GR_PTRACE:
15505 +               task = va_arg(ap, struct task_struct *);
15506 +               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);
15507 +               break;
15508 +       case GR_RESOURCE:
15509 +               task = va_arg(ap, struct task_struct *);
15510 +               ulong1 = va_arg(ap, unsigned long);
15511 +               str1 = va_arg(ap, char *);
15512 +               ulong2 = va_arg(ap, unsigned long);
15513 +               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);
15514 +               break;
15515 +       case GR_CAP:
15516 +               task = va_arg(ap, struct task_struct *);
15517 +               str1 = va_arg(ap, char *);
15518 +               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);
15519 +               break;
15520 +       case GR_SIG:
15521 +               task = va_arg(ap, struct task_struct *);
15522 +               num1 = va_arg(ap, int);
15523 +               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);
15524 +               break;
15525 +       case GR_CRASH1:
15526 +               task = va_arg(ap, struct task_struct *);
15527 +               ulong1 = va_arg(ap, unsigned long);
15528 +               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);
15529 +               break;
15530 +       case GR_CRASH2:
15531 +               task = va_arg(ap, struct task_struct *);
15532 +               ulong1 = va_arg(ap, unsigned long);
15533 +               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);
15534 +               break;
15535 +       case GR_PSACCT:
15536 +               {
15537 +                       unsigned int wday, cday;
15538 +                       __u8 whr, chr;
15539 +                       __u8 wmin, cmin;
15540 +                       __u8 wsec, csec;
15541 +                       char cur_tty[64] = { 0 };
15542 +                       char parent_tty[64] = { 0 };
15543 +
15544 +                       task = va_arg(ap, struct task_struct *);
15545 +                       wday = va_arg(ap, unsigned int);
15546 +                       cday = va_arg(ap, unsigned int);
15547 +                       whr = va_arg(ap, int);
15548 +                       chr = va_arg(ap, int);
15549 +                       wmin = va_arg(ap, int);
15550 +                       cmin = va_arg(ap, int);
15551 +                       wsec = va_arg(ap, int);
15552 +                       csec = va_arg(ap, int);
15553 +                       ulong1 = va_arg(ap, unsigned long);
15554 +
15555 +                       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);
15556 +               }
15557 +               break;
15558 +       default:
15559 +               gr_log_middle(audit, msg, ap);
15560 +       }
15561 +       va_end(ap);
15562 +       gr_log_end(audit);
15563 +       END_LOCKS(audit);
15564 +}
15565 diff -urNp linux-2.6.16.2/grsecurity/grsec_mem.c linux-2.6.16.2/grsecurity/grsec_mem.c
15566 --- linux-2.6.16.2/grsecurity/grsec_mem.c       1969-12-31 19:00:00.000000000 -0500
15567 +++ linux-2.6.16.2/grsecurity/grsec_mem.c       2006-04-09 21:23:54.000000000 -0400
15568 @@ -0,0 +1,71 @@
15569 +#include <linux/kernel.h>
15570 +#include <linux/sched.h>
15571 +#include <linux/mm.h>
15572 +#include <linux/mman.h>
15573 +#include <linux/grinternal.h>
15574 +
15575 +void
15576 +gr_handle_ioperm(void)
15577 +{
15578 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
15579 +       return;
15580 +}
15581 +
15582 +void
15583 +gr_handle_iopl(void)
15584 +{
15585 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
15586 +       return;
15587 +}
15588 +
15589 +void
15590 +gr_handle_mem_write(void)
15591 +{
15592 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
15593 +       return;
15594 +}
15595 +
15596 +void
15597 +gr_handle_kmem_write(void)
15598 +{
15599 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
15600 +       return;
15601 +}
15602 +
15603 +void
15604 +gr_handle_open_port(void)
15605 +{
15606 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
15607 +       return;
15608 +}
15609 +
15610 +int
15611 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
15612 +{
15613 +       unsigned long start, end;
15614 +
15615 +       start = offset;
15616 +       end = start + vma->vm_end - vma->vm_start;
15617 +
15618 +       if (start > end) {
15619 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
15620 +               return -EPERM;
15621 +       }
15622 +
15623 +       /* allowed ranges : ISA I/O BIOS */
15624 +       if ((start >= __pa(high_memory))
15625 +#ifdef CONFIG_X86
15626 +           || (start >= 0x000a0000 && end <= 0x00100000)
15627 +           || (start >= 0x00000000 && end <= 0x00001000)
15628 +#endif
15629 +       )
15630 +               return 0;
15631 +
15632 +       if (vma->vm_flags & VM_WRITE) {
15633 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
15634 +               return -EPERM;
15635 +       } else
15636 +               vma->vm_flags &= ~VM_MAYWRITE;
15637 +
15638 +       return 0;
15639 +}
15640 diff -urNp linux-2.6.16.2/grsecurity/grsec_mount.c linux-2.6.16.2/grsecurity/grsec_mount.c
15641 --- linux-2.6.16.2/grsecurity/grsec_mount.c     1969-12-31 19:00:00.000000000 -0500
15642 +++ linux-2.6.16.2/grsecurity/grsec_mount.c     2006-04-09 21:23:54.000000000 -0400
15643 @@ -0,0 +1,34 @@
15644 +#include <linux/kernel.h>
15645 +#include <linux/sched.h>
15646 +#include <linux/grsecurity.h>
15647 +#include <linux/grinternal.h>
15648 +
15649 +void
15650 +gr_log_remount(const char *devname, const int retval)
15651 +{
15652 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15653 +       if (grsec_enable_mount && (retval >= 0))
15654 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
15655 +#endif
15656 +       return;
15657 +}
15658 +
15659 +void
15660 +gr_log_unmount(const char *devname, const int retval)
15661 +{
15662 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15663 +       if (grsec_enable_mount && (retval >= 0))
15664 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
15665 +#endif
15666 +       return;
15667 +}
15668 +
15669 +void
15670 +gr_log_mount(const char *from, const char *to, const int retval)
15671 +{
15672 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
15673 +       if (grsec_enable_mount && (retval >= 0))
15674 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
15675 +#endif
15676 +       return;
15677 +}
15678 diff -urNp linux-2.6.16.2/grsecurity/grsec_rand.c linux-2.6.16.2/grsecurity/grsec_rand.c
15679 --- linux-2.6.16.2/grsecurity/grsec_rand.c      1969-12-31 19:00:00.000000000 -0500
15680 +++ linux-2.6.16.2/grsecurity/grsec_rand.c      2006-04-09 21:23:54.000000000 -0400
15681 @@ -0,0 +1,26 @@
15682 +#include <linux/kernel.h>
15683 +#include <linux/sched.h>
15684 +#include <linux/smp_lock.h>
15685 +#include <linux/grsecurity.h>
15686 +#include <linux/grinternal.h>
15687 +
15688 +extern int pid_max;
15689 +
15690 +int
15691 +gr_random_pid(void)
15692 +{
15693 +#ifdef CONFIG_GRKERNSEC_RANDPID
15694 +       int pid;
15695 +
15696 +       if (grsec_enable_randpid && current->fs->root) {
15697 +               /* return a pid in the range 1 ... pid_max - 1
15698 +                  optimize this so we don't have to do a real division
15699 +               */
15700 +               pid = 1 + (get_random_long() % pid_max);
15701 +               if (pid == pid_max)
15702 +                       pid = pid_max - 1;
15703 +               return pid;
15704 +       }
15705 +#endif
15706 +       return 0;
15707 +}
15708 diff -urNp linux-2.6.16.2/grsecurity/grsec_sig.c linux-2.6.16.2/grsecurity/grsec_sig.c
15709 --- linux-2.6.16.2/grsecurity/grsec_sig.c       1969-12-31 19:00:00.000000000 -0500
15710 +++ linux-2.6.16.2/grsecurity/grsec_sig.c       2006-04-09 21:23:54.000000000 -0400
15711 @@ -0,0 +1,59 @@
15712 +#include <linux/kernel.h>
15713 +#include <linux/sched.h>
15714 +#include <linux/grsecurity.h>
15715 +#include <linux/grinternal.h>
15716 +
15717 +void
15718 +gr_log_signal(const int sig, const struct task_struct *t)
15719 +{
15720 +#ifdef CONFIG_GRKERNSEC_SIGNAL
15721 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
15722 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
15723 +               if (t->pid == current->pid) {
15724 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
15725 +               } else {
15726 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
15727 +               }
15728 +       }
15729 +#endif
15730 +       return;
15731 +}
15732 +
15733 +int
15734 +gr_handle_signal(const struct task_struct *p, const int sig)
15735 +{
15736 +#ifdef CONFIG_GRKERNSEC
15737 +       if (current->pid > 1 && gr_check_protected_task(p)) {
15738 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
15739 +               return -EPERM;
15740 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
15741 +               return -EPERM;
15742 +       }
15743 +#endif
15744 +       return 0;
15745 +}
15746 +
15747 +void gr_handle_brute_attach(struct task_struct *p)
15748 +{
15749 +#ifdef CONFIG_GRKERNSEC_BRUTE
15750 +       read_lock(&tasklist_lock);
15751 +       read_lock(&grsec_exec_file_lock);
15752 +       if (p->parent && p->parent->exec_file == p->exec_file)
15753 +               p->parent->brute = 1;
15754 +       read_unlock(&grsec_exec_file_lock);
15755 +       read_unlock(&tasklist_lock);
15756 +#endif
15757 +       return;
15758 +}
15759 +
15760 +void gr_handle_brute_check(void)
15761 +{
15762 +#ifdef CONFIG_GRKERNSEC_BRUTE
15763 +       if (current->brute) {
15764 +               set_current_state(TASK_UNINTERRUPTIBLE);
15765 +               schedule_timeout(30 * HZ);
15766 +       }
15767 +#endif
15768 +       return;
15769 +}
15770 +
15771 diff -urNp linux-2.6.16.2/grsecurity/grsec_sock.c linux-2.6.16.2/grsecurity/grsec_sock.c
15772 --- linux-2.6.16.2/grsecurity/grsec_sock.c      1969-12-31 19:00:00.000000000 -0500
15773 +++ linux-2.6.16.2/grsecurity/grsec_sock.c      2006-04-09 21:23:54.000000000 -0400
15774 @@ -0,0 +1,263 @@
15775 +#include <linux/kernel.h>
15776 +#include <linux/module.h>
15777 +#include <linux/sched.h>
15778 +#include <linux/file.h>
15779 +#include <linux/net.h>
15780 +#include <linux/in.h>
15781 +#include <linux/ip.h>
15782 +#include <net/sock.h>
15783 +#include <net/inet_sock.h>
15784 +#include <linux/grsecurity.h>
15785 +#include <linux/grinternal.h>
15786 +#include <linux/gracl.h>
15787 +
15788 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
15789 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
15790 +EXPORT_SYMBOL(udp_v4_lookup);
15791 +#endif
15792 +
15793 +EXPORT_SYMBOL(gr_cap_rtnetlink);
15794 +
15795 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
15796 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
15797 +
15798 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
15799 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
15800 +
15801 +#ifdef CONFIG_UNIX_MODULE
15802 +EXPORT_SYMBOL(gr_acl_handle_unix);
15803 +EXPORT_SYMBOL(gr_acl_handle_mknod);
15804 +EXPORT_SYMBOL(gr_handle_chroot_unix);
15805 +EXPORT_SYMBOL(gr_handle_create);
15806 +#endif
15807 +
15808 +#ifdef CONFIG_GRKERNSEC
15809 +#define gr_conn_table_size 32749
15810 +struct conn_table_entry {
15811 +       struct conn_table_entry *next;
15812 +       struct signal_struct *sig;
15813 +};
15814 +
15815 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
15816 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
15817 +
15818 +extern const char * gr_socktype_to_name(unsigned char type);
15819 +extern const char * gr_proto_to_name(unsigned char proto);
15820 +
15821 +static __inline__ int 
15822 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
15823 +{
15824 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
15825 +}
15826 +
15827 +static __inline__ int
15828 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, 
15829 +          __u16 sport, __u16 dport)
15830 +{
15831 +       if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
15832 +                    sig->gr_sport == sport && sig->gr_dport == dport))
15833 +               return 1;
15834 +       else
15835 +               return 0;
15836 +}
15837 +
15838 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
15839 +{
15840 +       struct conn_table_entry **match;
15841 +       unsigned int index;
15842 +
15843 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
15844 +                         sig->gr_sport, sig->gr_dport, 
15845 +                         gr_conn_table_size);
15846 +
15847 +       newent->sig = sig;
15848 +       
15849 +       match = &gr_conn_table[index];
15850 +       newent->next = *match;
15851 +       *match = newent;
15852 +
15853 +       return;
15854 +}
15855 +
15856 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
15857 +{
15858 +       struct conn_table_entry *match, *last = NULL;
15859 +       unsigned int index;
15860 +
15861 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
15862 +                         sig->gr_sport, sig->gr_dport, 
15863 +                         gr_conn_table_size);
15864 +
15865 +       match = gr_conn_table[index];
15866 +       while (match && !conn_match(match->sig, 
15867 +               sig->gr_saddr, sig->gr_daddr, sig->gr_sport, 
15868 +               sig->gr_dport)) {
15869 +               last = match;
15870 +               match = match->next;
15871 +       }
15872 +
15873 +       if (match) {
15874 +               if (last)
15875 +                       last->next = match->next;
15876 +               else
15877 +                       gr_conn_table[index] = NULL;
15878 +               kfree(match);
15879 +       }
15880 +
15881 +       return;
15882 +}
15883 +
15884 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
15885 +                                            __u16 sport, __u16 dport)
15886 +{
15887 +       struct conn_table_entry *match;
15888 +       unsigned int index;
15889 +
15890 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
15891 +
15892 +       match = gr_conn_table[index];
15893 +       while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
15894 +               match = match->next;
15895 +
15896 +       if (match)
15897 +               return match->sig;
15898 +       else
15899 +               return NULL;
15900 +}
15901 +
15902 +#endif
15903 +
15904 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
15905 +{
15906 +#ifdef CONFIG_GRKERNSEC
15907 +       struct signal_struct *sig = task->signal;
15908 +       struct conn_table_entry *newent;
15909 +
15910 +       newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
15911 +       if (newent == NULL)
15912 +               return;
15913 +       
15914 +       spin_lock(&gr_conn_table_lock);
15915 +       gr_del_task_from_ip_table_nolock(sig);
15916 +       sig->gr_saddr = inet->rcv_saddr;
15917 +       sig->gr_daddr = inet->daddr;
15918 +       sig->gr_sport = inet->sport;
15919 +       sig->gr_dport = inet->dport;
15920 +       gr_add_to_task_ip_table_nolock(sig, newent);
15921 +       spin_unlock(&gr_conn_table_lock);
15922 +#endif
15923 +       return;
15924 +}
15925 +
15926 +void gr_del_task_from_ip_table(struct task_struct *task)
15927 +{
15928 +#ifdef CONFIG_GRKERNSEC
15929 +       spin_lock(&gr_conn_table_lock);
15930 +       gr_del_task_from_ip_table_nolock(task->signal);
15931 +       spin_unlock(&gr_conn_table_lock);
15932 +#endif
15933 +       return;
15934 +}
15935 +
15936 +void
15937 +gr_attach_curr_ip(const struct sock *sk)
15938 +{
15939 +#ifdef CONFIG_GRKERNSEC
15940 +       struct signal_struct *p, *set;
15941 +       const struct inet_sock *inet = inet_sk(sk);     
15942 +
15943 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
15944 +               return;
15945 +
15946 +       set = current->signal;
15947 +
15948 +       spin_lock(&gr_conn_table_lock);
15949 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
15950 +                                   inet->dport, inet->sport);
15951 +       if (unlikely(p != NULL)) {
15952 +               set->curr_ip = p->curr_ip;
15953 +               set->used_accept = 1;
15954 +               gr_del_task_from_ip_table_nolock(p);
15955 +               spin_unlock(&gr_conn_table_lock);
15956 +               return;
15957 +       }
15958 +       spin_unlock(&gr_conn_table_lock);
15959 +
15960 +       set->curr_ip = inet->daddr;
15961 +       set->used_accept = 1;
15962 +#endif
15963 +       return;
15964 +}
15965 +
15966 +int
15967 +gr_handle_sock_all(const int family, const int type, const int protocol)
15968 +{
15969 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
15970 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
15971 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
15972 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
15973 +               return -EACCES;
15974 +       }
15975 +#endif
15976 +       return 0;
15977 +}
15978 +
15979 +int
15980 +gr_handle_sock_server(const struct sockaddr *sck)
15981 +{
15982 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
15983 +       if (grsec_enable_socket_server &&
15984 +           in_group_p(grsec_socket_server_gid) &&
15985 +           sck && (sck->sa_family != AF_UNIX) &&
15986 +           (sck->sa_family != AF_LOCAL)) {
15987 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
15988 +               return -EACCES;
15989 +       }
15990 +#endif
15991 +       return 0;
15992 +}
15993 +
15994 +int
15995 +gr_handle_sock_server_other(const struct sock *sck)
15996 +{
15997 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
15998 +       if (grsec_enable_socket_server &&
15999 +           in_group_p(grsec_socket_server_gid) &&
16000 +           sck && (sck->sk_family != AF_UNIX) &&
16001 +           (sck->sk_family != AF_LOCAL)) {
16002 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
16003 +               return -EACCES;
16004 +       }
16005 +#endif
16006 +       return 0;
16007 +}
16008 +
16009 +int
16010 +gr_handle_sock_client(const struct sockaddr *sck)
16011 +{
16012 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
16013 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
16014 +           sck && (sck->sa_family != AF_UNIX) &&
16015 +           (sck->sa_family != AF_LOCAL)) {
16016 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
16017 +               return -EACCES;
16018 +       }
16019 +#endif
16020 +       return 0;
16021 +}
16022 +
16023 +__u32
16024 +gr_cap_rtnetlink(void)
16025 +{
16026 +#ifdef CONFIG_GRKERNSEC
16027 +       if (!gr_acl_is_enabled())
16028 +               return current->cap_effective;
16029 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
16030 +                gr_task_is_capable(current, CAP_NET_ADMIN))
16031 +               return current->cap_effective;
16032 +       else
16033 +               return 0;
16034 +#else
16035 +       return current->cap_effective;
16036 +#endif
16037 +}
16038 diff -urNp linux-2.6.16.2/grsecurity/grsec_sysctl.c linux-2.6.16.2/grsecurity/grsec_sysctl.c
16039 --- linux-2.6.16.2/grsecurity/grsec_sysctl.c    1969-12-31 19:00:00.000000000 -0500
16040 +++ linux-2.6.16.2/grsecurity/grsec_sysctl.c    2006-04-09 21:23:54.000000000 -0400
16041 @@ -0,0 +1,456 @@
16042 +#include <linux/kernel.h>
16043 +#include <linux/sched.h>
16044 +#include <linux/sysctl.h>
16045 +#include <linux/grsecurity.h>
16046 +#include <linux/grinternal.h>
16047 +
16048 +#ifdef CONFIG_GRKERNSEC_MODSTOP
16049 +int grsec_modstop;
16050 +#endif
16051 +
16052 +int
16053 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
16054 +{
16055 +#ifdef CONFIG_GRKERNSEC_SYSCTL
16056 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
16057 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
16058 +               return -EACCES;
16059 +       }
16060 +#endif
16061 +#ifdef CONFIG_GRKERNSEC_MODSTOP
16062 +       if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
16063 +           grsec_modstop && (op & 002)) {
16064 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
16065 +               return -EACCES;
16066 +       }
16067 +#endif
16068 +       return 0;
16069 +}
16070 +
16071 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
16072 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
16073 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
16074 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
16075 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
16076 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
16077 +GS_RANDPID, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
16078 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, 
16079 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
16080 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP};
16081 +
16082 +
16083 +ctl_table grsecurity_table[] = {
16084 +#ifdef CONFIG_GRKERNSEC_SYSCTL
16085 +#ifdef CONFIG_GRKERNSEC_LINK
16086 +       {
16087 +               .ctl_name       = GS_LINK,
16088 +               .procname       = "linking_restrictions",
16089 +               .data           = &grsec_enable_link,
16090 +               .maxlen         = sizeof(int),
16091 +               .mode           = 0600,
16092 +               .proc_handler   = &proc_dointvec,
16093 +       },
16094 +#endif
16095 +#ifdef CONFIG_GRKERNSEC_FIFO
16096 +       {
16097 +               .ctl_name       = GS_FIFO,
16098 +               .procname       = "fifo_restrictions",
16099 +               .data           = &grsec_enable_fifo,
16100 +               .maxlen         = sizeof(int),
16101 +               .mode           = 0600,
16102 +               .proc_handler   = &proc_dointvec,
16103 +       },
16104 +#endif
16105 +#ifdef CONFIG_GRKERNSEC_EXECVE
16106 +       {
16107 +               .ctl_name       = GS_EXECVE,
16108 +               .procname       = "execve_limiting",
16109 +               .data           = &grsec_enable_execve,
16110 +               .maxlen         = sizeof(int),
16111 +               .mode           = 0600,
16112 +               .proc_handler   = &proc_dointvec,
16113 +       },
16114 +#endif
16115 +#ifdef CONFIG_GRKERNSEC_EXECLOG
16116 +       {
16117 +               .ctl_name       = GS_EXECLOG,
16118 +               .procname       = "exec_logging",
16119 +               .data           = &grsec_enable_execlog,
16120 +               .maxlen         = sizeof(int),
16121 +               .mode           = 0600,
16122 +               .proc_handler   = &proc_dointvec,
16123 +       },
16124 +#endif
16125 +#ifdef CONFIG_GRKERNSEC_SIGNAL
16126 +       {
16127 +               .ctl_name       = GS_SIGNAL,
16128 +               .procname       = "signal_logging",
16129 +               .data           = &grsec_enable_signal,
16130 +               .maxlen         = sizeof(int),
16131 +               .mode           = 0600,
16132 +               .proc_handler   = &proc_dointvec,
16133 +       },
16134 +#endif
16135 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
16136 +       {
16137 +               .ctl_name       = GS_FORKFAIL,
16138 +               .procname       = "forkfail_logging",
16139 +               .data           = &grsec_enable_forkfail,
16140 +               .maxlen         = sizeof(int),
16141 +               .mode           = 0600,
16142 +               .proc_handler   = &proc_dointvec,
16143 +       },
16144 +#endif
16145 +#ifdef CONFIG_GRKERNSEC_TIME
16146 +       {
16147 +               .ctl_name       = GS_TIME,
16148 +               .procname       = "timechange_logging",
16149 +               .data           = &grsec_enable_time,
16150 +               .maxlen         = sizeof(int),
16151 +               .mode           = 0600,
16152 +               .proc_handler   = &proc_dointvec,
16153 +       },
16154 +#endif
16155 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
16156 +       {
16157 +               .ctl_name       = GS_CHROOT_SHMAT,
16158 +               .procname       = "chroot_deny_shmat",
16159 +               .data           = &grsec_enable_chroot_shmat,
16160 +               .maxlen         = sizeof(int),
16161 +               .mode           = 0600,
16162 +               .proc_handler   = &proc_dointvec,
16163 +       },
16164 +#endif
16165 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
16166 +       {
16167 +               .ctl_name       = GS_CHROOT_UNIX,
16168 +               .procname       = "chroot_deny_unix",
16169 +               .data           = &grsec_enable_chroot_unix,
16170 +               .maxlen         = sizeof(int),
16171 +               .mode           = 0600,
16172 +               .proc_handler   = &proc_dointvec,
16173 +       },
16174 +#endif
16175 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
16176 +       {
16177 +               .ctl_name       = GS_CHROOT_MNT,
16178 +               .procname       = "chroot_deny_mount",
16179 +               .data           = &grsec_enable_chroot_mount,
16180 +               .maxlen         = sizeof(int),
16181 +               .mode           = 0600,
16182 +               .proc_handler   = &proc_dointvec,
16183 +       },
16184 +#endif
16185 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
16186 +       {
16187 +               .ctl_name       = GS_CHROOT_FCHDIR,
16188 +               .procname       = "chroot_deny_fchdir",
16189 +               .data           = &grsec_enable_chroot_fchdir,
16190 +               .maxlen         = sizeof(int),
16191 +               .mode           = 0600,
16192 +               .proc_handler   = &proc_dointvec,
16193 +       },
16194 +#endif
16195 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
16196 +       {
16197 +               .ctl_name       = GS_CHROOT_DBL,
16198 +               .procname       = "chroot_deny_chroot",
16199 +               .data           = &grsec_enable_chroot_double,
16200 +               .maxlen         = sizeof(int),
16201 +               .mode           = 0600,
16202 +               .proc_handler   = &proc_dointvec,
16203 +       },
16204 +#endif
16205 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
16206 +       {
16207 +               .ctl_name       = GS_CHROOT_PVT,
16208 +               .procname       = "chroot_deny_pivot",
16209 +               .data           = &grsec_enable_chroot_pivot,
16210 +               .maxlen         = sizeof(int),
16211 +               .mode           = 0600,
16212 +               .proc_handler   = &proc_dointvec,
16213 +       },
16214 +#endif
16215 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
16216 +       {
16217 +               .ctl_name       = GS_CHROOT_CD,
16218 +               .procname       = "chroot_enforce_chdir",
16219 +               .data           = &grsec_enable_chroot_chdir,
16220 +               .maxlen         = sizeof(int),
16221 +               .mode           = 0600,
16222 +               .proc_handler   = &proc_dointvec,
16223 +       },
16224 +#endif
16225 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
16226 +       {
16227 +               .ctl_name       = GS_CHROOT_CM,
16228 +               .procname       = "chroot_deny_chmod",
16229 +               .data           = &grsec_enable_chroot_chmod,
16230 +               .maxlen         = sizeof(int),
16231 +               .mode           = 0600,
16232 +               .proc_handler   = &proc_dointvec,
16233 +       },
16234 +#endif
16235 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
16236 +       {
16237 +               .ctl_name       = GS_CHROOT_MK,
16238 +               .procname       = "chroot_deny_mknod",
16239 +               .data           = &grsec_enable_chroot_mknod,
16240 +               .maxlen         = sizeof(int),
16241 +               .mode           = 0600,
16242 +               .proc_handler   = &proc_dointvec,
16243 +       },
16244 +#endif
16245 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
16246 +       {
16247 +               .ctl_name       = GS_CHROOT_NI,
16248 +               .procname       = "chroot_restrict_nice",
16249 +               .data           = &grsec_enable_chroot_nice,
16250 +               .maxlen         = sizeof(int),
16251 +               .mode           = 0600,
16252 +               .proc_handler   = &proc_dointvec,
16253 +       },
16254 +#endif
16255 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
16256 +       {
16257 +               .ctl_name       = GS_CHROOT_EXECLOG,
16258 +               .procname       = "chroot_execlog",
16259 +               .data           = &grsec_enable_chroot_execlog,
16260 +               .maxlen         = sizeof(int),
16261 +               .mode           = 0600,
16262 +               .proc_handler   = &proc_dointvec,
16263 +       },
16264 +#endif
16265 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
16266 +       {
16267 +               .ctl_name       = GS_CHROOT_CAPS,
16268 +               .procname       = "chroot_caps",
16269 +               .data           = &grsec_enable_chroot_caps,
16270 +               .maxlen         = sizeof(int),
16271 +               .mode           = 0600,
16272 +               .proc_handler   = &proc_dointvec,
16273 +       },
16274 +#endif
16275 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
16276 +       {
16277 +               .ctl_name       = GS_CHROOT_SYSCTL,
16278 +               .procname       = "chroot_deny_sysctl",
16279 +               .data           = &grsec_enable_chroot_sysctl,
16280 +               .maxlen         = sizeof(int),
16281 +               .mode           = 0600,
16282 +               .proc_handler   = &proc_dointvec,
16283 +       },
16284 +#endif
16285 +#ifdef CONFIG_GRKERNSEC_TPE
16286 +       {
16287 +               .ctl_name       = GS_TPE,
16288 +               .procname       = "tpe",
16289 +               .data           = &grsec_enable_tpe,
16290 +               .maxlen         = sizeof(int),
16291 +               .mode           = 0600,
16292 +               .proc_handler   = &proc_dointvec,
16293 +       },
16294 +       {
16295 +               .ctl_name       = GS_TPE_GID,
16296 +               .procname       = "tpe_gid",
16297 +               .data           = &grsec_tpe_gid,
16298 +               .maxlen         = sizeof(int),
16299 +               .mode           = 0600,
16300 +               .proc_handler   = &proc_dointvec,
16301 +       },
16302 +#endif
16303 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
16304 +       {
16305 +               .ctl_name       = GS_TPE_ALL,
16306 +               .procname       = "tpe_restrict_all",
16307 +               .data           = &grsec_enable_tpe_all,
16308 +               .maxlen         = sizeof(int),
16309 +               .mode           = 0600,
16310 +               .proc_handler   = &proc_dointvec,
16311 +       },
16312 +#endif
16313 +#ifdef CONFIG_GRKERNSEC_RANDPID
16314 +       {
16315 +               .ctl_name       = GS_RANDPID,
16316 +               .procname       = "rand_pids",
16317 +               .data           = &grsec_enable_randpid,
16318 +               .maxlen         = sizeof(int),
16319 +               .mode           = 0600,
16320 +               .proc_handler   = &proc_dointvec,
16321 +       },
16322 +#endif
16323 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
16324 +       {
16325 +               .ctl_name       = GS_SOCKET_ALL,
16326 +               .procname       = "socket_all",
16327 +               .data           = &grsec_enable_socket_all,
16328 +               .maxlen         = sizeof(int),
16329 +               .mode           = 0600,
16330 +               .proc_handler   = &proc_dointvec,
16331 +       },
16332 +       {
16333 +               .ctl_name       = GS_SOCKET_ALL_GID,
16334 +               .procname       = "socket_all_gid",
16335 +               .data           = &grsec_socket_all_gid,
16336 +               .maxlen         = sizeof(int),
16337 +               .mode           = 0600,
16338 +               .proc_handler   = &proc_dointvec,
16339 +       },
16340 +#endif
16341 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
16342 +       {
16343 +               .ctl_name       = GS_SOCKET_CLIENT,
16344 +               .procname       = "socket_client",
16345 +               .data           = &grsec_enable_socket_client,
16346 +               .maxlen         = sizeof(int),
16347 +               .mode           = 0600,
16348 +               .proc_handler   = &proc_dointvec,
16349 +       },
16350 +       {
16351 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
16352 +               .procname       = "socket_client_gid",
16353 +               .data           = &grsec_socket_client_gid,
16354 +               .maxlen         = sizeof(int),
16355 +               .mode           = 0600,
16356 +               .proc_handler   = &proc_dointvec,
16357 +       },
16358 +#endif
16359 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
16360 +       {
16361 +               .ctl_name       = GS_SOCKET_SERVER,
16362 +               .procname       = "socket_server",
16363 +               .data           = &grsec_enable_socket_server,
16364 +               .maxlen         = sizeof(int),
16365 +               .mode           = 0600,
16366 +               .proc_handler   = &proc_dointvec,
16367 +       },
16368 +       {
16369 +               .ctl_name       = GS_SOCKET_SERVER_GID,
16370 +               .procname       = "socket_server_gid",
16371 +               .data           = &grsec_socket_server_gid,
16372 +               .maxlen         = sizeof(int),
16373 +               .mode           = 0600,
16374 +               .proc_handler   = &proc_dointvec,
16375 +       },
16376 +#endif
16377 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
16378 +       {
16379 +               .ctl_name       = GS_GROUP,
16380 +               .procname       = "audit_group",
16381 +               .data           = &grsec_enable_group,
16382 +               .maxlen         = sizeof(int),
16383 +               .mode           = 0600,
16384 +               .proc_handler   = &proc_dointvec,
16385 +       },
16386 +       {
16387 +               .ctl_name       = GS_GID,
16388 +               .procname       = "audit_gid",
16389 +               .data           = &grsec_audit_gid,
16390 +               .maxlen         = sizeof(int),
16391 +               .mode           = 0600,
16392 +               .proc_handler   = &proc_dointvec,
16393 +       },
16394 +#endif
16395 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
16396 +       {
16397 +               .ctl_name       = GS_ACHDIR,
16398 +               .procname       = "audit_chdir",
16399 +               .data           = &grsec_enable_chdir,
16400 +               .maxlen         = sizeof(int),
16401 +               .mode           = 0600,
16402 +               .proc_handler   = &proc_dointvec,
16403 +       },
16404 +#endif
16405 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
16406 +       {
16407 +               .ctl_name       = GS_AMOUNT,
16408 +               .procname       = "audit_mount",
16409 +               .data           = &grsec_enable_mount,
16410 +               .maxlen         = sizeof(int),
16411 +               .mode           = 0600,
16412 +               .proc_handler   = &proc_dointvec,
16413 +       },
16414 +#endif
16415 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
16416 +       {
16417 +               .ctl_name       = GS_AIPC,
16418 +               .procname       = "audit_ipc",
16419 +               .data           = &grsec_enable_audit_ipc,
16420 +               .maxlen         = sizeof(int),
16421 +               .mode           = 0600,
16422 +               .proc_handler   = &proc_dointvec,
16423 +       },
16424 +#endif
16425 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
16426 +       {
16427 +               .ctl_name       = GS_TEXTREL,
16428 +               .procname       = "audit_textrel",
16429 +               .data           = &grsec_enable_audit_textrel,
16430 +               .maxlen         = sizeof(int),
16431 +               .mode           = 0600,
16432 +               .proc_handler   = &proc_dointvec,
16433 +       },
16434 +#endif
16435 +#ifdef CONFIG_GRKERNSEC_DMESG
16436 +       {
16437 +               .ctl_name       = GS_DMSG,
16438 +               .procname       = "dmesg",
16439 +               .data           = &grsec_enable_dmesg,
16440 +               .maxlen         = sizeof(int),
16441 +               .mode           = 0600,
16442 +               .proc_handler   = &proc_dointvec,
16443 +       },
16444 +#endif
16445 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
16446 +       {
16447 +               .ctl_name       = GS_FINDTASK,
16448 +               .procname       = "chroot_findtask",
16449 +               .data           = &grsec_enable_chroot_findtask,
16450 +               .maxlen         = sizeof(int),
16451 +               .mode           = 0600,
16452 +               .proc_handler   = &proc_dointvec,
16453 +       },
16454 +#endif
16455 +#ifdef CONFIG_GRKERNSEC_SHM
16456 +       {
16457 +               .ctl_name       = GS_SHM,
16458 +               .procname       = "destroy_unused_shm",
16459 +               .data           = &grsec_enable_shm,
16460 +               .maxlen         = sizeof(int),
16461 +               .mode           = 0600,
16462 +               .proc_handler   = &proc_dointvec,
16463 +       },
16464 +#endif
16465 +       {
16466 +               .ctl_name       = GS_LOCK,
16467 +               .procname       = "grsec_lock",
16468 +               .data           = &grsec_lock,
16469 +               .maxlen         = sizeof(int),
16470 +               .mode           = 0600,
16471 +               .proc_handler   = &proc_dointvec,
16472 +       },
16473 +#endif
16474 +#ifdef CONFIG_GRKERNSEC_MODSTOP
16475 +       {
16476 +               .ctl_name       = GS_MODSTOP,
16477 +               .procname       = "disable_modules",
16478 +               .data           = &grsec_modstop,
16479 +               .maxlen         = sizeof(int),
16480 +               .mode           = 0600,
16481 +               .proc_handler   = &proc_dointvec,
16482 +       },
16483 +#endif
16484 +       { .ctl_name = 0 }
16485 +};
16486 +#endif
16487 +
16488 +int gr_check_modstop(void)
16489 +{
16490 +#ifdef CONFIG_GRKERNSEC_MODSTOP
16491 +       if (grsec_modstop == 1) {
16492 +               gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
16493 +               return 1;
16494 +       }
16495 +#endif
16496 +       return 0;
16497 +}
16498 diff -urNp linux-2.6.16.2/grsecurity/grsec_textrel.c linux-2.6.16.2/grsecurity/grsec_textrel.c
16499 --- linux-2.6.16.2/grsecurity/grsec_textrel.c   1969-12-31 19:00:00.000000000 -0500
16500 +++ linux-2.6.16.2/grsecurity/grsec_textrel.c   2006-04-09 21:23:54.000000000 -0400
16501 @@ -0,0 +1,16 @@
16502 +#include <linux/kernel.h>
16503 +#include <linux/sched.h>
16504 +#include <linux/mm.h>
16505 +#include <linux/file.h>
16506 +#include <linux/grinternal.h>
16507 +#include <linux/grsecurity.h>
16508 +
16509 +void
16510 +gr_log_textrel(struct vm_area_struct * vma)
16511 +{
16512 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
16513 +       if (grsec_enable_audit_textrel)
16514 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
16515 +#endif
16516 +       return;
16517 +}
16518 diff -urNp linux-2.6.16.2/grsecurity/grsec_time.c linux-2.6.16.2/grsecurity/grsec_time.c
16519 --- linux-2.6.16.2/grsecurity/grsec_time.c      1969-12-31 19:00:00.000000000 -0500
16520 +++ linux-2.6.16.2/grsecurity/grsec_time.c      2006-04-09 21:23:54.000000000 -0400
16521 @@ -0,0 +1,13 @@
16522 +#include <linux/kernel.h>
16523 +#include <linux/sched.h>
16524 +#include <linux/grinternal.h>
16525 +
16526 +void
16527 +gr_log_timechange(void)
16528 +{
16529 +#ifdef CONFIG_GRKERNSEC_TIME
16530 +       if (grsec_enable_time)
16531 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
16532 +#endif
16533 +       return;
16534 +}
16535 diff -urNp linux-2.6.16.2/grsecurity/grsec_tpe.c linux-2.6.16.2/grsecurity/grsec_tpe.c
16536 --- linux-2.6.16.2/grsecurity/grsec_tpe.c       1969-12-31 19:00:00.000000000 -0500
16537 +++ linux-2.6.16.2/grsecurity/grsec_tpe.c       2006-04-09 21:23:54.000000000 -0400
16538 @@ -0,0 +1,37 @@
16539 +#include <linux/kernel.h>
16540 +#include <linux/sched.h>
16541 +#include <linux/file.h>
16542 +#include <linux/fs.h>
16543 +#include <linux/grinternal.h>
16544 +
16545 +extern int gr_acl_tpe_check(void);
16546 +
16547 +int
16548 +gr_tpe_allow(const struct file *file)
16549 +{
16550 +#ifdef CONFIG_GRKERNSEC
16551 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
16552 +
16553 +       if (current->uid && ((grsec_enable_tpe &&
16554 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
16555 +           !in_group_p(grsec_tpe_gid)
16556 +#else
16557 +           in_group_p(grsec_tpe_gid)
16558 +#endif
16559 +           ) || gr_acl_tpe_check()) &&
16560 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
16561 +                                               (inode->i_mode & S_IWOTH))))) {
16562 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
16563 +               return 0;
16564 +       }
16565 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
16566 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
16567 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
16568 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
16569 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
16570 +               return 0;
16571 +       }
16572 +#endif
16573 +#endif
16574 +       return 1;
16575 +}
16576 diff -urNp linux-2.6.16.2/grsecurity/grsum.c linux-2.6.16.2/grsecurity/grsum.c
16577 --- linux-2.6.16.2/grsecurity/grsum.c   1969-12-31 19:00:00.000000000 -0500
16578 +++ linux-2.6.16.2/grsecurity/grsum.c   2006-04-09 21:23:54.000000000 -0400
16579 @@ -0,0 +1,59 @@
16580 +#include <linux/kernel.h>
16581 +#include <linux/sched.h>
16582 +#include <linux/mm.h>
16583 +#include <asm/scatterlist.h>
16584 +#include <linux/crypto.h>
16585 +#include <linux/gracl.h>
16586 +
16587 +
16588 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
16589 +#error "crypto and sha256 must be built into the kernel"
16590 +#endif
16591 +
16592 +int
16593 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
16594 +{
16595 +       char *p;
16596 +       struct crypto_tfm *tfm;
16597 +       unsigned char temp_sum[GR_SHA_LEN];
16598 +       struct scatterlist sg[2];
16599 +       volatile int retval = 0;
16600 +       volatile int dummy = 0;
16601 +       unsigned int i;
16602 +
16603 +       tfm = crypto_alloc_tfm("sha256", 0);
16604 +       if (tfm == NULL) {
16605 +               /* should never happen, since sha256 should be built in */
16606 +               return 1;
16607 +       }
16608 +
16609 +       crypto_digest_init(tfm);
16610 +
16611 +       p = salt;
16612 +       sg[0].page = virt_to_page(p);
16613 +       sg[0].offset = ((long) p & ~PAGE_MASK);
16614 +       sg[0].length = GR_SALT_LEN;
16615 +       
16616 +       crypto_digest_update(tfm, sg, 1);
16617 +
16618 +       p = entry->pw;
16619 +       sg[0].page = virt_to_page(p);
16620 +       sg[0].offset = ((long) p & ~PAGE_MASK);
16621 +       sg[0].length = strlen(entry->pw);
16622 +
16623 +       crypto_digest_update(tfm, sg, 1);
16624 +
16625 +       crypto_digest_final(tfm, temp_sum);
16626 +
16627 +       memset(entry->pw, 0, GR_PW_LEN);
16628 +
16629 +       for (i = 0; i < GR_SHA_LEN; i++)
16630 +               if (sum[i] != temp_sum[i])
16631 +                       retval = 1;
16632 +               else
16633 +                       dummy = 1;      // waste a cycle
16634 +
16635 +       crypto_free_tfm(tfm);
16636 +
16637 +       return retval;
16638 +}
16639 diff -urNp linux-2.6.16.2/grsecurity/Kconfig linux-2.6.16.2/grsecurity/Kconfig
16640 --- linux-2.6.16.2/grsecurity/Kconfig   1969-12-31 19:00:00.000000000 -0500
16641 +++ linux-2.6.16.2/grsecurity/Kconfig   2006-04-09 21:23:54.000000000 -0400
16642 @@ -0,0 +1,888 @@
16643 +#
16644 +# grecurity configuration
16645 +#
16646 +
16647 +menu "Grsecurity"
16648 +
16649 +config GRKERNSEC
16650 +       bool "Grsecurity"
16651 +       select CRYPTO
16652 +       select CRYPTO_SHA256
16653 +       help
16654 +         If you say Y here, you will be able to configure many features
16655 +         that will enhance the security of your system.  It is highly
16656 +         recommended that you say Y here and read through the help
16657 +         for each option so that you fully understand the features and
16658 +         can evaluate their usefulness for your machine.
16659 +
16660 +choice
16661 +       prompt "Security Level"
16662 +       depends GRKERNSEC
16663 +       default GRKERNSEC_CUSTOM
16664 +
16665 +config GRKERNSEC_LOW
16666 +       bool "Low"
16667 +       select GRKERNSEC_LINK
16668 +       select GRKERNSEC_FIFO
16669 +       select GRKERNSEC_RANDPID
16670 +       select GRKERNSEC_EXECVE
16671 +       select GRKERNSEC_RANDNET
16672 +       select GRKERNSEC_DMESG
16673 +       select GRKERNSEC_CHROOT_CHDIR
16674 +       select GRKERNSEC_MODSTOP if (MODULES)
16675 +
16676 +       help
16677 +         If you choose this option, several of the grsecurity options will
16678 +         be enabled that will give you greater protection against a number
16679 +         of attacks, while assuring that none of your software will have any
16680 +         conflicts with the additional security measures.  If you run a lot
16681 +         of unusual software, or you are having problems with the higher
16682 +         security levels, you should say Y here.  With this option, the
16683 +         following features are enabled:
16684 +
16685 +         - Linking restrictions
16686 +         - FIFO restrictions
16687 +         - Randomized PIDs
16688 +         - Enforcing RLIMIT_NPROC on execve
16689 +         - Restricted dmesg
16690 +         - Enforced chdir("/") on chroot
16691 +         - Runtime module disabling
16692 +
16693 +config GRKERNSEC_MEDIUM
16694 +       bool "Medium"
16695 +       select PAX
16696 +       select PAX_EI_PAX
16697 +       select PAX_PT_PAX_FLAGS
16698 +       select PAX_HAVE_ACL_FLAGS
16699 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
16700 +       select GRKERNSEC_CHROOT_SYSCTL
16701 +       select GRKERNSEC_LINK
16702 +       select GRKERNSEC_FIFO
16703 +       select GRKERNSEC_RANDPID
16704 +       select GRKERNSEC_EXECVE
16705 +       select GRKERNSEC_DMESG
16706 +       select GRKERNSEC_RANDNET
16707 +       select GRKERNSEC_FORKFAIL
16708 +       select GRKERNSEC_TIME
16709 +       select GRKERNSEC_SIGNAL
16710 +       select GRKERNSEC_CHROOT
16711 +       select GRKERNSEC_CHROOT_UNIX
16712 +       select GRKERNSEC_CHROOT_MOUNT
16713 +       select GRKERNSEC_CHROOT_PIVOT
16714 +       select GRKERNSEC_CHROOT_DOUBLE
16715 +       select GRKERNSEC_CHROOT_CHDIR
16716 +       select GRKERNSEC_CHROOT_MKNOD
16717 +       select GRKERNSEC_PROC
16718 +       select GRKERNSEC_PROC_USERGROUP
16719 +       select GRKERNSEC_MODSTOP if (MODULES)
16720 +       select PAX_RANDUSTACK
16721 +       select PAX_ASLR
16722 +       select PAX_RANDMMAP
16723 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
16724 +
16725 +       help
16726 +         If you say Y here, several features in addition to those included
16727 +         in the low additional security level will be enabled.  These
16728 +         features provide even more security to your system, though in rare
16729 +         cases they may be incompatible with very old or poorly written
16730 +         software.  If you enable this option, make sure that your auth
16731 +         service (identd) is running as gid 1001.  With this option, 
16732 +         the following features (in addition to those provided in the 
16733 +         low additional security level) will be enabled:
16734 +
16735 +         - Randomized TCP source ports
16736 +         - Failed fork logging
16737 +         - Time change logging
16738 +         - Signal logging
16739 +         - Deny mounts in chroot
16740 +         - Deny double chrooting
16741 +         - Deny sysctl writes in chroot
16742 +         - Deny mknod in chroot
16743 +         - Deny access to abstract AF_UNIX sockets out of chroot
16744 +         - Deny pivot_root in chroot
16745 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
16746 +         - /proc restrictions with special GID set to 10 (usually wheel)
16747 +         - Address Space Layout Randomization (ASLR)
16748 +
16749 +config GRKERNSEC_HIGH
16750 +       bool "High"
16751 +       select GRKERNSEC_LINK
16752 +       select GRKERNSEC_FIFO
16753 +       select GRKERNSEC_RANDPID
16754 +       select GRKERNSEC_EXECVE
16755 +       select GRKERNSEC_DMESG
16756 +       select GRKERNSEC_FORKFAIL
16757 +       select GRKERNSEC_TIME
16758 +       select GRKERNSEC_SIGNAL
16759 +       select GRKERNSEC_CHROOT_SHMAT
16760 +       select GRKERNSEC_CHROOT_UNIX
16761 +       select GRKERNSEC_CHROOT_MOUNT
16762 +       select GRKERNSEC_CHROOT_FCHDIR
16763 +       select GRKERNSEC_CHROOT_PIVOT
16764 +       select GRKERNSEC_CHROOT_DOUBLE
16765 +       select GRKERNSEC_CHROOT_CHDIR
16766 +       select GRKERNSEC_CHROOT_MKNOD
16767 +       select GRKERNSEC_CHROOT_CAPS
16768 +       select GRKERNSEC_CHROOT_SYSCTL
16769 +       select GRKERNSEC_CHROOT_FINDTASK
16770 +       select GRKERNSEC_PROC
16771 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
16772 +       select GRKERNSEC_HIDESYM
16773 +       select GRKERNSEC_BRUTE
16774 +       select GRKERNSEC_SHM if (SYSVIPC)
16775 +       select GRKERNSEC_PROC_USERGROUP
16776 +       select GRKERNSEC_KMEM
16777 +       select GRKERNSEC_RESLOG
16778 +       select GRKERNSEC_RANDNET
16779 +       select GRKERNSEC_PROC_ADD
16780 +       select GRKERNSEC_CHROOT_CHMOD
16781 +       select GRKERNSEC_CHROOT_NICE
16782 +       select GRKERNSEC_AUDIT_MOUNT
16783 +       select GRKERNSEC_MODSTOP if (MODULES)
16784 +       select PAX
16785 +       select PAX_RANDUSTACK
16786 +       select PAX_ASLR
16787 +       select PAX_RANDMMAP
16788 +       select PAX_NOEXEC
16789 +       select PAX_MPROTECT
16790 +       select PAX_EI_PAX
16791 +       select PAX_PT_PAX_FLAGS
16792 +       select PAX_HAVE_ACL_FLAGS
16793 +       select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
16794 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
16795 +       select PAX_SEGMEXEC if (X86 && !X86_64)
16796 +       select PAX_PAGEEXEC if (!X86)
16797 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
16798 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
16799 +       select PAX_SYSCALL if (PPC32)
16800 +       select PAX_EMUTRAMP if (PARISC)
16801 +       select PAX_EMUSIGRT if (PARISC)
16802 +       select PAX_NOVSYSCALL if (X86 && !X86_64)
16803 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
16804 +       help
16805 +         If you say Y here, many of the features of grsecurity will be
16806 +         enabled, which will protect you against many kinds of attacks
16807 +         against your system.  The heightened security comes at a cost
16808 +         of an increased chance of incompatibilities with rare software
16809 +         on your machine.  Since this security level enables PaX, you should
16810 +         view <http://pax.grsecurity.net> and read about the PaX
16811 +         project.  While you are there, download chpax and run it on
16812 +         binaries that cause problems with PaX.  Also remember that
16813 +         since the /proc restrictions are enabled, you must run your
16814 +         identd as gid 1001.  This security level enables the following 
16815 +         features in addition to those listed in the low and medium 
16816 +         security levels:
16817 +
16818 +         - Additional /proc restrictions
16819 +         - Chmod restrictions in chroot
16820 +         - No signals, ptrace, or viewing of processes outside of chroot
16821 +         - Capability restrictions in chroot
16822 +         - Deny fchdir out of chroot
16823 +         - Priority restrictions in chroot
16824 +         - Segmentation-based implementation of PaX
16825 +         - Mprotect restrictions
16826 +         - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
16827 +         - Kernel stack randomization
16828 +         - Mount/unmount/remount logging
16829 +         - Kernel symbol hiding
16830 +         - Destroy unused shared memory        
16831 +         - Prevention of memory exhaustion-based exploits
16832 +config GRKERNSEC_CUSTOM
16833 +       bool "Custom"
16834 +       help
16835 +         If you say Y here, you will be able to configure every grsecurity
16836 +         option, which allows you to enable many more features that aren't
16837 +         covered in the basic security levels.  These additional features
16838 +         include TPE, socket restrictions, and the sysctl system for
16839 +         grsecurity.  It is advised that you read through the help for
16840 +         each option to determine its usefulness in your situation.
16841 +
16842 +endchoice
16843 +
16844 +menu "Address Space Protection"
16845 +depends on GRKERNSEC
16846 +
16847 +config GRKERNSEC_KMEM
16848 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
16849 +       help
16850 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
16851 +         be written to via mmap or otherwise to modify the running kernel.
16852 +         /dev/port will also not be allowed to be opened. If you have module
16853 +         support disabled, enabling this will close up four ways that are
16854 +         currently used  to insert malicious code into the running kernel.
16855 +         Even with all these features enabled, we still highly recommend that
16856 +         you use the RBAC system, as it is still possible for an attacker to
16857 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
16858 +         If you are not using XFree86, you may be able to stop this additional
16859 +         case by enabling the 'Disable privileged I/O' option. Though nothing
16860 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
16861 +         but only to video memory, which is the only writing we allow in this
16862 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
16863 +         not be allowed to mprotect it with PROT_WRITE later.
16864 +         It is highly recommended that you say Y here if you meet all the
16865 +         conditions above.
16866 +
16867 +config GRKERNSEC_IO
16868 +       bool "Disable privileged I/O"
16869 +       depends on X86
16870 +       select RTC
16871 +       help
16872 +         If you say Y here, all ioperm and iopl calls will return an error.
16873 +         Ioperm and iopl can be used to modify the running kernel.
16874 +         Unfortunately, some programs need this access to operate properly,
16875 +         the most notable of which are XFree86 and hwclock.  hwclock can be
16876 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
16877 +         enabled if this option is enabled, to ensure that hwclock operates
16878 +         correctly.  XFree86 still will not operate correctly with this option
16879 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
16880 +         and you still want to protect your kernel against modification,
16881 +         use the RBAC system.
16882 +
16883 +config GRKERNSEC_PROC_MEMMAP
16884 +       bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
16885 +       depends on PAX_NOEXEC || PAX_ASLR
16886 +       help
16887 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
16888 +         give no information about the addresses of its mappings if
16889 +         PaX features that rely on random addresses are enabled on the task.
16890 +         If you use PaX it is greatly recommended that you say Y here as it
16891 +         closes up a hole that makes the full ASLR useless for suid
16892 +         binaries.
16893 +
16894 +config GRKERNSEC_BRUTE
16895 +       bool "Deter exploit bruteforcing"
16896 +       help
16897 +         If you say Y here, attempts to bruteforce exploits against forking
16898 +         daemons such as apache or sshd will be deterred.  When a child of a
16899 +         forking daemon is killed by PaX or crashes due to an illegal
16900 +         instruction, the parent process will be delayed 30 seconds upon every
16901 +         subsequent fork until the administrator is able to assess the
16902 +         situation and restart the daemon.  It is recommended that you also
16903 +         enable signal logging in the auditing section so that logs are
16904 +         generated when a process performs an illegal instruction.
16905 +
16906 +config GRKERNSEC_MODSTOP
16907 +       bool "Runtime module disabling"
16908 +       depends on MODULES
16909 +       help
16910 +         If you say Y here, you will be able to disable the ability to (un)load
16911 +         modules at runtime.  This feature is useful if you need the ability
16912 +         to load kernel modules at boot time, but do not want to allow an
16913 +         attacker to load a rootkit kernel module into the system, or to remove
16914 +         a loaded kernel module important to system functioning.  You should
16915 +         enable the /dev/mem protection feature as well, since rootkits can be
16916 +         inserted into the kernel via other methods than kernel modules.  Since
16917 +         an untrusted module could still be loaded by modifying init scripts and
16918 +         rebooting the system, it is also recommended that you enable the RBAC
16919 +         system.  If you enable this option, a sysctl option with name
16920 +         "disable_modules" will be created.  Setting this option to "1" disables
16921 +         module loading.  After this option is set, no further writes to it are
16922 +         allowed until the system is rebooted.
16923 +
16924 +config GRKERNSEC_HIDESYM
16925 +       bool "Hide kernel symbols"
16926 +       help
16927 +         If you say Y here, getting information on loaded modules, and
16928 +         displaying all kernel symbols through a syscall will be restricted
16929 +         to users with CAP_SYS_MODULE.  This option is only effective
16930 +         provided the following conditions are met:
16931 +         1) The kernel using grsecurity is not precompiled by some distribution
16932 +         2) You are using the RBAC system and hiding other files such as your
16933 +            kernel image and System.map
16934 +         3) You have the additional /proc restrictions enabled, which removes
16935 +            /proc/kcore
16936 +         If the above conditions are met, this option will aid to provide a
16937 +         useful protection against local and remote kernel exploitation of
16938 +         overflows and arbitrary read/write vulnerabilities.
16939 +
16940 +endmenu
16941 +menu "Role Based Access Control Options"
16942 +depends on GRKERNSEC
16943 +
16944 +config GRKERNSEC_ACL_HIDEKERN
16945 +       bool "Hide kernel processes"
16946 +       help
16947 +         If you say Y here, all kernel threads will be hidden to all
16948 +         processes but those whose subject has the "view hidden processes"
16949 +         flag.
16950 +
16951 +config GRKERNSEC_ACL_MAXTRIES
16952 +       int "Maximum tries before password lockout"
16953 +       default 3
16954 +       help
16955 +         This option enforces the maximum number of times a user can attempt
16956 +         to authorize themselves with the grsecurity RBAC system before being
16957 +         denied the ability to attempt authorization again for a specified time.
16958 +         The lower the number, the harder it will be to brute-force a password.
16959 +
16960 +config GRKERNSEC_ACL_TIMEOUT
16961 +       int "Time to wait after max password tries, in seconds"
16962 +       default 30
16963 +       help
16964 +         This option specifies the time the user must wait after attempting to
16965 +         authorize to the RBAC system with the maximum number of invalid
16966 +         passwords.  The higher the number, the harder it will be to brute-force
16967 +         a password.
16968 +
16969 +endmenu
16970 +menu "Filesystem Protections"
16971 +depends on GRKERNSEC
16972 +
16973 +config GRKERNSEC_PROC
16974 +       bool "Proc restrictions"
16975 +       help
16976 +         If you say Y here, the permissions of the /proc filesystem
16977 +         will be altered to enhance system security and privacy.  You MUST
16978 +         choose either a user only restriction or a user and group restriction.
16979 +         Depending upon the option you choose, you can either restrict users to
16980 +         see only the processes they themselves run, or choose a group that can
16981 +         view all processes and files normally restricted to root if you choose
16982 +         the "restrict to user only" option.  NOTE: If you're running identd as
16983 +         a non-root user, you will have to run it as the group you specify here.
16984 +
16985 +config GRKERNSEC_PROC_USER
16986 +       bool "Restrict /proc to user only"
16987 +       depends on GRKERNSEC_PROC
16988 +       help
16989 +         If you say Y here, non-root users will only be able to view their own
16990 +         processes, and restricts them from viewing network-related information,
16991 +         and viewing kernel symbol and module information.
16992 +
16993 +config GRKERNSEC_PROC_USERGROUP
16994 +       bool "Allow special group"
16995 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
16996 +       help
16997 +         If you say Y here, you will be able to select a group that will be
16998 +         able to view all processes, network-related information, and
16999 +         kernel and symbol information.  This option is useful if you want
17000 +         to run identd as a non-root user.
17001 +
17002 +config GRKERNSEC_PROC_GID
17003 +       int "GID for special group"
17004 +       depends on GRKERNSEC_PROC_USERGROUP
17005 +       default 1001
17006 +
17007 +config GRKERNSEC_PROC_ADD
17008 +       bool "Additional restrictions"
17009 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
17010 +       help
17011 +         If you say Y here, additional restrictions will be placed on
17012 +         /proc that keep normal users from viewing device information and 
17013 +         slabinfo information that could be useful for exploits.
17014 +
17015 +config GRKERNSEC_LINK
17016 +       bool "Linking restrictions"
17017 +       help
17018 +         If you say Y here, /tmp race exploits will be prevented, since users
17019 +         will no longer be able to follow symlinks owned by other users in
17020 +         world-writable +t directories (i.e. /tmp), unless the owner of the
17021 +         symlink is the owner of the directory. users will also not be
17022 +         able to hardlink to files they do not own.  If the sysctl option is
17023 +         enabled, a sysctl option with name "linking_restrictions" is created.
17024 +
17025 +config GRKERNSEC_FIFO
17026 +       bool "FIFO restrictions"
17027 +       help
17028 +         If you say Y here, users will not be able to write to FIFOs they don't
17029 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
17030 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
17031 +         option is enabled, a sysctl option with name "fifo_restrictions" is
17032 +         created.
17033 +
17034 +config GRKERNSEC_CHROOT
17035 +       bool "Chroot jail restrictions"
17036 +       help
17037 +         If you say Y here, you will be able to choose several options that will
17038 +         make breaking out of a chrooted jail much more difficult.  If you
17039 +         encounter no software incompatibilities with the following options, it
17040 +         is recommended that you enable each one.
17041 +
17042 +config GRKERNSEC_CHROOT_MOUNT
17043 +       bool "Deny mounts"
17044 +       depends on GRKERNSEC_CHROOT
17045 +       help
17046 +         If you say Y here, processes inside a chroot will not be able to
17047 +         mount or remount filesystems.  If the sysctl option is enabled, a
17048 +         sysctl option with name "chroot_deny_mount" is created.
17049 +
17050 +config GRKERNSEC_CHROOT_DOUBLE
17051 +       bool "Deny double-chroots"
17052 +       depends on GRKERNSEC_CHROOT
17053 +       help
17054 +         If you say Y here, processes inside a chroot will not be able to chroot
17055 +         again outside the chroot.  This is a widely used method of breaking
17056 +         out of a chroot jail and should not be allowed.  If the sysctl 
17057 +         option is enabled, a sysctl option with name 
17058 +         "chroot_deny_chroot" is created.
17059 +
17060 +config GRKERNSEC_CHROOT_PIVOT
17061 +       bool "Deny pivot_root in chroot"
17062 +       depends on GRKERNSEC_CHROOT
17063 +       help
17064 +         If you say Y here, processes inside a chroot will not be able to use
17065 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
17066 +         works similar to chroot in that it changes the root filesystem.  This
17067 +         function could be misused in a chrooted process to attempt to break out
17068 +         of the chroot, and therefore should not be allowed.  If the sysctl
17069 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
17070 +         created.
17071 +
17072 +config GRKERNSEC_CHROOT_CHDIR
17073 +       bool "Enforce chdir(\"/\") on all chroots"
17074 +       depends on GRKERNSEC_CHROOT
17075 +       help
17076 +         If you say Y here, the current working directory of all newly-chrooted
17077 +         applications will be set to the the root directory of the chroot.
17078 +         The man page on chroot(2) states:
17079 +         Note that this call does not change  the  current  working
17080 +         directory,  so  that `.' can be outside the tree rooted at
17081 +         `/'.  In particular, the  super-user  can  escape  from  a
17082 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
17083 +
17084 +         It is recommended that you say Y here, since it's not known to break
17085 +         any software.  If the sysctl option is enabled, a sysctl option with
17086 +         name "chroot_enforce_chdir" is created.
17087 +
17088 +config GRKERNSEC_CHROOT_CHMOD
17089 +       bool "Deny (f)chmod +s"
17090 +       depends on GRKERNSEC_CHROOT
17091 +       help
17092 +         If you say Y here, processes inside a chroot will not be able to chmod
17093 +         or fchmod files to make them have suid or sgid bits.  This protects
17094 +         against another published method of breaking a chroot.  If the sysctl
17095 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
17096 +         created.
17097 +
17098 +config GRKERNSEC_CHROOT_FCHDIR
17099 +       bool "Deny fchdir out of chroot"
17100 +       depends on GRKERNSEC_CHROOT
17101 +       help
17102 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
17103 +         to a file descriptor of the chrooting process that points to a directory
17104 +         outside the filesystem will be stopped.  If the sysctl option
17105 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
17106 +
17107 +config GRKERNSEC_CHROOT_MKNOD
17108 +       bool "Deny mknod"
17109 +       depends on GRKERNSEC_CHROOT
17110 +       help
17111 +         If you say Y here, processes inside a chroot will not be allowed to
17112 +         mknod.  The problem with using mknod inside a chroot is that it
17113 +         would allow an attacker to create a device entry that is the same
17114 +         as one on the physical root of your system, which could range from
17115 +         anything from the console device to a device for your harddrive (which
17116 +         they could then use to wipe the drive or steal data).  It is recommended
17117 +         that you say Y here, unless you run into software incompatibilities.
17118 +         If the sysctl option is enabled, a sysctl option with name
17119 +         "chroot_deny_mknod" is created.
17120 +
17121 +config GRKERNSEC_CHROOT_SHMAT
17122 +       bool "Deny shmat() out of chroot"
17123 +       depends on GRKERNSEC_CHROOT
17124 +       help
17125 +         If you say Y here, processes inside a chroot will not be able to attach
17126 +         to shared memory segments that were created outside of the chroot jail.
17127 +         It is recommended that you say Y here.  If the sysctl option is enabled,
17128 +         a sysctl option with name "chroot_deny_shmat" is created.
17129 +
17130 +config GRKERNSEC_CHROOT_UNIX
17131 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
17132 +       depends on GRKERNSEC_CHROOT
17133 +       help
17134 +         If you say Y here, processes inside a chroot will not be able to
17135 +         connect to abstract (meaning not belonging to a filesystem) Unix
17136 +         domain sockets that were bound outside of a chroot.  It is recommended
17137 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
17138 +         with name "chroot_deny_unix" is created.
17139 +
17140 +config GRKERNSEC_CHROOT_FINDTASK
17141 +       bool "Protect outside processes"
17142 +       depends on GRKERNSEC_CHROOT
17143 +       help
17144 +         If you say Y here, processes inside a chroot will not be able to
17145 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
17146 +         getsid, or view any process outside of the chroot.  If the sysctl
17147 +         option is enabled, a sysctl option with name "chroot_findtask" is
17148 +         created.
17149 +
17150 +config GRKERNSEC_CHROOT_NICE
17151 +       bool "Restrict priority changes"
17152 +       depends on GRKERNSEC_CHROOT
17153 +       help
17154 +         If you say Y here, processes inside a chroot will not be able to raise
17155 +         the priority of processes in the chroot, or alter the priority of
17156 +         processes outside the chroot.  This provides more security than simply
17157 +         removing CAP_SYS_NICE from the process' capability set.  If the
17158 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
17159 +         is created.
17160 +
17161 +config GRKERNSEC_CHROOT_SYSCTL
17162 +       bool "Deny sysctl writes"
17163 +       depends on GRKERNSEC_CHROOT
17164 +       help
17165 +         If you say Y here, an attacker in a chroot will not be able to
17166 +         write to sysctl entries, either by sysctl(2) or through a /proc
17167 +         interface.  It is strongly recommended that you say Y here. If the
17168 +         sysctl option is enabled, a sysctl option with name
17169 +         "chroot_deny_sysctl" is created.
17170 +
17171 +config GRKERNSEC_CHROOT_CAPS
17172 +       bool "Capability restrictions"
17173 +       depends on GRKERNSEC_CHROOT
17174 +       help
17175 +         If you say Y here, the capabilities on all root processes within a
17176 +         chroot jail will be lowered to stop module insertion, raw i/o,
17177 +         system and net admin tasks, rebooting the system, modifying immutable
17178 +         files, modifying IPC owned by another, and changing the system time.
17179 +         This is left an option because it can break some apps.  Disable this
17180 +         if your chrooted apps are having problems performing those kinds of
17181 +         tasks.  If the sysctl option is enabled, a sysctl option with
17182 +         name "chroot_caps" is created.
17183 +
17184 +endmenu
17185 +menu "Kernel Auditing"
17186 +depends on GRKERNSEC
17187 +
17188 +config GRKERNSEC_AUDIT_GROUP
17189 +       bool "Single group for auditing"
17190 +       help
17191 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
17192 +         will only operate on a group you specify.  This option is recommended
17193 +         if you only want to watch certain users instead of having a large
17194 +         amount of logs from the entire system.  If the sysctl option is enabled,
17195 +         a sysctl option with name "audit_group" is created.
17196 +
17197 +config GRKERNSEC_AUDIT_GID
17198 +       int "GID for auditing"
17199 +       depends on GRKERNSEC_AUDIT_GROUP
17200 +       default 1007
17201 +
17202 +config GRKERNSEC_EXECLOG
17203 +       bool "Exec logging"
17204 +       help
17205 +         If you say Y here, all execve() calls will be logged (since the
17206 +         other exec*() calls are frontends to execve(), all execution
17207 +         will be logged).  Useful for shell-servers that like to keep track
17208 +         of their users.  If the sysctl option is enabled, a sysctl option with
17209 +         name "exec_logging" is created.
17210 +         WARNING: This option when enabled will produce a LOT of logs, especially
17211 +         on an active system.
17212 +
17213 +config GRKERNSEC_RESLOG
17214 +       bool "Resource logging"
17215 +       help
17216 +         If you say Y here, all attempts to overstep resource limits will
17217 +         be logged with the resource name, the requested size, and the current
17218 +         limit.  It is highly recommended that you say Y here.
17219 +
17220 +config GRKERNSEC_CHROOT_EXECLOG
17221 +       bool "Log execs within chroot"
17222 +       help
17223 +         If you say Y here, all executions inside a chroot jail will be logged
17224 +         to syslog.  This can cause a large amount of logs if certain
17225 +         applications (eg. djb's daemontools) are installed on the system, and
17226 +         is therefore left as an option.  If the sysctl option is enabled, a
17227 +         sysctl option with name "chroot_execlog" is created.
17228 +
17229 +config GRKERNSEC_AUDIT_CHDIR
17230 +       bool "Chdir logging"
17231 +       help
17232 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
17233 +         option is enabled, a sysctl option with name "audit_chdir" is created.
17234 +
17235 +config GRKERNSEC_AUDIT_MOUNT
17236 +       bool "(Un)Mount logging"
17237 +       help
17238 +         If you say Y here, all mounts and unmounts will be logged.  If the
17239 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
17240 +         created.
17241 +
17242 +config GRKERNSEC_AUDIT_IPC
17243 +       bool "IPC logging"
17244 +       help
17245 +         If you say Y here, creation and removal of message queues, semaphores,
17246 +         and shared memory will be logged.  If the sysctl option is enabled, a
17247 +         sysctl option with name "audit_ipc" is created.
17248 +
17249 +config GRKERNSEC_SIGNAL
17250 +       bool "Signal logging"
17251 +       help
17252 +         If you say Y here, certain important signals will be logged, such as
17253 +         SIGSEGV, which will as a result inform you of when a error in a program
17254 +         occurred, which in some cases could mean a possible exploit attempt.
17255 +         If the sysctl option is enabled, a sysctl option with name
17256 +         "signal_logging" is created.
17257 +
17258 +config GRKERNSEC_FORKFAIL
17259 +       bool "Fork failure logging"
17260 +       help
17261 +         If you say Y here, all failed fork() attempts will be logged.
17262 +         This could suggest a fork bomb, or someone attempting to overstep
17263 +         their process limit.  If the sysctl option is enabled, a sysctl option
17264 +         with name "forkfail_logging" is created.
17265 +
17266 +config GRKERNSEC_TIME
17267 +       bool "Time change logging"
17268 +       help
17269 +         If you say Y here, any changes of the system clock will be logged.
17270 +         If the sysctl option is enabled, a sysctl option with name
17271 +         "timechange_logging" is created.
17272 +
17273 +config GRKERNSEC_PROC_IPADDR
17274 +       bool "/proc/<pid>/ipaddr support"
17275 +       help
17276 +         If you say Y here, a new entry will be added to each /proc/<pid>
17277 +         directory that contains the IP address of the person using the task.
17278 +         The IP is carried across local TCP and AF_UNIX stream sockets.
17279 +         This information can be useful for IDS/IPSes to perform remote response
17280 +         to a local attack.  The entry is readable by only the owner of the
17281 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
17282 +         the RBAC system), and thus does not create privacy concerns.
17283 +
17284 +config GRKERNSEC_AUDIT_TEXTREL
17285 +       bool 'ELF text relocations logging (READ HELP)'
17286 +       depends on PAX_MPROTECT
17287 +       help
17288 +         If you say Y here, text relocations will be logged with the filename
17289 +         of the offending library or binary.  The purpose of the feature is
17290 +         to help Linux distribution developers get rid of libraries and
17291 +         binaries that need text relocations which hinder the future progress
17292 +         of PaX.  Only Linux distribution developers should say Y here, and
17293 +         never on a production machine, as this option creates an information
17294 +         leak that could aid an attacker in defeating the randomization of
17295 +         a single memory region.  If the sysctl option is enabled, a sysctl
17296 +         option with name "audit_textrel" is created.
17297 +
17298 +endmenu
17299 +
17300 +menu "Executable Protections"
17301 +depends on GRKERNSEC
17302 +
17303 +config GRKERNSEC_EXECVE
17304 +       bool "Enforce RLIMIT_NPROC on execs"
17305 +       help
17306 +         If you say Y here, users with a resource limit on processes will
17307 +         have the value checked during execve() calls.  The current system
17308 +         only checks the system limit during fork() calls.  If the sysctl option
17309 +         is enabled, a sysctl option with name "execve_limiting" is created.
17310 +
17311 +config GRKERNSEC_SHM
17312 +       bool "Destroy unused shared memory"
17313 +       depends on SYSVIPC
17314 +       help
17315 +         If you say Y here, shared memory will be destroyed when no one is
17316 +         attached to it.  Otherwise, resources involved with the shared
17317 +         memory can be used up and not be associated with any process (as the
17318 +         shared memory still exists, and the creating process has exited).  If
17319 +         the sysctl option is enabled, a sysctl option with name
17320 +         "destroy_unused_shm" is created.
17321 +
17322 +config GRKERNSEC_DMESG
17323 +       bool "Dmesg(8) restriction"
17324 +       help
17325 +         If you say Y here, non-root users will not be able to use dmesg(8)
17326 +         to view up to the last 4kb of messages in the kernel's log buffer.
17327 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
17328 +         created.
17329 +
17330 +config GRKERNSEC_RANDPID
17331 +       bool "Randomized PIDs"
17332 +       help
17333 +         If you say Y here, all PIDs created on the system will be
17334 +         pseudo-randomly generated.  This is extremely effective along
17335 +         with the /proc restrictions to disallow an attacker from guessing
17336 +         pids of daemons, etc.  PIDs are also used in some cases as part
17337 +         of a naming system for temporary files, so this option would keep
17338 +         those filenames from being predicted as well.  We also use code
17339 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
17340 +         option is enabled, a sysctl option with name "rand_pids" is created.
17341 +
17342 +config GRKERNSEC_TPE
17343 +       bool "Trusted Path Execution (TPE)"
17344 +       help
17345 +         If you say Y here, you will be able to choose a gid to add to the
17346 +         supplementary groups of users you want to mark as "untrusted."
17347 +         These users will not be able to execute any files that are not in
17348 +         root-owned directories writable only by root.  If the sysctl option
17349 +         is enabled, a sysctl option with name "tpe" is created.
17350 +
17351 +config GRKERNSEC_TPE_ALL
17352 +       bool "Partially restrict non-root users"
17353 +       depends on GRKERNSEC_TPE
17354 +       help
17355 +         If you say Y here, All non-root users other than the ones in the
17356 +         group specified in the main TPE option will only be allowed to
17357 +         execute files in directories they own that are not group or
17358 +         world-writable, or in directories owned by root and writable only by
17359 +         root.  If the sysctl option is enabled, a sysctl option with name
17360 +         "tpe_restrict_all" is created.
17361 +
17362 +config GRKERNSEC_TPE_INVERT
17363 +       bool "Invert GID option"
17364 +       depends on GRKERNSEC_TPE
17365 +       help
17366 +         If you say Y here, the group you specify in the TPE configuration will
17367 +         decide what group TPE restrictions will be *disabled* for.  This
17368 +         option is useful if you want TPE restrictions to be applied to most
17369 +         users on the system.
17370 +
17371 +config GRKERNSEC_TPE_GID
17372 +       int "GID for untrusted users"
17373 +       depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
17374 +       default 1005
17375 +       help
17376 +         If you have selected the "Invert GID option" above, setting this
17377 +         GID determines what group TPE restrictions will be *disabled* for.
17378 +         If you have not selected the "Invert GID option" above, setting this
17379 +         GID determines what group TPE restrictions will be *enabled* for.
17380 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
17381 +         is created.
17382 +
17383 +config GRKERNSEC_TPE_GID
17384 +       int "GID for trusted users"
17385 +       depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
17386 +       default 1005
17387 +       help
17388 +         If you have selected the "Invert GID option" above, setting this
17389 +         GID determines what group TPE restrictions will be *disabled* for.
17390 +         If you have not selected the "Invert GID option" above, setting this
17391 +         GID determines what group TPE restrictions will be *enabled* for.
17392 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
17393 +         is created.
17394 +
17395 +endmenu
17396 +menu "Network Protections"
17397 +depends on GRKERNSEC
17398 +
17399 +config GRKERNSEC_RANDNET
17400 +       bool "Larger entropy pools"
17401 +       help
17402 +         If you say Y here, the entropy pools used for many features of Linux
17403 +         and grsecurity will be doubled in size.  Since several grsecurity
17404 +         features use additional randomness, it is recommended that you say Y
17405 +         here.  Saying Y here has a similar effect as modifying
17406 +         /proc/sys/kernel/random/poolsize.
17407 +
17408 +config GRKERNSEC_SOCKET
17409 +       bool "Socket restrictions"
17410 +       help
17411 +         If you say Y here, you will be able to choose from several options.
17412 +         If you assign a GID on your system and add it to the supplementary
17413 +         groups of users you want to restrict socket access to, this patch
17414 +         will perform up to three things, based on the option(s) you choose.
17415 +
17416 +config GRKERNSEC_SOCKET_ALL
17417 +       bool "Deny any sockets to group"
17418 +       depends on GRKERNSEC_SOCKET
17419 +       help
17420 +         If you say Y here, you will be able to choose a GID of whose users will
17421 +         be unable to connect to other hosts from your machine or run server
17422 +         applications from your machine.  If the sysctl option is enabled, a
17423 +         sysctl option with name "socket_all" is created.
17424 +
17425 +config GRKERNSEC_SOCKET_ALL_GID
17426 +       int "GID to deny all sockets for"
17427 +       depends on GRKERNSEC_SOCKET_ALL
17428 +       default 1004
17429 +       help
17430 +         Here you can choose the GID to disable socket access for. Remember to
17431 +         add the users you want socket access disabled for to the GID
17432 +         specified here.  If the sysctl option is enabled, a sysctl option
17433 +         with name "socket_all_gid" is created.
17434 +
17435 +config GRKERNSEC_SOCKET_CLIENT
17436 +       bool "Deny client sockets to group"
17437 +       depends on GRKERNSEC_SOCKET
17438 +       help
17439 +         If you say Y here, you will be able to choose a GID of whose users will
17440 +         be unable to connect to other hosts from your machine, but will be
17441 +         able to run servers.  If this option is enabled, all users in the group
17442 +         you specify will have to use passive mode when initiating ftp transfers
17443 +         from the shell on your machine.  If the sysctl option is enabled, a
17444 +         sysctl option with name "socket_client" is created.
17445 +
17446 +config GRKERNSEC_SOCKET_CLIENT_GID
17447 +       int "GID to deny client sockets for"
17448 +       depends on GRKERNSEC_SOCKET_CLIENT
17449 +       default 1003
17450 +       help
17451 +         Here you can choose the GID to disable client socket access for.
17452 +         Remember to add the users you want client socket access disabled for to
17453 +         the GID specified here.  If the sysctl option is enabled, a sysctl
17454 +         option with name "socket_client_gid" is created.
17455 +
17456 +config GRKERNSEC_SOCKET_SERVER
17457 +       bool "Deny server sockets to group"
17458 +       depends on GRKERNSEC_SOCKET
17459 +       help
17460 +         If you say Y here, you will be able to choose a GID of whose users will
17461 +         be unable to run server applications from your machine.  If the sysctl
17462 +         option is enabled, a sysctl option with name "socket_server" is created.
17463 +
17464 +config GRKERNSEC_SOCKET_SERVER_GID
17465 +       int "GID to deny server sockets for"
17466 +       depends on GRKERNSEC_SOCKET_SERVER
17467 +       default 1002
17468 +       help
17469 +         Here you can choose the GID to disable server socket access for.
17470 +         Remember to add the users you want server socket access disabled for to
17471 +         the GID specified here.  If the sysctl option is enabled, a sysctl
17472 +         option with name "socket_server_gid" is created.
17473 +
17474 +endmenu
17475 +menu "Sysctl support"
17476 +depends on GRKERNSEC && SYSCTL
17477 +
17478 +config GRKERNSEC_SYSCTL
17479 +       bool "Sysctl support"
17480 +       help
17481 +         If you say Y here, you will be able to change the options that
17482 +         grsecurity runs with at bootup, without having to recompile your
17483 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
17484 +         to enable (1) or disable (0) various features.  All the sysctl entries
17485 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
17486 +         All features enabled in the kernel configuration are disabled at boot
17487 +         if you do not say Y to the "Turn on features by default" option.
17488 +         All options should be set at startup, and the grsec_lock entry should
17489 +         be set to a non-zero value after all the options are set.
17490 +         *THIS IS EXTREMELY IMPORTANT*
17491 +
17492 +config GRKERNSEC_SYSCTL_ON
17493 +       bool "Turn on features by default"
17494 +       depends on GRKERNSEC_SYSCTL
17495 +       help
17496 +         If you say Y here, instead of having all features enabled in the
17497 +         kernel configuration disabled at boot time, the features will be
17498 +         enabled at boot time.  It is recommended you say Y here unless
17499 +         there is some reason you would want all sysctl-tunable features to
17500 +         be disabled by default.  As mentioned elsewhere, it is important
17501 +         to enable the grsec_lock entry once you have finished modifying
17502 +         the sysctl entries.
17503 +
17504 +endmenu
17505 +menu "Logging Options"
17506 +depends on GRKERNSEC
17507 +
17508 +config GRKERNSEC_FLOODTIME
17509 +       int "Seconds in between log messages (minimum)"
17510 +       default 10
17511 +       help
17512 +         This option allows you to enforce the number of seconds between
17513 +         grsecurity log messages.  The default should be suitable for most
17514 +         people, however, if you choose to change it, choose a value small enough
17515 +         to allow informative logs to be produced, but large enough to
17516 +         prevent flooding.
17517 +
17518 +config GRKERNSEC_FLOODBURST
17519 +       int "Number of messages in a burst (maximum)"
17520 +       default 4
17521 +       help
17522 +         This option allows you to choose the maximum number of messages allowed
17523 +         within the flood time interval you chose in a separate option.  The
17524 +         default should be suitable for most people, however if you find that
17525 +         many of your logs are being interpreted as flooding, you may want to
17526 +         raise this value.
17527 +
17528 +endmenu
17529 +
17530 +endmenu
17531 diff -urNp linux-2.6.16.2/grsecurity/Makefile linux-2.6.16.2/grsecurity/Makefile
17532 --- linux-2.6.16.2/grsecurity/Makefile  1969-12-31 19:00:00.000000000 -0500
17533 +++ linux-2.6.16.2/grsecurity/Makefile  2006-04-09 21:23:54.000000000 -0400
17534 @@ -0,0 +1,20 @@
17535 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
17536 +# during 2001-2005 it has been completely redesigned by Brad Spengler
17537 +# into an RBAC system
17538 +#
17539 +# All code in this directory and various hooks inserted throughout the kernel
17540 +# are copyright Brad Spengler, and released under the GPL v2 or higher
17541 +
17542 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
17543 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
17544 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
17545 +
17546 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
17547 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
17548 +       gracl_learn.o grsec_log.o
17549 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
17550 +
17551 +ifndef CONFIG_GRKERNSEC
17552 +obj-y += grsec_disabled.o
17553 +endif
17554 +
17555 diff -urNp linux-2.6.16.2/include/asm-alpha/a.out.h linux-2.6.16.2/include/asm-alpha/a.out.h
17556 --- linux-2.6.16.2/include/asm-alpha/a.out.h    2006-04-07 12:56:47.000000000 -0400
17557 +++ linux-2.6.16.2/include/asm-alpha/a.out.h    2006-04-09 21:23:54.000000000 -0400
17558 @@ -98,7 +98,7 @@ struct exec
17559         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
17560                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
17561  
17562 -#define STACK_TOP \
17563 +#define __STACK_TOP \
17564    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
17565  
17566  #endif
17567 diff -urNp linux-2.6.16.2/include/asm-alpha/elf.h linux-2.6.16.2/include/asm-alpha/elf.h
17568 --- linux-2.6.16.2/include/asm-alpha/elf.h      2006-04-07 12:56:47.000000000 -0400
17569 +++ linux-2.6.16.2/include/asm-alpha/elf.h      2006-04-09 21:23:54.000000000 -0400
17570 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
17571  
17572  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
17573  
17574 +#ifdef CONFIG_PAX_ASLR
17575 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
17576 +
17577 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17578 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
17579 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17580 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
17581 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17582 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
17583 +#endif
17584 +
17585  /* $0 is set by ld.so to a pointer to a function which might be 
17586     registered using atexit.  This provides a mean for the dynamic
17587     linker to call DT_FINI functions for shared libraries that have
17588 diff -urNp linux-2.6.16.2/include/asm-alpha/page.h linux-2.6.16.2/include/asm-alpha/page.h
17589 --- linux-2.6.16.2/include/asm-alpha/page.h     2006-04-07 12:56:47.000000000 -0400
17590 +++ linux-2.6.16.2/include/asm-alpha/page.h     2006-04-09 21:23:54.000000000 -0400
17591 @@ -96,6 +96,15 @@ typedef unsigned long pgprot_t;
17592  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
17593                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17594  
17595 +#ifdef CONFIG_PAX_PAGEEXEC
17596 +#ifdef CONFIG_PAX_MPROTECT
17597 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17598 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17599 +#else
17600 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
17601 +#endif
17602 +#endif
17603 +
17604  #endif /* __KERNEL__ */
17605  
17606  #include <asm-generic/page.h>
17607 diff -urNp linux-2.6.16.2/include/asm-alpha/pgtable.h linux-2.6.16.2/include/asm-alpha/pgtable.h
17608 --- linux-2.6.16.2/include/asm-alpha/pgtable.h  2006-04-07 12:56:47.000000000 -0400
17609 +++ linux-2.6.16.2/include/asm-alpha/pgtable.h  2006-04-09 21:23:54.000000000 -0400
17610 @@ -102,6 +102,17 @@ struct vm_area_struct;
17611  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
17612  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
17613  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
17614 +
17615 +#ifdef CONFIG_PAX_PAGEEXEC
17616 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
17617 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
17618 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
17619 +#else
17620 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17621 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17622 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17623 +#endif
17624 +
17625  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
17626  
17627  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
17628 diff -urNp linux-2.6.16.2/include/asm-arm/a.out.h linux-2.6.16.2/include/asm-arm/a.out.h
17629 --- linux-2.6.16.2/include/asm-arm/a.out.h      2006-04-07 12:56:47.000000000 -0400
17630 +++ linux-2.6.16.2/include/asm-arm/a.out.h      2006-04-09 21:23:54.000000000 -0400
17631 @@ -28,7 +28,7 @@ struct exec
17632  #define M_ARM 103
17633  
17634  #ifdef __KERNEL__
17635 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
17636 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
17637                          TASK_SIZE : TASK_SIZE_26)
17638  #endif
17639  
17640 diff -urNp linux-2.6.16.2/include/asm-arm/elf.h linux-2.6.16.2/include/asm-arm/elf.h
17641 --- linux-2.6.16.2/include/asm-arm/elf.h        2006-04-07 12:56:47.000000000 -0400
17642 +++ linux-2.6.16.2/include/asm-arm/elf.h        2006-04-09 21:23:54.000000000 -0400
17643 @@ -56,6 +56,17 @@ typedef struct user_fp elf_fpregset_t;
17644  
17645  #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
17646  
17647 +#ifdef CONFIG_PAX_ASLR
17648 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x00008000UL
17649 +
17650 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17651 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
17652 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17653 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
17654 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17655 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
17656 +#endif
17657 +
17658  /* When the program starts, a1 contains a pointer to a function to be 
17659     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
17660     have no such handler.  */
17661 diff -urNp linux-2.6.16.2/include/asm-i386/a.out.h linux-2.6.16.2/include/asm-i386/a.out.h
17662 --- linux-2.6.16.2/include/asm-i386/a.out.h     2006-04-07 12:56:47.000000000 -0400
17663 +++ linux-2.6.16.2/include/asm-i386/a.out.h     2006-04-09 21:23:54.000000000 -0400
17664 @@ -19,7 +19,11 @@ struct exec
17665  
17666  #ifdef __KERNEL__
17667  
17668 -#define STACK_TOP      TASK_SIZE
17669 +#ifdef CONFIG_PAX_SEGMEXEC
17670 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
17671 +#else
17672 +#define __STACK_TOP TASK_SIZE
17673 +#endif
17674  
17675  #endif
17676  
17677 diff -urNp linux-2.6.16.2/include/asm-i386/auxvec.h linux-2.6.16.2/include/asm-i386/auxvec.h
17678 --- linux-2.6.16.2/include/asm-i386/auxvec.h    2006-04-07 12:56:47.000000000 -0400
17679 +++ linux-2.6.16.2/include/asm-i386/auxvec.h    2006-04-09 21:23:54.000000000 -0400
17680 @@ -5,7 +5,9 @@
17681   * Architecture-neutral AT_ values in 0-17, leave some room
17682   * for more of them, start the x86-specific ones at 32.
17683   */
17684 +#ifndef CONFIG_PAX_NOVSYSCALL
17685  #define AT_SYSINFO             32
17686  #define AT_SYSINFO_EHDR                33
17687 +#endif
17688  
17689  #endif
17690 diff -urNp linux-2.6.16.2/include/asm-i386/desc.h linux-2.6.16.2/include/asm-i386/desc.h
17691 --- linux-2.6.16.2/include/asm-i386/desc.h      2006-04-07 12:56:47.000000000 -0400
17692 +++ linux-2.6.16.2/include/asm-i386/desc.h      2006-04-09 21:24:03.000000000 -0400
17693 @@ -10,11 +10,13 @@
17694  
17695  #include <linux/preempt.h>
17696  #include <linux/smp.h>
17697 -#include <linux/percpu.h>
17698 +#include <linux/sched.h>
17699  
17700  #include <asm/mmu.h>
17701 +#include <asm/pgtable.h>
17702 +#include <asm/tlbflush.h>
17703  
17704 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
17705 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
17706  
17707  DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
17708  
17709 @@ -24,13 +26,53 @@ struct Xgt_desc_struct {
17710         unsigned short pad;
17711  } __attribute__ ((packed));
17712  
17713 -extern struct Xgt_desc_struct idt_descr;
17714 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
17715 -
17716 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
17717  
17718  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
17719  {
17720 -       return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
17721 +       return cpu_gdt_table[cpu];
17722 +}
17723 +
17724 +#define pax_open_kernel(cr0)           \
17725 +do {                                   \
17726 +       typecheck(unsigned long,cr0);   \
17727 +       preempt_disable();              \
17728 +       cr0 = read_cr0();               \
17729 +       write_cr0(cr0 & ~0x10000UL);    \
17730 +} while(0)
17731 +
17732 +#define pax_close_kernel(cr0)          \
17733 +do {                                   \
17734 +       typecheck(unsigned long,cr0);   \
17735 +       write_cr0(cr0);                 \
17736 +       preempt_enable_no_resched();    \
17737 +} while(0)
17738 +
17739 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
17740 +{
17741 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17742 +       unsigned long base = mm->context.user_cs_base;
17743 +       unsigned long limit = mm->context.user_cs_limit;
17744 +
17745 +#ifdef CONFIG_PAX_KERNEXEC
17746 +       unsigned long cr0;
17747 +
17748 +       pax_open_kernel(cr0);
17749 +#endif
17750 +
17751 +       if (likely(limit)) {
17752 +               limit -= 1UL;
17753 +               limit >>= 12;
17754 +       }
17755 +
17756 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
17757 +       get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
17758 +
17759 +#ifdef CONFIG_PAX_KERNEXEC
17760 +       pax_close_kernel(cr0);
17761 +#endif
17762 +
17763 +#endif
17764  }
17765  
17766  #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
17767 @@ -50,7 +92,7 @@ static inline struct desc_struct *get_cp
17768   * This is the ldt that every process will get unless we need
17769   * something other than this.
17770   */
17771 -extern struct desc_struct default_ldt[];
17772 +extern const struct desc_struct default_ldt[];
17773  extern void set_intr_gate(unsigned int irq, void * addr);
17774  
17775  #define _set_tssldt_desc(n,addr,limit,type) \
17776 @@ -64,7 +106,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
17777         "rorl $16,%1" \
17778         : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
17779  
17780 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
17781 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
17782  {
17783         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
17784                 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
17785 @@ -72,11 +114,28 @@ static inline void __set_tss_desc(unsign
17786  
17787  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
17788  
17789 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
17790 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
17791  {
17792         _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
17793  }
17794  
17795 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
17796 +{
17797 +
17798 +#ifdef CONFIG_PAX_KERNEXEC
17799 +       unsigned long cr0;
17800 +
17801 +       pax_open_kernel(cr0);
17802 +#endif
17803 +
17804 +       _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
17805 +
17806 +#ifdef CONFIG_PAX_KERNEXEC
17807 +       pax_close_kernel(cr0);
17808 +#endif
17809 +
17810 +}
17811 +
17812  #define LDT_entry_a(info) \
17813         ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
17814  
17815 @@ -90,7 +149,7 @@ static inline void set_ldt_desc(unsigned
17816         ((info)->seg_32bit << 22) | \
17817         ((info)->limit_in_pages << 23) | \
17818         ((info)->useable << 20) | \
17819 -       0x7000)
17820 +       0x7100)
17821  
17822  #define LDT_empty(info) (\
17823         (info)->base_addr       == 0    && \
17824 @@ -134,7 +193,7 @@ static inline void clear_LDT(void)
17825   */
17826  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
17827  {
17828 -       void *segments = pc->ldt;
17829 +       const void *segments = pc->ldt;
17830         int count = pc->size;
17831  
17832         if (likely(!count)) {
17833 @@ -162,6 +221,22 @@ static inline unsigned long get_desc_bas
17834         return base;
17835  }
17836  
17837 +static inline void _load_LDT(mm_context_t *pc)
17838 +{
17839 +       int cpu = get_cpu();
17840 +       const void *segments = pc->ldt;
17841 +       int count = pc->size;
17842 +
17843 +       if (likely(!count)) {
17844 +               segments = &default_ldt[0];
17845 +               count = 5;
17846 +       }
17847 +               
17848 +       __set_ldt_desc(cpu, segments, count);
17849 +       load_LDT_desc();
17850 +       put_cpu();
17851 +}
17852 +
17853  #endif /* !__ASSEMBLY__ */
17854  
17855  #endif
17856 diff -urNp linux-2.6.16.2/include/asm-i386/elf.h linux-2.6.16.2/include/asm-i386/elf.h
17857 --- linux-2.6.16.2/include/asm-i386/elf.h       2006-04-07 12:56:47.000000000 -0400
17858 +++ linux-2.6.16.2/include/asm-i386/elf.h       2006-04-09 21:23:54.000000000 -0400
17859 @@ -71,7 +71,22 @@ typedef struct user_fxsr_struct elf_fpxr
17860     the loader.  We need to make sure that it is out of the way of the program
17861     that it will "exec", and that there is sufficient room for the brk.  */
17862  
17863 +#ifdef CONFIG_PAX_SEGMEXEC
17864 +#define ELF_ET_DYN_BASE         ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
17865 +#else
17866  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
17867 +#endif
17868 +
17869 +#ifdef CONFIG_PAX_ASLR
17870 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
17871 +
17872 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17873 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
17874 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17875 +#define PAX_DELTA_EXEC_LEN(tsk)                15
17876 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17877 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
17878 +#endif
17879  
17880  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
17881     now struct_user_regs, they are different) */
17882 @@ -131,7 +146,14 @@ extern int dump_task_extended_fpu (struc
17883  
17884  #define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
17885  #define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
17886 +
17887 +#ifndef CONFIG_PAX_NOVSYSCALL
17888 +#ifdef CONFIG_PAX_SEGMEXEC
17889 +#define VSYSCALL_ENTRY ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
17890 +#else
17891  #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
17892 +#endif
17893 +
17894  extern void __kernel_vsyscall;
17895  
17896  #define ARCH_DLINFO                                            \
17897 @@ -187,3 +209,5 @@ do {                                                                              \
17898  #endif
17899  
17900  #endif
17901 +
17902 +#endif
17903 diff -urNp linux-2.6.16.2/include/asm-i386/i387.h linux-2.6.16.2/include/asm-i386/i387.h
17904 --- linux-2.6.16.2/include/asm-i386/i387.h      2006-04-07 12:56:47.000000000 -0400
17905 +++ linux-2.6.16.2/include/asm-i386/i387.h      2006-04-09 21:23:54.000000000 -0400
17906 @@ -30,8 +30,8 @@ extern void init_fpu(struct task_struct 
17907   */
17908  #define restore_fpu(tsk)                       \
17909         alternative_input(                      \
17910 -               "nop ; frstor %1",              \
17911 -               "fxrstor %1",                   \
17912 +               "nop ; frstor %2",              \
17913 +               "fxrstor %2",                   \
17914                 X86_FEATURE_FXSR,               \
17915                 "m" ((tsk)->thread.i387.fxsave))
17916  
17917 diff -urNp linux-2.6.16.2/include/asm-i386/mach-default/apm.h linux-2.6.16.2/include/asm-i386/mach-default/apm.h
17918 --- linux-2.6.16.2/include/asm-i386/mach-default/apm.h  2006-04-07 12:56:47.000000000 -0400
17919 +++ linux-2.6.16.2/include/asm-i386/mach-default/apm.h  2006-04-09 21:23:54.000000000 -0400
17920 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
17921         __asm__ __volatile__(APM_DO_ZERO_SEGS
17922                 "pushl %%edi\n\t"
17923                 "pushl %%ebp\n\t"
17924 -               "lcall *%%cs:apm_bios_entry\n\t"
17925 +               "lcall *%%ss:apm_bios_entry\n\t"
17926                 "setc %%al\n\t"
17927                 "popl %%ebp\n\t"
17928                 "popl %%edi\n\t"
17929 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
17930         __asm__ __volatile__(APM_DO_ZERO_SEGS
17931                 "pushl %%edi\n\t"
17932                 "pushl %%ebp\n\t"
17933 -               "lcall *%%cs:apm_bios_entry\n\t"
17934 +               "lcall *%%ss:apm_bios_entry\n\t"
17935                 "setc %%bl\n\t"
17936                 "popl %%ebp\n\t"
17937                 "popl %%edi\n\t"
17938 diff -urNp linux-2.6.16.2/include/asm-i386/mman.h linux-2.6.16.2/include/asm-i386/mman.h
17939 --- linux-2.6.16.2/include/asm-i386/mman.h      2006-04-07 12:56:47.000000000 -0400
17940 +++ linux-2.6.16.2/include/asm-i386/mman.h      2006-04-09 21:23:54.000000000 -0400
17941 @@ -11,6 +11,10 @@
17942  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
17943  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
17944  
17945 +#ifdef CONFIG_PAX_SEGMEXEC
17946 +#define MAP_MIRROR     0x20000
17947 +#endif
17948 +
17949  #define MCL_CURRENT    1               /* lock all current mappings */
17950  #define MCL_FUTURE     2               /* lock all future mappings */
17951  
17952 diff -urNp linux-2.6.16.2/include/asm-i386/mmu_context.h linux-2.6.16.2/include/asm-i386/mmu_context.h
17953 --- linux-2.6.16.2/include/asm-i386/mmu_context.h       2006-04-07 12:56:47.000000000 -0400
17954 +++ linux-2.6.16.2/include/asm-i386/mmu_context.h       2006-04-09 21:23:54.000000000 -0400
17955 @@ -46,6 +46,13 @@ static inline void switch_mm(struct mm_s
17956                  */
17957                 if (unlikely(prev->context.ldt != next->context.ldt))
17958                         load_LDT_nolock(&next->context, cpu);
17959 +
17960 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17961 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
17962 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
17963 +#endif
17964 +
17965 +               set_user_cs(next, cpu);
17966         }
17967  #ifdef CONFIG_SMP
17968         else {
17969 @@ -58,6 +65,12 @@ static inline void switch_mm(struct mm_s
17970                          */
17971                         load_cr3(next->pgd);
17972                         load_LDT_nolock(&next->context, cpu);
17973 +
17974 +#ifdef CONFIG_PAX_PAGEEXEC
17975 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
17976 +#endif
17977 +
17978 +                       set_user_cs(next, cpu);
17979                 }
17980         }
17981  #endif
17982 diff -urNp linux-2.6.16.2/include/asm-i386/mmu.h linux-2.6.16.2/include/asm-i386/mmu.h
17983 --- linux-2.6.16.2/include/asm-i386/mmu.h       2006-04-07 12:56:47.000000000 -0400
17984 +++ linux-2.6.16.2/include/asm-i386/mmu.h       2006-04-09 21:23:54.000000000 -0400
17985 @@ -12,6 +12,17 @@ typedef struct { 
17986         int size;
17987         struct semaphore sem;
17988         void *ldt;
17989 +
17990 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17991 +       unsigned long user_cs_base;
17992 +       unsigned long user_cs_limit;
17993 +
17994 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17995 +       cpumask_t cpu_user_cs_mask;
17996 +#endif
17997 +
17998 +#endif
17999 +
18000  } mm_context_t;
18001  
18002  #endif
18003 diff -urNp linux-2.6.16.2/include/asm-i386/module.h linux-2.6.16.2/include/asm-i386/module.h
18004 --- linux-2.6.16.2/include/asm-i386/module.h    2006-04-07 12:56:47.000000000 -0400
18005 +++ linux-2.6.16.2/include/asm-i386/module.h    2006-04-09 21:23:54.000000000 -0400
18006 @@ -72,6 +72,12 @@ struct mod_arch_specific
18007  #define MODULE_STACKSIZE ""
18008  #endif
18009  
18010 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
18011 +#ifdef CONFIG_GRKERNSEC
18012 +#define MODULE_GRSEC "GRSECURITY "
18013 +#else
18014 +#define MODULE_GRSEC ""
18015 +#endif
18016 +
18017 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
18018  
18019  #endif /* _ASM_I386_MODULE_H */
18020 diff -urNp linux-2.6.16.2/include/asm-i386/page.h linux-2.6.16.2/include/asm-i386/page.h
18021 --- linux-2.6.16.2/include/asm-i386/page.h      2006-04-07 12:56:47.000000000 -0400
18022 +++ linux-2.6.16.2/include/asm-i386/page.h      2006-04-09 21:24:03.000000000 -0400
18023 @@ -57,7 +57,6 @@ typedef struct { unsigned long long pgpr
18024  typedef struct { unsigned long pte_low; } pte_t;
18025  typedef struct { unsigned long pgd; } pgd_t;
18026  typedef struct { unsigned long pgprot; } pgprot_t;
18027 -#define boot_pte_t pte_t /* or would you rather have a typedef */
18028  #define pte_val(x)     ((x).pte_low)
18029  #define HPAGE_SHIFT    22
18030  #endif
18031 @@ -118,6 +117,15 @@ extern int page_is_ram(unsigned long pag
18032  #endif
18033  #define __KERNEL_START         (__PAGE_OFFSET + __PHYSICAL_START)
18034  
18035 +#ifdef CONFIG_PAX_KERNEXEC
18036 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + ((__PHYSICAL_START + ~(4*1024*1024)) & (4*1024*1024)))
18037 +#ifndef __ASSEMBLY__
18038 +extern unsigned char MODULES_VADDR[];
18039 +extern unsigned char MODULES_END[];
18040 +#endif
18041 +#else
18042 +#define __KERNEL_TEXT_OFFSET   (0)
18043 +#endif
18044  
18045  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
18046  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
18047 @@ -139,6 +147,19 @@ extern int page_is_ram(unsigned long pag
18048         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
18049                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18050  
18051 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18052 +#ifdef CONFIG_PAX_MPROTECT
18053 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18054 +                         ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
18055 +#else
18056 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
18057 +#endif
18058 +#endif
18059 +
18060 +#ifdef CONFIG_PAX_PAGEEXEC
18061 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
18062 +#endif
18063 +
18064  #endif /* __KERNEL__ */
18065  
18066  #include <asm-generic/page.h>
18067 diff -urNp linux-2.6.16.2/include/asm-i386/pgalloc.h linux-2.6.16.2/include/asm-i386/pgalloc.h
18068 --- linux-2.6.16.2/include/asm-i386/pgalloc.h   2006-04-07 12:56:47.000000000 -0400
18069 +++ linux-2.6.16.2/include/asm-i386/pgalloc.h   2006-04-09 21:23:54.000000000 -0400
18070 @@ -3,11 +3,12 @@
18071  
18072  #include <linux/config.h>
18073  #include <asm/fixmap.h>
18074 +#include <asm/desc.h>
18075  #include <linux/threads.h>
18076  #include <linux/mm.h>          /* for struct page */
18077  
18078  #define pmd_populate_kernel(mm, pmd, pte) \
18079 -               set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
18080 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
18081  
18082  #define pmd_populate(mm, pmd, pte)                             \
18083         set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
18084 diff -urNp linux-2.6.16.2/include/asm-i386/pgtable.h linux-2.6.16.2/include/asm-i386/pgtable.h
18085 --- linux-2.6.16.2/include/asm-i386/pgtable.h   2006-04-07 12:56:47.000000000 -0400
18086 +++ linux-2.6.16.2/include/asm-i386/pgtable.h   2006-04-09 21:23:54.000000000 -0400
18087 @@ -34,7 +34,6 @@ struct vm_area_struct;
18088   */
18089  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
18090  extern unsigned long empty_zero_page[1024];
18091 -extern pgd_t swapper_pg_dir[1024];
18092  extern kmem_cache_t *pgd_cache;
18093  extern kmem_cache_t *pmd_cache;
18094  extern spinlock_t pgd_lock;
18095 @@ -59,6 +58,11 @@ void paging_init(void);
18096  # include <asm/pgtable-2level-defs.h>
18097  #endif
18098  
18099 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
18100 +#ifdef CONFIG_X86_PAE
18101 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
18102 +#endif
18103 +
18104  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
18105  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
18106  
18107 @@ -68,9 +72,11 @@ void paging_init(void);
18108  #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
18109  #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
18110  
18111 +#ifndef CONFIG_X86_PAE
18112  #define TWOLEVEL_PGDIR_SHIFT   22
18113  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
18114  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
18115 +#endif
18116  
18117  /* Just any arbitrary offset to the start of the vmalloc VM area: the
18118   * current 8MB value just means that there will be a 8MB "hole" after the
18119 @@ -141,17 +147,26 @@ void paging_init(void);
18120  
18121  #define PAGE_SHARED_EXEC \
18122         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
18123 -#define PAGE_COPY_NOEXEC \
18124 -       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18125  #define PAGE_COPY_EXEC \
18126         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18127 -#define PAGE_COPY \
18128 -       PAGE_COPY_NOEXEC
18129  #define PAGE_READONLY \
18130         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18131  #define PAGE_READONLY_EXEC \
18132         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18133  
18134 +#ifdef CONFIG_PAX_PAGEEXEC
18135 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
18136 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
18137 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
18138 +#else
18139 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18140 +# define PAGE_COPY_NOEXEC \
18141 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18142 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18143 +#endif
18144 +
18145 +#define PAGE_COPY \
18146 +       PAGE_COPY_NOEXEC
18147  #define _PAGE_KERNEL \
18148         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
18149  #define _PAGE_KERNEL_EXEC \
18150 @@ -176,18 +191,18 @@ extern unsigned long long __PAGE_KERNEL,
18151   * This is the closest we can get..
18152   */
18153  #define __P000 PAGE_NONE
18154 -#define __P001 PAGE_READONLY
18155 -#define __P010 PAGE_COPY
18156 -#define __P011 PAGE_COPY
18157 +#define __P001 PAGE_READONLY_NOEXEC
18158 +#define __P010 PAGE_COPY_NOEXEC
18159 +#define __P011 PAGE_COPY_NOEXEC
18160  #define __P100 PAGE_READONLY_EXEC
18161  #define __P101 PAGE_READONLY_EXEC
18162  #define __P110 PAGE_COPY_EXEC
18163  #define __P111 PAGE_COPY_EXEC
18164  
18165  #define __S000 PAGE_NONE
18166 -#define __S001 PAGE_READONLY
18167 -#define __S010 PAGE_SHARED
18168 -#define __S011 PAGE_SHARED
18169 +#define __S001 PAGE_READONLY_NOEXEC
18170 +#define __S010 PAGE_SHARED_NOEXEC
18171 +#define __S011 PAGE_SHARED_NOEXEC
18172  #define __S100 PAGE_READONLY_EXEC
18173  #define __S101 PAGE_READONLY_EXEC
18174  #define __S110 PAGE_SHARED_EXEC
18175 @@ -434,6 +449,9 @@ extern void noexec_setup(const char *str
18176  
18177  #endif /* !__ASSEMBLY__ */
18178  
18179 +#define HAVE_ARCH_UNMAPPED_AREA
18180 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
18181 +
18182  #ifdef CONFIG_FLATMEM
18183  #define kern_addr_valid(addr)  (1)
18184  #endif /* CONFIG_FLATMEM */
18185 diff -urNp linux-2.6.16.2/include/asm-i386/processor.h linux-2.6.16.2/include/asm-i386/processor.h
18186 --- linux-2.6.16.2/include/asm-i386/processor.h 2006-04-07 12:56:47.000000000 -0400
18187 +++ linux-2.6.16.2/include/asm-i386/processor.h 2006-04-09 21:23:54.000000000 -0400
18188 @@ -19,7 +19,6 @@
18189  #include <linux/cache.h>
18190  #include <linux/config.h>
18191  #include <linux/threads.h>
18192 -#include <asm/percpu.h>
18193  
18194  /* flag for disabling the tsc */
18195  extern int tsc_disable;
18196 @@ -90,8 +89,6 @@ struct cpuinfo_x86 {
18197  
18198  extern struct cpuinfo_x86 boot_cpu_data;
18199  extern struct cpuinfo_x86 new_cpu_data;
18200 -extern struct tss_struct doublefault_tss;
18201 -DECLARE_PER_CPU(struct tss_struct, init_tss);
18202  
18203  #ifdef CONFIG_SMP
18204  extern struct cpuinfo_x86 cpu_data[];
18205 @@ -320,10 +317,19 @@ extern int bootloader_type;
18206   */
18207  #define TASK_SIZE      (PAGE_OFFSET)
18208  
18209 +#ifdef CONFIG_PAX_SEGMEXEC
18210 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
18211 +#endif
18212 +
18213  /* This decides where the kernel will search for a free chunk of vm
18214   * space during mmap's.
18215   */
18216 +
18217 +#ifdef CONFIG_PAX_SEGMEXEC
18218 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
18219 +#else
18220  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
18221 +#endif
18222  
18223  #define HAVE_ARCH_PICK_MMAP_LAYOUT
18224  
18225 @@ -439,6 +445,9 @@ struct tss_struct {
18226  
18227  #define ARCH_MIN_TASKALIGN     16
18228  
18229 +extern struct tss_struct doublefault_tss;
18230 +extern struct tss_struct init_tss[NR_CPUS];
18231 +
18232  struct thread_struct {
18233  /* cached TLS descriptors. */
18234         struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
18235 @@ -467,6 +476,7 @@ struct thread_struct {
18236  };
18237  
18238  #define INIT_THREAD  {                                                 \
18239 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
18240         .vm86_info = NULL,                                              \
18241         .sysenter_cs = __KERNEL_CS,                                     \
18242         .io_bitmap_ptr = NULL,                                          \
18243 @@ -479,7 +489,7 @@ struct thread_struct {
18244   * be within the limit.
18245   */
18246  #define INIT_TSS  {                                                    \
18247 -       .esp0           = sizeof(init_stack) + (long)&init_stack,       \
18248 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
18249         .ss0            = __KERNEL_DS,                                  \
18250         .ss1            = __KERNEL_CS,                                  \
18251         .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,                     \
18252 @@ -555,11 +565,7 @@ void show_trace(struct task_struct *task
18253  unsigned long get_wchan(struct task_struct *p);
18254  
18255  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
18256 -#define KSTK_TOP(info)                                                 \
18257 -({                                                                     \
18258 -       unsigned long *__ptr = (unsigned long *)(info);                 \
18259 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
18260 -})
18261 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
18262  
18263  /*
18264   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
18265 @@ -574,7 +580,7 @@ unsigned long get_wchan(struct task_stru
18266  #define task_pt_regs(task)                                             \
18267  ({                                                                     \
18268         struct pt_regs *__regs__;                                       \
18269 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
18270 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
18271         __regs__ - 1;                                                   \
18272  })
18273  
18274 @@ -698,7 +704,7 @@ static inline void rep_nop(void)
18275  static inline void prefetch(const void *x)
18276  {
18277         alternative_input(ASM_NOP4,
18278 -                         "prefetchnta (%1)",
18279 +                         "prefetchnta (%2)",
18280                           X86_FEATURE_XMM,
18281                           "r" (x));
18282  }
18283 @@ -712,7 +718,7 @@ static inline void prefetch(const void *
18284  static inline void prefetchw(const void *x)
18285  {
18286         alternative_input(ASM_NOP4,
18287 -                         "prefetchw (%1)",
18288 +                         "prefetchw (%2)",
18289                           X86_FEATURE_3DNOW,
18290                           "r" (x));
18291  }
18292 diff -urNp linux-2.6.16.2/include/asm-i386/ptrace.h linux-2.6.16.2/include/asm-i386/ptrace.h
18293 --- linux-2.6.16.2/include/asm-i386/ptrace.h    2006-04-07 12:56:47.000000000 -0400
18294 +++ linux-2.6.16.2/include/asm-i386/ptrace.h    2006-04-09 21:23:54.000000000 -0400
18295 @@ -65,17 +65,18 @@ struct task_struct;
18296  extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
18297  
18298  /*
18299 - * user_mode_vm(regs) determines whether a register set came from user mode.
18300 + * user_mode(regs) determines whether a register set came from user mode.
18301   * This is true if V8086 mode was enabled OR if the register set was from
18302   * protected mode with RPL-3 CS value.  This tricky test checks that with
18303   * one comparison.  Many places in the kernel can bypass this full check
18304 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
18305 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
18306 + * be used.
18307   */
18308 -static inline int user_mode(struct pt_regs *regs)
18309 +static inline int user_mode_novm(struct pt_regs *regs)
18310  {
18311         return (regs->xcs & 3) != 0;
18312  }
18313 -static inline int user_mode_vm(struct pt_regs *regs)
18314 +static inline int user_mode(struct pt_regs *regs)
18315  {
18316         return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
18317  }
18318 diff -urNp linux-2.6.16.2/include/asm-i386/system.h linux-2.6.16.2/include/asm-i386/system.h
18319 --- linux-2.6.16.2/include/asm-i386/system.h    2006-04-07 12:56:47.000000000 -0400
18320 +++ linux-2.6.16.2/include/asm-i386/system.h    2006-04-09 21:23:54.000000000 -0400
18321 @@ -5,6 +5,7 @@
18322  #include <linux/kernel.h>
18323  #include <asm/segment.h>
18324  #include <asm/cpufeature.h>
18325 +#include <asm/page.h>
18326  #include <linux/bitops.h> /* for LOCK_PREFIX */
18327  
18328  #ifdef __KERNEL__
18329 @@ -151,7 +152,7 @@ static inline unsigned long get_limit(un
18330         unsigned long __limit;
18331         __asm__("lsll %1,%0"
18332                 :"=r" (__limit):"r" (segment));
18333 -       return __limit+1;
18334 +       return __limit;
18335  }
18336  
18337  #define nop() __asm__ __volatile__ ("nop")
18338 @@ -379,15 +380,15 @@ struct alt_instr { 
18339         asm volatile ("661:\n\t" oldinstr "\n662:\n"                 \
18340                       ".section .altinstructions,\"a\"\n"            \
18341                       "  .align 4\n"                                   \
18342 -                     "  .long 661b\n"            /* label */          \
18343 +                     "  .long 661b + %c1\n"      /* label */          \
18344                       "  .long 663f\n"            /* new instruction */         \
18345                       "  .byte %c0\n"             /* feature bit */    \
18346                       "  .byte 662b-661b\n"       /* sourcelen */      \
18347                       "  .byte 664f-663f\n"       /* replacementlen */ \
18348                       ".previous\n"                                             \
18349 -                     ".section .altinstr_replacement,\"ax\"\n"                 \
18350 +                     ".section .altinstr_replacement,\"a\"\n"                  \
18351                       "663:\n\t" newinstr "\n664:\n"   /* replacement */    \
18352 -                     ".previous" :: "i" (feature) : "memory")  
18353 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET) : "memory")  
18354  
18355  /*
18356   * Alternative inline assembly with input.
18357 @@ -403,15 +404,15 @@ struct alt_instr { 
18358         asm volatile ("661:\n\t" oldinstr "\n662:\n"                            \
18359                       ".section .altinstructions,\"a\"\n"                       \
18360                       "  .align 4\n"                                            \
18361 -                     "  .long 661b\n"            /* label */                   \
18362 +                     "  .long 661b + %c1\n"      /* label */                   \
18363                       "  .long 663f\n"            /* new instruction */         \
18364                       "  .byte %c0\n"             /* feature bit */             \
18365                       "  .byte 662b-661b\n"       /* sourcelen */               \
18366                       "  .byte 664f-663f\n"       /* replacementlen */          \
18367                       ".previous\n"                                             \
18368 -                     ".section .altinstr_replacement,\"ax\"\n"                 \
18369 +                     ".section .altinstr_replacement,\"a\"\n"                  \
18370                       "663:\n\t" newinstr "\n664:\n"   /* replacement */        \
18371 -                     ".previous" :: "i" (feature), ##input)
18372 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET), ##input)
18373  
18374  /*
18375   * Force strict CPU ordering.
18376 @@ -557,6 +558,6 @@ static inline void sched_cacheflush(void
18377         wbinvd();
18378  }
18379  
18380 -extern unsigned long arch_align_stack(unsigned long sp);
18381 +#define arch_align_stack(x) (x)
18382  
18383  #endif
18384 diff -urNp linux-2.6.16.2/include/asm-ia64/elf.h linux-2.6.16.2/include/asm-ia64/elf.h
18385 --- linux-2.6.16.2/include/asm-ia64/elf.h       2006-04-07 12:56:47.000000000 -0400
18386 +++ linux-2.6.16.2/include/asm-ia64/elf.h       2006-04-09 21:23:54.000000000 -0400
18387 @@ -163,6 +163,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
18388  typedef struct ia64_fpreg elf_fpreg_t;
18389  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
18390  
18391 +#ifdef CONFIG_PAX_ASLR
18392 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
18393 +
18394 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18395 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
18396 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18397 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
18398 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18399 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
18400 +#endif
18401  
18402  
18403  struct pt_regs;        /* forward declaration... */
18404 diff -urNp linux-2.6.16.2/include/asm-ia64/page.h linux-2.6.16.2/include/asm-ia64/page.h
18405 --- linux-2.6.16.2/include/asm-ia64/page.h      2006-04-07 12:56:47.000000000 -0400
18406 +++ linux-2.6.16.2/include/asm-ia64/page.h      2006-04-09 21:23:54.000000000 -0400
18407 @@ -219,4 +219,13 @@ get_order (unsigned long size)
18408                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
18409                                           ? VM_EXEC : 0))
18410  
18411 +#ifdef CONFIG_PAX_PAGEEXEC
18412 +#ifdef CONFIG_PAX_MPROTECT
18413 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18414 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18415 +#else
18416 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18417 +#endif
18418 +#endif
18419 +
18420  #endif /* _ASM_IA64_PAGE_H */
18421 diff -urNp linux-2.6.16.2/include/asm-ia64/pgtable.h linux-2.6.16.2/include/asm-ia64/pgtable.h
18422 --- linux-2.6.16.2/include/asm-ia64/pgtable.h   2006-04-07 12:56:47.000000000 -0400
18423 +++ linux-2.6.16.2/include/asm-ia64/pgtable.h   2006-04-09 21:23:54.000000000 -0400
18424 @@ -144,6 +144,17 @@
18425  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
18426  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
18427  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
18428 +
18429 +#ifdef CONFIG_PAX_PAGEEXEC
18430 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
18431 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
18432 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
18433 +#else
18434 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18435 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18436 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18437 +#endif
18438 +
18439  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
18440  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
18441  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
18442 diff -urNp linux-2.6.16.2/include/asm-ia64/processor.h linux-2.6.16.2/include/asm-ia64/processor.h
18443 --- linux-2.6.16.2/include/asm-ia64/processor.h 2006-04-07 12:56:47.000000000 -0400
18444 +++ linux-2.6.16.2/include/asm-ia64/processor.h 2006-04-09 21:23:54.000000000 -0400
18445 @@ -284,7 +284,7 @@ struct thread_struct {
18446         .on_ustack =    0,                                      \
18447         .ksp =          0,                                      \
18448         .map_base =     DEFAULT_MAP_BASE,                       \
18449 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
18450 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
18451         .task_size =    DEFAULT_TASK_SIZE,                      \
18452         .last_fph_cpu =  -1,                                    \
18453         INIT_THREAD_IA32                                        \
18454 diff -urNp linux-2.6.16.2/include/asm-ia64/ustack.h linux-2.6.16.2/include/asm-ia64/ustack.h
18455 --- linux-2.6.16.2/include/asm-ia64/ustack.h    2006-04-07 12:56:47.000000000 -0400
18456 +++ linux-2.6.16.2/include/asm-ia64/ustack.h    2006-04-09 21:23:54.000000000 -0400
18457 @@ -11,6 +11,6 @@
18458  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
18459  /* Make a default stack size of 2GB */
18460  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
18461 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
18462 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
18463  
18464  #endif /* _ASM_IA64_USTACK_H */
18465 diff -urNp linux-2.6.16.2/include/asm-mips/a.out.h linux-2.6.16.2/include/asm-mips/a.out.h
18466 --- linux-2.6.16.2/include/asm-mips/a.out.h     2006-04-07 12:56:47.000000000 -0400
18467 +++ linux-2.6.16.2/include/asm-mips/a.out.h     2006-04-09 21:23:54.000000000 -0400
18468 @@ -36,10 +36,10 @@ struct exec
18469  #ifdef __KERNEL__
18470  
18471  #ifdef CONFIG_32BIT
18472 -#define STACK_TOP      TASK_SIZE
18473 +#define __STACK_TOP    TASK_SIZE
18474  #endif
18475  #ifdef CONFIG_64BIT
18476 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
18477 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
18478  #endif
18479  
18480  #endif
18481 diff -urNp linux-2.6.16.2/include/asm-mips/elf.h linux-2.6.16.2/include/asm-mips/elf.h
18482 --- linux-2.6.16.2/include/asm-mips/elf.h       2006-04-07 12:56:47.000000000 -0400
18483 +++ linux-2.6.16.2/include/asm-mips/elf.h       2006-04-09 21:23:54.000000000 -0400
18484 @@ -331,4 +331,15 @@ extern int dump_task_fpu(struct task_str
18485  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
18486  #endif
18487  
18488 +#ifdef CONFIG_PAX_ASLR
18489 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
18490 +
18491 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18492 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
18493 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18494 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
18495 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18496 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
18497 +#endif
18498 +
18499  #endif /* _ASM_ELF_H */
18500 diff -urNp linux-2.6.16.2/include/asm-mips/page.h linux-2.6.16.2/include/asm-mips/page.h
18501 --- linux-2.6.16.2/include/asm-mips/page.h      2006-04-07 12:56:47.000000000 -0400
18502 +++ linux-2.6.16.2/include/asm-mips/page.h      2006-04-09 21:23:54.000000000 -0400
18503 @@ -151,6 +151,15 @@ typedef struct { unsigned long pgprot; }
18504  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18505                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18506  
18507 +#ifdef CONFIG_PAX_PAGEEXEC
18508 +#ifdef CONFIG_PAX_MPROTECT
18509 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18510 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18511 +#else
18512 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18513 +#endif
18514 +#endif
18515 +
18516  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
18517  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
18518  
18519 diff -urNp linux-2.6.16.2/include/asm-parisc/a.out.h linux-2.6.16.2/include/asm-parisc/a.out.h
18520 --- linux-2.6.16.2/include/asm-parisc/a.out.h   2006-04-07 12:56:47.000000000 -0400
18521 +++ linux-2.6.16.2/include/asm-parisc/a.out.h   2006-04-09 21:23:54.000000000 -0400
18522 @@ -22,7 +22,7 @@ struct exec
18523  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
18524   * prumpf */
18525  
18526 -#define STACK_TOP      TASK_SIZE
18527 +#define __STACK_TOP    TASK_SIZE
18528  
18529  #endif
18530  
18531 diff -urNp linux-2.6.16.2/include/asm-parisc/elf.h linux-2.6.16.2/include/asm-parisc/elf.h
18532 --- linux-2.6.16.2/include/asm-parisc/elf.h     2006-04-07 12:56:47.000000000 -0400
18533 +++ linux-2.6.16.2/include/asm-parisc/elf.h     2006-04-09 21:23:54.000000000 -0400
18534 @@ -337,6 +337,17 @@ struct pt_regs;    /* forward declaration..
18535  
18536  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
18537  
18538 +#ifdef CONFIG_PAX_ASLR
18539 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
18540 +
18541 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18542 +#define PAX_DELTA_MMAP_LEN(tsk)                16
18543 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18544 +#define PAX_DELTA_EXEC_LEN(tsk)                16
18545 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18546 +#define PAX_DELTA_STACK_LEN(tsk)       16
18547 +#endif
18548 +
18549  /* This yields a mask that user programs can use to figure out what
18550     instruction set this CPU supports.  This could be done in user space,
18551     but it's not easy, and we've already done it here.  */
18552 diff -urNp linux-2.6.16.2/include/asm-parisc/page.h linux-2.6.16.2/include/asm-parisc/page.h
18553 --- linux-2.6.16.2/include/asm-parisc/page.h    2006-04-07 12:56:47.000000000 -0400
18554 +++ linux-2.6.16.2/include/asm-parisc/page.h    2006-04-09 21:23:54.000000000 -0400
18555 @@ -150,6 +150,15 @@ extern int npmem_ranges;
18556  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18557                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18558  
18559 +#ifdef CONFIG_PAX_PAGEEXEC
18560 +#ifdef CONFIG_PAX_MPROTECT
18561 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18562 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18563 +#else
18564 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18565 +#endif
18566 +#endif
18567 +
18568  #endif /* __KERNEL__ */
18569  
18570  #include <asm-generic/page.h>
18571 diff -urNp linux-2.6.16.2/include/asm-parisc/pgtable.h linux-2.6.16.2/include/asm-parisc/pgtable.h
18572 --- linux-2.6.16.2/include/asm-parisc/pgtable.h 2006-04-07 12:56:47.000000000 -0400
18573 +++ linux-2.6.16.2/include/asm-parisc/pgtable.h 2006-04-09 21:23:54.000000000 -0400
18574 @@ -212,6 +212,17 @@ extern  void *vmalloc_start;
18575  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
18576  #define PAGE_COPY       PAGE_EXECREAD
18577  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
18578 +
18579 +#ifdef CONFIG_PAX_PAGEEXEC
18580 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
18581 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
18582 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
18583 +#else
18584 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18585 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18586 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18587 +#endif
18588 +
18589  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
18590  #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
18591  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
18592 diff -urNp linux-2.6.16.2/include/asm-powerpc/a.out.h linux-2.6.16.2/include/asm-powerpc/a.out.h
18593 --- linux-2.6.16.2/include/asm-powerpc/a.out.h  2006-04-07 12:56:47.000000000 -0400
18594 +++ linux-2.6.16.2/include/asm-powerpc/a.out.h  2006-04-09 21:23:54.000000000 -0400
18595 @@ -23,12 +23,12 @@ struct exec
18596  #define STACK_TOP_USER64 TASK_SIZE_USER64
18597  #define STACK_TOP_USER32 TASK_SIZE_USER32
18598  
18599 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
18600 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
18601                    STACK_TOP_USER32 : STACK_TOP_USER64)
18602  
18603  #else /* __powerpc64__ */
18604  
18605 -#define STACK_TOP TASK_SIZE
18606 +#define __STACK_TOP TASK_SIZE
18607  
18608  #endif /* __powerpc64__ */
18609  #endif /* __KERNEL__ */
18610 diff -urNp linux-2.6.16.2/include/asm-powerpc/elf.h linux-2.6.16.2/include/asm-powerpc/elf.h
18611 --- linux-2.6.16.2/include/asm-powerpc/elf.h    2006-04-07 12:56:47.000000000 -0400
18612 +++ linux-2.6.16.2/include/asm-powerpc/elf.h    2006-04-09 21:23:54.000000000 -0400
18613 @@ -176,6 +176,26 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF
18614  
18615  #define ELF_ET_DYN_BASE         (0x08000000)
18616  
18617 +#ifdef CONFIG_PAX_ASLR
18618 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
18619 +
18620 +#ifdef __powerpc64__
18621 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18622 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
18623 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18624 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
18625 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18626 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 16 : 28)
18627 +#else
18628 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18629 +#define PAX_DELTA_MMAP_LEN(tsk)                15
18630 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18631 +#define PAX_DELTA_EXEC_LEN(tsk)                15
18632 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18633 +#define PAX_DELTA_STACK_LEN(tsk)       15
18634 +#endif
18635 +#endif
18636 +
18637  #ifdef __KERNEL__
18638  
18639  /* Common routine for both 32-bit and 64-bit processes */
18640 diff -urNp linux-2.6.16.2/include/asm-powerpc/page_64.h linux-2.6.16.2/include/asm-powerpc/page_64.h
18641 --- linux-2.6.16.2/include/asm-powerpc/page_64.h        2006-04-07 12:56:47.000000000 -0400
18642 +++ linux-2.6.16.2/include/asm-powerpc/page_64.h        2006-04-09 21:23:54.000000000 -0400
18643 @@ -169,6 +169,15 @@ extern unsigned int HPAGE_SHIFT;
18644         (test_thread_flag(TIF_32BIT) ? \
18645          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
18646  
18647 +#ifdef CONFIG_PAX_PAGEEXEC
18648 +#ifdef CONFIG_PAX_MPROTECT
18649 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18650 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18651 +#else
18652 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18653 +#endif
18654 +#endif
18655 +
18656  #include <asm-generic/page.h>
18657  
18658  #endif /* __KERNEL__ */
18659 diff -urNp linux-2.6.16.2/include/asm-ppc/page.h linux-2.6.16.2/include/asm-ppc/page.h
18660 --- linux-2.6.16.2/include/asm-ppc/page.h       2006-04-07 12:56:47.000000000 -0400
18661 +++ linux-2.6.16.2/include/asm-ppc/page.h       2006-04-09 21:23:54.000000000 -0400
18662 @@ -175,5 +175,14 @@ extern __inline__ int get_order(unsigned
18663  /* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
18664  #define __HAVE_ARCH_GATE_AREA          1
18665  
18666 +#ifdef CONFIG_PAX_PAGEEXEC
18667 +#ifdef CONFIG_PAX_MPROTECT
18668 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18669 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18670 +#else
18671 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18672 +#endif
18673 +#endif
18674 +
18675  #endif /* __KERNEL__ */
18676  #endif /* _PPC_PAGE_H */
18677 diff -urNp linux-2.6.16.2/include/asm-ppc/pgtable.h linux-2.6.16.2/include/asm-ppc/pgtable.h
18678 --- linux-2.6.16.2/include/asm-ppc/pgtable.h    2006-04-07 12:56:47.000000000 -0400
18679 +++ linux-2.6.16.2/include/asm-ppc/pgtable.h    2006-04-09 21:23:54.000000000 -0400
18680 @@ -441,11 +441,21 @@ extern unsigned long ioremap_bot, iorema
18681  
18682  #define PAGE_NONE      __pgprot(_PAGE_BASE)
18683  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
18684 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
18685 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
18686  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
18687 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
18688 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
18689  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
18690 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
18691 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
18692 +
18693 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
18694 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
18695 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
18696 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
18697 +#else
18698 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18699 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18700 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18701 +#endif
18702  
18703  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
18704  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
18705 @@ -457,21 +467,21 @@ extern unsigned long ioremap_bot, iorema
18706   * This is the closest we can get..
18707   */
18708  #define __P000 PAGE_NONE
18709 -#define __P001 PAGE_READONLY_X
18710 -#define __P010 PAGE_COPY
18711 -#define __P011 PAGE_COPY_X
18712 -#define __P100 PAGE_READONLY
18713 +#define __P001 PAGE_READONLY_NOEXEC
18714 +#define __P010 PAGE_COPY_NOEXEC
18715 +#define __P011 PAGE_COPY_NOEXEC
18716 +#define __P100 PAGE_READONLY_X
18717  #define __P101 PAGE_READONLY_X
18718 -#define __P110 PAGE_COPY
18719 +#define __P110 PAGE_COPY_X
18720  #define __P111 PAGE_COPY_X
18721  
18722  #define __S000 PAGE_NONE
18723 -#define __S001 PAGE_READONLY_X
18724 -#define __S010 PAGE_SHARED
18725 -#define __S011 PAGE_SHARED_X
18726 -#define __S100 PAGE_READONLY
18727 +#define __S001 PAGE_READONLY_NOEXEC
18728 +#define __S010 PAGE_SHARED_NOEXEC
18729 +#define __S011 PAGE_SHARED_NOEXEC
18730 +#define __S100 PAGE_READONLY_X
18731  #define __S101 PAGE_READONLY_X
18732 -#define __S110 PAGE_SHARED
18733 +#define __S110 PAGE_SHARED_X
18734  #define __S111 PAGE_SHARED_X
18735  
18736  #ifndef __ASSEMBLY__
18737 diff -urNp linux-2.6.16.2/include/asm-sparc/a.out.h linux-2.6.16.2/include/asm-sparc/a.out.h
18738 --- linux-2.6.16.2/include/asm-sparc/a.out.h    2006-04-07 12:56:47.000000000 -0400
18739 +++ linux-2.6.16.2/include/asm-sparc/a.out.h    2006-04-09 21:23:54.000000000 -0400
18740 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
18741  
18742  #include <asm/page.h>
18743  
18744 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
18745 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
18746  
18747  #endif /* __KERNEL__ */
18748  
18749 diff -urNp linux-2.6.16.2/include/asm-sparc/elf.h linux-2.6.16.2/include/asm-sparc/elf.h
18750 --- linux-2.6.16.2/include/asm-sparc/elf.h      2006-04-07 12:56:47.000000000 -0400
18751 +++ linux-2.6.16.2/include/asm-sparc/elf.h      2006-04-09 21:23:54.000000000 -0400
18752 @@ -145,6 +145,17 @@ typedef struct {
18753  
18754  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
18755  
18756 +#ifdef CONFIG_PAX_ASLR
18757 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
18758 +
18759 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18760 +#define PAX_DELTA_MMAP_LEN(tsk)                16
18761 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18762 +#define PAX_DELTA_EXEC_LEN(tsk)                16
18763 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18764 +#define PAX_DELTA_STACK_LEN(tsk)       16
18765 +#endif
18766 +
18767  /* This yields a mask that user programs can use to figure out what
18768     instruction set this cpu supports.  This can NOT be done in userspace
18769     on Sparc.  */
18770 diff -urNp linux-2.6.16.2/include/asm-sparc/page.h linux-2.6.16.2/include/asm-sparc/page.h
18771 --- linux-2.6.16.2/include/asm-sparc/page.h     2006-04-07 12:56:47.000000000 -0400
18772 +++ linux-2.6.16.2/include/asm-sparc/page.h     2006-04-09 21:23:54.000000000 -0400
18773 @@ -162,6 +162,15 @@ extern unsigned long pfn_base;
18774  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18775                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18776  
18777 +#ifdef CONFIG_PAX_PAGEEXEC
18778 +#ifdef CONFIG_PAX_MPROTECT
18779 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18780 +                        ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18781 +#else
18782 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18783 +#endif
18784 +#endif
18785 +
18786  #endif /* __KERNEL__ */
18787  
18788  #include <asm-generic/page.h>
18789 diff -urNp linux-2.6.16.2/include/asm-sparc/pgtable.h linux-2.6.16.2/include/asm-sparc/pgtable.h
18790 --- linux-2.6.16.2/include/asm-sparc/pgtable.h  2006-04-07 12:56:47.000000000 -0400
18791 +++ linux-2.6.16.2/include/asm-sparc/pgtable.h  2006-04-09 21:23:54.000000000 -0400
18792 @@ -50,6 +50,13 @@ BTFIXUPDEF_INT(page_none)
18793  BTFIXUPDEF_INT(page_shared)
18794  BTFIXUPDEF_INT(page_copy)
18795  BTFIXUPDEF_INT(page_readonly)
18796 +
18797 +#ifdef CONFIG_PAX_PAGEEXEC
18798 +BTFIXUPDEF_INT(page_shared_noexec)
18799 +BTFIXUPDEF_INT(page_copy_noexec)
18800 +BTFIXUPDEF_INT(page_readonly_noexec)
18801 +#endif
18802 +
18803  BTFIXUPDEF_INT(page_kernel)
18804  
18805  #define PMD_SHIFT              SUN4C_PMD_SHIFT
18806 @@ -71,6 +78,16 @@ BTFIXUPDEF_INT(page_kernel)
18807  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
18808  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
18809  
18810 +#ifdef CONFIG_PAX_PAGEEXEC
18811 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
18812 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
18813 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
18814 +#else
18815 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
18816 +# define PAGE_COPY_NOEXEC      PAGE_COPY
18817 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
18818 +#endif
18819 +
18820  extern unsigned long page_kernel;
18821  
18822  #ifdef MODULE
18823 diff -urNp linux-2.6.16.2/include/asm-sparc/pgtsrmmu.h linux-2.6.16.2/include/asm-sparc/pgtsrmmu.h
18824 --- linux-2.6.16.2/include/asm-sparc/pgtsrmmu.h 2006-04-07 12:56:47.000000000 -0400
18825 +++ linux-2.6.16.2/include/asm-sparc/pgtsrmmu.h 2006-04-09 21:23:54.000000000 -0400
18826 @@ -115,6 +115,16 @@
18827                                     SRMMU_EXEC | SRMMU_REF)
18828  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18829                                     SRMMU_EXEC | SRMMU_REF)
18830 +
18831 +#ifdef CONFIG_PAX_PAGEEXEC
18832 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18833 +                                          SRMMU_WRITE | SRMMU_REF)
18834 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18835 +                                          SRMMU_REF)
18836 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
18837 +                                          SRMMU_REF)
18838 +#endif
18839 +
18840  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
18841                                     SRMMU_DIRTY | SRMMU_REF)
18842  
18843 diff -urNp linux-2.6.16.2/include/asm-sparc/uaccess.h linux-2.6.16.2/include/asm-sparc/uaccess.h
18844 --- linux-2.6.16.2/include/asm-sparc/uaccess.h  2006-04-07 12:56:47.000000000 -0400
18845 +++ linux-2.6.16.2/include/asm-sparc/uaccess.h  2006-04-09 21:23:54.000000000 -0400
18846 @@ -41,7 +41,7 @@
18847   * No one can read/write anything from userland in the kernel space by setting
18848   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
18849   */
18850 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
18851 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
18852  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
18853  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
18854  #define access_ok(type, addr, size)                                    \
18855 diff -urNp linux-2.6.16.2/include/asm-sparc64/a.out.h linux-2.6.16.2/include/asm-sparc64/a.out.h
18856 --- linux-2.6.16.2/include/asm-sparc64/a.out.h  2006-04-07 12:56:47.000000000 -0400
18857 +++ linux-2.6.16.2/include/asm-sparc64/a.out.h  2006-04-09 21:23:54.000000000 -0400
18858 @@ -95,7 +95,7 @@ struct relocation_info /* used when head
18859  
18860  #ifdef __KERNEL__
18861  
18862 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
18863 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
18864  
18865  #endif
18866  
18867 diff -urNp linux-2.6.16.2/include/asm-sparc64/elf.h linux-2.6.16.2/include/asm-sparc64/elf.h
18868 --- linux-2.6.16.2/include/asm-sparc64/elf.h    2006-04-07 12:56:47.000000000 -0400
18869 +++ linux-2.6.16.2/include/asm-sparc64/elf.h    2006-04-09 21:23:54.000000000 -0400
18870 @@ -140,6 +140,16 @@ typedef struct {
18871  #define ELF_ET_DYN_BASE         0x0000010000000000UL
18872  #endif
18873  
18874 +#ifdef CONFIG_PAX_ASLR
18875 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
18876 +
18877 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
18878 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
18879 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
18880 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
18881 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18882 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
18883 +#endif
18884  
18885  /* This yields a mask that user programs can use to figure out what
18886     instruction set this cpu supports.  */
18887 diff -urNp linux-2.6.16.2/include/asm-sparc64/page.h linux-2.6.16.2/include/asm-sparc64/page.h
18888 --- linux-2.6.16.2/include/asm-sparc64/page.h   2006-04-07 12:56:47.000000000 -0400
18889 +++ linux-2.6.16.2/include/asm-sparc64/page.h   2006-04-09 21:23:54.000000000 -0400
18890 @@ -145,6 +145,15 @@ extern unsigned long page_to_pfn(struct 
18891  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
18892                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18893  
18894 +#ifdef CONFIG_PAX_PAGEEXEC
18895 +#ifdef CONFIG_PAX_MPROTECT
18896 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18897 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18898 +#else
18899 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18900 +#endif
18901 +#endif
18902 +
18903  #endif /* !(__KERNEL__) */
18904  
18905  #include <asm-generic/page.h>
18906 diff -urNp linux-2.6.16.2/include/asm-x86_64/a.out.h linux-2.6.16.2/include/asm-x86_64/a.out.h
18907 --- linux-2.6.16.2/include/asm-x86_64/a.out.h   2006-04-07 12:56:47.000000000 -0400
18908 +++ linux-2.6.16.2/include/asm-x86_64/a.out.h   2006-04-09 21:23:54.000000000 -0400
18909 @@ -21,7 +21,7 @@ struct exec
18910  
18911  #ifdef __KERNEL__
18912  #include <linux/thread_info.h>
18913 -#define STACK_TOP TASK_SIZE
18914 +#define __STACK_TOP TASK_SIZE
18915  #endif
18916  
18917  #endif /* __A_OUT_GNU_H__ */
18918 diff -urNp linux-2.6.16.2/include/asm-x86_64/elf.h linux-2.6.16.2/include/asm-x86_64/elf.h
18919 --- linux-2.6.16.2/include/asm-x86_64/elf.h     2006-04-07 12:56:47.000000000 -0400
18920 +++ linux-2.6.16.2/include/asm-x86_64/elf.h     2006-04-09 21:23:54.000000000 -0400
18921 @@ -89,6 +89,17 @@ typedef struct user_i387_struct elf_fpre
18922  
18923  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
18924  
18925 +#ifdef CONFIG_PAX_ASLR
18926 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
18927 +
18928 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
18929 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
18930 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
18931 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
18932 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
18933 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 32)
18934 +#endif
18935 +
18936  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
18937     now struct_user_regs, they are different). Assumes current is the process
18938     getting dumped. */
18939 diff -urNp linux-2.6.16.2/include/asm-x86_64/ia32.h linux-2.6.16.2/include/asm-x86_64/ia32.h
18940 --- linux-2.6.16.2/include/asm-x86_64/ia32.h    2006-04-07 12:56:47.000000000 -0400
18941 +++ linux-2.6.16.2/include/asm-x86_64/ia32.h    2006-04-09 21:23:54.000000000 -0400
18942 @@ -157,7 +157,13 @@ struct ustat32 {
18943         char                    f_fpack[6];
18944  };
18945  
18946 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
18947 +#ifdef CONFIG_PAX_RANDUSTACK
18948 +#define IA32_DELTA_STACK (current->mm->delta_stack)
18949 +#else
18950 +#define IA32_DELTA_STACK 0UL
18951 +#endif
18952 +
18953 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
18954  
18955  #ifdef __KERNEL__
18956  struct user_desc;
18957 diff -urNp linux-2.6.16.2/include/asm-x86_64/page.h linux-2.6.16.2/include/asm-x86_64/page.h
18958 --- linux-2.6.16.2/include/asm-x86_64/page.h    2006-04-07 12:56:47.000000000 -0400
18959 +++ linux-2.6.16.2/include/asm-x86_64/page.h    2006-04-09 21:23:54.000000000 -0400
18960 @@ -136,6 +136,15 @@ typedef struct { unsigned long pgprot; }
18961         (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
18962          VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18963  
18964 +#ifdef CONFIG_PAX_PAGEEXEC
18965 +#ifdef CONFIG_PAX_MPROTECT
18966 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
18967 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18968 +#else
18969 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
18970 +#endif
18971 +#endif
18972 +
18973  #define __HAVE_ARCH_GATE_AREA 1        
18974  
18975  #endif /* __KERNEL__ */
18976 diff -urNp linux-2.6.16.2/include/asm-x86_64/pgalloc.h linux-2.6.16.2/include/asm-x86_64/pgalloc.h
18977 --- linux-2.6.16.2/include/asm-x86_64/pgalloc.h 2006-04-07 12:56:47.000000000 -0400
18978 +++ linux-2.6.16.2/include/asm-x86_64/pgalloc.h 2006-04-09 21:23:54.000000000 -0400
18979 @@ -7,7 +7,7 @@
18980  #include <linux/mm.h>
18981  
18982  #define pmd_populate_kernel(mm, pmd, pte) \
18983 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
18984 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
18985  #define pud_populate(mm, pud, pmd) \
18986                 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
18987  #define pgd_populate(mm, pgd, pud) \
18988 diff -urNp linux-2.6.16.2/include/asm-x86_64/pgtable.h linux-2.6.16.2/include/asm-x86_64/pgtable.h
18989 --- linux-2.6.16.2/include/asm-x86_64/pgtable.h 2006-04-07 12:56:47.000000000 -0400
18990 +++ linux-2.6.16.2/include/asm-x86_64/pgtable.h 2006-04-09 21:23:54.000000000 -0400
18991 @@ -180,6 +180,10 @@ static inline pte_t ptep_get_and_clear_f
18992  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18993  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18994  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18995 +
18996 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
18997 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
18998 +
18999  #define __PAGE_KERNEL \
19000         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
19001  #define __PAGE_KERNEL_EXEC \
19002 @@ -268,7 +272,13 @@ static inline pte_t pfn_pte(unsigned lon
19003  #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
19004  static inline int pte_user(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
19005  static inline int pte_read(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
19006 -static inline int pte_exec(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
19007 +extern inline int pte_exec(pte_t pte)
19008 +{
19009 +       if (__supported_pte_mask & _PAGE_NX)
19010 +               return pte_val(pte) & _PAGE_NX;
19011 +       else
19012 +               return pte_val(pte) & _PAGE_USER;
19013 +}
19014  static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
19015  static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
19016  static inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_RW; }
19017 @@ -276,12 +286,26 @@ static inline int pte_file(pte_t pte)             {
19018  static inline int pte_huge(pte_t pte)          { return (pte_val(pte) & __LARGE_PTE) == __LARGE_PTE; }
19019  
19020  static inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
19021 -static inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
19022 +extern inline pte_t pte_exprotect(pte_t pte)
19023 +{
19024 +       if (__supported_pte_mask & _PAGE_NX)
19025 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
19026 +       else
19027 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
19028 +       return pte;
19029 +}
19030  static inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
19031  static inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
19032  static inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
19033  static inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
19034 -static inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
19035 +extern inline pte_t pte_mkexec(pte_t pte)
19036 +{
19037 +       if (__supported_pte_mask & _PAGE_NX)
19038 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
19039 +       else
19040 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
19041 +       return pte;
19042 +}
19043  static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
19044  static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
19045  static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
19046 diff -urNp linux-2.6.16.2/include/asm-x86_64/system.h linux-2.6.16.2/include/asm-x86_64/system.h
19047 --- linux-2.6.16.2/include/asm-x86_64/system.h  2006-04-07 12:56:47.000000000 -0400
19048 +++ linux-2.6.16.2/include/asm-x86_64/system.h  2006-04-09 21:23:54.000000000 -0400
19049 @@ -372,6 +372,6 @@ static inline unsigned long __cmpxchg(vo
19050  
19051  void cpu_idle_wait(void);
19052  
19053 -extern unsigned long arch_align_stack(unsigned long sp);
19054 +#define arch_align_stack(x) (x)
19055  
19056  #endif
19057 diff -urNp linux-2.6.16.2/include/linux/a.out.h linux-2.6.16.2/include/linux/a.out.h
19058 --- linux-2.6.16.2/include/linux/a.out.h        2006-04-07 12:56:47.000000000 -0400
19059 +++ linux-2.6.16.2/include/linux/a.out.h        2006-04-09 21:23:54.000000000 -0400
19060 @@ -7,6 +7,16 @@
19061  
19062  #include <asm/a.out.h>
19063  
19064 +#ifdef CONFIG_PAX_RANDUSTACK
19065 +#define __DELTA_STACK (current->mm->delta_stack)
19066 +#else
19067 +#define __DELTA_STACK 0UL
19068 +#endif
19069 +
19070 +#ifndef STACK_TOP
19071 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
19072 +#endif
19073 +
19074  #endif /* __STRUCT_EXEC_OVERRIDE__ */
19075  
19076  /* these go in the N_MACHTYPE field */
19077 @@ -37,6 +47,14 @@ enum machine_type {
19078    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
19079  };
19080  
19081 +/* Constants for the N_FLAGS field */
19082 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
19083 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
19084 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
19085 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
19086 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
19087 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
19088 +
19089  #if !defined (N_MAGIC)
19090  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
19091  #endif
19092 diff -urNp linux-2.6.16.2/include/linux/binfmts.h linux-2.6.16.2/include/linux/binfmts.h
19093 --- linux-2.6.16.2/include/linux/binfmts.h      2006-04-07 12:56:47.000000000 -0400
19094 +++ linux-2.6.16.2/include/linux/binfmts.h      2006-04-09 21:23:54.000000000 -0400
19095 @@ -7,10 +7,10 @@ struct pt_regs;
19096  
19097  /*
19098   * MAX_ARG_PAGES defines the number of pages allocated for arguments
19099 - * and envelope for the new program. 32 should suffice, this gives
19100 - * a maximum env+arg of 128kB w/4KB pages!
19101 + * and envelope for the new program. 33 should suffice, this gives
19102 + * a maximum env+arg of 132kB w/4KB pages!
19103   */
19104 -#define MAX_ARG_PAGES 32
19105 +#define MAX_ARG_PAGES 33
19106  
19107  /* sizeof(linux_binprm->buf) */
19108  #define BINPRM_BUF_SIZE 128
19109 @@ -38,6 +38,7 @@ struct linux_binprm{
19110         unsigned interp_flags;
19111         unsigned interp_data;
19112         unsigned long loader, exec;
19113 +       int misc;
19114  };
19115  
19116  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
19117 @@ -87,5 +88,8 @@ extern void compute_creds(struct linux_b
19118  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
19119  extern int set_binfmt(struct linux_binfmt *new);
19120  
19121 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
19122 +void pax_report_insns(void *pc, void *sp);
19123 +
19124  #endif /* __KERNEL__ */
19125  #endif /* _LINUX_BINFMTS_H */
19126 diff -urNp linux-2.6.16.2/include/linux/capability.h linux-2.6.16.2/include/linux/capability.h
19127 --- linux-2.6.16.2/include/linux/capability.h   2006-04-07 12:56:47.000000000 -0400
19128 +++ linux-2.6.16.2/include/linux/capability.h   2006-04-09 21:23:54.000000000 -0400
19129 @@ -358,6 +358,7 @@ static inline kernel_cap_t cap_invert(ke
19130  #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
19131  
19132  extern int capable(int cap);
19133 +extern int capable_nolog(int cap);
19134  
19135  #endif /* __KERNEL__ */
19136  
19137 diff -urNp linux-2.6.16.2/include/linux/elf.h linux-2.6.16.2/include/linux/elf.h
19138 --- linux-2.6.16.2/include/linux/elf.h  2006-04-07 12:56:47.000000000 -0400
19139 +++ linux-2.6.16.2/include/linux/elf.h  2006-04-09 21:23:54.000000000 -0400
19140 @@ -5,6 +5,10 @@
19141  #include <linux/auxvec.h>
19142  #include <asm/elf.h>
19143  
19144 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19145 +#undef elf_read_implies_exec
19146 +#endif
19147 +
19148  #ifndef elf_read_implies_exec
19149    /* Executables for which elf_read_implies_exec() returns TRUE will
19150       have the READ_IMPLIES_EXEC personality flag set automatically.
19151 @@ -46,6 +50,16 @@ typedef __s64        Elf64_Sxword;
19152  
19153  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
19154  
19155 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
19156 +
19157 +/* Constants for the e_flags field */
19158 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
19159 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
19160 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
19161 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
19162 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
19163 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
19164 +
19165  /* These constants define the different elf file types */
19166  #define ET_NONE   0
19167  #define ET_REL    1
19168 @@ -138,6 +152,8 @@ typedef __s64       Elf64_Sxword;
19169  #define DT_DEBUG       21
19170  #define DT_TEXTREL     22
19171  #define DT_JMPREL      23
19172 +#define DT_FLAGS       30
19173 +  #define DF_TEXTREL   0x00000004
19174  #define DT_LOPROC      0x70000000
19175  #define DT_HIPROC      0x7fffffff
19176  
19177 @@ -267,6 +283,19 @@ typedef struct elf64_hdr {
19178  #define PF_W           0x2
19179  #define PF_X           0x1
19180  
19181 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
19182 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
19183 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
19184 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
19185 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
19186 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
19187 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
19188 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
19189 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
19190 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
19191 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
19192 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
19193 +
19194  typedef struct elf32_phdr{
19195    Elf32_Word   p_type;
19196    Elf32_Off    p_offset;
19197 @@ -359,6 +388,8 @@ typedef struct elf64_shdr {
19198  #define        EI_OSABI        7
19199  #define        EI_PAD          8
19200  
19201 +#define        EI_PAX          14
19202 +
19203  #define        ELFMAG0         0x7f            /* EI_MAG */
19204  #define        ELFMAG1         'E'
19205  #define        ELFMAG2         'L'
19206 @@ -415,6 +446,7 @@ extern Elf32_Dyn _DYNAMIC [];
19207  #define elfhdr         elf32_hdr
19208  #define elf_phdr       elf32_phdr
19209  #define elf_note       elf32_note
19210 +#define elf_dyn                Elf32_Dyn
19211  
19212  #else
19213  
19214 @@ -422,6 +454,7 @@ extern Elf64_Dyn _DYNAMIC [];
19215  #define elfhdr         elf64_hdr
19216  #define elf_phdr       elf64_phdr
19217  #define elf_note       elf64_note
19218 +#define elf_dyn                Elf64_Dyn
19219  
19220  #endif
19221  
19222 diff -urNp linux-2.6.16.2/include/linux/gracl.h linux-2.6.16.2/include/linux/gracl.h
19223 --- linux-2.6.16.2/include/linux/gracl.h        1969-12-31 19:00:00.000000000 -0500
19224 +++ linux-2.6.16.2/include/linux/gracl.h        2006-04-09 21:23:54.000000000 -0400
19225 @@ -0,0 +1,316 @@
19226 +#ifndef GR_ACL_H
19227 +#define GR_ACL_H
19228 +
19229 +#include <linux/grdefs.h>
19230 +#include <linux/resource.h>
19231 +#include <linux/dcache.h>
19232 +#include <asm/resource.h>
19233 +
19234 +/* Major status information */
19235 +
19236 +#define GR_VERSION  "grsecurity 2.1.9"
19237 +#define GRSECURITY_VERSION 0x219
19238 +
19239 +enum {
19240 +
19241 +       SHUTDOWN = 0,
19242 +       ENABLE = 1,
19243 +       SPROLE = 2,
19244 +       RELOAD = 3,
19245 +       SEGVMOD = 4,
19246 +       STATUS = 5,
19247 +       UNSPROLE = 6,
19248 +       PASSSET = 7,
19249 +       SPROLEPAM = 8
19250 +};
19251 +
19252 +/* Password setup definitions
19253 + * kernel/grhash.c */
19254 +enum {
19255 +       GR_PW_LEN = 128,
19256 +       GR_SALT_LEN = 16,
19257 +       GR_SHA_LEN = 32,
19258 +};
19259 +
19260 +enum {
19261 +       GR_SPROLE_LEN = 64,
19262 +};
19263 +
19264 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
19265 +
19266 +/* Begin Data Structures */
19267 +
19268 +struct sprole_pw {
19269 +       unsigned char *rolename;
19270 +       unsigned char salt[GR_SALT_LEN];
19271 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
19272 +};
19273 +
19274 +struct name_entry {
19275 +       __u32 key;
19276 +       ino_t inode;
19277 +       dev_t device;
19278 +       char *name;
19279 +       __u16 len;
19280 +       struct name_entry *prev;
19281 +       struct name_entry *next;
19282 +};
19283 +
19284 +struct inodev_entry {
19285 +       struct name_entry *nentry;
19286 +       struct inodev_entry *prev;
19287 +       struct inodev_entry *next;
19288 +};
19289 +
19290 +struct acl_role_db {
19291 +       struct acl_role_label **r_hash;
19292 +       __u32 r_size;
19293 +};
19294 +
19295 +struct inodev_db {
19296 +       struct inodev_entry **i_hash;
19297 +       __u32 i_size;
19298 +};
19299 +
19300 +struct name_db {
19301 +       struct name_entry **n_hash;
19302 +       __u32 n_size;
19303 +};
19304 +
19305 +struct crash_uid {
19306 +       uid_t uid;
19307 +       unsigned long expires;
19308 +};
19309 +
19310 +struct gr_hash_struct {
19311 +       void **table;
19312 +       void **nametable;
19313 +       void *first;
19314 +       __u32 table_size;
19315 +       __u32 used_size;
19316 +       int type;
19317 +};
19318 +
19319 +/* Userspace Grsecurity ACL data structures */
19320 +
19321 +struct acl_subject_label {
19322 +       char *filename;
19323 +       ino_t inode;
19324 +       dev_t device;
19325 +       __u32 mode;
19326 +       __u32 cap_mask;
19327 +       __u32 cap_lower;
19328 +
19329 +       struct rlimit res[GR_NLIMITS];
19330 +       __u16 resmask;
19331 +
19332 +       __u8 user_trans_type;
19333 +       __u8 group_trans_type;
19334 +       uid_t *user_transitions;
19335 +       gid_t *group_transitions;
19336 +       __u16 user_trans_num;
19337 +       __u16 group_trans_num;
19338 +
19339 +       __u32 ip_proto[8];
19340 +       __u32 ip_type;
19341 +       struct acl_ip_label **ips;
19342 +       __u32 ip_num;
19343 +
19344 +       __u32 crashes;
19345 +       unsigned long expires;
19346 +
19347 +       struct acl_subject_label *parent_subject;
19348 +       struct gr_hash_struct *hash;
19349 +       struct acl_subject_label *prev;
19350 +       struct acl_subject_label *next;
19351 +
19352 +       struct acl_object_label **obj_hash;
19353 +       __u32 obj_hash_size;
19354 +       __u16 pax_flags;
19355 +};
19356 +
19357 +struct role_allowed_ip {
19358 +       __u32 addr;
19359 +       __u32 netmask;
19360 +
19361 +       struct role_allowed_ip *prev;
19362 +       struct role_allowed_ip *next;
19363 +};
19364 +
19365 +struct role_transition {
19366 +       char *rolename;
19367 +
19368 +       struct role_transition *prev;
19369 +       struct role_transition *next;
19370 +};
19371 +
19372 +struct acl_role_label {
19373 +       char *rolename;
19374 +       uid_t uidgid;
19375 +       __u16 roletype;
19376 +
19377 +       __u16 auth_attempts;
19378 +       unsigned long expires;
19379 +
19380 +       struct acl_subject_label *root_label;
19381 +       struct gr_hash_struct *hash;
19382 +
19383 +       struct acl_role_label *prev;
19384 +       struct acl_role_label *next;
19385 +
19386 +       struct role_transition *transitions;
19387 +       struct role_allowed_ip *allowed_ips;
19388 +       uid_t *domain_children;
19389 +       __u16 domain_child_num;
19390 +
19391 +       struct acl_subject_label **subj_hash;
19392 +       __u32 subj_hash_size;
19393 +};
19394 +
19395 +struct user_acl_role_db {
19396 +       struct acl_role_label **r_table;
19397 +       __u32 num_pointers;             /* Number of allocations to track */
19398 +       __u32 num_roles;                /* Number of roles */
19399 +       __u32 num_domain_children;      /* Number of domain children */
19400 +       __u32 num_subjects;             /* Number of subjects */
19401 +       __u32 num_objects;              /* Number of objects */
19402 +};
19403 +
19404 +struct acl_object_label {
19405 +       char *filename;
19406 +       ino_t inode;
19407 +       dev_t device;
19408 +       __u32 mode;
19409 +
19410 +       struct acl_subject_label *nested;
19411 +       struct acl_object_label *globbed;
19412 +
19413 +       /* next two structures not used */
19414 +
19415 +       struct acl_object_label *prev;
19416 +       struct acl_object_label *next;
19417 +};
19418 +
19419 +struct acl_ip_label {
19420 +       char *iface;
19421 +       __u32 addr;
19422 +       __u32 netmask;
19423 +       __u16 low, high;
19424 +       __u8 mode;
19425 +       __u32 type;
19426 +       __u32 proto[8];
19427 +
19428 +       /* next two structures not used */
19429 +
19430 +       struct acl_ip_label *prev;
19431 +       struct acl_ip_label *next;
19432 +};
19433 +
19434 +struct gr_arg {
19435 +       struct user_acl_role_db role_db;
19436 +       unsigned char pw[GR_PW_LEN];
19437 +       unsigned char salt[GR_SALT_LEN];
19438 +       unsigned char sum[GR_SHA_LEN];
19439 +       unsigned char sp_role[GR_SPROLE_LEN];
19440 +       struct sprole_pw *sprole_pws;
19441 +       dev_t segv_device;
19442 +       ino_t segv_inode;
19443 +       uid_t segv_uid;
19444 +       __u16 num_sprole_pws;
19445 +       __u16 mode;
19446 +};
19447 +
19448 +struct gr_arg_wrapper {
19449 +       struct gr_arg *arg;
19450 +       __u32 version;
19451 +       __u32 size;
19452 +};
19453 +
19454 +struct subject_map {
19455 +       struct acl_subject_label *user;
19456 +       struct acl_subject_label *kernel;
19457 +       struct subject_map *prev;
19458 +       struct subject_map *next;
19459 +};
19460 +
19461 +struct acl_subj_map_db {
19462 +       struct subject_map **s_hash;
19463 +       __u32 s_size;
19464 +};
19465 +
19466 +/* End Data Structures Section */
19467 +
19468 +/* Hash functions generated by empirical testing by Brad Spengler
19469 +   Makes good use of the low bits of the inode.  Generally 0-1 times
19470 +   in loop for successful match.  0-3 for unsuccessful match.
19471 +   Shift/add algorithm with modulus of table size and an XOR*/
19472 +
19473 +static __inline__ unsigned int
19474 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
19475 +{
19476 +       return (((uid << type) + (uid ^ type)) % sz);
19477 +}
19478 +
19479 + static __inline__ unsigned int
19480 +shash(const struct acl_subject_label *userp, const unsigned int sz)
19481 +{
19482 +       return ((const unsigned long)userp % sz);
19483 +}
19484 +
19485 +static __inline__ unsigned int
19486 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
19487 +{
19488 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
19489 +}
19490 +
19491 +static __inline__ unsigned int
19492 +nhash(const char *name, const __u16 len, const unsigned int sz)
19493 +{
19494 +       return full_name_hash(name, len) % sz;
19495 +}
19496 +
19497 +#define FOR_EACH_ROLE_START(role,iter) \
19498 +       role = NULL; \
19499 +       iter = 0; \
19500 +       while (iter < acl_role_set.r_size) { \
19501 +               if (role == NULL) \
19502 +                       role = acl_role_set.r_hash[iter]; \
19503 +               if (role == NULL) { \
19504 +                       iter++; \
19505 +                       continue; \
19506 +               }
19507 +
19508 +#define FOR_EACH_ROLE_END(role,iter) \
19509 +               role = role->next; \
19510 +               if (role == NULL) \
19511 +                       iter++; \
19512 +       }
19513 +
19514 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
19515 +       subj = NULL; \
19516 +       iter = 0; \
19517 +       while (iter < role->subj_hash_size) { \
19518 +               if (subj == NULL) \
19519 +                       subj = role->subj_hash[iter]; \
19520 +               if (subj == NULL) { \
19521 +                       iter++; \
19522 +                       continue; \
19523 +               }
19524 +
19525 +#define FOR_EACH_SUBJECT_END(subj,iter) \
19526 +               subj = subj->next; \
19527 +               if (subj == NULL) \
19528 +                       iter++; \
19529 +       }
19530 +
19531 +
19532 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
19533 +       subj = role->hash->first; \
19534 +       while (subj != NULL) {
19535 +
19536 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
19537 +               subj = subj->next; \
19538 +       }
19539 +
19540 +#endif
19541 +
19542 diff -urNp linux-2.6.16.2/include/linux/gralloc.h linux-2.6.16.2/include/linux/gralloc.h
19543 --- linux-2.6.16.2/include/linux/gralloc.h      1969-12-31 19:00:00.000000000 -0500
19544 +++ linux-2.6.16.2/include/linux/gralloc.h      2006-04-09 21:23:54.000000000 -0400
19545 @@ -0,0 +1,8 @@
19546 +#ifndef __GRALLOC_H
19547 +#define __GRALLOC_H
19548 +
19549 +void acl_free_all(void);
19550 +int acl_alloc_stack_init(unsigned long size);
19551 +void *acl_alloc(unsigned long len);
19552 +
19553 +#endif
19554 diff -urNp linux-2.6.16.2/include/linux/grdefs.h linux-2.6.16.2/include/linux/grdefs.h
19555 --- linux-2.6.16.2/include/linux/grdefs.h       1969-12-31 19:00:00.000000000 -0500
19556 +++ linux-2.6.16.2/include/linux/grdefs.h       2006-04-09 21:23:54.000000000 -0400
19557 @@ -0,0 +1,131 @@
19558 +#ifndef GRDEFS_H
19559 +#define GRDEFS_H
19560 +
19561 +/* Begin grsecurity status declarations */
19562 +
19563 +enum {
19564 +       GR_READY = 0x01,
19565 +       GR_STATUS_INIT = 0x00   // disabled state
19566 +};
19567 +
19568 +/* Begin  ACL declarations */
19569 +
19570 +/* Role flags */
19571 +
19572 +enum {
19573 +       GR_ROLE_USER = 0x0001,
19574 +       GR_ROLE_GROUP = 0x0002,
19575 +       GR_ROLE_DEFAULT = 0x0004,
19576 +       GR_ROLE_SPECIAL = 0x0008,
19577 +       GR_ROLE_AUTH = 0x0010,
19578 +       GR_ROLE_NOPW = 0x0020,
19579 +       GR_ROLE_GOD = 0x0040,
19580 +       GR_ROLE_LEARN = 0x0080,
19581 +       GR_ROLE_TPE = 0x0100,
19582 +       GR_ROLE_DOMAIN = 0x0200,
19583 +       GR_ROLE_PAM = 0x0400
19584 +};
19585 +
19586 +/* ACL Subject and Object mode flags */
19587 +enum {
19588 +       GR_DELETED = 0x80000000
19589 +};
19590 +
19591 +/* ACL Object-only mode flags */
19592 +enum {
19593 +       GR_READ         = 0x00000001,
19594 +       GR_APPEND       = 0x00000002,
19595 +       GR_WRITE        = 0x00000004,
19596 +       GR_EXEC         = 0x00000008,
19597 +       GR_FIND         = 0x00000010,
19598 +       GR_INHERIT      = 0x00000020,
19599 +       GR_SETID        = 0x00000040,
19600 +       GR_CREATE       = 0x00000080,
19601 +       GR_DELETE       = 0x00000100,
19602 +       GR_LINK         = 0x00000200,
19603 +       GR_AUDIT_READ   = 0x00000400,
19604 +       GR_AUDIT_APPEND = 0x00000800,
19605 +       GR_AUDIT_WRITE  = 0x00001000,
19606 +       GR_AUDIT_EXEC   = 0x00002000,
19607 +       GR_AUDIT_FIND   = 0x00004000,
19608 +       GR_AUDIT_INHERIT= 0x00008000,
19609 +       GR_AUDIT_SETID  = 0x00010000,
19610 +       GR_AUDIT_CREATE = 0x00020000,
19611 +       GR_AUDIT_DELETE = 0x00040000,
19612 +       GR_AUDIT_LINK   = 0x00080000,
19613 +       GR_PTRACERD     = 0x00100000,
19614 +       GR_NOPTRACE     = 0x00200000,
19615 +       GR_SUPPRESS     = 0x00400000,
19616 +       GR_NOLEARN      = 0x00800000
19617 +};
19618 +
19619 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
19620 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
19621 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
19622 +
19623 +/* ACL subject-only mode flags */
19624 +enum {
19625 +       GR_KILL         = 0x00000001,
19626 +       GR_VIEW         = 0x00000002,
19627 +       GR_PROTECTED    = 0x00000004,
19628 +       GR_LEARN        = 0x00000008,
19629 +       GR_OVERRIDE     = 0x00000010,
19630 +       /* just a placeholder, this mode is only used in userspace */
19631 +       GR_DUMMY        = 0x00000020,
19632 +       GR_PROTSHM      = 0x00000040,
19633 +       GR_KILLPROC     = 0x00000080,
19634 +       GR_KILLIPPROC   = 0x00000100,
19635 +       /* just a placeholder, this mode is only used in userspace */
19636 +       GR_NOTROJAN     = 0x00000200,
19637 +       GR_PROTPROCFD   = 0x00000400,
19638 +       GR_PROCACCT     = 0x00000800,
19639 +       GR_RELAXPTRACE  = 0x00001000,
19640 +       GR_NESTED       = 0x00002000,
19641 +       GR_INHERITLEARN = 0x00004000,
19642 +       GR_PROCFIND     = 0x00008000,
19643 +       GR_POVERRIDE    = 0x00010000,
19644 +       GR_KERNELAUTH   = 0x00020000,
19645 +};
19646 +
19647 +enum {
19648 +       GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
19649 +       GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
19650 +       GR_PAX_ENABLE_MPROTECT  = 0x0004,
19651 +       GR_PAX_ENABLE_RANDMMAP  = 0x0008,
19652 +       GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
19653 +       GR_PAX_DISABLE_SEGMEXEC = 0x8001,
19654 +       GR_PAX_DISABLE_PAGEEXEC = 0x8002,
19655 +       GR_PAX_DISABLE_MPROTECT = 0x8004,
19656 +       GR_PAX_DISABLE_RANDMMAP = 0x8008,
19657 +       GR_PAX_DISABLE_EMUTRAMP = 0x8010,
19658 +};
19659 +
19660 +enum {
19661 +       GR_ID_USER      = 0x01,
19662 +       GR_ID_GROUP     = 0x02,
19663 +};
19664 +
19665 +enum {
19666 +       GR_ID_ALLOW     = 0x01,
19667 +       GR_ID_DENY      = 0x02,
19668 +};
19669 +
19670 +#define GR_CRASH_RES   11
19671 +#define GR_UIDTABLE_MAX 500
19672 +
19673 +/* begin resource learning section */
19674 +enum {
19675 +       GR_RLIM_CPU_BUMP = 60,
19676 +       GR_RLIM_FSIZE_BUMP = 50000,
19677 +       GR_RLIM_DATA_BUMP = 10000,
19678 +       GR_RLIM_STACK_BUMP = 1000,
19679 +       GR_RLIM_CORE_BUMP = 10000,
19680 +       GR_RLIM_RSS_BUMP = 500000,
19681 +       GR_RLIM_NPROC_BUMP = 1,
19682 +       GR_RLIM_NOFILE_BUMP = 5,
19683 +       GR_RLIM_MEMLOCK_BUMP = 50000,
19684 +       GR_RLIM_AS_BUMP = 500000,
19685 +       GR_RLIM_LOCKS_BUMP = 2
19686 +};
19687 +
19688 +#endif
19689 diff -urNp linux-2.6.16.2/include/linux/grinternal.h linux-2.6.16.2/include/linux/grinternal.h
19690 --- linux-2.6.16.2/include/linux/grinternal.h   1969-12-31 19:00:00.000000000 -0500
19691 +++ linux-2.6.16.2/include/linux/grinternal.h   2006-04-09 21:23:54.000000000 -0400
19692 @@ -0,0 +1,210 @@
19693 +#ifndef __GRINTERNAL_H
19694 +#define __GRINTERNAL_H
19695 +
19696 +#ifdef CONFIG_GRKERNSEC
19697 +
19698 +#include <linux/fs.h>
19699 +#include <linux/gracl.h>
19700 +#include <linux/grdefs.h>
19701 +#include <linux/grmsg.h>
19702 +
19703 +extern void gr_add_learn_entry(const char *fmt, ...);
19704 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
19705 +                           const struct vfsmount *mnt);
19706 +extern __u32 gr_check_create(const struct dentry *new_dentry,
19707 +                            const struct dentry *parent,
19708 +                            const struct vfsmount *mnt, const __u32 mode);
19709 +extern int gr_check_protected_task(const struct task_struct *task);
19710 +extern __u32 to_gr_audit(const __u32 reqmode);
19711 +extern int gr_set_acls(const int type);
19712 +
19713 +extern int gr_acl_is_enabled(void);
19714 +extern char gr_roletype_to_char(void);
19715 +
19716 +extern void gr_handle_alertkill(struct task_struct *task);
19717 +extern char *gr_to_filename(const struct dentry *dentry,
19718 +                           const struct vfsmount *mnt);
19719 +extern char *gr_to_filename1(const struct dentry *dentry,
19720 +                           const struct vfsmount *mnt);
19721 +extern char *gr_to_filename2(const struct dentry *dentry,
19722 +                           const struct vfsmount *mnt);
19723 +extern char *gr_to_filename3(const struct dentry *dentry,
19724 +                           const struct vfsmount *mnt);
19725 +
19726 +extern int grsec_enable_link;
19727 +extern int grsec_enable_fifo;
19728 +extern int grsec_enable_execve;
19729 +extern int grsec_enable_shm;
19730 +extern int grsec_enable_execlog;
19731 +extern int grsec_enable_signal;
19732 +extern int grsec_enable_forkfail;
19733 +extern int grsec_enable_time;
19734 +extern int grsec_enable_chroot_shmat;
19735 +extern int grsec_enable_chroot_findtask;
19736 +extern int grsec_enable_chroot_mount;
19737 +extern int grsec_enable_chroot_double;
19738 +extern int grsec_enable_chroot_pivot;
19739 +extern int grsec_enable_chroot_chdir;
19740 +extern int grsec_enable_chroot_chmod;
19741 +extern int grsec_enable_chroot_mknod;
19742 +extern int grsec_enable_chroot_fchdir;
19743 +extern int grsec_enable_chroot_nice;
19744 +extern int grsec_enable_chroot_execlog;
19745 +extern int grsec_enable_chroot_caps;
19746 +extern int grsec_enable_chroot_sysctl;
19747 +extern int grsec_enable_chroot_unix;
19748 +extern int grsec_enable_tpe;
19749 +extern int grsec_tpe_gid;
19750 +extern int grsec_enable_tpe_all;
19751 +extern int grsec_enable_sidcaps;
19752 +extern int grsec_enable_randpid;
19753 +extern int grsec_enable_socket_all;
19754 +extern int grsec_socket_all_gid;
19755 +extern int grsec_enable_socket_client;
19756 +extern int grsec_socket_client_gid;
19757 +extern int grsec_enable_socket_server;
19758 +extern int grsec_socket_server_gid;
19759 +extern int grsec_audit_gid;
19760 +extern int grsec_enable_group;
19761 +extern int grsec_enable_audit_ipc;
19762 +extern int grsec_enable_audit_textrel;
19763 +extern int grsec_enable_mount;
19764 +extern int grsec_enable_chdir;
19765 +extern int grsec_lock;
19766 +
19767 +extern struct task_struct *child_reaper;
19768 +
19769 +extern spinlock_t grsec_alert_lock;
19770 +extern unsigned long grsec_alert_wtime;
19771 +extern unsigned long grsec_alert_fyet;
19772 +
19773 +extern spinlock_t grsec_audit_lock;
19774 +
19775 +extern rwlock_t grsec_exec_file_lock;
19776 +
19777 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
19778 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
19779 +                       tsk->exec_file->f_vfsmnt) : "/")
19780 +
19781 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
19782 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
19783 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
19784 +
19785 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
19786 +                       gr_to_filename(tsk->exec_file->f_dentry, \
19787 +                       tsk->exec_file->f_vfsmnt) : "/")
19788 +
19789 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
19790 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
19791 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
19792 +
19793 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
19794 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
19795 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
19796 +                         (tsk_a->fs->root->d_inode->i_ino != \
19797 +                         child_reaper->fs->root->d_inode->i_ino)))
19798 +
19799 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
19800 +                         (tsk_a->fs->root->d_inode->i_sb->s_dev == \
19801 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
19802 +                         (tsk_a->fs->root->d_inode->i_ino == \
19803 +                         tsk_b->fs->root->d_inode->i_ino))
19804 +
19805 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
19806 +                      task->pid, task->uid, \
19807 +                      task->euid, task->gid, task->egid, \
19808 +                      gr_parent_task_fullpath(task), \
19809 +                      task->parent->comm, task->parent->pid, \
19810 +                      task->parent->uid, task->parent->euid, \
19811 +                      task->parent->gid, task->parent->egid
19812 +
19813 +#define GR_CHROOT_CAPS ( \
19814 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
19815 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
19816 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
19817 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
19818 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
19819 +       CAP_TO_MASK(CAP_IPC_OWNER))
19820 +
19821 +#define security_learn(normal_msg,args...) \
19822 +({ \
19823 +       read_lock(&grsec_exec_file_lock); \
19824 +       gr_add_learn_entry(normal_msg "\n", ## args); \
19825 +       read_unlock(&grsec_exec_file_lock); \
19826 +})
19827 +
19828 +enum {
19829 +       GR_DO_AUDIT,
19830 +       GR_DONT_AUDIT,
19831 +       GR_DONT_AUDIT_GOOD
19832 +};
19833 +
19834 +enum {
19835 +       GR_TTYSNIFF,
19836 +       GR_RBAC,
19837 +       GR_RBAC_STR,
19838 +       GR_STR_RBAC,
19839 +       GR_RBAC_MODE2,
19840 +       GR_RBAC_MODE3,
19841 +       GR_FILENAME,
19842 +       GR_NOARGS,
19843 +       GR_ONE_INT,
19844 +       GR_ONE_INT_TWO_STR,
19845 +       GR_ONE_STR,
19846 +       GR_STR_INT,
19847 +       GR_TWO_INT,
19848 +       GR_THREE_INT,
19849 +       GR_FIVE_INT_TWO_STR,
19850 +       GR_TWO_STR,
19851 +       GR_THREE_STR,
19852 +       GR_FOUR_STR,
19853 +       GR_STR_FILENAME,
19854 +       GR_FILENAME_STR,
19855 +       GR_FILENAME_TWO_INT,
19856 +       GR_FILENAME_TWO_INT_STR,
19857 +       GR_TEXTREL,
19858 +       GR_PTRACE,
19859 +       GR_RESOURCE,
19860 +       GR_CAP,
19861 +       GR_SIG,
19862 +       GR_CRASH1,
19863 +       GR_CRASH2,
19864 +       GR_PSACCT
19865 +};
19866 +
19867 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
19868 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
19869 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
19870 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
19871 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
19872 +#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)
19873 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
19874 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
19875 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
19876 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
19877 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
19878 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
19879 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
19880 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
19881 +#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)
19882 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
19883 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
19884 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
19885 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
19886 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
19887 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
19888 +#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)
19889 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
19890 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
19891 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
19892 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
19893 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
19894 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
19895 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
19896 +#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)
19897 +
19898 +extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
19899 +
19900 +#endif
19901 +
19902 +#endif
19903 diff -urNp linux-2.6.16.2/include/linux/grmsg.h linux-2.6.16.2/include/linux/grmsg.h
19904 --- linux-2.6.16.2/include/linux/grmsg.h        1969-12-31 19:00:00.000000000 -0500
19905 +++ linux-2.6.16.2/include/linux/grmsg.h        2006-04-09 21:23:54.000000000 -0400
19906 @@ -0,0 +1,108 @@
19907 +#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"
19908 +#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"
19909 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
19910 +#define GR_STOPMOD_MSG "denied modification of module state by "
19911 +#define GR_IOPERM_MSG "denied use of ioperm() by "
19912 +#define GR_IOPL_MSG "denied use of iopl() by "
19913 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
19914 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
19915 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
19916 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
19917 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
19918 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
19919 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
19920 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
19921 +#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"
19922 +#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"
19923 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
19924 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
19925 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
19926 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
19927 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
19928 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
19929 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
19930 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
19931 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
19932 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
19933 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
19934 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
19935 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
19936 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
19937 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
19938 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
19939 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
19940 +#define GR_NPROC_MSG "denied overstep of process limit by "
19941 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
19942 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
19943 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
19944 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
19945 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
19946 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
19947 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
19948 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
19949 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
19950 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
19951 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
19952 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
19953 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
19954 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
19955 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
19956 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
19957 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
19958 +#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"
19959 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
19960 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
19961 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
19962 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
19963 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
19964 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
19965 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
19966 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
19967 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
19968 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
19969 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
19970 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
19971 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
19972 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
19973 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
19974 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
19975 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
19976 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
19977 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
19978 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
19979 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
19980 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
19981 +#define GR_NICE_CHROOT_MSG "denied priority change by "
19982 +#define GR_UNISIGLOG_MSG "signal %d sent to "
19983 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
19984 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
19985 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
19986 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
19987 +#define GR_TIME_MSG "time set by "
19988 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
19989 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
19990 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
19991 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
19992 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
19993 +#define GR_BIND_MSG "denied bind() by "
19994 +#define GR_CONNECT_MSG "denied connect() by "
19995 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
19996 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
19997 +#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"
19998 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
19999 +#define GR_CAP_ACL_MSG "use of %s denied for "
20000 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
20001 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
20002 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
20003 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
20004 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
20005 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
20006 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
20007 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
20008 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
20009 +#define GR_SEM_AUDIT_MSG "semaphore created by "
20010 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
20011 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
20012 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
20013 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
20014 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
20015 diff -urNp linux-2.6.16.2/include/linux/grsecurity.h linux-2.6.16.2/include/linux/grsecurity.h
20016 --- linux-2.6.16.2/include/linux/grsecurity.h   1969-12-31 19:00:00.000000000 -0500
20017 +++ linux-2.6.16.2/include/linux/grsecurity.h   2006-04-09 21:23:54.000000000 -0400
20018 @@ -0,0 +1,196 @@
20019 +#ifndef GR_SECURITY_H
20020 +#define GR_SECURITY_H
20021 +#include <linux/fs.h>
20022 +#include <linux/binfmts.h>
20023 +#include <linux/gracl.h>
20024 +
20025 +extern void gr_handle_brute_attach(struct task_struct *p);
20026 +extern void gr_handle_brute_check(void);
20027 +
20028 +extern char gr_roletype_to_char(void);
20029 +
20030 +extern int gr_check_user_change(int real, int effective, int fs);
20031 +extern int gr_check_group_change(int real, int effective, int fs);
20032 +
20033 +extern void gr_del_task_from_ip_table(struct task_struct *p);
20034 +
20035 +extern int gr_pid_is_chrooted(struct task_struct *p);
20036 +extern int gr_handle_chroot_nice(void);
20037 +extern int gr_handle_chroot_sysctl(const int op);
20038 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
20039 +                                       const int niceval);
20040 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
20041 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
20042 +                                  const struct vfsmount *mnt);
20043 +extern void gr_handle_chroot_caps(struct task_struct *task);
20044 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
20045 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
20046 +                                 const struct vfsmount *mnt, const int mode);
20047 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
20048 +                                 const struct vfsmount *mnt, const int mode);
20049 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
20050 +                                 const struct vfsmount *mnt,
20051 +                                 const char *dev_name);
20052 +extern int gr_handle_chroot_pivot(void);
20053 +extern int gr_handle_chroot_unix(const pid_t pid);
20054 +
20055 +extern int gr_handle_rawio(const struct inode *inode);
20056 +extern int gr_handle_nproc(void);
20057 +
20058 +extern void gr_handle_ioperm(void);
20059 +extern void gr_handle_iopl(void);
20060 +
20061 +extern int gr_tpe_allow(const struct file *file);
20062 +
20063 +extern int gr_random_pid(void);
20064 +
20065 +extern void gr_log_forkfail(const int retval);
20066 +extern void gr_log_timechange(void);
20067 +extern void gr_log_signal(const int sig, const struct task_struct *t);
20068 +extern void gr_log_chdir(const struct dentry *dentry,
20069 +                        const struct vfsmount *mnt);
20070 +extern void gr_log_chroot_exec(const struct dentry *dentry,
20071 +                              const struct vfsmount *mnt);
20072 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
20073 +extern void gr_log_remount(const char *devname, const int retval);
20074 +extern void gr_log_unmount(const char *devname, const int retval);
20075 +extern void gr_log_mount(const char *from, const char *to, const int retval);
20076 +extern void gr_log_msgget(const int ret, const int msgflg);
20077 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
20078 +extern void gr_log_semget(const int err, const int semflg);
20079 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
20080 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
20081 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
20082 +extern void gr_log_textrel(struct vm_area_struct *vma);
20083 +
20084 +extern int gr_handle_follow_link(const struct inode *parent,
20085 +                                const struct inode *inode,
20086 +                                const struct dentry *dentry,
20087 +                                const struct vfsmount *mnt);
20088 +extern int gr_handle_fifo(const struct dentry *dentry,
20089 +                         const struct vfsmount *mnt,
20090 +                         const struct dentry *dir, const int flag,
20091 +                         const int acc_mode);
20092 +extern int gr_handle_hardlink(const struct dentry *dentry,
20093 +                             const struct vfsmount *mnt,
20094 +                             struct inode *inode,
20095 +                             const int mode, const char *to);
20096 +
20097 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
20098 +extern int gr_is_capable_nolog(const int cap);
20099 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
20100 +                             const unsigned long wanted, const int gt);
20101 +extern void gr_copy_label(struct task_struct *tsk);
20102 +extern void gr_handle_crash(struct task_struct *task, const int sig);
20103 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
20104 +extern int gr_check_crash_uid(const uid_t uid);
20105 +extern int gr_check_protected_task(const struct task_struct *task);
20106 +extern int gr_acl_handle_mmap(const struct file *file,
20107 +                             const unsigned long prot);
20108 +extern int gr_acl_handle_mprotect(const struct file *file,
20109 +                                 const unsigned long prot);
20110 +extern int gr_check_hidden_task(const struct task_struct *tsk);
20111 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
20112 +                                   const struct vfsmount *mnt);
20113 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
20114 +                                const struct vfsmount *mnt);
20115 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
20116 +                                 const struct vfsmount *mnt, const int fmode);
20117 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
20118 +                                 const struct vfsmount *mnt, mode_t mode);
20119 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
20120 +                                const struct vfsmount *mnt, mode_t mode);
20121 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
20122 +                                const struct vfsmount *mnt);
20123 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
20124 +extern int gr_handle_proc_ptrace(struct task_struct *task);
20125 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
20126 +                                 const struct vfsmount *mnt);
20127 +extern int gr_check_crash_exec(const struct file *filp);
20128 +extern int gr_acl_is_enabled(void);
20129 +extern void gr_set_kernel_label(struct task_struct *task);
20130 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
20131 +                             const gid_t gid);
20132 +extern int gr_set_proc_label(const struct dentry *dentry,
20133 +                             const struct vfsmount *mnt);
20134 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
20135 +                                      const struct vfsmount *mnt);
20136 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
20137 +                               const struct vfsmount *mnt, const int fmode);
20138 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
20139 +                                const struct dentry *p_dentry,
20140 +                                const struct vfsmount *p_mnt, const int fmode,
20141 +                                const int imode);
20142 +extern void gr_handle_create(const struct dentry *dentry,
20143 +                            const struct vfsmount *mnt);
20144 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
20145 +                                const struct dentry *parent_dentry,
20146 +                                const struct vfsmount *parent_mnt,
20147 +                                const int mode);
20148 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
20149 +                                const struct dentry *parent_dentry,
20150 +                                const struct vfsmount *parent_mnt);
20151 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
20152 +                                const struct vfsmount *mnt);
20153 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
20154 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
20155 +                                 const struct vfsmount *mnt);
20156 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
20157 +                                  const struct dentry *parent_dentry,
20158 +                                  const struct vfsmount *parent_mnt,
20159 +                                  const char *from);
20160 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
20161 +                               const struct dentry *parent_dentry,
20162 +                               const struct vfsmount *parent_mnt,
20163 +                               const struct dentry *old_dentry,
20164 +                               const struct vfsmount *old_mnt, const char *to);
20165 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
20166 +                               struct dentry *parent_dentry,
20167 +                               const struct vfsmount *parent_mnt,
20168 +                               struct dentry *old_dentry,
20169 +                               struct inode *old_parent_inode,
20170 +                               struct vfsmount *old_mnt, const char *newname);
20171 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
20172 +                               struct dentry *old_dentry,
20173 +                               struct dentry *new_dentry,
20174 +                               struct vfsmount *mnt, const __u8 replace);
20175 +extern __u32 gr_check_link(const struct dentry *new_dentry,
20176 +                          const struct dentry *parent_dentry,
20177 +                          const struct vfsmount *parent_mnt,
20178 +                          const struct dentry *old_dentry,
20179 +                          const struct vfsmount *old_mnt);
20180 +extern int gr_acl_handle_filldir(const struct file *file, const char *name,
20181 +                                const unsigned int namelen, const ino_t ino);
20182 +
20183 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
20184 +                               const struct vfsmount *mnt);
20185 +extern void gr_acl_handle_exit(void);
20186 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
20187 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
20188 +extern __u32 gr_cap_rtnetlink(void);
20189 +
20190 +#ifdef CONFIG_SYSVIPC
20191 +extern void gr_shm_exit(struct task_struct *task);
20192 +#else
20193 +static inline void gr_shm_exit(struct task_struct *task)
20194 +{
20195 +       return;
20196 +}
20197 +#endif
20198 +
20199 +#ifdef CONFIG_GRKERNSEC
20200 +extern void gr_handle_mem_write(void);
20201 +extern void gr_handle_kmem_write(void);
20202 +extern void gr_handle_open_port(void);
20203 +extern int gr_handle_mem_mmap(const unsigned long offset,
20204 +                             struct vm_area_struct *vma);
20205 +
20206 +extern unsigned long pax_get_random_long(void);
20207 +#define get_random_long() pax_get_random_long()
20208 +
20209 +extern int grsec_enable_dmesg;
20210 +extern int grsec_enable_randsrc;
20211 +extern int grsec_enable_shm;
20212 +#endif
20213 +
20214 +#endif
20215 diff -urNp linux-2.6.16.2/include/linux/mman.h linux-2.6.16.2/include/linux/mman.h
20216 --- linux-2.6.16.2/include/linux/mman.h 2006-04-07 12:56:47.000000000 -0400
20217 +++ linux-2.6.16.2/include/linux/mman.h 2006-04-09 21:23:54.000000000 -0400
20218 @@ -59,6 +59,11 @@ static inline unsigned long
20219  calc_vm_flag_bits(unsigned long flags)
20220  {
20221         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
20222 +
20223 +#ifdef CONFIG_PAX_SEGMEXEC
20224 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
20225 +#endif
20226 +
20227                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
20228                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
20229                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
20230 diff -urNp linux-2.6.16.2/include/linux/mm.h linux-2.6.16.2/include/linux/mm.h
20231 --- linux-2.6.16.2/include/linux/mm.h   2006-04-07 12:56:47.000000000 -0400
20232 +++ linux-2.6.16.2/include/linux/mm.h   2006-04-09 21:23:54.000000000 -0400
20233 @@ -38,6 +38,7 @@ extern int sysctl_legacy_va_layout;
20234  #include <asm/pgtable.h>
20235  #include <asm/processor.h>
20236  #include <asm/atomic.h>
20237 +#include <asm/mman.h>
20238  
20239  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
20240  
20241 @@ -111,8 +112,43 @@ struct vm_area_struct {
20242  #ifdef CONFIG_NUMA
20243         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
20244  #endif
20245 +
20246 +       unsigned long vm_mirror;        /* PaX: mirror distance */
20247  };
20248  
20249 +#ifdef CONFIG_PAX_SOFTMODE
20250 +extern unsigned int pax_softmode;
20251 +#endif
20252 +
20253 +extern int pax_check_flags(unsigned long *);
20254 +
20255 +/* if tsk != current then task_lock must be held on it */
20256 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
20257 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
20258 +{
20259 +       if (likely(tsk->mm))
20260 +               return tsk->mm->pax_flags;
20261 +       else
20262 +               return 0UL;
20263 +}
20264 +
20265 +/* if tsk != current then task_lock must be held on it */
20266 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
20267 +{
20268 +       if (likely(tsk->mm)) {
20269 +               tsk->mm->pax_flags = flags;
20270 +               return 0;
20271 +       }
20272 +       return -EINVAL;
20273 +}
20274 +#endif
20275 +
20276 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20277 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
20278 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
20279 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
20280 +#endif
20281 +
20282  /*
20283   * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
20284   * disabled, then there's a single shared list of VMAs maintained by the
20285 @@ -167,6 +203,18 @@ extern unsigned int kobjsize(const void 
20286  #define VM_MAPPED_COPY 0x01000000      /* T if mapped copy of data (nommu mmap) */
20287  #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
20288  
20289 +#ifdef CONFIG_PAX_SEGMEXEC
20290 +#define VM_MIRROR      0x04000000      /* vma is mirroring another */
20291 +#endif
20292 +
20293 +#ifdef CONFIG_PAX_MPROTECT
20294 +#define VM_MAYNOTWRITE 0x08000000      /* vma cannot be granted VM_WRITE any more */
20295 +#endif
20296 +
20297 +#ifdef __VM_STACK_FLAGS
20298 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
20299 +#endif
20300 +
20301  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
20302  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
20303  #endif
20304 @@ -1057,5 +1105,11 @@ void drop_slab(void);
20305  extern int randomize_va_space;
20306  #endif
20307  
20308 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
20309 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
20310 +#else
20311 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
20312 +#endif
20313 +
20314  #endif /* __KERNEL__ */
20315  #endif /* _LINUX_MM_H */
20316 diff -urNp linux-2.6.16.2/include/linux/module.h linux-2.6.16.2/include/linux/module.h
20317 --- linux-2.6.16.2/include/linux/module.h       2006-04-07 12:56:47.000000000 -0400
20318 +++ linux-2.6.16.2/include/linux/module.h       2006-04-09 21:23:54.000000000 -0400
20319 @@ -263,16 +263,16 @@ struct module
20320         int (*init)(void);
20321  
20322         /* If this is non-NULL, vfree after init() returns */
20323 -       void *module_init;
20324 +       void *module_init_rx, *module_init_rw;
20325  
20326         /* Here is the actual code + data, vfree'd on unload. */
20327 -       void *module_core;
20328 +       void *module_core_rx, *module_core_rw;
20329  
20330         /* Here are the sizes of the init and core sections */
20331 -       unsigned long init_size, core_size;
20332 +       unsigned long init_size_rw, core_size_rw;
20333  
20334         /* The size of the executable code in each section.  */
20335 -       unsigned long init_text_size, core_text_size;
20336 +       unsigned long init_size_rx, core_size_rx;
20337  
20338         /* Arch-specific module values */
20339         struct mod_arch_specific arch;
20340 diff -urNp linux-2.6.16.2/include/linux/moduleloader.h linux-2.6.16.2/include/linux/moduleloader.h
20341 --- linux-2.6.16.2/include/linux/moduleloader.h 2006-04-07 12:56:47.000000000 -0400
20342 +++ linux-2.6.16.2/include/linux/moduleloader.h 2006-04-09 21:23:54.000000000 -0400
20343 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
20344     sections.  Returns NULL on failure. */
20345  void *module_alloc(unsigned long size);
20346  
20347 +#ifdef CONFIG_PAX_KERNEXEC
20348 +void *module_alloc_exec(unsigned long size);
20349 +#else
20350 +#define module_alloc_exec(x) module_alloc(x)
20351 +#endif
20352 +
20353  /* Free memory returned from module_alloc. */
20354  void module_free(struct module *mod, void *module_region);
20355  
20356 +#ifdef CONFIG_PAX_KERNEXEC
20357 +void module_free_exec(struct module *mod, void *module_region);
20358 +#else
20359 +#define module_free_exec(x, y) module_free(x, y)
20360 +#endif
20361 +
20362  /* Apply the given relocation to the (simplified) ELF.  Return -error
20363     or 0. */
20364  int apply_relocate(Elf_Shdr *sechdrs,
20365 diff -urNp linux-2.6.16.2/include/linux/random.h linux-2.6.16.2/include/linux/random.h
20366 --- linux-2.6.16.2/include/linux/random.h       2006-04-07 12:56:47.000000000 -0400
20367 +++ linux-2.6.16.2/include/linux/random.h       2006-04-09 21:23:54.000000000 -0400
20368 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
20369  extern u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
20370                                        __u16 sport, __u16 dport);
20371  
20372 +extern unsigned long pax_get_random_long(void);
20373 +
20374  #ifndef MODULE
20375  extern struct file_operations random_fops, urandom_fops;
20376  #endif
20377 diff -urNp linux-2.6.16.2/include/linux/sched.h linux-2.6.16.2/include/linux/sched.h
20378 --- linux-2.6.16.2/include/linux/sched.h        2006-04-07 12:56:47.000000000 -0400
20379 +++ linux-2.6.16.2/include/linux/sched.h        2006-04-09 21:23:54.000000000 -0400
20380 @@ -39,6 +39,7 @@
20381  #include <linux/auxvec.h>      /* For AT_VECTOR_SIZE */
20382  
20383  struct exec_domain;
20384 +struct linux_binprm;
20385  
20386  /*
20387   * cloning flags:
20388 @@ -348,8 +349,34 @@ struct mm_struct {
20389         /* aio bits */
20390         rwlock_t                ioctx_list_lock;
20391         struct kioctx           *ioctx_list;
20392 +
20393 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
20394 +       unsigned long pax_flags;
20395 +#endif
20396 +
20397 +#ifdef CONFIG_PAX_DLRESOLVE
20398 +       unsigned long call_dl_resolve;
20399 +#endif
20400 +
20401 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
20402 +       unsigned long call_syscall;
20403 +#endif
20404 +
20405 +#ifdef CONFIG_PAX_ASLR
20406 +       unsigned long delta_mmap;               /* randomized offset */
20407 +       unsigned long delta_exec;               /* randomized offset */
20408 +       unsigned long delta_stack;              /* randomized offset */
20409 +#endif
20410 +
20411  };
20412  
20413 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
20414 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
20415 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
20416 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
20417 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
20418 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
20419 +
20420  struct sighand_struct {
20421         atomic_t                count;
20422         struct k_sigaction      action[_NSIG];
20423 @@ -454,6 +481,15 @@ struct signal_struct {
20424         struct key *session_keyring;    /* keyring inherited over fork */
20425         struct key *process_keyring;    /* keyring private to this process */
20426  #endif
20427 +
20428 +#ifdef CONFIG_GRKERNSEC
20429 +       u32 curr_ip;
20430 +       u32 gr_saddr;
20431 +       u32 gr_daddr;
20432 +       u16 gr_sport;
20433 +       u16 gr_dport;
20434 +       u8 used_accept:1;
20435 +#endif
20436  };
20437  
20438  /* Context switch must be unlocked if interrupts are to be enabled */
20439 @@ -869,6 +905,16 @@ struct task_struct {
20440         nodemask_t mems_allowed;
20441         int cpuset_mems_generation;
20442  #endif
20443 +#ifdef CONFIG_GRKERNSEC
20444 +       /* grsecurity */
20445 +       struct acl_subject_label *acl;
20446 +       struct acl_role_label *role;
20447 +       struct file *exec_file;
20448 +       u16 acl_role_id;
20449 +       u8 acl_sp_role:1;
20450 +       u8 is_writable:1;
20451 +       u8 brute:1;
20452 +#endif
20453         atomic_t fs_excl;       /* holding fs exclusive resources */
20454         struct rcu_head rcu;
20455  };
20456 @@ -1377,6 +1423,12 @@ extern void arch_pick_mmap_layout(struct
20457  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
20458  {
20459         mm->mmap_base = TASK_UNMAPPED_BASE;
20460 +
20461 +#ifdef CONFIG_PAX_RANDMMAP
20462 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
20463 +               mm->mmap_base += mm->delta_mmap;
20464 +#endif
20465 +
20466         mm->get_unmapped_area = arch_get_unmapped_area;
20467         mm->unmap_area = arch_unmap_area;
20468  }
20469 diff -urNp linux-2.6.16.2/include/linux/shm.h linux-2.6.16.2/include/linux/shm.h
20470 --- linux-2.6.16.2/include/linux/shm.h  2006-04-07 12:56:47.000000000 -0400
20471 +++ linux-2.6.16.2/include/linux/shm.h  2006-04-09 21:23:54.000000000 -0400
20472 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
20473         pid_t                   shm_cprid;
20474         pid_t                   shm_lprid;
20475         struct user_struct      *mlock_user;
20476 +#ifdef CONFIG_GRKERNSEC
20477 +       time_t                  shm_createtime;
20478 +       pid_t                   shm_lapid;
20479 +#endif
20480  };
20481  
20482  /* shm_mode upper byte flags */
20483 diff -urNp linux-2.6.16.2/include/linux/sysctl.h linux-2.6.16.2/include/linux/sysctl.h
20484 --- linux-2.6.16.2/include/linux/sysctl.h       2006-04-07 12:56:47.000000000 -0400
20485 +++ linux-2.6.16.2/include/linux/sysctl.h       2006-04-09 21:23:54.000000000 -0400
20486 @@ -148,8 +148,20 @@ enum
20487         KERN_ACPI_VIDEO_FLAGS=71, /* int: flags for setting up video after ACPI sleep */
20488         KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */
20489         KERN_FBSPLASH=73,       /* string: path to fbsplash helper */
20490 +#ifdef CONFIG_GRKERNSEC
20491 +       KERN_GRSECURITY=98,     /* grsecurity */
20492 +#endif
20493 +#ifdef CONFIG_PAX_SOFTMODE
20494 +       KERN_PAX=99,            /* PaX control */
20495 +#endif
20496 +
20497  };
20498  
20499 +#ifdef CONFIG_PAX_SOFTMODE
20500 +enum {
20501 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
20502 +};
20503 +#endif
20504  
20505  /* CTL_VM names: */
20506  enum
20507 diff -urNp linux-2.6.16.2/init/Kconfig linux-2.6.16.2/init/Kconfig
20508 --- linux-2.6.16.2/init/Kconfig 2006-04-07 12:56:47.000000000 -0400
20509 +++ linux-2.6.16.2/init/Kconfig 2006-04-09 21:23:54.000000000 -0400
20510 @@ -257,6 +257,7 @@ menuconfig EMBEDDED
20511  config KALLSYMS
20512          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
20513          default y
20514 +        depends on !GRKERNSEC_HIDESYM
20515          help
20516            Say Y here to let the kernel print out symbolic crash information and
20517            symbolic stack backtraces. This increases the size of the kernel
20518 diff -urNp linux-2.6.16.2/init/main.c linux-2.6.16.2/init/main.c
20519 --- linux-2.6.16.2/init/main.c  2006-04-07 12:56:47.000000000 -0400
20520 +++ linux-2.6.16.2/init/main.c  2006-04-09 21:23:54.000000000 -0400
20521 @@ -100,6 +100,7 @@ static inline void mark_rodata_ro(void) 
20522  #ifdef CONFIG_TC
20523  extern void tc_init(void);
20524  #endif
20525 +extern void grsecurity_init(void);
20526  
20527  enum system_states system_state;
20528  EXPORT_SYMBOL(system_state);
20529 @@ -150,6 +151,15 @@ static int __init maxcpus(char *str)
20530  
20531  __setup("maxcpus=", maxcpus);
20532  
20533 +#ifdef CONFIG_PAX_SOFTMODE
20534 +static int __init setup_pax_softmode(char *str)
20535 +{
20536 +       get_option(&str, &pax_softmode);
20537 +       return 1;
20538 +}
20539 +__setup("pax_softmode=", setup_pax_softmode);
20540 +#endif
20541 +
20542  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
20543  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
20544  static const char *panic_later, *panic_param;
20545 @@ -699,6 +709,8 @@ static int init(void * unused)
20546                 prepare_namespace();
20547         }
20548  
20549 +       grsecurity_init();
20550 +
20551         /*
20552          * Ok, we have completed the initial bootup, and
20553          * we're essentially up and running. Get rid of the
20554 diff -urNp linux-2.6.16.2/ipc/msg.c linux-2.6.16.2/ipc/msg.c
20555 --- linux-2.6.16.2/ipc/msg.c    2006-04-07 12:56:47.000000000 -0400
20556 +++ linux-2.6.16.2/ipc/msg.c    2006-04-09 21:23:54.000000000 -0400
20557 @@ -28,6 +28,7 @@
20558  #include <linux/syscalls.h>
20559  #include <linux/audit.h>
20560  #include <linux/seq_file.h>
20561 +#include <linux/grsecurity.h>
20562  #include <asm/current.h>
20563  #include <asm/uaccess.h>
20564  #include "util.h"
20565 @@ -233,6 +234,9 @@ asmlinkage long sys_msgget (key_t key, i
20566                 msg_unlock(msq);
20567         }
20568         up(&msg_ids.sem);
20569 +
20570 +       gr_log_msgget(ret, msgflg);
20571 +
20572         return ret;
20573  }
20574  
20575 @@ -484,6 +488,8 @@ asmlinkage long sys_msgctl (int msqid, i
20576                 break;
20577         }
20578         case IPC_RMID:
20579 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
20580 +
20581                 freeque (msq, msqid); 
20582                 break;
20583         }
20584 diff -urNp linux-2.6.16.2/ipc/sem.c linux-2.6.16.2/ipc/sem.c
20585 --- linux-2.6.16.2/ipc/sem.c    2006-04-07 12:56:47.000000000 -0400
20586 +++ linux-2.6.16.2/ipc/sem.c    2006-04-09 21:23:54.000000000 -0400
20587 @@ -75,6 +75,7 @@
20588  #include <linux/audit.h>
20589  #include <linux/capability.h>
20590  #include <linux/seq_file.h>
20591 +#include <linux/grsecurity.h>
20592  #include <asm/uaccess.h>
20593  #include "util.h"
20594  
20595 @@ -243,6 +244,9 @@ asmlinkage long sys_semget (key_t key, i
20596         }
20597  
20598         up(&sem_ids.sem);
20599 +
20600 +       gr_log_semget(err, semflg);
20601 +
20602         return err;
20603  }
20604  
20605 @@ -834,6 +838,8 @@ static int semctl_down(int semid, int se
20606  
20607         switch(cmd){
20608         case IPC_RMID:
20609 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
20610 +
20611                 freeary(sma, semid);
20612                 err = 0;
20613                 break;
20614 diff -urNp linux-2.6.16.2/ipc/shm.c linux-2.6.16.2/ipc/shm.c
20615 --- linux-2.6.16.2/ipc/shm.c    2006-04-07 12:56:47.000000000 -0400
20616 +++ linux-2.6.16.2/ipc/shm.c    2006-04-09 21:23:54.000000000 -0400
20617 @@ -30,6 +30,7 @@
20618  #include <linux/capability.h>
20619  #include <linux/ptrace.h>
20620  #include <linux/seq_file.h>
20621 +#include <linux/grsecurity.h>
20622  
20623  #include <asm/uaccess.h>
20624  
20625 @@ -53,6 +54,14 @@ static void shm_close (struct vm_area_st
20626  static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
20627  #endif
20628  
20629 +#ifdef CONFIG_GRKERNSEC
20630 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
20631 +                          const time_t shm_createtime, const uid_t cuid,
20632 +                          const int shmid);
20633 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
20634 +                          const time_t shm_createtime);
20635 +#endif
20636 +
20637  size_t shm_ctlmax = SHMMAX;
20638  size_t         shm_ctlall = SHMALL;
20639  int    shm_ctlmni = SHMMNI;
20640 @@ -146,6 +155,17 @@ static void shm_close (struct vm_area_st
20641         shp->shm_lprid = current->tgid;
20642         shp->shm_dtim = get_seconds();
20643         shp->shm_nattch--;
20644 +#ifdef CONFIG_GRKERNSEC_SHM
20645 +       if (grsec_enable_shm) {
20646 +               if (shp->shm_nattch == 0) {
20647 +                       shp->shm_perm.mode |= SHM_DEST;
20648 +                       shm_destroy(shp);
20649 +               } else
20650 +                       shm_unlock(shp);
20651 +               up(&shm_ids.sem);
20652 +               return;
20653 +       }
20654 +#endif
20655         if(shp->shm_nattch == 0 &&
20656            shp->shm_perm.mode & SHM_DEST)
20657                 shm_destroy (shp);
20658 @@ -243,6 +263,9 @@ static int newseg (key_t key, int shmflg
20659         shp->shm_lprid = 0;
20660         shp->shm_atim = shp->shm_dtim = 0;
20661         shp->shm_ctim = get_seconds();
20662 +#ifdef CONFIG_GRKERNSEC
20663 +       shp->shm_createtime = get_seconds();
20664 +#endif
20665         shp->shm_segsz = size;
20666         shp->shm_nattch = 0;
20667         shp->id = shm_buildid(id,shp->shm_perm.seq);
20668 @@ -298,6 +321,8 @@ asmlinkage long sys_shmget (key_t key, s
20669         }
20670         up(&shm_ids.sem);
20671  
20672 +       gr_log_shmget(err, shmflg, size);
20673 +
20674         return err;
20675  }
20676  
20677 @@ -603,6 +628,8 @@ asmlinkage long sys_shmctl (int shmid, i
20678                 if (err)
20679                         goto out_unlock_up;
20680  
20681 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
20682 +
20683                 if (shp->shm_nattch){
20684                         shp->shm_perm.mode |= SHM_DEST;
20685                         /* Do not find it any more */
20686 @@ -747,9 +774,27 @@ long do_shmat(int shmid, char __user *sh
20687                 return err;
20688         }
20689                 
20690 +#ifdef CONFIG_GRKERNSEC
20691 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
20692 +                            shp->shm_perm.cuid, shmid)) {
20693 +               shm_unlock(shp);
20694 +               return -EACCES;
20695 +       }
20696 +
20697 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
20698 +               shm_unlock(shp);
20699 +               return -EACCES;
20700 +       }
20701 +#endif
20702 +
20703         file = shp->shm_file;
20704         size = i_size_read(file->f_dentry->d_inode);
20705         shp->shm_nattch++;
20706 +
20707 +#ifdef CONFIG_GRKERNSEC
20708 +       shp->shm_lapid = current->pid;
20709 +#endif
20710 +
20711         shm_unlock(shp);
20712  
20713         down_write(&current->mm->mmap_sem);
20714 @@ -916,3 +961,24 @@ static int sysvipc_shm_proc_show(struct 
20715                           shp->shm_ctim);
20716  }
20717  #endif
20718 +
20719 +void gr_shm_exit(struct task_struct *task)
20720 +{
20721 +#ifdef CONFIG_GRKERNSEC_SHM
20722 +       int i;
20723 +       struct shmid_kernel *shp;
20724 +
20725 +       if (!grsec_enable_shm)
20726 +               return;
20727 +
20728 +       for (i = 0; i <= shm_ids.max_id; i++) {
20729 +               shp = shm_get(i);
20730 +               if (shp && (shp->shm_cprid == task->pid) &&
20731 +                   (shp->shm_nattch <= 0)) {
20732 +                       shp->shm_perm.mode |= SHM_DEST;
20733 +                       shm_destroy(shp);
20734 +               }
20735 +       }
20736 +#endif
20737 +       return;
20738 +}
20739 diff -urNp linux-2.6.16.2/kernel/capability.c linux-2.6.16.2/kernel/capability.c
20740 --- linux-2.6.16.2/kernel/capability.c  2006-04-07 12:56:47.000000000 -0400
20741 +++ linux-2.6.16.2/kernel/capability.c  2006-04-09 21:23:54.000000000 -0400
20742 @@ -12,6 +12,7 @@
20743  #include <linux/module.h>
20744  #include <linux/security.h>
20745  #include <linux/syscalls.h>
20746 +#include <linux/grsecurity.h>
20747  #include <asm/uaccess.h>
20748  
20749  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
20750 diff -urNp linux-2.6.16.2/kernel/configs.c linux-2.6.16.2/kernel/configs.c
20751 --- linux-2.6.16.2/kernel/configs.c     2006-04-07 12:56:47.000000000 -0400
20752 +++ linux-2.6.16.2/kernel/configs.c     2006-04-09 21:23:54.000000000 -0400
20753 @@ -89,8 +89,16 @@ static int __init ikconfig_init(void)
20754         struct proc_dir_entry *entry;
20755  
20756         /* create the current config file */
20757 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
20758 +#ifdef CONFIG_GRKERNSEC_PROC_USER
20759 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
20760 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
20761 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
20762 +#endif
20763 +#else
20764         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
20765                                   &proc_root);
20766 +#endif
20767         if (!entry)
20768                 return -ENOMEM;
20769  
20770 diff -urNp linux-2.6.16.2/kernel/exit.c linux-2.6.16.2/kernel/exit.c
20771 --- linux-2.6.16.2/kernel/exit.c        2006-04-07 12:56:47.000000000 -0400
20772 +++ linux-2.6.16.2/kernel/exit.c        2006-04-09 21:23:54.000000000 -0400
20773 @@ -31,6 +31,11 @@
20774  #include <linux/signal.h>
20775  #include <linux/cn_proc.h>
20776  #include <linux/mutex.h>
20777 +#include <linux/grsecurity.h>
20778 +
20779 +#ifdef CONFIG_GRKERNSEC
20780 +extern rwlock_t grsec_exec_file_lock;
20781 +#endif
20782  
20783  #include <asm/uaccess.h>
20784  #include <asm/unistd.h>
20785 @@ -234,6 +239,15 @@ static void reparent_to_init(void)
20786  {
20787         write_lock_irq(&tasklist_lock);
20788  
20789 +#ifdef CONFIG_GRKERNSEC
20790 +       write_lock(&grsec_exec_file_lock);
20791 +       if (current->exec_file) {
20792 +               fput(current->exec_file);
20793 +               current->exec_file = NULL;
20794 +       }
20795 +       write_unlock(&grsec_exec_file_lock);
20796 +#endif
20797 +
20798         ptrace_unlink(current);
20799         /* Reparent to init */
20800         REMOVE_LINKS(current);
20801 @@ -241,6 +255,8 @@ static void reparent_to_init(void)
20802         current->real_parent = child_reaper;
20803         SET_LINKS(current);
20804  
20805 +       gr_set_kernel_label(current);
20806 +
20807         /* Set the exit signal to SIGCHLD so we signal init on exit */
20808         current->exit_signal = SIGCHLD;
20809  
20810 @@ -337,6 +353,17 @@ void daemonize(const char *name, ...)
20811         vsnprintf(current->comm, sizeof(current->comm), name, args);
20812         va_end(args);
20813  
20814 +#ifdef CONFIG_GRKERNSEC
20815 +       write_lock(&grsec_exec_file_lock);
20816 +       if (current->exec_file) {
20817 +               fput(current->exec_file);
20818 +               current->exec_file = NULL;
20819 +       }
20820 +       write_unlock(&grsec_exec_file_lock);
20821 +#endif
20822 +
20823 +       gr_set_kernel_label(current);
20824 +
20825         /*
20826          * If we were started as result of loading a module, close all of the
20827          * user space pages.  We don't need them, and if we didn't close them
20828 @@ -852,9 +879,14 @@ fastcall NORET_TYPE void do_exit(long co
20829                 exit_itimers(tsk->signal);
20830                 acct_process(code);
20831         }
20832 +
20833 +       gr_acl_handle_psacct(tsk, code);
20834 +       gr_acl_handle_exit();
20835 +
20836         exit_mm(tsk);
20837  
20838         exit_sem(tsk);
20839 +       gr_shm_exit(tsk);
20840         __exit_files(tsk);
20841         __exit_fs(tsk);
20842         exit_namespace(tsk);
20843 diff -urNp linux-2.6.16.2/kernel/fork.c linux-2.6.16.2/kernel/fork.c
20844 --- linux-2.6.16.2/kernel/fork.c        2006-04-07 12:56:47.000000000 -0400
20845 +++ linux-2.6.16.2/kernel/fork.c        2006-04-09 21:23:54.000000000 -0400
20846 @@ -44,6 +44,7 @@
20847  #include <linux/rmap.h>
20848  #include <linux/acct.h>
20849  #include <linux/cn_proc.h>
20850 +#include <linux/grsecurity.h>
20851  
20852  #include <asm/pgtable.h>
20853  #include <asm/pgalloc.h>
20854 @@ -200,8 +201,8 @@ static inline int dup_mmap(struct mm_str
20855         mm->locked_vm = 0;
20856         mm->mmap = NULL;
20857         mm->mmap_cache = NULL;
20858 -       mm->free_area_cache = oldmm->mmap_base;
20859 -       mm->cached_hole_size = ~0UL;
20860 +       mm->free_area_cache = oldmm->free_area_cache;
20861 +       mm->cached_hole_size = oldmm->cached_hole_size;
20862         mm->map_count = 0;
20863         cpus_clear(mm->cpu_vm_mask);
20864         mm->mm_rb = RB_ROOT;
20865 @@ -326,7 +327,7 @@ static struct mm_struct * mm_init(struct
20866         spin_lock_init(&mm->page_table_lock);
20867         rwlock_init(&mm->ioctx_list_lock);
20868         mm->ioctx_list = NULL;
20869 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
20870 +       mm->free_area_cache = ~0UL;
20871         mm->cached_hole_size = ~0UL;
20872  
20873         if (likely(!mm_alloc_pgd(mm))) {
20874 @@ -946,6 +947,9 @@ static task_t *copy_process(unsigned lon
20875                 goto fork_out;
20876  
20877         retval = -EAGAIN;
20878 +
20879 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
20880 +
20881         if (atomic_read(&p->user->processes) >=
20882                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
20883                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
20884 @@ -1055,6 +1059,8 @@ static task_t *copy_process(unsigned lon
20885         if (retval)
20886                 goto bad_fork_cleanup_namespace;
20887  
20888 +       gr_copy_label(p);
20889 +
20890         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
20891         /*
20892          * Clear TID on mm_release()?
20893 @@ -1239,6 +1245,8 @@ bad_fork_cleanup_count:
20894  bad_fork_free:
20895         free_task(p);
20896  fork_out:
20897 +       gr_log_forkfail(retval);
20898 +
20899         return ERR_PTR(retval);
20900  }
20901  
20902 @@ -1296,6 +1304,9 @@ long do_fork(unsigned long clone_flags,
20903  
20904         if (pid < 0)
20905                 return -EAGAIN;
20906 +
20907 +       gr_handle_brute_check();
20908 +
20909         if (unlikely(current->ptrace)) {
20910                 trace = fork_traceflag (clone_flags);
20911                 if (trace)
20912 diff -urNp linux-2.6.16.2/kernel/futex.c linux-2.6.16.2/kernel/futex.c
20913 --- linux-2.6.16.2/kernel/futex.c       2006-04-07 12:56:47.000000000 -0400
20914 +++ linux-2.6.16.2/kernel/futex.c       2006-04-09 21:23:54.000000000 -0400
20915 @@ -147,6 +147,11 @@ static int get_futex_key(unsigned long u
20916         struct page *page;
20917         int err;
20918  
20919 +#ifdef CONFIG_PAX_SEGMEXEC
20920 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (uaddr >= SEGMEXEC_TASK_SIZE))
20921 +               return -EFAULT;
20922 +#endif
20923 +
20924         /*
20925          * The futex address must be "naturally" aligned.
20926          */
20927 diff -urNp linux-2.6.16.2/kernel/kallsyms.c linux-2.6.16.2/kernel/kallsyms.c
20928 --- linux-2.6.16.2/kernel/kallsyms.c    2006-04-07 12:56:47.000000000 -0400
20929 +++ linux-2.6.16.2/kernel/kallsyms.c    2006-04-09 21:23:54.000000000 -0400
20930 @@ -301,7 +301,6 @@ static unsigned long get_ksymbol_core(st
20931  
20932  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
20933  {
20934 -       iter->name[0] = '\0';
20935         iter->nameoff = get_symbol_offset(new_pos);
20936         iter->pos = new_pos;
20937  }
20938 @@ -380,7 +379,7 @@ static int kallsyms_open(struct inode *i
20939         struct kallsym_iter *iter;
20940         int ret;
20941  
20942 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
20943 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
20944         if (!iter)
20945                 return -ENOMEM;
20946         reset_iter(iter, 0);
20947 @@ -411,7 +410,15 @@ static int __init kallsyms_init(void)
20948  {
20949         struct proc_dir_entry *entry;
20950  
20951 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
20952 +#ifdef CONFIG_GRKERNSEC_PROC_USER
20953 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
20954 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
20955 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
20956 +#endif
20957 +#else
20958         entry = create_proc_entry("kallsyms", 0444, NULL);
20959 +#endif
20960         if (entry)
20961                 entry->proc_fops = &kallsyms_operations;
20962         return 0;
20963 diff -urNp linux-2.6.16.2/kernel/kprobes.c linux-2.6.16.2/kernel/kprobes.c
20964 --- linux-2.6.16.2/kernel/kprobes.c     2006-04-07 12:56:47.000000000 -0400
20965 +++ linux-2.6.16.2/kernel/kprobes.c     2006-04-09 21:23:54.000000000 -0400
20966 @@ -106,7 +106,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
20967          * kernel image and loaded module images reside. This is required
20968          * so x86_64 can correctly handle the %rip-relative fixups.
20969          */
20970 -       kip->insns = module_alloc(PAGE_SIZE);
20971 +       kip->insns = module_alloc_exec(PAGE_SIZE);
20972         if (!kip->insns) {
20973                 kfree(kip);
20974                 return NULL;
20975 diff -urNp linux-2.6.16.2/kernel/module.c linux-2.6.16.2/kernel/module.c
20976 --- linux-2.6.16.2/kernel/module.c      2006-04-07 12:56:47.000000000 -0400
20977 +++ linux-2.6.16.2/kernel/module.c      2006-04-09 21:23:54.000000000 -0400
20978 @@ -39,10 +39,15 @@
20979  #include <linux/device.h>
20980  #include <linux/string.h>
20981  #include <linux/sched.h>
20982 +#include <linux/kallsyms.h>
20983  #include <asm/uaccess.h>
20984  #include <asm/semaphore.h>
20985  #include <asm/cacheflush.h>
20986  
20987 +#ifdef CONFIG_PAX_KERNEXEC
20988 +#include <asm/desc.h>
20989 +#endif
20990 +
20991  #if 0
20992  #define DEBUGP printk
20993  #else
20994 @@ -66,6 +71,8 @@ static LIST_HEAD(modules);
20995  static DECLARE_MUTEX(notify_mutex);
20996  static struct notifier_block * module_notify_list;
20997  
20998 +extern int gr_check_modstop(void);
20999 +
21000  int register_module_notifier(struct notifier_block * nb)
21001  {
21002         int err;
21003 @@ -576,6 +583,9 @@ sys_delete_module(const char __user *nam
21004         char name[MODULE_NAME_LEN];
21005         int ret, forced = 0;
21006  
21007 +       if (gr_check_modstop())
21008 +               return -EPERM;
21009 +
21010         if (!capable(CAP_SYS_MODULE))
21011                 return -EPERM;
21012  
21013 @@ -1178,13 +1188,15 @@ static void free_module(struct module *m
21014         module_unload_free(mod);
21015  
21016         /* This may be NULL, but that's OK */
21017 -       module_free(mod, mod->module_init);
21018 +       module_free(mod, mod->module_init_rw);
21019 +       module_free_exec(mod, mod->module_init_rx);
21020         kfree(mod->args);
21021         if (mod->percpu)
21022                 percpu_modfree(mod->percpu);
21023  
21024         /* Finally, free the core (containing the module structure) */
21025 -       module_free(mod, mod->module_core);
21026 +       module_free_exec(mod, mod->module_core_rx);
21027 +       module_free(mod, mod->module_core_rw);
21028  }
21029  
21030  void *__symbol_get(const char *symbol)
21031 @@ -1341,11 +1353,14 @@ static void layout_sections(struct modul
21032                             || strncmp(secstrings + s->sh_name,
21033                                        ".init", 5) == 0)
21034                                 continue;
21035 -                       s->sh_entsize = get_offset(&mod->core_size, s);
21036 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
21037 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
21038 +                       else
21039 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
21040                         DEBUGP("\t%s\n", secstrings + s->sh_name);
21041                 }
21042                 if (m == 0)
21043 -                       mod->core_text_size = mod->core_size;
21044 +                       mod->core_size_rx = mod->core_size_rx;
21045         }
21046  
21047         DEBUGP("Init section allocation order:\n");
21048 @@ -1359,12 +1374,15 @@ static void layout_sections(struct modul
21049                             || strncmp(secstrings + s->sh_name,
21050                                        ".init", 5) != 0)
21051                                 continue;
21052 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
21053 -                                        | INIT_OFFSET_MASK);
21054 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
21055 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
21056 +                       else
21057 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
21058 +                       s->sh_entsize |= INIT_OFFSET_MASK;
21059                         DEBUGP("\t%s\n", secstrings + s->sh_name);
21060                 }
21061                 if (m == 0)
21062 -                       mod->init_text_size = mod->init_size;
21063 +                       mod->init_size_rx = mod->init_size_rx;
21064         }
21065  }
21066  
21067 @@ -1545,6 +1563,10 @@ static struct module *load_module(void _
21068         struct exception_table_entry *extable;
21069         mm_segment_t old_fs;
21070  
21071 +#ifdef CONFIG_PAX_KERNEXEC
21072 +       unsigned long cr0;
21073 +#endif
21074 +
21075         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
21076                umod, len, uargs);
21077         if (len < sizeof(*hdr))
21078 @@ -1704,21 +1726,57 @@ static struct module *load_module(void _
21079         layout_sections(mod, hdr, sechdrs, secstrings);
21080  
21081         /* Do the allocs. */
21082 -       ptr = module_alloc(mod->core_size);
21083 +       ptr = module_alloc(mod->core_size_rw);
21084         if (!ptr) {
21085                 err = -ENOMEM;
21086                 goto free_percpu;
21087         }
21088 -       memset(ptr, 0, mod->core_size);
21089 -       mod->module_core = ptr;
21090 +       memset(ptr, 0, mod->core_size_rw);
21091 +       mod->module_core_rw = ptr;
21092 +
21093 +       ptr = module_alloc(mod->init_size_rw);
21094 +       if (!ptr && mod->init_size_rw) {
21095 +               err = -ENOMEM;
21096 +               goto free_core_rw;
21097 +       }
21098 +       memset(ptr, 0, mod->init_size_rw);
21099 +       mod->module_init_rw = ptr;
21100 +
21101 +       ptr = module_alloc_exec(mod->core_size_rx);
21102 +       if (!ptr) {
21103 +               err = -ENOMEM;
21104 +               goto free_init_rw;
21105 +       }
21106 +
21107 +#ifdef CONFIG_PAX_KERNEXEC
21108 +       pax_open_kernel(cr0);
21109 +#endif
21110 +
21111 +       memset(ptr, 0, mod->core_size_rx);
21112 +
21113 +#ifdef CONFIG_PAX_KERNEXEC
21114 +       pax_close_kernel(cr0);
21115 +#endif
21116 +
21117 +       mod->module_core_rx = ptr;
21118  
21119 -       ptr = module_alloc(mod->init_size);
21120 -       if (!ptr && mod->init_size) {
21121 +       ptr = module_alloc_exec(mod->init_size_rx);
21122 +       if (!ptr && mod->init_size_rx) {
21123                 err = -ENOMEM;
21124 -               goto free_core;
21125 +               goto free_core_rx;
21126         }
21127 -       memset(ptr, 0, mod->init_size);
21128 -       mod->module_init = ptr;
21129 +
21130 +#ifdef CONFIG_PAX_KERNEXEC
21131 +       pax_open_kernel(cr0);
21132 +#endif
21133 +
21134 +       memset(ptr, 0, mod->init_size_rx);
21135 +
21136 +#ifdef CONFIG_PAX_KERNEXEC
21137 +       pax_close_kernel(cr0);
21138 +#endif
21139 +
21140 +       mod->module_init_rx = ptr;
21141  
21142         /* Transfer each section which specifies SHF_ALLOC */
21143         DEBUGP("final section addresses:\n");
21144 @@ -1728,17 +1786,44 @@ static struct module *load_module(void _
21145                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
21146                         continue;
21147  
21148 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
21149 -                       dest = mod->module_init
21150 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
21151 -               else
21152 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
21153 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
21154 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
21155 +                               dest = mod->module_init_rw
21156 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
21157 +                       else
21158 +                               dest = mod->module_init_rx
21159 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
21160 +               } else {
21161 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
21162 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
21163 +                       else
21164 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
21165 +               }
21166  
21167 -               if (sechdrs[i].sh_type != SHT_NOBITS)
21168 -                       memcpy(dest, (void *)sechdrs[i].sh_addr,
21169 -                              sechdrs[i].sh_size);
21170 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
21171 +
21172 +#ifdef CONFIG_PAX_KERNEXEC
21173 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
21174 +                               pax_open_kernel(cr0);
21175 +#endif
21176 +
21177 +                       memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
21178 +
21179 +#ifdef CONFIG_PAX_KERNEXEC
21180 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
21181 +                               pax_close_kernel(cr0);
21182 +#endif
21183 +
21184 +               }
21185                 /* Update sh_addr to point to copy in image. */
21186 -               sechdrs[i].sh_addr = (unsigned long)dest;
21187 +
21188 +#ifdef CONFIG_PAX_KERNEXEC
21189 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
21190 +                       sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
21191 +               else
21192 +#endif
21193 +
21194 +                       sechdrs[i].sh_addr = (unsigned long)dest;
21195                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
21196         }
21197         /* Module has been moved. */
21198 @@ -1761,8 +1846,18 @@ static struct module *load_module(void _
21199  #endif
21200  
21201         /* Fix up syms, so that st_value is a pointer to location. */
21202 +
21203 +#ifdef CONFIG_PAX_KERNEXEC
21204 +       pax_open_kernel(cr0);
21205 +#endif
21206 +
21207         err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
21208                                mod);
21209 +
21210 +#ifdef CONFIG_PAX_KERNEXEC
21211 +       pax_close_kernel(cr0);
21212 +#endif
21213 +
21214         if (err < 0)
21215                 goto cleanup;
21216  
21217 @@ -1798,11 +1893,20 @@ static struct module *load_module(void _
21218                 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
21219                         continue;
21220  
21221 +#ifdef CONFIG_PAX_KERNEXEC
21222 +       pax_open_kernel(cr0);
21223 +#endif
21224 +
21225                 if (sechdrs[i].sh_type == SHT_REL)
21226                         err = apply_relocate(sechdrs, strtab, symindex, i,mod);
21227                 else if (sechdrs[i].sh_type == SHT_RELA)
21228                         err = apply_relocate_add(sechdrs, strtab, symindex, i,
21229                                                  mod);
21230 +
21231 +#ifdef CONFIG_PAX_KERNEXEC
21232 +       pax_close_kernel(cr0);
21233 +#endif
21234 +
21235                 if (err < 0)
21236                         goto cleanup;
21237         }
21238 @@ -1816,14 +1920,31 @@ static struct module *load_module(void _
21239         /* Set up and sort exception table */
21240         mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
21241         mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
21242 +
21243 +#ifdef CONFIG_PAX_KERNEXEC
21244 +       pax_open_kernel(cr0);
21245 +#endif
21246 +
21247         sort_extable(extable, extable + mod->num_exentries);
21248  
21249 +#ifdef CONFIG_PAX_KERNEXEC
21250 +       pax_close_kernel(cr0);
21251 +#endif
21252 +
21253         /* Finally, copy percpu area over. */
21254         percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
21255                        sechdrs[pcpuindex].sh_size);
21256  
21257 +#ifdef CONFIG_PAX_KERNEXEC
21258 +       pax_open_kernel(cr0);
21259 +#endif
21260 +
21261         add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
21262  
21263 +#ifdef CONFIG_PAX_KERNEXEC
21264 +       pax_close_kernel(cr0);
21265 +#endif
21266 +
21267         err = module_finalize(hdr, sechdrs, mod);
21268         if (err < 0)
21269                 goto cleanup;
21270 @@ -1837,12 +1958,12 @@ static struct module *load_module(void _
21271          * Do it before processing of module parameters, so the module
21272          * can provide parameter accessor functions of its own.
21273          */
21274 -       if (mod->module_init)
21275 -               flush_icache_range((unsigned long)mod->module_init,
21276 -                                  (unsigned long)mod->module_init
21277 -                                  + mod->init_size);
21278 -       flush_icache_range((unsigned long)mod->module_core,
21279 -                          (unsigned long)mod->module_core + mod->core_size);
21280 +       if (mod->module_init_rx)
21281 +               flush_icache_range((unsigned long)mod->module_init_rx,
21282 +                                  (unsigned long)mod->module_init_rx
21283 +                                  + mod->init_size_rx);
21284 +       flush_icache_range((unsigned long)mod->module_core_rx,
21285 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
21286  
21287         set_fs(old_fs);
21288  
21289 @@ -1890,9 +2011,13 @@ static struct module *load_module(void _
21290         module_arch_cleanup(mod);
21291   cleanup:
21292         module_unload_free(mod);
21293 -       module_free(mod, mod->module_init);
21294 - free_core:
21295 -       module_free(mod, mod->module_core);
21296 +       module_free_exec(mod, mod->module_init_rx);
21297 + free_core_rx:
21298 +       module_free_exec(mod, mod->module_core_rx);
21299 + free_init_rw:
21300 +       module_free(mod, mod->module_init_rw);
21301 + free_core_rw:
21302 +       module_free(mod, mod->module_core_rw);
21303   free_percpu:
21304         if (percpu)
21305                 percpu_modfree(percpu);
21306 @@ -1928,6 +2053,9 @@ sys_init_module(void __user *umod,
21307         struct module *mod;
21308         int ret = 0;
21309  
21310 +       if (gr_check_modstop())
21311 +               return -EPERM;
21312 +
21313         /* Must have permission */
21314         if (!capable(CAP_SYS_MODULE))
21315                 return -EPERM;
21316 @@ -1979,10 +2107,12 @@ sys_init_module(void __user *umod,
21317         mod->state = MODULE_STATE_LIVE;
21318         /* Drop initial reference. */
21319         module_put(mod);
21320 -       module_free(mod, mod->module_init);
21321 -       mod->module_init = NULL;
21322 -       mod->init_size = 0;
21323 -       mod->init_text_size = 0;
21324 +       module_free(mod, mod->module_init_rw);
21325 +       module_free_exec(mod, mod->module_init_rx);
21326 +       mod->module_init_rw = NULL;
21327 +       mod->module_init_rx = NULL;
21328 +       mod->init_size_rw = 0;
21329 +       mod->init_size_rx = 0;
21330         up(&module_mutex);
21331  
21332         return 0;
21333 @@ -2013,10 +2143,14 @@ static const char *get_ksymbol(struct mo
21334         unsigned long nextval;
21335  
21336         /* At worse, next value is at end of module */
21337 -       if (within(addr, mod->module_init, mod->init_size))
21338 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
21339 -       else 
21340 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
21341 +       if (within(addr, mod->module_init_rx, mod->init_size_rx))
21342 +               nextval = (unsigned long)mod->module_init_rw;
21343 +       else if (within(addr, mod->module_init_rw, mod->init_size_rw))
21344 +               nextval = (unsigned long)mod->module_core_rx;
21345 +       else if (within(addr, mod->module_core_rx, mod->core_size_rx))
21346 +               nextval = (unsigned long)mod->module_core_rw;
21347 +       else
21348 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
21349  
21350         /* Scan for closest preceeding symbol, and next symbol. (ELF
21351             starts real symbols at 1). */
21352 @@ -2057,8 +2191,10 @@ const char *module_address_lookup(unsign
21353         struct module *mod;
21354  
21355         list_for_each_entry(mod, &modules, list) {
21356 -               if (within(addr, mod->module_init, mod->init_size)
21357 -                   || within(addr, mod->module_core, mod->core_size)) {
21358 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
21359 +                   || within(addr, mod->module_init_rw, mod->init_size_rw)
21360 +                   || within(addr, mod->module_core_rx, mod->core_size_rx)
21361 +                   || within(addr, mod->module_core_rw, mod->core_size_rw)) {
21362                         *modname = mod->name;
21363                         return get_ksymbol(mod, addr, size, offset);
21364                 }
21365 @@ -2069,7 +2205,7 @@ const char *module_address_lookup(unsign
21366  struct module *module_get_kallsym(unsigned int symnum,
21367                                   unsigned long *value,
21368                                   char *type,
21369 -                                 char namebuf[128])
21370 +                                 char namebuf[KSYM_NAME_LEN+1])
21371  {
21372         struct module *mod;
21373  
21374 @@ -2080,7 +2216,7 @@ struct module *module_get_kallsym(unsign
21375                         *type = mod->symtab[symnum].st_info;
21376                         strncpy(namebuf,
21377                                 mod->strtab + mod->symtab[symnum].st_name,
21378 -                               127);
21379 +                               KSYM_NAME_LEN);
21380                         up(&module_mutex);
21381                         return mod;
21382                 }
21383 @@ -2157,7 +2293,7 @@ static int m_show(struct seq_file *m, vo
21384  {
21385         struct module *mod = list_entry(p, struct module, list);
21386         seq_printf(m, "%s %lu",
21387 -                  mod->name, mod->init_size + mod->core_size);
21388 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
21389         print_unload_info(m, mod);
21390  
21391         /* Informative for users. */
21392 @@ -2166,7 +2302,7 @@ static int m_show(struct seq_file *m, vo
21393                    mod->state == MODULE_STATE_COMING ? "Loading":
21394                    "Live");
21395         /* Used by oprofile and other similar tools. */
21396 -       seq_printf(m, " 0x%p", mod->module_core);
21397 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
21398  
21399         seq_printf(m, "\n");
21400         return 0;
21401 @@ -2214,9 +2350,13 @@ struct module *__module_text_address(uns
21402  {
21403         struct module *mod;
21404  
21405 +#ifdef CONFIG_PAX_KERNEXEC
21406 +       addr += __KERNEL_TEXT_OFFSET;
21407 +#endif
21408 +
21409         list_for_each_entry(mod, &modules, list)
21410 -               if (within(addr, mod->module_init, mod->init_text_size)
21411 -                   || within(addr, mod->module_core, mod->core_text_size))
21412 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
21413 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
21414                         return mod;
21415         return NULL;
21416  }
21417 diff -urNp linux-2.6.16.2/kernel/pid.c linux-2.6.16.2/kernel/pid.c
21418 --- linux-2.6.16.2/kernel/pid.c 2006-04-07 12:56:47.000000000 -0400
21419 +++ linux-2.6.16.2/kernel/pid.c 2006-04-09 21:23:54.000000000 -0400
21420 @@ -26,6 +26,7 @@
21421  #include <linux/init.h>
21422  #include <linux/bootmem.h>
21423  #include <linux/hash.h>
21424 +#include <linux/grsecurity.h>
21425  
21426  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
21427  static struct hlist_head *pid_hash[PIDTYPE_MAX];
21428 @@ -76,7 +77,9 @@ int alloc_pidmap(void)
21429         int i, offset, max_scan, pid, last = last_pid;
21430         pidmap_t *map;
21431  
21432 -       pid = last + 1;
21433 +       pid = gr_random_pid();
21434 +       if (!pid)
21435 +               pid = last_pid + 1;
21436         if (pid >= pid_max)
21437                 pid = RESERVED_PIDS;
21438         offset = pid & BITS_PER_PAGE_MASK;
21439 @@ -207,12 +210,18 @@ void fastcall detach_pid(task_t *task, e
21440  task_t *find_task_by_pid_type(int type, int nr)
21441  {
21442         struct pid *pid;
21443 +       task_t *task = NULL;
21444  
21445         pid = find_pid(type, nr);
21446         if (!pid)
21447                 return NULL;
21448  
21449 -       return pid_task(&pid->pid_list, type);
21450 +       task = pid_task(&pid->pid_list, type);
21451 +
21452 +       if (gr_pid_is_chrooted(task))
21453 +               return NULL;
21454 +
21455 +       return task;
21456  }
21457  
21458  EXPORT_SYMBOL(find_task_by_pid_type);
21459 diff -urNp linux-2.6.16.2/kernel/posix-cpu-timers.c linux-2.6.16.2/kernel/posix-cpu-timers.c
21460 --- linux-2.6.16.2/kernel/posix-cpu-timers.c    2006-04-07 12:56:47.000000000 -0400
21461 +++ linux-2.6.16.2/kernel/posix-cpu-timers.c    2006-04-09 21:23:54.000000000 -0400
21462 @@ -6,6 +6,7 @@
21463  #include <linux/posix-timers.h>
21464  #include <asm/uaccess.h>
21465  #include <linux/errno.h>
21466 +#include <linux/grsecurity.h>
21467  
21468  static int check_clock(const clockid_t which_clock)
21469  {
21470 @@ -1128,6 +1129,7 @@ static void check_process_timers(struct 
21471                         __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
21472                         return;
21473                 }
21474 +               gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
21475                 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
21476                         /*
21477                          * At the soft limit, send a SIGXCPU every second.
21478 diff -urNp linux-2.6.16.2/kernel/printk.c linux-2.6.16.2/kernel/printk.c
21479 --- linux-2.6.16.2/kernel/printk.c      2006-04-07 12:56:47.000000000 -0400
21480 +++ linux-2.6.16.2/kernel/printk.c      2006-04-09 21:23:54.000000000 -0400
21481 @@ -31,6 +31,7 @@
21482  #include <linux/security.h>
21483  #include <linux/bootmem.h>
21484  #include <linux/syscalls.h>
21485 +#include <linux/grsecurity.h>
21486  
21487  #include <asm/uaccess.h>
21488  
21489 @@ -223,6 +224,11 @@ int do_syslog(int type, char __user *buf
21490         char c;
21491         int error = 0;
21492  
21493 +#ifdef CONFIG_GRKERNSEC_DMESG
21494 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
21495 +               return -EPERM;
21496 +#endif
21497 +
21498         error = security_syslog(type);
21499         if (error)
21500                 return error;
21501 diff -urNp linux-2.6.16.2/kernel/ptrace.c linux-2.6.16.2/kernel/ptrace.c
21502 --- linux-2.6.16.2/kernel/ptrace.c      2006-04-07 12:56:47.000000000 -0400
21503 +++ linux-2.6.16.2/kernel/ptrace.c      2006-04-09 21:23:54.000000000 -0400
21504 @@ -18,6 +18,7 @@
21505  #include <linux/ptrace.h>
21506  #include <linux/security.h>
21507  #include <linux/signal.h>
21508 +#include <linux/grsecurity.h>
21509  
21510  #include <asm/pgtable.h>
21511  #include <asm/uaccess.h>
21512 @@ -131,10 +132,10 @@ static int may_attach(struct task_struct
21513              (current->uid != task->uid) ||
21514              (current->gid != task->egid) ||
21515              (current->gid != task->sgid) ||
21516 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
21517 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
21518                 return -EPERM;
21519         smp_rmb();
21520 -       if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
21521 +       if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
21522                 return -EPERM;
21523  
21524         return security_ptrace(current, task);
21525 @@ -498,6 +499,11 @@ asmlinkage long sys_ptrace(long request,
21526         if (ret < 0)
21527                 goto out_put_task_struct;
21528  
21529 +       if (gr_handle_ptrace(child, request)) {
21530 +               ret = -EPERM;
21531 +               goto out_put_task_struct;
21532 +       }
21533 +
21534         ret = arch_ptrace(child, request, addr, data);
21535         if (ret < 0)
21536                 goto out_put_task_struct;
21537 diff -urNp linux-2.6.16.2/kernel/resource.c linux-2.6.16.2/kernel/resource.c
21538 --- linux-2.6.16.2/kernel/resource.c    2006-04-07 12:56:47.000000000 -0400
21539 +++ linux-2.6.16.2/kernel/resource.c    2006-04-09 21:23:54.000000000 -0400
21540 @@ -136,10 +136,27 @@ static int __init ioresources_init(void)
21541  {
21542         struct proc_dir_entry *entry;
21543  
21544 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
21545 +#ifdef CONFIG_GRKERNSEC_PROC_USER
21546 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
21547 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
21548 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
21549 +#endif
21550 +#else
21551         entry = create_proc_entry("ioports", 0, NULL);
21552 +#endif
21553         if (entry)
21554                 entry->proc_fops = &proc_ioports_operations;
21555 +
21556 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
21557 +#ifdef CONFIG_GRKERNSEC_PROC_USER
21558 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
21559 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
21560 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
21561 +#endif
21562 +#else
21563         entry = create_proc_entry("iomem", 0, NULL);
21564 +#endif
21565         if (entry)
21566                 entry->proc_fops = &proc_iomem_operations;
21567         return 0;
21568 diff -urNp linux-2.6.16.2/kernel/sched.c linux-2.6.16.2/kernel/sched.c
21569 --- linux-2.6.16.2/kernel/sched.c       2006-04-07 12:56:47.000000000 -0400
21570 +++ linux-2.6.16.2/kernel/sched.c       2006-04-09 21:23:54.000000000 -0400
21571 @@ -49,6 +49,7 @@
21572  #include <linux/syscalls.h>
21573  #include <linux/times.h>
21574  #include <linux/acct.h>
21575 +#include <linux/grsecurity.h>
21576  #include <asm/tlb.h>
21577  
21578  #include <asm/unistd.h>
21579 @@ -3537,7 +3538,8 @@ asmlinkage long sys_nice(int increment)
21580         if (nice > 19)
21581                 nice = 19;
21582  
21583 -       if (increment < 0 && !can_nice(current, nice))
21584 +       if (increment < 0 && (!can_nice(current, nice) ||
21585 +                             gr_handle_chroot_nice()))
21586                 return -EPERM;
21587  
21588         retval = security_task_setnice(current, nice);
21589 diff -urNp linux-2.6.16.2/kernel/signal.c linux-2.6.16.2/kernel/signal.c
21590 --- linux-2.6.16.2/kernel/signal.c      2006-04-07 12:56:47.000000000 -0400
21591 +++ linux-2.6.16.2/kernel/signal.c      2006-04-09 21:23:54.000000000 -0400
21592 @@ -26,6 +26,7 @@
21593  #include <linux/signal.h>
21594  #include <linux/audit.h>
21595  #include <linux/capability.h>
21596 +#include <linux/grsecurity.h>
21597  #include <asm/param.h>
21598  #include <asm/uaccess.h>
21599  #include <asm/unistd.h>
21600 @@ -380,6 +381,7 @@ void __exit_signal(struct task_struct *t
21601                 }
21602                 if (tsk == sig->curr_target)
21603                         sig->curr_target = next_thread(tsk);
21604 +               gr_del_task_from_ip_table(tsk);
21605                 tsk->signal = NULL;
21606                 /*
21607                  * Accumulate here the counters for all threads but the
21608 @@ -681,16 +683,18 @@ static int check_kill_permission(int sig
21609                 return error;
21610         error = -EPERM;
21611         if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
21612 -           && ((sig != SIGCONT) ||
21613 +           && ((((sig != SIGCONT) ||
21614                 (current->signal->session != t->signal->session))
21615             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
21616             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
21617 -           && !capable(CAP_KILL))
21618 +           && !capable(CAP_KILL)) || gr_handle_signal(t, sig)))
21619                 return error;
21620  
21621         error = security_task_kill(t, info, sig);
21622 -       if (!error)
21623 +       if (!error) {
21624                 audit_signal_info(sig, t); /* Let audit system see the signal */
21625 +               gr_log_signal(sig, t);
21626 +       }
21627         return error;
21628  }
21629  
21630 @@ -870,7 +874,7 @@ out_set:
21631         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
21632  
21633  
21634 -static int
21635 +int
21636  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
21637  {
21638         int ret = 0;
21639 @@ -916,6 +920,10 @@ force_sig_info(int sig, struct siginfo *
21640         }
21641         recalc_sigpending_tsk(t);
21642         ret = specific_send_sig_info(sig, info, t);
21643 +
21644 +       gr_log_signal(sig, t);
21645 +       gr_handle_crash(t, sig);
21646 +
21647         spin_unlock_irqrestore(&t->sighand->siglock, flags);
21648  
21649         return ret;
21650 diff -urNp linux-2.6.16.2/kernel/sys.c linux-2.6.16.2/kernel/sys.c
21651 --- linux-2.6.16.2/kernel/sys.c 2006-04-07 12:56:47.000000000 -0400
21652 +++ linux-2.6.16.2/kernel/sys.c 2006-04-09 21:23:54.000000000 -0400
21653 @@ -30,6 +30,7 @@
21654  #include <linux/tty.h>
21655  #include <linux/signal.h>
21656  #include <linux/cn_proc.h>
21657 +#include <linux/grsecurity.h>
21658  
21659  #include <linux/compat.h>
21660  #include <linux/syscalls.h>
21661 @@ -225,16 +226,33 @@ int unregister_reboot_notifier(struct no
21662  EXPORT_SYMBOL(unregister_reboot_notifier);
21663  
21664  #ifndef CONFIG_SECURITY
21665 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
21666 +extern int gr_is_capable_nolog(const int cap);
21667  int capable(int cap)
21668  {
21669 -        if (cap_raised(current->cap_effective, cap)) {
21670 +        if (cap_raised(current->cap_effective, cap) && gr_task_is_capable(current, cap)) {
21671 +              current->flags |= PF_SUPERPRIV;
21672 +              return 1;
21673 +        }
21674 +        return 0;
21675 +}
21676 +int capable_nolog(int cap)
21677 +{
21678 +        if (cap_raised(current->cap_effective, cap) && gr_is_capable_nolog(cap)) {
21679                current->flags |= PF_SUPERPRIV;
21680                return 1;
21681          }
21682          return 0;
21683  }
21684  EXPORT_SYMBOL(capable);
21685 +#else
21686 +int capable_nolog(int cap)
21687 +{
21688 +       return capable(cap);
21689 +}
21690 +
21691  #endif
21692 +EXPORT_SYMBOL(capable_nolog);
21693  
21694  static int set_one_prio(struct task_struct *p, int niceval, int error)
21695  {
21696 @@ -249,6 +267,12 @@ static int set_one_prio(struct task_stru
21697                 error = -EACCES;
21698                 goto out;
21699         }
21700 +
21701 +       if (gr_handle_chroot_setpriority(p, niceval)) {
21702 +               error = -EACCES;
21703 +               goto out;
21704 +       }
21705 +
21706         no_nice = security_task_setnice(p, niceval);
21707         if (no_nice) {
21708                 error = no_nice;
21709 @@ -638,6 +662,9 @@ asmlinkage long sys_setregid(gid_t rgid,
21710         if (rgid != (gid_t) -1 ||
21711             (egid != (gid_t) -1 && egid != old_rgid))
21712                 current->sgid = new_egid;
21713 +
21714 +       gr_set_role_label(current, current->uid, new_rgid);
21715 +
21716         current->fsgid = new_egid;
21717         current->egid = new_egid;
21718         current->gid = new_rgid;
21719 @@ -667,6 +694,9 @@ asmlinkage long sys_setgid(gid_t gid)
21720                         current->mm->dumpable = suid_dumpable;
21721                         smp_wmb();
21722                 }
21723 +
21724 +               gr_set_role_label(current, current->uid, gid);
21725 +
21726                 current->gid = current->egid = current->sgid = current->fsgid = gid;
21727         }
21728         else if ((gid == current->gid) || (gid == current->sgid))
21729 @@ -708,6 +738,9 @@ static int set_user(uid_t new_ruid, int 
21730                 current->mm->dumpable = suid_dumpable;
21731                 smp_wmb();
21732         }
21733 +
21734 +       gr_set_role_label(current, new_ruid, current->gid);
21735 +
21736         current->uid = new_ruid;
21737         return 0;
21738  }
21739 @@ -811,6 +844,9 @@ asmlinkage long sys_setuid(uid_t uid)
21740         } else if ((uid != current->uid) && (uid != new_suid))
21741                 return -EPERM;
21742  
21743 +       if (gr_check_crash_uid(uid))
21744 +               return -EPERM;
21745 +
21746         if (old_euid != uid)
21747         {
21748                 current->mm->dumpable = suid_dumpable;
21749 @@ -916,8 +952,10 @@ asmlinkage long sys_setresgid(gid_t rgid
21750                 current->egid = egid;
21751         }
21752         current->fsgid = current->egid;
21753 -       if (rgid != (gid_t) -1)
21754 +       if (rgid != (gid_t) -1) {
21755 +               gr_set_role_label(current, current->uid, rgid);
21756                 current->gid = rgid;
21757 +       }
21758         if (sgid != (gid_t) -1)
21759                 current->sgid = sgid;
21760  
21761 diff -urNp linux-2.6.16.2/kernel/sysctl.c linux-2.6.16.2/kernel/sysctl.c
21762 --- linux-2.6.16.2/kernel/sysctl.c      2006-04-07 12:56:47.000000000 -0400
21763 +++ linux-2.6.16.2/kernel/sysctl.c      2006-04-09 21:23:54.000000000 -0400
21764 @@ -54,6 +54,14 @@ extern int proc_nr_files(ctl_table *tabl
21765                       void __user *buffer, size_t *lenp, loff_t *ppos);
21766  
21767  #if defined(CONFIG_SYSCTL)
21768 +#include <linux/grsecurity.h>
21769 +#include <linux/grinternal.h>
21770 +
21771 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
21772 +                             const void *newval);
21773 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
21774 +                               const int op);
21775 +extern int gr_handle_chroot_sysctl(const int op);
21776  
21777  /* External variables not in a header file. */
21778  extern int C_A_D;
21779 @@ -157,6 +165,22 @@ extern ctl_table inotify_table[];
21780  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
21781  int sysctl_legacy_va_layout;
21782  #endif
21783 +extern ctl_table grsecurity_table[];
21784 +
21785 +#ifdef CONFIG_PAX_SOFTMODE
21786 +static ctl_table pax_table[] = {
21787 +       {
21788 +               .ctl_name       = PAX_SOFTMODE,
21789 +               .procname       = "softmode",
21790 +               .data           = &pax_softmode,
21791 +               .maxlen         = sizeof(unsigned int),
21792 +               .mode           = 0600,
21793 +               .proc_handler   = &proc_dointvec,
21794 +       },
21795 +
21796 +       { .ctl_name = 0 }
21797 +};
21798 +#endif
21799  
21800  /* /proc declarations: */
21801  
21802 @@ -683,6 +707,25 @@ static ctl_table kern_table[] = {
21803                 .proc_handler   = &proc_dointvec,
21804         },
21805  #endif
21806 +
21807 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
21808 +       {
21809 +               .ctl_name       = KERN_GRSECURITY,
21810 +               .procname       = "grsecurity",
21811 +               .mode           = 0500,
21812 +               .child          = grsecurity_table,
21813 +       },
21814 +#endif
21815 +
21816 +#ifdef CONFIG_PAX_SOFTMODE
21817 +       {
21818 +               .ctl_name       = KERN_PAX,
21819 +               .procname       = "pax",
21820 +               .mode           = 0500,
21821 +               .child          = pax_table,
21822 +       },
21823 +#endif
21824 +
21825         { .ctl_name = 0 }
21826  };
21827  
21828 @@ -1181,6 +1224,10 @@ static int test_perm(int mode, int op)
21829  static inline int ctl_perm(ctl_table *table, int op)
21830  {
21831         int error;
21832 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
21833 +               return -EACCES;
21834 +       if (gr_handle_chroot_sysctl(op))
21835 +               return -EACCES;
21836         error = security_sysctl(table, op);
21837         if (error)
21838                 return error;
21839 @@ -1217,6 +1264,10 @@ repeat:
21840                                 table = table->child;
21841                                 goto repeat;
21842                         }
21843 +
21844 +                       if (!gr_handle_sysctl(table, oldval, newval))
21845 +                               return -EACCES;
21846 +
21847                         error = do_sysctl_strategy(table, name, nlen,
21848                                                    oldval, oldlenp,
21849                                                    newval, newlen, context);
21850 diff -urNp linux-2.6.16.2/kernel/time.c linux-2.6.16.2/kernel/time.c
21851 --- linux-2.6.16.2/kernel/time.c        2006-04-07 12:56:47.000000000 -0400
21852 +++ linux-2.6.16.2/kernel/time.c        2006-04-09 21:23:54.000000000 -0400
21853 @@ -36,6 +36,7 @@
21854  #include <linux/security.h>
21855  #include <linux/fs.h>
21856  #include <linux/module.h>
21857 +#include <linux/grsecurity.h>
21858  
21859  #include <asm/uaccess.h>
21860  #include <asm/unistd.h>
21861 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user 
21862                 return err;
21863  
21864         do_settimeofday(&tv);
21865 +
21866 +       gr_log_timechange();
21867 +
21868         return 0;
21869  }
21870  
21871 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct 
21872                         return -EFAULT;
21873         }
21874  
21875 +       gr_log_timechange();
21876 +
21877         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
21878  }
21879  
21880 diff -urNp linux-2.6.16.2/localversion-grsec linux-2.6.16.2/localversion-grsec
21881 --- linux-2.6.16.2/localversion-grsec   1969-12-31 19:00:00.000000000 -0500
21882 +++ linux-2.6.16.2/localversion-grsec   2006-04-09 21:23:54.000000000 -0400
21883 @@ -0,0 +1 @@
21884 +-grsec
21885 diff -urNp linux-2.6.16.2/Makefile linux-2.6.16.2/Makefile
21886 --- linux-2.6.16.2/Makefile     2006-04-07 12:56:47.000000000 -0400
21887 +++ linux-2.6.16.2/Makefile     2006-04-09 21:23:54.000000000 -0400
21888 @@ -556,7 +556,7 @@ export MODLIB
21889  
21890  
21891  ifeq ($(KBUILD_EXTMOD),)
21892 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
21893 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
21894  
21895  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
21896                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
21897 diff -urNp linux-2.6.16.2/mm/filemap.c linux-2.6.16.2/mm/filemap.c
21898 --- linux-2.6.16.2/mm/filemap.c 2006-04-07 12:56:47.000000000 -0400
21899 +++ linux-2.6.16.2/mm/filemap.c 2006-04-09 21:23:54.000000000 -0400
21900 @@ -29,6 +29,7 @@
21901  #include <linux/blkdev.h>
21902  #include <linux/security.h>
21903  #include <linux/syscalls.h>
21904 +#include <linux/grsecurity.h>
21905  #include "filemap.h"
21906  /*
21907   * FIXME: remove all knowledge of the buffer layer from the core VM
21908 @@ -1587,7 +1588,13 @@ int generic_file_mmap(struct file * file
21909         struct address_space *mapping = file->f_mapping;
21910  
21911         if (!mapping->a_ops->readpage)
21912 -               return -ENOEXEC;
21913 +               return -ENODEV;
21914 +
21915 +#ifdef CONFIG_PAX_PAGEEXEC
21916 +       if (vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC)
21917 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
21918 +#endif
21919 +
21920         file_accessed(file);
21921         vma->vm_ops = &generic_file_vm_ops;
21922         return 0;
21923 @@ -1809,6 +1816,7 @@ inline int generic_write_checks(struct f
21924                          *pos = i_size_read(inode);
21925  
21926                 if (limit != RLIM_INFINITY) {
21927 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
21928                         if (*pos >= limit) {
21929                                 send_sig(SIGXFSZ, current, 0);
21930                                 return -EFBIG;
21931 diff -urNp linux-2.6.16.2/mm/madvise.c linux-2.6.16.2/mm/madvise.c
21932 --- linux-2.6.16.2/mm/madvise.c 2006-04-07 12:56:47.000000000 -0400
21933 +++ linux-2.6.16.2/mm/madvise.c 2006-04-09 21:23:54.000000000 -0400
21934 @@ -15,9 +15,46 @@
21935   * We can potentially split a vm area into separate
21936   * areas, each area with its own behavior.
21937   */
21938 +
21939 +#ifdef CONFIG_PAX_SEGMEXEC
21940 +static long __madvise_behavior(struct vm_area_struct * vma,
21941 +                    struct vm_area_struct **prev,
21942 +                    unsigned long start, unsigned long end, int behavior);
21943 +
21944 +static long madvise_behavior(struct vm_area_struct * vma,
21945 +                    struct vm_area_struct **prev,
21946 +                    unsigned long start, unsigned long end, int behavior)
21947 +{
21948 +       if (vma->vm_flags & VM_MIRROR) {
21949 +               struct vm_area_struct * vma_m, * prev_m;
21950 +               unsigned long start_m, end_m;
21951 +               int error;
21952 +
21953 +               start_m = vma->vm_start + vma->vm_mirror;
21954 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
21955 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
21956 +                       start_m = start + vma->vm_mirror;
21957 +                       end_m = end + vma->vm_mirror;
21958 +                       error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
21959 +                       if (error)
21960 +                               return error;
21961 +               } else {
21962 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
21963 +                       return -ENOMEM;
21964 +               }
21965 +       }
21966 +
21967 +       return __madvise_behavior(vma, prev, start, end, behavior);
21968 +}
21969 +
21970 +static long __madvise_behavior(struct vm_area_struct * vma,
21971 +                    struct vm_area_struct **prev,
21972 +                    unsigned long start, unsigned long end, int behavior)
21973 +#else
21974  static long madvise_behavior(struct vm_area_struct * vma,
21975                      struct vm_area_struct **prev,
21976                      unsigned long start, unsigned long end, int behavior)
21977 +#endif
21978  {
21979         struct mm_struct * mm = vma->vm_mm;
21980         int error = 0;
21981 diff -urNp linux-2.6.16.2/mm/memory.c linux-2.6.16.2/mm/memory.c
21982 --- linux-2.6.16.2/mm/memory.c  2006-04-07 12:56:47.000000000 -0400
21983 +++ linux-2.6.16.2/mm/memory.c  2006-04-09 21:23:54.000000000 -0400
21984 @@ -48,6 +48,7 @@
21985  #include <linux/rmap.h>
21986  #include <linux/module.h>
21987  #include <linux/init.h>
21988 +#include <linux/grsecurity.h>
21989  
21990  #include <asm/pgalloc.h>
21991  #include <asm/uaccess.h>
21992 @@ -321,6 +322,11 @@ int __pte_alloc(struct mm_struct *mm, pm
21993  
21994  int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
21995  {
21996 +
21997 +#ifdef CONFIG_PAX_KERNEXEC
21998 +       unsigned long cr0;
21999 +#endif
22000 +
22001         pte_t *new = pte_alloc_one_kernel(&init_mm, address);
22002         if (!new)
22003                 return -ENOMEM;
22004 @@ -328,8 +334,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
22005         spin_lock(&init_mm.page_table_lock);
22006         if (pmd_present(*pmd))          /* Another has populated it */
22007                 pte_free_kernel(new);
22008 -       else
22009 +       else {
22010 +
22011 +#ifdef CONFIG_PAX_KERNEXEC
22012 +               pax_open_kernel(cr0);
22013 +#endif
22014 +
22015                 pmd_populate_kernel(&init_mm, pmd, new);
22016 +
22017 +#ifdef CONFIG_PAX_KERNEXEC
22018 +               pax_close_kernel(cr0);
22019 +#endif
22020 +
22021 +       }
22022         spin_unlock(&init_mm.page_table_lock);
22023         return 0;
22024  }
22025 @@ -1424,6 +1441,93 @@ static inline void cow_user_page(struct 
22026         copy_user_highpage(dst, src, va);
22027  }
22028  
22029 +#ifdef CONFIG_PAX_SEGMEXEC
22030 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
22031 + *
22032 + * the ptl of the lower mapped page is held on entry and is not released on exit
22033 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
22034 + */
22035 +static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
22036 +       unsigned long address, pte_t *pte)
22037 +{
22038 +       unsigned long address_m, pfn_m;
22039 +       struct vm_area_struct * vma_m = NULL;
22040 +       pte_t * pte_m, entry_m;
22041 +       struct page * page_m = NULL;
22042 +
22043 +       address_m = vma->vm_start + vma->vm_mirror;
22044 +       vma_m = find_vma(mm, address_m);
22045 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
22046 +
22047 +       address_m = address + vma->vm_mirror;
22048 +
22049 +       {
22050 +               pgd_t *pgd_m;
22051 +               pud_t *pud_m;
22052 +               pmd_t *pmd_m;
22053 +
22054 +               pgd_m = pgd_offset(mm, address_m);
22055 +               pud_m = pud_offset(pgd_m, address_m);
22056 +               pmd_m = pmd_offset(pud_m, address_m);
22057 +               pte_m = pte_offset_map_nested(pmd_m, address_m);
22058 +       }
22059 +
22060 +       if (pte_present(*pte_m)) {
22061 +               page_m = vm_normal_page(vma_m, address_m, *pte_m);
22062 +               if (page_m) {
22063 +                       flush_cache_page(vma_m, address_m, pfn_m);
22064 +                       flush_icache_page(vma_m, page_m);
22065 +               }
22066 +       }
22067 +
22068 +       if (pte_present(*pte_m))
22069 +               entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
22070 +       else
22071 +               entry_m = ptep_get_and_clear(mm, address_m, pte_m);
22072 +
22073 +       if (pte_none(entry_m)) {
22074 +       } else if (pte_present(entry_m)) {
22075 +               if (page_m) {
22076 +                       page_remove_rmap(page_m);
22077 +                       page_cache_release(page_m);
22078 +                       if (PageAnon(page_m))
22079 +                               dec_mm_counter(mm, anon_rss);
22080 +                       else
22081 +                               dec_mm_counter(mm, file_rss);
22082 +               }
22083 +       } else if (!pte_file(entry_m)) {
22084 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
22085 +       } else {
22086 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
22087 +                               address, vma->vm_start, address_m, vma_m->vm_start);
22088 +       }
22089 +
22090 +       pfn_m = pte_pfn(*pte);
22091 +       page_m = vm_normal_page(vma, address, *pte);
22092 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
22093 +       if (pte_write(*pte))
22094 +               entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
22095 +       if (page_m) {
22096 +               page_cache_get(page_m);
22097 +               /*
22098 +                * we can test PAGE_MAPPING_ANON without holding page_map_lock because
22099 +                * we hold the page table lock and have a reference to page_m
22100 +                */
22101 +               if (PageAnon(page_m)) {
22102 +                       page_add_anon_rmap(page_m, vma_m, address_m);
22103 +                       inc_mm_counter(mm, anon_rss);
22104 +               } else {
22105 +                       page_add_file_rmap(page_m);
22106 +                       inc_mm_counter(mm, file_rss);
22107 +               }
22108 +       }
22109 +       set_pte_at(mm, address_m, pte_m, entry_m);
22110 +       update_mmu_cache(vma_m, address_m, entry_m);
22111 +       lazy_mmu_prot_update(entry_m);
22112 +       pte_unmap_nested(pte_m);
22113 +}
22114 +#endif
22115 +
22116  /*
22117   * This routine handles present pages, when users try to write
22118   * to a shared page. It is done by copying the page to a new address
22119 @@ -1514,6 +1618,12 @@ gotten:
22120                 /* Free the old page.. */
22121                 new_page = old_page;
22122                 ret |= VM_FAULT_WRITE;
22123 +
22124 +#ifdef CONFIG_PAX_SEGMEXEC
22125 +               if (vma->vm_flags & VM_MIRROR)
22126 +                       pax_mirror_fault(mm, vma, address, page_table);
22127 +#endif
22128 +
22129         }
22130         if (new_page)
22131                 page_cache_release(new_page);
22132 @@ -1764,6 +1874,7 @@ int vmtruncate(struct inode * inode, lof
22133  
22134  do_expand:
22135         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
22136 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
22137         if (limit != RLIM_INFINITY && offset > limit)
22138                 goto out_sig;
22139         if (offset > inode->i_sb->s_maxbytes)
22140 @@ -1953,6 +2064,12 @@ again:
22141         /* No need to invalidate - it was non-present before */
22142         update_mmu_cache(vma, address, pte);
22143         lazy_mmu_prot_update(pte);
22144 +
22145 +#ifdef CONFIG_PAX_SEGMEXEC
22146 +       if (vma->vm_flags & VM_MIRROR)
22147 +               pax_mirror_fault(mm, vma, address, page_table);
22148 +#endif
22149 +
22150  unlock:
22151         pte_unmap_unlock(page_table, ptl);
22152  out:
22153 @@ -2015,6 +2132,12 @@ static int do_anonymous_page(struct mm_s
22154         /* No need to invalidate - it was non-present before */
22155         update_mmu_cache(vma, address, entry);
22156         lazy_mmu_prot_update(entry);
22157 +
22158 +#ifdef CONFIG_PAX_SEGMEXEC
22159 +       if (vma->vm_flags & VM_MIRROR)
22160 +               pax_mirror_fault(mm, vma, address, page_table);
22161 +#endif
22162 +
22163  unlock:
22164         pte_unmap_unlock(page_table, ptl);
22165         return VM_FAULT_MINOR;
22166 @@ -2140,6 +2263,12 @@ retry:
22167         /* no need to invalidate: a not-present page shouldn't be cached */
22168         update_mmu_cache(vma, address, entry);
22169         lazy_mmu_prot_update(entry);
22170 +
22171 +#ifdef CONFIG_PAX_SEGMEXEC
22172 +       if (vma->vm_flags & VM_MIRROR)
22173 +               pax_mirror_fault(mm, vma, address, page_table);
22174 +#endif
22175 +
22176  unlock:
22177         pte_unmap_unlock(page_table, ptl);
22178         return ret;
22179 @@ -2271,6 +2400,50 @@ int __handle_mm_fault(struct mm_struct *
22180         if (unlikely(is_vm_hugetlb_page(vma)))
22181                 return hugetlb_fault(mm, vma, address, write_access);
22182  
22183 +#ifdef CONFIG_PAX_SEGMEXEC
22184 +       if (vma->vm_flags & VM_MIRROR) {
22185 +               unsigned long address_m;
22186 +               struct vm_area_struct * vma_m;
22187 +               pgd_t *pgd_m;
22188 +               pud_t *pud_m;
22189 +               pmd_t *pmd_m = NULL;
22190 +               pte_t *pte_m = NULL;
22191 +
22192 +               address_m = vma->vm_start + vma->vm_mirror;
22193 +               vma_m = find_vma(mm, address_m);
22194 +
22195 +               /* PaX: sanity checks */
22196 +               if (!vma_m) {
22197 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
22198 +                              address, vma, address_m, vma_m);
22199 +                       return VM_FAULT_SIGBUS;
22200 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
22201 +                       vma_m->vm_start != address_m ||
22202 +                       vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
22203 +               {
22204 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
22205 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
22206 +                       return VM_FAULT_SIGBUS;
22207 +               }
22208 +
22209 +               if (address_m < address) {
22210 +                       address += vma->vm_mirror;
22211 +                       vma = vma_m;
22212 +               }
22213 +
22214 +               address_m = address + vma->vm_mirror;
22215 +               pgd_m = pgd_offset(mm, address_m);
22216 +               pud_m = pud_alloc(mm, pgd_m, address_m);
22217 +               if (pud_m)
22218 +                       pmd_m = pmd_alloc(mm, pud_m, address_m);
22219 +               if (pmd_m)
22220 +                       pte_m = pte_alloc_map(mm, pmd_m, address_m);
22221 +               if (!pud_m || !pmd_m || !pte_m)
22222 +                       return VM_FAULT_OOM;
22223 +               pte_unmap(pte_m);
22224 +       }
22225 +#endif
22226 +
22227         pgd = pgd_offset(mm, address);
22228         pud = pud_alloc(mm, pgd, address);
22229         if (!pud)
22230 diff -urNp linux-2.6.16.2/mm/mempolicy.c linux-2.6.16.2/mm/mempolicy.c
22231 --- linux-2.6.16.2/mm/mempolicy.c       2006-04-07 12:56:47.000000000 -0400
22232 +++ linux-2.6.16.2/mm/mempolicy.c       2006-04-09 21:23:54.000000000 -0400
22233 @@ -355,6 +355,12 @@ check_range(struct mm_struct *mm, unsign
22234                         if (prev && prev->vm_end < vma->vm_start)
22235                                 return ERR_PTR(-EFAULT);
22236                 }
22237 +
22238 +#ifdef CONFIG_PAX_SEGMEXEC
22239 +               if (vma->vm_flags & VM_MIRROR)
22240 +                       return ERR_PTR(-EFAULT);
22241 +#endif
22242 +
22243                 if (!is_vm_hugetlb_page(vma) &&
22244                     ((flags & MPOL_MF_STRICT) ||
22245                      ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
22246 diff -urNp linux-2.6.16.2/mm/mlock.c linux-2.6.16.2/mm/mlock.c
22247 --- linux-2.6.16.2/mm/mlock.c   2006-04-07 12:56:47.000000000 -0400
22248 +++ linux-2.6.16.2/mm/mlock.c   2006-04-09 21:23:54.000000000 -0400
22249 @@ -10,14 +10,85 @@
22250  #include <linux/mm.h>
22251  #include <linux/mempolicy.h>
22252  #include <linux/syscalls.h>
22253 +#include <linux/grsecurity.h>
22254  
22255 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
22256 +       unsigned long start, unsigned long end, unsigned int newflags);
22257  
22258  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
22259         unsigned long start, unsigned long end, unsigned int newflags)
22260  {
22261         struct mm_struct * mm = vma->vm_mm;
22262 -       pgoff_t pgoff;
22263         int pages;
22264 +       int ret;
22265 +
22266 +#ifdef CONFIG_PAX_SEGMEXEC
22267 +       struct vm_area_struct * vma_m = NULL, *prev_m;
22268 +       unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
22269 +
22270 +       if (vma->vm_flags & VM_MIRROR) {
22271 +               start_m = vma->vm_start + vma->vm_mirror;
22272 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
22273 +               if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
22274 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
22275 +                       return -ENOMEM;
22276 +               }
22277 +
22278 +               start_m = start + vma->vm_mirror;
22279 +               end_m = end + vma->vm_mirror;
22280 +               if (newflags & VM_LOCKED)
22281 +                       newflags_m = vma_m->vm_flags | VM_LOCKED;
22282 +               else
22283 +                       newflags_m = vma_m->vm_flags & ~VM_LOCKED;
22284 +               ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
22285 +               if (ret)
22286 +                       return ret;
22287 +       }
22288 +#endif
22289 +
22290 +       ret = __mlock_fixup(vma, prev, start, end, newflags);
22291 +       if (ret)
22292 +               return ret;
22293 +
22294 +       /*
22295 +        * vm_flags is protected by the mmap_sem held in write mode.
22296 +        * It's okay if try_to_unmap_one unmaps a page just after we
22297 +        * set VM_LOCKED, make_pages_present below will bring it back.
22298 +        */
22299 +       vma->vm_flags = newflags;
22300 +
22301 +#ifdef CONFIG_PAX_SEGMEXEC
22302 +       if (vma->vm_flags & VM_MIRROR)
22303 +               vma_m->vm_flags = newflags_m;
22304 +#endif
22305 +
22306 +       /*
22307 +        * Keep track of amount of locked VM.
22308 +        */
22309 +       pages = (end - start) >> PAGE_SHIFT;
22310 +       if (newflags & VM_LOCKED) {
22311 +               pages = -pages;
22312 +               if (!(newflags & VM_IO))
22313 +                       ret = make_pages_present(start, end);
22314 +       }
22315 +
22316 +       mm->locked_vm -= pages;
22317 +
22318 +#ifdef CONFIG_PAX_SEGMEXEC
22319 +       if (vma->vm_flags & VM_MIRROR)
22320 +               mm->locked_vm -= pages;
22321 +#endif
22322 +
22323 +       if (ret == -ENOMEM)
22324 +               ret = -EAGAIN;
22325 +       return ret;
22326 +}
22327 +
22328 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
22329 +       unsigned long start, unsigned long end, unsigned int newflags)
22330 +{
22331 +       struct mm_struct * mm = vma->vm_mm;
22332 +       pgoff_t pgoff;
22333         int ret = 0;
22334  
22335         if (newflags == vma->vm_flags) {
22336 @@ -30,7 +101,7 @@ static int mlock_fixup(struct vm_area_st
22337                           vma->vm_file, pgoff, vma_policy(vma));
22338         if (*prev) {
22339                 vma = *prev;
22340 -               goto success;
22341 +               goto out;
22342         }
22343  
22344         *prev = vma;
22345 @@ -41,31 +112,9 @@ static int mlock_fixup(struct vm_area_st
22346                         goto out;
22347         }
22348  
22349 -       if (end != vma->vm_end) {
22350 +       if (end != vma->vm_end)
22351                 ret = split_vma(mm, vma, end, 0);
22352 -               if (ret)
22353 -                       goto out;
22354 -       }
22355  
22356 -success:
22357 -       /*
22358 -        * vm_flags is protected by the mmap_sem held in write mode.
22359 -        * It's okay if try_to_unmap_one unmaps a page just after we
22360 -        * set VM_LOCKED, make_pages_present below will bring it back.
22361 -        */
22362 -       vma->vm_flags = newflags;
22363 -
22364 -       /*
22365 -        * Keep track of amount of locked VM.
22366 -        */
22367 -       pages = (end - start) >> PAGE_SHIFT;
22368 -       if (newflags & VM_LOCKED) {
22369 -               pages = -pages;
22370 -               if (!(newflags & VM_IO))
22371 -                       ret = make_pages_present(start, end);
22372 -       }
22373 -
22374 -       vma->vm_mm->locked_vm -= pages;
22375  out:
22376         if (ret == -ENOMEM)
22377                 ret = -EAGAIN;
22378 @@ -84,6 +133,17 @@ static int do_mlock(unsigned long start,
22379                 return -EINVAL;
22380         if (end == start)
22381                 return 0;
22382 +
22383 +#ifdef CONFIG_PAX_SEGMEXEC
22384 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
22385 +               if (end > SEGMEXEC_TASK_SIZE)
22386 +                       return -EINVAL;
22387 +       } else
22388 +#endif
22389 +
22390 +       if (end > TASK_SIZE)
22391 +               return -EINVAL;
22392 +
22393         vma = find_vma_prev(current->mm, start, &prev);
22394         if (!vma || vma->vm_start > start)
22395                 return -ENOMEM;
22396 @@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long 
22397         lock_limit >>= PAGE_SHIFT;
22398  
22399         /* check against resource limits */
22400 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
22401         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
22402                 error = do_mlock(start, len, 1);
22403         up_write(&current->mm->mmap_sem);
22404 @@ -173,6 +234,16 @@ static int do_mlockall(int flags)
22405         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
22406                 unsigned int newflags;
22407  
22408 +#ifdef CONFIG_PAX_SEGMEXEC
22409 +               if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
22410 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
22411 +                               break;
22412 +               } else
22413 +#endif
22414 +
22415 +               if (vma->vm_end > TASK_SIZE)
22416 +                       break;
22417 +
22418                 newflags = vma->vm_flags | VM_LOCKED;
22419                 if (!(flags & MCL_CURRENT))
22420                         newflags &= ~VM_LOCKED;
22421 @@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
22422         lock_limit >>= PAGE_SHIFT;
22423  
22424         ret = -ENOMEM;
22425 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
22426         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
22427             capable(CAP_IPC_LOCK))
22428                 ret = do_mlockall(flags);
22429 diff -urNp linux-2.6.16.2/mm/mmap.c linux-2.6.16.2/mm/mmap.c
22430 --- linux-2.6.16.2/mm/mmap.c    2006-04-07 12:56:47.000000000 -0400
22431 +++ linux-2.6.16.2/mm/mmap.c    2006-04-09 21:23:54.000000000 -0400
22432 @@ -25,6 +25,7 @@
22433  #include <linux/mount.h>
22434  #include <linux/mempolicy.h>
22435  #include <linux/rmap.h>
22436 +#include <linux/grsecurity.h>
22437  
22438  #include <asm/uaccess.h>
22439  #include <asm/cacheflush.h>
22440 @@ -60,6 +61,8 @@ pgprot_t protection_map[16] = {
22441         __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
22442  };
22443  
22444 +EXPORT_SYMBOL(protection_map);
22445 +
22446  int sysctl_overcommit_memory = OVERCOMMIT_GUESS;  /* heuristic overcommit */
22447  int sysctl_overcommit_ratio = 50;      /* default is 50% */
22448  int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
22449 @@ -234,6 +237,7 @@ asmlinkage unsigned long sys_brk(unsigne
22450  
22451         /* Check against rlimit.. */
22452         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
22453 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
22454         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
22455                 goto out;
22456  
22457 @@ -612,11 +616,17 @@ again:                    remove_next = 1 + (end > next->
22458   * If the vma has a ->close operation then the driver probably needs to release
22459   * per-vma resources, so we don't attempt to merge those.
22460   */
22461 +#ifdef CONFIG_PAX_SEGMEXEC
22462 +#define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
22463 +#else
22464  #define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
22465 +#endif
22466  
22467  static inline int is_mergeable_vma(struct vm_area_struct *vma,
22468                         struct file *file, unsigned long vm_flags)
22469  {
22470 +       if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
22471 +               return 0;
22472         if (vma->vm_flags != vm_flags)
22473                 return 0;
22474         if (vma->vm_file != file)
22475 @@ -868,10 +878,55 @@ void vm_stat_account(struct mm_struct *m
22476   * The caller must hold down_write(current->mm->mmap_sem).
22477   */
22478  
22479 +#ifdef CONFIG_PAX_SEGMEXEC
22480 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
22481 +                       unsigned long len, unsigned long prot,
22482 +                       unsigned long flags, unsigned long pgoff);
22483 +
22484  unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
22485                         unsigned long len, unsigned long prot,
22486                         unsigned long flags, unsigned long pgoff)
22487  {
22488 +       unsigned long ret = -EINVAL;
22489 +
22490 +       if (flags & MAP_MIRROR)
22491 +               return ret;
22492 +
22493 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
22494 +           (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
22495 +               return ret;
22496 +
22497 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
22498 +
22499 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
22500 +
22501 +#ifdef CONFIG_PAX_MPROTECT
22502 +           && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
22503 +#endif
22504 +
22505 +          )
22506 +       {
22507 +               unsigned long ret_m;
22508 +               prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
22509 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
22510 +               if (ret_m >= TASK_SIZE) {
22511 +                       do_munmap(current->mm, ret, len);
22512 +                       ret = ret_m;
22513 +               }
22514 +       }
22515 +
22516 +       return ret;
22517 +}
22518 +
22519 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
22520 +                       unsigned long len, unsigned long prot,
22521 +                       unsigned long flags, unsigned long pgoff)
22522 +#else
22523 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
22524 +                       unsigned long len, unsigned long prot,
22525 +                       unsigned long flags, unsigned long pgoff)
22526 +#endif
22527 +{
22528         struct mm_struct * mm = current->mm;
22529         struct vm_area_struct * vma, * prev;
22530         struct inode *inode;
22531 @@ -882,6 +937,28 @@ unsigned long do_mmap_pgoff(struct file 
22532         int accountable = 1;
22533         unsigned long charged = 0, reqprot = prot;
22534  
22535 +#ifdef CONFIG_PAX_SEGMEXEC
22536 +       struct vm_area_struct * vma_m = NULL;
22537 +
22538 +       if (flags & MAP_MIRROR) {
22539 +               /* PaX: sanity checks, to be removed when proved to be stable */
22540 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
22541 +                       return -EINVAL;
22542 +
22543 +               vma_m = find_vma(mm, pgoff);
22544 +
22545 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
22546 +                   vma_m->vm_start != pgoff ||
22547 +                   (vma_m->vm_flags & VM_SPECIAL) ||
22548 +                   (prot & PROT_WRITE))
22549 +                       return -EINVAL;
22550 +
22551 +               file = vma_m->vm_file;
22552 +               pgoff = vma_m->vm_pgoff;
22553 +               len = vma_m->vm_end - vma_m->vm_start;
22554 +       }
22555 +#endif
22556 +
22557         if (file) {
22558                 if (is_file_hugepages(file))
22559                         accountable = 0;
22560 @@ -922,7 +999,7 @@ unsigned long do_mmap_pgoff(struct file 
22561         /* Obtain the address to map to. we verify (or select) it and ensure
22562          * that it represents a valid section of the address space.
22563          */
22564 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
22565 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
22566         if (addr & ~PAGE_MASK)
22567                 return addr;
22568  
22569 @@ -933,6 +1010,24 @@ unsigned long do_mmap_pgoff(struct file 
22570         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
22571                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
22572  
22573 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
22574 +               vm_flags &= ~VM_MAYEXEC;
22575 +
22576 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22577 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22578 +
22579 +#ifdef CONFIG_PAX_MPROTECT
22580 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
22581 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
22582 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
22583 +                       else
22584 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
22585 +               }
22586 +#endif
22587 +
22588 +       }
22589 +#endif
22590 +
22591         if (flags & MAP_LOCKED) {
22592                 if (!can_do_mlock())
22593                         return -EPERM;
22594 @@ -945,6 +1040,7 @@ unsigned long do_mmap_pgoff(struct file 
22595                 locked += mm->locked_vm;
22596                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
22597                 lock_limit >>= PAGE_SHIFT;
22598 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
22599                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
22600                         return -EAGAIN;
22601         }
22602 @@ -992,6 +1088,11 @@ unsigned long do_mmap_pgoff(struct file 
22603                         /*
22604                          * Set pgoff according to addr for anon_vma.
22605                          */
22606 +
22607 +#ifdef CONFIG_PAX_SEGMEXEC
22608 +                       if (!(flags & MAP_MIRROR))
22609 +#endif
22610 +
22611                         pgoff = addr >> PAGE_SHIFT;
22612                         break;
22613                 default:
22614 @@ -1003,14 +1104,17 @@ unsigned long do_mmap_pgoff(struct file 
22615         if (error)
22616                 return error;
22617                 
22618 +       if (!gr_acl_handle_mmap(file, prot))
22619 +               return -EACCES;
22620 +
22621         /* Clear old maps */
22622         error = -ENOMEM;
22623 -munmap_back:
22624         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22625         if (vma && vma->vm_start < addr + len) {
22626                 if (do_munmap(mm, addr, len))
22627                         return -ENOMEM;
22628 -               goto munmap_back;
22629 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22630 +               BUG_ON(vma && vma->vm_start < addr + len);
22631         }
22632  
22633         /* Check against address space limit. */
22634 @@ -1059,6 +1163,13 @@ munmap_back:
22635         vma->vm_start = addr;
22636         vma->vm_end = addr + len;
22637         vma->vm_flags = vm_flags;
22638 +
22639 +#ifdef CONFIG_PAX_PAGEEXEC
22640 +       if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
22641 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
22642 +       else
22643 +#endif
22644 +
22645         vma->vm_page_prot = protection_map[vm_flags & 0x0f];
22646         vma->vm_pgoff = pgoff;
22647  
22648 @@ -1083,6 +1194,14 @@ munmap_back:
22649                         goto free_vma;
22650         }
22651  
22652 +#ifdef CONFIG_PAX_SEGMEXEC
22653 +       if (flags & MAP_MIRROR) {
22654 +               vma_m->vm_flags |= VM_MIRROR;
22655 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
22656 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
22657 +       }
22658 +#endif
22659 +
22660         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
22661          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
22662          * that memory reservation must be checked; but that reservation
22663 @@ -1118,6 +1237,7 @@ munmap_back:
22664  out:   
22665         mm->total_vm += len >> PAGE_SHIFT;
22666         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
22667 +       track_exec_limit(mm, addr, addr + len, vm_flags);
22668         if (vm_flags & VM_LOCKED) {
22669                 mm->locked_vm += len >> PAGE_SHIFT;
22670                 make_pages_present(addr, addr + len);
22671 @@ -1172,6 +1292,10 @@ arch_get_unmapped_area(struct file *filp
22672         if (len > TASK_SIZE)
22673                 return -ENOMEM;
22674  
22675 +#ifdef CONFIG_PAX_RANDMMAP
22676 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
22677 +#endif
22678 +
22679         if (addr) {
22680                 addr = PAGE_ALIGN(addr);
22681                 vma = find_vma(mm, addr);
22682 @@ -1182,7 +1306,7 @@ arch_get_unmapped_area(struct file *filp
22683         if (len > mm->cached_hole_size) {
22684                 start_addr = addr = mm->free_area_cache;
22685         } else {
22686 -               start_addr = addr = TASK_UNMAPPED_BASE;
22687 +               start_addr = addr = mm->mmap_base;
22688                 mm->cached_hole_size = 0;
22689         }
22690  
22691 @@ -1194,9 +1318,8 @@ full_search:
22692                          * Start a new search - just in case we missed
22693                          * some holes.
22694                          */
22695 -                       if (start_addr != TASK_UNMAPPED_BASE) {
22696 -                               addr = TASK_UNMAPPED_BASE;
22697 -                               start_addr = addr;
22698 +                       if (start_addr != mm->mmap_base) {
22699 +                               start_addr = addr = mm->mmap_base;
22700                                 mm->cached_hole_size = 0;
22701                                 goto full_search;
22702                         }
22703 @@ -1221,7 +1344,7 @@ void arch_unmap_area(struct mm_struct *m
22704         /*
22705          * Is this a new hole at the lowest possible address?
22706          */
22707 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
22708 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
22709                 mm->free_area_cache = addr;
22710                 mm->cached_hole_size = ~0UL;
22711         }
22712 @@ -1239,12 +1362,16 @@ arch_get_unmapped_area_topdown(struct fi
22713  {
22714         struct vm_area_struct *vma;
22715         struct mm_struct *mm = current->mm;
22716 -       unsigned long addr = addr0;
22717 +       unsigned long base = mm->mmap_base, addr = addr0;
22718  
22719         /* requested length too big for entire address space */
22720         if (len > TASK_SIZE)
22721                 return -ENOMEM;
22722  
22723 +#ifdef CONFIG_PAX_RANDMMAP
22724 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
22725 +#endif
22726 +
22727         /* requesting a specific address */
22728         if (addr) {
22729                 addr = PAGE_ALIGN(addr);
22730 @@ -1302,13 +1429,21 @@ bottomup:
22731          * can happen with large stack limits and large mmap()
22732          * allocations.
22733          */
22734 +       mm->mmap_base = TASK_UNMAPPED_BASE;
22735 +
22736 +#ifdef CONFIG_PAX_RANDMMAP
22737 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
22738 +               mm->mmap_base += mm->delta_mmap;
22739 +#endif
22740 +
22741 +       mm->free_area_cache = mm->mmap_base;
22742         mm->cached_hole_size = ~0UL;
22743 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
22744         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
22745         /*
22746          * Restore the topdown base:
22747          */
22748 -       mm->free_area_cache = mm->mmap_base;
22749 +       mm->mmap_base = base;
22750 +       mm->free_area_cache = base;
22751         mm->cached_hole_size = ~0UL;
22752  
22753         return addr;
22754 @@ -1324,8 +1459,10 @@ void arch_unmap_area_topdown(struct mm_s
22755                 mm->free_area_cache = addr;
22756  
22757         /* dont allow allocations above current base */
22758 -       if (mm->free_area_cache > mm->mmap_base)
22759 +       if (mm->free_area_cache > mm->mmap_base) {
22760                 mm->free_area_cache = mm->mmap_base;
22761 +               mm->cached_hole_size = ~0UL;
22762 +       }
22763  }
22764  
22765  unsigned long
22766 @@ -1458,6 +1595,7 @@ static int acct_stack_growth(struct vm_a
22767                 return -ENOMEM;
22768  
22769         /* Stack limit test */
22770 +       gr_learn_resource(current, RLIMIT_STACK, size, 1);
22771         if (size > rlim[RLIMIT_STACK].rlim_cur)
22772                 return -ENOMEM;
22773  
22774 @@ -1467,6 +1605,7 @@ static int acct_stack_growth(struct vm_a
22775                 unsigned long limit;
22776                 locked = mm->locked_vm + grow;
22777                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
22778 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
22779                 if (locked > limit && !capable(CAP_IPC_LOCK))
22780                         return -ENOMEM;
22781         }
22782 @@ -1584,13 +1723,49 @@ int expand_stack(struct vm_area_struct *
22783         if (address < vma->vm_start) {
22784                 unsigned long size, grow;
22785  
22786 +#ifdef CONFIG_PAX_SEGMEXEC
22787 +               struct vm_area_struct *vma_m = NULL;
22788 +               unsigned long address_m = 0UL;
22789 +
22790 +               if (vma->vm_flags & VM_MIRROR) {
22791 +                       address_m = vma->vm_start + vma->vm_mirror;
22792 +                       vma_m = find_vma(vma->vm_mm, address_m);
22793 +                       if (!vma_m || vma_m->vm_start != address_m ||
22794 +                           !(vma_m->vm_flags & VM_MIRROR) ||
22795 +                           vma->vm_end - vma->vm_start !=
22796 +                           vma_m->vm_end - vma_m->vm_start ||
22797 +                           vma->anon_vma != vma_m->anon_vma) {
22798 +                               printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
22799 +                                      address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
22800 +                               anon_vma_unlock(vma);
22801 +                               return -EFAULT;
22802 +                       }
22803 +                       address_m = address + vma->vm_mirror;
22804 +               }
22805 +#endif
22806 +
22807                 size = vma->vm_end - address;
22808                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
22809  
22810 +#ifdef CONFIG_PAX_SEGMEXEC
22811 +               if (vma_m)
22812 +                       error = acct_stack_growth(vma, size, 2*grow);
22813 +               else
22814 +#endif
22815 +
22816                 error = acct_stack_growth(vma, size, grow);
22817                 if (!error) {
22818                         vma->vm_start = address;
22819                         vma->vm_pgoff -= grow;
22820 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
22821 +
22822 +#ifdef CONFIG_PAX_SEGMEXEC
22823 +                       if (vma_m) {
22824 +                               vma_m->vm_start = address_m;
22825 +                               vma_m->vm_pgoff -= grow;
22826 +                       }
22827 +#endif
22828 +
22829                 }
22830         }
22831         anon_vma_unlock(vma);
22832 @@ -1752,7 +1927,24 @@ int split_vma(struct mm_struct * mm, str
22833   * work.  This now handles partial unmappings.
22834   * Jeremy Fitzhardinge <jeremy@goop.org>
22835   */
22836 +#ifdef CONFIG_PAX_SEGMEXEC
22837 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
22838 +
22839 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22840 +{
22841 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
22842 +               int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
22843 +               if (ret)
22844 +                       return ret;
22845 +       }
22846 +
22847 +       return __do_munmap(mm, start, len);
22848 +}
22849 +
22850 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22851 +#else
22852  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22853 +#endif
22854  {
22855         unsigned long end;
22856         struct vm_area_struct *vma, *prev, *last;
22857 @@ -1806,6 +1998,8 @@ int do_munmap(struct mm_struct *mm, unsi
22858         /* Fix up all other VM information */
22859         remove_vma_list(mm, vma);
22860  
22861 +       track_exec_limit(mm, start, end, 0UL);
22862 +
22863         return 0;
22864  }
22865  
22866 @@ -1818,6 +2012,12 @@ asmlinkage long sys_munmap(unsigned long
22867  
22868         profile_munmap(addr);
22869  
22870 +#ifdef CONFIG_PAX_SEGMEXEC
22871 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
22872 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
22873 +               return -EINVAL;
22874 +#endif
22875 +
22876         down_write(&mm->mmap_sem);
22877         ret = do_munmap(mm, addr, len);
22878         up_write(&mm->mmap_sem);
22879 @@ -1839,11 +2039,35 @@ static inline void verify_mm_writelocked
22880   *  anonymous maps.  eventually we may be able to do some
22881   *  brk-specific accounting here.
22882   */
22883 +#ifdef CONFIG_PAX_SEGMEXEC
22884 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
22885 +
22886 +unsigned long do_brk(unsigned long addr, unsigned long len)
22887 +{
22888 +       unsigned long ret;
22889 +
22890 +       ret = __do_brk(addr, len);
22891 +       if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
22892 +               unsigned long ret_m;
22893 +
22894 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
22895 +               if (ret_m > TASK_SIZE) {
22896 +                       do_munmap(current->mm, addr, len);
22897 +                       ret = ret_m;
22898 +               }
22899 +       }
22900 +
22901 +       return ret;
22902 +}
22903 +
22904 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
22905 +#else
22906  unsigned long do_brk(unsigned long addr, unsigned long len)
22907 +#endif
22908  {
22909         struct mm_struct * mm = current->mm;
22910         struct vm_area_struct * vma, * prev;
22911 -       unsigned long flags;
22912 +       unsigned long flags, task_size = TASK_SIZE;
22913         struct rb_node ** rb_link, * rb_parent;
22914         pgoff_t pgoff = addr >> PAGE_SHIFT;
22915  
22916 @@ -1851,7 +2075,12 @@ unsigned long do_brk(unsigned long addr,
22917         if (!len)
22918                 return addr;
22919  
22920 -       if ((addr + len) > TASK_SIZE || (addr + len) < addr)
22921 +#ifdef CONFIG_PAX_SEGMEXEC
22922 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
22923 +               task_size = SEGMEXEC_TASK_SIZE;
22924 +#endif
22925 +
22926 +       if ((addr + len) > task_size || (addr + len) < addr)
22927                 return -EINVAL;
22928  
22929         /*
22930 @@ -1863,6 +2092,7 @@ unsigned long do_brk(unsigned long addr,
22931                 locked += mm->locked_vm;
22932                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
22933                 lock_limit >>= PAGE_SHIFT;
22934 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
22935                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
22936                         return -EAGAIN;
22937         }
22938 @@ -1876,12 +2106,12 @@ unsigned long do_brk(unsigned long addr,
22939         /*
22940          * Clear old maps.  this also does some error checking for us
22941          */
22942 - munmap_back:
22943         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22944         if (vma && vma->vm_start < addr + len) {
22945                 if (do_munmap(mm, addr, len))
22946                         return -ENOMEM;
22947 -               goto munmap_back;
22948 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22949 +               BUG_ON(vma && vma->vm_start < addr + len);
22950         }
22951  
22952         /* Check against address space limits *after* clearing old maps... */
22953 @@ -1896,6 +2126,18 @@ unsigned long do_brk(unsigned long addr,
22954  
22955         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
22956  
22957 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22958 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22959 +               flags &= ~VM_EXEC;
22960 +
22961 +#ifdef CONFIG_PAX_MPROTECT
22962 +               if (mm->pax_flags & MF_PAX_MPROTECT)
22963 +                       flags &= ~VM_MAYEXEC;
22964 +#endif
22965 +
22966 +       }
22967 +#endif
22968 +
22969         /* Can we just expand an old private anonymous mapping? */
22970         if (vma_merge(mm, prev, addr, addr + len, flags,
22971                                         NULL, NULL, pgoff, NULL))
22972 @@ -1916,6 +2158,13 @@ unsigned long do_brk(unsigned long addr,
22973         vma->vm_end = addr + len;
22974         vma->vm_pgoff = pgoff;
22975         vma->vm_flags = flags;
22976 +
22977 +#ifdef CONFIG_PAX_PAGEEXEC
22978 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
22979 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
22980 +       else
22981 +#endif
22982 +
22983         vma->vm_page_prot = protection_map[flags & 0x0f];
22984         vma_link(mm, vma, prev, rb_link, rb_parent);
22985  out:
22986 @@ -1924,6 +2173,7 @@ out:
22987                 mm->locked_vm += len >> PAGE_SHIFT;
22988                 make_pages_present(addr, addr + len);
22989         }
22990 +       track_exec_limit(mm, addr, addr + len, flags);
22991         return addr;
22992  }
22993  
22994 @@ -2056,7 +2306,7 @@ int may_expand_vm(struct mm_struct *mm, 
22995         unsigned long lim;
22996  
22997         lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
22998 -
22999 +       gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
23000         if (cur + npages > lim)
23001                 return 0;
23002         return 1;
23003 diff -urNp linux-2.6.16.2/mm/mprotect.c linux-2.6.16.2/mm/mprotect.c
23004 --- linux-2.6.16.2/mm/mprotect.c        2006-04-07 12:56:47.000000000 -0400
23005 +++ linux-2.6.16.2/mm/mprotect.c        2006-04-09 21:24:03.000000000 -0400
23006 @@ -19,11 +19,18 @@
23007  #include <linux/mempolicy.h>
23008  #include <linux/personality.h>
23009  #include <linux/syscalls.h>
23010 +#include <linux/grsecurity.h>
23011 +
23012 +#ifdef CONFIG_PAX_MPROTECT
23013 +#include <linux/elf.h>
23014 +#include <linux/fs.h>
23015 +#endif
23016  
23017  #include <asm/uaccess.h>
23018  #include <asm/pgtable.h>
23019  #include <asm/cacheflush.h>
23020  #include <asm/tlbflush.h>
23021 +#include <asm/mmu_context.h>
23022  
23023  static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
23024                 unsigned long addr, unsigned long end, pgprot_t newprot)
23025 @@ -98,6 +105,94 @@ static void change_protection(struct vm_
23026         flush_tlb_range(vma, start, end);
23027  }
23028  
23029 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
23030 +/* called while holding the mmap semaphor for writing */
23031 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
23032 +{
23033 +       struct vm_area_struct *vma = find_vma(mm, start);
23034 +
23035 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
23036 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
23037 +
23038 +}
23039 +
23040 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
23041 +{
23042 +       unsigned long oldlimit, newlimit = 0UL;
23043 +
23044 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
23045 +               return;
23046 +
23047 +       spin_lock(&mm->page_table_lock);
23048 +       oldlimit = mm->context.user_cs_limit;
23049 +       if ((prot & VM_EXEC) && oldlimit < end)
23050 +               /* USER_CS limit moved up */
23051 +               newlimit = end;
23052 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
23053 +               /* USER_CS limit moved down */
23054 +               newlimit = start;
23055 +
23056 +       if (newlimit) {
23057 +               mm->context.user_cs_limit = newlimit;
23058 +
23059 +#ifdef CONFIG_SMP
23060 +               wmb();
23061 +               cpus_clear(mm->context.cpu_user_cs_mask);
23062 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
23063 +#endif
23064 +
23065 +               set_user_cs(mm, smp_processor_id());
23066 +       }
23067 +       spin_unlock(&mm->page_table_lock);
23068 +       if (newlimit == end)
23069 +               establish_user_cs_limit(mm, oldlimit, end);
23070 +}
23071 +#endif
23072 +
23073 +#ifdef CONFIG_PAX_SEGMEXEC
23074 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
23075 +       unsigned long start, unsigned long end, unsigned int newflags);
23076 +
23077 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
23078 +       unsigned long start, unsigned long end, unsigned int newflags)
23079 +{
23080 +       if (vma->vm_flags & VM_MIRROR) {
23081 +               struct vm_area_struct * vma_m, * prev_m;
23082 +               unsigned long start_m, end_m;
23083 +               int error;
23084 +
23085 +               start_m = vma->vm_start + vma->vm_mirror;
23086 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
23087 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
23088 +                       start_m = start + vma->vm_mirror;
23089 +                       end_m = end + vma->vm_mirror;
23090 +
23091 +                       if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
23092 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
23093 +                       else
23094 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
23095 +                       if (error)
23096 +                               return error;
23097 +               } else {
23098 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
23099 +                       return -ENOMEM;
23100 +               }
23101 +       }
23102 +
23103 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
23104 +}
23105 +
23106 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
23107 +       unsigned long start, unsigned long end, unsigned int newflags)
23108 +{
23109 +       struct mm_struct * mm = vma->vm_mm;
23110 +       unsigned long oldflags = vma->vm_flags;
23111 +       long nrpages = (end - start) >> PAGE_SHIFT;
23112 +       unsigned long charged = 0;
23113 +       pgprot_t newprot;
23114 +       pgoff_t pgoff;
23115 +       int error;
23116 +#else
23117  static int
23118  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
23119         unsigned long start, unsigned long end, unsigned long newflags)
23120 @@ -114,6 +209,7 @@ mprotect_fixup(struct vm_area_struct *vm
23121                 *pprev = vma;
23122                 return 0;
23123         }
23124 +#endif
23125  
23126         /*
23127          * If we make a private mapping writable we increase our commit;
23128 @@ -132,6 +228,12 @@ mprotect_fixup(struct vm_area_struct *vm
23129                 }
23130         }
23131  
23132 +#ifdef CONFIG_PAX_PAGEEXEC
23133 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
23134 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
23135 +       else
23136 +#endif
23137 +
23138         newprot = protection_map[newflags & 0xf];
23139  
23140         /*
23141 @@ -176,6 +278,69 @@ fail:
23142         return error;
23143  }
23144  
23145 +#ifdef CONFIG_PAX_MPROTECT
23146 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
23147 + * therefore we'll grant them VM_MAYWRITE once during their life.
23148 + *
23149 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
23150 + * basis because we want to allow the common case and not the special ones.
23151 + */
23152 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
23153 +{
23154 +       struct elfhdr elf_h;
23155 +       struct elf_phdr elf_p, p_dyn;
23156 +       elf_dyn dyn;
23157 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
23158 +
23159 +#ifndef CONFIG_PAX_NOELFRELOCS
23160 +       if ((vma->vm_start != start) ||
23161 +           !vma->vm_file ||
23162 +           !(vma->vm_flags & VM_MAYEXEC) ||
23163 +           (vma->vm_flags & VM_MAYNOTWRITE))
23164 +#endif
23165 +
23166 +               return;
23167 +
23168 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
23169 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
23170 +
23171 +#ifdef CONFIG_PAX_ETEXECRELOCS
23172 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
23173 +#else
23174 +           elf_h.e_type != ET_DYN ||
23175 +#endif
23176 +
23177 +           !elf_check_arch(&elf_h) ||
23178 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
23179 +           elf_h.e_phnum > j)
23180 +               return;
23181 +
23182 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
23183 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
23184 +                       return;
23185 +               if (elf_p.p_type == PT_DYNAMIC) {
23186 +                       p_dyn = elf_p;
23187 +                       j = i;
23188 +               }
23189 +       }
23190 +       if (elf_h.e_phnum <= j)
23191 +               return;
23192 +
23193 +       i = 0UL;
23194 +       do {
23195 +               if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
23196 +                       return;
23197 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
23198 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
23199 +                       gr_log_textrel(vma);
23200 +                       return;
23201 +               }
23202 +               i++;
23203 +       } while (dyn.d_tag != DT_NULL);
23204 +       return;
23205 +}
23206 +#endif
23207 +
23208  asmlinkage long
23209  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
23210  {
23211 @@ -195,6 +360,17 @@ sys_mprotect(unsigned long start, size_t
23212         end = start + len;
23213         if (end <= start)
23214                 return -ENOMEM;
23215 +
23216 +#ifdef CONFIG_PAX_SEGMEXEC
23217 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
23218 +               if (end > SEGMEXEC_TASK_SIZE)
23219 +                       return -EINVAL;
23220 +       } else
23221 +#endif
23222 +
23223 +       if (end > TASK_SIZE)
23224 +               return -EINVAL;
23225 +
23226         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
23227                 return -EINVAL;
23228  
23229 @@ -235,6 +411,16 @@ sys_mprotect(unsigned long start, size_t
23230         if (start > vma->vm_start)
23231                 prev = vma;
23232  
23233 +#ifdef CONFIG_PAX_MPROTECT
23234 +       if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
23235 +               pax_handle_maywrite(vma, start);
23236 +#endif
23237 +
23238 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
23239 +               error = -EACCES;
23240 +               goto out;
23241 +       }
23242 +
23243         for (nstart = start ; ; ) {
23244                 unsigned long newflags;
23245  
23246 @@ -253,6 +439,12 @@ sys_mprotect(unsigned long start, size_t
23247                         goto out;
23248                 }
23249  
23250 +#ifdef CONFIG_PAX_MPROTECT
23251 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
23252 +               if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
23253 +                       newflags &= ~VM_MAYWRITE;
23254 +#endif
23255 +
23256                 error = security_file_mprotect(vma, reqprot, prot);
23257                 if (error)
23258                         goto out;
23259 @@ -276,6 +468,9 @@ sys_mprotect(unsigned long start, size_t
23260                         goto out;
23261                 }
23262         }
23263 +
23264 +       track_exec_limit(current->mm, start, end, vm_flags);
23265 +
23266  out:
23267         up_write(&current->mm->mmap_sem);
23268         return error;
23269 diff -urNp linux-2.6.16.2/mm/mremap.c linux-2.6.16.2/mm/mremap.c
23270 --- linux-2.6.16.2/mm/mremap.c  2006-04-07 12:56:47.000000000 -0400
23271 +++ linux-2.6.16.2/mm/mremap.c  2006-04-09 21:23:54.000000000 -0400
23272 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
23273                 pte = ptep_clear_flush(vma, old_addr, old_pte);
23274                 /* ZERO_PAGE can be dependant on virtual addr */
23275                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
23276 +
23277 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
23278 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
23279 +                       pte_exprotect(pte);
23280 +#endif
23281 +
23282                 set_pte_at(mm, new_addr, new_pte, pte);
23283         }
23284  
23285 @@ -253,6 +259,7 @@ unsigned long do_mremap(unsigned long ad
23286         struct vm_area_struct *vma;
23287         unsigned long ret = -EINVAL;
23288         unsigned long charged = 0;
23289 +       unsigned long task_size = TASK_SIZE;
23290  
23291         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
23292                 goto out;
23293 @@ -271,6 +278,15 @@ unsigned long do_mremap(unsigned long ad
23294         if (!new_len)
23295                 goto out;
23296  
23297 +#ifdef CONFIG_PAX_SEGMEXEC
23298 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
23299 +               task_size = SEGMEXEC_TASK_SIZE;
23300 +#endif
23301 +
23302 +       if (new_len > task_size || addr > task_size-new_len ||
23303 +           old_len > task_size || addr > task_size-old_len)
23304 +               goto out;
23305 +
23306         /* new_addr is only valid if MREMAP_FIXED is specified */
23307         if (flags & MREMAP_FIXED) {
23308                 if (new_addr & ~PAGE_MASK)
23309 @@ -278,16 +294,13 @@ unsigned long do_mremap(unsigned long ad
23310                 if (!(flags & MREMAP_MAYMOVE))
23311                         goto out;
23312  
23313 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
23314 +               if (new_addr > task_size - new_len)
23315                         goto out;
23316  
23317                 /* Check if the location we're moving into overlaps the
23318                  * old location at all, and fail if it does.
23319                  */
23320 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
23321 -                       goto out;
23322 -
23323 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
23324 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
23325                         goto out;
23326  
23327                 ret = do_munmap(mm, new_addr, new_len);
23328 @@ -321,6 +334,14 @@ unsigned long do_mremap(unsigned long ad
23329                 ret = -EINVAL;
23330                 goto out;
23331         }
23332 +
23333 +#ifdef CONFIG_PAX_SEGMEXEC
23334 +       if (vma->vm_flags & VM_MIRROR) {
23335 +               ret = -EINVAL;
23336 +               goto out;
23337 +       }
23338 +#endif
23339 +
23340         /* We can't remap across vm area boundaries */
23341         if (old_len > vma->vm_end - addr)
23342                 goto out;
23343 @@ -354,7 +375,7 @@ unsigned long do_mremap(unsigned long ad
23344         if (old_len == vma->vm_end - addr &&
23345             !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
23346             (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
23347 -               unsigned long max_addr = TASK_SIZE;
23348 +               unsigned long max_addr = task_size;
23349                 if (vma->vm_next)
23350                         max_addr = vma->vm_next->vm_start;
23351                 /* can we just expand the current mapping? */
23352 @@ -372,6 +393,7 @@ unsigned long do_mremap(unsigned long ad
23353                                                    addr + new_len);
23354                         }
23355                         ret = addr;
23356 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
23357                         goto out;
23358                 }
23359         }
23360 @@ -382,8 +404,8 @@ unsigned long do_mremap(unsigned long ad
23361          */
23362         ret = -ENOMEM;
23363         if (flags & MREMAP_MAYMOVE) {
23364 +               unsigned long map_flags = 0;
23365                 if (!(flags & MREMAP_FIXED)) {
23366 -                       unsigned long map_flags = 0;
23367                         if (vma->vm_flags & VM_MAYSHARE)
23368                                 map_flags |= MAP_SHARED;
23369  
23370 @@ -393,7 +415,12 @@ unsigned long do_mremap(unsigned long ad
23371                         if (new_addr & ~PAGE_MASK)
23372                                 goto out;
23373                 }
23374 +               map_flags = vma->vm_flags;
23375                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
23376 +               if (!(ret & ~PAGE_MASK)) {
23377 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
23378 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
23379 +               }
23380         }
23381  out:
23382         if (ret & ~PAGE_MASK)
23383 diff -urNp linux-2.6.16.2/mm/rmap.c linux-2.6.16.2/mm/rmap.c
23384 --- linux-2.6.16.2/mm/rmap.c    2006-04-07 12:56:47.000000000 -0400
23385 +++ linux-2.6.16.2/mm/rmap.c    2006-04-09 21:23:54.000000000 -0400
23386 @@ -108,6 +108,19 @@ int anon_vma_prepare(struct vm_area_stru
23387                         list_add(&vma->anon_vma_node, &anon_vma->head);
23388                         allocated = NULL;
23389                 }
23390 +
23391 +#ifdef CONFIG_PAX_SEGMEXEC
23392 +               if (vma->vm_flags & VM_MIRROR) {
23393 +                       struct vm_area_struct *vma_m;
23394 +
23395 +                       vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
23396 +                       BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
23397 +                       BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
23398 +                       vma_m->anon_vma = anon_vma;
23399 +                       __anon_vma_link(vma_m);
23400 +               }
23401 +#endif
23402 +
23403                 spin_unlock(&mm->page_table_lock);
23404  
23405                 if (locked)
23406 diff -urNp linux-2.6.16.2/mm/vmalloc.c linux-2.6.16.2/mm/vmalloc.c
23407 --- linux-2.6.16.2/mm/vmalloc.c 2006-04-07 12:56:47.000000000 -0400
23408 +++ linux-2.6.16.2/mm/vmalloc.c 2006-04-09 21:23:54.000000000 -0400
23409 @@ -193,6 +193,8 @@ struct vm_struct *__get_vm_area_node(uns
23410  
23411         write_lock(&vmlist_lock);
23412         for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
23413 +               if (addr > end - size)
23414 +                       goto out;
23415                 if ((unsigned long)tmp->addr < addr) {
23416                         if((unsigned long)tmp->addr + tmp->size >= addr)
23417                                 addr = ALIGN(tmp->size + 
23418 @@ -204,8 +206,6 @@ struct vm_struct *__get_vm_area_node(uns
23419                 if (size + addr <= (unsigned long)tmp->addr)
23420                         goto found;
23421                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
23422 -               if (addr > end - size)
23423 -                       goto out;
23424         }
23425  
23426  found:
23427 diff -urNp linux-2.6.16.2/net/ipv4/inet_connection_sock.c linux-2.6.16.2/net/ipv4/inet_connection_sock.c
23428 --- linux-2.6.16.2/net/ipv4/inet_connection_sock.c      2006-04-07 12:56:47.000000000 -0400
23429 +++ linux-2.6.16.2/net/ipv4/inet_connection_sock.c      2006-04-09 21:23:54.000000000 -0400
23430 @@ -16,6 +16,7 @@
23431  #include <linux/config.h>
23432  #include <linux/module.h>
23433  #include <linux/jhash.h>
23434 +#include <linux/grsecurity.h>
23435  
23436  #include <net/inet_connection_sock.h>
23437  #include <net/inet_hashtables.h>
23438 diff -urNp linux-2.6.16.2/net/ipv4/inet_hashtables.c linux-2.6.16.2/net/ipv4/inet_hashtables.c
23439 --- linux-2.6.16.2/net/ipv4/inet_hashtables.c   2006-04-07 12:56:47.000000000 -0400
23440 +++ linux-2.6.16.2/net/ipv4/inet_hashtables.c   2006-04-09 21:23:54.000000000 -0400
23441 @@ -19,11 +19,14 @@
23442  #include <linux/sched.h>
23443  #include <linux/slab.h>
23444  #include <linux/wait.h>
23445 +#include <linux/grsecurity.h>
23446  
23447  #include <net/inet_connection_sock.h>
23448  #include <net/inet_hashtables.h>
23449  #include <net/ip.h>
23450  
23451 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
23452 +
23453  /*
23454   * Allocate and initialize a new local port bind bucket.
23455   * The bindhash mutex for snum's hash chain must be held here.
23456 @@ -314,6 +317,8 @@ ok:
23457                 }
23458                 spin_unlock(&head->lock);
23459  
23460 +               gr_update_task_in_ip_table(current, inet_sk(sk));
23461 +
23462                 if (tw) {
23463                         inet_twsk_deschedule(tw, death_row);;
23464                         inet_twsk_put(tw);
23465 diff -urNp linux-2.6.16.2/net/ipv4/netfilter/ipt_stealth.c linux-2.6.16.2/net/ipv4/netfilter/ipt_stealth.c
23466 --- linux-2.6.16.2/net/ipv4/netfilter/ipt_stealth.c     1969-12-31 19:00:00.000000000 -0500
23467 +++ linux-2.6.16.2/net/ipv4/netfilter/ipt_stealth.c     2006-04-09 21:23:54.000000000 -0400
23468 @@ -0,0 +1,112 @@
23469 +/* Kernel module to add stealth support.
23470 + *
23471 + * Copyright (C) 2002,2005 Brad Spengler  <spender@grsecurity.net>
23472 + *
23473 + */
23474 +
23475 +#include <linux/kernel.h>
23476 +#include <linux/module.h>
23477 +#include <linux/skbuff.h>
23478 +#include <linux/net.h>
23479 +#include <linux/sched.h>
23480 +#include <linux/inet.h>
23481 +#include <linux/stddef.h>
23482 +
23483 +#include <net/ip.h>
23484 +#include <net/sock.h>
23485 +#include <net/tcp.h>
23486 +#include <net/udp.h>
23487 +#include <net/route.h>
23488 +#include <net/inet_common.h>
23489 +
23490 +#include <linux/netfilter_ipv4/ip_tables.h>
23491 +
23492 +MODULE_LICENSE("GPL");
23493 +
23494 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
23495 +
23496 +static int
23497 +match(const struct sk_buff *skb,
23498 +      const struct net_device *in,
23499 +      const struct net_device *out,
23500 +      const void *matchinfo,
23501 +      int offset,
23502 +      int *hotdrop)
23503 +{
23504 +       struct iphdr *ip = skb->nh.iph;
23505 +       struct tcphdr th;
23506 +       struct udphdr uh;
23507 +       struct sock *sk = NULL;
23508 +
23509 +       if (!ip || offset) return 0;
23510 +
23511 +       switch(ip->protocol) {
23512 +       case IPPROTO_TCP:
23513 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
23514 +                       *hotdrop = 1;
23515 +                       return 0;
23516 +               }
23517 +               if (!(th.syn && !th.ack)) return 0;
23518 +               sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);        
23519 +               break;
23520 +       case IPPROTO_UDP:
23521 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
23522 +                       *hotdrop = 1;
23523 +                       return 0;
23524 +               }
23525 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
23526 +               break;
23527 +       default:
23528 +               return 0;
23529 +       }
23530 +
23531 +       if(!sk) // port is being listened on, match this
23532 +               return 1;
23533 +       else {
23534 +               sock_put(sk);
23535 +               return 0;
23536 +       }
23537 +}
23538 +
23539 +/* Called when user tries to insert an entry of this type. */
23540 +static int
23541 +checkentry(const char *tablename,
23542 +           const struct ipt_ip *ip,
23543 +           void *matchinfo,
23544 +           unsigned int matchsize,
23545 +           unsigned int hook_mask)
23546 +{
23547 +        if (matchsize != IPT_ALIGN(0))
23548 +                return 0;
23549 +
23550 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
23551 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
23552 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
23553 +                       return 1;
23554 +
23555 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
23556 +
23557 +        return 0;
23558 +}
23559 +
23560 +
23561 +static struct ipt_match stealth_match = {
23562 +       .name = "stealth",
23563 +       .match = &match,
23564 +       .checkentry = &checkentry,
23565 +       .destroy = NULL,
23566 +       .me = THIS_MODULE
23567 +};
23568 +
23569 +static int __init init(void)
23570 +{
23571 +       return ipt_register_match(&stealth_match);
23572 +}
23573 +
23574 +static void __exit fini(void)
23575 +{
23576 +       ipt_unregister_match(&stealth_match);
23577 +}
23578 +
23579 +module_init(init);
23580 +module_exit(fini);
23581 diff -urNp linux-2.6.16.2/net/ipv4/netfilter/Kconfig linux-2.6.16.2/net/ipv4/netfilter/Kconfig
23582 --- linux-2.6.16.2/net/ipv4/netfilter/Kconfig   2006-04-07 12:56:47.000000000 -0400
23583 +++ linux-2.6.16.2/net/ipv4/netfilter/Kconfig   2006-04-09 21:23:54.000000000 -0400
23584 @@ -313,6 +313,21 @@ config IP_NF_MATCH_POLICY
23585  
23586           To compile it as a module, choose M here.  If unsure, say N.
23587  
23588 +config IP_NF_MATCH_STEALTH
23589 +       tristate "stealth match support"
23590 +       depends on IP_NF_IPTABLES
23591 +       help
23592 +         Enabling this option will drop all syn packets coming to unserved tcp
23593 +         ports as well as all packets coming to unserved udp ports.  If you
23594 +         are using your system to route any type of packets (ie. via NAT)
23595 +         you should put this module at the end of your ruleset, since it will
23596 +         drop packets that aren't going to ports that are listening on your
23597 +         machine itself, it doesn't take into account that the packet might be
23598 +         destined for someone on your internal network if you're using NAT for
23599 +         instance.
23600 +
23601 +         To compile it as a module, choose M here.  If unsure, say N.
23602 +
23603  # `filter', generic and specific targets
23604  config IP_NF_FILTER
23605         tristate "Packet filtering"
23606 @@ -607,4 +622,3 @@ config IP_NF_ARP_MANGLE
23607           hardware and network addresses.
23608  
23609  endmenu
23610 -
23611 diff -urNp linux-2.6.16.2/net/ipv4/netfilter/Makefile linux-2.6.16.2/net/ipv4/netfilter/Makefile
23612 --- linux-2.6.16.2/net/ipv4/netfilter/Makefile  2006-04-07 12:56:47.000000000 -0400
23613 +++ linux-2.6.16.2/net/ipv4/netfilter/Makefile  2006-04-09 21:23:54.000000000 -0400
23614 @@ -58,6 +58,7 @@ obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_
23615  obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
23616  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
23617  obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
23618 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
23619  
23620  # targets
23621  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
23622 diff -urNp linux-2.6.16.2/net/ipv4/tcp_ipv4.c linux-2.6.16.2/net/ipv4/tcp_ipv4.c
23623 --- linux-2.6.16.2/net/ipv4/tcp_ipv4.c  2006-04-07 12:56:47.000000000 -0400
23624 +++ linux-2.6.16.2/net/ipv4/tcp_ipv4.c  2006-04-09 21:23:54.000000000 -0400
23625 @@ -62,6 +62,7 @@
23626  #include <linux/jhash.h>
23627  #include <linux/init.h>
23628  #include <linux/times.h>
23629 +#include <linux/grsecurity.h>
23630  
23631  #include <net/icmp.h>
23632  #include <net/inet_hashtables.h>
23633 diff -urNp linux-2.6.16.2/net/ipv4/udp.c linux-2.6.16.2/net/ipv4/udp.c
23634 --- linux-2.6.16.2/net/ipv4/udp.c       2006-04-07 12:56:47.000000000 -0400
23635 +++ linux-2.6.16.2/net/ipv4/udp.c       2006-04-09 21:23:54.000000000 -0400
23636 @@ -102,6 +102,7 @@
23637  #include <linux/skbuff.h>
23638  #include <linux/proc_fs.h>
23639  #include <linux/seq_file.h>
23640 +#include <linux/grsecurity.h>
23641  #include <net/sock.h>
23642  #include <net/udp.h>
23643  #include <net/icmp.h>
23644 @@ -110,6 +111,12 @@
23645  #include <net/checksum.h>
23646  #include <net/xfrm.h>
23647  
23648 +extern int gr_search_udp_recvmsg(const struct sock *sk,
23649 +                                const struct sk_buff *skb);
23650 +extern int gr_search_udp_sendmsg(const struct sock *sk,
23651 +                                const struct sockaddr_in *addr);
23652 +
23653 +
23654  /*
23655   *     Snmp MIB for the UDP layer
23656   */
23657 @@ -266,8 +273,7 @@ static struct sock *udp_v4_lookup_longwa
23658         return result;
23659  }
23660  
23661 -static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
23662 -                                            u32 daddr, u16 dport, int dif)
23663 +struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
23664  {
23665         struct sock *sk;
23666  
23667 @@ -542,9 +548,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
23668                 dport = usin->sin_port;
23669                 if (dport == 0)
23670                         return -EINVAL;
23671 +
23672 +               if (!gr_search_udp_sendmsg(sk, usin))
23673 +                       return -EPERM;
23674         } else {
23675                 if (sk->sk_state != TCP_ESTABLISHED)
23676                         return -EDESTADDRREQ;
23677 +
23678 +               if (!gr_search_udp_sendmsg(sk, NULL))
23679 +                       return -EPERM;
23680 +
23681                 daddr = inet->daddr;
23682                 dport = inet->dport;
23683                 /* Open fast path for connected socket.
23684 @@ -798,6 +811,11 @@ try_again:
23685         if (!skb)
23686                 goto out;
23687    
23688 +       if (!gr_search_udp_recvmsg(sk, skb)) {
23689 +               err = -EPERM;
23690 +               goto out_free;
23691 +       }
23692 +
23693         copied = skb->len - sizeof(struct udphdr);
23694         if (copied > len) {
23695                 copied = len;
23696 diff -urNp linux-2.6.16.2/net/socket.c linux-2.6.16.2/net/socket.c
23697 --- linux-2.6.16.2/net/socket.c 2006-04-07 12:56:47.000000000 -0400
23698 +++ linux-2.6.16.2/net/socket.c 2006-04-09 21:23:54.000000000 -0400
23699 @@ -84,6 +84,7 @@
23700  #include <linux/compat.h>
23701  #include <linux/kmod.h>
23702  #include <linux/audit.h>
23703 +#include <linux/in.h>
23704  
23705  #ifdef CONFIG_NET_RADIO
23706  #include <linux/wireless.h>            /* Note : will define WIRELESS_EXT */
23707 @@ -97,6 +98,21 @@
23708  #include <net/sock.h>
23709  #include <linux/netfilter.h>
23710  
23711 +extern void gr_attach_curr_ip(const struct sock *sk);
23712 +extern int gr_handle_sock_all(const int family, const int type,
23713 +                             const int protocol);
23714 +extern int gr_handle_sock_server(const struct sockaddr *sck);
23715 +extern int gr_handle_sock_server_other(const struct socket *sck);
23716 +extern int gr_handle_sock_client(const struct sockaddr *sck);
23717 +extern int gr_search_connect(const struct socket * sock,
23718 +                            const struct sockaddr_in * addr);
23719 +extern int gr_search_bind(const struct socket * sock,
23720 +                          const struct sockaddr_in * addr);
23721 +extern int gr_search_listen(const struct socket * sock);
23722 +extern int gr_search_accept(const struct socket * sock);
23723 +extern int gr_search_socket(const int domain, const int type,
23724 +                           const int protocol);
23725 +
23726  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
23727  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
23728                          size_t size, loff_t pos);
23729 @@ -1194,6 +1210,16 @@ asmlinkage long sys_socket(int family, i
23730         int retval;
23731         struct socket *sock;
23732  
23733 +       if(!gr_search_socket(family, type, protocol)) {
23734 +               retval = -EACCES;
23735 +               goto out;
23736 +       }
23737 +
23738 +       if (gr_handle_sock_all(family, type, protocol)) {
23739 +               retval = -EACCES;
23740 +               goto out;
23741 +       }
23742 +
23743         retval = sock_create(family, type, protocol, &sock);
23744         if (retval < 0)
23745                 goto out;
23746 @@ -1289,11 +1315,23 @@ asmlinkage long sys_bind(int fd, struct 
23747  {
23748         struct socket *sock;
23749         char address[MAX_SOCK_ADDR];
23750 +       struct sockaddr *sck;
23751         int err;
23752  
23753         if((sock = sockfd_lookup(fd,&err))!=NULL)
23754         {
23755                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
23756 +                       sck = (struct sockaddr *)address;
23757 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck)) {
23758 +                               sockfd_put(sock);
23759 +                               return -EACCES;
23760 +                       }
23761 +
23762 +                       if (gr_handle_sock_server(sck)) {
23763 +                               sockfd_put(sock);
23764 +                               return -EACCES;
23765 +                       }
23766 +
23767                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
23768                         if (err) {
23769                                 sockfd_put(sock);
23770 @@ -1330,6 +1368,16 @@ asmlinkage long sys_listen(int fd, int b
23771                         return err;
23772                 }
23773  
23774 +               if (gr_handle_sock_server_other(sock)) {
23775 +                       sockfd_put(sock);
23776 +                       return -EPERM;
23777 +               }
23778 +
23779 +               if(!gr_search_listen(sock)) {
23780 +                       sockfd_put(sock);
23781 +                       return -EPERM;
23782 +               }
23783 +
23784                 err=sock->ops->listen(sock, backlog);
23785                 sockfd_put(sock);
23786         }
23787 @@ -1366,6 +1414,16 @@ asmlinkage long sys_accept(int fd, struc
23788         newsock->type = sock->type;
23789         newsock->ops = sock->ops;
23790  
23791 +       if (gr_handle_sock_server_other(sock)) {
23792 +               err = -EPERM;
23793 +               goto out_release;
23794 +       }
23795 +
23796 +       if(!gr_search_accept(sock)) {
23797 +               err = -EPERM;
23798 +               goto out_release;
23799 +       }
23800 +
23801         /*
23802          * We don't need try_module_get here, as the listening socket (sock)
23803          * has the protocol module (sock->ops->owner) held.
23804 @@ -1396,6 +1454,7 @@ asmlinkage long sys_accept(int fd, struc
23805                 goto out_release;
23806  
23807         security_socket_post_accept(sock, newsock);
23808 +       gr_attach_curr_ip(newsock->sk);
23809  
23810  out_put:
23811         sockfd_put(sock);
23812 @@ -1423,6 +1482,7 @@ asmlinkage long sys_connect(int fd, stru
23813  {
23814         struct socket *sock;
23815         char address[MAX_SOCK_ADDR];
23816 +       struct sockaddr *sck;
23817         int err;
23818  
23819         sock = sockfd_lookup(fd, &err);
23820 @@ -1432,6 +1492,18 @@ asmlinkage long sys_connect(int fd, stru
23821         if (err < 0)
23822                 goto out_put;
23823  
23824 +       sck = (struct sockaddr *)address;
23825 +
23826 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck)) {
23827 +               err = -EACCES;
23828 +               goto out_put;
23829 +       }
23830 +
23831 +       if (gr_handle_sock_client(sck)) {
23832 +               err = -EACCES;
23833 +               goto out_put;
23834 +       }
23835 +
23836         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
23837         if (err)
23838                 goto out_put;
23839 @@ -1685,6 +1757,7 @@ asmlinkage long sys_shutdown(int fd, int
23840                 err=sock->ops->shutdown(sock, how);
23841                 sockfd_put(sock);
23842         }
23843 +
23844         return err;
23845  }
23846  
23847 diff -urNp linux-2.6.16.2/net/unix/af_unix.c linux-2.6.16.2/net/unix/af_unix.c
23848 --- linux-2.6.16.2/net/unix/af_unix.c   2006-04-07 12:56:47.000000000 -0400
23849 +++ linux-2.6.16.2/net/unix/af_unix.c   2006-04-09 21:23:54.000000000 -0400
23850 @@ -117,6 +117,7 @@
23851  #include <linux/mount.h>
23852  #include <net/checksum.h>
23853  #include <linux/security.h>
23854 +#include <linux/grsecurity.h>
23855  
23856  int sysctl_unix_max_dgram_qlen = 10;
23857  
23858 @@ -680,6 +681,11 @@ static struct sock *unix_find_other(stru
23859                 if (err)
23860                         goto put_fail;
23861  
23862 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
23863 +                       err = -EACCES;
23864 +                       goto put_fail;
23865 +               }
23866 +
23867                 err = -ECONNREFUSED;
23868                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
23869                         goto put_fail;
23870 @@ -703,6 +709,13 @@ static struct sock *unix_find_other(stru
23871                 if (u) {
23872                         struct dentry *dentry;
23873                         dentry = unix_sk(u)->dentry;
23874 +
23875 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
23876 +                               err = -EPERM;
23877 +                               sock_put(u);
23878 +                               goto fail;
23879 +                       }
23880 +
23881                         if (dentry)
23882                                 touch_atime(unix_sk(u)->mnt, dentry);
23883                 } else
23884 @@ -781,9 +794,18 @@ static int unix_bind(struct socket *sock
23885                  */
23886                 mode = S_IFSOCK |
23887                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
23888 +
23889 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
23890 +                       err = -EACCES;
23891 +                       goto out_mknod_dput;
23892 +               }
23893 +
23894                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
23895                 if (err)
23896                         goto out_mknod_dput;
23897 +
23898 +               gr_handle_create(dentry, nd.mnt);
23899 +
23900                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
23901                 dput(nd.dentry);
23902                 nd.dentry = dentry;
23903 @@ -801,6 +823,10 @@ static int unix_bind(struct socket *sock
23904                         goto out_unlock;
23905                 }
23906  
23907 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23908 +               sk->sk_peercred.pid = current->pid;
23909 +#endif
23910 +
23911                 list = &unix_socket_table[addr->hash];
23912         } else {
23913                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
23914 diff -urNp linux-2.6.16.2/security/commoncap.c linux-2.6.16.2/security/commoncap.c
23915 --- linux-2.6.16.2/security/commoncap.c 2006-04-07 12:56:47.000000000 -0400
23916 +++ linux-2.6.16.2/security/commoncap.c 2006-04-09 21:23:54.000000000 -0400
23917 @@ -24,6 +24,7 @@
23918  #include <linux/ptrace.h>
23919  #include <linux/xattr.h>
23920  #include <linux/hugetlb.h>
23921 +#include <linux/grsecurity.h>
23922  
23923  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
23924  {
23925 @@ -45,7 +46,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
23926  int cap_capable (struct task_struct *tsk, int cap)
23927  {
23928         /* Derived from include/linux/sched.h:capable. */
23929 -       if (cap_raised(tsk->cap_effective, cap))
23930 +       if (cap_raised (tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
23931 +               return 0;
23932 +       return -EPERM;
23933 +}
23934 +
23935 +int cap_capable_nolog (struct task_struct *tsk, int cap)
23936 +{
23937 +       /* Derived from include/linux/sched.h:capable. */
23938 +       if (cap_raised (tsk->cap_effective, cap))
23939                 return 0;
23940         return -EPERM;
23941  }
23942 @@ -61,7 +70,7 @@ int cap_ptrace (struct task_struct *pare
23943  {
23944         /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
23945         if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
23946 -           !capable(CAP_SYS_PTRACE))
23947 +           !capable_nolog(CAP_SYS_PTRACE))
23948                 return -EPERM;
23949         return 0;
23950  }
23951 @@ -164,8 +173,11 @@ void cap_bprm_apply_creds (struct linux_
23952                 }
23953         }
23954  
23955 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
23956 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
23957 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
23958 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
23959 +
23960 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
23961 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
23962  
23963         /* For init, we want to retain the capabilities set
23964          * in the init_task struct. Thus we skip the usual
23965 @@ -176,6 +188,8 @@ void cap_bprm_apply_creds (struct linux_
23966                     cap_intersect (new_permitted, bprm->cap_effective);
23967         }
23968  
23969 +       gr_handle_chroot_caps(current);
23970 +
23971         /* AUD: Audit candidate if current->cap_effective is set */
23972  
23973         current->keep_capabilities = 0;
23974 @@ -321,12 +335,13 @@ int cap_vm_enough_memory(long pages)
23975  {
23976         int cap_sys_admin = 0;
23977  
23978 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
23979 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
23980                 cap_sys_admin = 1;
23981         return __vm_enough_memory(pages, cap_sys_admin);
23982  }
23983  
23984  EXPORT_SYMBOL(cap_capable);
23985 +EXPORT_SYMBOL(cap_capable_nolog);
23986  EXPORT_SYMBOL(cap_settime);
23987  EXPORT_SYMBOL(cap_ptrace);
23988  EXPORT_SYMBOL(cap_capget);
23989 diff -urNp linux-2.6.16.2/security/dummy.c linux-2.6.16.2/security/dummy.c
23990 --- linux-2.6.16.2/security/dummy.c     2006-04-07 12:56:47.000000000 -0400
23991 +++ linux-2.6.16.2/security/dummy.c     2006-04-09 21:23:54.000000000 -0400
23992 @@ -29,6 +29,7 @@
23993  #include <linux/hugetlb.h>
23994  #include <linux/ptrace.h>
23995  #include <linux/file.h>
23996 +#include <linux/grsecurity.h>
23997  
23998  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
23999  {
24000 @@ -139,8 +140,11 @@ static void dummy_bprm_apply_creds (stru
24001                 }
24002         }
24003  
24004 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
24005 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
24006 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
24007 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
24008 +
24009 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
24010 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
24011  
24012         dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
24013  }
24014 diff -urNp linux-2.6.16.2/security/Kconfig linux-2.6.16.2/security/Kconfig
24015 --- linux-2.6.16.2/security/Kconfig     2006-04-07 12:56:47.000000000 -0400
24016 +++ linux-2.6.16.2/security/Kconfig     2006-04-09 21:23:54.000000000 -0400
24017 @@ -4,6 +4,408 @@
24018  
24019  menu "Security options"
24020  
24021 +menu "PaX"
24022 +
24023 +config PAX
24024 +       bool "Enable various PaX features"
24025 +       depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
24026 +       help
24027 +         This allows you to enable various PaX features.  PaX adds
24028 +         intrusion prevention mechanisms to the kernel that reduce
24029 +         the risks posed by exploitable memory corruption bugs.
24030 +
24031 +menu "PaX Control"
24032 +       depends on PAX
24033 +
24034 +config PAX_SOFTMODE
24035 +       bool 'Support soft mode'
24036 +       help
24037 +         Enabling this option will allow you to run PaX in soft mode, that
24038 +         is, PaX features will not be enforced by default, only on executables
24039 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
24040 +         is the only way to mark executables for soft mode use.
24041 +
24042 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
24043 +         line option on boot.  Furthermore you can control various PaX features
24044 +         at runtime via the entries in /proc/sys/kernel/pax.
24045 +
24046 +config PAX_EI_PAX
24047 +       bool 'Use legacy ELF header marking'
24048 +       help
24049 +         Enabling this option will allow you to control PaX features on
24050 +         a per executable basis via the 'chpax' utility available at
24051 +         http://pax.grsecurity.net/.  The control flags will be read from
24052 +         an otherwise reserved part of the ELF header.  This marking has
24053 +         numerous drawbacks (no support for soft-mode, toolchain does not
24054 +         know about the non-standard use of the ELF header) therefore it
24055 +         has been deprecated in favour of PT_PAX_FLAGS support.
24056 +
24057 +         If you have applications not marked by the PT_PAX_FLAGS ELF
24058 +         program header then you MUST enable this option otherwise they
24059 +         will not get any protection.
24060 +
24061 +         Note that if you enable PT_PAX_FLAGS marking support as well,
24062 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
24063 +
24064 +config PAX_PT_PAX_FLAGS
24065 +       bool 'Use ELF program header marking'
24066 +       help
24067 +         Enabling this option will allow you to control PaX features on
24068 +         a per executable basis via the 'paxctl' utility available at
24069 +         http://pax.grsecurity.net/.  The control flags will be read from
24070 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
24071 +         has the benefits of supporting both soft mode and being fully
24072 +         integrated into the toolchain (the binutils patch is available
24073 +         from http://pax.grsecurity.net).
24074 +
24075 +         If you have applications not marked by the PT_PAX_FLAGS ELF
24076 +         program header then you MUST enable the EI_PAX marking support
24077 +         otherwise they will not get any protection.
24078 +
24079 +         Note that if you enable the legacy EI_PAX marking support as well,
24080 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
24081 +
24082 +choice
24083 +       prompt 'MAC system integration'
24084 +       default PAX_HAVE_ACL_FLAGS
24085 +       help
24086 +         Mandatory Access Control systems have the option of controlling
24087 +         PaX flags on a per executable basis, choose the method supported
24088 +         by your particular system.
24089 +
24090 +         - "none": if your MAC system does not interact with PaX,
24091 +         - "direct": if your MAC system defines pax_set_flags() itself,
24092 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
24093 +
24094 +         NOTE: this option is for developers/integrators only.
24095 +
24096 +config PAX_NO_ACL_FLAGS
24097 +       bool 'none'
24098 +
24099 +config PAX_HAVE_ACL_FLAGS
24100 +       bool 'direct'
24101 +
24102 +config PAX_HOOK_ACL_FLAGS
24103 +       bool 'hook'
24104 +endchoice
24105 +
24106 +endmenu
24107 +
24108 +menu "Non-executable pages"
24109 +       depends on PAX
24110 +
24111 +config PAX_NOEXEC
24112 +       bool "Enforce non-executable pages"
24113 +       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)
24114 +       help
24115 +         By design some architectures do not allow for protecting memory
24116 +         pages against execution or even if they do, Linux does not make
24117 +         use of this feature.  In practice this means that if a page is
24118 +         readable (such as the stack or heap) it is also executable.
24119 +
24120 +         There is a well known exploit technique that makes use of this
24121 +         fact and a common programming mistake where an attacker can
24122 +         introduce code of his choice somewhere in the attacked program's
24123 +         memory (typically the stack or the heap) and then execute it.
24124 +
24125 +         If the attacked program was running with different (typically
24126 +         higher) privileges than that of the attacker, then he can elevate
24127 +         his own privilege level (e.g. get a root shell, write to files for
24128 +         which he does not have write access to, etc).
24129 +
24130 +         Enabling this option will let you choose from various features
24131 +         that prevent the injection and execution of 'foreign' code in
24132 +         a program.
24133 +
24134 +         This will also break programs that rely on the old behaviour and
24135 +         expect that dynamically allocated memory via the malloc() family
24136 +         of functions is executable (which it is not).  Notable examples
24137 +         are the XFree86 4.x server, the java runtime and wine.
24138 +
24139 +config PAX_PAGEEXEC
24140 +       bool "Paging based non-executable pages"
24141 +       depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
24142 +       select PAX_NOVSYSCALL if X86_32
24143 +       help
24144 +         This implementation is based on the paging feature of the CPU.
24145 +         On i386 and ppc there is a variable but usually low performance
24146 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
24147 +         and x86_64 there is no performance impact.
24148 +
24149 +config PAX_SEGMEXEC
24150 +       bool "Segmentation based non-executable pages"
24151 +       depends on PAX_NOEXEC && X86_32
24152 +       select PAX_NOVSYSCALL if X86_32
24153 +       help
24154 +         This implementation is based on the segmentation feature of the
24155 +         CPU and has little performance impact, however applications will
24156 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
24157 +
24158 +choice
24159 +       prompt "Default non-executable page method"
24160 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
24161 +       default PAX_DEFAULT_SEGMEXEC
24162 +       help
24163 +         Select the default non-executable page method applied to applications
24164 +         that do not select one themselves.
24165 +
24166 +config PAX_DEFAULT_PAGEEXEC
24167 +       bool "PAGEEXEC"
24168 +
24169 +config PAX_DEFAULT_SEGMEXEC
24170 +       bool "SEGMEXEC"
24171 +endchoice
24172 +
24173 +config PAX_EMUTRAMP
24174 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
24175 +       default y if PARISC || PPC32
24176 +       help
24177 +         There are some programs and libraries that for one reason or
24178 +         another attempt to execute special small code snippets from
24179 +         non-executable memory pages.  Most notable examples are the
24180 +         signal handler return code generated by the kernel itself and
24181 +         the GCC trampolines.
24182 +
24183 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
24184 +         such programs will no longer work under your kernel.
24185 +
24186 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
24187 +         utilities to enable trampoline emulation for the affected programs
24188 +         yet still have the protection provided by the non-executable pages.
24189 +
24190 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
24191 +         well, otherwise your system will not even boot.
24192 +
24193 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
24194 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
24195 +         for the affected files.
24196 +
24197 +         NOTE: enabling this feature *may* open up a loophole in the
24198 +         protection provided by non-executable pages that an attacker
24199 +         could abuse.  Therefore the best solution is to not have any
24200 +         files on your system that would require this option.  This can
24201 +         be achieved by not using libc5 (which relies on the kernel
24202 +         signal handler return code) and not using or rewriting programs
24203 +         that make use of the nested function implementation of GCC.
24204 +         Skilled users can just fix GCC itself so that it implements
24205 +         nested function calls in a way that does not interfere with PaX.
24206 +
24207 +config PAX_EMUSIGRT
24208 +       bool "Automatically emulate sigreturn trampolines"
24209 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
24210 +       default y
24211 +       help
24212 +         Enabling this option will have the kernel automatically detect
24213 +         and emulate signal return trampolines executing on the stack
24214 +         that would otherwise lead to task termination.
24215 +
24216 +         This solution is intended as a temporary one for users with
24217 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
24218 +         Modula-3 runtime, etc) or executables linked to such, basically
24219 +         everything that does not specify its own SA_RESTORER function in
24220 +         normal executable memory like glibc 2.1+ does.
24221 +
24222 +         On parisc and ppc you MUST enable this option, otherwise your
24223 +         system will not even boot.
24224 +
24225 +         NOTE: this feature cannot be disabled on a per executable basis
24226 +         and since it *does* open up a loophole in the protection provided
24227 +         by non-executable pages, the best solution is to not have any
24228 +         files on your system that would require this option.
24229 +
24230 +config PAX_MPROTECT
24231 +       bool "Restrict mprotect()"
24232 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
24233 +       help
24234 +         Enabling this option will prevent programs from
24235 +          - changing the executable status of memory pages that were
24236 +            not originally created as executable,
24237 +          - making read-only executable pages writable again,
24238 +          - creating executable pages from anonymous memory.
24239 +
24240 +         You should say Y here to complete the protection provided by
24241 +         the enforcement of non-executable pages.
24242 +
24243 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
24244 +         this feature on a per file basis.
24245 +
24246 +config PAX_NOELFRELOCS
24247 +       bool "Disallow ELF text relocations"
24248 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
24249 +       help
24250 +         Non-executable pages and mprotect() restrictions are effective
24251 +         in preventing the introduction of new executable code into an
24252 +         attacked task's address space.  There remain only two venues
24253 +         for this kind of attack: if the attacker can execute already
24254 +         existing code in the attacked task then he can either have it
24255 +         create and mmap() a file containing his code or have it mmap()
24256 +         an already existing ELF library that does not have position
24257 +         independent code in it and use mprotect() on it to make it
24258 +         writable and copy his code there.  While protecting against
24259 +         the former approach is beyond PaX, the latter can be prevented
24260 +         by having only PIC ELF libraries on one's system (which do not
24261 +         need to relocate their code).  If you are sure this is your case,
24262 +         then enable this option otherwise be careful as you may not even
24263 +         be able to boot or log on your system (for example, some PAM
24264 +         modules are erroneously compiled as non-PIC by default).
24265 +
24266 +         NOTE: if you are using dynamic ELF executables (as suggested
24267 +         when using ASLR) then you must have made sure that you linked
24268 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
24269 +         referenced there has already been updated to support this).
24270 +
24271 +config PAX_ETEXECRELOCS
24272 +       bool "Allow ELF ET_EXEC text relocations"
24273 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
24274 +       default y
24275 +       help
24276 +         On some architectures there are incorrectly created applications
24277 +         that require text relocations and would not work without enabling
24278 +         this option.  If you are an alpha, ia64 or parisc user, you should
24279 +         enable this option and disable it once you have made sure that
24280 +         none of your applications need it.
24281 +
24282 +config PAX_EMUPLT
24283 +       bool "Automatically emulate ELF PLT"
24284 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
24285 +       default y
24286 +       help
24287 +         Enabling this option will have the kernel automatically detect
24288 +         and emulate the Procedure Linkage Table entries in ELF files.
24289 +         On some architectures such entries are in writable memory, and
24290 +         become non-executable leading to task termination.  Therefore
24291 +         it is mandatory that you enable this option on alpha, parisc, ppc,
24292 +         sparc and sparc64, otherwise your system would not even boot.
24293 +
24294 +         NOTE: this feature *does* open up a loophole in the protection
24295 +         provided by the non-executable pages, therefore the proper
24296 +         solution is to modify the toolchain to produce a PLT that does
24297 +         not need to be writable.
24298 +
24299 +config PAX_DLRESOLVE
24300 +       bool
24301 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
24302 +       default y
24303 +
24304 +config PAX_SYSCALL
24305 +       bool
24306 +       depends on PAX_PAGEEXEC && PPC32
24307 +       default y
24308 +
24309 +config PAX_KERNEXEC
24310 +       bool "Enforce non-executable kernel pages"
24311 +       depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !DEBUG_RODATA
24312 +       help
24313 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
24314 +         that is, enabling this option will make it harder to inject
24315 +         and execute 'foreign' code in kernel memory itself.
24316 +
24317 +endmenu
24318 +
24319 +menu "Address Space Layout Randomization"
24320 +       depends on PAX
24321 +
24322 +config PAX_ASLR
24323 +       bool "Address Space Layout Randomization"
24324 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
24325 +       help
24326 +         Many if not most exploit techniques rely on the knowledge of
24327 +         certain addresses in the attacked program.  The following options
24328 +         will allow the kernel to apply a certain amount of randomization
24329 +         to specific parts of the program thereby forcing an attacker to
24330 +         guess them in most cases.  Any failed guess will most likely crash
24331 +         the attacked program which allows the kernel to detect such attempts
24332 +         and react on them.  PaX itself provides no reaction mechanisms,
24333 +         instead it is strongly encouraged that you make use of Nergal's
24334 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
24335 +         (http://www.grsecurity.net/) built-in crash detection features or
24336 +         develop one yourself.
24337 +
24338 +         By saying Y here you can choose to randomize the following areas:
24339 +          - top of the task's kernel stack
24340 +          - top of the task's userland stack
24341 +          - base address for mmap() requests that do not specify one
24342 +            (this includes all libraries)
24343 +          - base address of the main executable
24344 +
24345 +         It is strongly recommended to say Y here as address space layout
24346 +         randomization has negligible impact on performance yet it provides
24347 +         a very effective protection.
24348 +
24349 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
24350 +         this feature on a per file basis.
24351 +
24352 +config PAX_RANDKSTACK
24353 +       bool "Randomize kernel stack base"
24354 +       depends on PAX_ASLR && X86_TSC && X86_32
24355 +       help
24356 +         By saying Y here the kernel will randomize every task's kernel
24357 +         stack on every system call.  This will not only force an attacker
24358 +         to guess it but also prevent him from making use of possible
24359 +         leaked information about it.
24360 +
24361 +         Since the kernel stack is a rather scarce resource, randomization
24362 +         may cause unexpected stack overflows, therefore you should very
24363 +         carefully test your system.  Note that once enabled in the kernel
24364 +         configuration, this feature cannot be disabled on a per file basis.
24365 +
24366 +config PAX_RANDUSTACK
24367 +       bool "Randomize user stack base"
24368 +       depends on PAX_ASLR
24369 +       help
24370 +         By saying Y here the kernel will randomize every task's userland
24371 +         stack.  The randomization is done in two steps where the second
24372 +         one may apply a big amount of shift to the top of the stack and
24373 +         cause problems for programs that want to use lots of memory (more
24374 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
24375 +         For this reason the second step can be controlled by 'chpax' or
24376 +         'paxctl' on a per file basis.
24377 +
24378 +config PAX_RANDMMAP
24379 +       bool "Randomize mmap() base"
24380 +       depends on PAX_ASLR
24381 +       help
24382 +         By saying Y here the kernel will use a randomized base address for
24383 +         mmap() requests that do not specify one themselves.  As a result
24384 +         all dynamically loaded libraries will appear at random addresses
24385 +         and therefore be harder to exploit by a technique where an attacker
24386 +         attempts to execute library code for his purposes (e.g. spawn a
24387 +         shell from an exploited program that is running at an elevated
24388 +         privilege level).
24389 +
24390 +         Furthermore, if a program is relinked as a dynamic ELF file, its
24391 +         base address will be randomized as well, completing the full
24392 +         randomization of the address space layout.  Attacking such programs
24393 +         becomes a guess game.  You can find an example of doing this at
24394 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
24395 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
24396 +
24397 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
24398 +         feature on a per file basis.
24399 +
24400 +config PAX_NOVSYSCALL
24401 +       bool "Disable the vsyscall page"
24402 +       depends on PAX_ASLR && X86_32
24403 +       help
24404 +         The Linux 2.6 kernel introduced a new feature that speeds up or
24405 +         simplifies certain operations, such as system calls or returns
24406 +         from signal handlers.
24407 +
24408 +         Unfortunately the implementation also gives a powerful instrument
24409 +         into the hands of exploit writers: the so-called vsyscall page exists
24410 +         in every task at the same fixed address and it contains machine code
24411 +         that is very useful in performing the return-to-libc style attack.
24412 +
24413 +         Since this exploit technique cannot in general be protected against
24414 +         via kernel solutions, this option will allow you to disable the use
24415 +         of the vsyscall page and revert back to the old behaviour.
24416 +
24417 +endmenu
24418 +
24419 +endmenu
24420 +
24421 +source grsecurity/Kconfig
24422 +
24423  config KEYS
24424         bool "Enable access key retention support"
24425         help
24426 diff -urNp linux-2.6.16.2/security/security.c linux-2.6.16.2/security/security.c
24427 --- linux-2.6.16.2/security/security.c  2006-04-07 12:56:47.000000000 -0400
24428 +++ linux-2.6.16.2/security/security.c  2006-04-09 21:23:54.000000000 -0400
24429 @@ -201,4 +201,5 @@ EXPORT_SYMBOL_GPL(unregister_security);
24430  EXPORT_SYMBOL_GPL(mod_reg_security);
24431  EXPORT_SYMBOL_GPL(mod_unreg_security);
24432  EXPORT_SYMBOL(capable);
24433 +EXPORT_SYMBOL(capable_nolog);
24434  EXPORT_SYMBOL(security_ops);
This page took 1.805295 seconds and 3 git commands to generate.