]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-grsec-2.0.1.patch
- now on HEAD
[packages/kernel.git] / kernel-grsec-2.0.1.patch
1 diff -uNr linux-2.6.8/arch/alpha/kernel/osf_sys.c linux-2.6.8.grsecurity/arch/alpha/kernel/osf_sys.c
2 --- linux-2.6.8/arch/alpha/kernel/osf_sys.c     2004-08-14 07:36:09.000000000 +0200
3 +++ linux-2.6.8.grsecurity/arch/alpha/kernel/osf_sys.c  2004-08-16 17:06:17.583265784 +0200
4 @@ -37,6 +37,7 @@
5  #include <linux/namei.h>
6  #include <linux/uio.h>
7  #include <linux/vfs.h>
8 +#include <linux/grsecurity.h>
9  
10  #include <asm/fpu.h>
11  #include <asm/io.h>
12 @@ -179,6 +180,11 @@
13         struct file *file = NULL;
14         unsigned long ret = -EBADF;
15  
16 +#ifdef CONFIG_PAX_RANDEXEC
17 +       if (flags & MAP_MIRROR)
18 +               return -EINVAL;
19 +#endif
20 +
21  #if 0
22         if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
23                 printk("%s: unimplemented OSF mmap flags %04lx\n", 
24 @@ -189,6 +195,13 @@
25                 if (!file)
26                         goto out;
27         }
28 +
29 +       if (gr_handle_mmap(file, prot)) {
30 +               fput(file);
31 +               ret = -EACCES;
32 +               goto out;
33 +       }
34 +
35         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
36         down_write(&current->mm->mmap_sem);
37         ret = do_mmap(file, addr, len, prot, flags, off);
38 @@ -1274,6 +1287,10 @@
39            merely specific addresses, but regions of memory -- perhaps
40            this feature should be incorporated into all ports?  */
41  
42 +#ifdef CONFIG_PAX_RANDMMAP
43 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
44 +#endif
45 +
46         if (addr) {
47                 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
48                 if (addr != (unsigned long) -ENOMEM)
49 @@ -1281,8 +1298,16 @@
50         }
51  
52         /* Next, try allocating at TASK_UNMAPPED_BASE.  */
53 -       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
54 -                                        len, limit);
55 +
56 +       addr = TASK_UNMAPPED_BASE;
57 +
58 +#ifdef CONFIG_PAX_RANDMMAP
59 +       if (current->flags & PF_PAX_RANDMMAP)
60 +               addr += current->mm->delta_mmap;
61 +#endif
62 +
63 +       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
64 +
65         if (addr != (unsigned long) -ENOMEM)
66                 return addr;
67  
68 diff -uNr linux-2.6.8/arch/alpha/kernel/ptrace.c linux-2.6.8.grsecurity/arch/alpha/kernel/ptrace.c
69 --- linux-2.6.8/arch/alpha/kernel/ptrace.c      2004-08-14 07:37:40.000000000 +0200
70 +++ linux-2.6.8.grsecurity/arch/alpha/kernel/ptrace.c   2004-08-16 17:06:17.598263504 +0200
71 @@ -14,6 +14,7 @@
72  #include <linux/user.h>
73  #include <linux/slab.h>
74  #include <linux/security.h>
75 +#include <linux/grsecurity.h>
76  
77  #include <asm/uaccess.h>
78  #include <asm/pgtable.h>
79 @@ -288,6 +289,9 @@
80         if (!child)
81                 goto out_notsk;
82  
83 +       if (gr_handle_ptrace(child, request))
84 +               goto out;
85 +
86         if (request == PTRACE_ATTACH) {
87                 ret = ptrace_attach(child);
88                 goto out;
89 diff -uNr linux-2.6.8/arch/alpha/mm/fault.c linux-2.6.8.grsecurity/arch/alpha/mm/fault.c
90 --- linux-2.6.8/arch/alpha/mm/fault.c   2004-08-14 07:36:44.000000000 +0200
91 +++ linux-2.6.8.grsecurity/arch/alpha/mm/fault.c        2004-08-16 17:06:17.639257272 +0200
92 @@ -25,6 +25,7 @@
93  #include <linux/smp_lock.h>
94  #include <linux/interrupt.h>
95  #include <linux/module.h>
96 +#include <linux/binfmts.h>
97  
98  #include <asm/system.h>
99  #include <asm/uaccess.h>
100 @@ -56,6 +57,142 @@
101         __reload_thread(pcb);
102  }
103  
104 +#ifdef CONFIG_PAX_PAGEEXEC
105 +/*
106 + * PaX: decide what to do with offenders (regs->pc = fault address)
107 + *
108 + * returns 1 when task should be killed
109 + *         2 when patched PLT trampoline was detected
110 + *         3 when unpatched PLT trampoline was detected
111 + *         4 when legitimate ET_EXEC was detected
112 + */
113 +static int pax_handle_fetch_fault(struct pt_regs *regs)
114 +{
115 +
116 +#ifdef CONFIG_PAX_EMUPLT
117 +       int err;
118 +#endif
119 +
120 +#ifdef CONFIG_PAX_RANDEXEC
121 +       if (current->flags & PF_PAX_RANDEXEC) {
122 +               if (regs->pc >= current->mm->start_code &&
123 +                   regs->pc < current->mm->end_code)
124 +               {
125 +                       if (regs->r26 == regs->pc)
126 +                               return 1;
127 +
128 +                       regs->pc += current->mm->delta_exec;
129 +                       return 4;
130 +               }
131 +       }
132 +#endif
133 +
134 +#ifdef CONFIG_PAX_EMUPLT
135 +       do { /* PaX: patched PLT emulation #1 */
136 +               unsigned int ldah, ldq, jmp;
137 +
138 +               err = get_user(ldah, (unsigned int *)regs->pc);
139 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
140 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
141 +
142 +               if (err)
143 +                       break;
144 +
145 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
146 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
147 +                   jmp == 0x6BFB0000U)
148 +               {
149 +                       unsigned long r27, addr;
150 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
151 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
152 +
153 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
154 +                       err = get_user(r27, (unsigned long*)addr);
155 +                       if (err)
156 +                               break;
157 +
158 +                       regs->r27 = r27;
159 +                       regs->pc = r27;
160 +                       return 2;
161 +               }
162 +       } while (0);
163 +
164 +       do { /* PaX: patched PLT emulation #2 */
165 +               unsigned int ldah, lda, br;
166 +
167 +               err = get_user(ldah, (unsigned int *)regs->pc);
168 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
169 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
170 +
171 +               if (err)
172 +                       break;
173 +
174 +               if ((ldah & 0xFFFF0000U)== 0x277B0000U &&
175 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
176 +                   (br & 0xFFE00000U) == 0xC3E00000U)
177 +               {
178 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
179 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
180 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
181 +
182 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
183 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
184 +                       return 2;
185 +               }
186 +       } while (0);
187 +
188 +       do { /* PaX: unpatched PLT emulation */
189 +               unsigned int br;
190 +
191 +               err = get_user(br, (unsigned int *)regs->pc);
192 +
193 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
194 +                       unsigned int br2, ldq, nop, jmp;
195 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
196 +
197 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
198 +                       err = get_user(br2, (unsigned int *)addr);
199 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
200 +                       err |= get_user(nop, (unsigned int *)(addr+8));
201 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
202 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
203 +
204 +                       if (err)
205 +                               break;
206 +
207 +                       if (br2 == 0xC3600000U &&
208 +                           ldq == 0xA77B000CU &&
209 +                           nop == 0x47FF041FU &&
210 +                           jmp == 0x6B7B0000U)
211 +                       {
212 +                               regs->r28 = regs->pc+4;
213 +                               regs->r27 = addr+16;
214 +                               regs->pc = resolver;
215 +                               return 3;
216 +                       }
217 +               }
218 +       } while (0);
219 +#endif
220 +
221 +       return 1;
222 +}
223 +
224 +void pax_report_insns(void *pc, void *sp)
225 +{
226 +       unsigned long i;
227 +
228 +       printk(KERN_ERR "PAX: bytes at PC: ");
229 +       for (i = 0; i < 5; i++) {
230 +               unsigned int c;
231 +               if (get_user(c, (unsigned int*)pc+i)) {
232 +                       printk("<invalid address>.");
233 +                       break;
234 +               }
235 +               printk("%08x ", c);
236 +       }
237 +       printk("\n");
238 +}
239 +#endif
240  
241  /*
242   * This routine handles page faults.  It determines the address,
243 @@ -133,8 +270,34 @@
244   good_area:
245         si_code = SEGV_ACCERR;
246         if (cause < 0) {
247 -               if (!(vma->vm_flags & VM_EXEC))
248 +               if (!(vma->vm_flags & VM_EXEC)) {
249 +
250 +#ifdef CONFIG_PAX_PAGEEXEC
251 +                       if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->pc)
252 +                               goto bad_area;
253 +
254 +                       up_read(&mm->mmap_sem);
255 +                       switch(pax_handle_fetch_fault(regs)) {
256 +
257 +#ifdef CONFIG_PAX_EMUPLT
258 +                       case 2:
259 +                       case 3:
260 +                               return;
261 +#endif
262 +
263 +#ifdef CONFIG_PAX_RANDEXEC
264 +                       case 4:
265 +                               return;
266 +#endif
267 +
268 +                       }
269 +                       pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
270 +                       do_exit(SIGKILL);
271 +#else
272                         goto bad_area;
273 +#endif
274 +
275 +               }
276         } else if (!cause) {
277                 /* Allow reads even for write-only mappings */
278                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
279 diff -uNr linux-2.6.8/arch/i386/Kconfig linux-2.6.8.grsecurity/arch/i386/Kconfig
280 --- linux-2.6.8/arch/i386/Kconfig       2004-08-14 07:36:17.000000000 +0200
281 +++ linux-2.6.8.grsecurity/arch/i386/Kconfig    2004-08-16 17:06:17.684250432 +0200
282 @@ -396,7 +396,7 @@
283  
284  config X86_ALIGNMENT_16
285         bool
286 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
287 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
288         default y
289  
290  config X86_GOOD_APIC
291 diff -uNr linux-2.6.8/arch/i386/kernel/apm.c linux-2.6.8.grsecurity/arch/i386/kernel/apm.c
292 --- linux-2.6.8/arch/i386/kernel/apm.c  2004-08-14 07:36:13.000000000 +0200
293 +++ linux-2.6.8.grsecurity/arch/i386/kernel/apm.c       2004-08-16 17:06:17.705247240 +0200
294 @@ -598,19 +598,40 @@
295         int                     cpu;
296         struct desc_struct      save_desc_40;
297  
298 +#ifdef CONFIG_PAX_KERNEXEC
299 +       unsigned long           cr3;
300 +#endif
301 +
302         cpus = apm_save_cpus();
303         
304         cpu = get_cpu();
305 +
306 +#ifdef CONFIG_PAX_KERNEXEC
307 +       pax_open_kernel(flags, cr3);
308 +#endif
309 +
310         save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
311         cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
312  
313 +#ifndef CONFIG_PAX_KERNEXEC
314         local_save_flags(flags);
315         APM_DO_CLI;
316 +#endif
317 +
318         APM_DO_SAVE_SEGS;
319         apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
320         APM_DO_RESTORE_SEGS;
321 +
322 +#ifndef CONFIG_PAX_KERNEXEC
323         local_irq_restore(flags);
324 +#endif
325 +
326         cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
327 +
328 +#ifdef CONFIG_PAX_KERNEXEC
329 +       pax_close_kernel(flags, cr3);
330 +#endif
331 +
332         put_cpu();
333         apm_restore_cpus(cpus);
334         
335 @@ -640,20 +661,40 @@
336         int                     cpu;
337         struct desc_struct      save_desc_40;
338  
339 +#ifdef CONFIG_PAX_KERNEXEC
340 +       unsigned long           cr3;
341 +#endif
342  
343         cpus = apm_save_cpus();
344         
345         cpu = get_cpu();
346 +
347 +#ifdef CONFIG_PAX_KERNEXEC
348 +       pax_open_kernel(flags, cr3);
349 +#endif
350 +
351         save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
352         cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
353  
354 +#ifndef CONFIG_PAX_KERNEXEC
355         local_save_flags(flags);
356         APM_DO_CLI;
357 +#endif
358 +
359         APM_DO_SAVE_SEGS;
360         error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
361         APM_DO_RESTORE_SEGS;
362 +
363 +#ifndef CONFIG_PAX_KERNEXEC
364         local_irq_restore(flags);
365 +#endif
366 +
367         cpu_gdt_table[smp_processor_id()][0x40 / 8] = save_desc_40;
368 +
369 +#ifdef CONFIG_PAX_KERNEXEC
370 +       pax_close_kernel(flags, cr3);
371 +#endif
372 +
373         put_cpu();
374         apm_restore_cpus(cpus);
375         return error;
376 diff -uNr linux-2.6.8/arch/i386/kernel/cpu/common.c linux-2.6.8.grsecurity/arch/i386/kernel/cpu/common.c
377 --- linux-2.6.8/arch/i386/kernel/cpu/common.c   2004-08-14 07:36:13.000000000 +0200
378 +++ linux-2.6.8.grsecurity/arch/i386/kernel/cpu/common.c        2004-08-16 17:06:17.737242376 +0200
379 @@ -358,6 +358,10 @@
380         if (this_cpu->c_init)
381                 this_cpu->c_init(c);
382  
383 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_NOVSYSCALL)
384 +       clear_bit(X86_FEATURE_SEP, c->x86_capability);
385 +#endif
386 +
387         /* Disable the PN if appropriate */
388         squash_the_stupid_serial_number(c);
389  
390 @@ -554,7 +558,7 @@
391         set_tss_desc(cpu,t);
392         cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
393         load_TR_desc();
394 -       load_LDT(&init_mm.context);
395 +       _load_LDT(&init_mm.context);
396  
397         /* Set up doublefault TSS pointer in the GDT */
398         __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
399 diff -uNr linux-2.6.8/arch/i386/kernel/entry.S linux-2.6.8.grsecurity/arch/i386/kernel/entry.S
400 --- linux-2.6.8/arch/i386/kernel/entry.S        2004-08-14 07:36:32.000000000 +0200
401 +++ linux-2.6.8.grsecurity/arch/i386/kernel/entry.S     2004-08-16 17:06:17.755239640 +0200
402 @@ -266,6 +266,11 @@
403         movl TI_flags(%ebp), %ecx
404         testw $_TIF_ALLWORK_MASK, %cx
405         jne syscall_exit_work
406 +
407 +#ifdef CONFIG_PAX_RANDKSTACK
408 +       call pax_randomize_kstack
409 +#endif
410 +
411  /* if something modifies registers it must also disable sysexit */
412         movl EIP(%esp), %edx
413         movl OLDESP(%esp), %ecx
414 @@ -293,6 +298,11 @@
415         movl TI_flags(%ebp), %ecx
416         testw $_TIF_ALLWORK_MASK, %cx   # current->work
417         jne syscall_exit_work
418 +
419 +#ifdef CONFIG_PAX_RANDKSTACK
420 +       call pax_randomize_kstack
421 +#endif
422 +
423  restore_all:
424         RESTORE_ALL
425  
426 @@ -600,7 +610,7 @@
427         pushl $do_spurious_interrupt_bug
428         jmp error_code
429  
430 -.data
431 +.section .rodata,"a",@progbits
432  ENTRY(sys_call_table)
433         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
434         .long sys_exit
435 diff -uNr linux-2.6.8/arch/i386/kernel/head.S linux-2.6.8.grsecurity/arch/i386/kernel/head.S
436 --- linux-2.6.8/arch/i386/kernel/head.S 2004-08-14 07:36:16.000000000 +0200
437 +++ linux-2.6.8.grsecurity/arch/i386/kernel/head.S      2004-08-16 17:06:17.777236296 +0200
438 @@ -48,6 +48,12 @@
439  
440  
441  /*
442 + * Real beginning of normal "text" segment
443 + */
444 +ENTRY(stext)
445 +ENTRY(_stext)
446 +
447 +/*
448   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
449   * %esi points to the real-mode code as a 32-bit pointer.
450   * CS and DS must be 4 GB flat segments, but we don't depend on
451 @@ -92,9 +98,9 @@
452  
453         movl $(pg0 - __PAGE_OFFSET), %edi
454         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
455 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
456 +       movl $0x067, %eax                       /* 0x067 = DIRTY+ACCESSED+PRESENT+RW+USER */
457  10:
458 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
459 +       leal 0x067(%edi),%ecx                   /* Create PDE entry */
460         movl %ecx,(%edx)                        /* Store identity PDE entry */
461         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
462         addl $4,%edx
463 @@ -104,8 +110,8 @@
464         addl $0x1000,%eax
465         loop 11b
466         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
467 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
468 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
469 +       /* bytes beyond the end of our own page tables; the +0x067 is the attribute bits */
470 +       leal (INIT_MAP_BEYOND_END+0x067)(%edi),%ebp
471         cmpl %ebp,%eax
472         jb 10b
473         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
474 @@ -190,7 +196,7 @@
475         movl %cr0,%eax
476         orl $0x80000000,%eax
477         movl %eax,%cr0          /* ..and set paging (PG) bit */
478 -       ljmp $__BOOT_CS,$1f     /* Clear prefetch and normalize %eip */
479 +       ljmp $__BOOT_CS,$1f + __KERNEL_TEXT_OFFSET      /* Clear prefetch and normalize %eip */
480  1:
481         /* Set up the stack pointer */
482         lss stack_start,%esp
483 @@ -405,31 +411,39 @@
484         iret
485  
486  /*
487 - * Real beginning of normal "text" segment
488 + * This starts the data section.
489   */
490 -ENTRY(stext)
491 -ENTRY(_stext)
492 +.data
493 +ready: .byte 0
494  
495 -/*
496 - * BSS section
497 - */
498 -.section ".bss.page_aligned","w"
499 +.section .data.swapper_pg_dir,"a",@progbits
500  ENTRY(swapper_pg_dir)
501         .fill 1024,4,0
502 +
503 +#ifdef CONFIG_PAX_KERNEXEC
504 +ENTRY(kernexec_pg_dir)
505 +       .fill 1024,4,0
506 +#endif
507 +
508 +.section .rodata.empty_zero_page,"a",@progbits
509  ENTRY(empty_zero_page)
510         .fill 4096,1,0
511  
512  /*
513 - * This starts the data section.
514 - */
515 -.data
516 + * The IDT has to be page-aligned to simplify the Pentium
517 + * F0 0F bug workaround.. We have a special link segment
518 + * for this.
519 + */
520 +.section .rodata.idt,"a",@progbits
521 +ENTRY(idt_table)
522 +       .fill 256,8,0
523  
524 +.section .rodata,"a",@progbits
525  ENTRY(stack_start)
526         .long init_thread_union+THREAD_SIZE
527         .long __BOOT_DS
528  
529 -ready: .byte 0
530 -
531 +/* This is the default interrupt "handler" :-) */
532  int_msg:
533         .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
534  
535 @@ -471,8 +485,8 @@
536         .align L1_CACHE_BYTES
537  ENTRY(boot_gdt_table)
538         .fill GDT_ENTRY_BOOT_CS,8,0
539 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
540 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
541 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
542 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
543  
544  /*
545   * The Global Descriptor Table contains 28 quadwords, per-CPU.
546 @@ -483,7 +497,13 @@
547         .quad 0x0000000000000000        /* 0x0b reserved */
548         .quad 0x0000000000000000        /* 0x13 reserved */
549         .quad 0x0000000000000000        /* 0x1b reserved */
550 +
551 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
552 +       .quad 0x00cf9b000000ffff        /* 0x20 kernel 4GB code at 0x00000000 */
553 +#else
554         .quad 0x0000000000000000        /* 0x20 unused */
555 +#endif
556 +
557         .quad 0x0000000000000000        /* 0x28 unused */
558         .quad 0x0000000000000000        /* 0x33 TLS entry 1 */
559         .quad 0x0000000000000000        /* 0x3b TLS entry 2 */
560 @@ -492,27 +512,32 @@
561         .quad 0x0000000000000000        /* 0x53 reserved */
562         .quad 0x0000000000000000        /* 0x5b reserved */
563  
564 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
565 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
566 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
567 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
568 +#ifdef CONFIG_PAX_KERNEXEC
569 +       .quad 0xc0cf9b400000ffff        /* 0x60 kernel 4GB code at 0xc0400000 */
570 +#else
571 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
572 +#endif
573 +
574 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
575 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
576 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
577  
578         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
579         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
580  
581         /* Segments used for calling PnP BIOS */
582 -       .quad 0x00c09a0000000000        /* 0x90 32-bit code */
583 -       .quad 0x00809a0000000000        /* 0x98 16-bit code */
584 -       .quad 0x0080920000000000        /* 0xa0 16-bit data */
585 -       .quad 0x0080920000000000        /* 0xa8 16-bit data */
586 -       .quad 0x0080920000000000        /* 0xb0 16-bit data */
587 +       .quad 0x00c09b0000000000        /* 0x90 32-bit code */
588 +       .quad 0x00809b0000000000        /* 0x98 16-bit code */
589 +       .quad 0x0080930000000000        /* 0xa0 16-bit data */
590 +       .quad 0x0080930000000000        /* 0xa8 16-bit data */
591 +       .quad 0x0080930000000000        /* 0xb0 16-bit data */
592         /*
593          * The APM segments have byte granularity and their bases
594          * and limits are set at run time.
595          */
596 -       .quad 0x00409a0000000000        /* 0xb8 APM CS    code */
597 -       .quad 0x00009a0000000000        /* 0xc0 APM CS 16 code (16 bit) */
598 -       .quad 0x0040920000000000        /* 0xc8 APM DS    data */
599 +       .quad 0x00409b0000000000        /* 0xb8 APM CS    code */
600 +       .quad 0x00009b0000000000        /* 0xc0 APM CS 16 code (16 bit) */
601 +       .quad 0x0040930000000000        /* 0xc8 APM DS    data */
602  
603         .quad 0x0000000000000000        /* 0xd0 - unused */
604         .quad 0x0000000000000000        /* 0xd8 - unused */
605 diff -uNr linux-2.6.8/arch/i386/kernel/ioport.c linux-2.6.8.grsecurity/arch/i386/kernel/ioport.c
606 --- linux-2.6.8/arch/i386/kernel/ioport.c       2004-08-14 07:36:57.000000000 +0200
607 +++ linux-2.6.8.grsecurity/arch/i386/kernel/ioport.c    2004-08-16 17:06:17.793233864 +0200
608 @@ -15,6 +15,7 @@
609  #include <linux/stddef.h>
610  #include <linux/slab.h>
611  #include <linux/thread_info.h>
612 +#include <linux/grsecurity.h>
613  
614  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
615  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
616 @@ -62,9 +63,16 @@
617  
618         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
619                 return -EINVAL;
620 +#ifdef CONFIG_GRKERNSEC_IO
621 +       if (turn_on) {
622 +               gr_handle_ioperm();
623 +#else
624         if (turn_on && !capable(CAP_SYS_RAWIO))
625 +#endif
626                 return -EPERM;
627 -
628 +#ifdef CONFIG_GRKERNSEC_IO
629 +       }
630 +#endif
631         /*
632          * If it's the first ioperm() call in this thread's lifetime, set the
633          * IO bitmap up. ioperm() is much less timing critical than clone(),
634 @@ -115,8 +123,13 @@
635                 return -EINVAL;
636         /* Trying to gain more privileges? */
637         if (level > old) {
638 +#ifdef CONFIG_GRKERNSEC_IO
639 +               gr_handle_iopl();
640 +               return -EPERM;
641 +#else
642                 if (!capable(CAP_SYS_RAWIO))
643                         return -EPERM;
644 +#endif
645         }
646         regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
647         /* Make sure we return the long way (not sysenter) */
648 diff -uNr linux-2.6.8/arch/i386/kernel/ldt.c linux-2.6.8.grsecurity/arch/i386/kernel/ldt.c
649 --- linux-2.6.8/arch/i386/kernel/ldt.c  2004-08-14 07:37:26.000000000 +0200
650 +++ linux-2.6.8.grsecurity/arch/i386/kernel/ldt.c       2004-08-16 17:06:17.801232648 +0200
651 @@ -102,6 +102,19 @@
652                 retval = copy_ldt(&mm->context, &old_mm->context);
653                 up(&old_mm->context.sem);
654         }
655 +
656 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
657 +       if (!mm->context.user_cs_limit) {
658 +               mm->context.user_cs_base = 0UL;
659 +               mm->context.user_cs_limit = ~0UL;
660 +
661 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
662 +               cpus_clear(mm->context.cpu_user_cs_mask);
663 +#endif
664 +
665 +       }
666 +#endif
667 +
668         return retval;
669  }
670  
671 @@ -154,7 +167,7 @@
672  {
673         int err;
674         unsigned long size;
675 -       void *address;
676 +       const void *address;
677  
678         err = 0;
679         address = &default_ldt[0];
680 @@ -211,6 +224,13 @@
681                 }
682         }
683  
684 +#ifdef CONFIG_PAX_SEGMEXEC
685 +       if ((current->flags & PF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) {
686 +               error = -EINVAL;
687 +               goto out_unlock;
688 +       }
689 +#endif
690 +
691         entry_1 = LDT_entry_a(&ldt_info);
692         entry_2 = LDT_entry_b(&ldt_info);
693         if (oldmode)
694 diff -uNr linux-2.6.8/arch/i386/kernel/process.c linux-2.6.8.grsecurity/arch/i386/kernel/process.c
695 --- linux-2.6.8/arch/i386/kernel/process.c      2004-08-14 07:36:09.000000000 +0200
696 +++ linux-2.6.8.grsecurity/arch/i386/kernel/process.c   2004-08-16 17:12:06.850169144 +0200
697 @@ -352,7 +352,7 @@
698         struct task_struct *tsk;
699         int err;
700  
701 -       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
702 +       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info - sizeof(unsigned long))) - 1;
703         *childregs = *regs;
704         childregs->eax = 0;
705         childregs->esp = esp;
706 @@ -454,9 +454,8 @@
707  int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
708  {
709         struct pt_regs ptregs;
710 -       
711 -       ptregs = *(struct pt_regs *)
712 -               ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs));
713 +
714 +       ptregs = *(struct pt_regs *)(tsk->thread.esp0 - sizeof(ptregs));
715         ptregs.xcs &= 0xffff;
716         ptregs.xds &= 0xffff;
717         ptregs.xes &= 0xffff;
718 @@ -509,10 +508,18 @@
719         int cpu = smp_processor_id();
720         struct tss_struct *tss = init_tss + cpu;
721  
722 +#ifdef CONFIG_PAX_KERNEXEC
723 +       unsigned long flags, cr3;
724 +#endif
725 +
726         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
727  
728         __unlazy_fpu(prev_p);
729  
730 +#ifdef CONFIG_PAX_KERNEXEC
731 +       pax_open_kernel(flags, cr3);
732 +#endif
733 +
734         /*
735          * Reload esp0, LDT and the page table pointer:
736          */
737 @@ -523,6 +530,10 @@
738          */
739         load_TLS(next, cpu);
740  
741 +#ifdef CONFIG_PAX_KERNEXEC
742 +       pax_close_kernel(flags, cr3);
743 +#endif
744 +
745         /*
746          * Save away %fs and %gs. No need to save %es and %ds, as
747          * those are always kernel segments while inside the kernel.
748 @@ -688,6 +699,10 @@
749         struct desc_struct *desc;
750         int cpu, idx;
751  
752 +#ifdef CONFIG_PAX_KERNEXEC
753 +       unsigned long flags, cr3;
754 +#endif
755 +
756         if (copy_from_user(&info, u_info, sizeof(info)))
757                 return -EFAULT;
758         idx = info.entry_number;
759 @@ -721,8 +736,17 @@
760                 desc->a = LDT_entry_a(&info);
761                 desc->b = LDT_entry_b(&info);
762         }
763 +
764 +#ifdef CONFIG_PAX_KERNEXEC
765 +       pax_open_kernel(flags, cr3);
766 +#endif
767 +
768         load_TLS(t, cpu);
769  
770 +#ifdef CONFIG_PAX_KERNEXEC
771 +       pax_close_kernel(flags, cr3);
772 +#endif
773 +
774         put_cpu();
775  
776         return 0;
777 @@ -776,3 +800,29 @@
778         return 0;
779  }
780  
781 +#ifdef CONFIG_PAX_RANDKSTACK
782 +asmlinkage void pax_randomize_kstack(void)
783 +{
784 +       struct tss_struct *tss = init_tss + smp_processor_id();
785 +       unsigned long time;
786 +
787 +#ifdef CONFIG_PAX_SOFTMODE
788 +       if (!pax_aslr)
789 +               return;
790 +#endif
791 +
792 +       rdtscl(time);
793 +
794 +       /* P4 seems to return a 0 LSB, ignore it */
795 +#ifdef CONFIG_MPENTIUM4
796 +       time &= 0x3EUL;
797 +       time <<= 1;
798 +#else
799 +       time &= 0x1FUL;
800 +       time <<= 2;
801 +#endif
802 +
803 +       tss->esp0 ^= time;
804 +       current->thread.esp0 = tss->esp0;
805 +}
806 +#endif
807 diff -uNr linux-2.6.8/arch/i386/kernel/ptrace.c linux-2.6.8.grsecurity/arch/i386/kernel/ptrace.c
808 --- linux-2.6.8/arch/i386/kernel/ptrace.c       2004-08-14 07:36:33.000000000 +0200
809 +++ linux-2.6.8.grsecurity/arch/i386/kernel/ptrace.c    2004-08-16 17:06:17.838227024 +0200
810 @@ -15,6 +15,7 @@
811  #include <linux/user.h>
812  #include <linux/security.h>
813  #include <linux/audit.h>
814 +#include <linux/grsecurity.h>
815  
816  #include <asm/uaccess.h>
817  #include <asm/pgtable.h>
818 @@ -264,6 +265,9 @@
819         if (pid == 1)           /* you may not mess with init */
820                 goto out_tsk;
821  
822 +       if (gr_handle_ptrace(child, request))
823 +               goto out_tsk;
824 +
825         if (request == PTRACE_ATTACH) {
826                 ret = ptrace_attach(child);
827                 goto out_tsk;
828 @@ -342,6 +346,17 @@
829                           if(addr == (long) &dummy->u_debugreg[5]) break;
830                           if(addr < (long) &dummy->u_debugreg[4] &&
831                              ((unsigned long) data) >= TASK_SIZE-3) break;
832 +
833 +#ifdef CONFIG_GRKERNSEC
834 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
835 +                            addr <= (long) &dummy->u_debugreg[3]){
836 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
837 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
838 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
839 +                               if((type & 1) && (data & align))
840 +                                       break;
841 +                         }
842 +#endif
843                           
844                           if(addr == (long) &dummy->u_debugreg[7]) {
845                                   data &= ~DR_CONTROL_RESERVED;
846 diff -uNr linux-2.6.8/arch/i386/kernel/reboot.c linux-2.6.8.grsecurity/arch/i386/kernel/reboot.c
847 --- linux-2.6.8/arch/i386/kernel/reboot.c       2004-08-14 07:36:44.000000000 +0200
848 +++ linux-2.6.8.grsecurity/arch/i386/kernel/reboot.c    2004-08-16 17:06:17.843226264 +0200
849 @@ -152,18 +152,18 @@
850     doesn't work with at least one type of 486 motherboard.  It is easy
851     to stop this code working; hence the copious comments. */
852  
853 -static unsigned long long
854 +static const unsigned long long
855  real_mode_gdt_entries [3] =
856  {
857         0x0000000000000000ULL,  /* Null descriptor */
858 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
859 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
860 +       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
861 +       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
862  };
863  
864  static struct
865  {
866         unsigned short       size __attribute__ ((packed));
867 -       unsigned long long * base __attribute__ ((packed));
868 +       const unsigned long long * base __attribute__ ((packed));
869  }
870  real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
871  real_mode_idt = { 0x3ff, NULL },
872 diff -uNr linux-2.6.8/arch/i386/kernel/setup.c linux-2.6.8.grsecurity/arch/i386/kernel/setup.c
873 --- linux-2.6.8/arch/i386/kernel/setup.c        2004-08-14 07:36:57.000000000 +0200
874 +++ linux-2.6.8.grsecurity/arch/i386/kernel/setup.c     2004-08-16 17:06:17.864223072 +0200
875 @@ -1326,7 +1326,7 @@
876  
877         code_resource.start = virt_to_phys(_text);
878         code_resource.end = virt_to_phys(_etext)-1;
879 -       data_resource.start = virt_to_phys(_etext);
880 +       data_resource.start = virt_to_phys(_data);
881         data_resource.end = virt_to_phys(_edata)-1;
882  
883         parse_cmdline_early(cmdline_p);
884 @@ -1386,6 +1386,15 @@
885  #endif
886  }
887  
888 +#ifdef CONFIG_PAX_SOFTMODE
889 +static int __init setup_pax_softmode(char *str)
890 +{
891 +       get_option (&str, &pax_softmode);
892 +       return 1;
893 +}
894 +__setup("pax_softmode=", setup_pax_softmode);
895 +#endif
896 +
897  #include "setup_arch_post.h"
898  /*
899   * Local Variables:
900 diff -uNr linux-2.6.8/arch/i386/kernel/signal.c linux-2.6.8.grsecurity/arch/i386/kernel/signal.c
901 --- linux-2.6.8/arch/i386/kernel/signal.c       2004-08-14 07:36:57.000000000 +0200
902 +++ linux-2.6.8.grsecurity/arch/i386/kernel/signal.c    2004-08-16 17:06:17.870222160 +0200
903 @@ -371,7 +371,17 @@
904         if (err)
905                 goto give_sigsegv;
906  
907 +#ifdef CONFIG_PAX_NOVSYSCALL
908 +       restorer = frame->retcode;
909 +#else
910         restorer = &__kernel_sigreturn;
911 +
912 +#ifdef CONFIG_PAX_SEGMEXEC
913 +       if (current->flags & PF_PAX_SEGMEXEC)
914 +               restorer -= SEGMEXEC_TASK_SIZE;
915 +#endif
916 +#endif
917 +
918         if (ka->sa.sa_flags & SA_RESTORER)
919                 restorer = ka->sa.sa_restorer;
920  
921 @@ -454,7 +464,18 @@
922                 goto give_sigsegv;
923  
924         /* Set up to return from userspace.  */
925 +
926 +#ifdef CONFIG_PAX_NOVSYSCALL
927 +       restorer = frame->retcode;
928 +#else
929         restorer = &__kernel_rt_sigreturn;
930 +
931 +#ifdef CONFIG_PAX_SEGMEXEC
932 +       if (current->flags & PF_PAX_SEGMEXEC)
933 +               restorer -= SEGMEXEC_TASK_SIZE;
934 +#endif
935 +#endif
936 +
937         if (ka->sa.sa_flags & SA_RESTORER)
938                 restorer = ka->sa.sa_restorer;
939         err |= __put_user(restorer, &frame->pretcode);
940 diff -uNr linux-2.6.8/arch/i386/kernel/sysenter.c linux-2.6.8.grsecurity/arch/i386/kernel/sysenter.c
941 --- linux-2.6.8/arch/i386/kernel/sysenter.c     2004-08-14 07:38:09.000000000 +0200
942 +++ linux-2.6.8.grsecurity/arch/i386/kernel/sysenter.c  2004-08-16 17:06:17.889219272 +0200
943 @@ -41,6 +41,7 @@
944  extern const char vsyscall_int80_start, vsyscall_int80_end;
945  extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
946  
947 +#ifndef CONFIG_PAX_NOVSYSCALL
948  static int __init sysenter_setup(void)
949  {
950         unsigned long page = get_zeroed_page(GFP_ATOMIC);
951 @@ -63,3 +64,4 @@
952  }
953  
954  __initcall(sysenter_setup);
955 +#endif
956 diff -uNr linux-2.6.8/arch/i386/kernel/sys_i386.c linux-2.6.8.grsecurity/arch/i386/kernel/sys_i386.c
957 --- linux-2.6.8/arch/i386/kernel/sys_i386.c     2004-08-14 07:38:08.000000000 +0200
958 +++ linux-2.6.8.grsecurity/arch/i386/kernel/sys_i386.c  2004-08-16 17:06:17.887219576 +0200
959 @@ -19,6 +19,7 @@
960  #include <linux/mman.h>
961  #include <linux/file.h>
962  #include <linux/utsname.h>
963 +#include <linux/grsecurity.h>
964  
965  #include <asm/uaccess.h>
966  #include <asm/ipc.h>
967 @@ -49,6 +50,11 @@
968         int error = -EBADF;
969         struct file * file = NULL;
970  
971 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
972 +       if (flags & MAP_MIRROR)
973 +               return -EINVAL;
974 +#endif
975 +
976         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
977         if (!(flags & MAP_ANONYMOUS)) {
978                 file = fget(fd);
979 @@ -56,6 +62,12 @@
980                         goto out;
981         }
982  
983 +       if (gr_handle_mmap(file, prot)) {
984 +               fput(file);
985 +               error = -EACCES;
986 +               goto out;
987 +       }
988 +
989         down_write(&current->mm->mmap_sem);
990         error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
991         up_write(&current->mm->mmap_sem);
992 @@ -106,6 +118,77 @@
993         return err;
994  }
995  
996 +unsigned long
997 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
998 +               unsigned long len, unsigned long pgoff, unsigned long flags)
999 +{
1000 +       struct mm_struct *mm = current->mm;
1001 +       struct vm_area_struct *vma;
1002 +       unsigned long start_addr, start_mmap, task_unmapped_base, task_size = TASK_SIZE;
1003 +
1004 +#ifdef CONFIG_PAX_SEGMEXEC
1005 +       if (current->flags & PF_PAX_SEGMEXEC)
1006 +               task_size = SEGMEXEC_TASK_SIZE;
1007 +#endif
1008 +
1009 +       if (len > task_size)
1010 +               return -ENOMEM;
1011 +
1012 +#ifdef CONFIG_PAX_RANDMMAP
1013 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
1014 +#endif
1015 +
1016 +       if (addr) {
1017 +               addr = PAGE_ALIGN(addr);
1018 +               vma = find_vma(mm, addr);
1019 +               if (task_size - len >= addr &&
1020 +                   (!vma || addr + len <= vma->vm_start))
1021 +                       return addr;
1022 +       }
1023 +       start_addr = addr = mm->free_area_cache;
1024 +       start_mmap = PAGE_ALIGN(task_size/3);
1025 +       task_unmapped_base = TASK_UNMAPPED_BASE;
1026 +
1027 +#ifdef CONFIG_PAX_RANDMMAP
1028 +       if (current->flags & PF_PAX_RANDMMAP) {
1029 +               start_mmap += mm->delta_mmap;
1030 +               task_unmapped_base += mm->delta_mmap;
1031 +       }
1032 +#endif
1033 +
1034 +       if (!(flags & MAP_EXECUTABLE) && start_addr < start_mmap)
1035 +               start_addr = addr = start_mmap;
1036 +       else if ((flags & MAP_EXECUTABLE) && start_addr >= start_mmap)
1037 +               start_addr = addr = task_unmapped_base;
1038 +
1039 +full_search:
1040 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
1041 +               /* At this point:  (!vma || addr < vma->vm_end). */
1042 +               if (task_size - len < addr) {
1043 +                       /*
1044 +                        * Start a new search - just in case we missed
1045 +                        * some holes.
1046 +                        */
1047 +                       if (start_addr != task_unmapped_base) {
1048 +                               start_addr = addr = task_unmapped_base;
1049 +                               goto full_search;
1050 +                       }
1051 +                       return -ENOMEM;
1052 +               }
1053 +               if (!vma || (addr + len <= vma->vm_start && (addr + len <= mm->start_brk || start_mmap <= addr))) {
1054 +                       /*
1055 +                        * Remember the place where we stopped the search:
1056 +                        */
1057 +                       mm->free_area_cache = addr + len;
1058 +                       return addr;
1059 +               }
1060 +               if (addr < start_mmap && addr + len > mm->start_brk) {
1061 +                       addr = start_mmap;
1062 +                       goto full_search;
1063 +               } else
1064 +                       addr = vma->vm_end;
1065 +       }
1066 +}
1067  
1068  struct sel_arg_struct {
1069         unsigned long n;
1070 diff -uNr linux-2.6.8/arch/i386/kernel/trampoline.S linux-2.6.8.grsecurity/arch/i386/kernel/trampoline.S
1071 --- linux-2.6.8/arch/i386/kernel/trampoline.S   2004-08-14 07:36:56.000000000 +0200
1072 +++ linux-2.6.8.grsecurity/arch/i386/kernel/trampoline.S        2004-08-16 17:06:17.891218968 +0200
1073 @@ -58,7 +58,7 @@
1074         inc     %ax             # protected mode (PE) bit
1075         lmsw    %ax             # into protected mode
1076         # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S
1077 -       ljmpl   $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET)
1078 +       ljmpl   $__BOOT_CS, $(startup_32_smp+__KERNEL_TEXT_OFFSET-__PAGE_OFFSET)
1079  
1080         # These need to be in the same 64K segment as the above;
1081         # hence we don't use the boot_gdt_descr defined in head.S
1082 diff -uNr linux-2.6.8/arch/i386/kernel/traps.c linux-2.6.8.grsecurity/arch/i386/kernel/traps.c
1083 --- linux-2.6.8/arch/i386/kernel/traps.c        2004-08-14 07:36:17.000000000 +0200
1084 +++ linux-2.6.8.grsecurity/arch/i386/kernel/traps.c     2004-08-16 17:06:17.919214712 +0200
1085 @@ -26,6 +26,7 @@
1086  #include <linux/kallsyms.h>
1087  #include <linux/ptrace.h>
1088  #include <linux/version.h>
1089 +#include <linux/binfmts.h>
1090  
1091  #ifdef CONFIG_EISA
1092  #include <linux/ioport.h>
1093 @@ -58,18 +59,13 @@
1094  asmlinkage void lcall7(void);
1095  asmlinkage void lcall27(void);
1096  
1097 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1098 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1099                 { 0, 0 }, { 0, 0 } };
1100  
1101  /* Do we ignore FPU interrupts ? */
1102  char ignore_fpu_irq = 0;
1103  
1104 -/*
1105 - * The IDT has to be page-aligned to simplify the Pentium
1106 - * F0 0F bug workaround.. We have a special link segment
1107 - * for this.
1108 - */
1109 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
1110 +extern struct desc_struct idt_table[256];
1111  
1112  asmlinkage void divide_error(void);
1113  asmlinkage void debug(void);
1114 @@ -107,13 +103,15 @@
1115                          unsigned long ebp)
1116  {
1117         unsigned long addr;
1118 +       int i = kstack_depth_to_print;
1119  
1120 -       while (valid_stack_ptr(task, (void *)ebp)) {
1121 +       while (i && valid_stack_ptr(task, (void *)ebp)) {
1122                 addr = *(unsigned long *)(ebp + 4);
1123                 printk(" [<%08lx>] ", addr);
1124                 print_symbol("%s", addr);
1125                 printk("\n");
1126                 ebp = *(unsigned long *)ebp;
1127 +               --i;
1128         }
1129  }
1130  #else
1131 @@ -239,14 +237,23 @@
1132                 show_stack(NULL, (unsigned long*)esp);
1133  
1134                 printk("Code: ");
1135 +
1136 +#ifndef CONFIG_PAX_KERNEXEC
1137                 if(regs->eip < PAGE_OFFSET)
1138                         goto bad;
1139 +#endif
1140  
1141                 for(i=0;i<20;i++)
1142                 {
1143                         unsigned char c;
1144 +
1145 +#ifdef CONFIG_PAX_KERNEXEC
1146 +                       if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) {
1147 +#else
1148                         if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
1149  bad:
1150 +#endif
1151 +
1152                                 printk(" Bad EIP value.");
1153                                 break;
1154                         }
1155 @@ -269,8 +276,13 @@
1156  
1157         eip = regs->eip;
1158  
1159 +#ifdef CONFIG_PAX_KERNEXEC
1160 +       eip += __KERNEL_TEXT_OFFSET;
1161 +#else
1162         if (eip < PAGE_OFFSET)
1163                 goto no_bug;
1164 +#endif
1165 +
1166         if (__get_user(ud2, (unsigned short *)eip))
1167                 goto no_bug;
1168         if (ud2 != 0x0b0f)
1169 @@ -278,7 +290,13 @@
1170         if (__get_user(line, (unsigned short *)(eip + 2)))
1171                 goto bug;
1172         if (__get_user(file, (char **)(eip + 4)) ||
1173 +
1174 +#ifdef CONFIG_PAX_KERNEXEC
1175 +               __get_user(c, file + __KERNEL_TEXT_OFFSET))
1176 +#else
1177                 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
1178 +#endif
1179 +
1180                 file = "<bad filename>";
1181  
1182         printk("------------[ cut here ]------------\n");
1183 @@ -440,6 +458,22 @@
1184         if (!(regs->xcs & 3))
1185                 goto gp_in_kernel;
1186  
1187 +#ifdef CONFIG_PAX_PAGEEXEC
1188 +       if ((current->flags & PF_PAX_PAGEEXEC)) {
1189 +               struct mm_struct *mm = current->mm;
1190 +               unsigned long limit;
1191 +
1192 +               down_write(&mm->mmap_sem);
1193 +               limit = mm->context.user_cs_limit;
1194 +               if (limit < TASK_SIZE) {
1195 +                       track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
1196 +                       up_write(&mm->mmap_sem);
1197 +                       return;
1198 +               }
1199 +               up_write(&mm->mmap_sem);
1200 +       }
1201 +#endif
1202 +
1203         current->thread.error_code = error_code;
1204         current->thread.trap_no = 13;
1205         force_sig(SIGSEGV, current);
1206 @@ -451,8 +485,16 @@
1207         return;
1208  
1209  gp_in_kernel:
1210 -       if (!fixup_exception(regs))
1211 +       if (!fixup_exception(regs)) {
1212 +
1213 +#ifdef CONFIG_PAX_KERNEXEC
1214 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
1215 +                       die("PAX: suspicious general protection fault", regs, error_code);
1216 +               else
1217 +#endif
1218 +
1219                 die("general protection fault", regs, error_code);
1220 +       }
1221  }
1222  
1223  static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
1224 @@ -885,7 +927,7 @@
1225         _set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
1226  }
1227  
1228 -static void __init set_call_gate(void *a, void *addr)
1229 +static void __init set_call_gate(const void *a, void *addr)
1230  {
1231         _set_gate(a,12,3,addr,__KERNEL_CS);
1232  }
1233 diff -uNr linux-2.6.8/arch/i386/kernel/vmlinux.lds.S linux-2.6.8.grsecurity/arch/i386/kernel/vmlinux.lds.S
1234 --- linux-2.6.8/arch/i386/kernel/vmlinux.lds.S  2004-08-14 07:36:32.000000000 +0200
1235 +++ linux-2.6.8.grsecurity/arch/i386/kernel/vmlinux.lds.S       2004-08-16 17:06:17.921214408 +0200
1236 @@ -2,7 +2,12 @@
1237   * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
1238   */
1239  
1240 +#include <linux/config.h>
1241 +
1242  #include <asm-generic/vmlinux.lds.h>
1243 +#include <asm-i386/page.h>
1244 +#include <asm-i386/segment.h>
1245 +
1246  #include <asm/thread_info.h>
1247  
1248  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
1249 @@ -11,26 +16,16 @@
1250  jiffies = jiffies_64;
1251  SECTIONS
1252  {
1253 -  . = 0xC0000000 + 0x100000;
1254 -  /* read-only */
1255 -  _text = .;                   /* Text and read-only data */
1256 -  .text : {
1257 -       *(.text)
1258 -       SCHED_TEXT
1259 -       *(.fixup)
1260 -       *(.gnu.warning)
1261 -       } = 0x9090
1262 -
1263 -  _etext = .;                  /* End of text section */
1264 -
1265 -  . = ALIGN(16);               /* Exception table */
1266 -  __start___ex_table = .;
1267 -  __ex_table : { *(__ex_table) }
1268 -  __stop___ex_table = .;
1269 -
1270 -  RODATA
1271 +  . = __PAGE_OFFSET + 0x100000;
1272 +  .text.startup : {
1273 +       BYTE(0xEA) /* jmp far */
1274 +       LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
1275 +       SHORT(__BOOT_CS)
1276 +       }
1277  
1278    /* writeable */
1279 +  . = ALIGN(32);
1280 +  _data = .;
1281    .data : {                    /* Data */
1282         *(.data)
1283         CONSTRUCTORS
1284 @@ -42,25 +37,29 @@
1285    . = ALIGN(4096);
1286    __nosave_end = .;
1287  
1288 -  . = ALIGN(4096);
1289 -  .data.page_aligned : { *(.data.idt) }
1290 -
1291    . = ALIGN(32);
1292    .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1293  
1294 -  _edata = .;                  /* End of data section */
1295 -
1296    . = ALIGN(THREAD_SIZE);      /* init_task */
1297    .data.init_task : { *(.data.init_task) }
1298  
1299 +  . = ALIGN(4096);
1300 +  .data.page_aligned : { *(.data.swapper_pg_dir) }
1301 +
1302 +  _edata = .;                  /* End of data section */
1303 +
1304 +  __bss_start = .;             /* BSS */
1305 +  .bss : {
1306 +       *(.bss.page_aligned)
1307 +       *(.bss)
1308 +       LONG(0)
1309 +       }
1310 +  . = ALIGN(4);
1311 +  __bss_stop = .; 
1312 +
1313    /* will be freed after init */
1314    . = ALIGN(4096);             /* Init code and data */
1315    __init_begin = .;
1316 -  .init.text : { 
1317 -       _sinittext = .;
1318 -       *(.init.text)
1319 -       _einittext = .;
1320 -  }
1321    .init.data : { *(.init.data) }
1322    . = ALIGN(16);
1323    __setup_start = .;
1324 @@ -89,9 +88,13 @@
1325    .altinstructions : { *(.altinstructions) } 
1326    __alt_instructions_end = .; 
1327   .altinstr_replacement : { *(.altinstr_replacement) } 
1328 +
1329 +#ifndef CONFIG_PAX_KERNEXEC
1330    /* .exit.text is discard at runtime, not link time, to deal with references
1331       from .altinstructions and .eh_frame */
1332    .exit.text : { *(.exit.text) }
1333 +#endif
1334 +
1335    .exit.data : { *(.exit.data) }
1336    . = ALIGN(4096);
1337    __initramfs_start = .;
1338 @@ -101,17 +104,67 @@
1339    __per_cpu_start = .;
1340    .data.percpu  : { *(.data.percpu) }
1341    __per_cpu_end = .;
1342 +
1343 +  /* read-only */
1344 +
1345 +#ifdef CONFIG_PAX_KERNEXEC
1346 +  __init_text_start = .;
1347 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT (__init_text_start) {
1348 +       _sinittext = .;
1349 +       *(.init.text)
1350 +       _einittext = .;
1351 +       *(.exit.text)
1352 +       . = ALIGN(4*1024*1024) - 1;
1353 +       BYTE(0)
1354 +  }
1355    . = ALIGN(4096);
1356 -  __init_end = .;
1357 +  __init_end = . + __KERNEL_TEXT_OFFSET;
1358    /* freed after init ends here */
1359 -       
1360 -  __bss_start = .;             /* BSS */
1361 -  .bss : {
1362 -       *(.bss.page_aligned)
1363 -       *(.bss)
1364 +
1365 +/*
1366 + * PaX: this must be kept in synch with the KERNEL_CS base
1367 + * in the GDTs in arch/i386/kernel/head.S
1368 + */
1369 +  _text = .;                   /* Text and read-only data */
1370 +  .text : AT (. + __KERNEL_TEXT_OFFSET) {
1371 +#else
1372 +  .init.text : {
1373 +       _sinittext = .;
1374 +       *(.init.text)
1375 +       _einittext = .;
1376    }
1377 -  . = ALIGN(4);
1378 -  __bss_stop = .; 
1379 +  . = ALIGN(4096);
1380 +  __init_end = .;
1381 +  /* freed after init ends here */
1382 +
1383 +  _text = .;                   /* Text and read-only data */
1384 +  .text : {
1385 +#endif
1386 +
1387 +       *(.text)
1388 +       SCHED_TEXT
1389 +       *(.fixup)
1390 +       *(.gnu.warning)
1391 +       } = 0x9090
1392 +
1393 +  _etext = .;                  /* End of text section */
1394 +  . += __KERNEL_TEXT_OFFSET;
1395 +  . = ALIGN(16);               /* Exception table */
1396 +  __start___ex_table = .;
1397 +  __ex_table : { *(__ex_table) }
1398 +  __stop___ex_table = .;
1399 +
1400 +  . = ALIGN(4096);
1401 +  .rodata.page_aligned : {
1402 +       *(.rodata.empty_zero_page)
1403 +       *(.rodata.idt)
1404 +       }
1405 +
1406 +  RODATA
1407 +
1408 +#ifdef CONFIG_PAX_KERNEXEC
1409 +  . = ALIGN(4*1024*1024);
1410 +#endif
1411  
1412    _end = . ;
1413  
1414 diff -uNr linux-2.6.8/arch/i386/mm/fault.c linux-2.6.8.grsecurity/arch/i386/mm/fault.c
1415 --- linux-2.6.8/arch/i386/mm/fault.c    2004-08-14 07:36:10.000000000 +0200
1416 +++ linux-2.6.8.grsecurity/arch/i386/mm/fault.c 2004-08-16 17:18:30.449853128 +0200
1417 @@ -21,6 +21,9 @@
1418  #include <linux/vt_kern.h>             /* For unblank_screen() */
1419  #include <linux/highmem.h>
1420  #include <linux/module.h>
1421 +#include <linux/unistd.h>
1422 +#include <linux/compiler.h>
1423 +#include <linux/binfmts.h>
1424  
1425  #include <asm/system.h>
1426  #include <asm/uaccess.h>
1427 @@ -203,6 +206,27 @@
1428  
1429  asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
1430  
1431 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
1432 +static int pax_handle_fetch_fault(struct pt_regs *regs);
1433 +#endif
1434 +
1435 +#ifdef CONFIG_PAX_PAGEEXEC
1436 +/* PaX: called with the page_table_lock spinlock held */
1437 +static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
1438 +{
1439 +       pgd_t *pgd;
1440 +       pmd_t *pmd;
1441 +
1442 +       pgd = pgd_offset(mm, address);
1443 +       if (!pgd || !pgd_present(*pgd))
1444 +               return 0;
1445 +       pmd = pmd_offset(pgd, address);
1446 +       if (!pmd || !pmd_present(*pmd))
1447 +               return 0;
1448 +       return pte_offset_map(pmd, address);
1449 +}
1450 +#endif
1451 +
1452  /*
1453   * This routine handles page faults.  It determines the address,
1454   * and the problem, and then passes it off to one of the appropriate
1455 @@ -223,6 +247,11 @@
1456         int write;
1457         siginfo_t info;
1458  
1459 +#ifdef CONFIG_PAX_PAGEEXEC
1460 +       pte_t *pte;
1461 +       unsigned char pte_mask1, pte_mask2;
1462 +#endif
1463 +
1464         /* get the address */
1465         __asm__("movl %%cr2,%0":"=r" (address));
1466  
1467 @@ -266,6 +295,91 @@
1468         if (in_atomic() || !mm)
1469                 goto bad_area_nosemaphore;
1470  
1471 +#ifdef CONFIG_PAX_PAGEEXEC
1472 +       if (unlikely(!(tsk->flags & PF_PAX_PAGEEXEC) || (error_code & 5) != 5))
1473 +               goto not_pax_fault;
1474 +
1475 +       /* PaX: it's our fault, let's handle it if we can */
1476 +
1477 +       /* PaX: take a look at read faults before acquiring any locks */
1478 +       if (unlikely((error_code == 5) && (regs->eip == address))) {
1479 +               /* instruction fetch attempt from a protected page in user mode */
1480 +               switch (pax_handle_fetch_fault(regs)) {
1481 +
1482 +#ifdef CONFIG_PAX_RANDEXEC
1483 +               case 3:
1484 +                       return;
1485 +#endif
1486 +
1487 +#ifdef CONFIG_PAX_EMUTRAMP
1488 +               case 2:
1489 +                       return;
1490 +#endif
1491 +
1492 +               }
1493 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1494 +               do_exit(SIGKILL);
1495 +       }
1496 +
1497 +       spin_lock(&mm->page_table_lock);
1498 +       pte = pax_get_pte(mm, address);
1499 +       if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) {
1500 +               pte_unmap(pte);
1501 +               spin_unlock(&mm->page_table_lock);
1502 +               goto not_pax_fault;
1503 +       }
1504 +
1505 +       if (unlikely((error_code == 7) && !pte_write(*pte))) {
1506 +               /* write attempt to a protected page in user mode */
1507 +               pte_unmap(pte);
1508 +               spin_unlock(&mm->page_table_lock);
1509 +               goto not_pax_fault;
1510 +       }
1511 +
1512 +       pte_mask1 = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
1513 +
1514 +#ifdef CONFIG_SMP
1515 +       if (likely(cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)) && address >= get_limit(regs->xcs))
1516 +               pte_mask2 = 0;
1517 +       else
1518 +               pte_mask2 = _PAGE_USER;
1519 +#else
1520 +       pte_mask2 = (address >= get_limit(regs->xcs)) ? 0 : _PAGE_USER;
1521 +#endif
1522 +
1523 +       /*
1524 +        * PaX: fill DTLB with user rights and retry
1525 +        */
1526 +       __asm__ __volatile__ (
1527 +               "orb %2,%1\n"
1528 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
1529 +/*
1530 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
1531 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
1532 + * page fault when examined during a TLB load attempt. this is true not only
1533 + * for PTEs holding a non-present entry but also present entries that will
1534 + * raise a page fault (such as those set up by PaX, or the copy-on-write
1535 + * mechanism). in effect it means that we do *not* need to flush the TLBs
1536 + * for our target pages since their PTEs are simply not in the TLBs at all.
1537 +
1538 + * the best thing in omitting it is that we gain around 15-20% speed in the
1539 + * fast path of the page fault handler and can get rid of tracing since we
1540 + * can no longer flush unintended entries.
1541 + */
1542 +               "invlpg %0\n"
1543 +#endif
1544 +               "testb $0,%0\n"
1545 +               "xorb %3,%1\n"
1546 +               :
1547 +               : "m" (*(char*)address), "m" (*(char*)pte), "q" (pte_mask1), "q" (pte_mask2)
1548 +               : "memory", "cc");
1549 +       pte_unmap(pte);
1550 +       spin_unlock(&mm->page_table_lock);
1551 +       return;
1552 +
1553 +not_pax_fault:
1554 +#endif
1555 +
1556         /* When running in the kernel we expect faults to occur only to
1557          * addresses in user space.  All other faults represent errors in the
1558          * kernel and should generate an OOPS.  Unfortunatly, in the case of an
1559 @@ -382,6 +496,34 @@
1560                 if (is_prefetch(regs, address, error_code))
1561                         return;
1562  
1563 +#ifdef CONFIG_PAX_SEGMEXEC
1564 +               if (current->flags & PF_PAX_SEGMEXEC) {
1565 +
1566 +#if defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
1567 +                       if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
1568 +                               switch (pax_handle_fetch_fault(regs)) {
1569 +
1570 +#ifdef CONFIG_PAX_RANDEXEC
1571 +                               case 3:
1572 +                                       return;
1573 +#endif
1574 +
1575 +#ifdef CONFIG_PAX_EMUTRAMP
1576 +                               case 2:
1577 +                                       return;
1578 +#endif
1579 +
1580 +                               }
1581 +                       }
1582 +#endif
1583 +
1584 +                       if (address >= SEGMEXEC_TASK_SIZE) {
1585 +                               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1586 +                               do_exit(SIGKILL);
1587 +                       }
1588 +               }
1589 +#endif
1590 +
1591                 tsk->thread.cr2 = address;
1592                 /* Kernel addresses are always protection faults */
1593                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
1594 @@ -440,6 +582,13 @@
1595  #endif
1596         if (address < PAGE_SIZE)
1597                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
1598 +
1599 +#ifdef CONFIG_PAX_KERNEXEC
1600 +       else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET)
1601 +               printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
1602 +                                tsk->comm, tsk->pid, tsk->uid, tsk->euid);
1603 +#endif
1604 +
1605         else
1606                 printk(KERN_ALERT "Unable to handle kernel paging request");
1607         printk(" at virtual address %08lx\n",address);
1608 @@ -541,3 +690,249 @@
1609                 return;
1610         }
1611  }
1612 +
1613 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
1614 +/*
1615 + * PaX: decide what to do with offenders (regs->eip = fault address)
1616 + *
1617 + * returns 1 when task should be killed
1618 + *         2 when gcc trampoline was detected
1619 + *         3 when legitimate ET_EXEC was detected
1620 + */
1621 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1622 +{
1623 +
1624 +#ifdef CONFIG_PAX_EMUTRAMP
1625 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
1626 +#endif
1627 +
1628 +#if defined(CONFIG_PAX_RANDEXEC) || defined(CONFIG_PAX_EMUTRAMP)
1629 +       int err;
1630 +#endif
1631 +
1632 +#ifdef CONFIG_PAX_RANDEXEC
1633 +       if (current->flags & PF_PAX_RANDEXEC) {
1634 +               unsigned long esp_4;
1635 +
1636 +               if (regs->eip >= current->mm->start_code &&
1637 +                   regs->eip < current->mm->end_code)
1638 +               {
1639 +                       err = get_user(esp_4, (unsigned long*)(regs->esp-4UL));
1640 +                       if (err || esp_4 == regs->eip)
1641 +                               return 1;
1642 +
1643 +                       regs->eip += current->mm->delta_exec;
1644 +                       return 3;
1645 +               }
1646 +       }
1647 +#endif
1648 +
1649 +#ifdef CONFIG_PAX_EMUTRAMP
1650 +       do { /* PaX: gcc trampoline emulation #1 */
1651 +               unsigned char mov1, mov2;
1652 +               unsigned short jmp;
1653 +               unsigned long addr1, addr2, ret;
1654 +               unsigned short call;
1655 +
1656 +               err = get_user(mov1, (unsigned char *)regs->eip);
1657 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1658 +               err |= get_user(mov2, (unsigned char *)(regs->eip + 5));
1659 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1660 +               err |= get_user(jmp, (unsigned short *)(regs->eip + 10));
1661 +               err |= get_user(ret, (unsigned long *)regs->esp);
1662 +
1663 +               if (err)
1664 +                       break;
1665 +
1666 +               err = get_user(call, (unsigned short *)(ret-2));
1667 +               if (err)
1668 +                       break;
1669 +
1670 +               if ((mov1 & 0xF8) == 0xB8 &&
1671 +                   (mov2 & 0xF8) == 0xB8 &&
1672 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
1673 +                   (jmp & 0xF8FF) == 0xE0FF &&
1674 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
1675 +                   (call & 0xF8FF) == 0xD0FF &&
1676 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1677 +               {
1678 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
1679 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
1680 +                       regs->eip = addr2;
1681 +                       return 2;
1682 +               }
1683 +       } while (0);
1684 +
1685 +       do { /* PaX: gcc trampoline emulation #2 */
1686 +               unsigned char mov, jmp;
1687 +               unsigned long addr1, addr2, ret;
1688 +               unsigned short call;
1689 +
1690 +               err = get_user(mov, (unsigned char *)regs->eip);
1691 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1692 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1693 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1694 +               err |= get_user(ret, (unsigned long *)regs->esp);
1695 +
1696 +               if (err)
1697 +                       break;
1698 +
1699 +               err = get_user(call, (unsigned short *)(ret-2));
1700 +               if (err)
1701 +                       break;
1702 +
1703 +               if ((mov & 0xF8) == 0xB8 &&
1704 +                   jmp == 0xE9 &&
1705 +                   (call & 0xF8FF) == 0xD0FF &&
1706 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1707 +               {
1708 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1709 +                       regs->eip += addr2 + 10;
1710 +                       return 2;
1711 +               }
1712 +       } while (0);
1713 +
1714 +       do { /* PaX: gcc trampoline emulation #3 */
1715 +               unsigned char mov, jmp;
1716 +               char offset;
1717 +               unsigned long addr1, addr2, ret;
1718 +               unsigned short call;
1719 +
1720 +               err = get_user(mov, (unsigned char *)regs->eip);
1721 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1722 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1723 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1724 +               err |= get_user(ret, (unsigned long *)regs->esp);
1725 +
1726 +               if (err)
1727 +                       break;
1728 +
1729 +               err = get_user(call, (unsigned short *)(ret-3));
1730 +               err |= get_user(offset, (char *)(ret-1));
1731 +               if (err)
1732 +                       break;
1733 +
1734 +               if ((mov & 0xF8) == 0xB8 &&
1735 +                   jmp == 0xE9 &&
1736 +                   call == 0x55FF)
1737 +               {
1738 +                       unsigned long addr;
1739 +
1740 +                       err = get_user(addr, (unsigned long*)(regs->ebp + (unsigned long)(long)offset));
1741 +                       if (err || regs->eip != addr)
1742 +                               break;
1743 +
1744 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1745 +                       regs->eip += addr2 + 10;
1746 +                       return 2;
1747 +               }
1748 +       } while (0);
1749 +
1750 +       do { /* PaX: gcc trampoline emulation #4 */
1751 +               unsigned char mov, jmp, sib;
1752 +               char offset;
1753 +               unsigned long addr1, addr2, ret;
1754 +               unsigned short call;
1755 +
1756 +               err = get_user(mov, (unsigned char *)regs->eip);
1757 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1758 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1759 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1760 +               err |= get_user(ret, (unsigned long *)regs->esp);
1761 +
1762 +               if (err)
1763 +                       break;
1764 +
1765 +               err = get_user(call, (unsigned short *)(ret-4));
1766 +               err |= get_user(sib, (unsigned char *)(ret-2));
1767 +               err |= get_user(offset, (char *)(ret-1));
1768 +               if (err)
1769 +                       break;
1770 +
1771 +               if ((mov & 0xF8) == 0xB8 &&
1772 +                   jmp == 0xE9 &&
1773 +                   call == 0x54FF &&
1774 +                   sib == 0x24)
1775 +               {
1776 +                       unsigned long addr;
1777 +
1778 +                       err = get_user(addr, (unsigned long*)(regs->esp + 4 + (unsigned long)(long)offset));
1779 +                       if (err || regs->eip != addr)
1780 +                               break;
1781 +
1782 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1783 +                       regs->eip += addr2 + 10;
1784 +                       return 2;
1785 +               }
1786 +       } while (0);
1787 +
1788 +       do { /* PaX: gcc trampoline emulation #5 */
1789 +               unsigned char mov, jmp, sib;
1790 +               unsigned long addr1, addr2, ret, offset;
1791 +               unsigned short call;
1792 +
1793 +               err = get_user(mov, (unsigned char *)regs->eip);
1794 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1795 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1796 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1797 +               err |= get_user(ret, (unsigned long *)regs->esp);
1798 +
1799 +               if (err)
1800 +                       break;
1801 +
1802 +               err = get_user(call, (unsigned short *)(ret-7));
1803 +               err |= get_user(sib, (unsigned char *)(ret-5));
1804 +               err |= get_user(offset, (unsigned long *)(ret-4));
1805 +               if (err)
1806 +                       break;
1807 +
1808 +               if ((mov & 0xF8) == 0xB8 &&
1809 +                   jmp == 0xE9 &&
1810 +                   call == 0x94FF &&
1811 +                   sib == 0x24)
1812 +               {
1813 +                       unsigned long addr;
1814 +
1815 +                       err = get_user(addr, (unsigned long*)(regs->esp + 4 + offset));
1816 +                       if (err || regs->eip != addr)
1817 +                               break;
1818 +
1819 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1820 +                       regs->eip += addr2 + 10;
1821 +                       return 2;
1822 +               }
1823 +       } while (0);
1824 +#endif
1825 +
1826 +       return 1; /* PaX in action */
1827 +}
1828 +#endif
1829 +
1830 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1831 +void pax_report_insns(void *pc, void *sp)
1832 +{
1833 +       unsigned long i;
1834 +
1835 +       printk(KERN_ERR "PAX: bytes at PC: ");
1836 +       for (i = 0; i < 20; i++) {
1837 +               unsigned char c;
1838 +               if (get_user(c, (unsigned char*)pc+i)) {
1839 +                       printk("<invalid address>.");
1840 +                       break;
1841 +               }
1842 +               printk("%02x ", c);
1843 +       }
1844 +       printk("\n");
1845 +
1846 +       printk(KERN_ERR "PAX: bytes at SP: ");
1847 +       for (i = 0; i < 20; i++) {
1848 +               unsigned long c;
1849 +               if (get_user(c, (unsigned long*)sp+i)) {
1850 +                       printk("<invalid address>.");
1851 +                       break;
1852 +               }
1853 +               printk("%08lx ", c);
1854 +       }
1855 +       printk("\n");
1856 +}
1857 +#endif
1858 diff -uNr linux-2.6.8/arch/i386/mm/init.c linux-2.6.8.grsecurity/arch/i386/mm/init.c
1859 --- linux-2.6.8/arch/i386/mm/init.c     2004-08-14 07:37:38.000000000 +0200
1860 +++ linux-2.6.8.grsecurity/arch/i386/mm/init.c  2004-08-16 17:06:18.014200272 +0200
1861 @@ -39,6 +39,7 @@
1862  #include <asm/tlb.h>
1863  #include <asm/tlbflush.h>
1864  #include <asm/sections.h>
1865 +#include <asm/desc.h>
1866  
1867  DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
1868  unsigned long highstart_pfn, highend_pfn;
1869 @@ -513,6 +514,10 @@
1870  #endif
1871         __flush_tlb_all();
1872  
1873 +#ifdef CONFIG_PAX_KERNEXEC
1874 +       memcpy(kernexec_pg_dir, swapper_pg_dir, sizeof(kernexec_pg_dir));
1875 +#endif
1876 +
1877         kmap_init();
1878         zone_sizes_init();
1879  }
1880 @@ -607,7 +612,7 @@
1881         set_highmem_pages_init(bad_ppro);
1882  
1883         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
1884 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
1885 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
1886         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
1887  
1888         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
1889 @@ -706,6 +711,42 @@
1890                 totalram_pages++;
1891         }
1892         printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
1893 +
1894 +#ifdef CONFIG_PAX_KERNEXEC
1895 +       /* PaX: limit KERNEL_CS to actual size */
1896 +       {
1897 +               unsigned long limit;
1898 +               int cpu;
1899 +               pgd_t *pgd;
1900 +               pmd_t *pmd;
1901 +
1902 +               limit = (unsigned long)&_etext >> PAGE_SHIFT;
1903 +               for (cpu = 0; cpu < NR_CPUS; cpu++) {
1904 +                       cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].a = (cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
1905 +                       cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].b = (cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
1906 +
1907 +#ifdef CONFIG_PCI_BIOS
1908 +               printk(KERN_INFO "PAX: warning, PCI BIOS might still be in use, keeping flat KERNEL_CS.\n");
1909 +#endif
1910 +
1911 +               }
1912 +
1913 +       /* PaX: make KERNEL_CS read-only */
1914 +               for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
1915 +                       pgd = pgd_offset_k(addr);
1916 +                       pmd = pmd_offset(pgd, addr);
1917 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_GLOBAL));
1918 +               }
1919 +               memcpy(kernexec_pg_dir, swapper_pg_dir, sizeof(kernexec_pg_dir));
1920 +               for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
1921 +                       pgd = pgd_offset_k(addr);
1922 +                       pmd = pmd_offset(pgd, addr);
1923 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
1924 +               }
1925 +               flush_tlb_all();
1926 +       }
1927 +#endif
1928 +
1929  }
1930  
1931  #ifdef CONFIG_BLK_DEV_INITRD
1932 diff -uNr linux-2.6.8/arch/i386/pci/pcbios.c linux-2.6.8.grsecurity/arch/i386/pci/pcbios.c
1933 --- linux-2.6.8/arch/i386/pci/pcbios.c  2004-08-14 07:36:14.000000000 +0200
1934 +++ linux-2.6.8.grsecurity/arch/i386/pci/pcbios.c       2004-08-16 17:06:18.059193432 +0200
1935 @@ -6,7 +6,7 @@
1936  #include <linux/init.h>
1937  #include "pci.h"
1938  #include "pci-functions.h"
1939 -
1940 +#include <asm/desc.h>
1941  
1942  /* BIOS32 signature: "_32_" */
1943  #define BIOS32_SIGNATURE       (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
1944 @@ -33,6 +33,12 @@
1945   * and the PCI BIOS specification.
1946   */
1947  
1948 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
1949 +#define __FLAT_KERNEL_CS 0x20
1950 +#else
1951 +#define __FLAT_KERNEL_CS __KERNEL_CS
1952 +#endif
1953 +
1954  union bios32 {
1955         struct {
1956                 unsigned long signature;        /* _32_ */
1957 @@ -55,7 +61,7 @@
1958  static struct {
1959         unsigned long address;
1960         unsigned short segment;
1961 -} bios32_indirect = { 0, __KERNEL_CS };
1962 +} bios32_indirect = { 0, __FLAT_KERNEL_CS };
1963  
1964  /*
1965   * Returns the entry point for the given service, NULL on error
1966 @@ -96,7 +102,9 @@
1967  static struct {
1968         unsigned long address;
1969         unsigned short segment;
1970 -} pci_indirect = { 0, __KERNEL_CS };
1971 +} pci_indirect = { 0, __FLAT_KERNEL_CS };
1972 +
1973 +#undef __FLAT_KERNEL_CS
1974  
1975  static int pci_bios_present;
1976  
1977 diff -uNr linux-2.6.8/arch/ia64/ia32/binfmt_elf32.c linux-2.6.8.grsecurity/arch/ia64/ia32/binfmt_elf32.c
1978 --- linux-2.6.8/arch/ia64/ia32/binfmt_elf32.c   2004-08-14 07:37:42.000000000 +0200
1979 +++ linux-2.6.8.grsecurity/arch/ia64/ia32/binfmt_elf32.c        2004-08-16 17:06:18.110185680 +0200
1980 @@ -43,6 +43,17 @@
1981  
1982  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
1983  
1984 +#ifdef CONFIG_PAX_ASLR
1985 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
1986 +
1987 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
1988 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
1989 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
1990 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
1991 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
1992 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
1993 +#endif
1994 +
1995  /* Ugly but avoids duplication */
1996  #include "../../../fs/binfmt_elf.c"
1997  
1998 diff -uNr linux-2.6.8/arch/ia64/ia32/ia32priv.h linux-2.6.8.grsecurity/arch/ia64/ia32/ia32priv.h
1999 --- linux-2.6.8/arch/ia64/ia32/ia32priv.h       2004-08-14 07:38:08.000000000 +0200
2000 +++ linux-2.6.8.grsecurity/arch/ia64/ia32/ia32priv.h    2004-08-16 17:06:18.155178840 +0200
2001 @@ -323,7 +323,14 @@
2002  #define ELF_ARCH       EM_386
2003  
2004  #define IA32_PAGE_OFFSET       0xc0000000
2005 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
2006 +
2007 +#ifdef CONFIG_PAX_RANDUSTACK
2008 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
2009 +#else
2010 +#define __IA32_DELTA_STACK 0UL
2011 +#endif
2012 +
2013 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
2014  
2015  /*
2016   * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
2017 diff -uNr linux-2.6.8/arch/ia64/ia32/sys_ia32.c linux-2.6.8.grsecurity/arch/ia64/ia32/sys_ia32.c
2018 --- linux-2.6.8/arch/ia64/ia32/sys_ia32.c       2004-08-14 07:37:15.000000000 +0200
2019 +++ linux-2.6.8.grsecurity/arch/ia64/ia32/sys_ia32.c    2004-08-16 17:06:18.178175344 +0200
2020 @@ -942,6 +942,11 @@
2021  
2022         flags = a.flags;
2023  
2024 +#ifdef CONFIG_PAX_RANDEXEC
2025 +       if (flags & MAP_MIRROR)
2026 +               return -EINVAL;
2027 +#endif
2028 +
2029         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2030         if (!(flags & MAP_ANONYMOUS)) {
2031                 file = fget(a.fd);
2032 @@ -963,6 +968,11 @@
2033         struct file *file = NULL;
2034         unsigned long retval;
2035  
2036 +#ifdef CONFIG_PAX_RANDEXEC
2037 +       if (flags & MAP_MIRROR)
2038 +               return -EINVAL;
2039 +#endif
2040 +
2041         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2042         if (!(flags & MAP_ANONYMOUS)) {
2043                 file = fget(fd);
2044 diff -uNr linux-2.6.8/arch/ia64/kernel/ptrace.c linux-2.6.8.grsecurity/arch/ia64/kernel/ptrace.c
2045 --- linux-2.6.8/arch/ia64/kernel/ptrace.c       2004-08-14 07:38:08.000000000 +0200
2046 +++ linux-2.6.8.grsecurity/arch/ia64/kernel/ptrace.c    2004-08-16 17:06:18.251164248 +0200
2047 @@ -17,6 +17,7 @@
2048  #include <linux/smp_lock.h>
2049  #include <linux/user.h>
2050  #include <linux/security.h>
2051 +#include <linux/grsecurity.h>
2052  
2053  #include <asm/pgtable.h>
2054  #include <asm/processor.h>
2055 @@ -1314,6 +1315,9 @@
2056         if (pid == 1)           /* no messing around with init! */
2057                 goto out_tsk;
2058  
2059 +       if (gr_handle_ptrace(child, request))
2060 +               goto out_tsk;
2061 +
2062         if (request == PTRACE_ATTACH) {
2063                 ret = ptrace_attach(child);
2064                 goto out_tsk;
2065 diff -uNr linux-2.6.8/arch/ia64/kernel/sys_ia64.c linux-2.6.8.grsecurity/arch/ia64/kernel/sys_ia64.c
2066 --- linux-2.6.8/arch/ia64/kernel/sys_ia64.c     2004-08-14 07:37:14.000000000 +0200
2067 +++ linux-2.6.8.grsecurity/arch/ia64/kernel/sys_ia64.c  2004-08-16 17:06:18.262162576 +0200
2068 @@ -18,6 +18,7 @@
2069  #include <linux/syscalls.h>
2070  #include <linux/highuid.h>
2071  #include <linux/hugetlb.h>
2072 +#include <linux/grsecurity.h>
2073  
2074  #include <asm/shmparam.h>
2075  #include <asm/uaccess.h>
2076 @@ -27,7 +28,7 @@
2077                         unsigned long pgoff, unsigned long flags)
2078  {
2079         long map_shared = (flags & MAP_SHARED);
2080 -       unsigned long start_addr, align_mask = PAGE_SIZE - 1;
2081 +       unsigned long start_addr, align_mask = PAGE_SIZE - 1, task_unmapped_base = TASK_UNMAPPED_BASE;
2082         struct mm_struct *mm = current->mm;
2083         struct vm_area_struct *vma;
2084  
2085 @@ -38,6 +39,15 @@
2086         if (REGION_NUMBER(addr) == REGION_HPAGE)
2087                 addr = 0;
2088  #endif
2089 +
2090 +#ifdef CONFIG_PAX_RANDMMAP
2091 +       if (current->flags & PF_PAX_RANDMMAP)
2092 +               task_unmapped_base += mm->delta_mmap;
2093 +       if ((current->flags & PF_PAX_RANDMMAP) && addr && filp)
2094 +               addr = mm->free_area_cache;
2095 +       else
2096 +#endif
2097 +
2098         if (!addr)
2099                 addr = mm->free_area_cache;
2100  
2101 @@ -56,9 +66,9 @@
2102         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2103                 /* At this point:  (!vma || addr < vma->vm_end). */
2104                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
2105 -                       if (start_addr != TASK_UNMAPPED_BASE) {
2106 +                       if (start_addr != task_unmapped_base) {
2107                                 /* Start a new search --- just in case we missed some holes.  */
2108 -                               addr = TASK_UNMAPPED_BASE;
2109 +                               addr = task_unmapped_base;
2110                                 goto full_search;
2111                         }
2112                         return -ENOMEM;
2113 @@ -185,6 +195,11 @@
2114         unsigned long roff;
2115         struct file *file = 0;
2116  
2117 +#ifdef CONFIG_PAX_RANDEXEC
2118 +       if (flags & MAP_MIRROR)
2119 +               return -EINVAL;
2120 +#endif
2121 +
2122         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2123         if (!(flags & MAP_ANONYMOUS)) {
2124                 file = fget(fd);
2125 @@ -222,6 +237,11 @@
2126                 goto out;
2127         }
2128  
2129 +       if (gr_handle_mmap(file, prot)) {
2130 +               addr = -EACCES;
2131 +               goto out;
2132 +       }
2133 +
2134         down_write(&current->mm->mmap_sem);
2135         addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
2136         up_write(&current->mm->mmap_sem);
2137 diff -uNr linux-2.6.8/arch/ia64/mm/fault.c linux-2.6.8.grsecurity/arch/ia64/mm/fault.c
2138 --- linux-2.6.8/arch/ia64/mm/fault.c    2004-08-14 07:38:07.000000000 +0200
2139 +++ linux-2.6.8.grsecurity/arch/ia64/mm/fault.c 2004-08-16 17:06:18.387143576 +0200
2140 @@ -9,6 +9,7 @@
2141  #include <linux/mm.h>
2142  #include <linux/smp_lock.h>
2143  #include <linux/interrupt.h>
2144 +#include <linux/binfmts.h>
2145  
2146  #include <asm/pgtable.h>
2147  #include <asm/processor.h>
2148 @@ -70,6 +71,54 @@
2149         return pte_present(pte);
2150  }
2151  
2152 +#ifdef CONFIG_PAX_PAGEEXEC
2153 +/*
2154 + * PaX: decide what to do with offenders (regs->cr_iip = fault address)
2155 + *
2156 + * returns 1 when task should be killed
2157 + *         2 when legitimate ET_EXEC was detected
2158 + */
2159 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2160 +{
2161 +
2162 +#ifdef CONFIG_PAX_RANDEXEC
2163 +       int err;
2164 +
2165 +       if (current->flags & PF_PAX_RANDEXEC) {
2166 +               if (regs->cr_iip >= current->mm->start_code &&
2167 +                   regs->cr_iip < current->mm->end_code)
2168 +               {
2169 +#if 0
2170 +                       /* PaX: this needs fixing */
2171 +                       if (regs->b0 == regs->cr_iip)
2172 +                               return 1;
2173 +#endif
2174 +                       regs->cr_iip += current->mm->delta_exec;
2175 +                       return 2;
2176 +               }
2177 +       }
2178 +#endif
2179 +
2180 +       return 1;
2181 +}
2182 +
2183 +void pax_report_insns(void *pc, void *sp)
2184 +{
2185 +       unsigned long i;
2186 +
2187 +       printk(KERN_ERR "PAX: bytes at PC: ");
2188 +       for (i = 0; i < 8; i++) {
2189 +               unsigned int c;
2190 +               if (get_user(c, (unsigned int*)pc+i)) {
2191 +                       printk("<invalid address>.");
2192 +                       break;
2193 +               }
2194 +               printk("%08x ", c);
2195 +       }
2196 +       printk("\n");
2197 +}
2198 +#endif
2199 +
2200  void
2201  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
2202  {
2203 @@ -125,9 +174,31 @@
2204                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
2205                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
2206  
2207 -       if ((vma->vm_flags & mask) != mask)
2208 +       if ((vma->vm_flags & mask) != mask) {
2209 +
2210 +#ifdef CONFIG_PAX_PAGEEXEC
2211 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
2212 +                       if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->cr_iip)
2213 +                               goto bad_area;
2214 +
2215 +                       up_read(&mm->mmap_sem);
2216 +                       switch(pax_handle_fetch_fault(regs)) {
2217 +
2218 +#ifdef CONFIG_PAX_RANDEXEC
2219 +                       case 2:
2220 +                               return;
2221 +#endif
2222 +
2223 +                       }
2224 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
2225 +                       do_exit(SIGKILL);
2226 +               }
2227 +#endif
2228 +
2229                 goto bad_area;
2230  
2231 +       }
2232 +
2233    survive:
2234         /*
2235          * If for any reason at all we couldn't handle the fault, make
2236 diff -uNr linux-2.6.8/arch/mips/kernel/binfmt_elfn32.c linux-2.6.8.grsecurity/arch/mips/kernel/binfmt_elfn32.c
2237 --- linux-2.6.8/arch/mips/kernel/binfmt_elfn32.c        2004-08-14 07:37:14.000000000 +0200
2238 +++ linux-2.6.8.grsecurity/arch/mips/kernel/binfmt_elfn32.c     2004-08-16 17:06:18.428137344 +0200
2239 @@ -50,6 +50,17 @@
2240  #undef ELF_ET_DYN_BASE
2241  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
2242  
2243 +#ifdef CONFIG_PAX_ASLR
2244 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
2245 +
2246 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
2247 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2248 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
2249 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2250 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
2251 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2252 +#endif
2253 +
2254  #include <asm/processor.h>
2255  #include <linux/module.h>
2256  #include <linux/config.h>
2257 diff -uNr linux-2.6.8/arch/mips/kernel/binfmt_elfo32.c linux-2.6.8.grsecurity/arch/mips/kernel/binfmt_elfo32.c
2258 --- linux-2.6.8/arch/mips/kernel/binfmt_elfo32.c        2004-08-14 07:36:45.000000000 +0200
2259 +++ linux-2.6.8.grsecurity/arch/mips/kernel/binfmt_elfo32.c     2004-08-16 17:06:18.445134760 +0200
2260 @@ -52,6 +52,17 @@
2261  #undef ELF_ET_DYN_BASE
2262  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
2263  
2264 +#ifdef CONFIG_PAX_ASLR
2265 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
2266 +
2267 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
2268 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2269 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
2270 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2271 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
2272 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2273 +#endif
2274 +
2275  #include <asm/processor.h>
2276  #include <linux/module.h>
2277  #include <linux/config.h>
2278 diff -uNr linux-2.6.8/arch/mips/kernel/syscall.c linux-2.6.8.grsecurity/arch/mips/kernel/syscall.c
2279 --- linux-2.6.8/arch/mips/kernel/syscall.c      2004-08-14 07:37:38.000000000 +0200
2280 +++ linux-2.6.8.grsecurity/arch/mips/kernel/syscall.c   2004-08-16 17:06:18.471130808 +0200
2281 @@ -86,6 +86,11 @@
2282         do_color_align = 0;
2283         if (filp || (flags & MAP_SHARED))
2284                 do_color_align = 1;
2285 +
2286 +#ifdef CONFIG_PAX_RANDMMAP
2287 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
2288 +#endif
2289 +
2290         if (addr) {
2291                 if (do_color_align)
2292                         addr = COLOUR_ALIGN(addr, pgoff);
2293 @@ -96,6 +101,13 @@
2294                     (!vmm || addr + len <= vmm->vm_start))
2295                         return addr;
2296         }
2297 +
2298 +#ifdef CONFIG_PAX_RANDMMAP
2299 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
2300 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
2301 +       else
2302 +#endif
2303 +
2304         addr = TASK_UNMAPPED_BASE;
2305         if (do_color_align)
2306                 addr = COLOUR_ALIGN(addr, pgoff);
2307 diff -uNr linux-2.6.8/arch/mips/mm/fault.c linux-2.6.8.grsecurity/arch/mips/mm/fault.c
2308 --- linux-2.6.8/arch/mips/mm/fault.c    2004-08-14 07:36:33.000000000 +0200
2309 +++ linux-2.6.8.grsecurity/arch/mips/mm/fault.c 2004-08-16 17:06:18.498126704 +0200
2310 @@ -27,6 +27,24 @@
2311  #include <asm/uaccess.h>
2312  #include <asm/ptrace.h>
2313  
2314 +#ifdef CONFIG_PAX_PAGEEXEC
2315 +void pax_report_insns(void *pc)
2316 +{
2317 +       unsigned long i;
2318 +
2319 +       printk(KERN_ERR "PAX: bytes at PC: ");
2320 +       for (i = 0; i < 5; i++) {
2321 +               unsigned int c;
2322 +               if (get_user(c, (unsigned int*)pc+i)) {
2323 +                       printk("<invalid address>.");
2324 +                       break;
2325 +               }
2326 +               printk("%08x ", c);
2327 +       }
2328 +       printk("\n");
2329 +}
2330 +#endif
2331 +
2332  /*
2333   * This routine handles page faults.  It determines the address,
2334   * and the problem, and then passes it off to one of the appropriate
2335 diff -uNr linux-2.6.8/arch/parisc/kernel/ptrace.c linux-2.6.8.grsecurity/arch/parisc/kernel/ptrace.c
2336 --- linux-2.6.8/arch/parisc/kernel/ptrace.c     2004-08-14 07:36:16.000000000 +0200
2337 +++ linux-2.6.8.grsecurity/arch/parisc/kernel/ptrace.c  2004-08-16 17:06:18.531121688 +0200
2338 @@ -17,6 +17,7 @@
2339  #include <linux/personality.h>
2340  #include <linux/security.h>
2341  #include <linux/compat.h>
2342 +#include <linux/grsecurity.h>
2343  
2344  #include <asm/uaccess.h>
2345  #include <asm/pgtable.h>
2346 @@ -114,6 +115,9 @@
2347         if (pid == 1)           /* no messing around with init! */
2348                 goto out_tsk;
2349  
2350 +       if (gr_handle_ptrace(child, request))
2351 +               goto out_tsk;
2352 +
2353         if (request == PTRACE_ATTACH) {
2354                 ret = ptrace_attach(child);
2355                 goto out_tsk;
2356 diff -uNr linux-2.6.8/arch/parisc/kernel/sys_parisc32.c linux-2.6.8.grsecurity/arch/parisc/kernel/sys_parisc32.c
2357 --- linux-2.6.8/arch/parisc/kernel/sys_parisc32.c       2004-08-14 07:36:45.000000000 +0200
2358 +++ linux-2.6.8.grsecurity/arch/parisc/kernel/sys_parisc32.c    2004-08-16 17:06:18.679099192 +0200
2359 @@ -48,6 +48,7 @@
2360  #include <linux/ptrace.h>
2361  #include <linux/swap.h>
2362  #include <linux/syscalls.h>
2363 +#include <linux/grsecurity.h>
2364  
2365  #include <asm/types.h>
2366  #include <asm/uaccess.h>
2367 diff -uNr linux-2.6.8/arch/parisc/kernel/sys_parisc.c linux-2.6.8.grsecurity/arch/parisc/kernel/sys_parisc.c
2368 --- linux-2.6.8/arch/parisc/kernel/sys_parisc.c 2004-08-14 07:37:40.000000000 +0200
2369 +++ linux-2.6.8.grsecurity/arch/parisc/kernel/sys_parisc.c      2004-08-16 17:06:18.547119256 +0200
2370 @@ -31,6 +31,7 @@
2371  #include <linux/shm.h>
2372  #include <linux/smp_lock.h>
2373  #include <linux/syscalls.h>
2374 +#include <linux/grsecurity.h>
2375  
2376  int sys_pipe(int *fildes)
2377  {
2378 @@ -104,6 +105,13 @@
2379  {
2380         if (len > TASK_SIZE)
2381                 return -ENOMEM;
2382 +
2383 +#ifdef CONFIG_PAX_RANDMMAP
2384 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
2385 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
2386 +       else
2387 +#endif
2388 +
2389         if (!addr)
2390                 addr = TASK_UNMAPPED_BASE;
2391  
2392 @@ -123,12 +131,23 @@
2393  {
2394         struct file * file = NULL;
2395         unsigned long error = -EBADF;
2396 +
2397 +#ifdef CONFIG_PAX_RANDEXEC
2398 +       if (flags & MAP_MIRROR)
2399 +               return -EINVAL;
2400 +#endif
2401 +
2402         if (!(flags & MAP_ANONYMOUS)) {
2403                 file = fget(fd);
2404                 if (!file)
2405                         goto out;
2406         }
2407  
2408 +       if (gr_handle_mmap(file, prot)) {
2409 +               fput(file);
2410 +               return -EACCES;
2411 +       }
2412 +
2413         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2414  
2415         down_write(&current->mm->mmap_sem);
2416 diff -uNr linux-2.6.8/arch/parisc/kernel/traps.c linux-2.6.8.grsecurity/arch/parisc/kernel/traps.c
2417 --- linux-2.6.8/arch/parisc/kernel/traps.c      2004-08-14 07:38:10.000000000 +0200
2418 +++ linux-2.6.8.grsecurity/arch/parisc/kernel/traps.c   2004-08-16 17:06:18.697096456 +0200
2419 @@ -625,9 +625,7 @@
2420  
2421                         down_read(&current->mm->mmap_sem);
2422                         vma = find_vma(current->mm,regs->iaoq[0]);
2423 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
2424 -                               && (vma->vm_flags & VM_EXEC)) {
2425 -
2426 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
2427                                 fault_address = regs->iaoq[0];
2428                                 fault_space = regs->iasq[0];
2429  
2430 diff -uNr linux-2.6.8/arch/parisc/mm/fault.c linux-2.6.8.grsecurity/arch/parisc/mm/fault.c
2431 --- linux-2.6.8/arch/parisc/mm/fault.c  2004-08-14 07:37:40.000000000 +0200
2432 +++ linux-2.6.8.grsecurity/arch/parisc/mm/fault.c       2004-08-16 17:06:18.704095392 +0200
2433 @@ -16,6 +16,8 @@
2434  #include <linux/sched.h>
2435  #include <linux/interrupt.h>
2436  #include <linux/module.h>
2437 +#include <linux/unistd.h>
2438 +#include <linux/binfmts.h>
2439  
2440  #include <asm/uaccess.h>
2441  #include <asm/traps.h>
2442 @@ -54,7 +56,7 @@
2443  static unsigned long
2444  parisc_acctyp(unsigned long code, unsigned int inst)
2445  {
2446 -       if (code == 6 || code == 16)
2447 +       if (code == 6 || code == 7 || code == 16)
2448             return VM_EXEC;
2449  
2450         switch (inst & 0xf0000000) {
2451 @@ -140,6 +142,139 @@
2452                         }
2453  #endif
2454  
2455 +#ifdef CONFIG_PAX_PAGEEXEC
2456 +/*
2457 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
2458 + *
2459 + * returns 1 when task should be killed
2460 + *         2 when rt_sigreturn trampoline was detected
2461 + *         3 when unpatched PLT trampoline was detected
2462 + *         4 when legitimate ET_EXEC was detected
2463 + */
2464 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2465 +{
2466 +
2467 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUTRAMP)
2468 +       int err;
2469 +#endif
2470 +
2471 +#ifdef CONFIG_PAX_RANDEXEC
2472 +       if (current->flags & PF_PAX_RANDEXEC) {
2473 +               if (instruction_pointer(regs) >= current->mm->start_code &&
2474 +                   instruction_pointer(regs) < current->mm->end_code)
2475 +               {
2476 +#if 0
2477 +                       /* PaX: this needs fixing */
2478 +                       if ((regs->gr[2] & ~3UL) == instruction_pointer(regs))
2479 +                               return 1;
2480 +#endif
2481 +                       regs->iaoq[0] += current->mm->delta_exec;
2482 +                       if ((regs->iaoq[1] & ~3UL) >= current->mm->start_code &&
2483 +                           (regs->iaoq[1] & ~3UL) < current->mm->end_code)
2484 +                               regs->iaoq[1] += current->mm->delta_exec;
2485 +                       return 4;
2486 +               }
2487 +       }
2488 +#endif
2489 +
2490 +#ifdef CONFIG_PAX_EMUPLT
2491 +       do { /* PaX: unpatched PLT emulation */
2492 +               unsigned int bl, depwi;
2493 +
2494 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
2495 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
2496 +
2497 +               if (err)
2498 +                       break;
2499 +
2500 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
2501 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
2502 +
2503 +                       err = get_user(ldw, (unsigned int*)addr);
2504 +                       err |= get_user(bv, (unsigned int*)(addr+4));
2505 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
2506 +
2507 +                       if (err)
2508 +                               break;
2509 +
2510 +                       if (ldw == 0x0E801096U &&
2511 +                           bv == 0xEAC0C000U &&
2512 +                           ldw2 == 0x0E881095U)
2513 +                       {
2514 +                               unsigned int resolver, map;
2515 +
2516 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
2517 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
2518 +                               if (err)
2519 +                                       break;
2520 +
2521 +                               regs->gr[20] = instruction_pointer(regs)+8;
2522 +                               regs->gr[21] = map;
2523 +                               regs->gr[22] = resolver;
2524 +                               regs->iaoq[0] = resolver | 3UL;
2525 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
2526 +                               return 3;
2527 +                       }
2528 +               }
2529 +       } while (0);
2530 +#endif
2531 +
2532 +#ifdef CONFIG_PAX_EMUTRAMP
2533 +
2534 +#ifndef CONFIG_PAX_EMUSIGRT
2535 +       if (!(current->flags & PF_PAX_EMUTRAMP))
2536 +               return 1;
2537 +#endif
2538 +
2539 +       do { /* PaX: rt_sigreturn emulation */
2540 +               unsigned int ldi1, ldi2, bel, nop;
2541 +
2542 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
2543 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
2544 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
2545 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
2546 +
2547 +               if (err)
2548 +                       break;
2549 +
2550 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
2551 +                   ldi2 == 0x3414015AU &&
2552 +                   bel == 0xE4008200U &&
2553 +                   nop == 0x08000240U)
2554 +               {
2555 +                       regs->gr[25] = (ldi1 & 2) >> 1;
2556 +                       regs->gr[20] = __NR_rt_sigreturn;
2557 +                       regs->gr[31] = regs->iaoq[1] + 16;
2558 +                       regs->sr[0] = regs->iasq[1];
2559 +                       regs->iaoq[0] = 0x100UL;
2560 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
2561 +                       regs->iasq[0] = regs->sr[2];
2562 +                       regs->iasq[1] = regs->sr[2];
2563 +                       return 2;
2564 +               }
2565 +       } while (0);
2566 +#endif
2567 +
2568 +       return 1;
2569 +}
2570 +
2571 +void pax_report_insns(void *pc, void *sp)
2572 +{
2573 +       unsigned long i;
2574 +
2575 +       printk(KERN_ERR "PAX: bytes at PC: ");
2576 +       for (i = 0; i < 5; i++) {
2577 +               unsigned int c;
2578 +               if (get_user(c, (unsigned int*)pc+i)) {
2579 +                       printk("<invalid address>.");
2580 +                       break;
2581 +               }
2582 +               printk("%08x ", c);
2583 +       }
2584 +       printk("\n");
2585 +}
2586 +#endif
2587 +
2588  void do_page_fault(struct pt_regs *regs, unsigned long code,
2589                               unsigned long address)
2590  {
2591 @@ -165,8 +300,38 @@
2592  
2593         acc_type = parisc_acctyp(code,regs->iir);
2594  
2595 -       if ((vma->vm_flags & acc_type) != acc_type)
2596 +       if ((vma->vm_flags & acc_type) != acc_type) {
2597 +
2598 +#ifdef CONFIG_PAX_PAGEEXEC
2599 +               if ((current->flags & PF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
2600 +                   (address & ~3UL) == instruction_pointer(regs))
2601 +               {
2602 +                       up_read(&mm->mmap_sem);
2603 +                       switch(pax_handle_fetch_fault(regs)) {
2604 +
2605 +#ifdef CONFIG_PAX_RANDEXEC
2606 +                       case 4:
2607 +                               return;
2608 +#endif
2609 +
2610 +#ifdef CONFIG_PAX_EMUPLT
2611 +                       case 3:
2612 +                               return;
2613 +#endif
2614 +
2615 +#ifdef CONFIG_PAX_EMUTRAMP
2616 +                       case 2:
2617 +                               return;
2618 +#endif
2619 +
2620 +                       }
2621 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
2622 +                       do_exit(SIGKILL);
2623 +               }
2624 +#endif
2625 +
2626                 goto bad_area;
2627 +       }
2628  
2629         /*
2630          * If for any reason at all we couldn't handle the fault, make
2631 diff -uNr linux-2.6.8/arch/ppc/kernel/ptrace.c linux-2.6.8.grsecurity/arch/ppc/kernel/ptrace.c
2632 --- linux-2.6.8/arch/ppc/kernel/ptrace.c        2004-08-14 07:36:32.000000000 +0200
2633 +++ linux-2.6.8.grsecurity/arch/ppc/kernel/ptrace.c     2004-08-16 17:06:18.736090528 +0200
2634 @@ -26,6 +26,7 @@
2635  #include <linux/ptrace.h>
2636  #include <linux/user.h>
2637  #include <linux/security.h>
2638 +#include <linux/grsecurity.h>
2639  
2640  #include <asm/uaccess.h>
2641  #include <asm/page.h>
2642 @@ -266,6 +267,9 @@
2643         if (pid == 1)           /* you may not mess with init */
2644                 goto out_tsk;
2645  
2646 +       if (gr_handle_ptrace(child, request))
2647 +               goto out_tsk;
2648 +
2649         if (request == PTRACE_ATTACH) {
2650                 ret = ptrace_attach(child);
2651                 goto out_tsk;
2652 diff -uNr linux-2.6.8/arch/ppc/kernel/syscalls.c linux-2.6.8.grsecurity/arch/ppc/kernel/syscalls.c
2653 --- linux-2.6.8/arch/ppc/kernel/syscalls.c      2004-08-14 07:38:04.000000000 +0200
2654 +++ linux-2.6.8.grsecurity/arch/ppc/kernel/syscalls.c   2004-08-16 17:06:18.789082472 +0200
2655 @@ -36,6 +36,7 @@
2656  #include <linux/utsname.h>
2657  #include <linux/file.h>
2658  #include <linux/unistd.h>
2659 +#include <linux/grsecurity.h>
2660  
2661  #include <asm/uaccess.h>
2662  #include <asm/ipc.h>
2663 @@ -165,12 +166,23 @@
2664         struct file * file = NULL;
2665         int ret = -EBADF;
2666  
2667 +#ifdef CONFIG_PAX_RANDEXEC
2668 +       if (flags & MAP_MIRROR)
2669 +               return -EINVAL;
2670 +#endif
2671 +
2672         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2673         if (!(flags & MAP_ANONYMOUS)) {
2674                 if (!(file = fget(fd)))
2675                         goto out;
2676         }
2677  
2678 +       if (gr_handle_mmap(file, prot)) {
2679 +               fput(file);
2680 +               ret = -EACCES;
2681 +               goto out;
2682 +       }
2683 +
2684         down_write(&current->mm->mmap_sem);
2685         ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
2686         up_write(&current->mm->mmap_sem);
2687 diff -uNr linux-2.6.8/arch/ppc/mm/fault.c linux-2.6.8.grsecurity/arch/ppc/mm/fault.c
2688 --- linux-2.6.8/arch/ppc/mm/fault.c     2004-08-14 07:36:44.000000000 +0200
2689 +++ linux-2.6.8.grsecurity/arch/ppc/mm/fault.c  2004-08-16 17:23:13.778780584 +0200
2690 @@ -28,6 +28,11 @@
2691  #include <linux/interrupt.h>
2692  #include <linux/highmem.h>
2693  #include <linux/module.h>
2694 +#include <linux/slab.h>
2695 +#include <linux/pagemap.h>
2696 +#include <linux/compiler.h>
2697 +#include <linux/binfmts.h>
2698 +#include <linux/unistd.h>
2699  
2700  #include <asm/page.h>
2701  #include <asm/pgtable.h>
2702 @@ -51,6 +56,363 @@
2703  unsigned long pte_errors;      /* updated by do_page_fault() */
2704  unsigned int probingmem;
2705  
2706 +#ifdef CONFIG_PAX_EMUSIGRT
2707 +void pax_syscall_close(struct vm_area_struct * vma)
2708 +{
2709 +       vma->vm_mm->call_syscall = 0UL;
2710 +}
2711 +
2712 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2713 +{
2714 +       struct page* page;
2715 +       unsigned int *kaddr;
2716 +
2717 +       page = alloc_page(GFP_HIGHUSER);
2718 +       if (!page)
2719 +               return NOPAGE_OOM;
2720 +
2721 +       kaddr = kmap(page);
2722 +       memset(kaddr, 0, PAGE_SIZE);
2723 +       kaddr[0] = 0x44000002U; /* sc */
2724 +       __flush_dcache_icache(kaddr);
2725 +       kunmap(page);
2726 +       if (type)
2727 +               *type = VM_FAULT_MAJOR;
2728 +       return page;
2729 +}
2730 +
2731 +static struct vm_operations_struct pax_vm_ops = {
2732 +       close:          pax_syscall_close,
2733 +       nopage:         pax_syscall_nopage,
2734 +};
2735 +
2736 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2737 +{
2738 +       memset(vma, 0, sizeof(*vma));
2739 +       vma->vm_mm = current->mm;
2740 +       vma->vm_start = addr;
2741 +       vma->vm_end = addr + PAGE_SIZE;
2742 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2743 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
2744 +       vma->vm_ops = &pax_vm_ops;
2745 +       insert_vm_struct(current->mm, vma);
2746 +       ++current->mm->total_vm;
2747 +}
2748 +#endif
2749 +
2750 +#ifdef CONFIG_PAX_PAGEEXEC
2751 +/*
2752 + * PaX: decide what to do with offenders (regs->nip = fault address)
2753 + *
2754 + * returns 1 when task should be killed
2755 + *         2 when patched GOT trampoline was detected
2756 + *         3 when patched PLT trampoline was detected
2757 + *         4 when unpatched PLT trampoline was detected
2758 + *         5 when legitimate ET_EXEC was detected
2759 + *         6 when sigreturn trampoline was detected
2760 + *         7 when rt_sigreturn trampoline was detected
2761 + */
2762 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2763 +{
2764 +
2765 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
2766 +       int err;
2767 +#endif
2768 +
2769 +#ifdef CONFIG_PAX_RANDEXEC
2770 +       if (current->flags & PF_PAX_RANDEXEC) {
2771 +               if (regs->nip >= current->mm->start_code &&
2772 +                   regs->nip < current->mm->end_code)
2773 +               {
2774 +                       if (regs->link == regs->nip)
2775 +                               return 1;
2776 +
2777 +                       regs->nip += current->mm->delta_exec;
2778 +                       return 5;
2779 +               }
2780 +       }
2781 +#endif
2782 +
2783 +#ifdef CONFIG_PAX_EMUPLT
2784 +       do { /* PaX: patched GOT emulation */
2785 +               unsigned int blrl;
2786 +
2787 +               err = get_user(blrl, (unsigned int*)regs->nip);
2788 +
2789 +               if (!err && blrl == 0x4E800021U) {
2790 +                       unsigned long temp = regs->nip;
2791 +
2792 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
2793 +                       regs->link = temp + 4UL;
2794 +                       return 2;
2795 +               }
2796 +       } while (0);
2797 +
2798 +       do { /* PaX: patched PLT emulation #1 */
2799 +               unsigned int b;
2800 +
2801 +               err = get_user(b, (unsigned int *)regs->nip);
2802 +
2803 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
2804 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
2805 +                       return 3;
2806 +               }
2807 +       } while (0);
2808 +
2809 +       do { /* PaX: unpatched PLT emulation #1 */
2810 +               unsigned int li, b;
2811 +
2812 +               err = get_user(li, (unsigned int *)regs->nip);
2813 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
2814 +
2815 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2816 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2817 +                       unsigned long addr = b | 0xFC000000UL;
2818 +
2819 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2820 +                       err = get_user(rlwinm, (unsigned int*)addr);
2821 +                       err |= get_user(add, (unsigned int*)(addr+4));
2822 +                       err |= get_user(li2, (unsigned int*)(addr+8));
2823 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
2824 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
2825 +                       err |= get_user(li3, (unsigned int*)(addr+20));
2826 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
2827 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
2828 +
2829 +                       if (err)
2830 +                               break;
2831 +
2832 +                       if (rlwinm == 0x556C083CU &&
2833 +                           add == 0x7D6C5A14U &&
2834 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2835 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2836 +                           mtctr == 0x7D8903A6U &&
2837 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2838 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2839 +                           bctr == 0x4E800420U)
2840 +                       {
2841 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2842 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2843 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2844 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2845 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
2846 +                               regs->nip = regs->ctr;
2847 +                               return 4;
2848 +                       }
2849 +               }
2850 +       } while (0);
2851 +
2852 +#if 0
2853 +       do { /* PaX: unpatched PLT emulation #2 */
2854 +               unsigned int lis, lwzu, b, bctr;
2855 +
2856 +               err = get_user(lis, (unsigned int *)regs->nip);
2857 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
2858 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
2859 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
2860 +
2861 +               if (err)
2862 +                       break;
2863 +
2864 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
2865 +                   (lwzu & 0xU) == 0xU &&
2866 +                   (b & 0xFC000003U) == 0x48000000U &&
2867 +                   bctr == 0x4E800420U)
2868 +               {
2869 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2870 +                       unsigned long addr = b | 0xFC000000UL;
2871 +
2872 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2873 +                       err = get_user(addis, (unsigned int*)addr);
2874 +                       err |= get_user(addi, (unsigned int*)(addr+4));
2875 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
2876 +                       err |= get_user(add, (unsigned int*)(addr+12));
2877 +                       err |= get_user(li2, (unsigned int*)(addr+16));
2878 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
2879 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
2880 +                       err |= get_user(li3, (unsigned int*)(addr+28));
2881 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
2882 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
2883 +
2884 +                       if (err)
2885 +                               break;
2886 +
2887 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2888 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
2889 +                           rlwinm == 0x556C083CU &&
2890 +                           add == 0x7D6C5A14U &&
2891 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2892 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2893 +                           mtctr == 0x7D8903A6U &&
2894 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2895 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2896 +                           bctr == 0x4E800420U)
2897 +                       {
2898 +                               regs->gpr[PT_R11] = 
2899 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2900 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2901 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2902 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2903 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
2904 +                               regs->nip = regs->ctr;
2905 +                               return 4;
2906 +                       }
2907 +               }
2908 +       } while (0);
2909 +#endif
2910 +
2911 +       do { /* PaX: unpatched PLT emulation #3 */
2912 +               unsigned int li, b;
2913 +
2914 +               err = get_user(li, (unsigned int *)regs->nip);
2915 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
2916 +
2917 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2918 +                       unsigned int addis, lwz, mtctr, bctr;
2919 +                       unsigned long addr = b | 0xFC000000UL;
2920 +
2921 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2922 +                       err = get_user(addis, (unsigned int*)addr);
2923 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
2924 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
2925 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
2926 +
2927 +                       if (err)
2928 +                               break;
2929 +
2930 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2931 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
2932 +                           mtctr == 0x7D6903A6U &&
2933 +                           bctr == 0x4E800420U)
2934 +                       {
2935 +                               unsigned int r11;
2936 +
2937 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2938 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2939 +
2940 +                               err = get_user(r11, (unsigned int*)addr);
2941 +                               if (err)
2942 +                                       break;
2943 +
2944 +                               regs->gpr[PT_R11] = r11;
2945 +                               regs->ctr = r11;
2946 +                               regs->nip = r11;
2947 +                               return 4;
2948 +                       }
2949 +               }
2950 +       } while (0);
2951 +#endif
2952 +
2953 +#ifdef CONFIG_PAX_EMUSIGRT
2954 +       do { /* PaX: sigreturn emulation */
2955 +               unsigned int li, sc;
2956 +
2957 +               err = get_user(li, (unsigned int *)regs->nip);
2958 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
2959 +
2960 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
2961 +                       struct vm_area_struct *vma;
2962 +                       unsigned long call_syscall;
2963 +
2964 +                       down_read(&current->mm->mmap_sem);
2965 +                       call_syscall = current->mm->call_syscall;
2966 +                       up_read(&current->mm->mmap_sem);
2967 +                       if (likely(call_syscall))
2968 +                               goto emulate;
2969 +
2970 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
2971 +
2972 +                       down_write(&current->mm->mmap_sem);
2973 +                       if (current->mm->call_syscall) {
2974 +                               call_syscall = current->mm->call_syscall;
2975 +                               up_write(&current->mm->mmap_sem);
2976 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2977 +                               goto emulate;
2978 +                       }
2979 +
2980 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2981 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
2982 +                               up_write(&current->mm->mmap_sem);
2983 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2984 +                               return 1;
2985 +                       }
2986 +
2987 +                       pax_insert_vma(vma, call_syscall);
2988 +                       current->mm->call_syscall = call_syscall;
2989 +                       up_write(&current->mm->mmap_sem);
2990 +
2991 +emulate:
2992 +                       regs->gpr[PT_R0] = __NR_sigreturn;
2993 +                       regs->nip = call_syscall;
2994 +                       return 6;
2995 +               }
2996 +       } while (0);
2997 +
2998 +       do { /* PaX: rt_sigreturn emulation */
2999 +               unsigned int li, sc;
3000 +
3001 +               err = get_user(li, (unsigned int *)regs->nip);
3002 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
3003 +
3004 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
3005 +                       struct vm_area_struct *vma;
3006 +                       unsigned int call_syscall;
3007 +
3008 +                       down_read(&current->mm->mmap_sem);
3009 +                       call_syscall = current->mm->call_syscall;
3010 +                       up_read(&current->mm->mmap_sem);
3011 +                       if (likely(call_syscall))
3012 +                               goto rt_emulate;
3013 +
3014 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3015 +
3016 +                       down_write(&current->mm->mmap_sem);
3017 +                       if (current->mm->call_syscall) {
3018 +                               call_syscall = current->mm->call_syscall;
3019 +                               up_write(&current->mm->mmap_sem);
3020 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3021 +                               goto rt_emulate;
3022 +                       }
3023 +
3024 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3025 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
3026 +                               up_write(&current->mm->mmap_sem);
3027 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
3028 +                               return 1;
3029 +                       }
3030 +
3031 +                       pax_insert_vma(vma, call_syscall);
3032 +                       current->mm->call_syscall = call_syscall;
3033 +                       up_write(&current->mm->mmap_sem);
3034 +
3035 +rt_emulate:
3036 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
3037 +                       regs->nip = call_syscall;
3038 +                       return 7;
3039 +               }
3040 +       } while (0);
3041 +#endif
3042 +
3043 +       return 1;
3044 +}
3045 +
3046 +void pax_report_insns(void *pc, void *sp)
3047 +{
3048 +       unsigned long i;
3049 +
3050 +       printk(KERN_ERR "PAX: bytes at PC: ");
3051 +       for (i = 0; i < 5; i++) {
3052 +               unsigned int c;
3053 +               if (get_user(c, (unsigned int*)pc+i)) {
3054 +                       printk("<invalid address>.");
3055 +                       break;
3056 +               }
3057 +               printk("%08x ", c);
3058 +       }
3059 +       printk("\n");
3060 +}
3061 +#endif
3062 +
3063  /*
3064   * Check whether the instruction at regs->nip is a store using
3065   * an update addressing form which will update r1.
3066 @@ -111,7 +473,7 @@
3067          * indicate errors in DSISR but can validly be set in SRR1.
3068          */
3069         if (TRAP(regs) == 0x400)
3070 -               error_code &= 0x48200000;
3071 +               error_code &= 0x58200000;
3072         else
3073                 is_write = error_code & 0x02000000;
3074  #endif /* CONFIG_4xx || CONFIG_BOOKE */
3075 @@ -205,14 +567,14 @@
3076         } else if (TRAP(regs) == 0x400) {
3077                 pte_t *ptep;
3078  
3079 -#if 0
3080 +#if 1
3081                 /* It would be nice to actually enforce the VM execute
3082                    permission on CPUs which can do so, but far too
3083                    much stuff in userspace doesn't get the permissions
3084                    right, so we let any page be executed for now. */
3085                 if (! (vma->vm_flags & VM_EXEC))
3086                         goto bad_area;
3087 -#endif
3088 +#else
3089  
3090                 /* Since 4xx/Book-E supports per-page execute permission,
3091                  * we lazily flush dcache to icache. */
3092 @@ -233,6 +595,7 @@
3093                 if (ptep != NULL)
3094                         pte_unmap(ptep);
3095  #endif
3096 +#endif
3097         /* a read */
3098         } else {
3099                 /* protection fault */
3100 @@ -278,6 +641,38 @@
3101  
3102         /* User mode accesses cause a SIGSEGV */
3103         if (user_mode(regs)) {
3104 +
3105 +#ifdef CONFIG_PAX_PAGEEXEC
3106 +               if (current->flags & PF_PAX_PAGEEXEC) {
3107 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
3108 +                               switch (pax_handle_fetch_fault(regs)) {
3109 +
3110 +#ifdef CONFIG_PAX_EMUPLT
3111 +                               case 2:
3112 +                               case 3:
3113 +                               case 4:
3114 +                                       return 0;
3115 +#endif
3116 +
3117 +#ifdef CONFIG_PAX_RANDEXEC
3118 +                               case 5:
3119 +                                       return 0;
3120 +#endif
3121 +
3122 +#ifdef CONFIG_PAX_EMUSIGRT
3123 +                               case 6:
3124 +                               case 7:
3125 +                                       return 0;
3126 +#endif
3127 +
3128 +                               }
3129 +
3130 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
3131 +                               do_exit(SIGKILL);
3132 +                       }
3133 +               }
3134 +#endif
3135 +
3136                 info.si_signo = SIGSEGV;
3137                 info.si_errno = 0;
3138                 info.si_code = code;
3139 diff -uNr linux-2.6.8/arch/ppc64/kernel/syscalls.c linux-2.6.8.grsecurity/arch/ppc64/kernel/syscalls.c
3140 --- linux-2.6.8/arch/ppc64/kernel/syscalls.c    2004-08-14 07:37:26.000000000 +0200
3141 +++ linux-2.6.8.grsecurity/arch/ppc64/kernel/syscalls.c 2004-08-16 17:06:18.852072896 +0200
3142 @@ -177,6 +177,11 @@
3143         struct file * file = NULL;
3144         unsigned long ret = -EBADF;
3145  
3146 +#ifdef CONFIG_PAX_RANDEXEC
3147 +       if (flags & MAP_MIRROR)
3148 +               return -EINVAL;
3149 +#endif
3150 +
3151         if (!(flags & MAP_ANONYMOUS)) {
3152                 if (!(file = fget(fd)))
3153                         goto out;
3154 diff -uNr linux-2.6.8/arch/ppc64/mm/fault.c linux-2.6.8.grsecurity/arch/ppc64/mm/fault.c
3155 --- linux-2.6.8/arch/ppc64/mm/fault.c   2004-08-14 07:37:37.000000000 +0200
3156 +++ linux-2.6.8.grsecurity/arch/ppc64/mm/fault.c        2004-08-16 17:06:18.876069248 +0200
3157 @@ -29,6 +29,7 @@
3158  #include <linux/interrupt.h>
3159  #include <linux/smp_lock.h>
3160  #include <linux/module.h>
3161 +#include <linux/binfmts.h>
3162  
3163  #include <asm/page.h>
3164  #include <asm/pgtable.h>
3165 @@ -75,6 +76,54 @@
3166         return 0;
3167  }
3168  
3169 +#ifdef CONFIG_PAX_PAGEEXEC
3170 +/*
3171 + * PaX: decide what to do with offenders (regs->nip = fault address)
3172 + *
3173 + * returns 1 when task should be killed
3174 + *         2 when legitimate ET_EXEC was detected
3175 + */
3176 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3177 +{
3178 +
3179 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
3180 +       int err;
3181 +#endif
3182 +
3183 +#ifdef CONFIG_PAX_RANDEXEC
3184 +       if (current->flags & PF_PAX_RANDEXEC) {
3185 +               if (regs->nip >= current->mm->start_code &&
3186 +                   regs->nip < current->mm->end_code)
3187 +               {
3188 +                       if (regs->link == regs->nip)
3189 +                               return 1;
3190 +
3191 +                       regs->nip += current->mm->delta_exec;
3192 +                       return 2;
3193 +               }
3194 +       }
3195 +#endif
3196 +
3197 +       return 1;
3198 +}
3199 +
3200 +void pax_report_insns(void *pc, void *sp)
3201 +{
3202 +       unsigned long i;
3203 +
3204 +       printk(KERN_ERR "PAX: bytes at PC: ");
3205 +       for (i = 0; i < 5; i++) {
3206 +               unsigned int c;
3207 +               if (get_user(c, (unsigned int*)pc+i)) {
3208 +                       printk("<invalid address>.");
3209 +                       break;
3210 +               }
3211 +               printk("%08x ", c);
3212 +       }
3213 +       printk("\n");
3214 +}
3215 +#endif
3216 +
3217  /*
3218   * The error_code parameter is
3219   *  - DSISR for a non-SLB data access fault,
3220 @@ -235,6 +284,25 @@
3221  bad_area_nosemaphore:
3222         /* User mode accesses cause a SIGSEGV */
3223         if (user_mode(regs)) {
3224 +
3225 +#ifdef CONFIG_PAX_PAGEEXEC
3226 +               if (current->flags & PF_PAX_PAGEEXEC) {
3227 +                       if ((regs->trap == 0x400) && (regs->nip == address)) {
3228 +                               switch (pax_handle_fetch_fault(regs)) {
3229 +
3230 +#ifdef CONFIG_PAX_RANDEXEC
3231 +                               case 2:
3232 +                                       return;
3233 +#endif
3234 +
3235 +                               }
3236 +
3237 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
3238 +                               do_exit(SIGKILL);
3239 +                       }
3240 +               }
3241 +#endif
3242 +
3243                 info.si_signo = SIGSEGV;
3244                 info.si_errno = 0;
3245                 info.si_code = code;
3246 diff -uNr linux-2.6.8/arch/sparc/kernel/ptrace.c linux-2.6.8.grsecurity/arch/sparc/kernel/ptrace.c
3247 --- linux-2.6.8/arch/sparc/kernel/ptrace.c      2004-08-14 07:38:09.000000000 +0200
3248 +++ linux-2.6.8.grsecurity/arch/sparc/kernel/ptrace.c   2004-08-16 17:06:18.905064840 +0200
3249 @@ -18,6 +18,7 @@
3250  #include <linux/smp.h>
3251  #include <linux/smp_lock.h>
3252  #include <linux/security.h>
3253 +#include <linux/grsecurity.h>
3254  
3255  #include <asm/pgtable.h>
3256  #include <asm/system.h>
3257 @@ -322,6 +323,11 @@
3258                 goto out;
3259         }
3260  
3261 +       if (gr_handle_ptrace(child, request)) {
3262 +               pt_error_return(regs, EPERM);
3263 +               goto out_tsk;
3264 +       }
3265 +
3266         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3267             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3268                 if (ptrace_attach(child)) {
3269 diff -uNr linux-2.6.8/arch/sparc/kernel/sys_sparc.c linux-2.6.8.grsecurity/arch/sparc/kernel/sys_sparc.c
3270 --- linux-2.6.8/arch/sparc/kernel/sys_sparc.c   2004-08-14 07:36:46.000000000 +0200
3271 +++ linux-2.6.8.grsecurity/arch/sparc/kernel/sys_sparc.c        2004-08-16 17:06:18.931060888 +0200
3272 @@ -21,6 +21,7 @@
3273  #include <linux/utsname.h>
3274  #include <linux/smp.h>
3275  #include <linux/smp_lock.h>
3276 +#include <linux/grsecurity.h>
3277  
3278  #include <asm/uaccess.h>
3279  #include <asm/ipc.h>
3280 @@ -55,6 +56,13 @@
3281                 return -ENOMEM;
3282         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
3283                 return -ENOMEM;
3284 +
3285 +#ifdef CONFIG_PAX_RANDMMAP
3286 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
3287 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
3288 +       else
3289 +#endif
3290 +
3291         if (!addr)
3292                 addr = TASK_UNMAPPED_BASE;
3293  
3294 @@ -228,6 +236,11 @@
3295         struct file * file = NULL;
3296         unsigned long retval = -EBADF;
3297  
3298 +#ifdef CONFIG_PAX_RANDEXEC
3299 +       if (flags & MAP_MIRROR)
3300 +               return -EINVAL;
3301 +#endif
3302 +
3303         if (!(flags & MAP_ANONYMOUS)) {
3304                 file = fget(fd);
3305                 if (!file)
3306 @@ -246,6 +259,12 @@
3307         if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
3308                 goto out_putf;
3309  
3310 +       if (gr_handle_mmap(file, prot)) {
3311 +               fput(file);
3312 +               retval = -EACCES;
3313 +               goto out;
3314 +       }
3315 +
3316         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3317  
3318         down_write(&current->mm->mmap_sem);
3319 diff -uNr linux-2.6.8/arch/sparc/kernel/sys_sunos.c linux-2.6.8.grsecurity/arch/sparc/kernel/sys_sunos.c
3320 --- linux-2.6.8/arch/sparc/kernel/sys_sunos.c   2004-08-14 07:36:56.000000000 +0200
3321 +++ linux-2.6.8.grsecurity/arch/sparc/kernel/sys_sunos.c        2004-08-16 17:06:18.935060280 +0200
3322 @@ -71,6 +71,11 @@
3323         struct file * file = NULL;
3324         unsigned long retval, ret_type;
3325  
3326 +#ifdef CONFIG_PAX_RANDEXEC
3327 +       if (flags & MAP_MIRROR)
3328 +               return -EINVAL;
3329 +#endif
3330 +
3331         if (flags & MAP_NORESERVE) {
3332                 static int cnt;
3333                 if (cnt++ < 10)
3334 diff -uNr linux-2.6.8/arch/sparc/mm/fault.c linux-2.6.8.grsecurity/arch/sparc/mm/fault.c
3335 --- linux-2.6.8/arch/sparc/mm/fault.c   2004-08-14 07:38:11.000000000 +0200
3336 +++ linux-2.6.8.grsecurity/arch/sparc/mm/fault.c        2004-08-16 17:06:18.973054504 +0200
3337 @@ -21,6 +21,10 @@
3338  #include <linux/smp_lock.h>
3339  #include <linux/interrupt.h>
3340  #include <linux/module.h>
3341 +#include <linux/slab.h>
3342 +#include <linux/pagemap.h>
3343 +#include <linux/compiler.h>
3344 +#include <linux/binfmts.h>
3345  
3346  #include <asm/system.h>
3347  #include <asm/segment.h>
3348 @@ -220,6 +224,269 @@
3349         return safe_compute_effective_address(regs, insn);
3350  }
3351  
3352 +#ifdef CONFIG_PAX_PAGEEXEC
3353 +void pax_emuplt_close(struct vm_area_struct * vma)
3354 +{
3355 +       vma->vm_mm->call_dl_resolve = 0UL;
3356 +}
3357 +
3358 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
3359 +{
3360 +       struct page* page;
3361 +       unsigned int *kaddr;
3362 +
3363 +       page = alloc_page(GFP_HIGHUSER);
3364 +       if (!page)
3365 +               return NOPAGE_OOM;
3366 +
3367 +       kaddr = kmap(page);
3368 +       memset(kaddr, 0, PAGE_SIZE);
3369 +       kaddr[0] = 0x9DE3BFA8U; /* save */
3370 +       flush_dcache_page(page);
3371 +       kunmap(page);
3372 +       if (type)
3373 +               *type = VM_FAULT_MAJOR;
3374 +
3375 +       return page;
3376 +}
3377 +
3378 +static struct vm_operations_struct pax_vm_ops = {
3379 +       close:          pax_emuplt_close,
3380 +       nopage:         pax_emuplt_nopage,
3381 +};
3382 +
3383 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3384 +{
3385 +       memset(vma, 0, sizeof(*vma));
3386 +       vma->vm_mm = current->mm;
3387 +       vma->vm_start = addr;
3388 +       vma->vm_end = addr + PAGE_SIZE;
3389 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3390 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3391 +       vma->vm_ops = &pax_vm_ops;
3392 +       insert_vm_struct(current->mm, vma);
3393 +       ++current->mm->total_vm;
3394 +}
3395 +
3396 +/*
3397 + * PaX: decide what to do with offenders (regs->pc = fault address)
3398 + *
3399 + * returns 1 when task should be killed
3400 + *         2 when patched PLT trampoline was detected
3401 + *         3 when unpatched PLT trampoline was detected
3402 + *         4 when legitimate ET_EXEC was detected
3403 + */
3404 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3405 +{
3406 +
3407 +#ifdef CONFIG_PAX_EMUPLT
3408 +       int err;
3409 +#endif
3410 +
3411 +#ifdef CONFIG_PAX_RANDEXEC
3412 +       if (current->flags & PF_PAX_RANDEXEC) {
3413 +               if (regs->pc >= current->mm->start_code &&
3414 +                   regs->pc < current->mm->end_code)
3415 +               {
3416 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
3417 +                               return 1;
3418 +
3419 +                       regs->pc += current->mm->delta_exec;
3420 +                       if (regs->npc >= current->mm->start_code &&
3421 +                           regs->npc < current->mm->end_code)
3422 +                               regs->npc += current->mm->delta_exec;
3423 +                       return 4;
3424 +               }
3425 +               if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
3426 +                   regs->pc < current->mm->end_code + current->mm->delta_exec)
3427 +               {
3428 +                       regs->pc -= current->mm->delta_exec;
3429 +                       if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
3430 +                           regs->npc < current->mm->end_code + current->mm->delta_exec)
3431 +                               regs->npc -= current->mm->delta_exec;
3432 +               }
3433 +       }
3434 +#endif
3435 +
3436 +#ifdef CONFIG_PAX_EMUPLT
3437 +       do { /* PaX: patched PLT emulation #1 */
3438 +               unsigned int sethi1, sethi2, jmpl;
3439 +
3440 +               err = get_user(sethi1, (unsigned int*)regs->pc);
3441 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
3442 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
3443 +
3444 +               if (err)
3445 +                       break;
3446 +
3447 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3448 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
3449 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
3450 +               {
3451 +                       unsigned int addr;
3452 +
3453 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3454 +                       addr = regs->u_regs[UREG_G1];
3455 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3456 +                       regs->pc = addr;
3457 +                       regs->npc = addr+4;
3458 +                       return 2;
3459 +               }
3460 +       } while (0);
3461 +
3462 +       { /* PaX: patched PLT emulation #2 */
3463 +               unsigned int ba;
3464 +
3465 +               err = get_user(ba, (unsigned int*)regs->pc);
3466 +
3467 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3468 +                       unsigned int addr;
3469 +
3470 +                       addr = regs->pc + 4 + (((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U);
3471 +                       regs->pc = addr;
3472 +                       regs->npc = addr+4;
3473 +                       return 2;
3474 +               }
3475 +       }
3476 +
3477 +       do { /* PaX: patched PLT emulation #3 */
3478 +               unsigned int sethi, jmpl, nop;
3479 +
3480 +               err = get_user(sethi, (unsigned int*)regs->pc);
3481 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
3482 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
3483 +
3484 +               if (err)
3485 +                       break;
3486 +
3487 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3488 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3489 +                   nop == 0x01000000U)
3490 +               {
3491 +                       unsigned int addr;
3492 +
3493 +                       addr = (sethi & 0x003FFFFFU) << 10;
3494 +                       regs->u_regs[UREG_G1] = addr;
3495 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3496 +                       regs->pc = addr;
3497 +                       regs->npc = addr+4;
3498 +                       return 2;
3499 +               }
3500 +       } while (0);
3501 +
3502 +       do { /* PaX: unpatched PLT emulation step 1 */
3503 +               unsigned int sethi, ba, nop;
3504 +
3505 +               err = get_user(sethi, (unsigned int*)regs->pc);
3506 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
3507 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
3508 +
3509 +               if (err)
3510 +                       break;
3511 +
3512 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3513 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
3514 +                   nop == 0x01000000U)
3515 +               {
3516 +                       unsigned int addr, save, call;
3517 +
3518 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
3519 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3520 +                       else
3521 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
3522 +
3523 +                       err = get_user(save, (unsigned int*)addr);
3524 +                       err |= get_user(call, (unsigned int*)(addr+4));
3525 +                       err |= get_user(nop, (unsigned int*)(addr+8));
3526 +                       if (err)
3527 +                               break;
3528 +
3529 +                       if (save == 0x9DE3BFA8U &&
3530 +                           (call & 0xC0000000U) == 0x40000000U &&
3531 +                           nop == 0x01000000U)
3532 +                       {
3533 +                               struct vm_area_struct *vma;
3534 +                               unsigned long call_dl_resolve;
3535 +
3536 +                               down_read(&current->mm->mmap_sem);
3537 +                               call_dl_resolve = current->mm->call_dl_resolve;
3538 +                               up_read(&current->mm->mmap_sem);
3539 +                               if (likely(call_dl_resolve))
3540 +                                       goto emulate;
3541 +
3542 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3543 +
3544 +                               down_write(&current->mm->mmap_sem);
3545 +                               if (current->mm->call_dl_resolve) {
3546 +                                       call_dl_resolve = current->mm->call_dl_resolve;
3547 +                                       up_write(&current->mm->mmap_sem);
3548 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3549 +                                       goto emulate;
3550 +                               }
3551 +
3552 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3553 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3554 +                                       up_write(&current->mm->mmap_sem);
3555 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3556 +                                       return 1;
3557 +                               }
3558 +
3559 +                               pax_insert_vma(vma, call_dl_resolve);
3560 +                               current->mm->call_dl_resolve = call_dl_resolve;
3561 +                               up_write(&current->mm->mmap_sem);
3562 +
3563 +emulate:
3564 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3565 +                               regs->pc = call_dl_resolve;
3566 +                               regs->npc = addr+4;
3567 +                               return 3;
3568 +                       }
3569 +               }
3570 +       } while (0);
3571 +
3572 +       do { /* PaX: unpatched PLT emulation step 2 */
3573 +               unsigned int save, call, nop;
3574 +
3575 +               err = get_user(save, (unsigned int*)(regs->pc-4));
3576 +               err |= get_user(call, (unsigned int*)regs->pc);
3577 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
3578 +               if (err)
3579 +                       break;
3580 +
3581 +               if (save == 0x9DE3BFA8U &&
3582 +                   (call & 0xC0000000U) == 0x40000000U &&
3583 +                   nop == 0x01000000U)
3584 +               {
3585 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
3586 +
3587 +                       regs->u_regs[UREG_RETPC] = regs->pc;
3588 +                       regs->pc = dl_resolve;
3589 +                       regs->npc = dl_resolve+4;
3590 +                       return 3;
3591 +               }
3592 +       } while (0);
3593 +#endif
3594 +
3595 +       return 1;
3596 +}
3597 +
3598 +void pax_report_insns(void *pc, void *sp)
3599 +{
3600 +       unsigned long i;
3601 +
3602 +       printk(KERN_ERR "PAX: bytes at PC: ");
3603 +       for (i = 0; i < 5; i++) {
3604 +               unsigned int c;
3605 +               if (get_user(c, (unsigned int*)pc+i)) {
3606 +                       printk("<invalid address>.");
3607 +                       break;
3608 +               }
3609 +               printk("%08x ", c);
3610 +       }
3611 +       printk("\n");
3612 +}
3613 +#endif
3614 +
3615  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
3616                                unsigned long address)
3617  {
3618 @@ -283,6 +550,29 @@
3619                 if(!(vma->vm_flags & VM_WRITE))
3620                         goto bad_area;
3621         } else {
3622 +
3623 +#ifdef CONFIG_PAX_PAGEEXEC
3624 +               if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
3625 +                       up_read(&mm->mmap_sem);
3626 +                       switch (pax_handle_fetch_fault(regs)) {
3627 +
3628 +#ifdef CONFIG_PAX_EMUPLT
3629 +                       case 2:
3630 +                       case 3:
3631 +                               return;
3632 +#endif
3633 +
3634 +#ifdef CONFIG_PAX_RANDEXEC
3635 +                       case 4:
3636 +                               return;
3637 +#endif
3638 +
3639 +                       }
3640 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
3641 +                       do_exit(SIGKILL);
3642 +               }
3643 +#endif
3644 +
3645                 /* Allow reads even for write-only mappings */
3646                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
3647                         goto bad_area;
3648 diff -uNr linux-2.6.8/arch/sparc/mm/init.c linux-2.6.8.grsecurity/arch/sparc/mm/init.c
3649 --- linux-2.6.8/arch/sparc/mm/init.c    2004-08-14 07:36:56.000000000 +0200
3650 +++ linux-2.6.8.grsecurity/arch/sparc/mm/init.c 2004-08-16 17:06:18.982053136 +0200
3651 @@ -337,17 +337,17 @@
3652  
3653         /* Initialize the protection map with non-constant, MMU dependent values. */
3654         protection_map[0] = PAGE_NONE;
3655 -       protection_map[1] = PAGE_READONLY;
3656 -       protection_map[2] = PAGE_COPY;
3657 -       protection_map[3] = PAGE_COPY;
3658 +       protection_map[1] = PAGE_READONLY_NOEXEC;
3659 +       protection_map[2] = PAGE_COPY_NOEXEC;
3660 +       protection_map[3] = PAGE_COPY_NOEXEC;
3661         protection_map[4] = PAGE_READONLY;
3662         protection_map[5] = PAGE_READONLY;
3663         protection_map[6] = PAGE_COPY;
3664         protection_map[7] = PAGE_COPY;
3665         protection_map[8] = PAGE_NONE;
3666 -       protection_map[9] = PAGE_READONLY;
3667 -       protection_map[10] = PAGE_SHARED;
3668 -       protection_map[11] = PAGE_SHARED;
3669 +       protection_map[9] = PAGE_READONLY_NOEXEC;
3670 +       protection_map[10] = PAGE_SHARED_NOEXEC;
3671 +       protection_map[11] = PAGE_SHARED_NOEXEC;
3672         protection_map[12] = PAGE_READONLY;
3673         protection_map[13] = PAGE_READONLY;
3674         protection_map[14] = PAGE_SHARED;
3675 diff -uNr linux-2.6.8/arch/sparc/mm/srmmu.c linux-2.6.8.grsecurity/arch/sparc/mm/srmmu.c
3676 --- linux-2.6.8/arch/sparc/mm/srmmu.c   2004-08-14 07:37:14.000000000 +0200
3677 +++ linux-2.6.8.grsecurity/arch/sparc/mm/srmmu.c        2004-08-16 17:06:18.991051768 +0200
3678 @@ -2145,6 +2145,13 @@
3679         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
3680         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
3681         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
3682 +
3683 +#ifdef CONFIG_PAX_PAGEEXEC
3684 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
3685 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
3686 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
3687 +#endif
3688 +
3689         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
3690         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
3691         pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
3692 diff -uNr linux-2.6.8/arch/sparc64/kernel/itlb_base.S linux-2.6.8.grsecurity/arch/sparc64/kernel/itlb_base.S
3693 --- linux-2.6.8/arch/sparc64/kernel/itlb_base.S 2004-08-14 07:36:16.000000000 +0200
3694 +++ linux-2.6.8.grsecurity/arch/sparc64/kernel/itlb_base.S      2004-08-16 17:06:19.045043560 +0200
3695 @@ -74,8 +74,6 @@
3696  /* ITLB ** ICACHE line 4: Unused...    */
3697         nop
3698         nop
3699 -       nop
3700 -       nop
3701         CREATE_VPTE_NOP
3702  
3703  #undef CREATE_VPTE_OFFSET1
3704 diff -uNr linux-2.6.8/arch/sparc64/kernel/ptrace.c linux-2.6.8.grsecurity/arch/sparc64/kernel/ptrace.c
3705 --- linux-2.6.8/arch/sparc64/kernel/ptrace.c    2004-08-14 07:38:08.000000000 +0200
3706 +++ linux-2.6.8.grsecurity/arch/sparc64/kernel/ptrace.c 2004-08-16 17:06:19.063040824 +0200
3707 @@ -19,6 +19,7 @@
3708  #include <linux/smp.h>
3709  #include <linux/smp_lock.h>
3710  #include <linux/security.h>
3711 +#include <linux/grsecurity.h>
3712  
3713  #include <asm/asi.h>
3714  #include <asm/pgtable.h>
3715 @@ -173,6 +174,11 @@
3716                 goto out;
3717         }
3718  
3719 +       if (gr_handle_ptrace(child, (long)request)) {
3720 +               pt_error_return(regs, EPERM);
3721 +               goto out_tsk;
3722 +       }
3723 +
3724         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3725             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3726                 if (ptrace_attach(child)) {
3727 diff -uNr linux-2.6.8/arch/sparc64/kernel/sys_sparc32.c linux-2.6.8.grsecurity/arch/sparc64/kernel/sys_sparc32.c
3728 --- linux-2.6.8/arch/sparc64/kernel/sys_sparc32.c       2004-08-14 07:37:15.000000000 +0200
3729 +++ linux-2.6.8.grsecurity/arch/sparc64/kernel/sys_sparc32.c    2004-08-16 17:06:19.090036720 +0200
3730 @@ -54,6 +54,7 @@
3731  #include <linux/netfilter_ipv4/ip_tables.h>
3732  #include <linux/ptrace.h>
3733  #include <linux/highuid.h>
3734 +#include <linux/grsecurity.h>
3735  
3736  #include <asm/types.h>
3737  #include <asm/ipc.h>
3738 diff -uNr linux-2.6.8/arch/sparc64/kernel/sys_sparc.c linux-2.6.8.grsecurity/arch/sparc64/kernel/sys_sparc.c
3739 --- linux-2.6.8/arch/sparc64/kernel/sys_sparc.c 2004-08-14 07:37:14.000000000 +0200
3740 +++ linux-2.6.8.grsecurity/arch/sparc64/kernel/sys_sparc.c      2004-08-16 17:06:19.077038696 +0200
3741 @@ -25,6 +25,7 @@
3742  #include <linux/syscalls.h>
3743  #include <linux/ipc.h>
3744  #include <linux/personality.h>
3745 +#include <linux/grsecurity.h>
3746  
3747  #include <asm/uaccess.h>
3748  #include <asm/ipc.h>
3749 @@ -49,7 +50,7 @@
3750  {
3751         struct mm_struct *mm = current->mm;
3752         struct vm_area_struct * vma;
3753 -       unsigned long task_size = TASK_SIZE;
3754 +       unsigned long task_size = TASK_SIZE, task_unmapped_base = TASK_UNMAPPED_BASE;
3755         unsigned long start_addr;
3756         int do_color_align;
3757  
3758 @@ -72,6 +73,12 @@
3759         if (filp || (flags & MAP_SHARED))
3760                 do_color_align = 1;
3761  
3762 +#ifdef CONFIG_PAX_RANDMMAP
3763 +       if (current->flags & PF_PAX_RANDMMAP)
3764 +               task_unmapped_base += mm->delta_mmap;
3765 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
3766 +#endif
3767 +
3768         if (addr) {
3769                 if (do_color_align)
3770                         addr = COLOUR_ALIGN(addr, pgoff);
3771 @@ -101,8 +108,8 @@
3772                         vma = find_vma(mm, PAGE_OFFSET);
3773                 }
3774                 if (task_size < addr) {
3775 -                       if (start_addr != TASK_UNMAPPED_BASE) {
3776 -                               start_addr = addr = TASK_UNMAPPED_BASE;
3777 +                       if (start_addr != task_unmapped_base) {
3778 +                               start_addr = addr = task_unmapped_base;
3779                                 goto full_search;
3780                         }
3781                         return -ENOMEM;
3782 @@ -319,11 +326,22 @@
3783         struct file * file = NULL;
3784         unsigned long retval = -EBADF;
3785  
3786 +#ifdef CONFIG_PAX_RANDEXEC
3787 +       if (flags & MAP_MIRROR)
3788 +               return -EINVAL;
3789 +#endif
3790 +
3791         if (!(flags & MAP_ANONYMOUS)) {
3792                 file = fget(fd);
3793                 if (!file)
3794                         goto out;
3795         }
3796 +
3797 +       if (gr_handle_mmap(file, prot)) {
3798 +               retval = -EACCES;
3799 +               goto out_putf;
3800 +       }
3801 +
3802         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3803         len = PAGE_ALIGN(len);
3804         retval = -EINVAL;
3805 diff -uNr linux-2.6.8/arch/sparc64/kernel/sys_sunos32.c linux-2.6.8.grsecurity/arch/sparc64/kernel/sys_sunos32.c
3806 --- linux-2.6.8/arch/sparc64/kernel/sys_sunos32.c       2004-08-14 07:37:15.000000000 +0200
3807 +++ linux-2.6.8.grsecurity/arch/sparc64/kernel/sys_sunos32.c    2004-08-16 17:06:19.111033528 +0200
3808 @@ -66,6 +66,11 @@
3809         struct file *file = NULL;
3810         unsigned long retval, ret_type;
3811  
3812 +#ifdef CONFIG_PAX_RANDEXEC
3813 +       if (flags & MAP_MIRROR)
3814 +               return -EINVAL;
3815 +#endif
3816 +
3817         if (flags & MAP_NORESERVE) {
3818                 static int cnt;
3819                 if (cnt++ < 10)
3820 diff -uNr linux-2.6.8/arch/sparc64/mm/fault.c linux-2.6.8.grsecurity/arch/sparc64/mm/fault.c
3821 --- linux-2.6.8/arch/sparc64/mm/fault.c 2004-08-14 07:38:04.000000000 +0200
3822 +++ linux-2.6.8.grsecurity/arch/sparc64/mm/fault.c      2004-08-16 17:06:19.171024408 +0200
3823 @@ -18,6 +18,10 @@
3824  #include <linux/smp_lock.h>
3825  #include <linux/init.h>
3826  #include <linux/interrupt.h>
3827 +#include <linux/slab.h>
3828 +#include <linux/pagemap.h>
3829 +#include <linux/compiler.h>
3830 +#include <linux/binfmts.h>
3831  
3832  #include <asm/page.h>
3833  #include <asm/pgtable.h>
3834 @@ -310,6 +314,361 @@
3835         unhandled_fault (address, current, regs);
3836  }
3837  
3838 +#ifdef CONFIG_PAX_PAGEEXEC
3839 +#ifdef CONFIG_PAX_EMUPLT
3840 +static void pax_emuplt_close(struct vm_area_struct * vma)
3841 +{
3842 +       vma->vm_mm->call_dl_resolve = 0UL;
3843 +}
3844 +
3845 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
3846 +{
3847 +       struct page* page;
3848 +       unsigned int *kaddr;
3849 +
3850 +       page = alloc_page(GFP_HIGHUSER);
3851 +       if (!page)
3852 +               return NOPAGE_OOM;
3853 +
3854 +       kaddr = kmap(page);
3855 +       memset(kaddr, 0, PAGE_SIZE);
3856 +       kaddr[0] = 0x9DE3BFA8U; /* save */
3857 +       flush_dcache_page(page);
3858 +       kunmap(page);
3859 +       if (type)
3860 +               *type = VM_FAULT_MAJOR;
3861 +       return page;
3862 +}
3863 +
3864 +static struct vm_operations_struct pax_vm_ops = {
3865 +       close:          pax_emuplt_close,
3866 +       nopage:         pax_emuplt_nopage,
3867 +};
3868 +
3869 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3870 +{
3871 +       memset(vma, 0, sizeof(*vma));
3872 +       vma->vm_mm = current->mm;
3873 +       vma->vm_start = addr;
3874 +       vma->vm_end = addr + PAGE_SIZE;
3875 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3876 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3877 +       vma->vm_ops = &pax_vm_ops;
3878 +       insert_vm_struct(current->mm, vma);
3879 +       ++current->mm->total_vm;
3880 +}
3881 +#endif
3882 +
3883 +/*
3884 + * PaX: decide what to do with offenders (regs->tpc = fault address)
3885 + *
3886 + * returns 1 when task should be killed
3887 + *         2 when patched PLT trampoline was detected
3888 + *         3 when unpatched PLT trampoline was detected
3889 + *         4 when legitimate ET_EXEC was detected
3890 + */
3891 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3892 +{
3893 +
3894 +#ifdef CONFIG_PAX_EMUPLT
3895 +       int err;
3896 +#endif
3897 +
3898 +#ifdef CONFIG_PAX_RANDEXEC
3899 +       if (current->flags & PF_PAX_RANDEXEC) {
3900 +               if (regs->tpc >= current->mm->start_code &&
3901 +                   regs->tpc < current->mm->end_code)
3902 +               {
3903 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
3904 +                               return 1;
3905 +
3906 +                       regs->tpc += current->mm->delta_exec;
3907 +                       if (regs->tnpc >= current->mm->start_code &&
3908 +                           regs->tnpc < current->mm->end_code)
3909 +                               regs->tnpc += current->mm->delta_exec;
3910 +                       return 4;
3911 +               }
3912 +               if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
3913 +                   regs->tpc < current->mm->end_code + current->mm->delta_exec)
3914 +               {
3915 +                       regs->tpc -= current->mm->delta_exec;
3916 +                       if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
3917 +                           regs->tnpc < current->mm->end_code + current->mm->delta_exec)
3918 +                               regs->tnpc -= current->mm->delta_exec;
3919 +               }
3920 +       }
3921 +#endif
3922 +
3923 +#ifdef CONFIG_PAX_EMUPLT
3924 +       do { /* PaX: patched PLT emulation #1 */
3925 +               unsigned int sethi1, sethi2, jmpl;
3926 +
3927 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
3928 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
3929 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
3930 +
3931 +               if (err)
3932 +                       break;
3933 +
3934 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3935 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
3936 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
3937 +               {
3938 +                       unsigned long addr;
3939 +
3940 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3941 +                       addr = regs->u_regs[UREG_G1];
3942 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3943 +                       regs->tpc = addr;
3944 +                       regs->tnpc = addr+4;
3945 +                       return 2;
3946 +               }
3947 +       } while (0);
3948 +
3949 +       { /* PaX: patched PLT emulation #2 */
3950 +               unsigned int ba;
3951 +
3952 +               err = get_user(ba, (unsigned int*)regs->tpc);
3953 +
3954 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3955 +                       unsigned long addr;
3956 +
3957 +                       addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL);
3958 +                       regs->tpc = addr;
3959 +                       regs->tnpc = addr+4;
3960 +                       return 2;
3961 +               }
3962 +       }
3963 +
3964 +       do { /* PaX: patched PLT emulation #3 */
3965 +               unsigned int sethi, jmpl, nop;
3966 +
3967 +               err = get_user(sethi, (unsigned int*)regs->tpc);
3968 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
3969 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
3970 +
3971 +               if (err)
3972 +                       break;
3973 +
3974 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3975 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3976 +                   nop == 0x01000000U)
3977 +               {
3978 +                       unsigned long addr;
3979 +
3980 +                       addr = (sethi & 0x003FFFFFU) << 10;
3981 +                       regs->u_regs[UREG_G1] = addr;
3982 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3983 +                       regs->tpc = addr;
3984 +                       regs->tnpc = addr+4;
3985 +                       return 2;
3986 +               }
3987 +       } while (0);
3988 +
3989 +       do { /* PaX: patched PLT emulation #4 */
3990 +               unsigned int mov1, call, mov2;
3991 +
3992 +               err = get_user(mov1, (unsigned int*)regs->tpc);
3993 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
3994 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
3995 +
3996 +               if (err)
3997 +                       break;
3998 +
3999 +               if (mov1 == 0x8210000FU &&
4000 +                   (call & 0xC0000000U) == 0x40000000U &&
4001 +                   mov2 == 0x9E100001U)
4002 +               {
4003 +                       unsigned long addr;
4004 +
4005 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
4006 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4007 +                       regs->tpc = addr;
4008 +                       regs->tnpc = addr+4;
4009 +                       return 2;
4010 +               }
4011 +       } while (0);
4012 +
4013 +       do { /* PaX: patched PLT emulation #5 */
4014 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
4015 +
4016 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4017 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4018 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
4019 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
4020 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
4021 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
4022 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
4023 +
4024 +               if (err)
4025 +                       break;
4026 +
4027 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4028 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4029 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
4030 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
4031 +                   sllx == 0x83287020 &&
4032 +                   jmpl == 0x81C04005U &&
4033 +                   nop == 0x01000000U)
4034 +               {
4035 +                       unsigned long addr;
4036 +
4037 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
4038 +                       regs->u_regs[UREG_G1] <<= 32;
4039 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
4040 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4041 +                       regs->tpc = addr;
4042 +                       regs->tnpc = addr+4;
4043 +                       return 2;
4044 +               }
4045 +       } while (0);
4046 +
4047 +       do { /* PaX: patched PLT emulation #6 */
4048 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
4049 +
4050 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
4051 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
4052 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
4053 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
4054 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
4055 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
4056 +
4057 +               if (err)
4058 +                       break;
4059 +
4060 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4061 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4062 +                   sllx == 0x83287020 &&
4063 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
4064 +                   jmpl == 0x81C04005U &&
4065 +                   nop == 0x01000000U)
4066 +               {
4067 +                       unsigned long addr;
4068 +
4069 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
4070 +                       regs->u_regs[UREG_G1] <<= 32;
4071 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
4072 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4073 +                       regs->tpc = addr;
4074 +                       regs->tnpc = addr+4;
4075 +                       return 2;
4076 +               }
4077 +       } while (0);
4078 +
4079 +       do { /* PaX: unpatched PLT emulation step 1 */
4080 +               unsigned int sethi, ba, nop;
4081 +
4082 +               err = get_user(sethi, (unsigned int*)regs->tpc);
4083 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
4084 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
4085 +
4086 +               if (err)
4087 +                       break;
4088 +
4089 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
4090 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4091 +                   nop == 0x01000000U)
4092 +               {
4093 +                       unsigned long addr;
4094 +                       unsigned int save, call;
4095 +
4096 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
4097 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4098 +                       else
4099 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4100 +
4101 +                       err = get_user(save, (unsigned int*)addr);
4102 +                       err |= get_user(call, (unsigned int*)(addr+4));
4103 +                       err |= get_user(nop, (unsigned int*)(addr+8));
4104 +                       if (err)
4105 +                               break;
4106 +
4107 +                       if (save == 0x9DE3BFA8U &&
4108 +                           (call & 0xC0000000U) == 0x40000000U &&
4109 +                           nop == 0x01000000U)
4110 +                       {
4111 +                               struct vm_area_struct *vma;
4112 +                               unsigned long call_dl_resolve;
4113 +
4114 +                               down_read(&current->mm->mmap_sem);
4115 +                               call_dl_resolve = current->mm->call_dl_resolve;
4116 +                               up_read(&current->mm->mmap_sem);
4117 +                               if (likely(call_dl_resolve))
4118 +                                       goto emulate;
4119 +
4120 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
4121 +
4122 +                               down_write(&current->mm->mmap_sem);
4123 +                               if (current->mm->call_dl_resolve) {
4124 +                                       call_dl_resolve = current->mm->call_dl_resolve;
4125 +                                       up_write(&current->mm->mmap_sem);
4126 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4127 +                                       goto emulate;
4128 +                               }
4129 +
4130 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4131 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4132 +                                       up_write(&current->mm->mmap_sem);
4133 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
4134 +                                       return 1;
4135 +                               }
4136 +
4137 +                               pax_insert_vma(vma, call_dl_resolve);
4138 +                               current->mm->call_dl_resolve = call_dl_resolve;
4139 +                               up_write(&current->mm->mmap_sem);
4140 +
4141 +emulate:
4142 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4143 +                               regs->tpc = call_dl_resolve;
4144 +                               regs->tnpc = addr+4;
4145 +                               return 3;
4146 +                       }
4147 +               }
4148 +       } while (0);
4149 +
4150 +       do { /* PaX: unpatched PLT emulation step 2 */
4151 +               unsigned int save, call, nop;
4152 +
4153 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
4154 +               err |= get_user(call, (unsigned int*)regs->tpc);
4155 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
4156 +               if (err)
4157 +                       break;
4158 +
4159 +               if (save == 0x9DE3BFA8U &&
4160 +                   (call & 0xC0000000U) == 0x40000000U &&
4161 +                   nop == 0x01000000U)
4162 +               {
4163 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4164 +
4165 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
4166 +                       regs->tpc = dl_resolve;
4167 +                       regs->tnpc = dl_resolve+4;
4168 +                       return 3;
4169 +               }
4170 +       } while (0);
4171 +#endif
4172 +
4173 +       return 1;
4174 +}
4175 +
4176 +void pax_report_insns(void *pc, void *sp)
4177 +{
4178 +       unsigned long i;
4179 +
4180 +       printk(KERN_ERR "PAX: bytes at PC: ");
4181 +       for (i = 0; i < 5; i++) {
4182 +               unsigned int c;
4183 +               if (get_user(c, (unsigned int*)pc+i)) {
4184 +                       printk("<invalid address>.");
4185 +                       break;
4186 +               }
4187 +               printk("%08x ", c);
4188 +       }
4189 +       printk("\n");
4190 +}
4191 +#endif
4192 +
4193  asmlinkage void do_sparc64_fault(struct pt_regs *regs)
4194  {
4195         struct mm_struct *mm = current->mm;
4196 @@ -347,8 +706,10 @@
4197                 goto intr_or_no_mm;
4198  
4199         if (test_thread_flag(TIF_32BIT)) {
4200 -               if (!(regs->tstate & TSTATE_PRIV))
4201 +               if (!(regs->tstate & TSTATE_PRIV)) {
4202                         regs->tpc &= 0xffffffff;
4203 +                       regs->tnpc &= 0xffffffff;
4204 +               }
4205                 address &= 0xffffffff;
4206         }
4207  
4208 @@ -357,6 +718,34 @@
4209         if (!vma)
4210                 goto bad_area;
4211  
4212 +#ifdef CONFIG_PAX_PAGEEXEC
4213 +       /* PaX: detect ITLB misses on non-exec pages */
4214 +       if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address &&
4215 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
4216 +       {
4217 +               if (address != regs->tpc)
4218 +                       goto good_area;
4219 +
4220 +               up_read(&mm->mmap_sem);
4221 +               switch (pax_handle_fetch_fault(regs)) {
4222 +
4223 +#ifdef CONFIG_PAX_EMUPLT
4224 +               case 2:
4225 +               case 3:
4226 +                       goto fault_done;
4227 +#endif
4228 +
4229 +#ifdef CONFIG_PAX_RANDEXEC
4230 +               case 4:
4231 +                       goto fault_done;
4232 +#endif
4233 +
4234 +               }
4235 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
4236 +               do_exit(SIGKILL);
4237 +       }
4238 +#endif
4239 +
4240         /* Pure DTLB misses do not tell us whether the fault causing
4241          * load/store/atomic was a write or not, it only says that there
4242          * was no match.  So in such a case we (carefully) read the
4243 diff -uNr linux-2.6.8/arch/sparc64/solaris/misc.c linux-2.6.8.grsecurity/arch/sparc64/solaris/misc.c
4244 --- linux-2.6.8/arch/sparc64/solaris/misc.c     2004-08-14 07:38:04.000000000 +0200
4245 +++ linux-2.6.8.grsecurity/arch/sparc64/solaris/misc.c  2004-08-16 17:06:19.209018632 +0200
4246 @@ -56,6 +56,11 @@
4247         struct file *file = NULL;
4248         unsigned long retval, ret_type;
4249  
4250 +#ifdef CONFIG_PAX_RANDEXEC
4251 +       if (flags & MAP_MIRROR)
4252 +               return -EINVAL;
4253 +#endif
4254 +
4255         /* Do we need it here? */
4256         set_personality(PER_SVR4);
4257         if (flags & MAP_NORESERVE) {
4258 diff -uNr linux-2.6.8/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.8.grsecurity/arch/x86_64/ia32/ia32_binfmt.c
4259 --- linux-2.6.8/arch/x86_64/ia32/ia32_binfmt.c  2004-08-14 07:36:12.000000000 +0200
4260 +++ linux-2.6.8.grsecurity/arch/x86_64/ia32/ia32_binfmt.c       2004-08-16 17:06:19.234014832 +0200
4261 @@ -185,6 +185,17 @@
4262  //#include <asm/ia32.h>
4263  #include <linux/elf.h>
4264  
4265 +#ifdef CONFIG_PAX_ASLR
4266 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
4267 +
4268 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
4269 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
4270 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
4271 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
4272 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
4273 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 24)
4274 +#endif
4275 +
4276  typedef struct user_i387_ia32_struct elf_fpregset_t;
4277  typedef struct user32_fxsr_struct elf_fpxregset_t;
4278  
4279 @@ -361,7 +372,13 @@
4280                 else if (executable_stack == EXSTACK_DISABLE_X)
4281                         mpnt->vm_flags = vm_stack_flags32 & ~VM_EXEC;
4282                 else
4283 +
4284 +#ifdef CONFIG_PAX_PAGEEXEC
4285 +                       mpnt->vm_flags = VM_STACK_FLAGS;
4286 +#else
4287                         mpnt->vm_flags = vm_stack_flags32;
4288 +#endif
4289 +
4290                 mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? 
4291                         PAGE_COPY_EXEC : PAGE_COPY;
4292                 insert_vm_struct(mm, mpnt);
4293 diff -uNr linux-2.6.8/arch/x86_64/ia32/sys_ia32.c linux-2.6.8.grsecurity/arch/x86_64/ia32/sys_ia32.c
4294 --- linux-2.6.8/arch/x86_64/ia32/sys_ia32.c     2004-08-14 07:36:56.000000000 +0200
4295 +++ linux-2.6.8.grsecurity/arch/x86_64/ia32/sys_ia32.c  2004-08-16 17:06:19.253011944 +0200
4296 @@ -212,6 +212,11 @@
4297         if (a.offset & ~PAGE_MASK)
4298                 return -EINVAL; 
4299  
4300 +#ifdef CONFIG_PAX_RANDEXEC
4301 +       if (a.flags & MAP_MIRROR)
4302 +               return -EINVAL;
4303 +#endif
4304 +
4305         if (!(a.flags & MAP_ANONYMOUS)) {
4306                 file = fget(a.fd);
4307                 if (!file)
4308 @@ -1037,6 +1042,11 @@
4309         unsigned long error;
4310         struct file * file = NULL;
4311  
4312 +#ifdef CONFIG_PAX_RANDEXEC
4313 +       if (flags & MAP_MIRROR)
4314 +               return -EINVAL;
4315 +#endif
4316 +
4317         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
4318         if (!(flags & MAP_ANONYMOUS)) {
4319                 file = fget(fd);
4320 diff -uNr linux-2.6.8/arch/x86_64/kernel/ptrace.c linux-2.6.8.grsecurity/arch/x86_64/kernel/ptrace.c
4321 --- linux-2.6.8/arch/x86_64/kernel/ptrace.c     2004-08-14 07:36:44.000000000 +0200
4322 +++ linux-2.6.8.grsecurity/arch/x86_64/kernel/ptrace.c  2004-08-16 17:06:19.278008144 +0200
4323 @@ -213,6 +213,9 @@
4324         if (pid == 1)           /* you may not mess with init */
4325                 goto out_tsk;
4326  
4327 +        if (gr_handle_ptrace(child, request))
4328 +                goto out_tsk;
4329 +
4330         if (request == PTRACE_ATTACH) {
4331                 ret = ptrace_attach(child);
4332                 goto out_tsk;
4333 diff -uNr linux-2.6.8/arch/x86_64/kernel/setup64.c linux-2.6.8.grsecurity/arch/x86_64/kernel/setup64.c
4334 --- linux-2.6.8/arch/x86_64/kernel/setup64.c    2004-08-14 07:36:33.000000000 +0200
4335 +++ linux-2.6.8.grsecurity/arch/x86_64/kernel/setup64.c 2004-08-16 17:06:19.280007840 +0200
4336 @@ -43,8 +43,15 @@
4337  
4338  unsigned long __supported_pte_mask = ~0UL;
4339  static int do_not_nx __initdata = 0;
4340 +
4341 +#ifdef CONFIG_PAX_PAGEEXEC
4342 +unsigned long vm_stack_flags = VM_GROWSDOWN | __VM_DATA_DEFAULT_FLAGS;
4343 +unsigned long vm_stack_flags32 = VM_GROWSDOWN | __VM_DATA_DEFAULT_FLAGS;
4344 +#else
4345  unsigned long vm_stack_flags = __VM_STACK_FLAGS; 
4346  unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; 
4347 +#endif
4348 +
4349  unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; 
4350  unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; 
4351  unsigned long vm_force_exec32 = PROT_EXEC; 
4352 diff -uNr linux-2.6.8/arch/x86_64/kernel/sys_x86_64.c linux-2.6.8.grsecurity/arch/x86_64/kernel/sys_x86_64.c
4353 --- linux-2.6.8/arch/x86_64/kernel/sys_x86_64.c 2004-08-14 07:37:25.000000000 +0200
4354 +++ linux-2.6.8.grsecurity/arch/x86_64/kernel/sys_x86_64.c      2004-08-16 17:06:19.290006320 +0200
4355 @@ -48,6 +48,11 @@
4356         if (off & ~PAGE_MASK)
4357                 goto out;
4358  
4359 +#ifdef CONFIG_PAX_RANDEXEC
4360 +       if (flags & MAP_MIRROR)
4361 +               goto out;
4362 +#endif
4363 +
4364         error = -EBADF;
4365         file = NULL;
4366         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
4367 @@ -102,6 +107,15 @@
4368         
4369         find_start_end(flags, &begin, &end); 
4370  
4371 +#ifdef CONFIG_PAX_RANDMMAP
4372 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp)) {
4373 +               if (begin == 0x40000000)
4374 +                       begin += current->mm->delta_mmap & 0x0FFFFFFFU;
4375 +               else
4376 +                       begin += current->mm->delta_mmap;
4377 +       }
4378 +#endif
4379 +
4380         if (len > end)
4381                 return -ENOMEM;
4382  
4383 diff -uNr linux-2.6.8/arch/x86_64/mm/fault.c linux-2.6.8.grsecurity/arch/x86_64/mm/fault.c
4384 --- linux-2.6.8/arch/x86_64/mm/fault.c  2004-08-14 07:36:11.000000000 +0200
4385 +++ linux-2.6.8.grsecurity/arch/x86_64/mm/fault.c       2004-08-16 17:06:19.312002976 +0200
4386 @@ -23,6 +23,7 @@
4387  #include <linux/vt_kern.h>             /* For unblank_screen() */
4388  #include <linux/compiler.h>
4389  #include <linux/module.h>
4390 +#include <linux/binfmts.h>
4391  
4392  #include <asm/system.h>
4393  #include <asm/uaccess.h>
4394 @@ -218,6 +219,63 @@
4395                 (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
4396  }
4397  
4398 +#ifdef CONFIG_PAX_PAGEEXEC
4399 +/*
4400 + * PaX: decide what to do with offenders (regs->rip = fault address)
4401 + *
4402 + * returns 1 when task should be killed
4403 + *         2 when legitimate ET_EXEC was detected
4404 + */
4405 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4406 +{
4407 +
4408 +#ifdef CONFIG_PAX_RANDEXEC
4409 +       int err;
4410 +
4411 +       if (current->flags & PF_PAX_RANDEXEC) {
4412 +               if (regs->rip >= current->mm->start_code &&
4413 +                   regs->rip < current->mm->end_code)
4414 +               {
4415 +                       if (test_thread_flag(TIF_IA32)) {
4416 +                               unsigned int esp_4;
4417 +
4418 +                               err = get_user(esp_4, (unsigned int*)(regs->rsp-4UL));
4419 +                               if (err || esp_4 == regs->rip)
4420 +                                       return 1;
4421 +                       } else {
4422 +                               unsigned long esp_8;
4423 +
4424 +                               err = get_user(esp_8, (unsigned long*)(regs->rsp-8UL));
4425 +                               if (err || esp_8 == regs->rip)
4426 +                                       return 1;
4427 +                       }
4428 +
4429 +                       regs->rip += current->mm->delta_exec;
4430 +                       return 2;
4431 +               }
4432 +       }
4433 +#endif
4434 +
4435 +       return 1;
4436 +}
4437 +
4438 +void pax_report_insns(void *pc, void *sp)
4439 +{
4440 +       unsigned long i;
4441 +
4442 +       printk(KERN_ERR "PAX: bytes at PC: ");
4443 +       for (i = 0; i < 20; i++) {
4444 +               unsigned int c;
4445 +               if (get_user(c, (unsigned char*)pc+i)) {
4446 +                       printk("<invalid address>.");
4447 +                       break;
4448 +               }
4449 +               printk("%08x ", c);
4450 +       }
4451 +       printk("\n");
4452 +}
4453 +#endif
4454 +
4455  int page_fault_trace; 
4456  int exception_trace = 1;
4457  
4458 @@ -303,6 +361,23 @@
4459   * we can handle it..
4460   */
4461  good_area:
4462 +
4463 +#ifdef CONFIG_PAX_PAGEEXEC
4464 +       if ((current->flags & PF_PAX_PAGEEXEC) && (error_code & 16) && !(vma->vm_flags & VM_EXEC)) {
4465 +               up_read(&mm->mmap_sem);
4466 +               switch(pax_handle_fetch_fault(regs)) {
4467 +
4468 +#ifdef CONFIG_PAX_RANDEXEC
4469 +               case 2:
4470 +                       return;
4471 +#endif
4472 +
4473 +               }
4474 +               pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
4475 +               do_exit(SIGKILL);
4476 +       }
4477 +#endif
4478 +
4479         info.si_code = SEGV_ACCERR;
4480         write = 0;
4481         switch (error_code & 3) {
4482 diff -uNr linux-2.6.8/drivers/char/keyboard.c linux-2.6.8.grsecurity/drivers/char/keyboard.c
4483 --- linux-2.6.8/drivers/char/keyboard.c 2004-08-14 07:38:11.000000000 +0200
4484 +++ linux-2.6.8.grsecurity/drivers/char/keyboard.c      2004-08-16 17:06:19.352996744 +0200
4485 @@ -605,6 +605,16 @@
4486              kbd->kbdmode == VC_MEDIUMRAW) && 
4487              value != KVAL(K_SAK))
4488                 return;         /* SAK is allowed even in raw mode */
4489 +
4490 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
4491 +       {
4492 +               void *func = fn_handler[value];
4493 +               if (func == fn_show_state || func == fn_show_ptregs ||
4494 +                   func == fn_show_mem)
4495 +                       return;
4496 +       }
4497 +#endif
4498 +
4499         fn_handler[value](vc, regs);
4500  }
4501  
4502 diff -uNr linux-2.6.8/drivers/char/mem.c linux-2.6.8.grsecurity/drivers/char/mem.c
4503 --- linux-2.6.8/drivers/char/mem.c      2004-08-14 07:36:58.000000000 +0200
4504 +++ linux-2.6.8.grsecurity/drivers/char/mem.c   2004-08-16 17:06:19.424985800 +0200
4505 @@ -23,6 +23,7 @@
4506  #include <linux/devfs_fs_kernel.h>
4507  #include <linux/ptrace.h>
4508  #include <linux/device.h>
4509 +#include <linux/grsecurity.h>
4510  
4511  #include <asm/uaccess.h>
4512  #include <asm/io.h>
4513 @@ -38,6 +39,10 @@
4514  extern void tapechar_init(void);
4515  #endif
4516  
4517 +#ifdef CONFIG_GRKERNSEC
4518 +extern struct file_operations grsec_fops;
4519 +#endif
4520 +
4521  /*
4522   * Architectures vary in how they handle caching for addresses
4523   * outside of main memory.
4524 @@ -190,6 +195,12 @@
4525  
4526         if (!valid_phys_addr_range(p, &count))
4527                 return -EFAULT;
4528 +
4529 +#ifdef CONFIG_GRKERNSEC_KMEM
4530 +       gr_handle_mem_write();
4531 +       return -EPERM;
4532 +#endif
4533 +
4534         return do_write_mem(__va(p), p, buf, count, ppos);
4535  }
4536  
4537 @@ -204,6 +215,11 @@
4538                 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
4539  #endif
4540  
4541 +#ifdef CONFIG_GRKERNSEC_KMEM
4542 +       if (gr_handle_mem_mmap(offset, vma))
4543 +               return -EPERM;
4544 +#endif
4545 +
4546         /* Don't try to swap out physical pages.. */
4547         vma->vm_flags |= VM_RESERVED;
4548  
4549 @@ -297,6 +313,11 @@
4550         ssize_t written;
4551         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
4552  
4553 +#ifdef CONFIG_GRKERNSEC_KMEM
4554 +       gr_handle_kmem_write();
4555 +       return -EPERM;
4556 +#endif
4557 +
4558         if (p < (unsigned long) high_memory) {
4559  
4560                 wrote = count;
4561 @@ -423,7 +444,23 @@
4562                         count = size;
4563  
4564                 zap_page_range(vma, addr, count, NULL);
4565 -               zeromap_page_range(vma, addr, count, PAGE_COPY);
4566 +               zeromap_page_range(vma, addr, count, vma->vm_page_prot);
4567 +
4568 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
4569 +               if (vma->vm_flags & VM_MIRROR) {
4570 +                       unsigned long addr_m;
4571 +                       struct vm_area_struct * vma_m;
4572 +
4573 +                       addr_m = vma->vm_start + vma->vm_mirror;
4574 +                       vma_m = find_vma(mm, addr_m);
4575 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
4576 +                               addr_m = addr + vma->vm_mirror;
4577 +                               zap_page_range(vma_m, addr_m, count, NULL);
4578 +                       } else
4579 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
4580 +                                      addr, vma->vm_start);
4581 +               }
4582 +#endif
4583  
4584                 size -= count;
4585                 buf += count;
4586 @@ -572,6 +609,16 @@
4587  
4588  static int open_port(struct inode * inode, struct file * filp)
4589  {
4590 +#ifdef CONFIG_GRKERNSEC_KMEM
4591 +       gr_handle_open_port();
4592 +       return -EPERM;
4593 +#endif
4594 +
4595 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
4596 +}
4597 +
4598 +static int open_mem(struct inode * inode, struct file * filp)
4599 +{
4600         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
4601  }
4602  
4603 @@ -580,7 +627,6 @@
4604  #define full_lseek      null_lseek
4605  #define write_zero     write_null
4606  #define read_full       read_zero
4607 -#define open_mem       open_port
4608  #define open_kmem      open_mem
4609  
4610  static struct file_operations mem_fops = {
4611 @@ -681,6 +727,11 @@
4612                 case 11:
4613                         filp->f_op = &kmsg_fops;
4614                         break;
4615 +#ifdef CONFIG_GRKERNSEC
4616 +               case 12:
4617 +                       filp->f_op = &grsec_fops;
4618 +                       break;
4619 +#endif
4620                 default:
4621                         return -ENXIO;
4622         }
4623 @@ -710,6 +761,9 @@
4624         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
4625         {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
4626         {11,"kmsg",    S_IRUGO | S_IWUSR,           &kmsg_fops},
4627 +#ifdef CONFIG_GRKERNSEC
4628 +       {12,"grsec",   S_IRUSR | S_IWUGO,           &grsec_fops},
4629 +#endif
4630  };
4631  
4632  static struct class_simple *mem_class;
4633 diff -uNr linux-2.6.8/drivers/char/random.c linux-2.6.8.grsecurity/drivers/char/random.c
4634 --- linux-2.6.8/drivers/char/random.c   2004-08-14 07:36:14.000000000 +0200
4635 +++ linux-2.6.8.grsecurity/drivers/char/random.c        2004-08-16 17:06:19.463979872 +0200
4636 @@ -263,9 +263,15 @@
4637  /*
4638   * Configuration information
4639   */
4640 +#ifdef CONFIG_GRKERNSEC_RANDNET
4641 +#define DEFAULT_POOL_SIZE 1024
4642 +#define SECONDARY_POOL_SIZE 256
4643 +#define BATCH_ENTROPY_SIZE 512
4644 +#else
4645  #define DEFAULT_POOL_SIZE 512
4646  #define SECONDARY_POOL_SIZE 128
4647  #define BATCH_ENTROPY_SIZE 256
4648 +#endif
4649  #define USE_SHA
4650  
4651  /*
4652 @@ -2384,6 +2390,29 @@
4653         return halfMD4Transform(hash, keyptr->secret);
4654  }
4655  
4656 +#ifdef CONFIG_GRKERNSEC
4657 +/* the following function is provided by PaX under the GPL */
4658 +unsigned long get_random_long(void)
4659 +{
4660 +       static time_t rekey_time;
4661 +       static __u32 secret[12];
4662 +       time_t t;
4663 +
4664 +       /*
4665 +        * Pick a random secret every REKEY_INTERVAL seconds
4666 +        */
4667 +       t = get_seconds();
4668 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
4669 +               rekey_time = t;
4670 +               get_random_bytes(secret, sizeof(secret));
4671 +       }
4672 +
4673 +       secret[1] = halfMD4Transform(secret+8, secret);
4674 +       secret[0] = halfMD4Transform(secret+8, secret);
4675 +       return *(unsigned long *)secret;
4676 +}
4677 +#endif
4678 +
4679  #ifdef CONFIG_SYN_COOKIES
4680  /*
4681   * Secure SYN cookie computation. This is the algorithm worked out by
4682 @@ -2483,3 +2512,25 @@
4683         return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */
4684  }
4685  #endif
4686 +
4687 +#ifdef CONFIG_PAX_ASLR
4688 +unsigned long pax_get_random_long(void)
4689 +{
4690 +       static time_t   rekey_time;
4691 +       static __u32    secret[12];
4692 +       time_t          t;
4693 +
4694 +       /*
4695 +        * Pick a random secret every REKEY_INTERVAL seconds.
4696 +        */
4697 +       t = get_seconds();
4698 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
4699 +               rekey_time = t;
4700 +               get_random_bytes(secret, sizeof(secret));
4701 +       }
4702 +
4703 +       secret[1] = halfMD4Transform(secret+8, secret);
4704 +       secret[0] = halfMD4Transform(secret+8, secret);
4705 +       return *(unsigned long *)secret;
4706 +}
4707 +#endif
4708 diff -uNr linux-2.6.8/drivers/char/vt_ioctl.c linux-2.6.8.grsecurity/drivers/char/vt_ioctl.c
4709 --- linux-2.6.8/drivers/char/vt_ioctl.c 2004-08-14 07:37:26.000000000 +0200
4710 +++ linux-2.6.8.grsecurity/drivers/char/vt_ioctl.c      2004-08-16 17:06:19.484976680 +0200
4711 @@ -96,6 +96,12 @@
4712         case KDSKBENT:
4713                 if (!perm)
4714                         return -EPERM;
4715 +
4716 +#ifdef CONFIG_GRKERNSEC
4717 +               if (!capable(CAP_SYS_TTY_CONFIG))
4718 +                       return -EPERM;
4719 +#endif
4720 +
4721                 if (!i && v == K_NOSUCHMAP) {
4722                         /* disallocate map */
4723                         key_map = key_maps[s];
4724 @@ -233,6 +239,13 @@
4725                         goto reterr;
4726                 }
4727  
4728 +#ifdef CONFIG_GRKERNSEC
4729 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
4730 +                       return -EPERM;
4731 +                       goto reterr;
4732 +               }
4733 +#endif
4734 +
4735                 q = func_table[i];
4736                 first_free = funcbufptr + (funcbufsize - funcbufleft);
4737                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
4738 diff -uNr linux-2.6.8/drivers/pci/proc.c linux-2.6.8.grsecurity/drivers/pci/proc.c
4739 --- linux-2.6.8/drivers/pci/proc.c      2004-08-14 07:37:14.000000000 +0200
4740 +++ linux-2.6.8.grsecurity/drivers/pci/proc.c   2004-08-16 17:06:19.534969080 +0200
4741 @@ -565,7 +565,15 @@
4742  
4743  static void legacy_proc_init(void)
4744  {
4745 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
4746 +#ifdef CONFIG_GRKERNSEC_PROC_USER
4747 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR, NULL);
4748 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
4749 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
4750 +#endif
4751 +#else
4752         struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
4753 +#endif
4754         if (entry)
4755                 entry->proc_fops = &proc_pci_operations;
4756  }
4757 @@ -594,7 +602,15 @@
4758  {
4759         struct proc_dir_entry *entry;
4760         struct pci_dev *dev = NULL;
4761 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
4762 +#ifdef CONFIG_GRKERNSEC_PROC_USER
4763 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
4764 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
4765 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
4766 +#endif
4767 +#else
4768         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
4769 +#endif
4770         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
4771         if (entry)
4772                 entry->proc_fops = &proc_bus_pci_dev_operations;
4773 diff -uNr linux-2.6.8/drivers/pnp/pnpbios/bioscalls.c linux-2.6.8.grsecurity/drivers/pnp/pnpbios/bioscalls.c
4774 --- linux-2.6.8/drivers/pnp/pnpbios/bioscalls.c 2004-08-14 07:37:26.000000000 +0200
4775 +++ linux-2.6.8.grsecurity/drivers/pnp/pnpbios/bioscalls.c      2004-08-16 17:06:19.557965584 +0200
4776 @@ -79,7 +79,7 @@
4777  set_limit(cpu_gdt_table[cpu][(selname) >> 3], size); \
4778  } while(0)
4779  
4780 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
4781 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
4782  
4783  /*
4784   * At some point we want to use this stack frame pointer to unwind
4785 @@ -107,6 +107,10 @@
4786         struct desc_struct save_desc_40;
4787         int cpu;
4788  
4789 +#ifdef CONFIG_PAX_KERNEXEC
4790 +       unsigned long cr3;
4791 +#endif
4792 +
4793         /*
4794          * PnP BIOSes are generally not terribly re-entrant.
4795          * Also, don't rely on them to save everything correctly.
4796 @@ -115,12 +119,17 @@
4797                 return PNP_FUNCTION_NOT_SUPPORTED;
4798  
4799         cpu = get_cpu();
4800 -       save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
4801 -       cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
4802  
4803         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
4804         spin_lock_irqsave(&pnp_bios_lock, flags);
4805  
4806 +#ifdef CONFIG_PAX_KERNEXEC
4807 +       pax_open_kernel_noirq(cr3);
4808 +#endif
4809 +
4810 +       save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
4811 +       cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
4812 +
4813         /* The lock prevents us bouncing CPU here */
4814         if (ts1_size)
4815                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
4816 @@ -156,9 +165,14 @@
4817                   "i" (0)
4818                 : "memory"
4819         );
4820 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
4821  
4822         cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
4823 +
4824 +#ifdef CONFIG_PAX_KERNEXEC
4825 +       pax_close_kernel_noirq(cr3);
4826 +#endif
4827 +
4828 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
4829         put_cpu();
4830  
4831         /* If we get here and this is set then the PnP BIOS faulted on us. */
4832 diff -uNr linux-2.6.8/drivers/video/vesafb.c linux-2.6.8.grsecurity/drivers/video/vesafb.c
4833 --- linux-2.6.8/drivers/video/vesafb.c  2004-08-14 07:36:14.000000000 +0200
4834 +++ linux-2.6.8.grsecurity/drivers/video/vesafb.c       2004-08-16 17:08:28.000000000 +0200
4835 @@ -250,7 +250,7 @@
4836         if (vesafb_fix.smem_len > 16 * 1024 * 1024)
4837                 vesafb_fix.smem_len = 16 * 1024 * 1024;
4838  
4839 -#ifndef __i386__
4840 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
4841         screen_info.vesapm_seg = 0;
4842  #endif
4843  
4844 diff -uNr linux-2.6.8/fs/binfmt_aout.c linux-2.6.8.grsecurity/fs/binfmt_aout.c
4845 --- linux-2.6.8/fs/binfmt_aout.c        2004-08-14 07:36:32.000000000 +0200
4846 +++ linux-2.6.8.grsecurity/fs/binfmt_aout.c     2004-08-16 17:08:28.000000000 +0200
4847 @@ -24,6 +24,7 @@
4848  #include <linux/binfmts.h>
4849  #include <linux/personality.h>
4850  #include <linux/init.h>
4851 +#include <linux/grsecurity.h>
4852  
4853  #include <asm/system.h>
4854  #include <asm/uaccess.h>
4855 @@ -117,10 +118,12 @@
4856  /* If the size of the dump file exceeds the rlimit, then see what would happen
4857     if we wrote the stack, but not the data area.  */
4858  #ifdef __sparc__
4859 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
4860         if ((dump.u_dsize+dump.u_ssize) >
4861             current->rlim[RLIMIT_CORE].rlim_cur)
4862                 dump.u_dsize = 0;
4863  #else
4864 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
4865         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
4866             current->rlim[RLIMIT_CORE].rlim_cur)
4867                 dump.u_dsize = 0;
4868 @@ -128,10 +131,12 @@
4869  
4870  /* Make sure we have enough room to write the stack and data areas. */
4871  #ifdef __sparc__
4872 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
4873         if ((dump.u_ssize) >
4874             current->rlim[RLIMIT_CORE].rlim_cur)
4875                 dump.u_ssize = 0;
4876  #else
4877 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
4878         if ((dump.u_ssize+1) * PAGE_SIZE >
4879             current->rlim[RLIMIT_CORE].rlim_cur)
4880                 dump.u_ssize = 0;
4881 @@ -281,6 +286,8 @@
4882         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
4883         if (rlim >= RLIM_INFINITY)
4884                 rlim = ~0;
4885 +
4886 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
4887         if (ex.a_data + ex.a_bss > rlim)
4888                 return -ENOMEM;
4889  
4890 @@ -309,10 +316,33 @@
4891                 (current->mm->start_brk = N_BSSADDR(ex));
4892         current->mm->free_area_cache = TASK_UNMAPPED_BASE;
4893  
4894 +#ifdef CONFIG_PAX_RANDMMAP
4895 +       if (current->flags & PF_PAX_RANDMMAP)
4896 +               current->mm->free_area_cache += current->mm->delta_mmap;
4897 +#endif
4898 +
4899         current->mm->rss = 0;
4900         current->mm->mmap = NULL;
4901         compute_creds(bprm);
4902         current->flags &= ~PF_FORKNOEXEC;
4903 +
4904 +#ifdef CONFIG_PAX_PAGEEXEC
4905 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
4906 +               current->flags |= PF_PAX_PAGEEXEC;
4907 +
4908 +#ifdef CONFIG_PAX_EMUTRAMP
4909 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
4910 +                       current->flags |= PF_PAX_EMUTRAMP;
4911 +#endif
4912 +
4913 +#ifdef CONFIG_PAX_MPROTECT
4914 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
4915 +                       current->flags |= PF_PAX_MPROTECT;
4916 +#endif
4917 +
4918 +       }
4919 +#endif
4920 +
4921  #ifdef __sparc__
4922         if (N_MAGIC(ex) == NMAGIC) {
4923                 loff_t pos = fd_offset;
4924 @@ -401,7 +431,7 @@
4925  
4926                 down_write(&current->mm->mmap_sem);
4927                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
4928 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
4929 +                               PROT_READ | PROT_WRITE,
4930                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
4931                                 fd_offset + ex.a_text);
4932                 up_write(&current->mm->mmap_sem);
4933 diff -uNr linux-2.6.8/fs/binfmt_elf.c linux-2.6.8.grsecurity/fs/binfmt_elf.c
4934 --- linux-2.6.8/fs/binfmt_elf.c 2004-08-14 07:36:57.000000000 +0200
4935 +++ linux-2.6.8.grsecurity/fs/binfmt_elf.c      2004-08-16 17:42:02.000000000 +0200
4936 @@ -37,6 +37,12 @@
4937  #include <linux/pagemap.h>
4938  #include <linux/security.h>
4939  #include <linux/syscalls.h>
4940 +#include <linux/grsecurity.h>
4941 +#include <linux/random.h>
4942 +  
4943 +#ifdef CONFIG_PAX_SEGMEXEC
4944 +#include <asm/desc.h>
4945 +#endif
4946  
4947  #include <asm/uaccess.h>
4948  #include <asm/param.h>
4949 @@ -84,14 +90,22 @@
4950  
4951  static int set_brk(unsigned long start, unsigned long end)
4952  {
4953 +       current->mm->start_brk = current->mm->brk = end;
4954         start = ELF_PAGEALIGN(start);
4955         end = ELF_PAGEALIGN(end);
4956         if (end > start) {
4957                 unsigned long addr = do_brk(start, end - start);
4958                 if (BAD_ADDR(addr))
4959                         return addr;
4960 +
4961 +#ifdef CONFIG_PAX_RANDEXEC
4962 +               if (current->flags & PF_PAX_RANDEXEC)
4963 +                       addr = __do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
4964 +               if (BAD_ADDR(addr))
4965 +                       return addr;
4966 +#endif
4967 +
4968         }
4969 -       current->mm->start_brk = current->mm->brk = end;
4970         return 0;
4971  }
4972  
4973 @@ -305,6 +319,7 @@
4974         unsigned long last_bss = 0, elf_bss = 0;
4975         unsigned long error = ~0UL;
4976         int retval, i, size;
4977 +       unsigned long task_size = TASK_SIZE;
4978  
4979         /* First of all, some simple consistency checks */
4980         if (interp_elf_ex->e_type != ET_EXEC &&
4981 @@ -338,6 +353,11 @@
4982         if (retval < 0)
4983                 goto out_close;
4984  
4985 +#ifdef CONFIG_PAX_SEGMEXEC
4986 +       if (current->flags & PF_PAX_SEGMEXEC)
4987 +               task_size = SEGMEXEC_TASK_SIZE;
4988 +#endif
4989 +
4990         eppnt = elf_phdata;
4991         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
4992           if (eppnt->p_type == PT_LOAD) {
4993 @@ -369,8 +389,8 @@
4994              * <= p_memsize so it is only necessary to check p_memsz.
4995              */
4996             k = load_addr + eppnt->p_vaddr;
4997 -           if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz ||
4998 -               eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
4999 +           if (k > task_size || eppnt->p_filesz > eppnt->p_memsz ||
5000 +               eppnt->p_memsz > task_size || task_size - eppnt->p_memsz < k) {
5001                 error = -ENOMEM;
5002                 goto out_close;
5003             }
5004 @@ -460,6 +480,227 @@
5005         return elf_entry;
5006  }
5007  
5008 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
5009 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
5010 +{
5011 +       unsigned long pax_flags = 0UL;
5012 +
5013 +#ifdef CONFIG_PAX_PAGEEXEC
5014 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
5015 +               pax_flags |= PF_PAX_PAGEEXEC;
5016 +#endif
5017 +
5018 +#ifdef CONFIG_PAX_SEGMEXEC
5019 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
5020 +               pax_flags |= PF_PAX_SEGMEXEC;
5021 +#endif
5022 +
5023 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
5024 +       if (pax_flags & PF_PAX_PAGEEXEC)
5025 +               pax_flags &= ~PF_PAX_SEGMEXEC;
5026 +#endif
5027 +
5028 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
5029 +       if (pax_flags & PF_PAX_SEGMEXEC)
5030 +               pax_flags &= ~PF_PAX_PAGEEXEC;
5031 +#endif
5032 +
5033 +#ifdef CONFIG_PAX_EMUTRAMP
5034 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
5035 +               pax_flags |= PF_PAX_EMUTRAMP;
5036 +#endif
5037 +
5038 +#ifdef CONFIG_PAX_MPROTECT
5039 +       if (elf_phdata->p_flags & PF_MPROTECT)
5040 +               pax_flags |= PF_PAX_MPROTECT;
5041 +#endif
5042 +
5043 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
5044 +
5045 +#ifdef CONFIG_PAX_SOFTMODE
5046 +       if (pax_aslr)
5047 +#endif
5048 +
5049 +       if (elf_phdata->p_flags & PF_RANDMMAP)
5050 +               pax_flags |= PF_PAX_RANDMMAP;
5051 +#endif
5052 +
5053 +#ifdef CONFIG_PAX_RANDEXEC
5054 +
5055 +#ifdef CONFIG_PAX_SOFTMODE
5056 +       if (pax_aslr)
5057 +#endif
5058 +
5059 +       if (elf_phdata->p_flags & PF_RANDEXEC)
5060 +               pax_flags |= PF_PAX_RANDEXEC;
5061 +#endif
5062 +
5063 +       return pax_flags;
5064 +}
5065 +#endif
5066 +
5067 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
5068 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
5069 +{
5070 +       unsigned long pax_flags = 0UL;
5071 +
5072 +#ifdef CONFIG_PAX_PAGEEXEC
5073 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
5074 +               pax_flags |= PF_PAX_PAGEEXEC;
5075 +#endif
5076 +
5077 +#ifdef CONFIG_PAX_SEGMEXEC
5078 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
5079 +               pax_flags |= PF_PAX_SEGMEXEC;
5080 +#endif
5081 +
5082 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
5083 +       if (pax_flags & PF_PAX_PAGEEXEC)
5084 +               pax_flags &= ~PF_PAX_SEGMEXEC;
5085 +#endif
5086 +
5087 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
5088 +       if (pax_flags & PF_PAX_SEGMEXEC)
5089 +               pax_flags &= ~PF_PAX_PAGEEXEC;
5090 +#endif
5091 +
5092 +#ifdef CONFIG_PAX_EMUTRAMP
5093 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
5094 +               pax_flags |= PF_PAX_EMUTRAMP;
5095 +#endif
5096 +
5097 +#ifdef CONFIG_PAX_MPROTECT
5098 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
5099 +               pax_flags |= PF_PAX_MPROTECT;
5100 +#endif
5101 +
5102 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
5103 +
5104 +#ifdef CONFIG_PAX_SOFTMODE
5105 +       if (pax_aslr)
5106 +#endif
5107 +
5108 +       if (!(elf_phdata->p_flags & PF_NORANDMMAP))
5109 +               pax_flags |= PF_PAX_RANDMMAP;
5110 +#endif
5111 +
5112 +#ifdef CONFIG_PAX_RANDEXEC
5113 +
5114 +#ifdef CONFIG_PAX_SOFTMODE
5115 +       if (pax_aslr)
5116 +#endif
5117 +
5118 +       if (!(elf_phdata->p_flags & PF_NORANDEXEC))
5119 +               pax_flags |= PF_PAX_RANDEXEC;
5120 +#endif
5121 +
5122 +       return pax_flags;
5123 +}
5124 +#endif
5125 +
5126 +#ifdef CONFIG_PAX_EI_PAX
5127 +static int pax_parse_ei_pax(const struct elfhdr * const elf_ex)
5128 +{
5129 +       unsigned long pax_flags = 0UL;
5130 +
5131 +#ifdef CONFIG_PAX_PAGEEXEC
5132 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
5133 +               pax_flags |= PF_PAX_PAGEEXEC;
5134 +#endif
5135 +
5136 +#ifdef CONFIG_PAX_SEGMEXEC
5137 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
5138 +               pax_flags |= PF_PAX_SEGMEXEC;
5139 +#endif
5140 +
5141 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
5142 +       if (pax_flags & PF_PAX_PAGEEXEC)
5143 +               pax_flags &= ~PF_PAX_SEGMEXEC;
5144 +#endif
5145 +
5146 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
5147 +       if (pax_flags & PF_PAX_SEGMEXEC)
5148 +               pax_flags &= ~PF_PAX_PAGEEXEC;
5149 +#endif
5150 +
5151 +#ifdef CONFIG_PAX_EMUTRAMP
5152 +       if ((pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
5153 +               pax_flags |= PF_PAX_EMUTRAMP;
5154 +#endif
5155 +
5156 +#ifdef CONFIG_PAX_MPROTECT
5157 +       if ((pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
5158 +               pax_flags |= PF_PAX_MPROTECT;
5159 +#endif
5160 +
5161 +#ifdef CONFIG_PAX_ASLR
5162 +
5163 +#ifdef CONFIG_PAX_SOFTMODE
5164 +       if (pax_aslr)
5165 +#endif
5166 +
5167 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
5168 +               pax_flags |= PF_PAX_RANDMMAP;
5169 +#endif
5170 +
5171 +#ifdef CONFIG_PAX_RANDEXEC
5172 +
5173 +#ifdef CONFIG_PAX_SOFTMODE
5174 +       if (pax_aslr)
5175 +#endif
5176 +
5177 +       if ((elf_ex->e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex->e_type == ET_EXEC) && (pax_flags & PF_PAX_MPROTECT))
5178 +               pax_flags |= PF_PAX_RANDEXEC;
5179 +#endif
5180 +
5181 +       return pax_flags;
5182 +}
5183 +#endif
5184 +
5185 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
5186 +static int pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
5187 +{
5188 +       unsigned long pax_flags = 0UL;
5189 +
5190 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
5191 +       unsigned long i;
5192 +#endif
5193 +
5194 +#ifdef CONFIG_PAX_EI_PAX
5195 +       pax_flags = pax_parse_ei_pax(elf_ex);
5196 +#endif
5197 +
5198 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
5199 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
5200 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
5201 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
5202 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
5203 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
5204 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
5205 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)) ||
5206 +                           ((elf_phdata[i].p_flags & PF_RANDEXEC) && ((elf_phdata[i].p_flags & PF_NORANDEXEC) || elf_ex->e_type == ET_DYN || !(elf_phdata[i].p_flags & PF_MPROTECT))) ||
5207 +                           (!(elf_phdata[i].p_flags & PF_NORANDEXEC) && (elf_ex->e_type == ET_DYN || (elf_phdata[i].p_flags & PF_NOMPROTECT))))
5208 +                               return -EINVAL;
5209 +
5210 +#ifdef CONFIG_PAX_SOFTMODE
5211 +                       if (pax_softmode)
5212 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
5213 +                       else
5214 +#endif
5215 +
5216 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
5217 +                       break;
5218 +               }
5219 +#endif
5220 +
5221 +       if (0 > pax_check_flags(&pax_flags))
5222 +               return -EINVAL;
5223 +
5224 +       current->flags |= pax_flags;
5225 +       return 0;
5226 +}
5227 +#endif
5228 +
5229  /*
5230   * These are the functions used to load ELF style executables and shared
5231   * libraries.  There is no binary dependent code anywhere else.
5232 @@ -494,7 +735,13 @@
5233         struct files_struct *files;
5234         int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT;
5235         unsigned long def_flags = 0;
5236 -       
5237 +       unsigned long task_size = TASK_SIZE;
5238 +
5239 +#ifdef CONFIG_PAX_RANDEXEC
5240 +       unsigned long load_addr_random = 0UL;
5241 +       unsigned long load_bias_random = 0UL;
5242 +#endif
5243 +
5244         /* Get the exec-header */
5245         elf_ex = *((struct elfhdr *) bprm->buf);
5246  
5247 @@ -618,6 +865,7 @@
5248                 elf_ppnt++;
5249         }
5250  
5251 +#if 0
5252         elf_ppnt = elf_phdata;
5253         for (i = 0; i < elf_ex.e_phnum; i++, elf_ppnt++)
5254                 if (elf_ppnt->p_type == PT_GNU_STACK) {
5255 @@ -627,6 +875,7 @@
5256                                 executable_stack = EXSTACK_DISABLE_X;
5257                         break;
5258                 }
5259 +#endif
5260         have_pt_gnu_stack = (i < elf_ex.e_phnum);
5261  
5262         /* Some simple consistency checks for the interpreter */
5263 @@ -694,9 +943,65 @@
5264         current->mm->end_data = 0;
5265         current->mm->end_code = 0;
5266         current->mm->mmap = NULL;
5267 +
5268 +#ifdef CONFIG_PAX_DLRESOLVE
5269 +       current->mm->call_dl_resolve = 0UL;
5270 +#endif
5271 +
5272 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
5273 +       current->mm->call_syscall = 0UL;
5274 +#endif
5275 +
5276 +#ifdef CONFIG_PAX_ASLR
5277 +       current->mm->delta_mmap = 0UL;
5278 +       current->mm->delta_exec = 0UL;
5279 +       current->mm->delta_stack = 0UL;
5280 +#endif
5281 +
5282         current->flags &= ~PF_FORKNOEXEC;
5283         current->mm->def_flags = def_flags;
5284  
5285 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
5286 +       if (0 > pax_parse_elf_flags(&elf_ex, elf_phdata)) {
5287 +               send_sig(SIGKILL, current, 0);
5288 +               goto out_free_dentry;
5289 +       }
5290 +#endif
5291 +
5292 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
5293 +       pax_set_flags(bprm);
5294 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
5295 +       if (pax_set_flags_func)
5296 +               (pax_set_flags_func)(bprm);
5297 +#endif
5298 +
5299 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
5300 +       if (current->flags & PF_PAX_PAGEEXEC)
5301 +               current->mm->context.user_cs_limit = PAGE_SIZE;
5302 +#endif
5303 +
5304 +#ifdef CONFIG_PAX_SEGMEXEC
5305 +       if (current->flags & PF_PAX_SEGMEXEC) {
5306 +               int cpu = get_cpu();
5307 +
5308 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
5309 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
5310 +               set_user_cs(current->mm, cpu);
5311 +               put_cpu();
5312 +               task_size = SEGMEXEC_TASK_SIZE;
5313 +       }
5314 +#endif
5315 +
5316 +#ifdef CONFIG_PAX_ASLR
5317 +       if (current->flags & PF_PAX_RANDMMAP) {
5318 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
5319 +
5320 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
5321 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
5322 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
5323 +       }
5324 +#endif
5325 +
5326         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
5327            may depend on the personality.  */
5328         SET_PERSONALITY(elf_ex, ibcs2_interpreter);
5329 @@ -707,6 +1012,12 @@
5330            change some of these later */
5331         current->mm->rss = 0;
5332         current->mm->free_area_cache = TASK_UNMAPPED_BASE;
5333 +
5334 +#ifdef CONFIG_PAX_RANDMMAP
5335 +       if (current->flags & PF_PAX_RANDMMAP)
5336 +               current->mm->free_area_cache += current->mm->delta_mmap;
5337 +#endif
5338 +
5339         retval = setup_arg_pages(bprm, executable_stack);
5340         if (retval < 0) {
5341                 send_sig(SIGKILL, current, 0);
5342 @@ -761,12 +1072,92 @@
5343                         /* Try and get dynamic programs out of the way of the default mmap
5344                            base, as well as whatever program they might try to exec.  This
5345                            is because the brk will follow the loader, and is not movable.  */
5346 +
5347 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5348 +                       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
5349 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr);
5350 +                               elf_flags |= MAP_FIXED;
5351 +                       } else
5352 +#endif
5353 +
5354                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
5355 +
5356 +#ifdef CONFIG_PAX_RANDMMAP
5357 +                       /* PaX: randomize base address at the default exe base if requested */
5358 +                       if (current->flags & PF_PAX_RANDMMAP)
5359 +                               load_bias += ELF_PAGESTART(current->mm->delta_exec);
5360 +#endif
5361 +
5362                 }
5363  
5364 -               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
5365 -               if (BAD_ADDR(error))
5366 -                       continue;
5367 +#ifdef CONFIG_PAX_RANDEXEC
5368 +               if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
5369 +                       error = -ENOMEM;
5370 +
5371 +#ifdef CONFIG_PAX_PAGEEXEC
5372 +                       if (current->flags & PF_PAX_PAGEEXEC)
5373 +                               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
5374 +#endif
5375 +
5376 +#ifdef CONFIG_PAX_SEGMEXEC
5377 +                       if (current->flags & PF_PAX_SEGMEXEC) {
5378 +                               unsigned long addr, len;
5379 +
5380 +                               addr = ELF_PAGESTART(load_bias + vaddr);
5381 +                               len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
5382 +                               if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)
5383 +                                       continue;
5384 +                               down_write(&current->mm->mmap_sem);
5385 +                               error = __do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
5386 +                               up_write(&current->mm->mmap_sem);
5387 +                       }
5388 +#endif
5389 +
5390 +                       if (BAD_ADDR(error))
5391 +                               continue;
5392 +
5393 +                       /* PaX: mirror at a randomized base */
5394 +                       down_write(&current->mm->mmap_sem);
5395 +
5396 +                       if (!load_addr_set) {
5397 +                               load_addr_random = get_unmapped_area(bprm->file, 0UL, elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT, MAP_PRIVATE);
5398 +                               if (BAD_ADDR(load_addr_random)) {
5399 +                                       up_write(&current->mm->mmap_sem);
5400 +                                       continue;
5401 +                               }
5402 +                               load_bias_random = load_addr_random - vaddr;
5403 +                       }
5404 +
5405 +#ifdef CONFIG_PAX_PAGEEXEC
5406 +                       if (current->flags & PF_PAX_PAGEEXEC)
5407 +                               load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5408 +#endif
5409 +
5410 +#ifdef CONFIG_PAX_SEGMEXEC
5411 +                       if (current->flags & PF_PAX_SEGMEXEC) {
5412 +                               if (elf_prot & PROT_EXEC) {
5413 +                                       load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), elf_ppnt->p_memsz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), PROT_NONE, MAP_PRIVATE | MAP_FIXED, 0UL);
5414 +                                       if (!BAD_ADDR(load_addr_random)) {
5415 +                                               load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5416 +                                               if (!BAD_ADDR(load_addr_random))
5417 +                                                       load_addr_random -= SEGMEXEC_TASK_SIZE;
5418 +                                       }
5419 +                               } else
5420 +                                       load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
5421 +                       }
5422 +#endif
5423 +
5424 +                       up_write(&current->mm->mmap_sem);
5425 +                       if (BAD_ADDR(load_addr_random))
5426 +                               continue;
5427 +               } else
5428 +#endif
5429 +
5430 +               {
5431 +                       error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
5432 +                       if (BAD_ADDR(error))
5433 +                               continue;
5434 +               }
5435  
5436                 if (!load_addr_set) {
5437                         load_addr_set = 1;
5438 @@ -777,6 +1168,11 @@
5439                                 load_addr += load_bias;
5440                                 reloc_func_desc = load_bias;
5441                         }
5442 +
5443 +#ifdef CONFIG_PAX_RANDEXEC
5444 +                       current->mm->delta_exec = load_addr_random - load_addr;
5445 +#endif
5446 +
5447                 }
5448                 k = elf_ppnt->p_vaddr;
5449                 if (k < start_code) start_code = k;
5450 @@ -787,9 +1183,9 @@
5451                  * allowed task size. Note that p_filesz must always be
5452                  * <= p_memsz so it is only necessary to check p_memsz.
5453                  */
5454 -               if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
5455 -                   elf_ppnt->p_memsz > TASK_SIZE ||
5456 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
5457 +               if (k > task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
5458 +                   elf_ppnt->p_memsz > task_size ||
5459 +                   task_size - elf_ppnt->p_memsz < k) {
5460                         /* set_brk can never work.  Avoid overflows.  */
5461                         send_sig(SIGKILL, current, 0);
5462                         goto out_free_dentry;
5463 @@ -816,6 +1212,16 @@
5464         start_data += load_bias;
5465         end_data += load_bias;
5466  
5467 +#ifdef CONFIG_PAX_RANDMMAP
5468 +
5469 +#ifdef CONFIG_PAX_SOFTMODE
5470 +       if (pax_aslr)
5471 +#endif
5472 +
5473 +       elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
5474 +#undef pax_delta_mask
5475 +#endif
5476 +
5477         /* Calling set_brk effectively mmaps the pages that we need
5478          * for the bss and break sections.  We must do this before
5479          * mapping in the interpreter, to make sure it doesn't wind
5480 @@ -1108,8 +1514,11 @@
5481  #undef DUMP_SEEK
5482  
5483  #define DUMP_WRITE(addr, nr)   \
5484 +       do { \
5485 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
5486         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
5487 -               goto end_coredump;
5488 +               goto end_coredump; \
5489 +       } while (0);
5490  #define DUMP_SEEK(off) \
5491         if (!dump_seek(file, (off))) \
5492                 goto end_coredump;
5493 diff -uNr linux-2.6.8/fs/binfmt_flat.c linux-2.6.8.grsecurity/fs/binfmt_flat.c
5494 --- linux-2.6.8/fs/binfmt_flat.c        2004-08-14 07:36:10.000000000 +0200
5495 +++ linux-2.6.8.grsecurity/fs/binfmt_flat.c     2004-08-16 17:08:28.000000000 +0200
5496 @@ -540,7 +540,9 @@
5497                                 realdatastart = (unsigned long) -ENOMEM;
5498                         printk("Unable to allocate RAM for process data, errno %d\n",
5499                                         (int)-datapos);
5500 +                       down_write(&current->mm->mmap_sem);
5501                         do_munmap(current->mm, textpos, text_len);
5502 +                       up_write(&current->mm->mmap_sem);
5503                         return realdatastart;
5504                 }
5505                 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
5506 @@ -561,8 +563,10 @@
5507                 }
5508                 if (result >= (unsigned long)-4096) {
5509                         printk("Unable to read data+bss, errno %d\n", (int)-result);
5510 +                       down_write(&current->mm->mmap_sem);
5511                         do_munmap(current->mm, textpos, text_len);
5512                         do_munmap(current->mm, realdatastart, data_len + extra);
5513 +                       up_write(&current->mm->mmap_sem);
5514                         return result;
5515                 }
5516  
5517 @@ -624,8 +628,10 @@
5518                 }
5519                 if (result >= (unsigned long)-4096) {
5520                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
5521 +                       down_write(&current->mm->mmap_sem);
5522                         do_munmap(current->mm, textpos, text_len + data_len + extra +
5523                                 MAX_SHARED_LIBS * sizeof(unsigned long));
5524 +                       up_write(&current->mm->mmap_sem);
5525                         return result;
5526                 }
5527         }
5528 diff -uNr linux-2.6.8/fs/binfmt_misc.c linux-2.6.8.grsecurity/fs/binfmt_misc.c
5529 --- linux-2.6.8/fs/binfmt_misc.c        2004-08-14 07:36:48.000000000 +0200
5530 +++ linux-2.6.8.grsecurity/fs/binfmt_misc.c     2004-08-16 17:08:28.000000000 +0200
5531 @@ -112,9 +112,11 @@
5532         struct files_struct *files = NULL;
5533  
5534         retval = -ENOEXEC;
5535 -       if (!enabled)
5536 +       if (!enabled || bprm->misc)
5537                 goto _ret;
5538  
5539 +       bprm->misc++;
5540 +
5541         /* to keep locking time low, we copy the interpreter string */
5542         read_lock(&entries_lock);
5543         fmt = check_file(bprm);
5544 diff -uNr linux-2.6.8/fs/buffer.c linux-2.6.8.grsecurity/fs/buffer.c
5545 --- linux-2.6.8/fs/buffer.c     2004-08-14 07:37:14.000000000 +0200
5546 +++ linux-2.6.8.grsecurity/fs/buffer.c  2004-08-16 17:08:28.000000000 +0200
5547 @@ -37,6 +37,7 @@
5548  #include <linux/bio.h>
5549  #include <linux/notifier.h>
5550  #include <linux/cpu.h>
5551 +#include <linux/grsecurity.h>
5552  #include <asm/bitops.h>
5553  
5554  static void invalidate_bh_lrus(void);
5555 @@ -2234,6 +2235,9 @@
5556         int err;
5557  
5558         err = -EFBIG;
5559 +
5560 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
5561 +
5562          limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
5563         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
5564                 send_sig(SIGXFSZ, current, 0);
5565 diff -uNr linux-2.6.8/fs/compat.c linux-2.6.8.grsecurity/fs/compat.c
5566 --- linux-2.6.8/fs/compat.c     2004-08-14 07:36:57.000000000 +0200
5567 +++ linux-2.6.8.grsecurity/fs/compat.c  2004-08-16 17:08:28.000000000 +0200
5568 @@ -41,6 +41,7 @@
5569  #include <linux/nfsd/nfsd.h>
5570  #include <linux/nfsd/syscall.h>
5571  #include <linux/personality.h>
5572 +#include <linux/grsecurity.h>
5573  
5574  #include <net/sock.h>          /* siocdevprivate_ioctl */
5575  
5576 @@ -1372,6 +1373,11 @@
5577         struct file *file;
5578         int retval;
5579         int i;
5580 +#ifdef CONFIG_GRKERNSEC
5581 +       struct file *old_exec_file;
5582 +       struct acl_subject_label *old_acl;
5583 +       struct rlimit old_rlim[RLIM_NLIMITS];
5584 +#endif
5585  
5586         sched_balance_exec();
5587  
5588 @@ -1381,6 +1387,20 @@
5589         if (IS_ERR(file))
5590                 return retval;
5591  
5592 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
5593 +
5594 +       if (gr_handle_nproc()) {
5595 +               allow_write_access(file);
5596 +               fput(file);
5597 +               return -EAGAIN;
5598 +       }
5599 +
5600 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
5601 +               allow_write_access(file);
5602 +               fput(file);
5603 +               return -EACCES;
5604 +       }
5605 +
5606         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
5607         memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
5608  
5609 @@ -1429,15 +1449,49 @@
5610         if (retval < 0)
5611                 goto out;
5612  
5613 +       if (!gr_tpe_allow(file)) {
5614 +               retval = -EACCES;
5615 +               goto out;
5616 +       }
5617 +
5618 +       if (gr_check_crash_exec(file)) {
5619 +               retval = -EACCES;
5620 +               goto out;
5621 +       }
5622 +
5623 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
5624 +
5625 +#ifdef CONFIG_GRKERNSEC
5626 +       old_acl = current->acl;
5627 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
5628 +       old_exec_file = current->exec_file;
5629 +       get_file(file);
5630 +       current->exec_file = file;
5631 +#endif
5632 +
5633 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
5634 +
5635         retval = search_binary_handler(&bprm,regs);
5636         if (retval >= 0) {
5637                 free_arg_pages(&bprm);
5638  
5639 +#ifdef CONFIG_GRKERNSEC
5640 +               if (old_exec_file)
5641 +                       fput(old_exec_file);
5642 +#endif
5643 +
5644                 /* execve success */
5645                 security_bprm_free(&bprm);
5646                 return retval;
5647         }
5648  
5649 +#ifdef CONFIG_GRKERNSEC
5650 +       current->acl = old_acl;
5651 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
5652 +       fput(current->exec_file);
5653 +       current->exec_file = old_exec_file;
5654 +#endif
5655 +
5656  out:
5657         /* Something went wrong, return the inode and free the argument pages*/
5658         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
5659 diff -uNr linux-2.6.8/fs/dcache.c linux-2.6.8.grsecurity/fs/dcache.c
5660 --- linux-2.6.8/fs/dcache.c     2004-08-14 07:36:16.000000000 +0200
5661 +++ linux-2.6.8.grsecurity/fs/dcache.c  2004-08-16 17:08:28.000000000 +0200
5662 @@ -1277,7 +1277,7 @@
5663   *
5664   * "buflen" should be positive. Caller holds the dcache_lock.
5665   */
5666 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
5667 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
5668                         struct dentry *root, struct vfsmount *rootmnt,
5669                         char *buffer, int buflen)
5670  {
5671 diff -uNr linux-2.6.8/fs/exec.c linux-2.6.8.grsecurity/fs/exec.c
5672 --- linux-2.6.8/fs/exec.c       2004-08-14 07:36:56.000000000 +0200
5673 +++ linux-2.6.8.grsecurity/fs/exec.c    2004-08-16 17:50:08.000000000 +0200
5674 @@ -46,6 +46,8 @@
5675  #include <linux/security.h>
5676  #include <linux/syscalls.h>
5677  #include <linux/rmap.h>
5678 +#include <linux/grsecurity.h>
5679 +#include <linux/random.h>
5680  
5681  #include <asm/uaccess.h>
5682  #include <asm/mmu_context.h>
5683 @@ -61,6 +63,20 @@
5684  static struct linux_binfmt *formats;
5685  static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
5686  
5687 +#ifdef CONFIG_PAX_SOFTMODE
5688 +
5689 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
5690 +unsigned int pax_aslr=1;
5691 +#endif
5692 +
5693 +unsigned int pax_softmode;
5694 +#endif
5695 +
5696 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
5697 +void (*pax_set_flags_func)(struct linux_binprm * bprm);
5698 +EXPORT_SYMBOL(pax_set_flags_func);
5699 +#endif
5700 +
5701  int register_binfmt(struct linux_binfmt * fmt)
5702  {
5703         struct linux_binfmt ** tmp = &formats;
5704 @@ -305,6 +321,10 @@
5705         if (unlikely(anon_vma_prepare(vma)))
5706                 goto out_sig;
5707  
5708 +#ifdef CONFIG_PAX_SEGMEXEC
5709 +       if (page_count(page) == 1)
5710 +#endif
5711 +
5712         flush_dcache_page(page);
5713         pgd = pgd_offset(mm, address);
5714  
5715 @@ -320,6 +340,11 @@
5716                 goto out;
5717         }
5718         mm->rss++;
5719 +
5720 +#ifdef CONFIG_PAX_SEGMEXEC
5721 +       if (page_count(page) == 1)
5722 +#endif
5723 +
5724         lru_cache_add_active(page);
5725         set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(
5726                                         page, vma->vm_page_prot))));
5727 @@ -344,6 +369,10 @@
5728         int i;
5729         long arg_size;
5730  
5731 +#ifdef CONFIG_PAX_SEGMEXEC
5732 +       struct vm_area_struct *mpnt_m = NULL;
5733 +#endif
5734 +
5735  #ifdef CONFIG_STACK_GROWSUP
5736         /* Move the argument and environment strings to the bottom of the
5737          * stack space.
5738 @@ -403,8 +432,24 @@
5739         if (!mpnt)
5740                 return -ENOMEM;
5741  
5742 +#ifdef CONFIG_PAX_SEGMEXEC
5743 +       if ((current->flags & PF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
5744 +               mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5745 +               if (!mpnt_m) {
5746 +                       kmem_cache_free(vm_area_cachep, mpnt);
5747 +                       return -ENOMEM;
5748 +               }
5749 +       }
5750 +#endif
5751 +
5752         if (security_vm_enough_memory(arg_size >> PAGE_SHIFT)) {
5753                 kmem_cache_free(vm_area_cachep, mpnt);
5754 +
5755 +#ifdef CONFIG_PAX_SEGMEXEC
5756 +               if (mpnt_m)
5757 +                       kmem_cache_free(vm_area_cachep, mpnt_m);
5758 +#endif
5759 +
5760                 return -ENOMEM;
5761         }
5762  
5763 @@ -431,9 +476,36 @@
5764                 else
5765                         mpnt->vm_flags = VM_STACK_FLAGS;
5766                 mpnt->vm_flags |= mm->def_flags;
5767 -               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
5768 +
5769 +#ifdef CONFIG_PAX_PAGEEXEC
5770 +               if (!(current->flags & PF_PAX_PAGEEXEC))
5771 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & 0x7];
5772 +               else
5773 +#endif
5774 +                       mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
5775 +
5776                 insert_vm_struct(mm, mpnt);
5777                 mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
5778 +
5779 +#ifdef CONFIG_PAX_SEGMEXEC
5780 +               if (mpnt_m) {
5781 +                       *mpnt_m = *mpnt;
5782 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
5783 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
5784 +                               mpnt_m->vm_page_prot = PAGE_NONE;
5785 +                       }
5786 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
5787 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
5788 +                       mpnt_m->vm_flags |= VM_MIRROR;
5789 +                       mpnt->vm_flags |= VM_MIRROR;
5790 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
5791 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
5792 +                       insert_vm_struct(mm, mpnt_m);
5793 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
5794 +                       mm->total_vm += (mpnt_m->vm_end - mpnt_m->vm_start) >> PAGE_SHIFT;
5795 +               }
5796 +#endif
5797 +
5798         }
5799  
5800         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
5801 @@ -441,6 +513,14 @@
5802                 if (page) {
5803                         bprm->page[i] = NULL;
5804                         install_arg_page(mpnt, page, stack_base);
5805 +
5806 +#if defined(CONFIG_PAX_SEGMEXEC) && defined(CONFIG_PAX_MPROTECT)
5807 +                       if (mpnt_m) {
5808 +                               page_cache_get(page);
5809 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
5810 +                       }
5811 +#endif
5812 +
5813                 }
5814                 stack_base += PAGE_SIZE;
5815         }
5816 @@ -836,6 +916,30 @@
5817         }
5818         current->comm[i] = '\0';
5819  
5820 +#ifdef CONFIG_PAX_PAGEEXEC
5821 +       current->flags &= ~PF_PAX_PAGEEXEC;
5822 +#endif
5823 +
5824 +#ifdef CONFIG_PAX_EMUTRAMP
5825 +       current->flags &= ~PF_PAX_EMUTRAMP;
5826 +#endif
5827 +
5828 +#ifdef CONFIG_PAX_MPROTECT
5829 +       current->flags &= ~PF_PAX_MPROTECT;
5830 +#endif
5831 +
5832 +#ifdef CONFIG_PAX_ASLR
5833 +       current->flags &= ~PF_PAX_RANDMMAP;
5834 +#endif
5835 +
5836 +#ifdef CONFIG_PAX_RANDEXEC
5837 +       current->flags &= ~PF_PAX_RANDEXEC;
5838 +#endif
5839 +
5840 +#ifdef CONFIG_PAX_SEGMEXEC
5841 +       current->flags &= ~PF_PAX_SEGMEXEC;
5842 +#endif
5843 +
5844         flush_thread();
5845  
5846         if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
5847 @@ -1078,6 +1182,11 @@
5848         struct file *file;
5849         int retval;
5850         int i;
5851 +#ifdef CONFIG_GRKERNSEC
5852 +       struct file *old_exec_file;
5853 +       struct acl_subject_label *old_acl;
5854 +       struct rlimit old_rlim[RLIM_NLIMITS];
5855 +#endif
5856  
5857         file = open_exec(filename);
5858  
5859 @@ -1087,7 +1196,29 @@
5860  
5861         sched_balance_exec();
5862  
5863 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
5864 +
5865 +       if (gr_handle_nproc()) {
5866 +               allow_write_access(file);
5867 +               fput(file);
5868 +               return -EAGAIN;
5869 +       }
5870 +
5871 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
5872 +               allow_write_access(file);
5873 +               fput(file);
5874 +               return -EACCES;
5875 +       }
5876 +
5877         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
5878 +
5879 +#ifdef CONFIG_PAX_RANDUSTACK
5880 +#ifdef CONFIG_PAX_SOFTMODE
5881 +       if (pax_aslr)
5882 +#endif
5883 +       bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
5884 +#endif
5885 +
5886         memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
5887  
5888         bprm.file = file;
5889 @@ -1096,6 +1227,7 @@
5890         bprm.interp_flags = 0;
5891         bprm.interp_data = 0;
5892         bprm.sh_bang = 0;
5893 +       bprm.misc = 0;
5894         bprm.loader = 0;
5895         bprm.exec = 0;
5896         bprm.security = NULL;
5897 @@ -1124,11 +1256,26 @@
5898         if (retval < 0)
5899                 goto out;
5900  
5901 +       if (!gr_tpe_allow(file)) {
5902 +               retval = -EACCES;
5903 +               goto out;
5904 +       }
5905 +
5906 +       if (gr_check_crash_exec(file)) {
5907 +               retval = -EACCES;
5908 +               goto out;
5909 +       }
5910 +
5911         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
5912         if (retval < 0)
5913                 goto out;
5914  
5915         bprm.exec = bprm.p;
5916 +
5917 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
5918 +
5919 +       gr_handle_exec_args(&bprm, argv);
5920 +
5921         retval = copy_strings(bprm.envc, envp, &bprm);
5922         if (retval < 0)
5923                 goto out;
5924 @@ -1137,8 +1284,24 @@
5925         if (retval < 0)
5926                 goto out;
5927  
5928 +#ifdef CONFIG_GRKERNSEC
5929 +       old_acl = current->acl;
5930 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
5931 +       old_exec_file = current->exec_file;
5932 +       get_file(file);
5933 +       current->exec_file = file;
5934 +#endif
5935 +
5936 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
5937 +       if (retval < 0)
5938 +               goto out_fail;
5939 +
5940         retval = search_binary_handler(&bprm,regs);
5941         if (retval >= 0) {
5942 +#ifdef CONFIG_GRKERNSEC
5943 +               if (old_exec_file)
5944 +                       fput(old_exec_file);
5945 +#endif
5946                 free_arg_pages(&bprm);
5947  
5948                 /* execve success */
5949 @@ -1146,6 +1309,14 @@
5950                 return retval;
5951         }
5952  
5953 +out_fail:
5954 +#ifdef CONFIG_GRKERNSEC
5955 +       current->acl = old_acl;
5956 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
5957 +       fput(current->exec_file);
5958 +       current->exec_file = old_exec_file;
5959 +#endif
5960 +
5961  out:
5962         /* Something went wrong, return the inode and free the argument pages*/
5963         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
5964 @@ -1303,6 +1474,138 @@
5965         *out_ptr = 0;
5966  }
5967  
5968 +int pax_check_flags(unsigned long * flags)
5969 +{
5970 +       int retval = 0;
5971 +
5972 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
5973 +       if (*flags & PF_PAX_SEGMEXEC)
5974 +       {
5975 +               *flags &= ~PF_PAX_SEGMEXEC;
5976 +               retval = -EINVAL;
5977 +       }
5978 +#endif
5979 +
5980 +       if ((*flags & PF_PAX_PAGEEXEC)
5981 +
5982 +#ifdef CONFIG_PAX_PAGEEXEC
5983 +           &&  (*flags & PF_PAX_SEGMEXEC)
5984 +#endif
5985 +
5986 +          )
5987 +       {
5988 +               *flags &= ~PF_PAX_PAGEEXEC;
5989 +               retval = -EINVAL;
5990 +       }
5991 +
5992 +       if ((*flags & PF_PAX_MPROTECT)
5993 +
5994 +#ifdef CONFIG_PAX_MPROTECT
5995 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
5996 +#endif
5997 +
5998 +          )
5999 +       {
6000 +               *flags &= ~PF_PAX_MPROTECT;
6001 +               retval = -EINVAL;
6002 +       }
6003 +
6004 +       if ((*flags & PF_PAX_EMUTRAMP)
6005 +
6006 +#ifdef CONFIG_PAX_EMUTRAMP
6007 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
6008 +#endif
6009 +
6010 +          )
6011 +       {
6012 +               *flags &= ~PF_PAX_EMUTRAMP;
6013 +               retval = -EINVAL;
6014 +       }
6015 +
6016 +       if ((*flags & PF_PAX_RANDEXEC)
6017 +
6018 +#ifdef CONFIG_PAX_RANDEXEC
6019 +           && !(*flags & PF_PAX_MPROTECT)
6020 +#endif
6021 +
6022 +          )
6023 +       {
6024 +               *flags &= ~PF_PAX_RANDEXEC;
6025 +               retval = -EINVAL;
6026 +       }
6027 +
6028 +       return retval;
6029 +}
6030 +
6031 +EXPORT_SYMBOL(pax_check_flags);
6032 +
6033 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6034 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
6035 +{
6036 +       struct task_struct *tsk = current;
6037 +       struct mm_struct *mm = current->mm;
6038 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
6039 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
6040 +       char* path_exec=NULL;
6041 +       char* path_fault=NULL;
6042 +       unsigned long start=0UL, end=0UL, offset=0UL;
6043 +
6044 +       if (buffer_exec && buffer_fault) {
6045 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
6046 +
6047 +               down_read(&mm->mmap_sem);
6048 +               vma = mm->mmap;
6049 +               while (vma && (!vma_exec || !vma_fault)) {
6050 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
6051 +                               vma_exec = vma;
6052 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
6053 +                               vma_fault = vma;
6054 +                       vma = vma->vm_next;
6055 +               }
6056 +               if (vma_exec) {
6057 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
6058 +                       if (IS_ERR(path_exec))
6059 +                               path_exec = "<path too long>";
6060 +               }
6061 +               if (vma_fault) {
6062 +                       start = vma_fault->vm_start;
6063 +                       end = vma_fault->vm_end;
6064 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
6065 +                       if (vma_fault->vm_file) {
6066 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
6067 +                               if (IS_ERR(path_fault))
6068 +                                       path_fault = "<path too long>";
6069 +                       } else
6070 +                               path_fault = "<anonymous mapping>";
6071 +               }
6072 +               up_read(&mm->mmap_sem);
6073 +       }
6074 +       printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
6075 +       if (current->curr_ip && gr_acl_is_enabled())
6076 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: (%.64s:%c:%.950s) terminating task: %s(%s):%d, uid/euid: %u/%u, "
6077 +                               "PC: %p, SP: %p\n", NIPQUAD(tsk->curr_ip), tsk->role->rolename, gr_roletype_to_char(),
6078 +                               tsk->acl->filename, path_exec, tsk->comm, tsk->pid,
6079 +                               tsk->uid, tsk->euid, pc, sp);
6080 +       else if (current->curr_ip)
6081 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: terminating task: %s(%s):%d, uid/euid: %u/%u, "
6082 +                               "PC: %p, SP: %p\n", NIPQUAD(tsk->curr_ip), path_exec, tsk->comm, tsk->pid,
6083 +                               tsk->uid, tsk->euid, pc, sp);
6084 +       else if (gr_acl_is_enabled())
6085 +               printk(KERN_ERR "PAX: (%.64s:%c:%.950s) terminating task: %s(%s):%d, uid/euid: %u/%u, "
6086 +                               "PC: %p, SP: %p\n", tsk->role->rolename, gr_roletype_to_char(),
6087 +                               tsk->acl->filename, path_exec, tsk->comm, tsk->pid,
6088 +                               tsk->uid, tsk->euid, pc, sp);
6089 +       else
6090 +               printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
6091 +                               "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
6092 +                               tsk->uid, tsk->euid, pc, sp);
6093 +       if (buffer_exec) free_page((unsigned long)buffer_exec);
6094 +       if (buffer_fault) free_page((unsigned long)buffer_fault);
6095 +       pax_report_insns(pc, sp);
6096 +       do_coredump(SIGKILL, SIGKILL, regs);
6097 +}
6098 +#endif
6099 +
6100  static void zap_threads (struct mm_struct *mm)
6101  {
6102         struct task_struct *g, *p;
6103 @@ -1372,6 +1675,10 @@
6104         current->signal->group_exit_code = exit_code;
6105         coredump_wait(mm);
6106  
6107 +       if (signr == SIGKILL || signr == SIGILL)
6108 +               gr_handle_brute_attach(current);
6109 +
6110 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
6111         if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
6112                 goto fail_unlock;
6113  
6114 @@ -1391,7 +1698,7 @@
6115                 goto close_fail;
6116         if (!file->f_op->write)
6117                 goto close_fail;
6118 -       if (do_truncate(file->f_dentry, 0) != 0)
6119 +       if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
6120                 goto close_fail;
6121  
6122         retval = binfmt->core_dump(signr, regs, file);
6123 diff -uNr linux-2.6.8/fs/fcntl.c linux-2.6.8.grsecurity/fs/fcntl.c
6124 --- linux-2.6.8/fs/fcntl.c      2004-08-14 07:37:25.000000000 +0200
6125 +++ linux-2.6.8.grsecurity/fs/fcntl.c   2004-08-16 17:08:28.000000000 +0200
6126 @@ -14,6 +14,7 @@
6127  #include <linux/module.h>
6128  #include <linux/security.h>
6129  #include <linux/ptrace.h>
6130 +#include <linux/grsecurity.h>
6131  
6132  #include <asm/poll.h>
6133  #include <asm/siginfo.h>
6134 @@ -86,6 +87,9 @@
6135         int error;
6136  
6137         error = -EINVAL;
6138 +
6139 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
6140 +
6141         if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
6142                 goto out;
6143  
6144 @@ -105,6 +109,9 @@
6145         }
6146         
6147         error = -EMFILE;
6148 +
6149 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
6150 +
6151         if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
6152                 goto out;
6153  
6154 @@ -154,6 +161,8 @@
6155         struct file * file, *tofree;
6156         struct files_struct * files = current->files;
6157  
6158 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
6159 +
6160         spin_lock(&files->file_lock);
6161         if (!(file = fcheck(oldfd)))
6162                 goto out_unlock;
6163 @@ -494,13 +503,15 @@
6164         if (pid > 0) {
6165                 p = find_task_by_pid(pid);
6166                 if (p) {
6167 -                       send_sigio_to_task(p, fown, fd, band);
6168 +                       if (!gr_check_protected_task(p))
6169 +                               send_sigio_to_task(p, fown, fd, band);
6170                 }
6171         } else {
6172                 struct list_head *l;
6173                 struct pid *pidptr;
6174                 for_each_task_pid(-pid, PIDTYPE_PGID, p, l, pidptr) {
6175 -                       send_sigio_to_task(p, fown, fd, band);
6176 +                       if (!gr_check_protected_task(p) && !gr_pid_is_chrooted(p))
6177 +                               send_sigio_to_task(p, fown, fd, band);
6178                 }
6179         }
6180         read_unlock(&tasklist_lock);
6181 diff -uNr linux-2.6.8/fs/Kconfig linux-2.6.8.grsecurity/fs/Kconfig
6182 --- linux-2.6.8/fs/Kconfig      2004-08-14 07:37:14.000000000 +0200
6183 +++ linux-2.6.8.grsecurity/fs/Kconfig   2004-08-16 17:08:28.000000000 +0200
6184 @@ -806,6 +806,7 @@
6185  
6186  config PROC_KCORE
6187         bool
6188 +       depends on !GRKERNSEC_PROC_ADD
6189         default y if !ARM
6190  
6191  config SYSFS
6192 diff -uNr linux-2.6.8/fs/namei.c linux-2.6.8.grsecurity/fs/namei.c
6193 --- linux-2.6.8/fs/namei.c      2004-08-14 07:36:45.000000000 +0200
6194 +++ linux-2.6.8.grsecurity/fs/namei.c   2004-08-16 17:08:28.000000000 +0200
6195 @@ -27,6 +27,7 @@
6196  #include <linux/security.h>
6197  #include <linux/mount.h>
6198  #include <linux/audit.h>
6199 +#include <linux/grsecurity.h>
6200  #include <asm/namei.h>
6201  #include <asm/uaccess.h>
6202  
6203 @@ -483,6 +484,13 @@
6204         err = security_inode_follow_link(dentry, nd);
6205         if (err)
6206                 goto loop;
6207 +
6208 +       if (gr_handle_follow_link(dentry->d_parent->d_inode,
6209 +                                 dentry->d_inode, dentry, nd->mnt)) {
6210 +               err = -EACCES;
6211 +               goto loop;
6212 +       }
6213 +
6214         current->link_count++;
6215         current->total_link_count++;
6216         nd->depth++;
6217 @@ -844,6 +852,10 @@
6218                                 break;
6219                 }
6220  return_base:
6221 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
6222 +                       path_release(nd);
6223 +                       return -ENOENT;
6224 +               }
6225                 return 0;
6226  out_dput:
6227                 dput(next.dentry);
6228 @@ -1293,7 +1305,7 @@
6229                 if (!error) {
6230                         DQUOT_INIT(inode);
6231                         
6232 -                       error = do_truncate(dentry, 0);
6233 +                       error = do_truncate(dentry, 0, nd->mnt);
6234                 }
6235                 put_write_access(inode);
6236                 if (error)
6237 @@ -1344,6 +1356,17 @@
6238                 error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
6239                 if (error)
6240                         return error;
6241 +
6242 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
6243 +                       error = -EPERM;
6244 +                       goto exit;
6245 +               }
6246 +
6247 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
6248 +                       error = -EACCES;
6249 +                       goto exit;
6250 +               }
6251 +
6252                 goto ok;
6253         }
6254  
6255 @@ -1377,9 +1400,19 @@
6256  
6257         /* Negative dentry, just create the file */
6258         if (!dentry->d_inode) {
6259 +               if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
6260 +                       error = -EACCES;
6261 +                       up(&dir->d_inode->i_sem);
6262 +                       goto exit_dput;
6263 +               }
6264 +
6265                 if (!IS_POSIXACL(dir->d_inode))
6266                         mode &= ~current->fs->umask;
6267                 error = vfs_create(dir->d_inode, dentry, mode, nd);
6268 +
6269 +               if (!error)
6270 +                       gr_handle_create(dentry, nd->mnt);
6271 +
6272                 up(&dir->d_inode->i_sem);
6273                 dput(nd->dentry);
6274                 nd->dentry = dentry;
6275 @@ -1394,6 +1427,25 @@
6276         /*
6277          * It already exists.
6278          */
6279 +
6280 +       if (gr_handle_rawio(dentry->d_inode)) {
6281 +               error = -EPERM;
6282 +               up(&dir->d_inode->i_sem);
6283 +               goto exit_dput;
6284 +       }
6285 +
6286 +       if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
6287 +               up(&dir->d_inode->i_sem);
6288 +               error = -EACCES;
6289 +               goto exit_dput;
6290 +       }
6291 +
6292 +       if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
6293 +               up(&dir->d_inode->i_sem);
6294 +               error = -EACCES;
6295 +               goto exit_dput;
6296 +       }
6297 +
6298         up(&dir->d_inode->i_sem);
6299  
6300         error = -EEXIST;
6301 @@ -1447,6 +1499,13 @@
6302         error = security_inode_follow_link(dentry, nd);
6303         if (error)
6304                 goto exit_dput;
6305 +
6306 +       if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
6307 +                                 dentry, nd->mnt)) {
6308 +               error = -EACCES;
6309 +               goto exit_dput;
6310 +       }
6311 +
6312         touch_atime(nd->mnt, dentry);
6313         nd_set_link(nd, NULL);
6314         error = dentry->d_inode->i_op->follow_link(dentry, nd);
6315 @@ -1562,6 +1621,22 @@
6316         if (!IS_POSIXACL(nd.dentry->d_inode))
6317                 mode &= ~current->fs->umask;
6318         if (!IS_ERR(dentry)) {
6319 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
6320 +                       error = -EPERM;
6321 +                       dput(dentry);
6322 +                       up(&nd.dentry->d_inode->i_sem);
6323 +                       path_release(&nd);
6324 +                       goto out;
6325 +               }
6326 +
6327 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
6328 +                       error = -EACCES;
6329 +                       dput(dentry);
6330 +                       up(&nd.dentry->d_inode->i_sem);
6331 +                       path_release(&nd);
6332 +                       goto out;
6333 +               }
6334 +
6335                 switch (mode & S_IFMT) {
6336                 case 0: case S_IFREG:
6337                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
6338 @@ -1579,6 +1654,10 @@
6339                 default:
6340                         error = -EINVAL;
6341                 }
6342 +
6343 +               if (!error)
6344 +                       gr_handle_create(dentry, nd.mnt);
6345 +
6346                 dput(dentry);
6347         }
6348         up(&nd.dentry->d_inode->i_sem);
6349 @@ -1630,9 +1709,19 @@
6350                 dentry = lookup_create(&nd, 1);
6351                 error = PTR_ERR(dentry);
6352                 if (!IS_ERR(dentry)) {
6353 +                       error = 0;
6354                         if (!IS_POSIXACL(nd.dentry->d_inode))
6355                                 mode &= ~current->fs->umask;
6356 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6357 +
6358 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
6359 +                               error = -EACCES;
6360 +
6361 +                       if (!error)
6362 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
6363 +
6364 +                       if (!error)
6365 +                               gr_handle_create(dentry, nd.mnt);
6366 +
6367                         dput(dentry);
6368                 }
6369                 up(&nd.dentry->d_inode->i_sem);
6370 @@ -1716,6 +1805,8 @@
6371         char * name;
6372         struct dentry *dentry;
6373         struct nameidata nd;
6374 +       ino_t saved_ino = 0;
6375 +       dev_t saved_dev = 0;
6376  
6377         name = getname(pathname);
6378         if(IS_ERR(name))
6379 @@ -1740,7 +1831,21 @@
6380         dentry = lookup_hash(&nd.last, nd.dentry);
6381         error = PTR_ERR(dentry);
6382         if (!IS_ERR(dentry)) {
6383 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
6384 +               error = 0;
6385 +               if (dentry->d_inode) {
6386 +                       if (dentry->d_inode->i_nlink <= 1) {
6387 +                               saved_ino = dentry->d_inode->i_ino;
6388 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
6389 +                       }
6390 +
6391 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
6392 +                               error = -EACCES;
6393 +               }
6394 +
6395 +               if (!error)
6396 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry);
6397 +               if (!error && (saved_dev || saved_ino))
6398 +                       gr_handle_delete(saved_ino, saved_dev);
6399                 dput(dentry);
6400         }
6401         up(&nd.dentry->d_inode->i_sem);
6402 @@ -1794,6 +1899,8 @@
6403         struct dentry *dentry;
6404         struct nameidata nd;
6405         struct inode *inode = NULL;
6406 +       ino_t saved_ino = 0;
6407 +       dev_t saved_dev = 0;
6408  
6409         name = getname(pathname);
6410         if(IS_ERR(name))
6411 @@ -1809,13 +1916,26 @@
6412         dentry = lookup_hash(&nd.last, nd.dentry);
6413         error = PTR_ERR(dentry);
6414         if (!IS_ERR(dentry)) {
6415 +               error = 0;
6416                 /* Why not before? Because we want correct error value */
6417                 if (nd.last.name[nd.last.len])
6418                         goto slashes;
6419                 inode = dentry->d_inode;
6420 -               if (inode)
6421 +               if (inode) {
6422 +                       if (inode->i_nlink <= 1) {
6423 +                               saved_ino = inode->i_ino;
6424 +                               saved_dev = inode->i_sb->s_dev;
6425 +                       }
6426 +
6427 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
6428 +                               error = -EACCES;
6429 +
6430                         atomic_inc(&inode->i_count);
6431 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
6432 +               }
6433 +               if (!error)
6434 +                       error = vfs_unlink(nd.dentry->d_inode, dentry);
6435 +               if (!error && (saved_ino || saved_dev))
6436 +                       gr_handle_delete(saved_ino, saved_dev);
6437         exit2:
6438                 dput(dentry);
6439         }
6440 @@ -1879,7 +1999,15 @@
6441                 dentry = lookup_create(&nd, 0);
6442                 error = PTR_ERR(dentry);
6443                 if (!IS_ERR(dentry)) {
6444 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
6445 +                       error = 0;
6446 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
6447 +                               error = -EACCES;
6448 +
6449 +                       if (!error)
6450 +                               error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
6451 +
6452 +                       if (!error)
6453 +                               gr_handle_create(dentry, nd.mnt);
6454                         dput(dentry);
6455                 }
6456                 up(&nd.dentry->d_inode->i_sem);
6457 @@ -1963,7 +2091,20 @@
6458         new_dentry = lookup_create(&nd, 0);
6459         error = PTR_ERR(new_dentry);
6460         if (!IS_ERR(new_dentry)) {
6461 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
6462 +               error = 0;
6463 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
6464 +                                      old_nd.dentry->d_inode,
6465 +                                      old_nd.dentry->d_inode->i_mode, to))
6466 +                       error = -EPERM;
6467 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
6468 +                                       old_nd.dentry, old_nd.mnt, to))
6469 +                       error = -EACCES;
6470 +               if (!error)
6471 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
6472 +
6473 +               if (!error)
6474 +                       gr_handle_create(new_dentry, nd.mnt);
6475 +
6476                 dput(new_dentry);
6477         }
6478         up(&nd.dentry->d_inode->i_sem);
6479 @@ -2185,8 +2326,16 @@
6480         if (new_dentry == trap)
6481                 goto exit5;
6482  
6483 -       error = vfs_rename(old_dir->d_inode, old_dentry,
6484 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
6485 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
6486 +                                    newname);
6487 +
6488 +       if (!error)
6489 +               error = vfs_rename(old_dir->d_inode, old_dentry,
6490                                    new_dir->d_inode, new_dentry);
6491 +       if (!error)
6492 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
6493 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
6494  exit5:
6495         dput(new_dentry);
6496  exit4:
6497 diff -uNr linux-2.6.8/fs/namespace.c linux-2.6.8.grsecurity/fs/namespace.c
6498 --- linux-2.6.8/fs/namespace.c  2004-08-14 07:37:25.000000000 +0200
6499 +++ linux-2.6.8.grsecurity/fs/namespace.c       2004-08-16 17:08:28.000000000 +0200
6500 @@ -21,6 +21,8 @@
6501  #include <linux/namei.h>
6502  #include <linux/security.h>
6503  #include <linux/mount.h>
6504 +#include <linux/sched.h>
6505 +#include <linux/grsecurity.h>
6506  #include <asm/uaccess.h>
6507  #include <asm/unistd.h>
6508  
6509 @@ -426,6 +428,8 @@
6510                         lock_kernel();
6511                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
6512                         unlock_kernel();
6513 +
6514 +                       gr_log_remount(mnt->mnt_devname, retval);
6515                 }
6516                 up_write(&sb->s_umount);
6517                 return retval;
6518 @@ -454,6 +458,9 @@
6519         if (retval)
6520                 security_sb_umount_busy(mnt);
6521         up_write(&current->namespace->sem);
6522 +
6523 +       gr_log_unmount(mnt->mnt_devname, retval);
6524 +
6525         return retval;
6526  }
6527  
6528 @@ -1016,6 +1023,11 @@
6529         if (retval)
6530                 goto dput_out;
6531  
6532 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
6533 +               retval = -EPERM;
6534 +               goto dput_out;
6535 +       }
6536 +
6537         if (flags & MS_REMOUNT)
6538                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
6539                                     data_page);
6540 @@ -1028,6 +1040,9 @@
6541                                       dev_name, data_page);
6542  dput_out:
6543         path_release(&nd);
6544 +
6545 +       gr_log_mount(dev_name, dir_name, retval);
6546 +
6547         return retval;
6548  }
6549  
6550 @@ -1252,6 +1267,9 @@
6551         if (!capable(CAP_SYS_ADMIN))
6552                 return -EPERM;
6553  
6554 +       if (gr_handle_chroot_pivot())
6555 +               return -EPERM;
6556 +
6557         lock_kernel();
6558  
6559         error = __user_walk(new_root, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
6560 diff -uNr linux-2.6.8/fs/open.c linux-2.6.8.grsecurity/fs/open.c
6561 --- linux-2.6.8/fs/open.c       2004-08-14 07:36:13.000000000 +0200
6562 +++ linux-2.6.8.grsecurity/fs/open.c    2004-08-16 17:08:28.000000000 +0200
6563 @@ -22,6 +22,7 @@
6564  #include <asm/uaccess.h>
6565  #include <linux/fs.h>
6566  #include <linux/pagemap.h>
6567 +#include <linux/grsecurity.h>
6568  
6569  #include <asm/unistd.h>
6570  
6571 @@ -191,7 +192,7 @@
6572         return error;
6573  }
6574  
6575 -int do_truncate(struct dentry *dentry, loff_t length)
6576 +int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
6577  {
6578         int err;
6579         struct iattr newattrs;
6580 @@ -200,6 +201,9 @@
6581         if (length < 0)
6582                 return -EINVAL;
6583  
6584 +       if (!gr_acl_handle_truncate(dentry, mnt))
6585 +               return -EACCES;
6586 +
6587         newattrs.ia_size = length;
6588         newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
6589         down(&dentry->d_inode->i_sem);
6590 @@ -260,7 +264,7 @@
6591         error = locks_verify_truncate(inode, NULL, length);
6592         if (!error) {
6593                 DQUOT_INIT(inode);
6594 -               error = do_truncate(nd.dentry, length);
6595 +               error = do_truncate(nd.dentry, length, nd.mnt);
6596         }
6597         put_write_access(inode);
6598  
6599 @@ -312,7 +316,7 @@
6600  
6601         error = locks_verify_truncate(inode, file, length);
6602         if (!error)
6603 -               error = do_truncate(dentry, length);
6604 +               error = do_truncate(dentry, length, file->f_vfsmnt);
6605  out_putf:
6606         fput(file);
6607  out:
6608 @@ -391,6 +395,11 @@
6609                     (error = permission(inode,MAY_WRITE,&nd)) != 0)
6610                         goto dput_and_out;
6611         }
6612 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6613 +               error = -EACCES;
6614 +               goto dput_and_out;
6615 +       }
6616 +
6617         down(&inode->i_sem);
6618         error = notify_change(nd.dentry, &newattrs);
6619         up(&inode->i_sem);
6620 @@ -444,6 +453,12 @@
6621                     (error = permission(inode,MAY_WRITE,&nd)) != 0)
6622                         goto dput_and_out;
6623         }
6624 +
6625 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
6626 +               error = -EACCES;
6627 +               goto dput_and_out;
6628 +       }
6629 +
6630         down(&inode->i_sem);
6631         error = notify_change(nd.dentry, &newattrs);
6632         up(&inode->i_sem);
6633 @@ -505,6 +520,10 @@
6634                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
6635                    && !special_file(nd.dentry->d_inode->i_mode))
6636                         res = -EROFS;
6637 +
6638 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
6639 +                       res = -EACCES;
6640 +
6641                 path_release(&nd);
6642         }
6643  
6644 @@ -528,6 +547,8 @@
6645         if (error)
6646                 goto dput_and_out;
6647  
6648 +       gr_log_chdir(nd.dentry, nd.mnt);
6649 +
6650         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
6651  
6652  dput_and_out:
6653 @@ -558,6 +579,13 @@
6654                 goto out_putf;
6655  
6656         error = permission(inode, MAY_EXEC, NULL);
6657 +
6658 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
6659 +               error = -EPERM;
6660 +
6661 +       if (!error)
6662 +               gr_log_chdir(dentry, mnt);
6663 +
6664         if (!error)
6665                 set_fs_pwd(current->fs, mnt, dentry);
6666  out_putf:
6667 @@ -583,8 +611,16 @@
6668         if (!capable(CAP_SYS_CHROOT))
6669                 goto dput_and_out;
6670  
6671 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
6672 +               goto dput_and_out;
6673 +
6674         set_fs_root(current->fs, nd.mnt, nd.dentry);
6675         set_fs_altroot();
6676 +
6677 +       gr_handle_chroot_caps(current);
6678 +
6679 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
6680 +
6681         error = 0;
6682  dput_and_out:
6683         path_release(&nd);
6684 @@ -613,9 +649,22 @@
6685         err = -EPERM;
6686         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6687                 goto out_putf;
6688 +
6689 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
6690 +               err = -EACCES;
6691 +               goto out_putf;
6692 +       }
6693 +
6694         down(&inode->i_sem);
6695         if (mode == (mode_t) -1)
6696                 mode = inode->i_mode;
6697 +
6698 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
6699 +               err = -EPERM;
6700 +               up(&inode->i_sem);
6701 +               goto out_putf;
6702 +       }
6703 +
6704         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6705         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
6706         err = notify_change(dentry, &newattrs);
6707 @@ -647,9 +696,21 @@
6708         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6709                 goto dput_and_out;
6710  
6711 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
6712 +               error = -EACCES;
6713 +               goto dput_and_out;
6714 +       }
6715 +
6716         down(&inode->i_sem);
6717         if (mode == (mode_t) -1)
6718                 mode = inode->i_mode;
6719 +
6720 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
6721 +               error = -EACCES;
6722 +               up(&inode->i_sem);
6723 +               goto dput_and_out;
6724 +       }
6725 +
6726         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6727         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
6728         error = notify_change(nd.dentry, &newattrs);
6729 @@ -661,7 +722,7 @@
6730         return error;
6731  }
6732  
6733 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
6734 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
6735  {
6736         struct inode * inode;
6737         int error;
6738 @@ -678,6 +739,12 @@
6739         error = -EPERM;
6740         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6741                 goto out;
6742 +
6743 +       if (!gr_acl_handle_chown(dentry, mnt)) {
6744 +               error = -EACCES;
6745 +               goto out;
6746 +       }
6747 +
6748         newattrs.ia_valid =  ATTR_CTIME;
6749         if (user != (uid_t) -1) {
6750                 newattrs.ia_valid |= ATTR_UID;
6751 @@ -703,7 +770,7 @@
6752  
6753         error = user_path_walk(filename, &nd);
6754         if (!error) {
6755 -               error = chown_common(nd.dentry, user, group);
6756 +               error = chown_common(nd.dentry, user, group, nd.mnt);
6757                 path_release(&nd);
6758         }
6759         return error;
6760 @@ -716,7 +783,7 @@
6761  
6762         error = user_path_walk_link(filename, &nd);
6763         if (!error) {
6764 -               error = chown_common(nd.dentry, user, group);
6765 +               error = chown_common(nd.dentry, user, group, nd.mnt);
6766                 path_release(&nd);
6767         }
6768         return error;
6769 @@ -730,7 +797,8 @@
6770  
6771         file = fget(fd);
6772         if (file) {
6773 -               error = chown_common(file->f_dentry, user, group);
6774 +               error = chown_common(file->f_dentry, user,
6775 +                                    group, file->f_vfsmnt);
6776                 fput(file);
6777         }
6778         return error;
6779 @@ -852,6 +920,7 @@
6780          * N.B. For clone tasks sharing a files structure, this test
6781          * will limit the total number of files that can be opened.
6782          */
6783 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
6784         if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
6785                 goto out;
6786  
6787 diff -uNr linux-2.6.8/fs/proc/array.c linux-2.6.8.grsecurity/fs/proc/array.c
6788 --- linux-2.6.8/fs/proc/array.c 2004-08-14 07:37:15.000000000 +0200
6789 +++ linux-2.6.8.grsecurity/fs/proc/array.c      2004-08-16 17:08:28.000000000 +0200
6790 @@ -275,6 +275,19 @@
6791                             cap_t(p->cap_effective));
6792  }
6793  
6794 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
6795 +static inline char *task_pax(struct task_struct *p, char *buffer)
6796 +{
6797 +       return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c%c\n",
6798 +                               p->flags & PF_PAX_PAGEEXEC ? 'P' : 'p',
6799 +                               p->flags & PF_PAX_EMUTRAMP ? 'E' : 'e',
6800 +                               p->flags & PF_PAX_MPROTECT ? 'M' : 'm',
6801 +                               p->flags & PF_PAX_RANDMMAP ? 'R' : 'r',
6802 +                               p->flags & PF_PAX_RANDEXEC ? 'X' : 'x',
6803 +                               p->flags & PF_PAX_SEGMEXEC ? 'S' : 's');
6804 +}
6805 +#endif
6806 +
6807  extern char *task_mem(struct mm_struct *, char *);
6808  int proc_pid_status(struct task_struct *task, char * buffer)
6809  {
6810 @@ -293,9 +306,20 @@
6811  #if defined(CONFIG_ARCH_S390)
6812         buffer = task_show_regs(task, buffer);
6813  #endif
6814 +
6815 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
6816 +       buffer = task_pax(task, buffer);
6817 +#endif
6818 +
6819         return buffer - orig;
6820  }
6821  
6822 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6823 +#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
6824 +                       task->flags & PF_PAX_SEGMEXEC || \
6825 +                       task->flags & PF_PAX_RANDEXEC)
6826 +#endif
6827 +
6828  extern unsigned long task_vsize(struct mm_struct *);
6829  int proc_pid_stat(struct task_struct *task, char * buffer)
6830  {
6831 @@ -327,6 +351,19 @@
6832  
6833         wchan = get_wchan(task);
6834  
6835 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6836 +       if (PAX_RAND_FLAGS) {
6837 +               eip = 0;
6838 +               esp = 0;
6839 +               wchan = 0;
6840 +       }
6841 +#endif
6842 +#ifdef CONFIG_GRKERNSEC_HIDESYM
6843 +       wchan = 0;
6844 +       eip =0;
6845 +       esp =0;
6846 +#endif
6847 +
6848         sigemptyset(&sigign);
6849         sigemptyset(&sigcatch);
6850         read_lock(&tasklist_lock);
6851 @@ -386,9 +423,15 @@
6852                 vsize,
6853                 mm ? mm->rss : 0, /* you might want to shift this left 3 */
6854                 task->rlim[RLIMIT_RSS].rlim_cur,
6855 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6856 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
6857 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
6858 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
6859 +#else
6860                 mm ? mm->start_code : 0,
6861                 mm ? mm->end_code : 0,
6862                 mm ? mm->start_stack : 0,
6863 +#endif
6864                 esp,
6865                 eip,
6866                 /* The signal information here is obsolete.
6867 @@ -428,3 +471,14 @@
6868         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
6869                        size, resident, shared, text, lib, data, 0);
6870  }
6871 +
6872 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6873 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
6874 +{
6875 +       int len;
6876 +
6877 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
6878 +       return len;
6879 +}
6880 +#endif
6881 +
6882 diff -uNr linux-2.6.8/fs/proc/base.c linux-2.6.8.grsecurity/fs/proc/base.c
6883 --- linux-2.6.8/fs/proc/base.c  2004-08-14 07:37:15.000000000 +0200
6884 +++ linux-2.6.8.grsecurity/fs/proc/base.c       2004-08-16 17:08:28.000000000 +0200
6885 @@ -32,6 +32,7 @@
6886  #include <linux/mount.h>
6887  #include <linux/security.h>
6888  #include <linux/ptrace.h>
6889 +#include <linux/grsecurity.h>
6890  
6891  /*
6892   * For hysterical raisins we keep the same inumbers as in the old procfs.
6893 @@ -67,6 +68,9 @@
6894         PROC_TGID_ATTR_EXEC,
6895         PROC_TGID_ATTR_FSCREATE,
6896  #endif
6897 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6898 +       PROC_TGID_IPADDR,
6899 +#endif
6900         PROC_TGID_FD_DIR,
6901         PROC_TID_INO,
6902         PROC_TID_STATUS,
6903 @@ -117,6 +121,9 @@
6904         E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
6905         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
6906         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
6907 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6908 +       E(PROC_TGID_IPADDR,     "ipaddr",  S_IFREG|S_IRUSR),
6909 +#endif
6910  #ifdef CONFIG_SECURITY
6911         E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
6912  #endif
6913 @@ -181,6 +188,9 @@
6914  int proc_pid_status(struct task_struct*,char*);
6915  int proc_pid_statm(struct task_struct*,char*);
6916  int proc_pid_cpu(struct task_struct*,char*);
6917 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6918 +int proc_pid_ipaddr(struct task_struct*,char*);
6919 +#endif
6920  
6921  static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
6922  {
6923 @@ -277,7 +287,7 @@
6924         (task == current || \
6925         (task->parent == current && \
6926         (task->ptrace & PT_PTRACED) &&  task->state == TASK_STOPPED && \
6927 -        security_ptrace(current,task) == 0))
6928 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
6929  
6930  static int may_ptrace_attach(struct task_struct *task)
6931  {
6932 @@ -292,13 +302,15 @@
6933              (current->uid != task->uid) ||
6934              (current->gid != task->egid) ||
6935              (current->gid != task->sgid) ||
6936 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
6937 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
6938                 goto out;
6939         rmb();
6940 -       if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
6941 +       if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
6942                 goto out;
6943         if (security_ptrace(current, task))
6944                 goto out;
6945 +       if (gr_handle_proc_ptrace(task))
6946 +               goto out;
6947  
6948         retval = 1;
6949  out:
6950 @@ -445,9 +457,22 @@
6951  
6952  static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
6953  {
6954 +       int ret;
6955 +       struct task_struct *task;
6956 +
6957         if (vfs_permission(inode, mask) != 0)
6958                 return -EACCES;
6959 -       return proc_check_root(inode);
6960 +       ret = proc_check_root(inode);
6961 +
6962 +       if (ret)
6963 +               return ret;
6964 +
6965 +       task = proc_task(inode);
6966 +
6967 +       if (!task)
6968 +               return 0;
6969 +
6970 +       return gr_acl_handle_procpidmem(task);
6971  }
6972  
6973  extern struct seq_operations proc_pid_maps_op;
6974 @@ -954,6 +979,9 @@
6975                 inode->i_uid = task->euid;
6976                 inode->i_gid = task->egid;
6977         }
6978 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6979 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
6980 +#endif
6981         security_task_to_inode(task, inode);
6982  
6983  out:
6984 @@ -982,7 +1010,9 @@
6985         if (pid_alive(task)) {
6986                 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
6987                         inode->i_uid = task->euid;
6988 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
6989                         inode->i_gid = task->egid;
6990 +#endif
6991                 } else {
6992                         inode->i_uid = 0;
6993                         inode->i_gid = 0;
6994 @@ -1318,6 +1348,12 @@
6995                         inode->i_fop = &proc_info_file_operations;
6996                         ei->op.proc_read = proc_pid_status;
6997                         break;
6998 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6999 +               case PROC_TGID_IPADDR:
7000 +                       inode->i_fop = &proc_info_file_operations;
7001 +                       ei->op.proc_read = proc_pid_ipaddr;
7002 +                       break;
7003 +#endif
7004                 case PROC_TID_STAT:
7005                 case PROC_TGID_STAT:
7006                         inode->i_fop = &proc_info_file_operations;
7007 @@ -1568,6 +1604,22 @@
7008         if (!task)
7009                 goto out;
7010  
7011 +       if (gr_check_hidden_task(task)) {
7012 +               put_task_struct(task);
7013 +               goto out;
7014 +       }
7015 +
7016 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
7017 +       if (current->uid && (task->uid != current->uid)
7018 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7019 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
7020 +#endif
7021 +       ) {
7022 +               put_task_struct(task);
7023 +               goto out;
7024 +       }
7025 +#endif
7026 +
7027         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
7028  
7029  
7030 @@ -1575,7 +1627,15 @@
7031                 put_task_struct(task);
7032                 goto out;
7033         }
7034 +
7035 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7036 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
7037 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7038 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
7039 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7040 +#else
7041         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
7042 +#endif
7043         inode->i_op = &proc_tgid_base_inode_operations;
7044         inode->i_fop = &proc_tgid_base_operations;
7045         inode->i_nlink = 3;
7046 @@ -1659,6 +1719,9 @@
7047  static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
7048  {
7049         struct task_struct *p;
7050 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
7051 +       struct task_struct *tmp = current;
7052 +#endif
7053         int nr_tgids = 0;
7054  
7055         index--;
7056 @@ -1679,6 +1742,18 @@
7057                 int tgid = p->pid;
7058                 if (!pid_alive(p))
7059                         continue;
7060 +               if (gr_pid_is_chrooted(p))
7061 +                       continue;
7062 +               if (gr_check_hidden_task(p))
7063 +                       continue;
7064 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
7065 +               if (tmp->uid && (p->uid != tmp->uid)
7066 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7067 +                   && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
7068 +#endif
7069 +               )
7070 +                       continue;
7071 +#endif
7072                 if (--index >= 0)
7073                         continue;
7074                 tgids[nr_tgids] = tgid;
7075 diff -uNr linux-2.6.8/fs/proc/inode.c linux-2.6.8.grsecurity/fs/proc/inode.c
7076 --- linux-2.6.8/fs/proc/inode.c 2004-08-14 07:37:40.000000000 +0200
7077 +++ linux-2.6.8.grsecurity/fs/proc/inode.c      2004-08-16 17:08:28.000000000 +0200
7078 @@ -209,7 +209,11 @@
7079                 if (de->mode) {
7080                         inode->i_mode = de->mode;
7081                         inode->i_uid = de->uid;
7082 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
7083 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
7084 +#else
7085                         inode->i_gid = de->gid;
7086 +#endif
7087                 }
7088                 if (de->size)
7089                         inode->i_size = de->size;
7090 diff -uNr linux-2.6.8/fs/proc/proc_misc.c linux-2.6.8.grsecurity/fs/proc/proc_misc.c
7091 --- linux-2.6.8/fs/proc/proc_misc.c     2004-08-14 07:36:17.000000000 +0200
7092 +++ linux-2.6.8.grsecurity/fs/proc/proc_misc.c  2004-08-16 17:52:36.000000000 +0200
7093 @@ -640,6 +640,8 @@
7094  void __init proc_misc_init(void)
7095  {
7096         struct proc_dir_entry *entry;
7097 +       int gr_mode = 0;
7098 +
7099         static struct {
7100                 char *name;
7101                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
7102 @@ -654,9 +656,13 @@
7103  #ifdef CONFIG_STRAM_PROC
7104                 {"stram",       stram_read_proc},
7105  #endif
7106 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7107                 {"devices",     devices_read_proc},
7108 +#endif
7109                 {"filesystems", filesystems_read_proc},
7110 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
7111                 {"cmdline",     cmdline_read_proc},
7112 +#endif
7113                 {"locks",       locks_read_proc},
7114                 {"execdomains", execdomains_read_proc},
7115                 {NULL,}
7116 @@ -664,24 +670,39 @@
7117         for (p = simple_ones; p->name; p++)
7118                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
7119  
7120 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7121 +       gr_mode = S_IRUSR;
7122 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7123 +       gr_mode = S_IRUSR | S_IRGRP;
7124 +#endif
7125 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7126 +       create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
7127 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
7128 +#endif 
7129 +
7130         proc_symlink("mounts", NULL, "self/mounts");
7131  
7132         /* And now for trickier ones */
7133         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
7134         if (entry)
7135                 entry->proc_fops = &proc_kmsg_operations;
7136 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7137 +       create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
7138 +       create_seq_entry("slabinfo",gr_mode,&proc_slabinfo_operations);
7139 +#else
7140         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
7141 +       create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
7142 +#endif
7143         create_seq_entry("partitions", 0, &proc_partitions_operations);
7144         create_seq_entry("stat", 0, &proc_stat_operations);
7145         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
7146 -       create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
7147         create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
7148         create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
7149         create_seq_entry("diskstats", 0, &proc_diskstats_operations);
7150  #ifdef CONFIG_MODULES
7151 -       create_seq_entry("modules", 0, &proc_modules_operations);
7152 +       create_seq_entry("modules", gr_mode, &proc_modules_operations);
7153  #endif
7154 -#ifdef CONFIG_PROC_KCORE
7155 +#if defined(CONFIG_PROC_KCORE)
7156         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
7157         if (proc_root_kcore) {
7158                 proc_root_kcore->proc_fops = &proc_kcore_operations;
7159 diff -uNr linux-2.6.8/fs/proc/root.c linux-2.6.8.grsecurity/fs/proc/root.c
7160 --- linux-2.6.8/fs/proc/root.c  2004-08-14 07:37:38.000000000 +0200
7161 +++ linux-2.6.8.grsecurity/fs/proc/root.c       2004-08-16 17:57:30.000000000 +0200
7162 @@ -52,13 +52,26 @@
7163                 return;
7164         }
7165         proc_misc_init();
7166 -       proc_net = proc_mkdir("net", NULL);
7167 +
7168 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7169 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, 0);
7170 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7171 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
7172 +#else
7173 +       proc_net = proc_mkdir("net", 0);
7174 +#endif
7175  #ifdef CONFIG_SYSVIPC
7176         proc_mkdir("sysvipc", NULL);
7177  #endif
7178  #ifdef CONFIG_SYSCTL
7179 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7180 +       proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR, 0);
7181 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7182 +       proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
7183 +#else
7184         proc_sys_root = proc_mkdir("sys", NULL);
7185  #endif
7186 +#endif
7187  #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
7188         proc_mkdir("sys/fs", NULL);
7189         proc_mkdir("sys/fs/binfmt_misc", NULL);
7190 @@ -74,7 +87,15 @@
7191  #ifdef CONFIG_PROC_DEVICETREE
7192         proc_device_tree_init();
7193  #endif
7194 -       proc_bus = proc_mkdir("bus", NULL);
7195 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
7196 +#ifdef CONFIG_GRKERNSEC_PROC_USER
7197 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, 0);
7198 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
7199 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
7200 +#endif
7201 +#else
7202 +       proc_bus = proc_mkdir("bus", 0);
7203 +#endif
7204  }
7205  
7206  static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
7207 diff -uNr linux-2.6.8/fs/proc/task_mmu.c linux-2.6.8.grsecurity/fs/proc/task_mmu.c
7208 --- linux-2.6.8/fs/proc/task_mmu.c      2004-08-14 07:36:17.000000000 +0200
7209 +++ linux-2.6.8.grsecurity/fs/proc/task_mmu.c   2004-08-16 17:08:28.000000000 +0200
7210 @@ -34,12 +34,23 @@
7211                 "VmData:\t%8lu kB\n"
7212                 "VmStk:\t%8lu kB\n"
7213                 "VmExe:\t%8lu kB\n"
7214 -               "VmLib:\t%8lu kB\n",
7215 -               mm->total_vm << (PAGE_SHIFT-10),
7216 +               "VmLib:\t%8lu kB\n"
7217 +
7218 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
7219 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
7220 +#endif
7221 +
7222 +               ,mm->total_vm << (PAGE_SHIFT-10),
7223                 mm->locked_vm << (PAGE_SHIFT-10),
7224                 mm->rss << (PAGE_SHIFT-10),
7225                 data - stack, stack,
7226 -               exec - lib, lib);
7227 +               exec - lib, lib
7228 +
7229 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
7230 +               , mm->context.user_cs_base, mm->context.user_cs_limit
7231 +#endif
7232 +
7233 +);
7234         up_read(&mm->mmap_sem);
7235         return buffer;
7236  }
7237 @@ -76,8 +87,17 @@
7238         return size;
7239  }
7240  
7241 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7242 +#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
7243 +                       task->flags & PF_PAX_SEGMEXEC || \
7244 +                       task->flags & PF_PAX_RANDEXEC)
7245 +#endif
7246 +
7247  static int show_map(struct seq_file *m, void *v)
7248  {
7249 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7250 +       struct task_struct *task = m->private;
7251 +#endif
7252         struct vm_area_struct *map = v;
7253         struct file *file = map->vm_file;
7254         int flags = map->vm_flags;
7255 @@ -92,8 +112,14 @@
7256         }
7257  
7258         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
7259 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
7260 +                       PAX_RAND_FLAGS ? 0UL : map->vm_start,
7261 +                       PAX_RAND_FLAGS ? 0UL : map->vm_end,
7262 +#else
7263                         map->vm_start,
7264                         map->vm_end,
7265 +#endif
7266 +
7267                         flags & VM_READ ? 'r' : '-',
7268                         flags & VM_WRITE ? 'w' : '-',
7269                         flags & VM_EXEC ? 'x' : '-',
7270 diff -uNr linux-2.6.8/fs/readdir.c linux-2.6.8.grsecurity/fs/readdir.c
7271 --- linux-2.6.8/fs/readdir.c    2004-08-14 07:36:57.000000000 +0200
7272 +++ linux-2.6.8.grsecurity/fs/readdir.c 2004-08-16 17:08:28.000000000 +0200
7273 @@ -15,6 +15,8 @@
7274  #include <linux/dirent.h>
7275  #include <linux/security.h>
7276  #include <linux/unistd.h>
7277 +#include <linux/namei.h>
7278 +#include <linux/grsecurity.h>
7279  
7280  #include <asm/uaccess.h>
7281  
7282 @@ -65,6 +67,7 @@
7283  struct readdir_callback {
7284         struct old_linux_dirent __user * dirent;
7285         int result;
7286 +       struct nameidata nd;
7287  };
7288  
7289  static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
7290 @@ -75,6 +78,10 @@
7291  
7292         if (buf->result)
7293                 return -EINVAL;
7294 +
7295 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7296 +               return 0;
7297 +
7298         buf->result++;
7299         dirent = buf->dirent;
7300         if (!access_ok(VERIFY_WRITE, dirent,
7301 @@ -107,6 +114,9 @@
7302         buf.result = 0;
7303         buf.dirent = dirent;
7304  
7305 +       buf.nd.dentry = file->f_dentry;
7306 +       buf.nd.mnt = file->f_vfsmnt;
7307 +
7308         error = vfs_readdir(file, fillonedir, &buf);
7309         if (error >= 0)
7310                 error = buf.result;
7311 @@ -134,6 +144,7 @@
7312         struct linux_dirent __user * previous;
7313         int count;
7314         int error;
7315 +       struct nameidata nd;
7316  };
7317  
7318  static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
7319 @@ -146,6 +157,10 @@
7320         buf->error = -EINVAL;   /* only used if we fail.. */
7321         if (reclen > buf->count)
7322                 return -EINVAL;
7323 +
7324 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7325 +               return 0;
7326 +
7327         dirent = buf->previous;
7328         if (dirent) {
7329                 if (__put_user(offset, &dirent->d_off))
7330 @@ -193,6 +208,9 @@
7331         buf.count = count;
7332         buf.error = 0;
7333  
7334 +       buf.nd.dentry = file->f_dentry;
7335 +       buf.nd.mnt = file->f_vfsmnt;
7336 +
7337         error = vfs_readdir(file, filldir, &buf);
7338         if (error < 0)
7339                 goto out_putf;
7340 @@ -218,6 +236,7 @@
7341         struct linux_dirent64 __user * previous;
7342         int count;
7343         int error;
7344 +       struct nameidata nd;
7345  };
7346  
7347  static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
7348 @@ -230,6 +249,10 @@
7349         buf->error = -EINVAL;   /* only used if we fail.. */
7350         if (reclen > buf->count)
7351                 return -EINVAL;
7352 +
7353 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
7354 +               return 0;
7355 +
7356         dirent = buf->previous;
7357         if (dirent) {
7358                 if (__put_user(offset, &dirent->d_off))
7359 @@ -279,6 +302,9 @@
7360         buf.count = count;
7361         buf.error = 0;
7362  
7363 +       buf.nd.mnt = file->f_vfsmnt;
7364 +       buf.nd.dentry = file->f_dentry;
7365 +
7366         error = vfs_readdir(file, filldir64, &buf);
7367         if (error < 0)
7368                 goto out_putf;
7369 diff -uNr linux-2.6.8/grsecurity/gracl_alloc.c linux-2.6.8.grsecurity/grsecurity/gracl_alloc.c
7370 --- linux-2.6.8/grsecurity/gracl_alloc.c        1970-01-01 01:00:00.000000000 +0100
7371 +++ linux-2.6.8.grsecurity/grsecurity/gracl_alloc.c     2004-08-16 17:08:29.000000000 +0200
7372 @@ -0,0 +1,93 @@
7373 +/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
7374 +
7375 +#include <linux/kernel.h>
7376 +#include <linux/mm.h>
7377 +#include <linux/slab.h>
7378 +#include <linux/vmalloc.h>
7379 +#include <linux/gracl.h>
7380 +#include <linux/grsecurity.h>
7381 +
7382 +static unsigned long alloc_stack_next = 1;
7383 +static unsigned long alloc_stack_size = 1;
7384 +static void **alloc_stack;
7385 +
7386 +static __inline__ int
7387 +alloc_pop(void)
7388 +{
7389 +       if (alloc_stack_next == 1)
7390 +               return 0;
7391 +
7392 +       kfree(alloc_stack[alloc_stack_next - 2]);
7393 +
7394 +       alloc_stack_next--;
7395 +
7396 +       return 1;
7397 +}
7398 +
7399 +static __inline__ void
7400 +alloc_push(void *buf)
7401 +{
7402 +       if (alloc_stack_next >= alloc_stack_size)
7403 +               BUG();
7404 +
7405 +       alloc_stack[alloc_stack_next - 1] = buf;
7406 +
7407 +       alloc_stack_next++;
7408 +
7409 +       return;
7410 +}
7411 +
7412 +void *
7413 +acl_alloc(unsigned long len)
7414 +{
7415 +       void *ret;
7416 +
7417 +       if (len > PAGE_SIZE)
7418 +               BUG();
7419 +
7420 +       ret = kmalloc(len, GFP_KERNEL);
7421 +
7422 +       if (ret)
7423 +               alloc_push(ret);
7424 +
7425 +       return ret;
7426 +}
7427 +
7428 +void
7429 +acl_free_all(void)
7430 +{
7431 +       if (gr_acl_is_enabled() || !alloc_stack)
7432 +               return;
7433 +
7434 +       while (alloc_pop()) ;
7435 +
7436 +       if (alloc_stack) {
7437 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
7438 +                       kfree(alloc_stack);
7439 +               else
7440 +                       vfree(alloc_stack);
7441 +       }
7442 +
7443 +       alloc_stack = NULL;
7444 +       alloc_stack_size = 1;
7445 +       alloc_stack_next = 1;
7446 +
7447 +       return;
7448 +}
7449 +
7450 +int
7451 +acl_alloc_stack_init(unsigned long size)
7452 +{
7453 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
7454 +               alloc_stack =
7455 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
7456 +       else
7457 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
7458 +
7459 +       alloc_stack_size = size;
7460 +
7461 +       if (!alloc_stack)
7462 +               return 0;
7463 +       else
7464 +               return 1;
7465 +}
7466 diff -uNr linux-2.6.8/grsecurity/gracl.c linux-2.6.8.grsecurity/grsecurity/gracl.c
7467 --- linux-2.6.8/grsecurity/gracl.c      1970-01-01 01:00:00.000000000 +0100
7468 +++ linux-2.6.8.grsecurity/grsecurity/gracl.c   2004-08-16 17:08:29.000000000 +0200
7469 @@ -0,0 +1,3440 @@
7470 +/* 
7471 + * grsecurity/gracl.c
7472 + * Copyright Brad Spengler 2001, 2002, 2003
7473 + *
7474 + */
7475 +
7476 +#include <linux/kernel.h>
7477 +#include <linux/module.h>
7478 +#include <linux/sched.h>
7479 +#include <linux/mm.h>
7480 +#include <linux/file.h>
7481 +#include <linux/fs.h>
7482 +#include <linux/namei.h>
7483 +#include <linux/mount.h>
7484 +#include <linux/tty.h>
7485 +#include <linux/proc_fs.h>
7486 +#include <linux/smp_lock.h>
7487 +#include <linux/slab.h>
7488 +#include <linux/vmalloc.h>
7489 +#include <linux/types.h>
7490 +#include <linux/capability.h>
7491 +#include <linux/sysctl.h>
7492 +#include <linux/ptrace.h>
7493 +#include <linux/gracl.h>
7494 +#include <linux/gralloc.h>
7495 +#include <linux/grsecurity.h>
7496 +#include <linux/grinternal.h>
7497 +#include <linux/percpu.h>
7498 +
7499 +#include <asm/uaccess.h>
7500 +#include <asm/errno.h>
7501 +#include <asm/mman.h>
7502 +
7503 +static struct acl_role_db acl_role_set;
7504 +static struct acl_role_label *role_list_head;
7505 +static struct name_db name_set;
7506 +static struct name_db inodev_set;
7507 +
7508 +/* for keeping track of userspace pointers used for subjects, so we
7509 +   can share references in the kernel as well
7510 +*/
7511 +
7512 +static struct dentry *real_root;
7513 +static struct vfsmount *real_root_mnt;
7514 +
7515 +static struct acl_subj_map_db subj_map_set;
7516 +
7517 +static struct acl_role_label *default_role;
7518 +
7519 +static u16 acl_sp_role_value;
7520 +
7521 +extern char *gr_shared_page[4];
7522 +static DECLARE_MUTEX(gr_dev_sem);
7523 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
7524 +
7525 +struct gr_arg *gr_usermode;
7526 +
7527 +static unsigned long gr_status = GR_STATUS_INIT;
7528 +
7529 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
7530 +extern void gr_clear_learn_entries(void);
7531 +
7532 +#ifdef CONFIG_GRKERNSEC_RESLOG
7533 +extern void gr_log_resource(const struct task_struct *task,
7534 +                           const int res, const unsigned long wanted, const int gt);
7535 +#endif
7536 +
7537 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
7538 +                        struct dentry *root, struct vfsmount *rootmnt,
7539 +                        char *buffer, int buflen);
7540 +
7541 +unsigned char *gr_system_salt;
7542 +unsigned char *gr_system_sum;
7543 +
7544 +static struct sprole_pw **acl_special_roles = NULL;
7545 +static __u16 num_sprole_pws = 0;
7546 +
7547 +static struct acl_role_label *kernel_role = NULL;
7548 +
7549 +/* The following are used to keep a place held in the hash table when we move
7550 +   entries around.  They can be replaced during insert. */
7551 +
7552 +static struct acl_subject_label *deleted_subject;
7553 +static struct acl_object_label *deleted_object;
7554 +static struct name_entry *deleted_inodev;
7555 +
7556 +/* for keeping track of the last and final allocated subjects, since
7557 +   nested subject parsing is tricky
7558 +*/
7559 +static struct acl_subject_label *s_last = NULL;
7560 +static struct acl_subject_label *s_final = NULL;
7561 +
7562 +static unsigned int gr_auth_attempts = 0;
7563 +static unsigned long gr_auth_expires = 0UL;
7564 +
7565 +extern int gr_init_uidset(void);
7566 +extern void gr_free_uidset(void);
7567 +extern void gr_remove_uid(uid_t uid);
7568 +extern int gr_find_uid(uid_t uid);
7569 +
7570 +__inline__ int
7571 +gr_acl_is_enabled(void)
7572 +{
7573 +       return (gr_status & GR_READY);
7574 +}
7575 +
7576 +char gr_roletype_to_char(void)
7577 +{
7578 +       switch (current->role->roletype &
7579 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
7580 +                GR_ROLE_SPECIAL)) {
7581 +       case GR_ROLE_DEFAULT:
7582 +               return 'D';
7583 +       case GR_ROLE_USER:
7584 +               return 'U';
7585 +       case GR_ROLE_GROUP:
7586 +               return 'G';
7587 +       case GR_ROLE_SPECIAL:
7588 +               return 'S';
7589 +       }
7590 +
7591 +       return 'X';
7592 +}
7593 +
7594 +__inline__ int
7595 +gr_acl_tpe_check(void)
7596 +{
7597 +       if (unlikely(!(gr_status & GR_READY)))
7598 +               return 0;
7599 +       if (current->role->roletype & GR_ROLE_TPE)
7600 +               return 1;
7601 +       else
7602 +               return 0;
7603 +}
7604 +
7605 +int
7606 +gr_handle_rawio(const struct inode *inode)
7607 +{
7608 +       if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
7609 +           ((gr_status & GR_READY)
7610 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7611 +            || (grsec_enable_chroot_caps && proc_is_chrooted(current))
7612 +#endif
7613 +           ))
7614 +               return 1;
7615 +       return 0;
7616 +}
7617 +
7618 +
7619 +static __inline__ int
7620 +gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
7621 +{
7622 +       int i;
7623 +       unsigned long *l1;
7624 +       unsigned long *l2;
7625 +       unsigned char *c1;
7626 +       unsigned char *c2;
7627 +       int num_longs;
7628 +
7629 +       if (likely(lena != lenb))
7630 +               return 0;
7631 +
7632 +       l1 = (unsigned long *)a;
7633 +       l2 = (unsigned long *)b;
7634 +
7635 +       num_longs = lena / sizeof(unsigned long);
7636 +
7637 +       for (i = num_longs; i--; l1++, l2++) {
7638 +               if (unlikely(*l1 != *l2))
7639 +                       return 0;
7640 +       }
7641 +
7642 +       c1 = (unsigned char *) l1;
7643 +       c2 = (unsigned char *) l2;
7644 +
7645 +       i = lena - (num_longs * sizeof(unsigned long)); 
7646 +
7647 +       for (; i--; c1++, c2++) {
7648 +               if (unlikely(*c1 != *c2))
7649 +                       return 0;
7650 +       }
7651 +
7652 +       return 1;
7653 +}
7654 +               
7655 +static char *
7656 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
7657 +               char *buf, int buflen)
7658 +{
7659 +       char *res;
7660 +       struct dentry *root;
7661 +       struct vfsmount *rootmnt;
7662 +
7663 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
7664 +       read_lock(&child_reaper->fs->lock);
7665 +       root = dget(child_reaper->fs->root);
7666 +       rootmnt = mntget(child_reaper->fs->rootmnt);
7667 +       read_unlock(&child_reaper->fs->lock);
7668 +
7669 +       res = __d_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
7670 +       if (unlikely(IS_ERR(res)))
7671 +               res = strcpy(buf, "<path too long>");
7672 +       dput(root);
7673 +       mntput(rootmnt);
7674 +       return res;
7675 +}
7676 +
7677 +char *
7678 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
7679 +{
7680 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
7681 +                               PAGE_SIZE);
7682 +}
7683 +
7684 +static char *
7685 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
7686 +           char *buf, int buflen)
7687 +{
7688 +       char *res;
7689 +       struct dentry *root;
7690 +       struct vfsmount *rootmnt;
7691 +
7692 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
7693 +       read_lock(&child_reaper->fs->lock);
7694 +       root = dget(child_reaper->fs->root);
7695 +       rootmnt = mntget(child_reaper->fs->rootmnt);
7696 +       read_unlock(&child_reaper->fs->lock);
7697 +
7698 +       spin_lock(&dcache_lock);
7699 +       res = __d_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
7700 +       spin_unlock(&dcache_lock);
7701 +       if (unlikely(IS_ERR(res)))
7702 +               res = strcpy(buf, "<path too long>");
7703 +       dput(root);
7704 +       mntput(rootmnt);
7705 +       return res;
7706 +}
7707 +
7708 +char *
7709 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
7710 +{
7711 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
7712 +                          PAGE_SIZE);
7713 +}
7714 +
7715 +char *
7716 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
7717 +{
7718 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
7719 +                          PAGE_SIZE);
7720 +}
7721 +
7722 +char *
7723 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
7724 +{
7725 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
7726 +                          PAGE_SIZE);
7727 +}
7728 +
7729 +char *
7730 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
7731 +{
7732 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
7733 +                          PAGE_SIZE);
7734 +}
7735 +
7736 +__inline__ __u32
7737 +to_gr_audit(const __u32 reqmode)
7738 +{
7739 +       __u32 retmode = 0;
7740 +
7741 +       retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
7742 +       retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
7743 +       retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
7744 +       retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
7745 +       retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
7746 +       retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
7747 +       retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
7748 +       retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
7749 +       retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
7750 +
7751 +       return retmode;
7752 +}
7753 +
7754 +__inline__ struct acl_subject_label *
7755 +lookup_subject_map(const struct acl_subject_label *userp)
7756 +{
7757 +       unsigned long index = shash(userp, subj_map_set.s_size);
7758 +       struct subject_map *match;
7759 +       __u8 i = 0;
7760 +
7761 +       match = subj_map_set.s_hash[index];
7762 +
7763 +       while (match && match->user != userp) {
7764 +               index = (index + (1 << i)) % subj_map_set.s_size;
7765 +               match = subj_map_set.s_hash[index];
7766 +               i = (i + 1) % 32;
7767 +       }
7768 +
7769 +       if (match)
7770 +               return match->kernel;
7771 +       else
7772 +               return NULL;
7773 +}
7774 +
7775 +static void
7776 +insert_subj_map_entry(struct subject_map *subjmap)
7777 +{
7778 +       unsigned long index = shash(subjmap->user, subj_map_set.s_size);
7779 +       struct subject_map **curr;
7780 +       __u8 i = 0;
7781 +
7782 +       curr = &subj_map_set.s_hash[index];
7783 +
7784 +       while (*curr) {
7785 +               index = (index + (1 << i)) % subj_map_set.s_size;
7786 +               curr = &subj_map_set.s_hash[index];
7787 +               i = (i + 1) % 32;
7788 +       }
7789 +
7790 +       *curr = subjmap;
7791 +
7792 +       return;
7793 +}
7794 +
7795 +__inline__ struct acl_role_label *
7796 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
7797 +                     const gid_t gid)
7798 +{
7799 +       unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
7800 +       struct acl_role_label *match;
7801 +       struct role_allowed_ip *ipp;
7802 +       int x;
7803 +       __u8 i = 0;
7804 +
7805 +       match = acl_role_set.r_hash[index];
7806 +
7807 +       while (match) {
7808 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
7809 +                       for (x = 0; x < match->domain_child_num; x++) {
7810 +                               if (match->domain_children[x] == uid)
7811 +                                       goto found;
7812 +                       }
7813 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
7814 +                       break;
7815 +               index = (index + (1 << i)) % acl_role_set.r_size;
7816 +               match = acl_role_set.r_hash[index];
7817 +               i = (i + 1) % 32;
7818 +       }
7819 +found:
7820 +       if (match == NULL) {
7821 +             try_group:
7822 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
7823 +               match = acl_role_set.r_hash[index];
7824 +               i = 0;
7825 +
7826 +               while (match) {
7827 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
7828 +                               for (x = 0; x < match->domain_child_num; x++) {
7829 +                                       if (match->domain_children[x] == gid)
7830 +                                               goto found2;
7831 +                               }
7832 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
7833 +                               break;
7834 +                       index = (index + (1 << i)) % acl_role_set.r_size;
7835 +                       match = acl_role_set.r_hash[index];
7836 +                       i = (i + 1) % 32;
7837 +               }
7838 +found2:
7839 +               if (match == NULL)
7840 +                       match = default_role;
7841 +               if (match->allowed_ips == NULL)
7842 +                       return match;
7843 +               else {
7844 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
7845 +                               if (likely
7846 +                                   ((ntohl(task->curr_ip) & ipp->netmask) ==
7847 +                                    (ntohl(ipp->addr) & ipp->netmask)))
7848 +                                       return match;
7849 +                       }
7850 +                       match = default_role;
7851 +               }
7852 +       } else if (match->allowed_ips == NULL) {
7853 +               return match;
7854 +       } else {
7855 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
7856 +                       if (likely
7857 +                           ((ntohl(task->curr_ip) & ipp->netmask) ==
7858 +                            (ntohl(ipp->addr) & ipp->netmask)))
7859 +                               return match;
7860 +               }
7861 +               goto try_group;
7862 +       }
7863 +
7864 +       return match;
7865 +}
7866 +
7867 +__inline__ struct acl_subject_label *
7868 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
7869 +                     const struct acl_role_label *role)
7870 +{
7871 +       unsigned long subj_size = role->subj_hash_size;
7872 +       struct acl_subject_label **s_hash = role->subj_hash;
7873 +       unsigned long index = fhash(ino, dev, subj_size);
7874 +       struct acl_subject_label *match;
7875 +       __u8 i = 0;
7876 +
7877 +       match = s_hash[index];
7878 +
7879 +       while (match && (match->inode != ino || match->device != dev ||
7880 +              (match->mode & GR_DELETED))) {
7881 +               index = (index + (1 << i)) % subj_size;
7882 +               match = s_hash[index];
7883 +               i = (i + 1) % 32;
7884 +       }
7885 +
7886 +       if (match && (match != deleted_subject) && !(match->mode & GR_DELETED))
7887 +               return match;
7888 +       else
7889 +               return NULL;
7890 +}
7891 +
7892 +static __inline__ struct acl_object_label *
7893 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
7894 +                    const struct acl_subject_label *subj)
7895 +{
7896 +       unsigned long obj_size = subj->obj_hash_size;
7897 +       struct acl_object_label **o_hash = subj->obj_hash;
7898 +       unsigned long index = fhash(ino, dev, obj_size);
7899 +       struct acl_object_label *match;
7900 +       __u8 i = 0;
7901 +
7902 +       match = o_hash[index];
7903 +
7904 +       while (match && (match->inode != ino || match->device != dev ||
7905 +              (match->mode & GR_DELETED))) {
7906 +               index = (index + (1 << i)) % obj_size;
7907 +               match = o_hash[index];
7908 +               i = (i + 1) % 32;
7909 +       }
7910 +
7911 +       if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
7912 +               return match;
7913 +       else
7914 +               return NULL;
7915 +}
7916 +
7917 +static __inline__ struct acl_object_label *
7918 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
7919 +                    const struct acl_subject_label *subj)
7920 +{
7921 +       unsigned long obj_size = subj->obj_hash_size;
7922 +       struct acl_object_label **o_hash = subj->obj_hash;
7923 +       unsigned long index = fhash(ino, dev, obj_size);
7924 +       struct acl_object_label *match;
7925 +       __u8 i = 0;
7926 +
7927 +       match = o_hash[index];
7928 +
7929 +       while (match && (match->inode != ino || match->device != dev ||
7930 +              !(match->mode & GR_DELETED))) {
7931 +               index = (index + (1 << i)) % obj_size;
7932 +               match = o_hash[index];
7933 +               i = (i + 1) % 32;
7934 +       }
7935 +
7936 +       if (match && (match != deleted_object) && (match->mode & GR_DELETED))
7937 +               return match;
7938 +
7939 +       i = 0;
7940 +       index = fhash(ino, dev, obj_size);
7941 +       match = o_hash[index];
7942 +
7943 +       while (match && (match->inode != ino || match->device != dev ||
7944 +              (match->mode & GR_DELETED))) {
7945 +               index = (index + (1 << i)) % obj_size;
7946 +               match = o_hash[index];
7947 +               i = (i + 1) % 32;
7948 +       }
7949 +
7950 +       if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
7951 +               return match;
7952 +       else
7953 +               return NULL;
7954 +}
7955 +
7956 +static __inline__ struct name_entry *
7957 +lookup_name_entry(const char *name)
7958 +{
7959 +       __u16 len = strlen(name);
7960 +       unsigned long index = nhash(name, len, name_set.n_size);
7961 +       struct name_entry *match;
7962 +       __u8 i = 0;
7963 +
7964 +       match = name_set.n_hash[index];
7965 +
7966 +       while (match && !gr_streq(match->name, name, match->len, len)) {
7967 +               index = (index + (1 << i)) % name_set.n_size;
7968 +               match = name_set.n_hash[index];
7969 +               i = (i + 1) % 32;
7970 +       }
7971 +
7972 +       return match;
7973 +}
7974 +
7975 +static __inline__ struct name_entry *
7976 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
7977 +{
7978 +       unsigned long index = fhash(ino, dev, inodev_set.n_size);
7979 +       struct name_entry *match;
7980 +       __u8 i = 0;
7981 +
7982 +       match = inodev_set.n_hash[index];
7983 +
7984 +       while (match && (match->inode != ino || match->device != dev)) {
7985 +               index = (index + (1 << i)) % inodev_set.n_size;
7986 +               match = inodev_set.n_hash[index];
7987 +               i = (i + 1) % 32;
7988 +       }
7989 +
7990 +       if (match && (match != deleted_inodev))
7991 +               return match;
7992 +       else
7993 +               return NULL;
7994 +}
7995 +
7996 +static void
7997 +insert_inodev_entry(struct name_entry *nentry)
7998 +{
7999 +       unsigned long index = fhash(nentry->inode, nentry->device,
8000 +                                   inodev_set.n_size);
8001 +       struct name_entry **curr;
8002 +       __u8 i = 0;
8003 +
8004 +       curr = &inodev_set.n_hash[index];
8005 +
8006 +       while (*curr && *curr != deleted_inodev) {
8007 +               index = (index + (1 << i)) % inodev_set.n_size;
8008 +               curr = &inodev_set.n_hash[index];
8009 +               i = (i + 1) % 32;
8010 +       }
8011 +
8012 +       *curr = nentry;
8013 +
8014 +       return;
8015 +}
8016 +
8017 +static void
8018 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
8019 +{
8020 +       unsigned long index =
8021 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
8022 +       struct acl_role_label **curr;
8023 +       __u8 i = 0;
8024 +
8025 +       curr = &acl_role_set.r_hash[index];
8026 +
8027 +       while (*curr) {
8028 +               index = (index + (1 << i)) % acl_role_set.r_size;
8029 +               curr = &acl_role_set.r_hash[index];
8030 +               i = (i + 1) % 32;
8031 +       }
8032 +
8033 +       *curr = role;
8034 +
8035 +       return;
8036 +}
8037 +
8038 +static void
8039 +insert_acl_role_label(struct acl_role_label *role)
8040 +{
8041 +       int i;
8042 +
8043 +       if (role->roletype & GR_ROLE_DOMAIN) {
8044 +               for (i = 0; i < role->domain_child_num; i++)
8045 +                       __insert_acl_role_label(role, role->domain_children[i]);
8046 +       } else
8047 +               __insert_acl_role_label(role, role->uidgid);
8048 +}
8049 +                                       
8050 +static int
8051 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
8052 +{
8053 +       struct name_entry **curr;
8054 +       __u8 i = 0;
8055 +       __u16 len = strlen(name);
8056 +       unsigned long index = nhash(name, len, name_set.n_size);
8057 +
8058 +       curr = &name_set.n_hash[index];
8059 +
8060 +       while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
8061 +               index = (index + (1 << i)) % name_set.n_size;
8062 +               curr = &name_set.n_hash[index];
8063 +               i = (i + 1) % 32;
8064 +       }
8065 +
8066 +       if (!(*curr)) {
8067 +               struct name_entry *nentry =
8068 +                   acl_alloc(sizeof (struct name_entry));
8069 +               if (!nentry)
8070 +                       return 0;
8071 +               nentry->name = name;
8072 +               nentry->inode = inode;
8073 +               nentry->device = device;
8074 +               nentry->len = len;
8075 +               *curr = nentry;
8076 +               /* insert us into the table searchable by inode/dev */
8077 +               insert_inodev_entry(nentry);
8078 +       }
8079 +
8080 +       return 1;
8081 +}
8082 +
8083 +static void
8084 +insert_acl_obj_label(struct acl_object_label *obj,
8085 +                    struct acl_subject_label *subj)
8086 +{
8087 +       unsigned long index =
8088 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
8089 +       struct acl_object_label **curr;
8090 +       __u8 i = 0;
8091 +
8092 +       curr = &subj->obj_hash[index];
8093 +
8094 +       while (*curr && *curr != deleted_object) {
8095 +               index = (index + (1 << i)) % subj->obj_hash_size;
8096 +               curr = &subj->obj_hash[index];
8097 +               i = (i + 1) % 32;
8098 +       }
8099 +
8100 +       *curr = obj;
8101 +
8102 +       return;
8103 +}
8104 +
8105 +static void
8106 +insert_acl_subj_label(struct acl_subject_label *obj,
8107 +                     struct acl_role_label *role)
8108 +{
8109 +       unsigned long subj_size = role->subj_hash_size;
8110 +       struct acl_subject_label **s_hash = role->subj_hash;
8111 +       unsigned long index = fhash(obj->inode, obj->device, subj_size);
8112 +       struct acl_subject_label **curr;
8113 +       __u8 i = 0;
8114 +
8115 +       curr = &s_hash[index];
8116 +
8117 +       while (*curr && *curr != deleted_subject) {
8118 +               index = (index + (1 << i)) % subj_size;
8119 +               curr = &s_hash[index];
8120 +               i = (i + 1) % 32;
8121 +       }
8122 +
8123 +       *curr = obj;
8124 +
8125 +       return;
8126 +}
8127 +
8128 +static void **
8129 +create_table(__u32 * len)
8130 +{
8131 +       unsigned long table_sizes[] = {
8132 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
8133 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
8134 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
8135 +               268435399, 536870909, 1073741789, 2147483647
8136 +       };
8137 +       void *newtable = NULL;
8138 +       unsigned int pwr = 0;
8139 +
8140 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
8141 +              table_sizes[pwr] <= (2 * (*len)))
8142 +               pwr++;
8143 +
8144 +       if (table_sizes[pwr] <= (2 * (*len)))
8145 +               return newtable;
8146 +
8147 +       if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
8148 +               newtable =
8149 +                   kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
8150 +       else
8151 +               newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
8152 +
8153 +       *len = table_sizes[pwr];
8154 +
8155 +       return newtable;
8156 +}
8157 +
8158 +static int
8159 +init_variables(const struct gr_arg *arg)
8160 +{
8161 +       unsigned long stacksize;
8162 +
8163 +       subj_map_set.s_size = arg->role_db.num_subjects;
8164 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
8165 +       name_set.n_size = arg->role_db.num_objects;
8166 +       inodev_set.n_size = arg->role_db.num_objects;
8167 +
8168 +       if (!gr_init_uidset())
8169 +               return 1;
8170 +
8171 +       /* set up the stack that holds allocation info */
8172 +
8173 +       stacksize = arg->role_db.num_pointers + 5;
8174 +
8175 +       if (!acl_alloc_stack_init(stacksize))
8176 +               return 1;
8177 +
8178 +       /* create our empty, fake deleted acls */
8179 +       deleted_subject =
8180 +           (struct acl_subject_label *)
8181 +           acl_alloc(sizeof (struct acl_subject_label));
8182 +       deleted_object =
8183 +           (struct acl_object_label *)
8184 +           acl_alloc(sizeof (struct acl_object_label));
8185 +       deleted_inodev =
8186 +           (struct name_entry *) acl_alloc(sizeof (struct name_entry));
8187 +
8188 +       if (!deleted_subject || !deleted_object || !deleted_inodev)
8189 +               return 1;
8190 +
8191 +       memset(deleted_subject, 0, sizeof (struct acl_subject_label));
8192 +       memset(deleted_object, 0, sizeof (struct acl_object_label));
8193 +       memset(deleted_inodev, 0, sizeof (struct name_entry));
8194 +
8195 +       /* grab reference for the real root dentry and vfsmount */
8196 +       read_lock(&child_reaper->fs->lock);
8197 +       real_root_mnt = mntget(child_reaper->fs->rootmnt);
8198 +       real_root = dget(child_reaper->fs->root);
8199 +       read_unlock(&child_reaper->fs->lock);
8200 +       
8201 +
8202 +       /* We only want 50% full tables for now */
8203 +
8204 +       subj_map_set.s_hash =
8205 +           (struct subject_map **) create_table(&subj_map_set.s_size);
8206 +       acl_role_set.r_hash =
8207 +           (struct acl_role_label **) create_table(&acl_role_set.r_size);
8208 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
8209 +       inodev_set.n_hash =
8210 +           (struct name_entry **) create_table(&inodev_set.n_size);
8211 +
8212 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
8213 +           !name_set.n_hash || !inodev_set.n_hash)
8214 +               return 1;
8215 +
8216 +       memset(subj_map_set.s_hash, 0,
8217 +              sizeof(struct subject_map *) * subj_map_set.s_size);
8218 +       memset(acl_role_set.r_hash, 0,
8219 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
8220 +       memset(name_set.n_hash, 0,
8221 +              sizeof (struct name_entry *) * name_set.n_size);
8222 +       memset(inodev_set.n_hash, 0,
8223 +              sizeof (struct name_entry *) * inodev_set.n_size);
8224 +
8225 +       return 0;
8226 +}
8227 +
8228 +/* free information not needed after startup
8229 +   currently contains user->kernel pointer mappings for subjects
8230 +*/
8231 +
8232 +static void
8233 +free_init_variables(void)
8234 +{
8235 +       __u32 i;
8236 +
8237 +       if (subj_map_set.s_hash) {
8238 +               for (i = 0; i < subj_map_set.s_size; i++) {
8239 +                       if (subj_map_set.s_hash[i]) {
8240 +                               kfree(subj_map_set.s_hash[i]);
8241 +                               subj_map_set.s_hash[i] = NULL;
8242 +                       }
8243 +               }
8244 +
8245 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
8246 +                   PAGE_SIZE)
8247 +                       kfree(subj_map_set.s_hash);
8248 +               else
8249 +                       vfree(subj_map_set.s_hash);
8250 +       }
8251 +
8252 +       return;
8253 +}
8254 +
8255 +static void
8256 +free_variables(void)
8257 +{
8258 +       struct acl_subject_label *s;
8259 +       struct acl_role_label *r;
8260 +       struct task_struct *task, *task2;
8261 +
8262 +       gr_clear_learn_entries();
8263 +
8264 +       read_lock(&tasklist_lock);
8265 +       for_each_process(task) {
8266 +               task2 = task;
8267 +               do {
8268 +                       task2->acl_sp_role = 0;
8269 +                       task2->acl_role_id = 0;
8270 +                       task2->acl = NULL;
8271 +                       task2->role = NULL;
8272 +               } while ((task2 = next_thread(task2)) != task);
8273 +       }
8274 +       read_unlock(&tasklist_lock);
8275 +
8276 +       /* release the reference to the real root dentry and vfsmount */
8277 +       if (real_root)
8278 +               dput(real_root);
8279 +       real_root = NULL;
8280 +       if (real_root_mnt)
8281 +               mntput(real_root_mnt);
8282 +       real_root_mnt = NULL;
8283 +
8284 +       /* free all object hash tables */
8285 +
8286 +       if (role_list_head) {
8287 +               for (r = role_list_head; r; r = r->next) {
8288 +                       if (!r->subj_hash)
8289 +                               break;
8290 +                       for (s = r->hash->first; s; s = s->next) {
8291 +                               if (!s->obj_hash)
8292 +                                       break;
8293 +                               if ((s->obj_hash_size *
8294 +                                    sizeof (struct acl_object_label *)) <=
8295 +                                   PAGE_SIZE)
8296 +                                       kfree(s->obj_hash);
8297 +                               else
8298 +                                       vfree(s->obj_hash);
8299 +                       }
8300 +                       if ((r->subj_hash_size *
8301 +                            sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
8302 +                               kfree(r->subj_hash);
8303 +                       else
8304 +                               vfree(r->subj_hash);
8305 +               }
8306 +       }
8307 +
8308 +       acl_free_all();
8309 +
8310 +       if (acl_role_set.r_hash) {
8311 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
8312 +                   PAGE_SIZE)
8313 +                       kfree(acl_role_set.r_hash);
8314 +               else
8315 +                       vfree(acl_role_set.r_hash);
8316 +       }
8317 +       if (name_set.n_hash) {
8318 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
8319 +                   PAGE_SIZE)
8320 +                       kfree(name_set.n_hash);
8321 +               else
8322 +                       vfree(name_set.n_hash);
8323 +       }
8324 +
8325 +       if (inodev_set.n_hash) {
8326 +               if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
8327 +                   PAGE_SIZE)
8328 +                       kfree(inodev_set.n_hash);
8329 +               else
8330 +                       vfree(inodev_set.n_hash);
8331 +       }
8332 +
8333 +       gr_free_uidset();
8334 +
8335 +       memset(&name_set, 0, sizeof (struct name_db));
8336 +       memset(&inodev_set, 0, sizeof (struct name_db));
8337 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
8338 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
8339 +
8340 +       role_list_head = NULL;
8341 +       default_role = NULL;
8342 +
8343 +       return;
8344 +}
8345 +
8346 +static __u32
8347 +count_user_objs(struct acl_object_label *userp)
8348 +{
8349 +       struct acl_object_label o_tmp;
8350 +       __u32 num = 0;
8351 +
8352 +       while (userp) {
8353 +               if (copy_from_user(&o_tmp, userp,
8354 +                                  sizeof (struct acl_object_label)))
8355 +                       break;
8356 +
8357 +               userp = o_tmp.prev;
8358 +               num++;
8359 +       }
8360 +
8361 +       return num;
8362 +}
8363 +
8364 +static struct acl_subject_label *
8365 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
8366 +
8367 +static int
8368 +copy_user_glob(struct acl_object_label *obj)
8369 +{
8370 +       struct acl_object_label *g_tmp, **guser, *glast = NULL;
8371 +       unsigned int len;
8372 +       char *tmp;
8373 +
8374 +       if (obj->globbed == NULL)
8375 +               return 0;
8376 +
8377 +       guser = &obj->globbed;
8378 +       while (*guser) {
8379 +               g_tmp = (struct acl_object_label *)
8380 +                       acl_alloc(sizeof (struct acl_object_label));
8381 +               if (g_tmp == NULL)
8382 +                       return -ENOMEM;
8383 +
8384 +               if (copy_from_user(g_tmp, *guser,
8385 +                                  sizeof (struct acl_object_label)))
8386 +                       return -EFAULT;
8387 +
8388 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
8389 +
8390 +               if (!len || len >= PATH_MAX)
8391 +                       return -EINVAL;
8392 +
8393 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
8394 +                       return -ENOMEM;
8395 +
8396 +               if (copy_from_user(tmp, g_tmp->filename, len))
8397 +                       return -EFAULT;
8398 +
8399 +               g_tmp->filename = tmp;
8400 +
8401 +               if (glast)
8402 +                       glast->next = g_tmp;
8403 +               g_tmp->prev = glast;
8404 +               *guser = g_tmp;
8405 +               glast = g_tmp;
8406 +               guser = &((*guser)->next);
8407 +       }
8408 +
8409 +       return 0;
8410 +}
8411 +
8412 +static int
8413 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
8414 +              struct acl_role_label *role)
8415 +{
8416 +       struct acl_object_label *o_tmp;
8417 +       unsigned int len;
8418 +       int ret;
8419 +       char *tmp;
8420 +
8421 +       while (userp) {
8422 +               if ((o_tmp = (struct acl_object_label *)
8423 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
8424 +                       return -ENOMEM;
8425 +
8426 +               if (copy_from_user(o_tmp, userp,
8427 +                                  sizeof (struct acl_object_label)))
8428 +                       return -EFAULT;
8429 +
8430 +               userp = o_tmp->prev;
8431 +
8432 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
8433 +
8434 +               if (!len || len >= PATH_MAX)
8435 +                       return -EINVAL;
8436 +
8437 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
8438 +                       return -ENOMEM;
8439 +
8440 +               if (copy_from_user(tmp, o_tmp->filename, len))
8441 +                       return -EFAULT;
8442 +
8443 +               o_tmp->filename = tmp;
8444 +
8445 +               insert_acl_obj_label(o_tmp, subj);
8446 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
8447 +                                      o_tmp->device))
8448 +                       return -ENOMEM;
8449 +
8450 +               ret = copy_user_glob(o_tmp);
8451 +               if (ret)
8452 +                       return ret;
8453 +
8454 +               if (o_tmp->nested) {
8455 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
8456 +                       if (IS_ERR(o_tmp->nested))
8457 +                               return PTR_ERR(o_tmp->nested);
8458 +
8459 +                       s_final = o_tmp->nested;
8460 +               }
8461 +       }
8462 +
8463 +       return 0;
8464 +}
8465 +
8466 +static __u32
8467 +count_user_subjs(struct acl_subject_label *userp)
8468 +{
8469 +       struct acl_subject_label s_tmp;
8470 +       __u32 num = 0;
8471 +
8472 +       while (userp) {
8473 +               if (copy_from_user(&s_tmp, userp,
8474 +                                  sizeof (struct acl_subject_label)))
8475 +                       break;
8476 +
8477 +               userp = s_tmp.prev;
8478 +               /* do not count nested subjects against this count, since
8479 +                  they are not included in the hash table, but are
8480 +                  attached to objects.  We have already counted
8481 +                  the subjects in userspace for the allocation 
8482 +                  stack
8483 +               */
8484 +               if (!(s_tmp.mode & GR_NESTED))
8485 +                       num++;
8486 +       }
8487 +
8488 +       return num;
8489 +}
8490 +
8491 +static int
8492 +copy_user_allowedips(struct acl_role_label *rolep)
8493 +{
8494 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
8495 +
8496 +       ruserip = rolep->allowed_ips;
8497 +
8498 +       while (ruserip) {
8499 +               rlast = rtmp;
8500 +
8501 +               if ((rtmp = (struct role_allowed_ip *)
8502 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
8503 +                       return -ENOMEM;
8504 +
8505 +               if (copy_from_user(rtmp, ruserip,
8506 +                                  sizeof (struct role_allowed_ip)))
8507 +                       return -EFAULT;
8508 +
8509 +               ruserip = rtmp->prev;
8510 +
8511 +               if (!rlast) {
8512 +                       rtmp->prev = NULL;
8513 +                       rolep->allowed_ips = rtmp;
8514 +               } else {
8515 +                       rlast->next = rtmp;
8516 +                       rtmp->prev = rlast;
8517 +               }
8518 +
8519 +               if (!ruserip)
8520 +                       rtmp->next = NULL;
8521 +       }
8522 +
8523 +       return 0;
8524 +}
8525 +
8526 +static int
8527 +copy_user_transitions(struct acl_role_label *rolep)
8528 +{
8529 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
8530 +       unsigned int len;
8531 +       char *tmp;
8532 +
8533 +       rusertp = rolep->transitions;
8534 +
8535 +       while (rusertp) {
8536 +               rlast = rtmp;
8537 +
8538 +               if ((rtmp = (struct role_transition *)
8539 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
8540 +                       return -ENOMEM;
8541 +
8542 +               if (copy_from_user(rtmp, rusertp,
8543 +                                  sizeof (struct role_transition)))
8544 +                       return -EFAULT;
8545 +
8546 +               rusertp = rtmp->prev;
8547 +
8548 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
8549 +
8550 +               if (!len || len >= GR_SPROLE_LEN)
8551 +                       return -EINVAL;
8552 +
8553 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
8554 +                       return -ENOMEM;
8555 +
8556 +               if (copy_from_user(tmp, rtmp->rolename, len))
8557 +                       return -EFAULT;
8558 +
8559 +               rtmp->rolename = tmp;
8560 +
8561 +               if (!rlast) {
8562 +                       rtmp->prev = NULL;
8563 +                       rolep->transitions = rtmp;
8564 +               } else {
8565 +                       rlast->next = rtmp;
8566 +                       rtmp->prev = rlast;
8567 +               }
8568 +
8569 +               if (!rusertp)
8570 +                       rtmp->next = NULL;
8571 +       }
8572 +
8573 +       return 0;
8574 +}
8575 +
8576 +static struct acl_subject_label *
8577 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
8578 +{
8579 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
8580 +       unsigned int len;
8581 +       char *tmp;
8582 +       __u32 num_objs;
8583 +       struct acl_ip_label **i_tmp, *i_utmp2;
8584 +       struct gr_hash_struct ghash;
8585 +       struct subject_map *subjmap;
8586 +       unsigned long i_num;
8587 +       int err;
8588 +
8589 +       s_tmp = lookup_subject_map(userp);
8590 +
8591 +       /* we've already copied this subject into the kernel, just return
8592 +          the reference to it, and don't copy it over again
8593 +       */
8594 +       if (s_tmp)
8595 +               return(s_tmp);
8596 +
8597 +
8598 +       if ((s_tmp = (struct acl_subject_label *)
8599 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
8600 +               return ERR_PTR(-ENOMEM);
8601 +
8602 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
8603 +       if (subjmap == NULL)
8604 +               return ERR_PTR(-ENOMEM);
8605 +
8606 +       subjmap->user = userp;
8607 +       subjmap->kernel = s_tmp;
8608 +       insert_subj_map_entry(subjmap);
8609 +
8610 +       if (copy_from_user(s_tmp, userp,
8611 +                          sizeof (struct acl_subject_label)))
8612 +               return ERR_PTR(-EFAULT);
8613 +
8614 +       if (!s_last) {
8615 +               s_tmp->prev = NULL;
8616 +               role->hash->first = s_tmp;
8617 +       } else {
8618 +               s_last->next = s_tmp;
8619 +               s_tmp->prev = s_last;
8620 +       }
8621 +
8622 +       s_last = s_tmp;
8623 +
8624 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
8625 +
8626 +       if (!len || len >= PATH_MAX)
8627 +               return ERR_PTR(-EINVAL);
8628 +
8629 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
8630 +               return ERR_PTR(-ENOMEM);
8631 +
8632 +       if (copy_from_user(tmp, s_tmp->filename, len))
8633 +               return ERR_PTR(-EFAULT);
8634 +
8635 +       s_tmp->filename = tmp;
8636 +
8637 +       if (!strcmp(s_tmp->filename, "/"))
8638 +               role->root_label = s_tmp;
8639 +
8640 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
8641 +               return ERR_PTR(-EFAULT);
8642 +
8643 +       /* copy user and group transition tables */
8644 +
8645 +       if (s_tmp->user_trans_num) {
8646 +               uid_t *uidlist;
8647 +
8648 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
8649 +               if (uidlist == NULL)
8650 +                       return ERR_PTR(-ENOMEM);
8651 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
8652 +                       return ERR_PTR(-EFAULT);
8653 +
8654 +               s_tmp->user_transitions = uidlist;
8655 +       }
8656 +
8657 +       if (s_tmp->group_trans_num) {
8658 +               gid_t *gidlist;
8659 +
8660 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
8661 +               if (gidlist == NULL)
8662 +                       return ERR_PTR(-ENOMEM);
8663 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
8664 +                       return ERR_PTR(-EFAULT);
8665 +
8666 +               s_tmp->group_transitions = gidlist;
8667 +       }
8668 +
8669 +       /* set up object hash table */
8670 +       num_objs = count_user_objs(ghash.first);
8671 +
8672 +       s_tmp->obj_hash_size = num_objs;
8673 +       s_tmp->obj_hash =
8674 +           (struct acl_object_label **)
8675 +           create_table(&(s_tmp->obj_hash_size));
8676 +
8677 +       if (!s_tmp->obj_hash)
8678 +               return ERR_PTR(-ENOMEM);
8679 +
8680 +       memset(s_tmp->obj_hash, 0,
8681 +              s_tmp->obj_hash_size *
8682 +              sizeof (struct acl_object_label *));
8683 +
8684 +       /* copy before adding in objects, since a nested
8685 +          acl could be found and be the final subject
8686 +          copied
8687 +       */
8688 +
8689 +       s_final = s_tmp;
8690 +
8691 +       /* add in objects */
8692 +       err = copy_user_objs(ghash.first, s_tmp, role);
8693 +
8694 +       if (err)
8695 +               return ERR_PTR(err);
8696 +
8697 +       /* set pointer for parent subject */
8698 +       if (s_tmp->parent_subject) {
8699 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
8700 +
8701 +               if (IS_ERR(s_tmp2))
8702 +                       return s_tmp2;
8703 +
8704 +               s_tmp->parent_subject = s_tmp2;
8705 +       }
8706 +
8707 +       /* add in ip acls */
8708 +
8709 +       if (!s_tmp->ip_num) {
8710 +               s_tmp->ips = NULL;
8711 +               goto insert;
8712 +       }
8713 +
8714 +       i_tmp =
8715 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
8716 +                                              sizeof (struct
8717 +                                                      acl_ip_label *));
8718 +
8719 +       if (!i_tmp)
8720 +               return ERR_PTR(-ENOMEM);
8721 +
8722 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
8723 +               *(i_tmp + i_num) =
8724 +                   (struct acl_ip_label *)
8725 +                   acl_alloc(sizeof (struct acl_ip_label));
8726 +               if (!*(i_tmp + i_num))
8727 +                       return ERR_PTR(-ENOMEM);
8728 +
8729 +               if (copy_from_user
8730 +                   (&i_utmp2, s_tmp->ips + i_num,
8731 +                    sizeof (struct acl_ip_label *)))
8732 +                       return ERR_PTR(-EFAULT);
8733 +
8734 +               if (copy_from_user
8735 +                   (*(i_tmp + i_num), i_utmp2,
8736 +                    sizeof (struct acl_ip_label)))
8737 +                       return ERR_PTR(-EFAULT);
8738 +       }
8739 +
8740 +       s_tmp->ips = i_tmp;
8741 +
8742 +insert:
8743 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
8744 +                              s_tmp->device))
8745 +               return ERR_PTR(-ENOMEM);
8746 +
8747 +       return s_tmp;
8748 +}
8749 +
8750 +static int
8751 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
8752 +{
8753 +       struct acl_subject_label s_pre;
8754 +       struct acl_subject_label * ret;
8755 +       int err;
8756 +
8757 +       while (userp) {
8758 +               if (copy_from_user(&s_pre, userp,
8759 +                                  sizeof (struct acl_subject_label)))
8760 +                       return -EFAULT;
8761 +               
8762 +               /* do not add nested subjects here, add
8763 +                  while parsing objects
8764 +               */
8765 +
8766 +               if (s_pre.mode & GR_NESTED) {
8767 +                       userp = s_pre.prev;
8768 +                       continue;
8769 +               }
8770 +
8771 +               ret = do_copy_user_subj(userp, role);
8772 +
8773 +               err = PTR_ERR(ret);
8774 +               if (IS_ERR(ret))
8775 +                       return err;
8776 +
8777 +               insert_acl_subj_label(ret, role);
8778 +
8779 +               userp = s_pre.prev;
8780 +       }
8781 +
8782 +       s_final->next = NULL;
8783 +
8784 +       return 0;
8785 +}
8786 +
8787 +static int
8788 +copy_user_acl(struct gr_arg *arg)
8789 +{
8790 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
8791 +       struct sprole_pw *sptmp;
8792 +       struct gr_hash_struct *ghash;
8793 +       uid_t *domainlist;
8794 +       unsigned long r_num;
8795 +       unsigned int len;
8796 +       char *tmp;
8797 +       int err = 0;
8798 +       __u16 i;
8799 +       __u32 num_subjs;
8800 +
8801 +       /* we need a default and kernel role */
8802 +       if (arg->role_db.num_roles < 2)
8803 +               return -EINVAL;
8804 +
8805 +       /* copy special role authentication info from userspace */
8806 +
8807 +       num_sprole_pws = arg->num_sprole_pws;
8808 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
8809 +
8810 +       if (!acl_special_roles) {
8811 +               err = -ENOMEM;
8812 +               goto cleanup;
8813 +       }
8814 +
8815 +       for (i = 0; i < num_sprole_pws; i++) {
8816 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
8817 +               if (!sptmp) {
8818 +                       err = -ENOMEM;
8819 +                       goto cleanup;
8820 +               }
8821 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
8822 +                                  sizeof (struct sprole_pw))) {
8823 +                       err = -EFAULT;
8824 +                       goto cleanup;
8825 +               }
8826 +
8827 +               len =
8828 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
8829 +
8830 +               if (!len || len >= GR_SPROLE_LEN) {
8831 +                       err = -EINVAL;
8832 +                       goto cleanup;
8833 +               }
8834 +
8835 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
8836 +                       err = -ENOMEM;
8837 +                       goto cleanup;
8838 +               }
8839 +
8840 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
8841 +                       err = -EFAULT;
8842 +                       goto cleanup;
8843 +               }
8844 +
8845 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
8846 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
8847 +#endif
8848 +               sptmp->rolename = tmp;
8849 +               acl_special_roles[i] = sptmp;
8850 +       }
8851 +
8852 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
8853 +
8854 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
8855 +               r_last = r_tmp;
8856 +
8857 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
8858 +
8859 +               if (!r_tmp) {
8860 +                       err = -ENOMEM;
8861 +                       goto cleanup;
8862 +               }
8863 +
8864 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
8865 +                                  sizeof (struct acl_role_label *))) {
8866 +                       err = -EFAULT;
8867 +                       goto cleanup;
8868 +               }
8869 +
8870 +               if (copy_from_user(r_tmp, r_utmp2,
8871 +                                  sizeof (struct acl_role_label))) {
8872 +                       err = -EFAULT;
8873 +                       goto cleanup;
8874 +               }
8875 +
8876 +               if (!r_last) {
8877 +                       r_tmp->prev = NULL;
8878 +                       role_list_head = r_tmp;
8879 +               } else {
8880 +                       r_last->next = r_tmp;
8881 +                       r_tmp->prev = r_last;
8882 +               }
8883 +
8884 +               if (r_num == (arg->role_db.num_roles - 1))
8885 +                       r_tmp->next = NULL;
8886 +
8887 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
8888 +
8889 +               if (!len || len >= PATH_MAX) {
8890 +                       err = -EINVAL;
8891 +                       goto cleanup;
8892 +               }
8893 +
8894 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
8895 +                       err = -ENOMEM;
8896 +                       goto cleanup;
8897 +               }
8898 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
8899 +                       err = -EFAULT;
8900 +                       goto cleanup;
8901 +               }
8902 +               r_tmp->rolename = tmp;
8903 +
8904 +               if (!strcmp(r_tmp->rolename, "default")
8905 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
8906 +                       default_role = r_tmp;
8907 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
8908 +                       kernel_role = r_tmp;
8909 +               }
8910 +
8911 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
8912 +                       err = -ENOMEM;
8913 +                       goto cleanup;
8914 +               }
8915 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
8916 +                       err = -EFAULT;
8917 +                       goto cleanup;
8918 +               }
8919 +
8920 +               r_tmp->hash = ghash;
8921 +
8922 +               num_subjs = count_user_subjs(r_tmp->hash->first);
8923 +
8924 +               r_tmp->subj_hash_size = num_subjs;
8925 +               r_tmp->subj_hash =
8926 +                   (struct acl_subject_label **)
8927 +                   create_table(&(r_tmp->subj_hash_size));
8928 +
8929 +               if (!r_tmp->subj_hash) {
8930 +                       err = -ENOMEM;
8931 +                       goto cleanup;
8932 +               }
8933 +
8934 +               err = copy_user_allowedips(r_tmp);
8935 +               if (err)
8936 +                       goto cleanup;
8937 +
8938 +               /* copy domain info */
8939 +               if (r_tmp->domain_children != NULL) {
8940 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
8941 +                       if (domainlist == NULL) {
8942 +                               err = -ENOMEM;
8943 +                               goto cleanup;
8944 +                       }
8945 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
8946 +                               err = -EFAULT;
8947 +                               goto cleanup;
8948 +                       }
8949 +                       r_tmp->domain_children = domainlist;
8950 +               }
8951 +
8952 +               err = copy_user_transitions(r_tmp);
8953 +               if (err)
8954 +                       goto cleanup;
8955 +
8956 +               memset(r_tmp->subj_hash, 0,
8957 +                      r_tmp->subj_hash_size *
8958 +                      sizeof (struct acl_subject_label *));
8959 +
8960 +               s_last = NULL;
8961 +
8962 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
8963 +
8964 +               if (err)
8965 +                       goto cleanup;
8966 +
8967 +               insert_acl_role_label(r_tmp);
8968 +       }
8969 +
8970 +       goto return_err;
8971 +      cleanup:
8972 +       free_variables();
8973 +      return_err:
8974 +       return err;
8975 +
8976 +}
8977 +
8978 +static int
8979 +gracl_init(struct gr_arg *args)
8980 +{
8981 +       int error = 0;
8982 +
8983 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
8984 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
8985 +
8986 +       if (init_variables(args)) {
8987 +               security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
8988 +               error = -ENOMEM;
8989 +               free_variables();
8990 +               goto out;
8991 +       }
8992 +
8993 +       error = copy_user_acl(args);
8994 +       free_init_variables();
8995 +       if (error) {
8996 +               free_variables();
8997 +               goto out;
8998 +       }
8999 +
9000 +       if ((error = gr_set_acls(0))) {
9001 +               free_variables();
9002 +               goto out;
9003 +       }
9004 +
9005 +       gr_status |= GR_READY;
9006 +      out:
9007 +       return error;
9008 +}
9009 +
9010 +/* derived from glibc fnmatch() 0: match, 1: no match*/
9011 +
9012 +static int
9013 +glob_match(const char *pattern, const char *string)
9014 +{
9015 +       const char *p = pattern, *n = string;
9016 +       char c;
9017 +
9018 +       while ((c = *p++) != '\0') {
9019 +       switch (c) {
9020 +               case '?':
9021 +                       if (*n == '\0')
9022 +                               return 1;
9023 +                       else if (*n == '/')
9024 +                               return 1;
9025 +                       break;
9026 +               case '\\':
9027 +                       if (*n != c)
9028 +                               return 1;
9029 +                       break;
9030 +               case '*':
9031 +                       for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
9032 +                               if ((*n == '/') || (c == '?' && *n == '\0'))
9033 +                                       return 1;
9034 +                       if (c == '\0')
9035 +                               return 0;
9036 +                       {
9037 +                               char c1 = c;
9038 +                               for (--p; *n != '\0'; ++n)
9039 +                                       if (((c == '[') || (*n == c1)) && !glob_match(p, n))
9040 +                                               return 0;
9041 +                               return 1;
9042 +                       }
9043 +               case '[':
9044 +                       {
9045 +                       int not;
9046 +
9047 +                       if (*n == '\0')
9048 +                               return 1;
9049 +                       not = (*p == '!' || *p == '^');
9050 +                       if (not)
9051 +                               ++p;
9052 +
9053 +                       c = *p++;
9054 +                       for (;;) {
9055 +                               char cstart = c, cend = c;
9056 +
9057 +                               if (c == '\0')
9058 +                                       return 1;
9059 +                               c = *p++;
9060 +
9061 +                               if (c == '/')
9062 +                                       return 1;
9063 +
9064 +                               if (c == '-' && *p != ']') {
9065 +                                       cend = *p++;
9066 +                                       if (cend == '\0')
9067 +                                               return 1;
9068 +                                       c = *p++;
9069 +                               }
9070 +
9071 +                               if (*n >= cstart && *n <= cend)
9072 +                                       goto matched;
9073 +
9074 +                               if (c == ']')
9075 +                                       break;
9076 +                       }
9077 +                       if (!not)
9078 +                               return 1;
9079 +                       break;
9080 +               matched:
9081 +                       while (c != ']') {
9082 +                               if (c == '\0')
9083 +                                       return 1;
9084 +
9085 +                               c = *p++;
9086 +                       }
9087 +                       if (not)
9088 +                               return 1;
9089 +               }
9090 +               break;
9091 +       default:
9092 +               if (c != *n)
9093 +                       return 1;
9094 +       }
9095 +
9096 +       ++n;
9097 +       }
9098 +
9099 +       if (*n == '\0')
9100 +               return 0;
9101 +
9102 +       if (*n == '/')
9103 +               return 0;
9104 +
9105 +       return 1;
9106 +}
9107 +
9108 +static struct acl_object_label *
9109 +chk_glob_label(struct acl_object_label *globbed,
9110 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
9111 +{
9112 +       struct acl_object_label *tmp;
9113 +
9114 +       if (*path == NULL)
9115 +               *path = gr_to_filename_nolock(dentry, mnt);
9116 +
9117 +       tmp = globbed;
9118 +
9119 +       while (tmp) {
9120 +               if (!glob_match(tmp->filename, *path))
9121 +                       return tmp;
9122 +               tmp = tmp->next;
9123 +       }
9124 +
9125 +       return NULL;
9126 +}
9127 +
9128 +static __inline__ struct acl_object_label *
9129 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
9130 +           struct dentry *curr_dentry,
9131 +           const struct acl_subject_label *subj, char **path)
9132 +{
9133 +       struct acl_subject_label *tmpsubj;
9134 +       struct acl_object_label *retval;
9135 +       struct acl_object_label *retval2;
9136 +
9137 +       tmpsubj = (struct acl_subject_label *) subj;
9138 +       read_lock(&gr_inode_lock);
9139 +       do {
9140 +               retval = lookup_acl_obj_label(curr_dentry->d_inode->i_ino,
9141 +                                       curr_dentry->d_inode->i_sb->s_dev, tmpsubj);
9142 +               if (retval) {
9143 +                       if (retval->globbed) {
9144 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
9145 +                                               (struct vfsmount *)orig_mnt, path);
9146 +                               if (retval2)
9147 +                                       retval = retval2;
9148 +                       }
9149 +                       break;
9150 +               }
9151 +       } while ((tmpsubj = tmpsubj->parent_subject));
9152 +       read_unlock(&gr_inode_lock);
9153 +
9154 +       return retval;
9155 +}
9156 +
9157 +static struct acl_object_label *
9158 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
9159 +             const struct acl_subject_label *subj)
9160 +{
9161 +       struct dentry *dentry = (struct dentry *) l_dentry;
9162 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
9163 +       struct acl_object_label *retval;
9164 +       char *path = NULL;
9165 +
9166 +       spin_lock(&dcache_lock);
9167 +
9168 +       for (;;) {
9169 +               if (dentry == real_root && mnt == real_root_mnt)
9170 +                       break;
9171 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
9172 +                       if (mnt->mnt_parent == mnt)
9173 +                               break;
9174 +
9175 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
9176 +                       if (retval != NULL)
9177 +                               goto out;
9178 +
9179 +                       dentry = mnt->mnt_mountpoint;
9180 +                       mnt = mnt->mnt_parent;
9181 +                       continue;
9182 +               }
9183 +
9184 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
9185 +               if (retval != NULL)
9186 +                       goto out;
9187 +
9188 +               dentry = dentry->d_parent;
9189 +       }
9190 +
9191 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
9192 +
9193 +       if (retval == NULL)
9194 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
9195 +out:
9196 +       spin_unlock(&dcache_lock);
9197 +
9198 +       return retval;
9199 +}
9200 +
9201 +static struct acl_object_label *
9202 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
9203 +             const struct acl_subject_label *subj, char *path)
9204 +{
9205 +       struct dentry *dentry = (struct dentry *) l_dentry;
9206 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
9207 +       struct acl_object_label *retval;
9208 +
9209 +       spin_lock(&dcache_lock);
9210 +
9211 +       for (;;) {
9212 +               if (dentry == real_root && mnt == real_root_mnt)
9213 +                       break;
9214 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
9215 +                       if (mnt->mnt_parent == mnt)
9216 +                               break;
9217 +
9218 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
9219 +                       if (retval != NULL)
9220 +                               goto out;
9221 +
9222 +                       dentry = mnt->mnt_mountpoint;
9223 +                       mnt = mnt->mnt_parent;
9224 +                       continue;
9225 +               }
9226 +
9227 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
9228 +               if (retval != NULL)
9229 +                       goto out;
9230 +
9231 +               dentry = dentry->d_parent;
9232 +       }
9233 +
9234 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
9235 +
9236 +       if (retval == NULL)
9237 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
9238 +out:
9239 +       spin_unlock(&dcache_lock);
9240 +
9241 +       return retval;
9242 +}
9243 +
9244 +static struct acl_subject_label *
9245 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
9246 +              const struct acl_role_label *role)
9247 +{
9248 +       struct dentry *dentry = (struct dentry *) l_dentry;
9249 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
9250 +       struct acl_subject_label *retval;
9251 +
9252 +       spin_lock(&dcache_lock);
9253 +
9254 +       for (;;) {
9255 +               if (unlikely(dentry == real_root && mnt == real_root_mnt))
9256 +                       break;
9257 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
9258 +                       if (mnt->mnt_parent == mnt)
9259 +                               break;
9260 +
9261 +                       read_lock(&gr_inode_lock);
9262 +                       retval =
9263 +                           lookup_acl_subj_label(dentry->d_inode->i_ino,
9264 +                                                 dentry->d_inode->i_sb->s_dev, role);
9265 +                       read_unlock(&gr_inode_lock);
9266 +                       if (unlikely(retval != NULL))
9267 +                               goto out;
9268 +
9269 +                       dentry = mnt->mnt_mountpoint;
9270 +                       mnt = mnt->mnt_parent;
9271 +                       continue;
9272 +               }
9273 +
9274 +               read_lock(&gr_inode_lock);
9275 +               retval =
9276 +                   lookup_acl_subj_label(dentry->d_inode->i_ino,
9277 +                                         dentry->d_inode->i_sb->s_dev, role);
9278 +               read_unlock(&gr_inode_lock);
9279 +               if (unlikely(retval != NULL))
9280 +                       goto out;
9281 +
9282 +               dentry = dentry->d_parent;
9283 +       }
9284 +
9285 +       read_lock(&gr_inode_lock);
9286 +       retval =
9287 +           lookup_acl_subj_label(dentry->d_inode->i_ino,
9288 +                                 dentry->d_inode->i_sb->s_dev, role);
9289 +       read_unlock(&gr_inode_lock);
9290 +
9291 +       if (unlikely(retval == NULL)) {
9292 +               read_lock(&gr_inode_lock);
9293 +               retval =
9294 +                   lookup_acl_subj_label(real_root->d_inode->i_ino,
9295 +                                         real_root->d_inode->i_sb->s_dev, role);
9296 +               read_unlock(&gr_inode_lock);
9297 +       }
9298 +      out:
9299 +       spin_unlock(&dcache_lock);
9300 +
9301 +       return retval;
9302 +}
9303 +
9304 +static __inline__ void
9305 +gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
9306 +            const struct task_struct *task, const char *pathname,
9307 +            const __u32 mode)
9308 +{
9309 +       security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
9310 +                      uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
9311 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
9312 +                      1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
9313 +
9314 +       return;
9315 +}
9316 +
9317 +__u32
9318 +gr_check_link(const struct dentry * new_dentry,
9319 +             const struct dentry * parent_dentry,
9320 +             const struct vfsmount * parent_mnt,
9321 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
9322 +{
9323 +       struct acl_object_label *obj;
9324 +       __u32 oldmode, newmode;
9325 +
9326 +       if (unlikely(!(gr_status & GR_READY)))
9327 +               return (GR_WRITE | GR_CREATE);
9328 +
9329 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
9330 +       oldmode = obj->mode;
9331 +
9332 +       if (current->acl->mode & GR_LEARN)
9333 +               oldmode |= (GR_WRITE | GR_CREATE);
9334 +       newmode =
9335 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
9336 +                           oldmode | GR_CREATE | GR_AUDIT_CREATE |
9337 +                           GR_AUDIT_WRITE | GR_SUPPRESS);
9338 +
9339 +       if ((newmode & oldmode) == oldmode)
9340 +               return newmode;
9341 +       else if (current->acl->mode & GR_LEARN) {
9342 +               gr_log_learn(current->role, current->uid, current->gid,
9343 +                       current, gr_to_filename(old_dentry, old_mnt), oldmode);
9344 +               return (GR_WRITE | GR_CREATE);
9345 +       } else if (newmode & GR_SUPPRESS)
9346 +               return GR_SUPPRESS;
9347 +       else
9348 +               return 0;
9349 +}
9350 +
9351 +__u32
9352 +gr_search_file(const struct dentry * dentry, const __u32 mode,
9353 +              const struct vfsmount * mnt)
9354 +{
9355 +       __u32 retval = mode;
9356 +       struct acl_subject_label *curracl;
9357 +       struct acl_object_label *currobj;
9358 +
9359 +       if (unlikely(!(gr_status & GR_READY)))
9360 +               return (mode & ~GR_AUDITS);
9361 +
9362 +       curracl = current->acl;
9363 +
9364 +       currobj = chk_obj_label(dentry, mnt, curracl);
9365 +       retval = currobj->mode & mode;
9366 +
9367 +       if (unlikely
9368 +           ((curracl->mode & GR_LEARN) && !(mode & GR_NOPTRACE)
9369 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
9370 +               __u32 new_mode = mode;
9371 +
9372 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9373 +
9374 +               retval = new_mode;
9375 +
9376 +               if (!(mode & GR_NOLEARN))
9377 +                       gr_log_learn(current->role, current->uid, current->gid,
9378 +                                    current, gr_to_filename(dentry, mnt), new_mode);
9379 +       }
9380 +
9381 +       return retval;
9382 +}
9383 +
9384 +__u32
9385 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
9386 +               const struct vfsmount * mnt, const __u32 mode)
9387 +{
9388 +       struct name_entry *match;
9389 +       struct acl_object_label *matchpo;
9390 +       struct acl_subject_label *curracl;
9391 +       char *path;
9392 +       __u32 retval;
9393 +
9394 +       if (unlikely(!(gr_status & GR_READY)))
9395 +               return (mode & ~GR_AUDITS);
9396 +
9397 +       preempt_disable();
9398 +       path = gr_to_filename(new_dentry, mnt);
9399 +       match = lookup_name_entry(path);
9400 +
9401 +       if (!match)
9402 +               goto check_parent;
9403 +
9404 +       curracl = current->acl;
9405 +
9406 +       read_lock(&gr_inode_lock);
9407 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
9408 +       read_unlock(&gr_inode_lock);
9409 +
9410 +       if (matchpo) {
9411 +               if ((matchpo->mode & mode) !=
9412 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
9413 +                   && curracl->mode & GR_LEARN) {
9414 +                       __u32 new_mode = mode;
9415 +
9416 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9417 +
9418 +                       gr_log_learn(current->role, current->uid, current->gid,
9419 +                                    current, gr_to_filename(new_dentry, mnt), new_mode);
9420 +
9421 +                       preempt_enable();
9422 +                       return new_mode;
9423 +               }
9424 +               preempt_enable();
9425 +               return (matchpo->mode & mode);
9426 +       }
9427 +
9428 +      check_parent:
9429 +       curracl = current->acl;
9430 +
9431 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
9432 +       retval = matchpo->mode & mode;
9433 +
9434 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
9435 +           && (curracl->mode & GR_LEARN)) {
9436 +               __u32 new_mode = mode;
9437 +
9438 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9439 +
9440 +               gr_log_learn(current->role, current->uid, current->gid, 
9441 +                            current, gr_to_filename(new_dentry, mnt), new_mode);
9442 +               preempt_enable();
9443 +               return new_mode;
9444 +       }
9445 +
9446 +       preempt_enable();
9447 +       return retval;
9448 +}
9449 +
9450 +int
9451 +gr_check_hidden_task(const struct task_struct *task)
9452 +{
9453 +       if (unlikely(!(gr_status & GR_READY)))
9454 +               return 0;
9455 +
9456 +       if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
9457 +               return 1;
9458 +
9459 +       return 0;
9460 +}
9461 +
9462 +int
9463 +gr_check_protected_task(const struct task_struct *task)
9464 +{
9465 +       if (unlikely(!(gr_status & GR_READY) || !task))
9466 +               return 0;
9467 +
9468 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
9469 +               return 1;
9470 +
9471 +       return 0;
9472 +}
9473 +
9474 +__inline__ void
9475 +gr_copy_label(struct task_struct *tsk)
9476 +{
9477 +       tsk->used_accept = 0;
9478 +       tsk->acl_sp_role = 0;
9479 +       tsk->acl_role_id = current->acl_role_id;
9480 +       tsk->acl = current->acl;
9481 +       tsk->role = current->role;
9482 +       tsk->curr_ip = current->curr_ip;
9483 +       if (current->exec_file)
9484 +               get_file(current->exec_file);
9485 +       tsk->exec_file = current->exec_file;
9486 +       tsk->is_writable = current->is_writable;
9487 +       if (unlikely(current->used_accept))
9488 +               current->curr_ip = 0;
9489 +
9490 +       return;
9491 +}
9492 +
9493 +static __inline__ void
9494 +gr_set_proc_res(void)
9495 +{
9496 +       struct acl_subject_label *proc;
9497 +       unsigned short i;
9498 +
9499 +       proc = current->acl;
9500 +
9501 +       if (proc->mode & GR_LEARN)
9502 +               return;
9503 +
9504 +       for (i = 0; i < RLIM_NLIMITS; i++) {
9505 +               if (!(proc->resmask & (1 << i)))
9506 +                       continue;
9507 +
9508 +               current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
9509 +               current->rlim[i].rlim_max = proc->res[i].rlim_max;
9510 +       }
9511 +
9512 +       return;
9513 +}
9514 +
9515 +static __inline__ void
9516 +do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
9517 +{
9518 +       task->role = lookup_acl_role_label(task, uid, gid);
9519 +
9520 +       return;
9521 +}
9522 +
9523 +EXPORT_SYMBOL(gr_check_user_change);
9524 +
9525 +int
9526 +gr_check_user_change(int real, int effective, int fs)
9527 +{
9528 +       unsigned int i;
9529 +       __u16 num;
9530 +       uid_t *uidlist;
9531 +       int curuid;
9532 +       int realok = 0;
9533 +       int effectiveok = 0;
9534 +       int fsok = 0;
9535 +
9536 +       if (unlikely(!(gr_status & GR_READY)))
9537 +               return 0;
9538 +
9539 +       num = current->acl->user_trans_num;
9540 +       uidlist = current->acl->user_transitions;
9541 +
9542 +       if (uidlist == NULL)
9543 +               return 0;
9544 +
9545 +       if (real == -1)
9546 +               realok = 1;
9547 +       if (effective == -1)
9548 +               effectiveok = 1;
9549 +       if (fs == -1)
9550 +               fsok = 1;
9551 +
9552 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
9553 +               for (i = 0; i < num; i++) {
9554 +                       curuid = (int)uidlist[i];
9555 +                       if (real == curuid)
9556 +                               realok = 1;
9557 +                       if (effective == curuid)
9558 +                               effectiveok = 1;
9559 +                       if (fs == curuid)
9560 +                               fsok = 1;
9561 +               }
9562 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
9563 +               for (i = 0; i < num; i++) {
9564 +                       curuid = (int)uidlist[i];
9565 +                       if (real == curuid)
9566 +                               break;
9567 +                       if (effective == curuid)
9568 +                               break;
9569 +                       if (fs == curuid)
9570 +                               break;
9571 +               }
9572 +               /* not in deny list */
9573 +               if (i == num) {
9574 +                       realok = 1;
9575 +                       effectiveok = 1;
9576 +                       fsok = 1;
9577 +               }
9578 +       }
9579 +
9580 +       if (realok && effectiveok && fsok)
9581 +               return 0;
9582 +       else {
9583 +               security_alert(GR_USRCHANGE_ACL_MSG,
9584 +                       realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real, DEFAULTSECARGS);
9585 +               return 1;
9586 +       }
9587 +}
9588 +
9589 +EXPORT_SYMBOL(gr_check_group_change);
9590 +
9591 +int
9592 +gr_check_group_change(int real, int effective, int fs)
9593 +{
9594 +       unsigned int i;
9595 +       __u16 num;
9596 +       gid_t *gidlist;
9597 +       int curgid;
9598 +       int realok = 0;
9599 +       int effectiveok = 0;
9600 +       int fsok = 0;
9601 +
9602 +       if (unlikely(!(gr_status & GR_READY)))
9603 +               return 0;
9604 +
9605 +       num = current->acl->group_trans_num;
9606 +       gidlist = current->acl->group_transitions;
9607 +
9608 +       if (gidlist == NULL)
9609 +               return 0;
9610 +
9611 +       if (real == -1)
9612 +               realok = 1;
9613 +       if (effective == -1)
9614 +               effectiveok = 1;
9615 +       if (fs == -1)
9616 +               fsok = 1;
9617 +
9618 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
9619 +               for (i = 0; i < num; i++) {
9620 +                       curgid = (int)gidlist[i];
9621 +                       if (real == curgid)
9622 +                               realok = 1;
9623 +                       if (effective == curgid)
9624 +                               effectiveok = 1;
9625 +                       if (fs == curgid)
9626 +                               fsok = 1;
9627 +               }
9628 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
9629 +               for (i = 0; i < num; i++) {
9630 +                       curgid = (int)gidlist[i];
9631 +                       if (real == curgid)
9632 +                               break;
9633 +                       if (effective == curgid)
9634 +                               break;
9635 +                       if (fs == curgid)
9636 +                               break;
9637 +               }
9638 +               /* not in deny list */
9639 +               if (i == num) {
9640 +                       realok = 1;
9641 +                       effectiveok = 1;
9642 +                       fsok = 1;
9643 +               }
9644 +       }
9645 +
9646 +       if (realok && effectiveok && fsok)
9647 +               return 0;
9648 +       else {
9649 +               security_alert(GR_GRPCHANGE_ACL_MSG,
9650 +                       realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real, DEFAULTSECARGS);
9651 +               return 1;
9652 +       }
9653 +}
9654 +
9655 +void
9656 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
9657 +{
9658 +       struct acl_object_label *obj;
9659 +       struct file *filp;
9660 +
9661 +       if (unlikely(!(gr_status & GR_READY)))
9662 +               return;
9663 +
9664 +       filp = task->exec_file;
9665 +
9666 +       /* kernel process, we'll give them the kernel role */
9667 +       if (unlikely(!filp)) {
9668 +               task->role = kernel_role;
9669 +               task->acl = kernel_role->root_label;
9670 +               return;
9671 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
9672 +               do_set_role_label(task, uid, gid);
9673 +
9674 +       task->acl =
9675 +           chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
9676 +
9677 +       task->is_writable = 0;
9678 +
9679 +       /* ignore additional mmap checks for processes that are writable 
9680 +          by the default ACL */
9681 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9682 +       if (unlikely(obj->mode & GR_WRITE))
9683 +               task->is_writable = 1;
9684 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
9685 +       if (unlikely(obj->mode & GR_WRITE))
9686 +               task->is_writable = 1;
9687 +
9688 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9689 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9690 +#endif
9691 +
9692 +       gr_set_proc_res();
9693 +
9694 +       return;
9695 +}
9696 +
9697 +int
9698 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
9699 +{
9700 +       struct task_struct *task = current;
9701 +       struct acl_subject_label *newacl;
9702 +       struct acl_object_label *obj;
9703 +       __u32 retmode;
9704 +
9705 +       if (unlikely(!(gr_status & GR_READY)))
9706 +               return 0;
9707 +
9708 +       newacl = chk_subj_label(dentry, mnt, task->role);
9709 +
9710 +       task_lock(task);
9711 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
9712 +            GR_OVERRIDE) && (task->acl != newacl) &&
9713 +            !(task->role->roletype & GR_ROLE_GOD) &&
9714 +            !gr_search_file(dentry, GR_PTRACERD, mnt)) ||
9715 +           (atomic_read(&task->fs->count) > 1 ||
9716 +            atomic_read(&task->files->count) > 1 ||
9717 +            atomic_read(&task->sighand->count) > 1)) {
9718 +                task_unlock(task);
9719 +               security_alert(GR_PTRACE_EXEC_ACL_MSG,
9720 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
9721 +               return -EACCES;
9722 +       }
9723 +       obj = chk_obj_label(dentry, mnt, task->acl);
9724 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
9725 +
9726 +       if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
9727 +               if (obj->nested)
9728 +                       task->acl = obj->nested;
9729 +               else
9730 +                       task->acl = newacl;
9731 +               task_unlock(task);
9732 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT) {
9733 +               task_unlock(task);
9734 +               security_audit(GR_INHERIT_ACL_MSG, task->acl->filename,
9735 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
9736 +       } else
9737 +               task_unlock(task);
9738 +
9739 +       task->is_writable = 0;
9740 +
9741 +       /* ignore additional mmap checks for processes that are writable 
9742 +          by the default ACL */
9743 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
9744 +       if (unlikely(obj->mode & GR_WRITE))
9745 +               task->is_writable = 1;
9746 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
9747 +       if (unlikely(obj->mode & GR_WRITE))
9748 +               task->is_writable = 1;
9749 +
9750 +       gr_set_proc_res();
9751 +
9752 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9753 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9754 +#endif
9755 +       return 0;
9756 +}
9757 +
9758 +static __inline__ void
9759 +do_handle_delete(const ino_t ino, const dev_t dev)
9760 +{
9761 +       struct acl_object_label *matchpo;
9762 +       struct acl_subject_label *matchps;
9763 +       struct acl_subject_label *i;
9764 +       struct acl_role_label *role;
9765 +
9766 +       for (role = role_list_head; role; role = role->next) {
9767 +               for (i = role->hash->first; i; i = i->next) {
9768 +                       if (unlikely((i->mode & GR_NESTED) &&
9769 +                                    (i->inode == ino) &&
9770 +                                    (i->device == dev)))
9771 +                               i->mode |= GR_DELETED;
9772 +                       if (unlikely((matchpo =
9773 +                            lookup_acl_obj_label(ino, dev, i)) != NULL))
9774 +                               matchpo->mode |= GR_DELETED;
9775 +               }
9776 +
9777 +               if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
9778 +                       matchps->mode |= GR_DELETED;
9779 +       }
9780 +
9781 +       return;
9782 +}
9783 +
9784 +void
9785 +gr_handle_delete(const ino_t ino, const dev_t dev)
9786 +{
9787 +       if (unlikely(!(gr_status & GR_READY)))
9788 +               return;
9789 +
9790 +       write_lock(&gr_inode_lock);
9791 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
9792 +               do_handle_delete(ino, dev);
9793 +       write_unlock(&gr_inode_lock);
9794 +
9795 +       return;
9796 +}
9797 +
9798 +static __inline__ void
9799 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
9800 +                    const ino_t newinode, const dev_t newdevice,
9801 +                    struct acl_subject_label *subj)
9802 +{
9803 +       unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
9804 +       struct acl_object_label **match;
9805 +       struct acl_object_label *tmp;
9806 +       __u8 i = 0;
9807 +
9808 +       match = &subj->obj_hash[index];
9809 +
9810 +       while (*match && ((*match)->inode != oldinode ||
9811 +              (*match)->device != olddevice ||
9812 +              !((*match)->mode & GR_DELETED))) {
9813 +               index = (index + (1 << i)) % subj->obj_hash_size;
9814 +               match = &subj->obj_hash[index];
9815 +               i = (i + 1) % 32;
9816 +       }
9817 +
9818 +       if (*match && ((*match) != deleted_object)
9819 +           && ((*match)->inode == oldinode)
9820 +           && ((*match)->device == olddevice)
9821 +           && ((*match)->mode & GR_DELETED)) {
9822 +               tmp = *match;
9823 +               tmp->inode = newinode;
9824 +               tmp->device = newdevice;
9825 +               tmp->mode &= ~GR_DELETED;
9826 +
9827 +               *match = deleted_object;
9828 +
9829 +               insert_acl_obj_label(tmp, subj);
9830 +       }
9831 +
9832 +       return;
9833 +}
9834 +
9835 +static __inline__ void
9836 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
9837 +                     const ino_t newinode, const dev_t newdevice,
9838 +                     struct acl_role_label *role)
9839 +{
9840 +       struct acl_subject_label **s_hash = role->subj_hash;
9841 +       unsigned long subj_size = role->subj_hash_size;
9842 +       unsigned long index = fhash(oldinode, olddevice, subj_size);
9843 +       struct acl_subject_label **match;
9844 +       struct acl_subject_label *tmp;
9845 +       __u8 i = 0;
9846 +
9847 +       match = &s_hash[index];
9848 +
9849 +       while (*match && ((*match)->inode != oldinode ||
9850 +              (*match)->device != olddevice ||
9851 +              !((*match)->mode & GR_DELETED))) {
9852 +               index = (index + (1 << i)) % subj_size;
9853 +               i = (i + 1) % 32;
9854 +               match = &s_hash[index];
9855 +       }
9856 +
9857 +       if (*match && (*match != deleted_subject)
9858 +           && ((*match)->inode == oldinode)
9859 +           && ((*match)->device == olddevice)
9860 +           && ((*match)->mode & GR_DELETED)) {
9861 +               tmp = *match;
9862 +
9863 +               tmp->inode = newinode;
9864 +               tmp->device = newdevice;
9865 +               tmp->mode &= ~GR_DELETED;
9866 +
9867 +               *match = deleted_subject;
9868 +
9869 +               insert_acl_subj_label(tmp, role);
9870 +       }
9871 +
9872 +       return;
9873 +}
9874 +
9875 +static __inline__ void
9876 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
9877 +                   const ino_t newinode, const dev_t newdevice)
9878 +{
9879 +       unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
9880 +       struct name_entry **match;
9881 +       struct name_entry *tmp;
9882 +       __u8 i = 0;
9883 +
9884 +       match = &inodev_set.n_hash[index];
9885 +
9886 +       while (*match
9887 +              && ((*match)->inode != oldinode
9888 +                  || (*match)->device != olddevice)) {
9889 +               index = (index + (1 << i)) % inodev_set.n_size;
9890 +               i = (i + 1) % 32;
9891 +               match = &inodev_set.n_hash[index];
9892 +       }
9893 +
9894 +       if (*match && (*match != deleted_inodev)
9895 +           && ((*match)->inode == oldinode)
9896 +           && ((*match)->device == olddevice)) {
9897 +               tmp = *match;
9898 +
9899 +               tmp->inode = newinode;
9900 +               tmp->device = newdevice;
9901 +
9902 +               *match = deleted_inodev;
9903 +
9904 +               insert_inodev_entry(tmp);
9905 +       }
9906 +
9907 +       return;
9908 +}
9909 +
9910 +static __inline__ void
9911 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
9912 +                const struct vfsmount *mnt)
9913 +{
9914 +       struct acl_subject_label *i;
9915 +       struct acl_role_label *role;
9916 +
9917 +       for (role = role_list_head; role; role = role->next) {
9918 +               update_acl_subj_label(matchn->inode, matchn->device,
9919 +                                     dentry->d_inode->i_ino,
9920 +                                     dentry->d_inode->i_sb->s_dev, role);
9921 +
9922 +               for (i = role->hash->first; i; i = i->next) {
9923 +                       if (unlikely((i->mode & GR_NESTED) &&
9924 +                                    (i->inode == dentry->d_inode->i_ino) &&
9925 +                                    (i->device == dentry->d_inode->i_sb->s_dev))) {
9926 +                               i->inode = dentry->d_inode->i_ino;
9927 +                               i->device = dentry->d_inode->i_sb->s_dev;
9928 +                       }
9929 +                       update_acl_obj_label(matchn->inode, matchn->device,
9930 +                                            dentry->d_inode->i_ino,
9931 +                                            dentry->d_inode->i_sb->s_dev, i);
9932 +               }
9933 +       }
9934 +
9935 +       update_inodev_entry(matchn->inode, matchn->device,
9936 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
9937 +
9938 +       return;
9939 +}
9940 +
9941 +void
9942 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
9943 +{
9944 +       struct name_entry *matchn;
9945 +
9946 +       if (unlikely(!(gr_status & GR_READY)))
9947 +               return;
9948 +
9949 +       preempt_disable();
9950 +       matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
9951 +       preempt_enable();
9952 +
9953 +       if (unlikely((unsigned long)matchn)) {
9954 +               write_lock(&gr_inode_lock);
9955 +               do_handle_create(matchn, dentry, mnt);
9956 +               write_unlock(&gr_inode_lock);
9957 +       }
9958 +
9959 +       return;
9960 +}
9961 +
9962 +void
9963 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
9964 +                struct dentry *old_dentry,
9965 +                struct dentry *new_dentry,
9966 +                struct vfsmount *mnt, const __u8 replace)
9967 +{
9968 +       struct name_entry *matchn;
9969 +
9970 +       if (unlikely(!(gr_status & GR_READY)))
9971 +               return;
9972 +
9973 +       preempt_disable();
9974 +       matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
9975 +       preempt_enable();
9976 +
9977 +       /* we wouldn't have to check d_inode if it weren't for
9978 +          NFS silly-renaming
9979 +        */
9980 +
9981 +       write_lock(&gr_inode_lock);
9982 +       if (unlikely(replace && new_dentry->d_inode)) {
9983 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
9984 +                                       new_dentry->d_inode->i_sb->s_dev) &&
9985 +                   (old_dentry->d_inode->i_nlink <= 1)))
9986 +                       do_handle_delete(new_dentry->d_inode->i_ino,
9987 +                                        new_dentry->d_inode->i_sb->s_dev);
9988 +       }
9989 +
9990 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
9991 +                               old_dentry->d_inode->i_sb->s_dev) &&
9992 +           (old_dentry->d_inode->i_nlink <= 1)))
9993 +               do_handle_delete(old_dentry->d_inode->i_ino,
9994 +                                old_dentry->d_inode->i_sb->s_dev);
9995 +
9996 +       if (unlikely((unsigned long)matchn))
9997 +               do_handle_create(matchn, old_dentry, mnt);
9998 +       write_unlock(&gr_inode_lock);
9999 +
10000 +       return;
10001 +}
10002 +
10003 +static int
10004 +lookup_special_role_auth(const char *rolename, unsigned char **salt,
10005 +                        unsigned char **sum)
10006 +{
10007 +       struct acl_role_label *r;
10008 +       struct role_allowed_ip *ipp;
10009 +       struct role_transition *trans;
10010 +       __u16 i;
10011 +       int found = 0;
10012 +
10013 +       /* check transition table */
10014 +
10015 +       for (trans = current->role->transitions; trans; trans = trans->next) {
10016 +               if (!strcmp(rolename, trans->rolename)) {
10017 +                       found = 1;
10018 +                       break;
10019 +               }
10020 +       }
10021 +
10022 +       if (!found)
10023 +               return 0;
10024 +
10025 +       /* handle special roles that do not require authentication
10026 +          and check ip */
10027 +
10028 +       for (r = role_list_head; r; r = r->next) {
10029 +               if (!strcmp(rolename, r->rolename) &&
10030 +                   (r->roletype & GR_ROLE_SPECIAL)) {
10031 +                       found = 0;
10032 +                       if (r->allowed_ips != NULL) {
10033 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
10034 +                                       if ((ntohl(current->curr_ip) & ipp->netmask) ==
10035 +                                            (ntohl(ipp->addr) & ipp->netmask))
10036 +                                               found = 1;
10037 +                               }
10038 +                       } else
10039 +                               found = 2;
10040 +                       if (!found)
10041 +                               return 0;
10042 +
10043 +                       if (r->roletype & GR_ROLE_NOPW) {
10044 +                               *salt = NULL;
10045 +                               *sum = NULL;
10046 +                               return 1;
10047 +                       }
10048 +               }
10049 +       }
10050 +
10051 +       for (i = 0; i < num_sprole_pws; i++) {
10052 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
10053 +                       *salt = acl_special_roles[i]->salt;
10054 +                       *sum = acl_special_roles[i]->sum;
10055 +                       return 1;
10056 +               }
10057 +       }
10058 +
10059 +       return 0;
10060 +}
10061 +
10062 +static void
10063 +assign_special_role(char *rolename)
10064 +{
10065 +       struct acl_object_label *obj;
10066 +       struct acl_role_label *r;
10067 +       struct acl_role_label *assigned = NULL;
10068 +       struct task_struct *tsk;
10069 +       struct file *filp;
10070 +
10071 +       for (r = role_list_head; r; r = r->next)
10072 +               if (!strcmp(rolename, r->rolename) &&
10073 +                   (r->roletype & GR_ROLE_SPECIAL))
10074 +                       assigned = r;
10075 +
10076 +       if (!assigned)
10077 +               return;
10078 +
10079 +       read_lock(&tasklist_lock);
10080 +       read_lock(&grsec_exec_file_lock);
10081 +
10082 +       tsk = current->parent;
10083 +       if (tsk == NULL) {
10084 +               read_unlock(&grsec_exec_file_lock);
10085 +               read_unlock(&tasklist_lock);
10086 +               return;
10087 +       }
10088 +
10089 +       filp = tsk->exec_file;
10090 +       if (filp == NULL) {
10091 +               read_unlock(&grsec_exec_file_lock);
10092 +               read_unlock(&tasklist_lock);
10093 +               return;
10094 +       }
10095 +
10096 +       tsk->is_writable = 0;
10097 +
10098 +       acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
10099 +       tsk->acl_sp_role = 1;
10100 +       tsk->acl_role_id = acl_sp_role_value;
10101 +       tsk->role = assigned;
10102 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
10103 +
10104 +       /* ignore additional mmap checks for processes that are writable 
10105 +          by the default ACL */
10106 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10107 +       if (unlikely(obj->mode & GR_WRITE))
10108 +               tsk->is_writable = 1;
10109 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
10110 +       if (unlikely(obj->mode & GR_WRITE))
10111 +               tsk->is_writable = 1;
10112 +
10113 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10114 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
10115 +#endif
10116 +
10117 +       read_unlock(&grsec_exec_file_lock);
10118 +       read_unlock(&tasklist_lock);
10119 +       return;
10120 +}
10121 +
10122 +ssize_t
10123 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
10124 +{
10125 +       struct gr_arg_wrapper uwrap;
10126 +       unsigned char *sprole_salt;
10127 +       unsigned char *sprole_sum;
10128 +       int error = sizeof (struct gr_arg_wrapper);
10129 +       int error2 = 0;
10130 +
10131 +       down(&gr_dev_sem);
10132 +
10133 +       if (count != sizeof (struct gr_arg_wrapper)) {
10134 +               security_alert_good(GR_DEV_ACL_MSG, (int)count,
10135 +                                   (int) sizeof (struct gr_arg_wrapper));
10136 +               error = -EINVAL;
10137 +               goto out;
10138 +       }
10139 +
10140 +       if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
10141 +           && time_before_eq(gr_auth_expires, get_seconds())) {
10142 +               gr_auth_expires = 0;
10143 +               gr_auth_attempts = 0;
10144 +       }
10145 +
10146 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
10147 +               error = -EFAULT;
10148 +               goto out;
10149 +       }
10150 +
10151 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
10152 +               error = -EINVAL;
10153 +               goto out;
10154 +       }
10155 +
10156 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
10157 +               error = -EFAULT;
10158 +               goto out;
10159 +       }
10160 +
10161 +       if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, get_seconds())) {
10162 +               error = -EBUSY;
10163 +               goto out;
10164 +       }
10165 +
10166 +       /* if non-root trying to do anything other than use a special role,
10167 +          do not attempt authentication, do not count towards authentication
10168 +          locking
10169 +        */
10170 +
10171 +       if (gr_usermode->mode != SPROLE && current->uid) {
10172 +               error = -EPERM;
10173 +               goto out;
10174 +       }
10175 +
10176 +       /* ensure pw and special role name are null terminated */
10177 +
10178 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
10179 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
10180 +
10181 +       /* Okay. 
10182 +        * We have our enough of the argument structure..(we have yet
10183 +        * to copy_from_user the tables themselves) . Copy the tables
10184 +        * only if we need them, i.e. for loading operations. */
10185 +
10186 +       switch (gr_usermode->mode) {
10187 +       case STATUS:
10188 +                       if (gr_status & GR_READY)
10189 +                               error = 1;
10190 +                       else
10191 +                               error = 2;
10192 +                       goto out;
10193 +       case SHUTDOWN:
10194 +               if ((gr_status & GR_READY)
10195 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10196 +                       gr_status &= ~GR_READY;
10197 +                       security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
10198 +                       free_variables();
10199 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
10200 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
10201 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
10202 +               } else if (gr_status & GR_READY) {
10203 +                       security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
10204 +                       error = -EPERM;
10205 +               } else {
10206 +                       security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
10207 +                       error = -EAGAIN;
10208 +               }
10209 +               break;
10210 +       case ENABLE:
10211 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
10212 +                       security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
10213 +               else {
10214 +                       if (gr_status & GR_READY)
10215 +                               error = -EAGAIN;
10216 +                       else
10217 +                               error = error2;
10218 +                       security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
10219 +                                      DEFAULTSECARGS);
10220 +               }
10221 +               break;
10222 +       case RELOAD:
10223 +               if (!(gr_status & GR_READY)) {
10224 +                       security_alert_good(GR_RELOADI_ACL_MSG);
10225 +                       error = -EAGAIN;
10226 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10227 +                       lock_kernel();
10228 +                       gr_status &= ~GR_READY;
10229 +                       free_variables();
10230 +                       if (!(error2 = gracl_init(gr_usermode))) {
10231 +                               unlock_kernel();
10232 +                               security_alert_good(GR_RELOAD_ACL_MSG,
10233 +                                                   GR_VERSION);
10234 +                       } else {
10235 +                               unlock_kernel();
10236 +                               error = error2;
10237 +                               security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
10238 +                                              DEFAULTSECARGS);
10239 +                       }
10240 +               } else {
10241 +                       security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
10242 +                                      DEFAULTSECARGS);
10243 +                       error = -EPERM;
10244 +               }
10245 +               break;
10246 +       case SEGVMOD:
10247 +               if (unlikely(!(gr_status & GR_READY))) {
10248 +                       security_alert_good(GR_SEGVMODI_ACL_MSG,
10249 +                                           DEFAULTSECARGS);
10250 +                       error = -EAGAIN;
10251 +                       break;
10252 +               }
10253 +
10254 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
10255 +                       security_alert_good(GR_SEGVMODS_ACL_MSG,
10256 +                                           DEFAULTSECARGS);
10257 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
10258 +                               struct acl_subject_label *segvacl;
10259 +                               segvacl =
10260 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
10261 +                                                         gr_usermode->segv_device,
10262 +                                                         current->role);
10263 +                               if (segvacl) {
10264 +                                       segvacl->crashes = 0;
10265 +                                       segvacl->expires = 0;
10266 +                               }
10267 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
10268 +                               gr_remove_uid(gr_usermode->segv_uid);
10269 +                       }
10270 +               } else {
10271 +                       security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
10272 +                       error = -EPERM;
10273 +               }
10274 +               break;
10275 +       case SPROLE:
10276 +               if (unlikely(!(gr_status & GR_READY))) {
10277 +                       security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
10278 +                       error = -EAGAIN;
10279 +                       break;
10280 +               }
10281 +
10282 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
10283 +                   && time_before_eq(current->role->expires, get_seconds())) {
10284 +                       current->role->expires = 0;
10285 +                       current->role->auth_attempts = 0;
10286 +               }
10287 +
10288 +               if (time_after(current->role->expires, get_seconds())) {
10289 +                       error = -EBUSY;
10290 +                       goto out;
10291 +               }
10292 +
10293 +               if (lookup_special_role_auth
10294 +                   (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
10295 +                   && ((!sprole_salt && !sprole_sum)
10296 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
10297 +                       assign_special_role(gr_usermode->sp_role);
10298 +                       security_alert_good(GR_SPROLES_ACL_MSG,
10299 +                                           (current->parent) ? current->
10300 +                                           parent->role->rolename : "",
10301 +                                           acl_sp_role_value, DEFAULTSECARGS);
10302 +               } else {
10303 +                       security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
10304 +                                      DEFAULTSECARGS);
10305 +                       error = -EPERM;
10306 +                       current->role->auth_attempts++;
10307 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
10308 +                               current->role->expires =
10309 +                                   get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
10310 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
10311 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
10312 +                                      gr_usermode->sp_role, DEFAULTSECARGS);
10313 +                       }
10314 +
10315 +                       goto out;
10316 +               }
10317 +               break;
10318 +       case UNSPROLE:
10319 +               if (unlikely(!(gr_status & GR_READY))) {
10320 +                       security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
10321 +                       error = -EAGAIN;
10322 +                       break;
10323 +               }
10324 +
10325 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
10326 +                       security_alert_good(GR_UNSPROLES_ACL_MSG,
10327 +                                           (current->parent) ? current->
10328 +                                           parent->role->rolename : "",
10329 +                                           (current->parent) ? current->
10330 +                                           parent->acl_role_id : 0, DEFAULTSECARGS);
10331 +                       gr_set_acls(1);
10332 +               } else {
10333 +                       security_alert(GR_UNSPROLEF_ACL_MSG, current->role->rolename,
10334 +                                      DEFAULTSECARGS);
10335 +                       error = -EPERM;
10336 +                       goto out;
10337 +               }
10338 +               break;
10339 +       default:
10340 +               security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
10341 +                              DEFAULTSECARGS);
10342 +               error = -EINVAL;
10343 +               break;
10344 +       }
10345 +
10346 +       if (error != -EPERM)
10347 +               goto out;
10348 +
10349 +       gr_auth_attempts++;
10350 +
10351 +       if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
10352 +               security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
10353 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
10354 +       }
10355 +
10356 +      out:
10357 +       up(&gr_dev_sem);
10358 +       return error;
10359 +}
10360 +
10361 +int
10362 +gr_set_acls(const int type)
10363 +{
10364 +       struct acl_object_label *obj;
10365 +       struct task_struct *task, *task2;
10366 +       struct file *filp;
10367 +       unsigned short i;
10368 +
10369 +       read_lock(&tasklist_lock);
10370 +       read_lock(&grsec_exec_file_lock);
10371 +       for_each_process(task2) {
10372 +               task = task2;
10373 +               do {
10374 +               /* check to see if we're called from the exit handler,
10375 +                  if so, only replace ACLs that have inherited the admin
10376 +                  ACL */
10377 +
10378 +               if (type && (task->role != current->role ||
10379 +                            task->acl_role_id != current->acl_role_id))
10380 +                       continue;
10381 +
10382 +               task->acl_role_id = 0;
10383 +               task->acl_sp_role = 0;
10384 +
10385 +               if ((filp = task->exec_file)) {
10386 +                       do_set_role_label(task, task->uid, task->gid);
10387 +
10388 +                       task->acl =
10389 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
10390 +                                          task->role);
10391 +                       if (task->acl) {
10392 +                               struct acl_subject_label *curr;
10393 +                               curr = task->acl;
10394 +
10395 +                               task->is_writable = 0;
10396 +                               /* ignore additional mmap checks for processes that are writable 
10397 +                                  by the default ACL */
10398 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10399 +                               if (unlikely(obj->mode & GR_WRITE))
10400 +                                       task->is_writable = 1;
10401 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
10402 +                               if (unlikely(obj->mode & GR_WRITE))
10403 +                                       task->is_writable = 1;
10404 +
10405 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
10406 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
10407 +#endif
10408 +                               if (!(curr->mode & GR_LEARN))
10409 +                                       for (i = 0; i < RLIM_NLIMITS; i++) {
10410 +                                               if (!(curr->resmask & (1 << i)))
10411 +                                                       continue;
10412 +
10413 +                                               task->rlim[i].rlim_cur =
10414 +                                                   curr->res[i].rlim_cur;
10415 +                                               task->rlim[i].rlim_max =
10416 +                                                   curr->res[i].rlim_max;
10417 +                                       }
10418 +                       } else {
10419 +                               read_unlock(&grsec_exec_file_lock);
10420 +                               read_unlock(&tasklist_lock);
10421 +                               security_alert_good(GR_DEFACL_MSG, task->comm,
10422 +                                                   task->pid);
10423 +                               return 1;
10424 +                       }
10425 +               } else {
10426 +                       // it's a kernel process
10427 +                       task->role = kernel_role;
10428 +                       task->acl = kernel_role->root_label;
10429 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
10430 +                       task->acl->mode &= ~GR_FIND;
10431 +#endif
10432 +               }
10433 +       } while ((task = next_thread(task)) != task2);
10434 +       }
10435 +       read_unlock(&grsec_exec_file_lock);
10436 +       read_unlock(&tasklist_lock);
10437 +       return 0;
10438 +}
10439 +
10440 +EXPORT_SYMBOL(gr_learn_resource);
10441 +
10442 +void
10443 +gr_learn_resource(const struct task_struct *task,
10444 +                 const int res, const unsigned long wanted, const int gt)
10445 +{
10446 +       struct acl_subject_label *acl;
10447 +
10448 +       if (unlikely((gr_status & GR_READY) &&
10449 +                    task->acl && (task->acl->mode & GR_LEARN)))
10450 +               goto skip_reslog;
10451 +
10452 +#ifdef CONFIG_GRKERNSEC_RESLOG
10453 +       gr_log_resource(task, res, wanted, gt);
10454 +#endif
10455 +      skip_reslog:
10456 +
10457 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
10458 +               return;
10459 +
10460 +       acl = task->acl;
10461 +
10462 +       if (likely(!acl || !(acl->mode & GR_LEARN) ||
10463 +                  !(acl->resmask & (1 << (unsigned short) res))))
10464 +               return;
10465 +
10466 +       if (wanted >= acl->res[res].rlim_cur) {
10467 +               unsigned long res_add;
10468 +
10469 +               res_add = wanted;
10470 +               switch (res) {
10471 +               case RLIMIT_CPU:
10472 +                       res_add += GR_RLIM_CPU_BUMP;
10473 +                       break;
10474 +               case RLIMIT_FSIZE:
10475 +                       res_add += GR_RLIM_FSIZE_BUMP;
10476 +                       break;
10477 +               case RLIMIT_DATA:
10478 +                       res_add += GR_RLIM_DATA_BUMP;
10479 +                       break;
10480 +               case RLIMIT_STACK:
10481 +                       res_add += GR_RLIM_STACK_BUMP;
10482 +                       break;
10483 +               case RLIMIT_CORE:
10484 +                       res_add += GR_RLIM_CORE_BUMP;
10485 +                       break;
10486 +               case RLIMIT_RSS:
10487 +                       res_add += GR_RLIM_RSS_BUMP;
10488 +                       break;
10489 +               case RLIMIT_NPROC:
10490 +                       res_add += GR_RLIM_NPROC_BUMP;
10491 +                       break;
10492 +               case RLIMIT_NOFILE:
10493 +                       res_add += GR_RLIM_NOFILE_BUMP;
10494 +                       break;
10495 +               case RLIMIT_MEMLOCK:
10496 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
10497 +                       break;
10498 +               case RLIMIT_AS:
10499 +                       res_add += GR_RLIM_AS_BUMP;
10500 +                       break;
10501 +               case RLIMIT_LOCKS:
10502 +                       res_add += GR_RLIM_LOCKS_BUMP;
10503 +                       break;
10504 +               }
10505 +
10506 +               acl->res[res].rlim_cur = res_add;
10507 +
10508 +               if (wanted > acl->res[res].rlim_max)
10509 +                       acl->res[res].rlim_max = res_add;
10510 +
10511 +               security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
10512 +                              current->role->roletype, acl->filename,
10513 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
10514 +                              "", (unsigned long) res);
10515 +       }
10516 +
10517 +       return;
10518 +}
10519 +
10520 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
10521 +void
10522 +pax_set_flags(struct linux_binprm *bprm)
10523 +{
10524 +       struct task_struct *task = current;
10525 +        struct acl_subject_label *proc;
10526 +
10527 +        if (unlikely(!(gr_status & GR_READY)))
10528 +                return;
10529 +
10530 +        proc = task->acl;
10531 +
10532 +        if (proc->mode & GR_PAXPAGE)
10533 +                task->flags &= ~PF_PAX_PAGEEXEC;
10534 +        if (proc->mode & GR_PAXSEGM)
10535 +                task->flags &= ~PF_PAX_SEGMEXEC;
10536 +        if (proc->mode & GR_PAXGCC)
10537 +                task->flags |= PF_PAX_EMUTRAMP;
10538 +        if (proc->mode & GR_PAXMPROTECT)
10539 +                task->flags &= ~PF_PAX_MPROTECT;
10540 +        if (proc->mode & GR_PAXRANDMMAP)
10541 +                task->flags &= ~PF_PAX_RANDMMAP;
10542 +        if (proc->mode & GR_PAXRANDEXEC)
10543 +                task->flags |= PF_PAX_RANDEXEC;
10544 +
10545 +        return;
10546 +}
10547 +#endif
10548 +
10549 +#ifdef CONFIG_SYSCTL
10550 +extern struct proc_dir_entry *proc_sys_root;
10551 +
10552 +
10553 +/* the following function is called under the BKL */
10554 +
10555 +__u32
10556 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
10557 +                const void *newval)
10558 +{
10559 +       struct proc_dir_entry *tmp;
10560 +       struct nameidata nd;
10561 +       const char *proc_sys = "/proc/sys";
10562 +       char *path;
10563 +       struct acl_object_label *obj;
10564 +       unsigned short len = 0, pos = 0, depth = 0, i;
10565 +       __u32 err = 0;
10566 +       __u32 mode = 0;
10567 +
10568 +       if (unlikely(!(gr_status & GR_READY)))
10569 +               return 1;
10570 +
10571 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
10572 +
10573 +       if (oldval)
10574 +               mode |= GR_READ;
10575 +       if (newval)
10576 +               mode |= GR_WRITE;
10577 +
10578 +       /* convert the requested sysctl entry into a pathname */
10579 +
10580 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
10581 +               len += strlen(tmp->name);
10582 +               len++;
10583 +               depth++;
10584 +       }
10585 +
10586 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
10587 +               return 0;       /* deny */
10588 +
10589 +       memset(path, 0, PAGE_SIZE);
10590 +
10591 +       memcpy(path, proc_sys, strlen(proc_sys));
10592 +
10593 +       pos += strlen(proc_sys);
10594 +
10595 +       for (; depth > 0; depth--) {
10596 +               path[pos] = '/';
10597 +               pos++;
10598 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
10599 +                    tmp = tmp->parent) {
10600 +                       if (depth == i) {
10601 +                               memcpy(path + pos, tmp->name,
10602 +                                      strlen(tmp->name));
10603 +                               pos += strlen(tmp->name);
10604 +                       }
10605 +                       i++;
10606 +               }
10607 +       }
10608 +
10609 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
10610 +
10611 +       if (err)
10612 +               goto out;
10613 +
10614 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
10615 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
10616 +
10617 +       if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
10618 +               __u32 new_mode = mode;
10619 +
10620 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
10621 +
10622 +               err = new_mode;
10623 +               gr_log_learn(current->role, current->uid, current->gid,
10624 +                            current, path, new_mode);
10625 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
10626 +               security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
10627 +                              (mode & GR_READ) ? " reading" : "",
10628 +                              (mode & GR_WRITE) ? " writing" : "",
10629 +                              DEFAULTSECARGS);
10630 +               err = 0;
10631 +       } else if ((err & mode) != mode) {
10632 +               err = 0;
10633 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
10634 +               security_audit(GR_SYSCTL_ACL_MSG, "successful",
10635 +                              path, (mode & GR_READ) ? " reading" : "",
10636 +                              (mode & GR_WRITE) ? " writing" : "",
10637 +                              DEFAULTSECARGS);
10638 +       }
10639 +
10640 +       path_release(&nd);
10641 +
10642 +      out:
10643 +       return err;
10644 +}
10645 +#endif
10646 +
10647 +int
10648 +gr_handle_proc_ptrace(struct task_struct *task)
10649 +{
10650 +       struct file *filp;
10651 +       struct task_struct *tmp = task;
10652 +       struct task_struct *curtemp = current;
10653 +       __u32 retmode;
10654 +
10655 +       if (unlikely(!(gr_status & GR_READY)))
10656 +               return 0;
10657 +
10658 +       read_lock(&tasklist_lock);
10659 +       read_lock(&grsec_exec_file_lock);
10660 +       filp = task->exec_file;
10661 +
10662 +       while (tmp->pid > 0) {
10663 +               if (tmp == curtemp)
10664 +                       break;
10665 +               tmp = tmp->parent;
10666 +       }
10667 +
10668 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
10669 +               read_unlock(&grsec_exec_file_lock);
10670 +               read_unlock(&tasklist_lock);
10671 +               return 1;
10672 +       }
10673 +
10674 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
10675 +       read_unlock(&grsec_exec_file_lock);
10676 +       read_unlock(&tasklist_lock);
10677 +
10678 +       if (retmode & GR_NOPTRACE)
10679 +               return 1;
10680 +
10681 +       if (!(current->acl->mode & GR_OVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
10682 +           && (current->acl != task->acl || (current->acl != current->role->root_label
10683 +           && current->pid != task->pid)))
10684 +               return 1;
10685 +
10686 +       return 0;
10687 +}
10688 +
10689 +int
10690 +gr_handle_ptrace(struct task_struct *task, const long request)
10691 +{
10692 +       struct task_struct *tmp = task;
10693 +       struct task_struct *curtemp = current;
10694 +       __u32 retmode;
10695 +
10696 +       if (unlikely(!(gr_status & GR_READY)))
10697 +               return 0;
10698 +
10699 +       read_lock(&tasklist_lock);
10700 +       while (tmp->pid > 0) {
10701 +               if (tmp == curtemp)
10702 +                       break;
10703 +               tmp = tmp->parent;
10704 +       }
10705 +       read_unlock(&tasklist_lock);
10706 +
10707 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
10708 +               security_alert(GR_PTRACE_ACL_MSG, task->exec_file ?
10709 +                              gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt)
10710 +                              : "(none)", task->comm, task->pid,
10711 +                              DEFAULTSECARGS);
10712 +               return 1;
10713 +       }
10714 +
10715 +       read_lock(&grsec_exec_file_lock);
10716 +       if (unlikely(!task->exec_file)) {
10717 +               read_unlock(&grsec_exec_file_lock);
10718 +               return 0;
10719 +       }
10720 +
10721 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
10722 +       read_unlock(&grsec_exec_file_lock);
10723 +
10724 +       if (retmode & GR_NOPTRACE) {
10725 +               security_alert(GR_PTRACE_ACL_MSG, gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt),
10726 +                              task->comm, task->pid, DEFAULTSECARGS);
10727 +               return 1;
10728 +       }
10729 +               
10730 +       if (retmode & GR_PTRACERD) {
10731 +               switch (request) {
10732 +               case PTRACE_POKETEXT:
10733 +               case PTRACE_POKEDATA:
10734 +               case PTRACE_POKEUSR:
10735 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
10736 +               case PTRACE_SETREGS:
10737 +               case PTRACE_SETFPREGS:
10738 +#endif
10739 +#ifdef CONFIG_X86
10740 +               case PTRACE_SETFPXREGS:
10741 +#endif
10742 +#ifdef CONFIG_ALTIVEC
10743 +               case PTRACE_SETVRREGS:
10744 +#endif
10745 +                       return 1;
10746 +               default:
10747 +                       return 0;
10748 +               }
10749 +       } else if (!(current->acl->mode & GR_OVERRIDE) &&
10750 +                  !(current->role->roletype & GR_ROLE_GOD) &&
10751 +                  (current->acl != task->acl)) {
10752 +               security_alert(GR_PTRACE_ACL_MSG,
10753 +                              gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt),
10754 +                              task->comm, task->pid, DEFAULTSECARGS);
10755 +               return 1;
10756 +       }
10757 +
10758 +       return 0;
10759 +}
10760 +
10761 +int
10762 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
10763 +{
10764 +       struct acl_object_label *obj, *obj2;
10765 +
10766 +       if (unlikely(!(gr_status & GR_READY) ||
10767 +                    (current->acl->mode & GR_OVERRIDE) || !filp ||
10768 +                    !(prot & PROT_EXEC)))
10769 +               return 0;
10770 +
10771 +       if (unlikely(current->is_writable))
10772 +               return 0;
10773 +
10774 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
10775 +       obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
10776 +                            current->role->root_label);
10777 +       if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
10778 +               security_alert(GR_WRITLIB_ACL_MSG,
10779 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
10780 +                              DEFAULTSECARGS);
10781 +               return 1;
10782 +       }
10783 +
10784 +       return 0;
10785 +}
10786 +
10787 +int
10788 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
10789 +{
10790 +       __u32 mode;
10791 +
10792 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10793 +               return 1;
10794 +
10795 +       mode =
10796 +           gr_search_file(file->f_dentry,
10797 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10798 +                          file->f_vfsmnt);
10799 +
10800 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10801 +               security_alert(GR_MMAP_ACL_MSG, "denied",
10802 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10803 +                              DEFAULTSECARGS);
10804 +               return 0;
10805 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10806 +               return 0;
10807 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10808 +               security_audit(GR_MMAP_ACL_MSG, "successful",
10809 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10810 +                              DEFAULTSECARGS);
10811 +               return 1;
10812 +       }
10813 +
10814 +       return 1;
10815 +}
10816 +
10817 +int
10818 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
10819 +{
10820 +       __u32 mode;
10821 +
10822 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10823 +               return 1;
10824 +
10825 +       mode =
10826 +           gr_search_file(file->f_dentry,
10827 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10828 +                          file->f_vfsmnt);
10829 +
10830 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10831 +               security_alert(GR_MPROTECT_ACL_MSG, "denied",
10832 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10833 +                              DEFAULTSECARGS);
10834 +               return 0;
10835 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10836 +               return 0;
10837 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10838 +               security_audit(GR_MPROTECT_ACL_MSG, "successful",
10839 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10840 +                              DEFAULTSECARGS);
10841 +               return 1;
10842 +       }
10843 +
10844 +       return 1;
10845 +}
10846 +
10847 +void
10848 +gr_acl_handle_psacct(struct task_struct *task, const long code)
10849 +{
10850 +       u64 runtime64;
10851 +       unsigned long runtime;
10852 +       unsigned long cputime;
10853 +       unsigned int wday, cday;
10854 +       __u8 whr, chr;
10855 +       __u8 wmin, cmin;
10856 +       __u8 wsec, csec;
10857 +       char cur_tty[64] = { 0 };
10858 +       char parent_tty[64] = { 0 };
10859 +
10860 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
10861 +                    !(task->acl->mode & GR_PROCACCT)))
10862 +               return;
10863 +
10864 +       runtime64 = get_jiffies_64() - task->start_time;
10865 +       do_div(runtime64, HZ);
10866 +       runtime = (unsigned long)runtime64;
10867 +       wday = runtime / (3600 * 24);
10868 +       runtime -= wday * (3600 * 24);
10869 +       whr = runtime / 3600;
10870 +       runtime -= whr * 3600;
10871 +       wmin = runtime / 60;
10872 +       runtime -= wmin * 60;
10873 +       wsec = runtime;
10874 +
10875 +       cputime = (task->utime + task->stime) / HZ;
10876 +       cday = cputime / (3600 * 24);
10877 +       cputime -= cday * (3600 * 24);
10878 +       chr = cputime / 3600;
10879 +       cputime -= chr * 3600;
10880 +       cmin = cputime / 60;
10881 +       cputime -= cmin * 60;
10882 +       csec = cputime;
10883 +
10884 +       security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
10885 +                      task->pid, NIPQUAD(task->curr_ip), tty_name(task->signal->tty,
10886 +                                                                  cur_tty),
10887 +                      task->uid, task->euid, task->gid, task->egid, wday, whr,
10888 +                      wmin, wsec, cday, chr, cmin, csec,
10889 +                      (task->flags & PF_SIGNALED) ? "killed by signal" : "exited",
10890 +                      code, gr_parent_task_fullpath(task), 
10891 +                      task->parent->comm, task->parent->pid,
10892 +                      NIPQUAD(task->parent->curr_ip),
10893 +                      tty_name(task->parent->signal->tty, parent_tty),
10894 +                      task->parent->uid, task->parent->euid, task->parent->gid,
10895 +                      task->parent->egid);
10896 +
10897 +       return;
10898 +}
10899 +
10900 +EXPORT_SYMBOL(gr_set_kernel_label);
10901 +
10902 +void gr_set_kernel_label(struct task_struct *task)
10903 +{
10904 +       if (gr_status & GR_READY) {
10905 +               task->role = kernel_role;
10906 +               task->acl = kernel_role->root_label;
10907 +       }
10908 +       return;
10909 +}
10910 diff -uNr linux-2.6.8/grsecurity/gracl_cap.c linux-2.6.8.grsecurity/grsecurity/gracl_cap.c
10911 --- linux-2.6.8/grsecurity/gracl_cap.c  1970-01-01 01:00:00.000000000 +0100
10912 +++ linux-2.6.8.grsecurity/grsecurity/gracl_cap.c       2004-08-16 17:08:29.000000000 +0200
10913 @@ -0,0 +1,116 @@
10914 +/* capability handling routines, (c) Brad Spengler 2002,2003 */
10915 +
10916 +#include <linux/kernel.h>
10917 +#include <linux/module.h>
10918 +#include <linux/sched.h>
10919 +#include <linux/capability.h>
10920 +#include <linux/gracl.h>
10921 +#include <linux/grsecurity.h>
10922 +#include <linux/grinternal.h>
10923 +
10924 +static const char *captab_log[29] = {
10925 +       "CAP_CHOWN",
10926 +       "CAP_DAC_OVERRIDE",
10927 +       "CAP_DAC_READ_SEARCH",
10928 +       "CAP_FOWNER",
10929 +       "CAP_FSETID",
10930 +       "CAP_KILL",
10931 +       "CAP_SETGID",
10932 +       "CAP_SETUID",
10933 +       "CAP_SETPCAP",
10934 +       "CAP_LINUX_IMMUTABLE",
10935 +       "CAP_NET_BIND_SERVICE",
10936 +       "CAP_NET_BROADCAST",
10937 +       "CAP_NET_ADMIN",
10938 +       "CAP_NET_RAW",
10939 +       "CAP_IPC_LOCK",
10940 +       "CAP_IPC_OWNER",
10941 +       "CAP_SYS_MODULE",
10942 +       "CAP_SYS_RAWIO",
10943 +       "CAP_SYS_CHROOT",
10944 +       "CAP_SYS_PTRACE",
10945 +       "CAP_SYS_PACCT",
10946 +       "CAP_SYS_ADMIN",
10947 +       "CAP_SYS_BOOT",
10948 +       "CAP_SYS_NICE",
10949 +       "CAP_SYS_RESOURCE",
10950 +       "CAP_SYS_TIME",
10951 +       "CAP_SYS_TTY_CONFIG",
10952 +       "CAP_MKNOD",
10953 +       "CAP_LEASE"
10954 +};
10955 +
10956 +EXPORT_SYMBOL(gr_task_is_capable);
10957 +
10958 +int
10959 +gr_task_is_capable(struct task_struct *task, const int cap)
10960 +{
10961 +       struct acl_subject_label *curracl;
10962 +       __u32 cap_drop = 0, cap_mask = 0;
10963 +
10964 +       if (!gr_acl_is_enabled())
10965 +               return 1;
10966 +
10967 +       curracl = task->acl;
10968 +
10969 +       cap_drop = curracl->cap_lower;
10970 +       cap_mask = curracl->cap_mask;
10971 +
10972 +       while ((curracl = curracl->parent_subject)) {
10973 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
10974 +                       cap_drop |= curracl->cap_lower & (1 << cap);
10975 +               cap_mask |= curracl->cap_mask;
10976 +       }
10977 +
10978 +       if (!cap_raised(cap_drop, cap))
10979 +               return 1;
10980 +
10981 +       curracl = task->acl;
10982 +
10983 +       if ((curracl->mode & GR_LEARN)
10984 +           && cap_raised(task->cap_effective, cap)) {
10985 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
10986 +                              task->role->roletype, task->uid,
10987 +                              task->gid, task->exec_file ?
10988 +                              gr_to_filename(task->exec_file->f_dentry,
10989 +                              task->exec_file->f_vfsmnt) : curracl->filename,
10990 +                              curracl->filename, 0UL,
10991 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->curr_ip));
10992 +               return 1;
10993 +       }
10994 +
10995 +       if ((cap >= 0) && (cap < 29) && cap_raised(task->cap_effective, cap))
10996 +               security_alert(GR_CAP_ACL_MSG, captab_log[cap],
10997 +                               gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid,
10998 +                               task->gid, task->egid, gr_parent_task_fullpath(task),
10999 +                               task->parent->comm, task->parent->pid, task->parent->uid,
11000 +                               task->parent->euid, task->parent->gid, task->parent->egid);
11001 +
11002 +       return 0;
11003 +}
11004 +
11005 +int
11006 +gr_is_capable_nolog(const int cap)
11007 +{
11008 +       struct acl_subject_label *curracl;
11009 +       __u32 cap_drop = 0, cap_mask = 0;
11010 +
11011 +       if (!gr_acl_is_enabled())
11012 +               return 1;
11013 +
11014 +       curracl = current->acl;
11015 +
11016 +       cap_drop = curracl->cap_lower;
11017 +       cap_mask = curracl->cap_mask;
11018 +
11019 +       while ((curracl = curracl->parent_subject)) {
11020 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
11021 +               cap_mask |= curracl->cap_mask;
11022 +       }
11023 +
11024 +       if (!cap_raised(cap_drop, cap))
11025 +               return 1;
11026 +
11027 +       return 0;
11028 +}
11029 +
11030 diff -uNr linux-2.6.8/grsecurity/gracl_fs.c linux-2.6.8.grsecurity/grsecurity/gracl_fs.c
11031 --- linux-2.6.8/grsecurity/gracl_fs.c   1970-01-01 01:00:00.000000000 +0100
11032 +++ linux-2.6.8.grsecurity/grsecurity/gracl_fs.c        2004-08-16 17:08:29.000000000 +0200
11033 @@ -0,0 +1,468 @@
11034 +#include <linux/kernel.h>
11035 +#include <linux/sched.h>
11036 +#include <linux/types.h>
11037 +#include <linux/fs.h>
11038 +#include <linux/file.h>
11039 +#include <linux/stat.h>
11040 +#include <linux/grsecurity.h>
11041 +#include <linux/grinternal.h>
11042 +#include <linux/gracl.h>
11043 +
11044 +__u32
11045 +gr_acl_handle_hidden_file(const struct dentry * dentry,
11046 +                         const struct vfsmount * mnt)
11047 +{
11048 +       __u32 mode;
11049 +
11050 +       if (unlikely(!dentry->d_inode))
11051 +               return GR_FIND;
11052 +
11053 +       mode =
11054 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
11055 +
11056 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
11057 +               security_audit(GR_HIDDEN_ACL_MSG, "successful",
11058 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
11059 +               return mode;
11060 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
11061 +               security_alert(GR_HIDDEN_ACL_MSG, "denied",
11062 +                              gr_to_filename(dentry, mnt),
11063 +                              DEFAULTSECARGS);
11064 +               return 0;
11065 +       } else if (unlikely(!(mode & GR_FIND)))
11066 +               return 0;
11067 +
11068 +       return GR_FIND;
11069 +}
11070 +
11071 +__u32
11072 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
11073 +                  const int fmode)
11074 +{
11075 +       __u32 reqmode = GR_FIND;
11076 +       __u32 mode;
11077 +
11078 +       if (unlikely(!dentry->d_inode))
11079 +               return reqmode;
11080 +
11081 +       if (unlikely(fmode & O_APPEND))
11082 +               reqmode |= GR_APPEND;
11083 +       else if (unlikely(fmode & FMODE_WRITE))
11084 +               reqmode |= GR_WRITE;
11085 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
11086 +               reqmode |= GR_READ;
11087 +
11088 +       mode =
11089 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
11090 +                          mnt);
11091 +
11092 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11093 +               security_audit(GR_OPEN_ACL_MSG, "successful",
11094 +                              gr_to_filename(dentry, mnt),
11095 +                              reqmode & GR_READ ? " reading" : "",
11096 +                              reqmode & GR_WRITE ? " writing" :
11097 +                              reqmode & GR_APPEND ? " appending" : "",
11098 +                              DEFAULTSECARGS);
11099 +               return reqmode;
11100 +       } else
11101 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11102 +       {
11103 +               security_alert(GR_OPEN_ACL_MSG, "denied",
11104 +                              gr_to_filename(dentry, mnt),
11105 +                              reqmode & GR_READ ? " reading" : "",
11106 +                              reqmode & GR_WRITE ? " writing" : reqmode &
11107 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
11108 +               return 0;
11109 +       } else if (unlikely((mode & reqmode) != reqmode))
11110 +               return 0;
11111 +
11112 +       return reqmode;
11113 +}
11114 +
11115 +__u32
11116 +gr_acl_handle_creat(const struct dentry * dentry,
11117 +                   const struct dentry * p_dentry,
11118 +                   const struct vfsmount * p_mnt, const int fmode,
11119 +                   const int imode)
11120 +{
11121 +       __u32 reqmode = GR_WRITE | GR_CREATE;
11122 +       __u32 mode;
11123 +
11124 +       if (unlikely(fmode & O_APPEND))
11125 +               reqmode |= GR_APPEND;
11126 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
11127 +               reqmode |= GR_READ;
11128 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
11129 +               reqmode |= GR_SETID;
11130 +
11131 +       mode =
11132 +           gr_check_create(dentry, p_dentry, p_mnt,
11133 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
11134 +
11135 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11136 +               security_audit(GR_CREATE_ACL_MSG, "successful",
11137 +                              gr_to_filename(dentry, p_mnt),
11138 +                              reqmode & GR_READ ? " reading" : "",
11139 +                              reqmode & GR_WRITE ? " writing" :
11140 +                              reqmode & GR_APPEND ? " appending" : "",
11141 +                              DEFAULTSECARGS);
11142 +               return reqmode;
11143 +       } else
11144 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11145 +       {
11146 +               security_alert(GR_CREATE_ACL_MSG, "denied",
11147 +                              gr_to_filename(dentry, p_mnt),
11148 +                              reqmode & GR_READ ? " reading" : "",
11149 +                              reqmode & GR_WRITE ? " writing" : reqmode &
11150 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
11151 +               return 0;
11152 +       } else if (unlikely((mode & reqmode) != reqmode))
11153 +               return 0;
11154 +
11155 +       return reqmode;
11156 +}
11157 +
11158 +__u32
11159 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
11160 +                    const int fmode)
11161 +{
11162 +       __u32 mode, reqmode = GR_FIND;
11163 +
11164 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
11165 +               reqmode |= GR_EXEC;
11166 +       if (fmode & S_IWOTH)
11167 +               reqmode |= GR_WRITE;
11168 +       if (fmode & S_IROTH)
11169 +               reqmode |= GR_READ;
11170 +
11171 +       mode =
11172 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
11173 +                          mnt);
11174 +
11175 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
11176 +               security_audit(GR_ACCESS_ACL_MSG, "successful",
11177 +                              gr_to_filename(dentry, mnt),
11178 +                              reqmode & GR_READ ? " reading" : "",
11179 +                              reqmode & GR_WRITE ? " writing" : "",
11180 +                              reqmode & GR_EXEC ? " executing" : "",
11181 +                              DEFAULTSECARGS);
11182 +               return reqmode;
11183 +       } else
11184 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
11185 +       {
11186 +               security_alert(GR_ACCESS_ACL_MSG, "denied",
11187 +                              gr_to_filename(dentry, mnt),
11188 +                              reqmode & GR_READ ? " reading" : "",
11189 +                              reqmode & GR_WRITE ? " writing" : "",
11190 +                              reqmode & GR_EXEC ? " executing" : "",
11191 +                              DEFAULTSECARGS);
11192 +               return 0;
11193 +       } else if (unlikely((mode & reqmode) != reqmode))
11194 +               return 0;
11195 +
11196 +       return reqmode;
11197 +}
11198 +
11199 +#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
11200 +{ \
11201 +       __u32 mode; \
11202 +       \
11203 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
11204 +       \
11205 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
11206 +               security_audit(fmt, "successful", \
11207 +                               gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
11208 +               return mode; \
11209 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
11210 +               security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
11211 +                               DEFAULTSECARGS); \
11212 +               return 0; \
11213 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
11214 +               return 0; \
11215 +       \
11216 +       return (reqmode); \
11217 +}
11218 +
11219 +__u32
11220 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
11221 +{
11222 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
11223 +}
11224 +
11225 +__u32
11226 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
11227 +{
11228 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
11229 +}
11230 +
11231 +__u32
11232 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
11233 +{
11234 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
11235 +}
11236 +
11237 +__u32
11238 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
11239 +{
11240 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
11241 +}
11242 +
11243 +__u32
11244 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
11245 +                    mode_t mode)
11246 +{
11247 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
11248 +               return 1;
11249 +
11250 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
11251 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
11252 +                                  GR_FCHMOD_ACL_MSG);
11253 +       } else {
11254 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
11255 +       }
11256 +}
11257 +
11258 +__u32
11259 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
11260 +                   mode_t mode)
11261 +{
11262 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
11263 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
11264 +                                  GR_CHMOD_ACL_MSG);
11265 +       } else {
11266 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
11267 +       }
11268 +}
11269 +
11270 +__u32
11271 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
11272 +{
11273 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
11274 +}
11275 +
11276 +__u32
11277 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
11278 +{
11279 +       generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
11280 +}
11281 +
11282 +__u32
11283 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
11284 +{
11285 +       generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
11286 +                          GR_UNIXCONNECT_ACL_MSG);
11287 +}
11288 +
11289 +__u32
11290 +gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
11291 +                     const ino_t ino)
11292 +{
11293 +       if (likely((unsigned long)(dentry->d_inode))) {
11294 +               struct dentry d = *dentry;
11295 +               struct inode inode = *(dentry->d_inode);
11296 +
11297 +               inode.i_ino = ino;
11298 +               d.d_inode = &inode;
11299 +
11300 +               if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
11301 +                       return 0;
11302 +       }
11303 +
11304 +       return 1;
11305 +}
11306 +
11307 +__u32
11308 +gr_acl_handle_link(const struct dentry * new_dentry,
11309 +                  const struct dentry * parent_dentry,
11310 +                  const struct vfsmount * parent_mnt,
11311 +                  const struct dentry * old_dentry,
11312 +                  const struct vfsmount * old_mnt, const char *to)
11313 +{
11314 +       __u32 needmode = GR_WRITE | GR_CREATE;
11315 +       __u32 mode;
11316 +
11317 +       mode =
11318 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
11319 +                         old_mnt);
11320 +
11321 +       if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
11322 +               security_audit(GR_LINK_ACL_MSG, "successful",
11323 +                              gr_to_filename(old_dentry, old_mnt), to,
11324 +                              DEFAULTSECARGS);
11325 +               return mode;
11326 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
11327 +               security_alert(GR_LINK_ACL_MSG, "denied",
11328 +                              gr_to_filename(old_dentry, old_mnt), to,
11329 +                              DEFAULTSECARGS);
11330 +               return 0;
11331 +       } else if (unlikely((mode & needmode) != needmode))
11332 +               return 0;
11333 +
11334 +       return (GR_WRITE | GR_CREATE);
11335 +}
11336 +
11337 +__u32
11338 +gr_acl_handle_symlink(const struct dentry * new_dentry,
11339 +                     const struct dentry * parent_dentry,
11340 +                     const struct vfsmount * parent_mnt, const char *from)
11341 +{
11342 +       __u32 needmode = GR_WRITE | GR_CREATE;
11343 +       __u32 mode;
11344 +
11345 +       mode =
11346 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
11347 +                           GR_CREATE | GR_AUDIT_CREATE |
11348 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
11349 +
11350 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
11351 +               security_audit(GR_SYMLINK_ACL_MSG, "successful",
11352 +                              from, gr_to_filename(new_dentry, parent_mnt),
11353 +                              DEFAULTSECARGS);
11354 +               return mode;
11355 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
11356 +               security_alert(GR_SYMLINK_ACL_MSG, "denied",
11357 +                              from, gr_to_filename(new_dentry, parent_mnt),
11358 +                              DEFAULTSECARGS);
11359 +               return 0;
11360 +       } else if (unlikely((mode & needmode) != needmode))
11361 +               return 0;
11362 +
11363 +       return (GR_WRITE | GR_CREATE);
11364 +}
11365 +
11366 +#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
11367 +{ \
11368 +       __u32 mode; \
11369 +       \
11370 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
11371 +       \
11372 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
11373 +               security_audit(fmt, "successful", \
11374 +                               gr_to_filename(new_dentry, parent_mnt), \
11375 +                               DEFAULTSECARGS); \
11376 +               return mode; \
11377 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
11378 +               security_alert(fmt, "denied", \
11379 +                               gr_to_filename(new_dentry, parent_mnt), \
11380 +                               DEFAULTSECARGS); \
11381 +               return 0; \
11382 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
11383 +               return 0; \
11384 +       \
11385 +       return (reqmode); \
11386 +}
11387 +
11388 +__u32
11389 +gr_acl_handle_mknod(const struct dentry * new_dentry,
11390 +                   const struct dentry * parent_dentry,
11391 +                   const struct vfsmount * parent_mnt,
11392 +                   const int mode)
11393 +{
11394 +       __u32 reqmode = GR_WRITE | GR_CREATE;
11395 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
11396 +               reqmode |= GR_SETID;
11397 +
11398 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
11399 +                                 reqmode, GR_MKNOD_ACL_MSG);
11400 +}
11401 +
11402 +__u32
11403 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
11404 +                   const struct dentry *parent_dentry,
11405 +                   const struct vfsmount *parent_mnt)
11406 +{
11407 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
11408 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
11409 +}
11410 +
11411 +#define RENAME_CHECK_SUCCESS(old, new) \
11412 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
11413 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
11414 +
11415 +int
11416 +gr_acl_handle_rename(struct dentry *new_dentry,
11417 +                    struct dentry *parent_dentry,
11418 +                    const struct vfsmount *parent_mnt,
11419 +                    struct dentry *old_dentry,
11420 +                    struct inode *old_parent_inode,
11421 +                    struct vfsmount *old_mnt, const char *newname)
11422 +{
11423 +       __u32 comp1, comp2;
11424 +       int error = 0;
11425 +
11426 +       if (unlikely(!gr_acl_is_enabled()))
11427 +               return 0;
11428 +
11429 +       if (!new_dentry->d_inode) {
11430 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
11431 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
11432 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
11433 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
11434 +                                      GR_DELETE | GR_AUDIT_DELETE |
11435 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
11436 +                                      GR_SUPPRESS, old_mnt);
11437 +       } else {
11438 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
11439 +                                      GR_CREATE | GR_DELETE |
11440 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
11441 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
11442 +                                      GR_SUPPRESS, parent_mnt);
11443 +               comp2 =
11444 +                   gr_search_file(old_dentry,
11445 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
11446 +                                  GR_DELETE | GR_AUDIT_DELETE |
11447 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
11448 +       }
11449 +
11450 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
11451 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
11452 +               security_audit(GR_RENAME_ACL_MSG, "successful",
11453 +                              gr_to_filename(old_dentry, old_mnt),
11454 +                              newname, DEFAULTSECARGS);
11455 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
11456 +                && !(comp2 & GR_SUPPRESS)) {
11457 +               security_alert(GR_RENAME_ACL_MSG, "denied",
11458 +                              gr_to_filename(old_dentry, old_mnt), newname,
11459 +                              DEFAULTSECARGS);
11460 +               error = -EACCES;
11461 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
11462 +               error = -EACCES;
11463 +
11464 +       return error;
11465 +}
11466 +
11467 +void
11468 +gr_acl_handle_exit(void)
11469 +{
11470 +       u16 id;
11471 +       char *rolename;
11472 +       struct file *exec_file;
11473 +
11474 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
11475 +               id = current->acl_role_id;
11476 +               rolename = current->role->rolename;
11477 +               gr_set_acls(1);
11478 +               security_alert_good(GR_SPROLEL_ACL_MSG,
11479 +                                   rolename, id, DEFAULTSECARGS);
11480 +       }
11481 +
11482 +       write_lock(&grsec_exec_file_lock);
11483 +       exec_file = current->exec_file;
11484 +       current->exec_file = NULL;
11485 +       write_unlock(&grsec_exec_file_lock);
11486 +
11487 +       if (exec_file)
11488 +               fput(exec_file);
11489 +}
11490 +
11491 +int
11492 +gr_acl_handle_procpidmem(const struct task_struct *task)
11493 +{
11494 +       if (unlikely(!gr_acl_is_enabled()))
11495 +               return 0;
11496 +
11497 +       if (task->acl->mode & GR_PROTPROCFD)
11498 +               return -EACCES;
11499 +
11500 +       return 0;
11501 +}
11502 diff -uNr linux-2.6.8/grsecurity/gracl_ip.c linux-2.6.8.grsecurity/grsecurity/gracl_ip.c
11503 --- linux-2.6.8/grsecurity/gracl_ip.c   1970-01-01 01:00:00.000000000 +0100
11504 +++ linux-2.6.8.grsecurity/grsecurity/gracl_ip.c        2004-08-16 17:08:29.000000000 +0200
11505 @@ -0,0 +1,236 @@
11506 +/* 
11507 + * grsecurity/gracl_ip.c
11508 + * Copyright Brad Spengler 2002, 2003
11509 + *
11510 + */
11511 +
11512 +#include <linux/kernel.h>
11513 +#include <asm/uaccess.h>
11514 +#include <asm/errno.h>
11515 +#include <net/sock.h>
11516 +#include <linux/file.h>
11517 +#include <linux/fs.h>
11518 +#include <linux/net.h>
11519 +#include <linux/in.h>
11520 +#include <linux/skbuff.h>
11521 +#include <linux/ip.h>
11522 +#include <linux/udp.h>
11523 +#include <linux/smp_lock.h>
11524 +#include <linux/types.h>
11525 +#include <linux/sched.h>
11526 +#include <linux/gracl.h>
11527 +#include <linux/grsecurity.h>
11528 +#include <linux/grinternal.h>
11529 +
11530 +#define GR_BIND        0x01
11531 +#define GR_CONNECT     0x02
11532 +
11533 +static const char * gr_protocols[256] = {
11534 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
11535 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
11536 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
11537 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
11538 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
11539 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
11540 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
11541 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
11542 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
11543 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
11544 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
11545 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
11546 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
11547 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
11548 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
11549 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
11550 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
11551 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
11552 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
11553 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
11554 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
11555 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
11556 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
11557 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
11558 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
11559 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
11560 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
11561 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
11562 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
11563 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
11564 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
11565 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
11566 +       };
11567 +
11568 +static const char * gr_socktypes[11] = {
11569 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
11570 +       "unknown:7", "unknown:8", "unknown:9", "packet"
11571 +       };
11572 +
11573 +__inline__ const char *
11574 +gr_proto_to_name(unsigned char proto)
11575 +{
11576 +       return gr_protocols[proto];
11577 +}
11578 +
11579 +__inline__ const char *
11580 +gr_socktype_to_name(unsigned char type)
11581 +{
11582 +       return gr_socktypes[type];
11583 +}
11584 +
11585 +int
11586 +gr_search_socket(const int domain, const int type, const int protocol)
11587 +{
11588 +       struct acl_subject_label *curr;
11589 +
11590 +       if (unlikely(!gr_acl_is_enabled()))
11591 +               goto exit;
11592 +
11593 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
11594 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
11595 +               goto exit;      // let the kernel handle it
11596 +
11597 +       curr = current->acl;
11598 +
11599 +       if (!curr->ips)
11600 +               goto exit;
11601 +
11602 +       if ((curr->ip_type & (1 << type)) &&
11603 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
11604 +               goto exit;
11605 +
11606 +       if (curr->mode & GR_LEARN) {
11607 +               /* we don't place acls on raw sockets , and sometimes
11608 +                  dgram/ip sockets are opened for ioctl and not
11609 +                  bind/connect, so we'll fake a bind learn log */
11610 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
11611 +                       __u32 fakeip = 0;
11612 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11613 +                                      current->role->roletype, current->uid,
11614 +                                      current->gid, current->exec_file ?
11615 +                                      gr_to_filename(current->exec_file->f_dentry,
11616 +                                      current->exec_file->f_vfsmnt) :
11617 +                                      curr->filename, curr->filename,
11618 +                                      NIPQUAD(fakeip), 0, type,
11619 +                                      protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
11620 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
11621 +                       __u32 fakeip = 0;
11622 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11623 +                                      current->role->roletype, current->uid,
11624 +                                      current->gid, current->exec_file ?
11625 +                                      gr_to_filename(current->exec_file->f_dentry,
11626 +                                      current->exec_file->f_vfsmnt) :
11627 +                                      curr->filename, curr->filename,
11628 +                                      NIPQUAD(fakeip), 0, type,
11629 +                                      protocol, GR_BIND, NIPQUAD(current->curr_ip));
11630 +               }
11631 +               /* we'll log when they use connect or bind */
11632 +               goto exit;
11633 +       }
11634 +
11635 +       security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
11636 +                      gr_proto_to_name(protocol), DEFAULTSECARGS);
11637 +
11638 +       return 0;
11639 +      exit:
11640 +       return 1;
11641 +}
11642 +
11643 +static __inline__ int
11644 +gr_search_connectbind(const int mode, const struct sock *sk,
11645 +                     const struct sockaddr_in *addr, const int type)
11646 +{
11647 +       struct acl_subject_label *curr;
11648 +       struct acl_ip_label *ip;
11649 +       unsigned long i;
11650 +       __u32 ip_addr = 0;
11651 +       __u16 ip_port = 0;
11652 +
11653 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
11654 +               return 1;
11655 +
11656 +       curr = current->acl;
11657 +
11658 +       if (!curr->ips)
11659 +               return 1;
11660 +
11661 +       ip_addr = addr->sin_addr.s_addr;
11662 +       ip_port = ntohs(addr->sin_port);
11663 +
11664 +       for (i = 0; i < curr->ip_num; i++) {
11665 +               ip = *(curr->ips + i);
11666 +               if ((ip->mode & mode) &&
11667 +                   (ip_port >= ip->low) &&
11668 +                   (ip_port <= ip->high) &&
11669 +                   ((ntohl(ip_addr) & ip->netmask) ==
11670 +                    (ntohl(ip->addr) & ip->netmask))
11671 +                   && (ip->
11672 +                       proto[sk->sk_protocol / 32] & (1 << (sk->sk_protocol % 32)))
11673 +                   && (ip->type & (1 << type)))
11674 +                       return 1;
11675 +       }
11676 +
11677 +       if (curr->mode & GR_LEARN) {
11678 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
11679 +                              current->role->roletype, current->uid,
11680 +                              current->gid, current->exec_file ?
11681 +                              gr_to_filename(current->exec_file->f_dentry,
11682 +                              current->exec_file->f_vfsmnt) :
11683 +                              curr->filename, curr->filename,
11684 +                              NIPQUAD(ip_addr), ip_port, type,
11685 +                              sk->sk_protocol, mode, NIPQUAD(current->curr_ip));
11686 +               return 1;
11687 +       }
11688 +
11689 +       if (mode == GR_BIND)
11690 +               security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11691 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol),
11692 +                              DEFAULTSECARGS);
11693 +       else if (mode == GR_CONNECT)
11694 +               security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
11695 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol),
11696 +                              DEFAULTSECARGS);
11697 +
11698 +       return 0;
11699 +}
11700 +
11701 +int
11702 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
11703 +{
11704 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
11705 +}
11706 +
11707 +int
11708 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
11709 +{
11710 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
11711 +}
11712 +
11713 +int
11714 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
11715 +{
11716 +       if (addr)
11717 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
11718 +       else {
11719 +               struct sockaddr_in sin;
11720 +               const struct inet_opt *inet = inet_sk(sk);
11721 +
11722 +               sin.sin_addr.s_addr = inet->daddr;
11723 +               sin.sin_port = inet->dport;
11724 +
11725 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11726 +       }
11727 +}
11728 +
11729 +int
11730 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
11731 +{
11732 +       struct sockaddr_in sin;
11733 +
11734 +       if (unlikely(skb->len < sizeof (struct udphdr)))
11735 +               return 1;       // skip this packet
11736 +
11737 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
11738 +       sin.sin_port = skb->h.uh->source;
11739 +
11740 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
11741 +}
11742 diff -uNr linux-2.6.8/grsecurity/gracl_learn.c linux-2.6.8.grsecurity/grsecurity/gracl_learn.c
11743 --- linux-2.6.8/grsecurity/gracl_learn.c        1970-01-01 01:00:00.000000000 +0100
11744 +++ linux-2.6.8.grsecurity/grsecurity/gracl_learn.c     2004-08-16 17:08:29.000000000 +0200
11745 @@ -0,0 +1,204 @@
11746 +#include <linux/kernel.h>
11747 +#include <linux/mm.h>
11748 +#include <linux/sched.h>
11749 +#include <linux/poll.h>
11750 +#include <linux/smp_lock.h>
11751 +#include <linux/string.h>
11752 +#include <linux/file.h>
11753 +#include <linux/types.h>
11754 +#include <linux/vmalloc.h>
11755 +#include <linux/grinternal.h>
11756 +
11757 +extern ssize_t write_grsec_handler(struct file * file, const char * buf,
11758 +                                  size_t count, loff_t *ppos);
11759 +extern int gr_acl_is_enabled(void);
11760 +
11761 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
11762 +static int gr_learn_attached;
11763 +
11764 +/* use a 512k buffer */
11765 +#define LEARN_BUFFER_SIZE (512 * 1024)
11766 +
11767 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
11768 +static DECLARE_MUTEX(gr_learn_user_sem);
11769 +
11770 +/* we need to maintain two buffers, so that the kernel context of grlearn
11771 +   uses a semaphore around the userspace copying, and the other kernel contexts
11772 +   use a spinlock when copying into the buffer, since they cannot sleep
11773 +*/
11774 +static char *learn_buffer;
11775 +static char *learn_buffer_user;
11776 +static int learn_buffer_len;
11777 +static int learn_buffer_user_len;
11778 +
11779 +static ssize_t
11780 +read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
11781 +{
11782 +       DECLARE_WAITQUEUE(wait, current);
11783 +       ssize_t retval = 0;
11784 +
11785 +       add_wait_queue(&learn_wait, &wait);
11786 +       set_current_state(TASK_INTERRUPTIBLE);
11787 +       do {
11788 +               down(&gr_learn_user_sem);
11789 +               spin_lock(&gr_learn_lock);
11790 +               if (learn_buffer_len)
11791 +                       break;
11792 +               spin_unlock(&gr_learn_lock);
11793 +               up(&gr_learn_user_sem);
11794 +               if (file->f_flags & O_NONBLOCK) {
11795 +                       retval = -EAGAIN;
11796 +                       goto out;
11797 +               }
11798 +               if (signal_pending(current)) {
11799 +                       retval = -ERESTARTSYS;
11800 +                       goto out;
11801 +               }
11802 +
11803 +               schedule();
11804 +       } while (1);
11805 +
11806 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
11807 +       learn_buffer_user_len = learn_buffer_len;
11808 +       retval = learn_buffer_len;
11809 +       learn_buffer_len = 0;
11810 +
11811 +       spin_unlock(&gr_learn_lock);
11812 +
11813 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
11814 +               retval = -EFAULT;
11815 +
11816 +       up(&gr_learn_user_sem);
11817 +out:
11818 +       set_current_state(TASK_RUNNING);
11819 +       remove_wait_queue(&learn_wait, &wait);
11820 +       return retval;
11821 +}
11822 +
11823 +static unsigned int
11824 +poll_learn(struct file * file, poll_table * wait)
11825 +{
11826 +       poll_wait(file, &learn_wait, wait);
11827 +
11828 +       if (learn_buffer_len)
11829 +               return (POLLIN | POLLRDNORM);
11830 +
11831 +       return 0;
11832 +}
11833 +
11834 +void
11835 +gr_clear_learn_entries(void)
11836 +{
11837 +       char *tmp;
11838 +
11839 +       down(&gr_learn_user_sem);
11840 +       if (learn_buffer != NULL) {
11841 +               spin_lock(&gr_learn_lock);
11842 +               tmp = learn_buffer;
11843 +               learn_buffer = NULL;
11844 +               spin_unlock(&gr_learn_lock);
11845 +               vfree(learn_buffer);
11846 +       }
11847 +       if (learn_buffer_user != NULL) {
11848 +               vfree(learn_buffer_user);
11849 +               learn_buffer_user = NULL;
11850 +       }
11851 +       learn_buffer_len = 0;
11852 +       up(&gr_learn_user_sem);
11853 +
11854 +       return;
11855 +}
11856 +
11857 +void
11858 +gr_add_learn_entry(const char *fmt, ...)
11859 +{
11860 +       va_list args;
11861 +       unsigned int len;
11862 +
11863 +       if (!gr_learn_attached)
11864 +               return;
11865 +
11866 +       spin_lock(&gr_learn_lock);
11867 +
11868 +       /* leave a gap at the end so we know when it's "full" but don't have to
11869 +          compute the exact length of the string we're trying to append
11870 +       */
11871 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
11872 +               spin_unlock(&gr_learn_lock);
11873 +               wake_up_interruptible(&learn_wait);
11874 +               return;
11875 +       }
11876 +       if (learn_buffer == NULL) {
11877 +               spin_unlock(&gr_learn_lock);
11878 +               return;
11879 +       }
11880 +
11881 +       va_start(args, fmt);
11882 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
11883 +       va_end(args);
11884 +
11885 +       learn_buffer_len += len + 1;
11886 +
11887 +       spin_unlock(&gr_learn_lock);
11888 +       wake_up_interruptible(&learn_wait);
11889 +
11890 +       return;
11891 +}
11892 +
11893 +static int
11894 +open_learn(struct inode *inode, struct file *file)
11895 +{
11896 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
11897 +               return -EBUSY;
11898 +       if (file->f_mode & FMODE_READ) {
11899 +               down(&gr_learn_user_sem);
11900 +               if (learn_buffer == NULL)
11901 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
11902 +               if (learn_buffer_user == NULL)
11903 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
11904 +               if (learn_buffer == NULL)
11905 +                       return -ENOMEM;
11906 +               if (learn_buffer_user == NULL)
11907 +                       return -ENOMEM;
11908 +               learn_buffer_len = 0;
11909 +               learn_buffer_user_len = 0;
11910 +               gr_learn_attached = 1;
11911 +               up(&gr_learn_user_sem);
11912 +       }
11913 +       return 0;
11914 +}
11915 +
11916 +static int
11917 +close_learn(struct inode *inode, struct file *file)
11918 +{
11919 +       char *tmp;
11920 +
11921 +       if (file->f_mode & FMODE_READ) {
11922 +               down(&gr_learn_user_sem);
11923 +               if (learn_buffer != NULL) {
11924 +                       spin_lock(&gr_learn_lock);
11925 +                       tmp = learn_buffer;
11926 +                       learn_buffer = NULL;
11927 +                       spin_unlock(&gr_learn_lock);
11928 +                       vfree(tmp);
11929 +               }
11930 +               if (learn_buffer_user != NULL) {
11931 +                       vfree(learn_buffer_user);
11932 +                       learn_buffer_user = NULL;
11933 +               }
11934 +               learn_buffer_len = 0;
11935 +               learn_buffer_user_len = 0;
11936 +               gr_learn_attached = 0;
11937 +               up(&gr_learn_user_sem);
11938 +       }
11939 +
11940 +       return 0;
11941 +}
11942 +               
11943 +struct file_operations grsec_fops = {
11944 +       read:           read_learn,
11945 +       write:          write_grsec_handler,
11946 +       open:           open_learn,
11947 +       release:        close_learn,
11948 +       poll:           poll_learn,
11949 +};
11950 diff -uNr linux-2.6.8/grsecurity/gracl_res.c linux-2.6.8.grsecurity/grsecurity/gracl_res.c
11951 --- linux-2.6.8/grsecurity/gracl_res.c  1970-01-01 01:00:00.000000000 +0100
11952 +++ linux-2.6.8.grsecurity/grsecurity/gracl_res.c       2004-08-16 17:08:29.000000000 +0200
11953 @@ -0,0 +1,50 @@
11954 +/* resource handling routines (c) Brad Spengler 2002, 2003 */
11955 +
11956 +#include <linux/kernel.h>
11957 +#include <linux/sched.h>
11958 +#include <linux/gracl.h>
11959 +#include <linux/grinternal.h>
11960 +
11961 +static const char *restab_log[11] = {
11962 +       "RLIMIT_CPU",
11963 +       "RLIMIT_FSIZE",
11964 +       "RLIMIT_DATA",
11965 +       "RLIMIT_STACK",
11966 +       "RLIMIT_CORE",
11967 +       "RLIMIT_RSS",
11968 +       "RLIMIT_NPROC",
11969 +       "RLIMIT_NOFILE",
11970 +       "RLIMIT_MEMLOCK",
11971 +       "RLIMIT_AS",
11972 +       "RLIMIT_LOCKS"
11973 +};
11974 +
11975 +__inline__ void
11976 +gr_log_resource(const struct task_struct *task,
11977 +               const int res, const unsigned long wanted, const int gt)
11978 +{
11979 +       if (unlikely(res == RLIMIT_NPROC && 
11980 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
11981 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
11982 +               return;
11983 +
11984 +       preempt_disable();
11985 +
11986 +       if (unlikely(((gt && wanted > task->rlim[res].rlim_cur) ||
11987 +                     (!gt && wanted >= task->rlim[res].rlim_cur)) &&
11988 +                    task->rlim[res].rlim_cur != RLIM_INFINITY))
11989 +               security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
11990 +                              task->rlim[res].rlim_cur,
11991 +                              gr_task_fullpath(task), task->comm,
11992 +                              task->pid, task->uid, task->euid,
11993 +                              task->gid, task->egid,
11994 +                              gr_parent_task_fullpath(task),
11995 +                              task->parent->comm,
11996 +                              task->parent->pid, task->parent->uid, 
11997 +                              task->parent->euid, task->parent->gid,
11998 +                              task->parent->egid);
11999 +
12000 +       preempt_enable_no_resched();
12001 +
12002 +       return;
12003 +}
12004 diff -uNr linux-2.6.8/grsecurity/gracl_segv.c linux-2.6.8.grsecurity/grsecurity/gracl_segv.c
12005 --- linux-2.6.8/grsecurity/gracl_segv.c 1970-01-01 01:00:00.000000000 +0100
12006 +++ linux-2.6.8.grsecurity/grsecurity/gracl_segv.c      2004-08-16 17:08:29.000000000 +0200
12007 @@ -0,0 +1,330 @@
12008 +/* 
12009 + * grsecurity/gracl_segv.c
12010 + * Copyright Brad Spengler 2002, 2003
12011 + *
12012 + */
12013 +
12014 +#include <linux/kernel.h>
12015 +#include <linux/mm.h>
12016 +#include <asm/uaccess.h>
12017 +#include <asm/errno.h>
12018 +#include <asm/mman.h>
12019 +#include <net/sock.h>
12020 +#include <linux/file.h>
12021 +#include <linux/fs.h>
12022 +#include <linux/net.h>
12023 +#include <linux/in.h>
12024 +#include <linux/smp_lock.h>
12025 +#include <linux/slab.h>
12026 +#include <linux/types.h>
12027 +#include <linux/sched.h>
12028 +#include <linux/timer.h>
12029 +#include <linux/gracl.h>
12030 +#include <linux/grsecurity.h>
12031 +#include <linux/grinternal.h>
12032 +
12033 +static struct crash_uid *uid_set;
12034 +static unsigned short uid_used;
12035 +static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
12036 +extern rwlock_t gr_inode_lock;
12037 +extern struct acl_subject_label *
12038 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
12039 +                             struct acl_role_label *role);
12040 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
12041 +
12042 +int
12043 +gr_init_uidset(void)
12044 +{
12045 +       uid_set =
12046 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
12047 +       uid_used = 0;
12048 +
12049 +       return uid_set ? 1 : 0;
12050 +}
12051 +
12052 +void
12053 +gr_free_uidset(void)
12054 +{
12055 +       if (uid_set)
12056 +               kfree(uid_set);
12057 +
12058 +       return;
12059 +}
12060 +
12061 +int
12062 +gr_find_uid(const uid_t uid)
12063 +{
12064 +       struct crash_uid *tmp = uid_set;
12065 +       uid_t buid;
12066 +       int low = 0, high = uid_used - 1, mid;
12067 +
12068 +       while (high >= low) {
12069 +               mid = (low + high) >> 1;
12070 +               buid = tmp[mid].uid;
12071 +               if (buid == uid)
12072 +                       return mid;
12073 +               if (buid > uid)
12074 +                       high = mid - 1;
12075 +               if (buid < uid)
12076 +                       low = mid + 1;
12077 +       }
12078 +
12079 +       return -1;
12080 +}
12081 +
12082 +static __inline__ void
12083 +gr_insertsort(void)
12084 +{
12085 +       unsigned short i, j;
12086 +       struct crash_uid index;
12087 +
12088 +       for (i = 1; i < uid_used; i++) {
12089 +               index = uid_set[i];
12090 +               j = i;
12091 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
12092 +                       uid_set[j] = uid_set[j - 1];
12093 +                       j--;
12094 +               }
12095 +               uid_set[j] = index;
12096 +       }
12097 +
12098 +       return;
12099 +}
12100 +
12101 +static __inline__ void
12102 +gr_insert_uid(const uid_t uid, const unsigned long expires)
12103 +{
12104 +       int loc;
12105 +
12106 +       if (uid_used == GR_UIDTABLE_MAX)
12107 +               return;
12108 +
12109 +       loc = gr_find_uid(uid);
12110 +
12111 +       if (loc >= 0) {
12112 +               uid_set[loc].expires = expires;
12113 +               return;
12114 +       }
12115 +
12116 +       uid_set[uid_used].uid = uid;
12117 +       uid_set[uid_used].expires = expires;
12118 +       uid_used++;
12119 +
12120 +       gr_insertsort();
12121 +
12122 +       return;
12123 +}
12124 +
12125 +void
12126 +gr_remove_uid(const unsigned short loc)
12127 +{
12128 +       unsigned short i;
12129 +
12130 +       for (i = loc + 1; i < uid_used; i++)
12131 +               uid_set[i - i] = uid_set[i];
12132 +
12133 +       uid_used--;
12134 +
12135 +       return;
12136 +}
12137 +
12138 +int
12139 +gr_check_crash_uid(const uid_t uid)
12140 +{
12141 +       int loc;
12142 +
12143 +       if (unlikely(!gr_acl_is_enabled()))
12144 +               return 0;
12145 +
12146 +       read_lock(&gr_uid_lock);
12147 +       loc = gr_find_uid(uid);
12148 +       read_unlock(&gr_uid_lock);
12149 +
12150 +       if (loc < 0)
12151 +               return 0;
12152 +
12153 +       write_lock(&gr_uid_lock);
12154 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
12155 +               gr_remove_uid(loc);
12156 +       else {
12157 +               write_unlock(&gr_uid_lock);
12158 +               return 1;
12159 +       }
12160 +
12161 +       write_unlock(&gr_uid_lock);
12162 +       return 0;
12163 +}
12164 +
12165 +static __inline__ int
12166 +proc_is_setxid(const struct task_struct *task)
12167 +{
12168 +       if (task->uid != task->euid || task->uid != task->suid ||
12169 +           task->uid != task->fsuid)
12170 +               return 1;
12171 +       if (task->gid != task->egid || task->gid != task->sgid ||
12172 +           task->gid != task->fsgid)
12173 +               return 1;
12174 +
12175 +       return 0;
12176 +}
12177 +static __inline__ int
12178 +gr_fake_force_sig(int sig, struct task_struct *t)
12179 +{
12180 +       unsigned long int flags;
12181 +       int ret;
12182 +
12183 +       spin_lock_irqsave(&t->sighand->siglock, flags);
12184 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
12185 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
12186 +               sigdelset(&t->blocked, sig);
12187 +               recalc_sigpending_tsk(t);
12188 +       }
12189 +       ret = specific_send_sig_info(sig, (void*)1L, t);
12190 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
12191 +
12192 +       return ret;
12193 +}
12194 +
12195 +void
12196 +gr_handle_crash(struct task_struct *task, const int sig)
12197 +{
12198 +       struct acl_subject_label *curr;
12199 +       struct acl_subject_label *curr2;
12200 +       struct task_struct *tsk, *tsk2;
12201 +
12202 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
12203 +               return;
12204 +
12205 +       if (unlikely(!gr_acl_is_enabled()))
12206 +               return;
12207 +
12208 +       curr = task->acl;
12209 +
12210 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
12211 +               return;
12212 +
12213 +       if (time_before_eq(curr->expires, get_seconds())) {
12214 +               curr->expires = 0;
12215 +               curr->crashes = 0;
12216 +       }
12217 +
12218 +       curr->crashes++;
12219 +
12220 +       if (!curr->expires)
12221 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
12222 +
12223 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
12224 +           time_after(curr->expires, get_seconds())) {
12225 +               if (task->uid && proc_is_setxid(task)) {
12226 +                       security_alert(GR_SEGVSTART_ACL_MSG,
12227 +                                      gr_task_fullpath(task), task->comm,
12228 +                                      task->pid, task->uid, task->euid,
12229 +                                      task->gid, task->egid,
12230 +                                      gr_parent_task_fullpath(task),
12231 +                                      task->parent->comm, task->parent->pid,
12232 +                                      task->parent->uid, task->parent->euid,
12233 +                                      task->parent->gid, task->parent->egid,
12234 +                                      task->uid,
12235 +                                      curr->res[GR_CRASH_RES].rlim_max);
12236 +                       write_lock(&gr_uid_lock);
12237 +                       gr_insert_uid(task->uid, curr->expires);
12238 +                       write_unlock(&gr_uid_lock);
12239 +                       curr->expires = 0;
12240 +                       curr->crashes = 0;
12241 +                       read_lock(&tasklist_lock);
12242 +                       for_each_process(tsk) {
12243 +                               tsk2 = tsk;
12244 +                               do {
12245 +                                       if (tsk2 != task && tsk2->uid == task->uid)
12246 +                                       gr_fake_force_sig(SIGKILL, tsk2);
12247 +                               } while ((tsk2 = next_thread(tsk2)) != tsk);
12248 +                       }
12249 +                       read_unlock(&tasklist_lock);
12250 +               } else {
12251 +                       security_alert(GR_SEGVNOSUID_ACL_MSG,
12252 +                                      gr_task_fullpath(task), task->comm,
12253 +                                      task->pid, task->uid, task->euid,
12254 +                                      task->gid, task->egid,
12255 +                                      gr_parent_task_fullpath(task),
12256 +                                      task->parent->comm, task->parent->pid,
12257 +                                      task->parent->uid, task->parent->euid,
12258 +                                      task->parent->gid, task->parent->egid,
12259 +                                      curr->res[GR_CRASH_RES].rlim_max);
12260 +                       read_lock(&tasklist_lock);
12261 +                       for_each_process(tsk) {
12262 +                               tsk2 = tsk;
12263 +                               do {
12264 +                                       if (likely(tsk2 != task)) {
12265 +                                               curr2 = tsk2->acl;
12266 +
12267 +                                               if (curr2->device == curr->device &&
12268 +                                                   curr2->inode == curr->inode)
12269 +                                                       gr_fake_force_sig(SIGKILL, tsk2);
12270 +                                       }
12271 +                               } while ((tsk2 = next_thread(tsk2)) != tsk);
12272 +                       }
12273 +                       read_unlock(&tasklist_lock);
12274 +               }
12275 +       }
12276 +
12277 +       return;
12278 +}
12279 +
12280 +int
12281 +gr_check_crash_exec(const struct file *filp)
12282 +{
12283 +       struct acl_subject_label *curr;
12284 +
12285 +       if (unlikely(!gr_acl_is_enabled()))
12286 +               return 0;
12287 +
12288 +       read_lock(&gr_inode_lock);
12289 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
12290 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
12291 +                                    current->role);
12292 +       read_unlock(&gr_inode_lock);
12293 +
12294 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
12295 +           (!curr->crashes && !curr->expires))
12296 +               return 0;
12297 +
12298 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
12299 +           time_after(curr->expires, get_seconds()))
12300 +               return 1;
12301 +       else if (time_before_eq(curr->expires, get_seconds())) {
12302 +               curr->crashes = 0;
12303 +               curr->expires = 0;
12304 +       }
12305 +
12306 +       return 0;
12307 +}
12308 +
12309 +void
12310 +gr_handle_alertkill(void)
12311 +{
12312 +       struct acl_subject_label *curracl;
12313 +       __u32 curr_ip;
12314 +       struct task_struct *task, *task2;
12315 +
12316 +       if (unlikely(!gr_acl_is_enabled()))
12317 +               return;
12318 +
12319 +       curracl = current->acl;
12320 +       curr_ip = current->curr_ip;
12321 +
12322 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
12323 +           (curr_ip != 0xffffffff)) {
12324 +               read_lock(&tasklist_lock);
12325 +               for_each_process(task) {
12326 +                       task2 = task;
12327 +                       do {
12328 +                               if (task2->curr_ip == curr_ip)
12329 +                                       gr_fake_force_sig(SIGKILL, task2);
12330 +                       } while ((task2 = next_thread(task2)) != task);
12331 +               }
12332 +               read_unlock(&tasklist_lock);
12333 +       } else if (curracl->mode & GR_KILLPROC)
12334 +               gr_fake_force_sig(SIGKILL, current);
12335 +
12336 +       return;
12337 +}
12338 diff -uNr linux-2.6.8/grsecurity/gracl_shm.c linux-2.6.8.grsecurity/grsecurity/gracl_shm.c
12339 --- linux-2.6.8/grsecurity/gracl_shm.c  1970-01-01 01:00:00.000000000 +0100
12340 +++ linux-2.6.8.grsecurity/grsecurity/gracl_shm.c       2004-08-16 17:08:29.000000000 +0200
12341 @@ -0,0 +1,36 @@
12342 +/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
12343 +
12344 +#include <linux/kernel.h>
12345 +#include <linux/mm.h>
12346 +#include <linux/sched.h>
12347 +#include <linux/file.h>
12348 +#include <linux/ipc.h>
12349 +#include <linux/gracl.h>
12350 +#include <linux/grsecurity.h>
12351 +#include <linux/grinternal.h>
12352 +
12353 +int
12354 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12355 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
12356 +{
12357 +       struct task_struct *task;
12358 +
12359 +       if (!gr_acl_is_enabled())
12360 +               return 1;
12361 +
12362 +       task = find_task_by_pid(shm_cprid);
12363 +
12364 +       if (unlikely(!task))
12365 +               task = find_task_by_pid(shm_lapid);
12366 +
12367 +       if (unlikely(task && ((task->start_time < shm_createtime) ||
12368 +                             (task->pid == shm_lapid)) &&
12369 +                    (task->acl->mode & GR_PROTSHM) &&
12370 +                    (task->acl != current->acl))) {
12371 +               security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
12372 +                              DEFAULTSECARGS);
12373 +               return 0;
12374 +       }
12375 +
12376 +       return 1;
12377 +}
12378 diff -uNr linux-2.6.8/grsecurity/grsec_chdir.c linux-2.6.8.grsecurity/grsecurity/grsec_chdir.c
12379 --- linux-2.6.8/grsecurity/grsec_chdir.c        1970-01-01 01:00:00.000000000 +0100
12380 +++ linux-2.6.8.grsecurity/grsecurity/grsec_chdir.c     2004-08-16 17:08:29.000000000 +0200
12381 @@ -0,0 +1,20 @@
12382 +#include <linux/kernel.h>
12383 +#include <linux/sched.h>
12384 +#include <linux/fs.h>
12385 +#include <linux/file.h>
12386 +#include <linux/grsecurity.h>
12387 +#include <linux/grinternal.h>
12388 +
12389 +void
12390 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
12391 +{
12392 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
12393 +       if ((grsec_enable_chdir && grsec_enable_group &&
12394 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
12395 +                                             !grsec_enable_group)) {
12396 +               security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
12397 +                              DEFAULTSECARGS);
12398 +       }
12399 +#endif
12400 +       return;
12401 +}
12402 diff -uNr linux-2.6.8/grsecurity/grsec_chroot.c linux-2.6.8.grsecurity/grsecurity/grsec_chroot.c
12403 --- linux-2.6.8/grsecurity/grsec_chroot.c       1970-01-01 01:00:00.000000000 +0100
12404 +++ linux-2.6.8.grsecurity/grsecurity/grsec_chroot.c    2004-08-16 17:08:29.000000000 +0200
12405 @@ -0,0 +1,362 @@
12406 +#include <linux/kernel.h>
12407 +#include <linux/module.h>
12408 +#include <linux/sched.h>
12409 +#include <linux/file.h>
12410 +#include <linux/fs.h>
12411 +#include <linux/mount.h>
12412 +#include <linux/types.h>
12413 +#include <linux/grinternal.h>
12414 +
12415 +int
12416 +gr_handle_chroot_unix(const pid_t pid)
12417 +{
12418 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
12419 +       struct pid *spid = NULL;
12420 +
12421 +       if (unlikely(!grsec_enable_chroot_unix))
12422 +               return 1;
12423 +
12424 +       if (likely(!proc_is_chrooted(current)))
12425 +               return 1;
12426 +
12427 +       read_lock(&tasklist_lock);
12428 +
12429 +       spid = find_pid(PIDTYPE_PID, pid);
12430 +       if (spid) {
12431 +               struct task_struct *p;
12432 +               p = pid_task(spid->task_list.next, PIDTYPE_PID);
12433 +               task_lock(p);
12434 +               if (unlikely(!have_same_root(current, p))) {
12435 +                       task_unlock(p);
12436 +                       read_unlock(&tasklist_lock);
12437 +                       security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
12438 +                       return 0;
12439 +               }
12440 +               task_unlock(p);
12441 +       }
12442 +       read_unlock(&tasklist_lock);
12443 +#endif
12444 +       return 1;
12445 +}
12446 +
12447 +int
12448 +gr_handle_chroot_nice(void)
12449 +{
12450 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12451 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
12452 +               security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
12453 +               return -EPERM;
12454 +       }
12455 +#endif
12456 +       return 0;
12457 +}
12458 +
12459 +int
12460 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
12461 +{
12462 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12463 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
12464 +                       && proc_is_chrooted(current)) {
12465 +               security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
12466 +                              DEFAULTSECARGS);
12467 +               return -EACCES;
12468 +       }
12469 +#endif
12470 +       return 0;
12471 +}
12472 +
12473 +int
12474 +gr_handle_chroot_capset(struct task_struct *target)
12475 +{
12476 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12477 +       if (!grsec_enable_chroot_caps || !proc_is_chrooted(current))
12478 +               return 0;
12479 +
12480 +       task_lock(target);
12481 +       if (!have_same_root(current, target)) {
12482 +               task_unlock(target);
12483 +               security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
12484 +                              DEFAULTSECARGS);
12485 +               return 1;
12486 +       }
12487 +       task_unlock(target);
12488 +#endif
12489 +       return 0;
12490 +}
12491 +
12492 +int
12493 +gr_handle_chroot_rawio(const struct inode *inode)
12494 +{
12495 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12496 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
12497 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
12498 +               return 1;
12499 +#endif
12500 +       return 0;
12501 +}
12502 +
12503 +int
12504 +gr_pid_is_chrooted(struct task_struct *p)
12505 +{
12506 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
12507 +       if (!grsec_enable_chroot_findtask || !current->fs || 
12508 +           !proc_is_chrooted(current) || !p)
12509 +               return 0;
12510 +
12511 +       task_lock(p);
12512 +       if (p->fs && !have_same_root(current, p)) {
12513 +               task_unlock(p);
12514 +               return 1;
12515 +       }
12516 +       task_unlock(p);
12517 +#endif
12518 +       return 0;
12519 +}
12520 +
12521 +EXPORT_SYMBOL(gr_pid_is_chrooted);
12522 +
12523 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
12524 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
12525 +{
12526 +       struct dentry *dentry = (struct dentry *)u_dentry;
12527 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
12528 +       struct dentry *realroot;
12529 +       struct vfsmount *realrootmnt;
12530 +       struct dentry *currentroot;
12531 +       struct vfsmount *currentmnt;
12532 +
12533 +       read_lock(&child_reaper->fs->lock);
12534 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
12535 +       realroot = dget(child_reaper->fs->root);
12536 +       read_unlock(&child_reaper->fs->lock);
12537 +
12538 +       read_lock(&current->fs->lock);
12539 +       currentmnt = mntget(current->fs->rootmnt);
12540 +       currentroot = dget(current->fs->root);
12541 +       read_unlock(&current->fs->lock);
12542 +
12543 +       spin_lock(&dcache_lock);
12544 +       for (;;) {
12545 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
12546 +                    || (dentry == currentroot && mnt == currentmnt)))
12547 +                       break;
12548 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
12549 +                       if (mnt->mnt_parent == mnt)
12550 +                               break;
12551 +                       dentry = mnt->mnt_mountpoint;
12552 +                       mnt = mnt->mnt_parent;
12553 +                       continue;
12554 +               }
12555 +               dentry = dentry->d_parent;
12556 +       }
12557 +       spin_unlock(&dcache_lock);
12558 +
12559 +       dput(currentroot);
12560 +       mntput(currentmnt);
12561 +
12562 +       if (dentry == realroot && mnt == realrootmnt) {
12563 +               /* access is outside of chroot */
12564 +               dput(realroot);
12565 +               mntput(realrootmnt);
12566 +               return 0;
12567 +       }
12568 +
12569 +       dput(realroot);
12570 +       mntput(realrootmnt);
12571 +       return 1;
12572 +}
12573 +#endif
12574 +
12575 +int
12576 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
12577 +{
12578 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
12579 +       if (!grsec_enable_chroot_fchdir)
12580 +               return 1;
12581 +
12582 +       if (!proc_is_chrooted(current))
12583 +               return 1;
12584 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
12585 +               security_alert(GR_CHROOT_FCHDIR_MSG,
12586 +                              gr_to_filename(u_dentry, u_mnt),
12587 +                              DEFAULTSECARGS);
12588 +               return 0;
12589 +       }
12590 +#endif
12591 +       return 1;
12592 +}
12593 +
12594 +int
12595 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12596 +               const time_t shm_createtime)
12597 +{
12598 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
12599 +       struct pid *pid = NULL;
12600 +       u64 starttime64;
12601 +       time_t starttime;
12602 +
12603 +       if (unlikely(!grsec_enable_chroot_shmat))
12604 +               return 1;
12605 +
12606 +       if (likely(!proc_is_chrooted(current)))
12607 +               return 1;
12608 +
12609 +       read_lock(&tasklist_lock);
12610 +
12611 +       pid = find_pid(PIDTYPE_PID, shm_cprid);
12612 +       if (pid) {
12613 +               struct task_struct *p;
12614 +               p = pid_task(pid->task_list.next, PIDTYPE_PID);
12615 +               task_lock(p);
12616 +               starttime64 = p->start_time;
12617 +               do_div(starttime64, HZ);
12618 +               starttime = (time_t) starttime64;
12619 +               if (unlikely(!have_same_root(current, p) &&
12620 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
12621 +                       task_unlock(p);
12622 +                       read_unlock(&tasklist_lock);
12623 +                       security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12624 +                       return 0;
12625 +               }
12626 +               task_unlock(p);
12627 +       } else {
12628 +               pid = find_pid(PIDTYPE_PID, shm_lapid);
12629 +               if (pid) {
12630 +                       struct task_struct *p;
12631 +                       p = pid_task(pid->task_list.next, PIDTYPE_PID);
12632 +                       task_lock(p);
12633 +                       if (unlikely(!have_same_root(current, p))) {
12634 +                               task_unlock(p);
12635 +                               read_unlock(&tasklist_lock);
12636 +                               security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
12637 +                               return 0;
12638 +                       }
12639 +                       task_unlock(p);
12640 +               }
12641 +       }
12642 +
12643 +       read_unlock(&tasklist_lock);
12644 +#endif
12645 +       return 1;
12646 +}
12647 +
12648 +void
12649 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12650 +{
12651 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
12652 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
12653 +               security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
12654 +                              DEFAULTSECARGS);
12655 +#endif
12656 +       return;
12657 +}
12658 +
12659 +int
12660 +gr_handle_chroot_mknod(const struct dentry *dentry,
12661 +                      const struct vfsmount *mnt, const int mode)
12662 +{
12663 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
12664 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
12665 +           proc_is_chrooted(current)) {
12666 +               security_alert(GR_MKNOD_CHROOT_MSG,
12667 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12668 +               return -EPERM;
12669 +       }
12670 +#endif
12671 +       return 0;
12672 +}
12673 +
12674 +int
12675 +gr_handle_chroot_mount(const struct dentry *dentry,
12676 +                      const struct vfsmount *mnt, const char *dev_name)
12677 +{
12678 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
12679 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
12680 +               security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
12681 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12682 +               return -EPERM;
12683 +       }
12684 +#endif
12685 +       return 0;
12686 +}
12687 +
12688 +int
12689 +gr_handle_chroot_pivot(void)
12690 +{
12691 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
12692 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
12693 +               security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
12694 +               return -EPERM;
12695 +       }
12696 +#endif
12697 +       return 0;
12698 +}
12699 +
12700 +int
12701 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
12702 +{
12703 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
12704 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
12705 +           !gr_is_outside_chroot(dentry, mnt)) {
12706 +               security_alert(GR_CHROOT_CHROOT_MSG,
12707 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12708 +               return -EPERM;
12709 +       }
12710 +#endif
12711 +       return 0;
12712 +}
12713 +
12714 +void
12715 +gr_handle_chroot_caps(struct task_struct *task)
12716 +{
12717 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12718 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
12719 +               task->cap_permitted =
12720 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
12721 +               task->cap_inheritable =
12722 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
12723 +               task->cap_effective =
12724 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
12725 +       }
12726 +#endif
12727 +       return;
12728 +}
12729 +
12730 +EXPORT_SYMBOL(gr_handle_chroot_caps);
12731 +
12732 +int
12733 +gr_handle_chroot_sysctl(const int op)
12734 +{
12735 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
12736 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
12737 +           && (op & 002))
12738 +               return -EACCES;
12739 +#endif
12740 +       return 0;
12741 +}
12742 +
12743 +void
12744 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
12745 +{
12746 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
12747 +       if (grsec_enable_chroot_chdir)
12748 +               set_fs_pwd(current->fs, mnt, dentry);
12749 +#endif
12750 +       return;
12751 +}
12752 +
12753 +int
12754 +gr_handle_chroot_chmod(const struct dentry *dentry,
12755 +                      const struct vfsmount *mnt, const int mode)
12756 +{
12757 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
12758 +       if (grsec_enable_chroot_chmod &&
12759 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
12760 +           proc_is_chrooted(current)) {
12761 +               security_alert(GR_CHMOD_CHROOT_MSG,
12762 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
12763 +               return -EPERM;
12764 +       }
12765 +#endif
12766 +       return 0;
12767 +}
12768 diff -uNr linux-2.6.8/grsecurity/grsec_disabled.c linux-2.6.8.grsecurity/grsecurity/grsec_disabled.c
12769 --- linux-2.6.8/grsecurity/grsec_disabled.c     1970-01-01 01:00:00.000000000 +0100
12770 +++ linux-2.6.8.grsecurity/grsecurity/grsec_disabled.c  2004-08-16 17:08:29.000000000 +0200
12771 @@ -0,0 +1,415 @@
12772 +/* 
12773 + * when grsecurity is disabled, compile all external functions into nothing
12774 + */
12775 +
12776 +#include <linux/kernel.h>
12777 +#include <linux/module.h>
12778 +#include <linux/config.h>
12779 +#include <linux/sched.h>
12780 +#include <linux/file.h>
12781 +#include <linux/fs.h>
12782 +#include <linux/kdev_t.h>
12783 +#include <linux/net.h>
12784 +#include <linux/in.h>
12785 +#include <linux/ip.h>
12786 +#include <linux/skbuff.h>
12787 +#include <linux/sysctl.h>
12788 +
12789 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
12790 +__inline__ void
12791 +pax_set_flags(struct linux_binprm *bprm)
12792 +{
12793 +       return;
12794 +}
12795 +#endif
12796 +
12797 +#ifdef CONFIG_SYSCTL
12798 +__inline__ __u32
12799 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
12800 +{
12801 +       return mode;
12802 +}
12803 +#endif
12804 +
12805 +__inline__ int
12806 +gr_acl_is_enabled(void)
12807 +{
12808 +       return 0;
12809 +}
12810 +
12811 +__inline__ int
12812 +gr_handle_rawio(const struct inode *inode)
12813 +{
12814 +       return 0;
12815 +}
12816 +
12817 +__inline__ void
12818 +gr_acl_handle_psacct(struct task_struct *task, const long code)
12819 +{
12820 +       return;
12821 +}
12822 +
12823 +__inline__ int
12824 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
12825 +{
12826 +       return 0;
12827 +}
12828 +
12829 +__inline__ int
12830 +gr_handle_ptrace(struct task_struct *task, const long request)
12831 +{
12832 +       return 0;
12833 +}
12834 +
12835 +__inline__ int
12836 +gr_handle_proc_ptrace(struct task_struct *task)
12837 +{
12838 +       return 0;
12839 +}
12840 +
12841 +__inline__ void
12842 +gr_learn_resource(const struct task_struct *task,
12843 +                 const int res, const unsigned long wanted, const int gt)
12844 +{
12845 +       return;
12846 +}
12847 +
12848 +__inline__ int
12849 +gr_set_acls(const int type)
12850 +{
12851 +       return 0;
12852 +}
12853 +
12854 +__inline__ int
12855 +gr_check_hidden_task(const struct task_struct *tsk)
12856 +{
12857 +       return 0;
12858 +}
12859 +
12860 +__inline__ int
12861 +gr_check_protected_task(const struct task_struct *task)
12862 +{
12863 +       return 0;
12864 +}
12865 +
12866 +__inline__ void
12867 +gr_copy_label(struct task_struct *tsk)
12868 +{
12869 +       return;
12870 +}
12871 +
12872 +__inline__ void
12873 +gr_set_pax_flags(struct task_struct *task)
12874 +{
12875 +       return;
12876 +}
12877 +
12878 +__inline__ int
12879 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
12880 +{
12881 +       return 0;
12882 +}
12883 +
12884 +__inline__ void
12885 +gr_handle_delete(const ino_t ino, const dev_t dev)
12886 +{
12887 +       return;
12888 +}
12889 +
12890 +__inline__ void
12891 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
12892 +{
12893 +       return;
12894 +}
12895 +
12896 +__inline__ void
12897 +gr_handle_crash(struct task_struct *task, const int sig)
12898 +{
12899 +       return;
12900 +}
12901 +
12902 +__inline__ int
12903 +gr_check_crash_exec(const struct file *filp)
12904 +{
12905 +       return 0;
12906 +}
12907 +
12908 +__inline__ int
12909 +gr_check_crash_uid(const uid_t uid)
12910 +{
12911 +       return 0;
12912 +}
12913 +
12914 +__inline__ void
12915 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
12916 +                struct dentry *old_dentry,
12917 +                struct dentry *new_dentry,
12918 +                struct vfsmount *mnt, const __u8 replace)
12919 +{
12920 +       return;
12921 +}
12922 +
12923 +__inline__ int
12924 +gr_search_socket(const int family, const int type, const int protocol)
12925 +{
12926 +       return 1;
12927 +}
12928 +
12929 +__inline__ int
12930 +gr_search_connectbind(const int mode, const struct socket *sock,
12931 +                     const struct sockaddr_in *addr)
12932 +{
12933 +       return 1;
12934 +}
12935 +
12936 +__inline__ int
12937 +gr_task_is_capable(struct task_struct *task, const int cap)
12938 +{
12939 +       return 1;
12940 +}
12941 +
12942 +__inline__ int
12943 +gr_is_capable_nolog(const int cap)
12944 +{
12945 +       return 1;
12946 +}
12947 +
12948 +__inline__ void
12949 +gr_handle_alertkill(void)
12950 +{
12951 +       return;
12952 +}
12953 +
12954 +__inline__ __u32
12955 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
12956 +{
12957 +       return 1;
12958 +}
12959 +
12960 +__inline__ __u32
12961 +gr_acl_handle_hidden_file(const struct dentry * dentry,
12962 +                         const struct vfsmount * mnt)
12963 +{
12964 +       return 1;
12965 +}
12966 +
12967 +__inline__ __u32
12968 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12969 +                  const int fmode)
12970 +{
12971 +       return 1;
12972 +}
12973 +
12974 +__inline__ __u32
12975 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
12976 +{
12977 +       return 1;
12978 +}
12979 +
12980 +__inline__ __u32
12981 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
12982 +{
12983 +       return 1;
12984 +}
12985 +
12986 +__inline__ int
12987 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
12988 +                  unsigned int *vm_flags)
12989 +{
12990 +       return 1;
12991 +}
12992 +
12993 +__inline__ __u32
12994 +gr_acl_handle_truncate(const struct dentry * dentry,
12995 +                      const struct vfsmount * mnt)
12996 +{
12997 +       return 1;
12998 +}
12999 +
13000 +__inline__ __u32
13001 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
13002 +{
13003 +       return 1;
13004 +}
13005 +
13006 +__inline__ __u32
13007 +gr_acl_handle_access(const struct dentry * dentry,
13008 +                    const struct vfsmount * mnt, const int fmode)
13009 +{
13010 +       return 1;
13011 +}
13012 +
13013 +__inline__ __u32
13014 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
13015 +                    mode_t mode)
13016 +{
13017 +       return 1;
13018 +}
13019 +
13020 +__inline__ __u32
13021 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
13022 +                   mode_t mode)
13023 +{
13024 +       return 1;
13025 +}
13026 +
13027 +__inline__ __u32
13028 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
13029 +{
13030 +       return 1;
13031 +}
13032 +
13033 +__inline__ void
13034 +grsecurity_init(void)
13035 +{
13036 +       return;
13037 +}
13038 +
13039 +__inline__ __u32
13040 +gr_acl_handle_mknod(const struct dentry * new_dentry,
13041 +                   const struct dentry * parent_dentry,
13042 +                   const struct vfsmount * parent_mnt,
13043 +                   const int mode)
13044 +{
13045 +       return 1;
13046 +}
13047 +
13048 +__inline__ __u32
13049 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
13050 +                   const struct dentry * parent_dentry,
13051 +                   const struct vfsmount * parent_mnt)
13052 +{
13053 +       return 1;
13054 +}
13055 +
13056 +__inline__ __u32
13057 +gr_acl_handle_symlink(const struct dentry * new_dentry,
13058 +                     const struct dentry * parent_dentry,
13059 +                     const struct vfsmount * parent_mnt, const char *from)
13060 +{
13061 +       return 1;
13062 +}
13063 +
13064 +__inline__ __u32
13065 +gr_acl_handle_link(const struct dentry * new_dentry,
13066 +                  const struct dentry * parent_dentry,
13067 +                  const struct vfsmount * parent_mnt,
13068 +                  const struct dentry * old_dentry,
13069 +                  const struct vfsmount * old_mnt, const char *to)
13070 +{
13071 +       return 1;
13072 +}
13073 +
13074 +__inline__ int
13075 +gr_acl_handle_rename(const struct dentry *new_dentry,
13076 +                    const struct dentry *parent_dentry,
13077 +                    const struct vfsmount *parent_mnt,
13078 +                    const struct dentry *old_dentry,
13079 +                    const struct inode *old_parent_inode,
13080 +                    const struct vfsmount *old_mnt, const char *newname)
13081 +{
13082 +       return 0;
13083 +}
13084 +
13085 +__inline__ __u32
13086 +gr_acl_handle_filldir(const struct dentry * dentry,
13087 +                     const struct vfsmount * mnt, const ino_t ino)
13088 +{
13089 +       return 1;
13090 +}
13091 +
13092 +__inline__ int
13093 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
13094 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
13095 +{
13096 +       return 1;
13097 +}
13098 +
13099 +__inline__ int
13100 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
13101 +{
13102 +       return 1;
13103 +}
13104 +
13105 +__inline__ int
13106 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
13107 +{
13108 +       return 1;
13109 +}
13110 +
13111 +__inline__ __u32
13112 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
13113 +{
13114 +       return 1;
13115 +}
13116 +
13117 +__inline__ __u32
13118 +gr_acl_handle_creat(const struct dentry * dentry,
13119 +                   const struct dentry * p_dentry,
13120 +                   const struct vfsmount * p_mnt, const int fmode,
13121 +                   const int imode)
13122 +{
13123 +       return 1;
13124 +}
13125 +
13126 +__inline__ void
13127 +gr_acl_handle_exit(void)
13128 +{
13129 +       return;
13130 +}
13131 +
13132 +__inline__ int
13133 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
13134 +{
13135 +       return 1;
13136 +}
13137 +
13138 +__inline__ void
13139 +gr_set_role_label(const uid_t uid, const gid_t gid)
13140 +{
13141 +       return;
13142 +}
13143 +
13144 +__inline__ int
13145 +gr_acl_handle_procpidmem(const struct task_struct *task)
13146 +{
13147 +       return 0;
13148 +}
13149 +
13150 +__inline__ int
13151 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
13152 +{
13153 +       return 1;
13154 +}
13155 +
13156 +__inline__ int
13157 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
13158 +{
13159 +       return 1;
13160 +}
13161 +
13162 +__inline__ void
13163 +gr_set_kernel_label(struct task_struct *task)
13164 +{
13165 +       return;
13166 +}
13167 +
13168 +__inline__ int
13169 +gr_check_user_change(int real, int effective, int fs)
13170 +{
13171 +       return 0;
13172 +}
13173 +
13174 +__inline__ int
13175 +gr_check_group_change(int real, int effective, int fs)
13176 +{
13177 +       return 0;
13178 +}
13179 +
13180 +
13181 +EXPORT_SYMBOL(gr_check_user_change);
13182 +EXPORT_SYMBOL(gr_check_group_change);
13183 +EXPORT_SYMBOL(gr_task_is_capable);
13184 +EXPORT_SYMBOL(gr_learn_resource);
13185 +EXPORT_SYMBOL(gr_set_kernel_label);
13186 +
13187 diff -uNr linux-2.6.8/grsecurity/grsec_exec.c linux-2.6.8.grsecurity/grsecurity/grsec_exec.c
13188 --- linux-2.6.8/grsecurity/grsec_exec.c 1970-01-01 01:00:00.000000000 +0100
13189 +++ linux-2.6.8.grsecurity/grsecurity/grsec_exec.c      2004-08-16 17:08:29.000000000 +0200
13190 @@ -0,0 +1,71 @@
13191 +#include <linux/kernel.h>
13192 +#include <linux/sched.h>
13193 +#include <linux/file.h>
13194 +#include <linux/binfmts.h>
13195 +#include <linux/fs.h>
13196 +#include <linux/types.h>
13197 +#include <linux/grdefs.h>
13198 +#include <linux/grinternal.h>
13199 +#include <linux/capability.h>
13200 +
13201 +#include <asm/uaccess.h>
13202 +
13203 +int
13204 +gr_handle_nproc(void)
13205 +{
13206 +#ifdef CONFIG_GRKERNSEC_EXECVE
13207 +       if (grsec_enable_execve && current->user &&
13208 +           (atomic_read(&current->user->processes) >
13209 +            current->rlim[RLIMIT_NPROC].rlim_cur) &&
13210 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
13211 +               security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
13212 +               return -EAGAIN;
13213 +       }
13214 +#endif
13215 +       return 0;
13216 +}
13217 +
13218 +void
13219 +gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
13220 +{
13221 +#ifdef CONFIG_GRKERNSEC_EXECLOG
13222 +       char grarg[64] = { 0 };
13223 +       __u8 execlen = 0;
13224 +       unsigned int i;
13225 +
13226 +       if (!((grsec_enable_execlog && grsec_enable_group &&
13227 +              in_group_p(grsec_audit_gid))
13228 +             || (grsec_enable_execlog && !grsec_enable_group)))
13229 +               return;
13230 +
13231 +       if (unlikely(!argv))
13232 +               goto log;
13233 +
13234 +       for (i = 0; i < bprm->argc && execlen < 62; i++) {
13235 +               char *p;
13236 +               __u8 len;
13237 +
13238 +               if (get_user(p, argv + i))
13239 +                       goto log;
13240 +               if (!p)
13241 +                       goto log;
13242 +               len = strnlen_user(p, 62 - execlen);
13243 +               if (len > 62 - execlen)
13244 +                       len = 62 - execlen;
13245 +               else if (len > 0)
13246 +                       len--;
13247 +               if (copy_from_user(grarg + execlen, p, len))
13248 +                       goto log;
13249 +               execlen += len;
13250 +               *(grarg + execlen) = ' ';
13251 +               *(grarg + execlen + 1) = '\0';
13252 +               execlen++;
13253 +       }
13254 +
13255 +      log:
13256 +       security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
13257 +                                                        bprm->file->f_vfsmnt),
13258 +                      grarg, DEFAULTSECARGS);
13259 +#endif
13260 +       return;
13261 +}
13262 diff -uNr linux-2.6.8/grsecurity/grsec_fifo.c linux-2.6.8.grsecurity/grsecurity/grsec_fifo.c
13263 --- linux-2.6.8/grsecurity/grsec_fifo.c 1970-01-01 01:00:00.000000000 +0100
13264 +++ linux-2.6.8.grsecurity/grsecurity/grsec_fifo.c      2004-08-16 17:08:29.000000000 +0200
13265 @@ -0,0 +1,24 @@
13266 +#include <linux/kernel.h>
13267 +#include <linux/sched.h>
13268 +#include <linux/fs.h>
13269 +#include <linux/file.h>
13270 +#include <linux/grinternal.h>
13271 +
13272 +int
13273 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
13274 +              const struct dentry *dir, const int flag, const int acc_mode)
13275 +{
13276 +#ifdef CONFIG_GRKERNSEC_FIFO
13277 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
13278 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
13279 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
13280 +           (current->fsuid != dentry->d_inode->i_uid)) {
13281 +               if (!vfs_permission(dentry->d_inode, acc_mode))
13282 +                       security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
13283 +                                      dentry->d_inode->i_uid,
13284 +                                      dentry->d_inode->i_gid, DEFAULTSECARGS);
13285 +               return -EACCES;
13286 +       }
13287 +#endif
13288 +       return 0;
13289 +}
13290 diff -uNr linux-2.6.8/grsecurity/grsec_fork.c linux-2.6.8.grsecurity/grsecurity/grsec_fork.c
13291 --- linux-2.6.8/grsecurity/grsec_fork.c 1970-01-01 01:00:00.000000000 +0100
13292 +++ linux-2.6.8.grsecurity/grsecurity/grsec_fork.c      2004-08-16 17:08:29.000000000 +0200
13293 @@ -0,0 +1,14 @@
13294 +#include <linux/kernel.h>
13295 +#include <linux/sched.h>
13296 +#include <linux/grsecurity.h>
13297 +#include <linux/grinternal.h>
13298 +
13299 +void
13300 +gr_log_forkfail(const int retval)
13301 +{
13302 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
13303 +       if (grsec_enable_forkfail)
13304 +               security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
13305 +#endif
13306 +       return;
13307 +}
13308 diff -uNr linux-2.6.8/grsecurity/grsec_init.c linux-2.6.8.grsecurity/grsecurity/grsec_init.c
13309 --- linux-2.6.8/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100
13310 +++ linux-2.6.8.grsecurity/grsecurity/grsec_init.c      2004-08-16 17:08:29.000000000 +0200
13311 @@ -0,0 +1,225 @@
13312 +#include <linux/kernel.h>
13313 +#include <linux/sched.h>
13314 +#include <linux/mm.h>
13315 +#include <linux/smp_lock.h>
13316 +#include <linux/gracl.h>
13317 +#include <linux/slab.h>
13318 +#include <linux/vmalloc.h>
13319 +#include <linux/percpu.h>
13320 +
13321 +int grsec_enable_link;
13322 +int grsec_enable_dmesg;
13323 +int grsec_enable_fifo;
13324 +int grsec_enable_execve;
13325 +int grsec_enable_execlog;
13326 +int grsec_enable_signal;
13327 +int grsec_enable_forkfail;
13328 +int grsec_enable_time;
13329 +int grsec_enable_audit_textrel;
13330 +int grsec_enable_group;
13331 +int grsec_audit_gid;
13332 +int grsec_enable_chdir;
13333 +int grsec_enable_audit_ipc;
13334 +int grsec_enable_mount;
13335 +int grsec_enable_chroot_findtask;
13336 +int grsec_enable_chroot_mount;
13337 +int grsec_enable_chroot_shmat;
13338 +int grsec_enable_chroot_fchdir;
13339 +int grsec_enable_chroot_double;
13340 +int grsec_enable_chroot_pivot;
13341 +int grsec_enable_chroot_chdir;
13342 +int grsec_enable_chroot_chmod;
13343 +int grsec_enable_chroot_mknod;
13344 +int grsec_enable_chroot_nice;
13345 +int grsec_enable_chroot_execlog;
13346 +int grsec_enable_chroot_caps;
13347 +int grsec_enable_chroot_sysctl;
13348 +int grsec_enable_chroot_unix;
13349 +int grsec_enable_tpe;
13350 +int grsec_tpe_gid;
13351 +int grsec_enable_tpe_all;
13352 +int grsec_enable_randpid;
13353 +int grsec_enable_randid;
13354 +int grsec_enable_randisn;
13355 +int grsec_enable_randsrc;
13356 +int grsec_enable_randrpc;
13357 +int grsec_enable_socket_all;
13358 +int grsec_socket_all_gid;
13359 +int grsec_enable_socket_client;
13360 +int grsec_socket_client_gid;
13361 +int grsec_enable_socket_server;
13362 +int grsec_socket_server_gid;
13363 +int grsec_lock;
13364 +
13365 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
13366 +unsigned long grsec_alert_wtime = 0;
13367 +unsigned long grsec_alert_fyet = 0;
13368 +
13369 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
13370 +
13371 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
13372 +
13373 +char *gr_shared_page[4];
13374 +extern struct gr_arg *gr_usermode;
13375 +extern unsigned char *gr_system_salt;
13376 +extern unsigned char *gr_system_sum;
13377 +extern struct task_struct **gr_conn_table;
13378 +extern const unsigned int gr_conn_table_size;
13379 +
13380 +void
13381 +grsecurity_init(void)
13382 +{
13383 +       int j;
13384 +       /* create the per-cpu shared pages */
13385 +
13386 +       preempt_disable();
13387 +       for (j = 0; j < 4; j++) {
13388 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(char *));
13389 +               if (gr_shared_page[j] == NULL) {
13390 +                       panic("Unable to allocate grsecurity shared page");
13391 +                       return;
13392 +               }
13393 +       }
13394 +       preempt_enable();
13395 +
13396 +       /* create hash tables for ip tagging */
13397 +
13398 +       gr_conn_table = (struct task_struct **) vmalloc(gr_conn_table_size * sizeof(struct task_struct *));
13399 +       if (gr_conn_table == NULL) {
13400 +               panic("Unable to allocate grsecurity IP tagging table");
13401 +               return;
13402 +       }
13403 +       memset(gr_conn_table, 0, gr_conn_table_size * sizeof(struct task_struct *));
13404 +
13405 +       /* allocate memory for authentication structure */
13406 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
13407 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
13408 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
13409 +
13410 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
13411 +               panic("Unable to allocate grsecurity authentication structure");
13412 +               return;
13413 +       }
13414 +
13415 +#ifndef CONFIG_GRKERNSEC_SYSCTL
13416 +       grsec_lock = 1;
13417 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
13418 +       grsec_enable_audit_textrel = 1;
13419 +#endif
13420 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
13421 +       grsec_enable_group = 1;
13422 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
13423 +#endif
13424 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
13425 +       grsec_enable_chdir = 1;
13426 +#endif
13427 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13428 +       grsec_enable_audit_ipc = 1;
13429 +#endif
13430 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13431 +       grsec_enable_mount = 1;
13432 +#endif
13433 +#ifdef CONFIG_GRKERNSEC_LINK
13434 +       grsec_enable_link = 1;
13435 +#endif
13436 +#ifdef CONFIG_GRKERNSEC_DMESG
13437 +       grsec_enable_dmesg = 1;
13438 +#endif
13439 +#ifdef CONFIG_GRKERNSEC_FIFO
13440 +       grsec_enable_fifo = 1;
13441 +#endif
13442 +#ifdef CONFIG_GRKERNSEC_EXECVE
13443 +       grsec_enable_execve = 1;
13444 +#endif
13445 +#ifdef CONFIG_GRKERNSEC_EXECLOG
13446 +       grsec_enable_execlog = 1;
13447 +#endif
13448 +#ifdef CONFIG_GRKERNSEC_SIGNAL
13449 +       grsec_enable_signal = 1;
13450 +#endif
13451 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
13452 +       grsec_enable_forkfail = 1;
13453 +#endif
13454 +#ifdef CONFIG_GRKERNSEC_TIME
13455 +       grsec_enable_time = 1;
13456 +#endif
13457 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
13458 +       grsec_enable_chroot_findtask = 1;
13459 +#endif
13460 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
13461 +       grsec_enable_chroot_unix = 1;
13462 +#endif
13463 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
13464 +       grsec_enable_chroot_mount = 1;
13465 +#endif
13466 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
13467 +       grsec_enable_chroot_fchdir = 1;
13468 +#endif
13469 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
13470 +       grsec_enable_chroot_shmat = 1;
13471 +#endif
13472 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
13473 +       grsec_enable_chroot_double = 1;
13474 +#endif
13475 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
13476 +       grsec_enable_chroot_pivot = 1;
13477 +#endif
13478 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
13479 +       grsec_enable_chroot_chdir = 1;
13480 +#endif
13481 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
13482 +       grsec_enable_chroot_chmod = 1;
13483 +#endif
13484 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
13485 +       grsec_enable_chroot_mknod = 1;
13486 +#endif
13487 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
13488 +       grsec_enable_chroot_nice = 1;
13489 +#endif
13490 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
13491 +       grsec_enable_chroot_execlog = 1;
13492 +#endif
13493 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
13494 +       grsec_enable_chroot_caps = 1;
13495 +#endif
13496 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
13497 +       grsec_enable_chroot_sysctl = 1;
13498 +#endif
13499 +#ifdef CONFIG_GRKERNSEC_TPE
13500 +       grsec_enable_tpe = 1;
13501 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
13502 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
13503 +       grsec_enable_tpe_all = 1;
13504 +#endif
13505 +#endif
13506 +#ifdef CONFIG_GRKERNSEC_RANDPID
13507 +       grsec_enable_randpid = 1;
13508 +#endif
13509 +#ifdef CONFIG_GRKERNSEC_RANDID
13510 +       grsec_enable_randid = 1;
13511 +#endif
13512 +#ifdef CONFIG_GRKERNSEC_RANDISN
13513 +       grsec_enable_randisn = 1;
13514 +#endif
13515 +#ifdef CONFIG_GRKERNSEC_RANDSRC
13516 +       grsec_enable_randsrc = 1;
13517 +#endif
13518 +#ifdef CONFIG_GRKERNSEC_RANDRPC
13519 +       grsec_enable_randrpc = 1;
13520 +#endif
13521 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13522 +       grsec_enable_socket_all = 1;
13523 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
13524 +#endif
13525 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13526 +       grsec_enable_socket_client = 1;
13527 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
13528 +#endif
13529 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13530 +       grsec_enable_socket_server = 1;
13531 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
13532 +#endif
13533 +#endif
13534 +
13535 +       return;
13536 +}
13537 diff -uNr linux-2.6.8/grsecurity/grsec_ipc.c linux-2.6.8.grsecurity/grsecurity/grsec_ipc.c
13538 --- linux-2.6.8/grsecurity/grsec_ipc.c  1970-01-01 01:00:00.000000000 +0100
13539 +++ linux-2.6.8.grsecurity/grsecurity/grsec_ipc.c       2004-08-16 17:08:29.000000000 +0200
13540 @@ -0,0 +1,81 @@
13541 +#include <linux/kernel.h>
13542 +#include <linux/sched.h>
13543 +#include <linux/types.h>
13544 +#include <linux/ipc.h>
13545 +#include <linux/grsecurity.h>
13546 +#include <linux/grinternal.h>
13547 +
13548 +void
13549 +gr_log_msgget(const int ret, const int msgflg)
13550 +{
13551 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13552 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13553 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13554 +                                         !grsec_enable_group)) && (ret >= 0)
13555 +           && (msgflg & IPC_CREAT))
13556 +               security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
13557 +#endif
13558 +       return;
13559 +}
13560 +
13561 +void
13562 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
13563 +{
13564 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13565 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13566 +            grsec_enable_audit_ipc) ||
13567 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13568 +               security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13569 +#endif
13570 +       return;
13571 +}
13572 +
13573 +void
13574 +gr_log_semget(const int err, const int semflg)
13575 +{
13576 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13577 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13578 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13579 +                                         !grsec_enable_group)) && (err >= 0)
13580 +           && (semflg & IPC_CREAT))
13581 +               security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
13582 +#endif
13583 +       return;
13584 +}
13585 +
13586 +void
13587 +gr_log_semrm(const uid_t uid, const uid_t cuid)
13588 +{
13589 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13590 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13591 +            grsec_enable_audit_ipc) ||
13592 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13593 +               security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13594 +#endif
13595 +       return;
13596 +}
13597 +
13598 +void
13599 +gr_log_shmget(const int err, const int shmflg, const size_t size)
13600 +{
13601 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13602 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13603 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
13604 +                                         !grsec_enable_group)) && (err >= 0)
13605 +           && (shmflg & IPC_CREAT))
13606 +               security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
13607 +#endif
13608 +       return;
13609 +}
13610 +
13611 +void
13612 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
13613 +{
13614 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13615 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
13616 +            grsec_enable_audit_ipc) ||
13617 +           (grsec_enable_audit_ipc && !grsec_enable_group))
13618 +               security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
13619 +#endif
13620 +       return;
13621 +}
13622 diff -uNr linux-2.6.8/grsecurity/grsec_link.c linux-2.6.8.grsecurity/grsecurity/grsec_link.c
13623 --- linux-2.6.8/grsecurity/grsec_link.c 1970-01-01 01:00:00.000000000 +0100
13624 +++ linux-2.6.8.grsecurity/grsecurity/grsec_link.c      2004-08-16 17:08:29.000000000 +0200
13625 @@ -0,0 +1,41 @@
13626 +#include <linux/kernel.h>
13627 +#include <linux/sched.h>
13628 +#include <linux/fs.h>
13629 +#include <linux/file.h>
13630 +#include <linux/grinternal.h>
13631 +
13632 +int
13633 +gr_handle_follow_link(const struct inode *parent,
13634 +                     const struct inode *inode,
13635 +                     const struct dentry *dentry, const struct vfsmount *mnt)
13636 +{
13637 +#ifdef CONFIG_GRKERNSEC_LINK
13638 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
13639 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
13640 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
13641 +               security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
13642 +                              inode->i_uid, inode->i_gid, DEFAULTSECARGS);
13643 +               return -EACCES;
13644 +       }
13645 +#endif
13646 +       return 0;
13647 +}
13648 +
13649 +int
13650 +gr_handle_hardlink(const struct dentry *dentry,
13651 +                  const struct vfsmount *mnt,
13652 +                  struct inode *inode, const int mode, const char *to)
13653 +{
13654 +#ifdef CONFIG_GRKERNSEC_LINK
13655 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
13656 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
13657 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
13658 +            (vfs_permission(inode, MAY_READ | MAY_WRITE))) &&
13659 +           !capable(CAP_FOWNER) && current->uid) {
13660 +               security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
13661 +                              inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
13662 +               return -EPERM;
13663 +       }
13664 +#endif
13665 +       return 0;
13666 +}
13667 diff -uNr linux-2.6.8/grsecurity/grsec_mem.c linux-2.6.8.grsecurity/grsecurity/grsec_mem.c
13668 --- linux-2.6.8/grsecurity/grsec_mem.c  1970-01-01 01:00:00.000000000 +0100
13669 +++ linux-2.6.8.grsecurity/grsecurity/grsec_mem.c       2004-08-16 17:08:29.000000000 +0200
13670 @@ -0,0 +1,62 @@
13671 +#include <linux/kernel.h>
13672 +#include <linux/sched.h>
13673 +#include <linux/mm.h>
13674 +#include <linux/mman.h>
13675 +#include <linux/grinternal.h>
13676 +
13677 +void
13678 +gr_handle_ioperm(void)
13679 +{
13680 +       security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
13681 +       return;
13682 +}
13683 +
13684 +void
13685 +gr_handle_iopl(void)
13686 +{
13687 +       security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
13688 +       return;
13689 +}
13690 +
13691 +void
13692 +gr_handle_mem_write(void)
13693 +{
13694 +       security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
13695 +       return;
13696 +}
13697 +
13698 +void
13699 +gr_handle_kmem_write(void)
13700 +{
13701 +       security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
13702 +       return;
13703 +}
13704 +
13705 +void
13706 +gr_handle_open_port(void)
13707 +{
13708 +       security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
13709 +       return;
13710 +}
13711 +
13712 +int
13713 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
13714 +{
13715 +       if (offset + vma->vm_end - vma->vm_start <= offset) {
13716 +               security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
13717 +               return -EPERM;
13718 +       }
13719 +
13720 +       if (offset < __pa(high_memory) && (vma->vm_flags & VM_WRITE)
13721 +#ifdef CONFIG_X86
13722 +           && !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000))
13723 +           && !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))
13724 +#endif
13725 +          ) {
13726 +               security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
13727 +               return -EPERM;
13728 +       } else if (offset < __pa(high_memory))
13729 +               vma->vm_flags &= ~VM_MAYWRITE;
13730 +
13731 +       return 0;
13732 +}
13733 diff -uNr linux-2.6.8/grsecurity/grsec_mount.c linux-2.6.8.grsecurity/grsecurity/grsec_mount.c
13734 --- linux-2.6.8/grsecurity/grsec_mount.c        1970-01-01 01:00:00.000000000 +0100
13735 +++ linux-2.6.8.grsecurity/grsecurity/grsec_mount.c     2004-08-16 17:08:29.000000000 +0200
13736 @@ -0,0 +1,34 @@
13737 +#include <linux/kernel.h>
13738 +#include <linux/sched.h>
13739 +#include <linux/grsecurity.h>
13740 +#include <linux/grinternal.h>
13741 +
13742 +void
13743 +gr_log_remount(const char *devname, const int retval)
13744 +{
13745 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13746 +       if (grsec_enable_mount && (retval >= 0))
13747 +               security_audit(GR_REMOUNT_AUDIT_MSG, devname ? devname : "none", DEFAULTSECARGS);
13748 +#endif
13749 +       return;
13750 +}
13751 +
13752 +void
13753 +gr_log_unmount(const char *devname, const int retval)
13754 +{
13755 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13756 +       if (grsec_enable_mount && (retval >= 0))
13757 +               security_audit(GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none", DEFAULTSECARGS);
13758 +#endif
13759 +       return;
13760 +}
13761 +
13762 +void
13763 +gr_log_mount(const char *from, const char *to, const int retval)
13764 +{
13765 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13766 +       if (grsec_enable_mount && (retval >= 0))
13767 +               security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
13768 +#endif
13769 +       return;
13770 +}
13771 diff -uNr linux-2.6.8/grsecurity/grsec_rand.c linux-2.6.8.grsecurity/grsecurity/grsec_rand.c
13772 --- linux-2.6.8/grsecurity/grsec_rand.c 1970-01-01 01:00:00.000000000 +0100
13773 +++ linux-2.6.8.grsecurity/grsecurity/grsec_rand.c      2004-08-16 17:08:29.000000000 +0200
13774 @@ -0,0 +1,22 @@
13775 +#include <linux/kernel.h>
13776 +#include <linux/sched.h>
13777 +#include <linux/smp_lock.h>
13778 +#include <linux/grsecurity.h>
13779 +#include <linux/grinternal.h>
13780 +
13781 +extern int pid_max;
13782 +
13783 +int
13784 +gr_random_pid(void)
13785 +{
13786 +#ifdef CONFIG_GRKERNSEC_RANDPID
13787 +       int pid;
13788 +
13789 +       if (grsec_enable_randpid && current->fs->root) {
13790 +
13791 +               pid = 1 + (get_random_long() % pid_max);
13792 +               return pid;
13793 +       }
13794 +#endif
13795 +       return 0;
13796 +}
13797 diff -uNr linux-2.6.8/grsecurity/grsec_sig.c linux-2.6.8.grsecurity/grsecurity/grsec_sig.c
13798 --- linux-2.6.8/grsecurity/grsec_sig.c  1970-01-01 01:00:00.000000000 +0100
13799 +++ linux-2.6.8.grsecurity/grsecurity/grsec_sig.c       2004-08-16 17:08:29.000000000 +0200
13800 @@ -0,0 +1,73 @@
13801 +#include <linux/kernel.h>
13802 +#include <linux/sched.h>
13803 +#include <linux/grsecurity.h>
13804 +#include <linux/grinternal.h>
13805 +
13806 +void
13807 +gr_log_signal(const int sig, const struct task_struct *t)
13808 +{
13809 +#ifdef CONFIG_GRKERNSEC_SIGNAL
13810 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
13811 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
13812 +               if (t->pid == current->pid) {
13813 +                       security_alert_good(GR_UNISIGLOG_MSG, sig,
13814 +                                           DEFAULTSECARGS);
13815 +               } else {
13816 +                       security_alert_good(GR_DUALSIGLOG_MSG, sig,
13817 +                                           gr_task_fullpath0(t), t->comm,
13818 +                                           t->pid, t->uid, t->euid, t->gid,
13819 +                                           t->egid, gr_parent_task_fullpath0(t),
13820 +                                           t->parent->comm,
13821 +                                           t->parent->pid, t->parent->uid,
13822 +                                           t->parent->euid, t->parent->gid,
13823 +                                           t->parent->egid, DEFAULTSECARGS);
13824 +               }
13825 +       }
13826 +#endif
13827 +       return;
13828 +}
13829 +
13830 +int
13831 +gr_handle_signal(const struct task_struct *p, const int sig)
13832 +{
13833 +#ifdef CONFIG_GRKERNSEC
13834 +       if (current->pid > 1 && gr_check_protected_task(p)) {
13835 +               security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath0(p),
13836 +                              p->comm, p->pid, p->uid,
13837 +                              p->euid, p->gid, p->egid,
13838 +                              gr_parent_task_fullpath0(p), p->parent->comm,
13839 +                              p->parent->pid, p->parent->uid,
13840 +                              p->parent->euid, p->parent->gid,
13841 +                              p->parent->egid, DEFAULTSECARGS);
13842 +               return -EPERM;
13843 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
13844 +               return -EPERM;
13845 +       }
13846 +#endif
13847 +       return 0;
13848 +}
13849 +
13850 +void gr_handle_brute_attach(struct task_struct *p)
13851 +{
13852 +#ifdef CONFIG_GRKERNSEC_BRUTE
13853 +       read_lock(&tasklist_lock);
13854 +       read_lock(&grsec_exec_file_lock);
13855 +       if (p->parent && p->parent->exec_file == p->exec_file)
13856 +               p->parent->brute = 1;
13857 +       read_unlock(&grsec_exec_file_lock);
13858 +       read_unlock(&tasklist_lock);
13859 +#endif
13860 +       return;
13861 +}
13862 +
13863 +void gr_handle_brute_check(void)
13864 +{
13865 +#ifdef CONFIG_GRKERNSEC_BRUTE
13866 +       if (current->brute) {
13867 +               set_current_state(TASK_UNINTERRUPTIBLE);
13868 +               schedule_timeout(30 * HZ);
13869 +       }
13870 +#endif
13871 +       return;
13872 +}
13873 +
13874 diff -uNr linux-2.6.8/grsecurity/grsec_sock.c linux-2.6.8.grsecurity/grsecurity/grsec_sock.c
13875 --- linux-2.6.8/grsecurity/grsec_sock.c 1970-01-01 01:00:00.000000000 +0100
13876 +++ linux-2.6.8.grsecurity/grsecurity/grsec_sock.c      2004-08-16 17:08:29.000000000 +0200
13877 @@ -0,0 +1,259 @@
13878 +#include <linux/kernel.h>
13879 +#include <linux/module.h>
13880 +#include <linux/sched.h>
13881 +#include <linux/file.h>
13882 +#include <linux/net.h>
13883 +#include <linux/in.h>
13884 +#include <linux/ip.h>
13885 +#include <net/sock.h>
13886 +#include <linux/grsecurity.h>
13887 +#include <linux/grinternal.h>
13888 +#include <linux/gracl.h>
13889 +
13890 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
13891 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
13892 +EXPORT_SYMBOL(udp_v4_lookup);
13893 +#endif
13894 +#if defined(CONFIG_GRKERNSEC_RANDID)
13895 +EXPORT_SYMBOL(ip_randomid);
13896 +#endif
13897 +#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
13898 +EXPORT_SYMBOL(get_random_long);
13899 +#endif
13900 +#ifdef CONFIG_GRKERNSEC_RANDISN
13901 +EXPORT_SYMBOL(ip_randomisn);
13902 +EXPORT_SYMBOL(grsec_enable_randisn);
13903 +#endif
13904 +#ifdef CONFIG_GRKERNSEC_RANDID
13905 +EXPORT_SYMBOL(grsec_enable_randid);
13906 +#endif
13907 +#ifdef CONFIG_GRKERNSEC_RANDSRC
13908 +EXPORT_SYMBOL(grsec_enable_randsrc);
13909 +#endif
13910 +#ifdef CONFIG_GRKERNSEC_RANDRPC
13911 +EXPORT_SYMBOL(grsec_enable_randrpc);
13912 +#endif
13913 +
13914 +EXPORT_SYMBOL(gr_cap_rtnetlink);
13915 +
13916 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
13917 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
13918 +
13919 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
13920 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
13921 +
13922 +#ifdef CONFIG_UNIX_MODULE
13923 +EXPORT_SYMBOL(gr_acl_handle_unix);
13924 +EXPORT_SYMBOL(gr_acl_handle_mknod);
13925 +EXPORT_SYMBOL(gr_handle_chroot_unix);
13926 +EXPORT_SYMBOL(gr_handle_create);
13927 +#endif
13928 +
13929 +#ifdef CONFIG_GRKERNSEC
13930 +struct task_struct **gr_conn_table;
13931 +const unsigned int gr_conn_table_size = 65521;
13932 +struct task_struct *deleted_conn = (struct task_struct *)~0;
13933 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
13934 +
13935 +extern __inline__ const char * gr_socktype_to_name(unsigned char type);
13936 +extern __inline__ const char * gr_proto_to_name(unsigned char proto);
13937 +
13938 +static __inline__ int 
13939 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
13940 +{
13941 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
13942 +}
13943 +
13944 +static __inline__ int
13945 +conn_match(const struct task_struct *task, __u32 saddr, __u32 daddr, 
13946 +          __u16 sport, __u16 dport)
13947 +{
13948 +       if (unlikely(task != deleted_conn && task->gr_saddr == saddr && 
13949 +                    task->gr_daddr == daddr && task->gr_sport == sport &&
13950 +                    task->gr_dport == dport))
13951 +               return 1;
13952 +       else
13953 +               return 0;
13954 +}
13955 +
13956 +void gr_add_to_task_ip_table(struct task_struct *task)
13957 +{
13958 +       unsigned int index;
13959 +
13960 +       if (unlikely(gr_conn_table == NULL))
13961 +               return;
13962 +
13963 +       if (!thread_group_leader(task))
13964 +               task = task->group_leader;
13965 +
13966 +       index = conn_hash(task->gr_saddr, task->gr_daddr, 
13967 +                         task->gr_sport, task->gr_dport, 
13968 +                         gr_conn_table_size);
13969 +
13970 +       spin_lock(&gr_conn_table_lock);
13971 +
13972 +       while (gr_conn_table[index] && gr_conn_table[index] != deleted_conn) {
13973 +               index = (index + 1) % gr_conn_table_size;
13974 +       }
13975 +
13976 +       gr_conn_table[index] = task;
13977 +
13978 +       spin_unlock(&gr_conn_table_lock);
13979 +
13980 +       return;
13981 +}
13982 +
13983 +void gr_del_task_from_ip_table_nolock(struct task_struct *task)
13984 +{
13985 +       unsigned int index;
13986 +
13987 +       if (unlikely(gr_conn_table == NULL))
13988 +               return;
13989 +
13990 +       if (!thread_group_leader(task))
13991 +               task = task->group_leader;
13992 +
13993 +       index = conn_hash(task->gr_saddr, task->gr_daddr, 
13994 +                         task->gr_sport, task->gr_dport, 
13995 +                         gr_conn_table_size);
13996 +
13997 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
13998 +               task->gr_saddr, task->gr_daddr, task->gr_sport, 
13999 +               task->gr_dport)) {
14000 +               index = (index + 1) % gr_conn_table_size;
14001 +       }
14002 +
14003 +       if (gr_conn_table[index]) {
14004 +               if (gr_conn_table[(index + 1) % gr_conn_table_size])
14005 +                       gr_conn_table[index] = deleted_conn;
14006 +               else
14007 +                       gr_conn_table[index] = NULL;
14008 +       }
14009 +
14010 +       return;
14011 +}
14012 +
14013 +struct task_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
14014 +                                            __u16 sport, __u16 dport)
14015 +{
14016 +       unsigned int index;
14017 +
14018 +       if (unlikely(gr_conn_table == NULL))
14019 +               return NULL;
14020 +
14021 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
14022 +
14023 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
14024 +               saddr, daddr, sport, dport)) {
14025 +               index = (index + 1) % gr_conn_table_size;
14026 +       }
14027 +
14028 +       return gr_conn_table[index];
14029 +}
14030 +
14031 +#endif
14032 +
14033 +void gr_del_task_from_ip_table(struct task_struct *task)
14034 +{
14035 +#ifdef CONFIG_GRKERNSEC
14036 +       spin_lock(&gr_conn_table_lock);
14037 +       if (!thread_group_leader(task))
14038 +               gr_del_task_from_ip_table_nolock(task->group_leader);
14039 +       else
14040 +               gr_del_task_from_ip_table_nolock(task);
14041 +       spin_unlock(&gr_conn_table_lock);
14042 +#endif
14043 +       return;
14044 +}
14045 +
14046 +void
14047 +gr_attach_curr_ip(const struct sock *sk)
14048 +{
14049 +#ifdef CONFIG_GRKERNSEC
14050 +       struct task_struct *p;
14051 +       struct task_struct *set;
14052 +       const struct inet_opt *inet = inet_sk(sk);      
14053 +
14054 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
14055 +               return;
14056 +
14057 +       set = current;
14058 +       if (!thread_group_leader(set))
14059 +               set = set->group_leader;
14060 +
14061 +       spin_lock(&gr_conn_table_lock);
14062 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
14063 +                                   inet->dport, inet->sport);
14064 +       if (unlikely(p != NULL)) {
14065 +               set->curr_ip = p->curr_ip;
14066 +               set->used_accept = 1;
14067 +               gr_del_task_from_ip_table_nolock(p);
14068 +               spin_unlock(&gr_conn_table_lock);
14069 +               return;
14070 +       }
14071 +       spin_unlock(&gr_conn_table_lock);
14072 +
14073 +       set->curr_ip = inet->daddr;
14074 +       set->used_accept = 1;
14075 +#endif
14076 +       return;
14077 +}
14078 +
14079 +int
14080 +gr_handle_sock_all(const int family, const int type, const int protocol)
14081 +{
14082 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
14083 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
14084 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
14085 +               security_alert(GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol),
14086 +                              DEFAULTSECARGS);
14087 +               return -EACCES;
14088 +       }
14089 +#endif
14090 +       return 0;
14091 +}
14092 +
14093 +int
14094 +gr_handle_sock_server(const struct sockaddr *sck)
14095 +{
14096 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
14097 +       if (grsec_enable_socket_server &&
14098 +           in_group_p(grsec_socket_server_gid) &&
14099 +           sck && (sck->sa_family != AF_UNIX) &&
14100 +           (sck->sa_family != AF_LOCAL)) {
14101 +               security_alert(GR_BIND_MSG, DEFAULTSECARGS);
14102 +               return -EACCES;
14103 +       }
14104 +#endif
14105 +       return 0;
14106 +}
14107 +
14108 +int
14109 +gr_handle_sock_client(const struct sockaddr *sck)
14110 +{
14111 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
14112 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
14113 +           sck && (sck->sa_family != AF_UNIX) &&
14114 +           (sck->sa_family != AF_LOCAL)) {
14115 +               security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
14116 +               return -EACCES;
14117 +       }
14118 +#endif
14119 +       return 0;
14120 +}
14121 +
14122 +__u32
14123 +gr_cap_rtnetlink(void)
14124 +{
14125 +#ifdef CONFIG_GRKERNSEC
14126 +       if (!gr_acl_is_enabled())
14127 +               return current->cap_effective;
14128 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
14129 +                gr_task_is_capable(current, CAP_NET_ADMIN))
14130 +               return current->cap_effective;
14131 +       else
14132 +               return 0;
14133 +#else
14134 +       return current->cap_effective;
14135 +#endif
14136 +}
14137 diff -uNr linux-2.6.8/grsecurity/grsec_sysctl.c linux-2.6.8.grsecurity/grsecurity/grsec_sysctl.c
14138 --- linux-2.6.8/grsecurity/grsec_sysctl.c       1970-01-01 01:00:00.000000000 +0100
14139 +++ linux-2.6.8.grsecurity/grsecurity/grsec_sysctl.c    2004-08-16 17:08:29.000000000 +0200
14140 @@ -0,0 +1,453 @@
14141 +#include <linux/kernel.h>
14142 +#include <linux/sched.h>
14143 +#include <linux/sysctl.h>
14144 +#include <linux/grsecurity.h>
14145 +#include <linux/grinternal.h>
14146 +
14147 +int
14148 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
14149 +{
14150 +#ifdef CONFIG_GRKERNSEC_SYSCTL
14151 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
14152 +               security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
14153 +               return -EACCES;
14154 +       }
14155 +#endif
14156 +       return 0;
14157 +}
14158 +
14159 +#ifdef CONFIG_GRKERNSEC_SYSCTL
14160 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
14161 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
14162 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
14163 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
14164 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
14165 +GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
14166 +GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
14167 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS,
14168 +GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
14169 +GS_TEXTREL, GS_FINDTASK, GS_LOCK};
14170 +
14171 +
14172 +ctl_table grsecurity_table[] = {
14173 +#ifdef CONFIG_GRKERNSEC_LINK
14174 +       {
14175 +               .ctl_name       = GS_LINK,
14176 +               .procname       = "linking_restrictions",
14177 +               .data           = &grsec_enable_link,
14178 +               .maxlen         = sizeof(int),
14179 +               .mode           = 0600,
14180 +               .proc_handler   = &proc_dointvec,
14181 +       },
14182 +#endif
14183 +#ifdef CONFIG_GRKERNSEC_FIFO
14184 +       {
14185 +               .ctl_name       = GS_FIFO,
14186 +               .procname       = "fifo_restrictions",
14187 +               .data           = &grsec_enable_fifo,
14188 +               .maxlen         = sizeof(int),
14189 +               .mode           = 0600,
14190 +               .proc_handler   = &proc_dointvec,
14191 +       },
14192 +#endif
14193 +#ifdef CONFIG_GRKERNSEC_EXECVE
14194 +       {
14195 +               .ctl_name       = GS_EXECVE,
14196 +               .procname       = "execve_limiting",
14197 +               .data           = &grsec_enable_execve,
14198 +               .maxlen         = sizeof(int),
14199 +               .mode           = 0600,
14200 +               .proc_handler   = &proc_dointvec,
14201 +       },
14202 +#endif
14203 +#ifdef CONFIG_GRKERNSEC_EXECLOG
14204 +       {
14205 +               .ctl_name       = GS_EXECLOG,
14206 +               .procname       = "exec_logging",
14207 +               .data           = &grsec_enable_execlog,
14208 +               .maxlen         = sizeof(int),
14209 +               .mode           = 0600,
14210 +               .proc_handler   = &proc_dointvec,
14211 +       },
14212 +#endif
14213 +#ifdef CONFIG_GRKERNSEC_SIGNAL
14214 +       {
14215 +               .ctl_name       = GS_SIGNAL,
14216 +               .procname       = "signal_logging",
14217 +               .data           = &grsec_enable_signal,
14218 +               .maxlen         = sizeof(int),
14219 +               .mode           = 0600,
14220 +               .proc_handler   = &proc_dointvec,
14221 +       },
14222 +#endif
14223 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
14224 +       {
14225 +               .ctl_name       = GS_FORKFAIL,
14226 +               .procname       = "forkfail_logging",
14227 +               .data           = &grsec_enable_forkfail,
14228 +               .maxlen         = sizeof(int),
14229 +               .mode           = 0600,
14230 +               .proc_handler   = &proc_dointvec,
14231 +       },
14232 +#endif
14233 +#ifdef CONFIG_GRKERNSEC_TIME
14234 +       {
14235 +               .ctl_name       = GS_TIME,
14236 +               .procname       = "timechange_logging",
14237 +               .data           = &grsec_enable_time,
14238 +               .maxlen         = sizeof(int),
14239 +               .mode           = 0600,
14240 +               .proc_handler   = &proc_dointvec,
14241 +       },
14242 +#endif
14243 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
14244 +       {
14245 +               .ctl_name       = GS_CHROOT_SHMAT,
14246 +               .procname       = "chroot_deny_shmat",
14247 +               .data           = &grsec_enable_chroot_shmat,
14248 +               .maxlen         = sizeof(int),
14249 +               .mode           = 0600,
14250 +               .proc_handler   = &proc_dointvec,
14251 +       },
14252 +#endif
14253 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
14254 +       {
14255 +               .ctl_name       = GS_CHROOT_UNIX,
14256 +               .procname       = "chroot_deny_unix",
14257 +               .data           = &grsec_enable_chroot_unix,
14258 +               .maxlen         = sizeof(int),
14259 +               .mode           = 0600,
14260 +               .proc_handler   = &proc_dointvec,
14261 +       },
14262 +#endif
14263 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
14264 +       {
14265 +               .ctl_name       = GS_CHROOT_MNT,
14266 +               .procname       = "chroot_deny_mount",
14267 +               .data           = &grsec_enable_chroot_mount,
14268 +               .maxlen         = sizeof(int),
14269 +               .mode           = 0600,
14270 +               .proc_handler   = &proc_dointvec,
14271 +       },
14272 +#endif
14273 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
14274 +       {
14275 +               .ctl_name       = GS_CHROOT_FCHDIR,
14276 +               .procname       = "chroot_deny_fchdir",
14277 +               .data           = &grsec_enable_chroot_fchdir,
14278 +               .maxlen         = sizeof(int),
14279 +               .mode           = 0600,
14280 +               .proc_handler   = &proc_dointvec,
14281 +       },
14282 +#endif
14283 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
14284 +       {
14285 +               .ctl_name       = GS_CHROOT_DBL,
14286 +               .procname       = "chroot_deny_chroot",
14287 +               .data           = &grsec_enable_chroot_double,
14288 +               .maxlen         = sizeof(int),
14289 +               .mode           = 0600,
14290 +               .proc_handler   = &proc_dointvec,
14291 +       },
14292 +#endif
14293 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
14294 +       {
14295 +               .ctl_name       = GS_CHROOT_PVT,
14296 +               .procname       = "chroot_deny_pivot",
14297 +               .data           = &grsec_enable_chroot_pivot,
14298 +               .maxlen         = sizeof(int),
14299 +               .mode           = 0600,
14300 +               .proc_handler   = &proc_dointvec,
14301 +       },
14302 +#endif
14303 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
14304 +       {
14305 +               .ctl_name       = GS_CHROOT_CD,
14306 +               .procname       = "chroot_enforce_chdir",
14307 +               .data           = &grsec_enable_chroot_chdir,
14308 +               .maxlen         = sizeof(int),
14309 +               .mode           = 0600,
14310 +               .proc_handler   = &proc_dointvec,
14311 +       },
14312 +#endif
14313 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
14314 +       {
14315 +               .ctl_name       = GS_CHROOT_CM,
14316 +               .procname       = "chroot_deny_chmod",
14317 +               .data           = &grsec_enable_chroot_chmod,
14318 +               .maxlen         = sizeof(int),
14319 +               .mode           = 0600,
14320 +               .proc_handler   = &proc_dointvec,
14321 +       },
14322 +#endif
14323 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
14324 +       {
14325 +               .ctl_name       = GS_CHROOT_MK,
14326 +               .procname       = "chroot_deny_mknod",
14327 +               .data           = &grsec_enable_chroot_mknod,
14328 +               .maxlen         = sizeof(int),
14329 +               .mode           = 0600,
14330 +               .proc_handler   = &proc_dointvec,
14331 +       },
14332 +#endif
14333 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
14334 +       {
14335 +               .ctl_name       = GS_CHROOT_NI,
14336 +               .procname       = "chroot_restrict_nice",
14337 +               .data           = &grsec_enable_chroot_nice,
14338 +               .maxlen         = sizeof(int),
14339 +               .mode           = 0600,
14340 +               .proc_handler   = &proc_dointvec,
14341 +       },
14342 +#endif
14343 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
14344 +       {
14345 +               .ctl_name       = GS_CHROOT_EXECLOG,
14346 +               .procname       = "chroot_execlog",
14347 +               .data           = &grsec_enable_chroot_execlog,
14348 +               .maxlen         = sizeof(int),
14349 +               .mode           = 0600,
14350 +               .proc_handler   = &proc_dointvec,
14351 +       },
14352 +#endif
14353 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14354 +       {
14355 +               .ctl_name       = GS_CHROOT_CAPS,
14356 +               .procname       = "chroot_caps",
14357 +               .data           = &grsec_enable_chroot_caps,
14358 +               .maxlen         = sizeof(int),
14359 +               .mode           = 0600,
14360 +               .proc_handler   = &proc_dointvec,
14361 +       },
14362 +#endif
14363 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
14364 +       {
14365 +               .ctl_name       = GS_CHROOT_SYSCTL,
14366 +               .procname       = "chroot_deny_sysctl",
14367 +               .data           = &grsec_enable_chroot_sysctl,
14368 +               .maxlen         = sizeof(int),
14369 +               .mode           = 0600,
14370 +               .proc_handler   = &proc_dointvec,
14371 +       },
14372 +#endif
14373 +#ifdef CONFIG_GRKERNSEC_TPE
14374 +       {
14375 +               .ctl_name       = GS_TPE,
14376 +               .procname       = "tpe",
14377 +               .data           = &grsec_enable_tpe,
14378 +               .maxlen         = sizeof(int),
14379 +               .mode           = 0600,
14380 +               .proc_handler   = &proc_dointvec,
14381 +       },
14382 +       {
14383 +               .ctl_name       = GS_TPE_GID,
14384 +               .procname       = "tpe_gid",
14385 +               .data           = &grsec_tpe_gid,
14386 +               .maxlen         = sizeof(int),
14387 +               .mode           = 0600,
14388 +               .proc_handler   = &proc_dointvec,
14389 +       },
14390 +#endif
14391 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
14392 +       {
14393 +               .ctl_name       = GS_TPE_ALL,
14394 +               .procname       = "tpe_restrict_all",
14395 +               .data           = &grsec_enable_tpe_all,
14396 +               .maxlen         = sizeof(int),
14397 +               .mode           = 0600,
14398 +               .proc_handler   = &proc_dointvec,
14399 +       },
14400 +#endif
14401 +#ifdef CONFIG_GRKERNSEC_RANDPID
14402 +       {
14403 +               .ctl_name       = GS_RANDPID,
14404 +               .procname       = "rand_pids",
14405 +               .data           = &grsec_enable_randpid,
14406 +               .maxlen         = sizeof(int),
14407 +               .mode           = 0600,
14408 +               .proc_handler   = &proc_dointvec,
14409 +       },
14410 +#endif
14411 +#ifdef CONFIG_GRKERNSEC_RANDID
14412 +       {
14413 +               .ctl_name       = GS_RANDID,
14414 +               .procname       = "rand_ip_ids",
14415 +               .data           = &grsec_enable_randid,
14416 +               .maxlen         = sizeof(int),
14417 +               .mode           = 0600,
14418 +               .proc_handler   = &proc_dointvec,
14419 +       },
14420 +#endif
14421 +#ifdef CONFIG_GRKERNSEC_RANDSRC
14422 +       {
14423 +               .ctl_name       = GS_RANDSRC,
14424 +               .procname       = "rand_tcp_src_ports",
14425 +               .data           = &grsec_enable_randsrc,
14426 +               .maxlen         = sizeof(int),
14427 +               .mode           = 0600,
14428 +               .proc_handler   = &proc_dointvec,
14429 +       },
14430 +#endif
14431 +#ifdef CONFIG_GRKERNSEC_RANDISN
14432 +       {
14433 +               .ctl_name       = GS_RANDISN,
14434 +               .procname       = "rand_isns",
14435 +               .data           = &grsec_enable_randisn,
14436 +               .maxlen         = sizeof(int),
14437 +               .mode           = 0600,
14438 +               .proc_handler   = &proc_dointvec,
14439 +       },
14440 +#endif
14441 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
14442 +       {
14443 +               .ctl_name       = GS_SOCKET_ALL,
14444 +               .procname       = "socket_all",
14445 +               .data           = &grsec_enable_socket_all,
14446 +               .maxlen         = sizeof(int),
14447 +               .mode           = 0600,
14448 +               .proc_handler   = &proc_dointvec,
14449 +       },
14450 +       {
14451 +               .ctl_name       = GS_SOCKET_ALL_GID,
14452 +               .procname       = "socket_all_gid",
14453 +               .data           = &grsec_socket_all_gid,
14454 +               .maxlen         = sizeof(int),
14455 +               .mode           = 0600,
14456 +               .proc_handler   = &proc_dointvec,
14457 +       },
14458 +#endif
14459 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
14460 +       {
14461 +               .ctl_name       = GS_SOCKET_CLIENT,
14462 +               .procname       = "socket_client",
14463 +               .data           = &grsec_enable_socket_client,
14464 +               .maxlen         = sizeof(int),
14465 +               .mode           = 0600,
14466 +               .proc_handler   = &proc_dointvec,
14467 +       },
14468 +       {
14469 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
14470 +               .procname       = "socket_client_gid",
14471 +               .data           = &grsec_socket_client_gid,
14472 +               .maxlen         = sizeof(int),
14473 +               .mode           = 0600,
14474 +               .proc_handler   = &proc_dointvec,
14475 +       },
14476 +#endif
14477 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
14478 +       {
14479 +               .ctl_name       = GS_SOCKET_SERVER,
14480 +               .procname       = "socket_server",
14481 +               .data           = &grsec_enable_socket_server,
14482 +               .maxlen         = sizeof(int),
14483 +               .mode           = 0600,
14484 +               .proc_handler   = &proc_dointvec,
14485 +       },
14486 +       {
14487 +               .ctl_name       = GS_SOCKET_SERVER_GID,
14488 +               .procname       = "socket_server_gid",
14489 +               .data           = &grsec_socket_server_gid,
14490 +               .maxlen         = sizeof(int),
14491 +               .mode           = 0600,
14492 +               .proc_handler   = &proc_dointvec,
14493 +       },
14494 +#endif
14495 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
14496 +       {
14497 +               .ctl_name       = GS_GROUP,
14498 +               .procname       = "audit_group",
14499 +               .data           = &grsec_enable_group,
14500 +               .maxlen         = sizeof(int),
14501 +               .mode           = 0600,
14502 +               .proc_handler   = &proc_dointvec,
14503 +       },
14504 +       {
14505 +               .ctl_name       = GS_GID,
14506 +               .procname       = "audit_gid",
14507 +               .data           = &grsec_audit_gid,
14508 +               .maxlen         = sizeof(int),
14509 +               .mode           = 0600,
14510 +               .proc_handler   = &proc_dointvec,
14511 +       },
14512 +#endif
14513 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
14514 +       {
14515 +               .ctl_name       = GS_ACHDIR,
14516 +               .procname       = "audit_chdir",
14517 +               .data           = &grsec_enable_chdir,
14518 +               .maxlen         = sizeof(int),
14519 +               .mode           = 0600,
14520 +               .proc_handler   = &proc_dointvec,
14521 +       },
14522 +#endif
14523 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
14524 +       {
14525 +               .ctl_name       = GS_AMOUNT,
14526 +               .procname       = "audit_mount",
14527 +               .data           = &grsec_enable_mount,
14528 +               .maxlen         = sizeof(int),
14529 +               .mode           = 0600,
14530 +               .proc_handler   = &proc_dointvec,
14531 +       },
14532 +#endif
14533 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
14534 +       {
14535 +               .ctl_name       = GS_AIPC,
14536 +               .procname       = "audit_ipc",
14537 +               .data           = &grsec_enable_audit_ipc,
14538 +               .maxlen         = sizeof(int),
14539 +               .mode           = 0600,
14540 +               .proc_handler   = &proc_dointvec,
14541 +       },
14542 +#endif
14543 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
14544 +       {
14545 +               .ctl_name       = GS_TEXTREL,
14546 +               .procname       = "audit_textrel",
14547 +               .data           = &grsec_enable_audit_textrel,
14548 +               .maxlen         = sizeof(int),
14549 +               .mode           = 0600,
14550 +               .proc_handler   = &proc_dointvec,
14551 +       },
14552 +#endif
14553 +#ifdef CONFIG_GRKERNSEC_DMESG
14554 +       {
14555 +               .ctl_name       = GS_DMSG,
14556 +               .procname       = "dmesg",
14557 +               .data           = &grsec_enable_dmesg,
14558 +               .maxlen         = sizeof(int),
14559 +               .mode           = 0600,
14560 +               .proc_handler   = &proc_dointvec,
14561 +       },
14562 +#endif
14563 +#ifdef CONFIG_GRKERNSEC_RANDRPC
14564 +       {
14565 +               .ctl_name       = GS_RANDRPC,
14566 +               .procname       = "rand_rpc",
14567 +               .data           = &grsec_enable_randrpc,
14568 +               .maxlen         = sizeof(int),
14569 +               .mode           = 0600,
14570 +               .proc_handler   = &proc_dointvec,
14571 +       },
14572 +#endif
14573 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
14574 +       {
14575 +               .ctl_name       = GS_FINDTASK,
14576 +               .procname       = "chroot_findtask",
14577 +               .data           = &grsec_enable_chroot_findtask,
14578 +               .maxlen         = sizeof(int),
14579 +               .mode           = 0600,
14580 +               .proc_handler   = &proc_dointvec,
14581 +       },
14582 +#endif
14583 +       {
14584 +               .ctl_name       = GS_LOCK,
14585 +               .procname       = "grsec_lock",
14586 +               .data           = &grsec_lock,
14587 +               .maxlen         = sizeof(int),
14588 +               .mode           = 0600,
14589 +               .proc_handler   = &proc_dointvec,
14590 +       },
14591 +       { .ctl_name = 0 }
14592 +};
14593 +#endif
14594 diff -uNr linux-2.6.8/grsecurity/grsec_textrel.c linux-2.6.8.grsecurity/grsecurity/grsec_textrel.c
14595 --- linux-2.6.8/grsecurity/grsec_textrel.c      1970-01-01 01:00:00.000000000 +0100
14596 +++ linux-2.6.8.grsecurity/grsecurity/grsec_textrel.c   2004-08-16 17:08:29.000000000 +0200
14597 @@ -0,0 +1,19 @@
14598 +#include <linux/kernel.h>
14599 +#include <linux/sched.h>
14600 +#include <linux/mm.h>
14601 +#include <linux/file.h>
14602 +#include <linux/grinternal.h>
14603 +#include <linux/grsecurity.h>
14604 +
14605 +void
14606 +gr_log_textrel(struct vm_area_struct * vma)
14607 +{
14608 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
14609 +       if (grsec_enable_audit_textrel)
14610 +               security_audit(GR_TEXTREL_AUDIT_MSG, vma->vm_file ? 
14611 +                               gr_to_filename(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt)
14612 +                               : "<anonymous mapping>", vma->vm_start, 
14613 +                               vma->vm_pgoff, DEFAULTSECARGS);
14614 +#endif
14615 +       return;
14616 +}
14617 diff -uNr linux-2.6.8/grsecurity/grsec_time.c linux-2.6.8.grsecurity/grsecurity/grsec_time.c
14618 --- linux-2.6.8/grsecurity/grsec_time.c 1970-01-01 01:00:00.000000000 +0100
14619 +++ linux-2.6.8.grsecurity/grsecurity/grsec_time.c      2004-08-16 17:08:29.000000000 +0200
14620 @@ -0,0 +1,13 @@
14621 +#include <linux/kernel.h>
14622 +#include <linux/sched.h>
14623 +#include <linux/grinternal.h>
14624 +
14625 +void
14626 +gr_log_timechange(void)
14627 +{
14628 +#ifdef CONFIG_GRKERNSEC_TIME
14629 +       if (grsec_enable_time)
14630 +               security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
14631 +#endif
14632 +       return;
14633 +}
14634 diff -uNr linux-2.6.8/grsecurity/grsec_tpe.c linux-2.6.8.grsecurity/grsecurity/grsec_tpe.c
14635 --- linux-2.6.8/grsecurity/grsec_tpe.c  1970-01-01 01:00:00.000000000 +0100
14636 +++ linux-2.6.8.grsecurity/grsecurity/grsec_tpe.c       2004-08-16 17:08:29.000000000 +0200
14637 @@ -0,0 +1,35 @@
14638 +#include <linux/kernel.h>
14639 +#include <linux/sched.h>
14640 +#include <linux/file.h>
14641 +#include <linux/fs.h>
14642 +#include <linux/grinternal.h>
14643 +
14644 +extern int gr_acl_tpe_check(void);
14645 +
14646 +int
14647 +gr_tpe_allow(const struct file *file)
14648 +{
14649 +#ifdef CONFIG_GRKERNSEC
14650 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
14651 +
14652 +       if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
14653 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
14654 +                                               (inode->i_mode & S_IWOTH))))) {
14655 +               security_alert(GR_EXEC_TPE_MSG,
14656 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
14657 +                              DEFAULTSECARGS);
14658 +               return 0;
14659 +       }
14660 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
14661 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
14662 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
14663 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
14664 +               security_alert(GR_EXEC_TPE_MSG,
14665 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
14666 +                              DEFAULTSECARGS);
14667 +               return 0;
14668 +       }
14669 +#endif
14670 +#endif
14671 +       return 1;
14672 +}
14673 diff -uNr linux-2.6.8/grsecurity/grsum.c linux-2.6.8.grsecurity/grsecurity/grsum.c
14674 --- linux-2.6.8/grsecurity/grsum.c      1970-01-01 01:00:00.000000000 +0100
14675 +++ linux-2.6.8.grsecurity/grsecurity/grsum.c   2004-08-16 17:08:29.000000000 +0200
14676 @@ -0,0 +1,59 @@
14677 +#include <linux/kernel.h>
14678 +#include <linux/sched.h>
14679 +#include <linux/mm.h>
14680 +#include <asm/scatterlist.h>
14681 +#include <linux/crypto.h>
14682 +#include <linux/gracl.h>
14683 +
14684 +
14685 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
14686 +#error "crypto and sha256 must be built into the kernel"
14687 +#endif
14688 +
14689 +int
14690 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
14691 +{
14692 +       char *p;
14693 +       struct crypto_tfm *tfm;
14694 +       unsigned char temp_sum[GR_SHA_LEN];
14695 +       struct scatterlist sg[2];
14696 +       volatile int retval = 0;
14697 +       volatile int dummy = 0;
14698 +       unsigned int i;
14699 +
14700 +       tfm = crypto_alloc_tfm("sha256", 0);
14701 +       if (tfm == NULL) {
14702 +               /* should never happen, since sha256 should be built in */
14703 +               return 1;
14704 +       }
14705 +
14706 +       crypto_digest_init(tfm);
14707 +
14708 +       p = salt;
14709 +       sg[0].page = virt_to_page(p);
14710 +       sg[0].offset = ((long) p & ~PAGE_MASK);
14711 +       sg[0].length = GR_SALT_LEN;
14712 +       
14713 +       crypto_digest_update(tfm, sg, 1);
14714 +
14715 +       p = entry->pw;
14716 +       sg[0].page = virt_to_page(p);
14717 +       sg[0].offset = ((long) p & ~PAGE_MASK);
14718 +       sg[0].length = strlen(entry->pw);
14719 +
14720 +       crypto_digest_update(tfm, sg, 1);
14721 +
14722 +       crypto_digest_final(tfm, temp_sum);
14723 +
14724 +       memset(entry->pw, 0, GR_PW_LEN);
14725 +
14726 +       for (i = 0; i < GR_SHA_LEN; i++)
14727 +               if (sum[i] != temp_sum[i])
14728 +                       retval = 1;
14729 +               else
14730 +                       dummy = 1;      // waste a cycle
14731 +
14732 +       crypto_free_tfm(tfm);
14733 +
14734 +       return retval;
14735 +}
14736 diff -uNr linux-2.6.8/grsecurity/Kconfig linux-2.6.8.grsecurity/grsecurity/Kconfig
14737 --- linux-2.6.8/grsecurity/Kconfig      1970-01-01 01:00:00.000000000 +0100
14738 +++ linux-2.6.8.grsecurity/grsecurity/Kconfig   2004-08-16 17:08:29.000000000 +0200
14739 @@ -0,0 +1,1291 @@
14740 +#
14741 +# grecurity configuration
14742 +#
14743 +
14744 +menu "Grsecurity"
14745 +
14746 +config GRKERNSEC
14747 +       bool "Grsecurity"
14748 +       select CRYPTO
14749 +       select CRYPTO_SHA256
14750 +       help
14751 +         If you say Y here, you will be able to configure many features
14752 +         that will enhance the security of your system.  It is highly
14753 +         recommended that you say Y here and read through the help
14754 +         for each option so that you fully understand the features and
14755 +         can evaluate their usefulness for your machine.
14756 +
14757 +choice
14758 +       prompt "Security Level"
14759 +       depends GRKERNSEC
14760 +       default GRKERNSEC_CUSTOM
14761 +
14762 +config GRKERNSEC_LOW
14763 +       bool "Low"
14764 +       select GRKERNSEC_LINK
14765 +       select GRKERNSEC_FIFO
14766 +       select GRKERNSEC_RANDPID
14767 +       select GRKERNSEC_EXECVE
14768 +       select GRKERNSEC_RANDNET
14769 +       select GRKERNSEC_RANDISN
14770 +       select GRKERNSEC_DMESG
14771 +       select GRKERNSEC_RANDID
14772 +       select GRKERNSEC_CHROOT_CHDIR
14773 +       help
14774 +         If you choose this option, several of the grsecurity options will
14775 +         be enabled that will give you greater protection against a number
14776 +         of attacks, while assuring that none of your software will have any
14777 +         conflicts with the additional security measures.  If you run a lot
14778 +         of unusual software, or you are having problems with the higher
14779 +         security levels, you should say Y here.  With this option, the
14780 +         following features are enabled:
14781 +
14782 +         - Linking Restrictions
14783 +         - FIFO Restrictions
14784 +         - Randomized PIDs
14785 +         - Enforcing RLIMIT_NPROC on execve
14786 +         - Restricted dmesg
14787 +         - Randomized IP IDs
14788 +         - Enforced chdir("/") on chroot
14789 +
14790 +config GRKERNSEC_MEDIUM
14791 +       bool "Medium"
14792 +       select PAX_EI_PAX
14793 +       select PAX_PT_PAX_FLAGS
14794 +       select PAX_HAVE_ACL_FLAGS
14795 +       select GRKERNSEC_PROC_MEMMAP
14796 +       select GRKERNSEC_CHROOT_SYSCTL
14797 +       select GRKERNSEC_LINK
14798 +       select GRKERNSEC_FIFO
14799 +       select GRKERNSEC_RANDPID
14800 +       select GRKERNSEC_EXECVE
14801 +       select GRKERNSEC_DMESG
14802 +       select GRKERNSEC_RANDID
14803 +       select GRKERNSEC_RANDNET
14804 +       select GRKERNSEC_RANDISN
14805 +       select GRKERNSEC_RANDSRC
14806 +       select GRKERNSEC_RANDRPC
14807 +       select GRKERNSEC_FORKFAIL
14808 +       select GRKERNSEC_TIME
14809 +       select GRKERNSEC_SIGNAL
14810 +       select GRKERNSEC_CHROOT
14811 +       select GRKERNSEC_CHROOT_UNIX
14812 +       select GRKERNSEC_CHROOT_MOUNT
14813 +       select GRKERNSEC_CHROOT_PIVOT
14814 +       select GRKERNSEC_CHROOT_DOUBLE
14815 +       select GRKERNSEC_CHROOT_CHDIR
14816 +       select GRKERNSEC_CHROOT_MKNOD
14817 +       select GRKERNSEC_PROC
14818 +       select GRKERNSEC_PROC_USERGROUP
14819 +       select PAX_RANDUSTACK
14820 +       select PAX_ASLR
14821 +       select PAX_RANDMMAP
14822 +
14823 +       help
14824 +         If you say Y here, several features in addition to those included
14825 +         in the low additional security level will be enabled.  These
14826 +         features provide even more security to your system, though in rare
14827 +         cases they may be incompatible with very old or poorly written
14828 +         software.  If you enable this option, make sure that your auth
14829 +         service (identd) is running as gid 1001.  With this option, 
14830 +         the following features (in addition to those provided in the 
14831 +         low additional security level) will be enabled:
14832 +
14833 +         - Randomized TCP Source Ports
14834 +         - Failed Fork Logging
14835 +         - Time Change Logging
14836 +         - Signal Logging
14837 +         - Deny Mounts in chroot
14838 +         - Deny Double chrooting
14839 +         - Deny Sysctl Writes in chroot
14840 +         - Deny Mknod in chroot
14841 +         - Deny Access to Abstract AF_UNIX Sockets out of chroot
14842 +         - Deny pivot_root in chroot
14843 +         - Denied Writes of /dev/kmem, /dev/mem, and /dev/port
14844 +         - /proc restrictions with special GID set to 10 (usually wheel)
14845 +         - Address Space Layout Randomization (ASLR)
14846 +
14847 +config GRKERNSEC_HIGH
14848 +       bool "High"
14849 +       select GRKERNSEC_LINK
14850 +       select GRKERNSEC_FIFO
14851 +       select GRKERNSEC_RANDPID
14852 +       select GRKERNSEC_EXECVE
14853 +       select GRKERNSEC_DMESG
14854 +       select GRKERNSEC_RANDID
14855 +       select GRKERNSEC_RANDSRC
14856 +       select GRKERNSEC_RANDRPC
14857 +       select GRKERNSEC_FORKFAIL
14858 +       select GRKERNSEC_TIME
14859 +       select GRKERNSEC_SIGNAL
14860 +       select GRKERNSEC_CHROOT_SHMAT
14861 +       select GRKERNSEC_CHROOT_UNIX
14862 +       select GRKERNSEC_CHROOT_MOUNT
14863 +       select GRKERNSEC_CHROOT_FCHDIR
14864 +       select GRKERNSEC_CHROOT_PIVOT
14865 +       select GRKERNSEC_CHROOT_DOUBLE
14866 +       select GRKERNSEC_CHROOT_CHDIR
14867 +       select GRKERNSEC_CHROOT_MKNOD
14868 +       select GRKERNSEC_CHROOT_CAPS
14869 +       select GRKERNSEC_CHROOT_SYSCTL
14870 +       select GRKERNSEC_CHROOT_FINDTASK
14871 +       select GRKERNSEC_PROC
14872 +       select GRKERNSEC_PROC_MEMMAP
14873 +       select GRKERNSEC_HIDESYM
14874 +       select GRKERNSEC_BRUTE
14875 +       select GRKERNSEC_PROC_USERGROUP
14876 +       select GRKERNSEC_KMEM
14877 +       select GRKERNSEC_RESLOG
14878 +       select GRKERNSEC_RANDNET
14879 +       select GRKERNSEC_RANDISN
14880 +       select GRKERNSEC_PROC_ADD
14881 +       select GRKERNSEC_CHROOT_CHMOD
14882 +       select GRKERNSEC_CHROOT_NICE
14883 +       select GRKERNSEC_AUDIT_MOUNT
14884 +       select PAX_RANDUSTACK
14885 +       select PAX_ASLR
14886 +       select PAX_RANDMMAP
14887 +       select PAX_NOEXEC
14888 +       select PAX_MPROTECT
14889 +       select PAX_EI_PAX
14890 +       select PAX_PT_PAX_FLAGS
14891 +       select PAX_HAVE_ACL_FLAGS
14892 +       select PAX_KERNEXEC
14893 +       select PAX_RANDKSTACK
14894 +       select PAX_RANDEXEC
14895 +       select PAX_SEGMEXEC
14896 +       select PAX_EMUTRAMP
14897 +       select PAX_NOVSYSCALL
14898 +       help
14899 +         If you say Y here, many of the features of grsecurity will be
14900 +         enabled, which will protect you against many kinds of attacks
14901 +         against your system.  The heightened security comes at a cost
14902 +         of an increased chance of incompatibilities with rare software
14903 +         on your machine.  Since this security level enables PaX, you should
14904 +         view <http://pax.grsecurity.net> and read about the PaX
14905 +         project.  While you are there, download chpax and run it on
14906 +         binaries that cause problems with PaX.  Also remember that
14907 +         since the /proc restrictions are enabled, you must run your
14908 +         identd as gid 1001.  This security level enables the following 
14909 +         features in addition to those listed in the low and medium 
14910 +         security levels:
14911 +
14912 +         - Additional /proc Restrictions
14913 +         - Chmod Restrictions in chroot
14914 +         - No Signals, Ptrace, or Viewing of Processes Outside of chroot
14915 +         - Capability Restrictions in chroot
14916 +         - Deny fchdir out of chroot
14917 +         - Priority Restrictions in chroot
14918 +         - Segmentation-based Implementation of PaX
14919 +         - Mprotect Restrictions
14920 +         - Removal of Addresses from /proc/<pid>/[maps|stat]
14921 +         - Kernel Stack Randomization
14922 +         - Mount/Unmount/Remount Logging
14923 +         - Kernel Symbol Hiding
14924 +       
14925 +config GRKERNSEC_CUSTOM
14926 +       bool "Custom"
14927 +       help
14928 +         If you say Y here, you will be able to configure every grsecurity
14929 +         option, which allows you to enable many more features that aren't
14930 +         covered in the basic security levels.  These additional features
14931 +         include TPE, socket restrictions, and the sysctl system for
14932 +         grsecurity.  It is advised that you read through the help for
14933 +         each option to determine its usefulness in your situation.
14934 +
14935 +endchoice
14936 +
14937 +menu "Address Space Protection"
14938 +depends on GRKERNSEC
14939 +
14940 +config GRKERNSEC_KMEM
14941 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
14942 +       help
14943 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
14944 +         be written to via mmap or otherwise to modify the running kernel.
14945 +         /dev/port will also not be allowed to be opened. If you have module
14946 +         support disabled, enabling this will close up four ways that are
14947 +         currently used  to insert malicious code into the running kernel.
14948 +         Even with all these features enabled, we still highly recommend that
14949 +         you use the ACL system, as it is still possible for an attacker to
14950 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
14951 +         If you are not using XFree86, you may be able to stop this additional
14952 +         case by enabling the 'Disable privileged I/O' option. Though nothing
14953 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
14954 +         but only to video memory, which is the only writing we allow in this
14955 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
14956 +         not be allowed to mprotect it with PROT_WRITE later.
14957 +         Enabling this feature could make certain apps like VMWare stop working,
14958 +         as they need to write to other locations in /dev/mem.
14959 +         It is highly recommended that you say Y here if you meet all the
14960 +         conditions above.
14961 +
14962 +config GRKERNSEC_IO
14963 +       bool "Disable privileged I/O"
14964 +       depends on X86
14965 +       select RTC
14966 +       help
14967 +         If you say Y here, all ioperm and iopl calls will return an error.
14968 +         Ioperm and iopl can be used to modify the running kernel.
14969 +         Unfortunately, some programs need this access to operate properly,
14970 +         the most notable of which are XFree86 and hwclock.  hwclock can be
14971 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
14972 +         enabled if this option is enabled, to ensure that hwclock operates
14973 +         correctly.  XFree86 still will not operate correctly with this option
14974 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
14975 +         and you still want to protect your kernel against modification,
14976 +         use the ACL system.
14977 +
14978 +config GRKERNSEC_PROC_MEMMAP
14979 +       bool "Remove addresses from /proc/<pid>/[maps|stat]"
14980 +       help
14981 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
14982 +         give no information about the addresses of its mappings if
14983 +         PaX features that rely on random addresses are enabled on the task.
14984 +         If you use PaX it is greatly recommended that you say Y here as it
14985 +         closes up a hole that makes the full ASLR useless for suid
14986 +         binaries.
14987 +
14988 +config GRKERNSEC_BRUTE
14989 +       bool "Deter exploit bruteforcing"
14990 +       help
14991 +         If you say Y here, attempts to bruteforce exploits against forking
14992 +         daemons such as apache or sshd will be deterred.  When a child of a
14993 +         forking daemon is killed by PaX or crashes due to an illegal
14994 +         instruction, the parent process will be delayed 30 seconds upon every
14995 +         subsequent fork until the administrator is able to assess the
14996 +         situation and restart the daemon.  It is recommended that you also
14997 +         enable signal logging in the auditing section so that logs are
14998 +         generated when a process performs an illegal instruction.
14999 +
15000 +config GRKERNSEC_HIDESYM
15001 +       bool "Hide kernel symbols"
15002 +       help
15003 +         If you say Y here, getting information on loaded modules, and
15004 +         displaying all kernel symbols through a syscall will be restricted
15005 +         to users with CAP_SYS_MODULE.  This option is only effective
15006 +         provided the following conditions are met:
15007 +         1) The kernel using grsecurity is not precompiled by some distribution
15008 +         2) You are using the ACL system and hiding other files such as your
15009 +            kernel image and System.map
15010 +         3) You have the additional /proc restrictions enabled, which removes
15011 +            /proc/kcore
15012 +         If the above conditions are met, this option will aid to provide a
15013 +         useful protection against local and remote kernel exploitation of
15014 +         overflows and arbitrary read/write vulnerabilities.
15015 +
15016 +endmenu
15017 +menu "Role Based Access Control Options"
15018 +depends on GRKERNSEC
15019 +
15020 +config GRKERNSEC_ACL_HIDEKERN
15021 +       bool "Hide kernel processes"
15022 +       help
15023 +         If you say Y here, when the RBAC system is enabled via gradm -E,
15024 +         an additional ACL will be passed to the kernel that hides all kernel
15025 +         processes.  These processes will only be viewable by the authenticated
15026 +         admin, or processes that have viewing access set.
15027 +
15028 +config GRKERNSEC_ACL_MAXTRIES
15029 +       int "Maximum tries before password lockout"
15030 +       default 3
15031 +       help
15032 +         This option enforces the maximum number of times a user can attempt
15033 +         to authorize themselves with the grsecurity ACL system before being
15034 +         denied the ability to attempt authorization again for a specified time.
15035 +         The lower the number, the harder it will be to brute-force a password.
15036 +
15037 +config GRKERNSEC_ACL_TIMEOUT
15038 +       int "Time to wait after max password tries, in seconds"
15039 +       default 30
15040 +       help
15041 +         This option specifies the time the user must wait after attempting to
15042 +         authorize to the ACL system with the maximum number of invalid
15043 +         passwords.  The higher the number, the harder it will be to brute-force
15044 +         a password.
15045 +
15046 +endmenu
15047 +menu "Filesystem Protections"
15048 +depends on GRKERNSEC
15049 +
15050 +config GRKERNSEC_PROC
15051 +       bool "Proc restrictions"
15052 +       help
15053 +         If you say Y here, the permissions of the /proc filesystem
15054 +         will be altered to enhance system security and privacy.  Depending
15055 +         upon the options you choose, you can either restrict users to see
15056 +         only the processes they themselves run, or choose a group that can
15057 +         view all processes and files normally restricted to root if you choose
15058 +         the "restrict to user only" option.  NOTE: If you're running identd as
15059 +         a non-root user, you will have to run it as the group you specify here.
15060 +
15061 +config GRKERNSEC_PROC_USER
15062 +       bool "Restrict /proc to user only"
15063 +       depends on GRKERNSEC_PROC
15064 +       help
15065 +         If you say Y here, non-root users will only be able to view their own
15066 +         processes, and restricts them from viewing network-related information,
15067 +         and viewing kernel symbol and module information.
15068 +
15069 +config GRKERNSEC_PROC_USERGROUP
15070 +       bool "Allow special group"
15071 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
15072 +       help
15073 +         If you say Y here, you will be able to select a group that will be
15074 +         able to view all processes, network-related information, and
15075 +         kernel and symbol information.  This option is useful if you want
15076 +         to run identd as a non-root user.
15077 +
15078 +config GRKERNSEC_PROC_GID
15079 +       int "GID for special group"
15080 +       depends on GRKERNSEC_PROC_USERGROUP
15081 +       default 1001
15082 +
15083 +config GRKERNSEC_PROC_ADD
15084 +       bool "Additional restrictions"
15085 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
15086 +       help
15087 +         If you say Y here, additional restrictions will be placed on
15088 +         /proc that keep normal users from viewing cpu and device information.
15089 +
15090 +config GRKERNSEC_LINK
15091 +       bool "Linking restrictions"
15092 +       help
15093 +         If you say Y here, /tmp race exploits will be prevented, since users
15094 +         will no longer be able to follow symlinks owned by other users in
15095 +         world-writable +t directories (i.e. /tmp), unless the owner of the
15096 +         symlink is the owner of the directory. users will also not be
15097 +         able to hardlink to files they do not own.  If the sysctl option is
15098 +         enabled, a sysctl option with name "linking_restrictions" is created.
15099 +
15100 +config GRKERNSEC_FIFO
15101 +       bool "FIFO restrictions"
15102 +       help
15103 +         If you say Y here, users will not be able to write to FIFOs they don't
15104 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
15105 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
15106 +         option is enabled, a sysctl option with name "fifo_restrictions" is
15107 +         created.
15108 +
15109 +config GRKERNSEC_CHROOT
15110 +       bool "Chroot jail restrictions"
15111 +       help
15112 +         If you say Y here, you will be able to choose several options that will
15113 +         make breaking out of a chrooted jail much more difficult.  If you
15114 +         encounter no software incompatibilities with the following options, it
15115 +         is recommended that you enable each one.
15116 +
15117 +config GRKERNSEC_CHROOT_MOUNT
15118 +       bool "Deny mounts"
15119 +       depends on GRKERNSEC_CHROOT
15120 +       help
15121 +         If you say Y here, processes inside a chroot will not be able to
15122 +         mount or remount filesystems.  If the sysctl option is enabled, a
15123 +         sysctl option with name "chroot_deny_mount" is created.
15124 +
15125 +config GRKERNSEC_CHROOT_DOUBLE
15126 +       bool "Deny double-chroots"
15127 +       depends on GRKERNSEC_CHROOT
15128 +       help
15129 +         If you say Y here, processes inside a chroot will not be able to chroot
15130 +         again outside the chroot.  This is a widely used method of breaking
15131 +         out of a chroot jail and should not be allowed.  If the sysctl 
15132 +         option is enabled, a sysctl option with name 
15133 +         "chroot_deny_chroot" is created.
15134 +
15135 +config GRKERNSEC_CHROOT_PIVOT
15136 +       bool "Deny pivot_root in chroot"
15137 +       depends on GRKERNSEC_CHROOT
15138 +       help
15139 +         If you say Y here, processes inside a chroot will not be able to use
15140 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
15141 +         works similar to chroot in that it changes the root filesystem.  This
15142 +         function could be misused in a chrooted process to attempt to break out
15143 +         of the chroot, and therefore should not be allowed.  If the sysctl
15144 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
15145 +         created.
15146 +
15147 +config GRKERNSEC_CHROOT_CHDIR
15148 +       bool "Enforce chdir(\"/\") on all chroots"
15149 +       depends on GRKERNSEC_CHROOT
15150 +       help
15151 +         If you say Y here, the current working directory of all newly-chrooted
15152 +         applications will be set to the the root directory of the chroot.
15153 +         The man page on chroot(2) states:
15154 +         Note that this call does not change  the  current  working
15155 +         directory,  so  that `.' can be outside the tree rooted at
15156 +         `/'.  In particular, the  super-user  can  escape  from  a
15157 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
15158 +
15159 +         It is recommended that you say Y here, since it's not known to break
15160 +         any software.  If the sysctl option is enabled, a sysctl option with
15161 +         name "chroot_enforce_chdir" is created.
15162 +
15163 +config GRKERNSEC_CHROOT_CHMOD
15164 +       bool "Deny (f)chmod +s"
15165 +       depends on GRKERNSEC_CHROOT
15166 +       help
15167 +         If you say Y here, processes inside a chroot will not be able to chmod
15168 +         or fchmod files to make them have suid or sgid bits.  This protects
15169 +         against another published method of breaking a chroot.  If the sysctl
15170 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
15171 +         created.
15172 +
15173 +config GRKERNSEC_CHROOT_FCHDIR
15174 +       bool "Deny fchdir out of chroot"
15175 +       depends on GRKERNSEC_CHROOT
15176 +       help
15177 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
15178 +         to a file descriptor of the chrooting process that points to a directory
15179 +         outside the filesystem will be stopped.  If the sysctl option
15180 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
15181 +
15182 +config GRKERNSEC_CHROOT_MKNOD
15183 +       bool "Deny mknod"
15184 +       depends on GRKERNSEC_CHROOT
15185 +       help
15186 +         If you say Y here, processes inside a chroot will not be allowed to
15187 +         mknod.  The problem with using mknod inside a chroot is that it
15188 +         would allow an attacker to create a device entry that is the same
15189 +         as one on the physical root of your system, which could range from
15190 +         anything from the console device to a device for your harddrive (which
15191 +         they could then use to wipe the drive or steal data).  It is recommended
15192 +         that you say Y here, unless you run into software incompatibilities.
15193 +         If the sysctl option is enabled, a sysctl option with name
15194 +         "chroot_deny_mknod" is created.
15195 +
15196 +config GRKERNSEC_CHROOT_SHMAT
15197 +       bool "Deny shmat() out of chroot"
15198 +       depends on GRKERNSEC_CHROOT
15199 +       help
15200 +         If you say Y here, processes inside a chroot will not be able to attach
15201 +         to shared memory segments that were created outside of the chroot jail.
15202 +         It is recommended that you say Y here.  If the sysctl option is enabled,
15203 +         a sysctl option with name "chroot_deny_shmat" is created.
15204 +
15205 +config GRKERNSEC_CHROOT_UNIX
15206 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
15207 +       depends on GRKERNSEC_CHROOT
15208 +       help
15209 +         If you say Y here, processes inside a chroot will not be able to
15210 +         connect to abstract (meaning not belonging to a filesystem) Unix
15211 +         domain sockets that were bound outside of a chroot.  It is recommended
15212 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
15213 +         with name "chroot_deny_unix" is created.
15214 +
15215 +config GRKERNSEC_CHROOT_FINDTASK
15216 +       bool "Protect outside processes"
15217 +       depends on GRKERNSEC_CHROOT
15218 +       help
15219 +         If you say Y here, processes inside a chroot will not be able to
15220 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
15221 +         getsid, or view any process outside of the chroot.  If the sysctl
15222 +         option is enabled, a sysctl option with name "chroot_findtask" is
15223 +         created.
15224 +
15225 +config GRKERNSEC_CHROOT_NICE
15226 +       bool "Restrict priority changes"
15227 +       depends on GRKERNSEC_CHROOT
15228 +       help
15229 +         If you say Y here, processes inside a chroot will not be able to raise
15230 +         the priority of processes in the chroot, or alter the priority of
15231 +         processes outside the chroot.  This provides more security than simply
15232 +         removing CAP_SYS_NICE from the process' capability set.  If the
15233 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
15234 +         is created.
15235 +
15236 +config GRKERNSEC_CHROOT_SYSCTL
15237 +       bool "Deny sysctl writes"
15238 +       depends on GRKERNSEC_CHROOT
15239 +       help
15240 +         If you say Y here, an attacker in a chroot will not be able to
15241 +         write to sysctl entries, either by sysctl(2) or through a /proc
15242 +         interface.  It is strongly recommended that you say Y here. If the
15243 +         sysctl option is enabled, a sysctl option with name
15244 +         "chroot_deny_sysctl" is created.
15245 +
15246 +config GRKERNSEC_CHROOT_CAPS
15247 +       bool "Capability restrictions"
15248 +       depends on GRKERNSEC_CHROOT
15249 +       help
15250 +         If you say Y here, the capabilities on all root processes within a
15251 +         chroot jail will be lowered to stop module insertion, raw i/o,
15252 +         system and net admin tasks, rebooting the system, modifying immutable
15253 +         files, modifying IPC owned by another, and changing the system time.
15254 +         This is left an option because it can break some apps.  Disable this
15255 +         if your chrooted apps are having problems performing those kinds of
15256 +         tasks.  If the sysctl option is enabled, a sysctl option with
15257 +         name "chroot_caps" is created.
15258 +
15259 +endmenu
15260 +menu "Kernel Auditing"
15261 +depends on GRKERNSEC
15262 +
15263 +config GRKERNSEC_AUDIT_GROUP
15264 +       bool "Single group for auditing"
15265 +       help
15266 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
15267 +         will only operate on a group you specify.  This option is recommended
15268 +         if you only want to watch certain users instead of having a large
15269 +         amount of logs from the entire system.  If the sysctl option is enabled,
15270 +         a sysctl option with name "audit_group" is created.
15271 +
15272 +config GRKERNSEC_AUDIT_GID
15273 +       int "GID for auditing"
15274 +       depends on GRKERNSEC_AUDIT_GROUP
15275 +       default 1007
15276 +
15277 +config GRKERNSEC_EXECLOG
15278 +       bool "Exec logging"
15279 +       help
15280 +         If you say Y here, all execve() calls will be logged (since the
15281 +         other exec*() calls are frontends to execve(), all execution
15282 +         will be logged).  Useful for shell-servers that like to keep track
15283 +         of their users.  If the sysctl option is enabled, a sysctl option with
15284 +         name "exec_logging" is created.
15285 +         WARNING: This option when enabled will produce a LOT of logs, especially
15286 +         on an active system.
15287 +
15288 +config GRKERNSEC_RESLOG
15289 +       bool "Resource logging"
15290 +       help
15291 +         If you say Y here, all attempts to overstep resource limits will
15292 +         be logged with the resource name, the requested size, and the current
15293 +         limit.  It is highly recommended that you say Y here.
15294 +
15295 +config GRKERNSEC_CHROOT_EXECLOG
15296 +       bool "Log execs within chroot"
15297 +       help
15298 +         If you say Y here, all executions inside a chroot jail will be logged
15299 +         to syslog.  This can cause a large amount of logs if certain
15300 +         applications (eg. djb's daemontools) are installed on the system, and
15301 +         is therefore left as an option.  If the sysctl option is enabled, a
15302 +         sysctl option with name "chroot_execlog" is created.
15303 +
15304 +config GRKERNSEC_AUDIT_CHDIR
15305 +       bool "Chdir logging"
15306 +       help
15307 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
15308 +         option is enabled, a sysctl option with name "audit_chdir" is created.
15309 +
15310 +config GRKERNSEC_AUDIT_MOUNT
15311 +       bool "(Un)Mount logging"
15312 +       help
15313 +         If you say Y here, all mounts and unmounts will be logged.  If the
15314 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
15315 +         created.
15316 +
15317 +config GRKERNSEC_AUDIT_IPC
15318 +       bool "IPC logging"
15319 +       help
15320 +         If you say Y here, creation and removal of message queues, semaphores,
15321 +         and shared memory will be logged.  If the sysctl option is enabled, a
15322 +         sysctl option with name "audit_ipc" is created.
15323 +
15324 +config GRKERNSEC_SIGNAL
15325 +       bool "Signal logging"
15326 +       help
15327 +         If you say Y here, certain important signals will be logged, such as
15328 +         SIGSEGV, which will as a result inform you of when a error in a program
15329 +         occurred, which in some cases could mean a possible exploit attempt.
15330 +         If the sysctl option is enabled, a sysctl option with name
15331 +         "signal_logging" is created.
15332 +
15333 +config GRKERNSEC_FORKFAIL
15334 +       bool "Fork failure logging"
15335 +       help
15336 +         If you say Y here, all failed fork() attempts will be logged.
15337 +         This could suggest a fork bomb, or someone attempting to overstep
15338 +         their process limit.  If the sysctl option is enabled, a sysctl option
15339 +         with name "forkfail_logging" is created.
15340 +
15341 +config GRKERNSEC_TIME
15342 +       bool "Time change logging"
15343 +       help
15344 +         If you say Y here, any changes of the system clock will be logged.
15345 +         If the sysctl option is enabled, a sysctl option with name
15346 +         "timechange_logging" is created.
15347 +
15348 +config GRKERNSEC_PROC_IPADDR
15349 +       bool "/proc/<pid>/ipaddr support"
15350 +       help
15351 +         If you say Y here, a new entry will be added to each /proc/<pid>
15352 +         directory that contains the IP address of the person using the task.
15353 +         The IP is carried across local TCP and AF_UNIX stream sockets.
15354 +         This information can be useful for IDS/IPSes to perform remote response
15355 +         to a local attack.  The entry is readable by only the owner of the
15356 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
15357 +         the RBAC system), and thus does not create privacy concerns.
15358 +
15359 +config GRKERNSEC_AUDIT_TEXTREL
15360 +       bool 'ELF text relocations logging (READ HELP)'
15361 +       depends on PAX_MPROTECT
15362 +       help
15363 +         If you say Y here, text relocations will be logged with the filename
15364 +         of the offending library or binary.  The purpose of the feature is
15365 +         to help Linux distribution developers get rid of libraries and
15366 +         binaries that need text relocations which hinder the future progress
15367 +         of PaX.  Only Linux distribution developers should say Y here, and
15368 +         never on a production machine, as this option creates an information
15369 +         leak that could aid an attacker in defeating the randomization of
15370 +         a single memory region.  If the sysctl option is enabled, a sysctl
15371 +         option with name "audit_textrel" is created.
15372 +
15373 +endmenu
15374 +
15375 +menu "Executable Protections"
15376 +depends on GRKERNSEC
15377 +
15378 +config GRKERNSEC_EXECVE
15379 +       bool "Enforce RLIMIT_NPROC on execs"
15380 +       help
15381 +         If you say Y here, users with a resource limit on processes will
15382 +         have the value checked during execve() calls.  The current system
15383 +         only checks the system limit during fork() calls.  If the sysctl option
15384 +         is enabled, a sysctl option with name "execve_limiting" is created.
15385 +
15386 +config GRKERNSEC_DMESG
15387 +       bool "Dmesg(8) restriction"
15388 +       help
15389 +         If you say Y here, non-root users will not be able to use dmesg(8)
15390 +         to view up to the last 4kb of messages in the kernel's log buffer.
15391 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
15392 +         created.
15393 +
15394 +config GRKERNSEC_RANDPID
15395 +       bool "Randomized PIDs"
15396 +       help
15397 +         If you say Y here, all PIDs created on the system will be
15398 +         pseudo-randomly generated.  This is extremely effective along
15399 +         with the /proc restrictions to disallow an attacker from guessing
15400 +         pids of daemons, etc.  PIDs are also used in some cases as part
15401 +         of a naming system for temporary files, so this option would keep
15402 +         those filenames from being predicted as well.  We also use code
15403 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
15404 +         option is enabled, a sysctl option with name "rand_pids" is created.
15405 +
15406 +config GRKERNSEC_TPE
15407 +       bool "Trusted Path Execution (TPE)"
15408 +       help
15409 +         If you say Y here, you will be able to choose a gid to add to the
15410 +         supplementary groups of users you want to mark as "untrusted."
15411 +         These users will not be able to execute any files that are not in
15412 +         root-owned directories writable only by root.  If the sysctl option
15413 +         is enabled, a sysctl option with name "tpe" is created.
15414 +
15415 +config GRKERNSEC_TPE_ALL
15416 +       bool "Partially restrict non-root users"
15417 +       depends on GRKERNSEC_TPE
15418 +       help
15419 +         If you say Y here, All non-root users other than the ones in the
15420 +         group specified in the main TPE option will only be allowed to
15421 +         execute files in directories they own that are not group or
15422 +         world-writable, or in directories owned by root and writable only by
15423 +         root.  If the sysctl option is enabled, a sysctl option with name
15424 +         "tpe_restrict_all" is created.
15425 +
15426 +config GRKERNSEC_TPE_GID
15427 +       int "GID for untrusted users"
15428 +       depends on GRKERNSEC_TPE
15429 +       default 1005
15430 +       help
15431 +         Here you can choose the GID to enable trusted path protection for.
15432 +         Remember to add the users you want protection enabled for to the GID
15433 +         specified here.  If the sysctl option is enabled, whatever you choose
15434 +         here won't matter. You'll have to specify the GID in your bootup
15435 +         script by echoing the GID to the proper /proc entry.  View the help
15436 +         on the sysctl option for more information.  If the sysctl option is
15437 +         enabled, a sysctl option with name "tpe_gid" is created.
15438 +
15439 +endmenu
15440 +menu "Network Protections"
15441 +depends on GRKERNSEC
15442 +
15443 +config GRKERNSEC_RANDNET
15444 +       bool "Larger entropy pools"
15445 +       help
15446 +         If you say Y here, the entropy pools used for many features of Linux
15447 +         and grsecurity will be doubled in size.  Since several grsecurity
15448 +         features use additional randomness, it is recommended that you say Y
15449 +         here.  Saying Y here has a similar effect as modifying
15450 +         /proc/sys/kernel/random/poolsize.
15451 +
15452 +config GRKERNSEC_RANDISN
15453 +       bool "Truly random TCP ISN selection"
15454 +       help
15455 +         If you say Y here, Linux's default selection of TCP Initial Sequence
15456 +         Numbers (ISNs) will be replaced with that of OpenBSD.  Linux uses
15457 +         an MD4 hash based on the connection plus a time value to create the
15458 +         ISN, while OpenBSD's selection is random.  If the sysctl option is
15459 +         enabled, a sysctl option with name "rand_isns" is created.
15460 +
15461 +config GRKERNSEC_RANDID
15462 +       bool "Randomized IP IDs"
15463 +       help
15464 +         If you say Y here, all the id field on all outgoing packets
15465 +         will be randomized.  This hinders os fingerprinters and
15466 +         keeps your machine from being used as a bounce for an untraceable
15467 +         portscan.  Ids are used for fragmented packets, fragments belonging
15468 +         to the same packet have the same id.  By default linux only
15469 +         increments the id value on each packet sent to an individual host.
15470 +         We use a port of the OpenBSD random ip id code to achieve the
15471 +         randomness, while keeping the possibility of id duplicates to
15472 +         near none.  If the sysctl option is enabled, a sysctl option with name
15473 +         "rand_ip_ids" is created.
15474 +
15475 +config GRKERNSEC_RANDSRC
15476 +       bool "Randomized TCP source ports"
15477 +       default n if GRKERNSEC_LOW || GRKERNSEC_MID
15478 +       default y if GRKERNSEC_HIGH
15479 +       help
15480 +         If you say Y here, situations where a source port is generated on the
15481 +         fly for the TCP protocol (ie. with connect() ) will be altered so that
15482 +         the source port is generated at random, instead of a simple incrementing
15483 +         algorithm.  If the sysctl option is enabled, a sysctl option with name
15484 +         "rand_tcp_src_ports" is created.
15485 +
15486 +config GRKERNSEC_RANDRPC
15487 +       bool "Randomized RPC XIDs"
15488 +       help
15489 +         If you say Y here, the method of determining XIDs for RPC requests will
15490 +         be randomized, instead of using linux's default behavior of simply
15491 +         incrementing the XID.  If you want your RPC connections to be more
15492 +         secure, say Y here.  If the sysctl option is enabled, a sysctl option
15493 +         with name "rand_rpc" is created.
15494 +
15495 +config GRKERNSEC_SOCKET
15496 +       bool "Socket restrictions"
15497 +       help
15498 +         If you say Y here, you will be able to choose from several options.
15499 +         If you assign a GID on your system and add it to the supplementary
15500 +         groups of users you want to restrict socket access to, this patch
15501 +         will perform up to three things, based on the option(s) you choose.
15502 +
15503 +config GRKERNSEC_SOCKET_ALL
15504 +       bool "Deny any sockets to group"
15505 +       depends on GRKERNSEC_SOCKET
15506 +       help
15507 +         If you say Y here, you will be able to choose a GID of whose users will
15508 +         be unable to connect to other hosts from your machine or run server
15509 +         applications from your machine.  If the sysctl option is enabled, a
15510 +         sysctl option with name "socket_all" is created.
15511 +
15512 +config GRKERNSEC_SOCKET_ALL_GID
15513 +       int "GID to deny all sockets for"
15514 +       depends on GRKERNSEC_SOCKET_ALL
15515 +       default 1004
15516 +       help
15517 +         Here you can choose the GID to disable socket access for. Remember to
15518 +         add the users you want socket access disabled for to the GID
15519 +         specified here.  If the sysctl option is enabled, whatever you choose
15520 +         here won't matter. You'll have to specify the GID in your bootup
15521 +         script by echoing the GID to the proper /proc entry.  View the help
15522 +         on the sysctl option for more information.  If the sysctl option is
15523 +         enabled, a sysctl option with name "socket_all_gid" is created.
15524 +
15525 +config GRKERNSEC_SOCKET_CLIENT
15526 +       bool "Deny client sockets to group"
15527 +       depends on GRKERNSEC_SOCKET
15528 +       help
15529 +         If you say Y here, you will be able to choose a GID of whose users will
15530 +         be unable to connect to other hosts from your machine, but will be
15531 +         able to run servers.  If this option is enabled, all users in the group
15532 +         you specify will have to use passive mode when initiating ftp transfers
15533 +         from the shell on your machine.  If the sysctl option is enabled, a
15534 +         sysctl option with name "socket_client" is created.
15535 +
15536 +config GRKERNSEC_SOCKET_CLIENT_GID
15537 +       int "GID to deny client sockets for"
15538 +       depends on GRKERNSEC_SOCKET_CLIENT
15539 +       default 1003
15540 +       help
15541 +         Here you can choose the GID to disable client socket access for.
15542 +         Remember to add the users you want client socket access disabled for to
15543 +         the GID specified here.  If the sysctl option is enabled, whatever you
15544 +         choose here won't matter. You'll have to specify the GID in your bootup
15545 +         script by echoing the GID to the proper /proc entry.  View the help
15546 +         on the sysctl option for more information.  If the sysctl option is
15547 +         enabled, a sysctl option with name "socket_client_gid" is created.
15548 +
15549 +config GRKERNSEC_SOCKET_SERVER
15550 +       bool "Deny server sockets to group"
15551 +       depends on GRKERNSEC_SOCKET
15552 +       help
15553 +         If you say Y here, you will be able to choose a GID of whose users will
15554 +         be unable to run server applications from your machine.  If the sysctl
15555 +         option is enabled, a sysctl option with name "socket_server" is created.
15556 +
15557 +config GRKERNSEC_SOCKET_SERVER_GID
15558 +       int "GID to deny server sockets for"
15559 +       depends on GRKERNSEC_SOCKET_SERVER
15560 +       default 1002
15561 +       help
15562 +         Here you can choose the GID to disable server socket access for.
15563 +         Remember to add the users you want server socket access disabled for to
15564 +         the GID specified here.  If the sysctl option is enabled, whatever you
15565 +         choose here won't matter. You'll have to specify the GID in your bootup
15566 +         script by echoing the GID to the proper /proc entry.  View the help
15567 +         on the sysctl option for more information.  If the sysctl option is
15568 +         enabled, a sysctl option with name "socket_server_gid" is created.
15569 +
15570 +endmenu
15571 +menu "Sysctl support"
15572 +depends on GRKERNSEC && SYSCTL
15573 +
15574 +config GRKERNSEC_SYSCTL
15575 +       bool "Sysctl support"
15576 +       help
15577 +         If you say Y here, you will be able to change the options that
15578 +         grsecurity runs with at bootup, without having to recompile your
15579 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
15580 +         to enable (1) or disable (0) various features.  All the sysctl entries
15581 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
15582 +         All features are disabled by default. Please note that this option could
15583 +         reduce the effectiveness of the added security of this patch if an ACL
15584 +         system is not put in place.  Your init scripts should be read-only, and
15585 +         root should not have access to adding modules or performing raw i/o
15586 +         operations.  All options should be set at startup, and the grsec_lock
15587 +         entry should be set to a non-zero value after all the options are set.
15588 +         *THIS IS EXTREMELY IMPORTANT*
15589 +
15590 +endmenu
15591 +menu "Logging Options"
15592 +depends on GRKERNSEC
15593 +
15594 +config GRKERNSEC_FLOODTIME
15595 +       int "Seconds in between log messages (minimum)"
15596 +       default 10
15597 +       help
15598 +         This option allows you to enforce the number of seconds between
15599 +         grsecurity log messages.  The default should be suitable for most
15600 +         people, however, if you choose to change it, choose a value small enough
15601 +         to allow informative logs to be produced, but large enough to
15602 +         prevent flooding.
15603 +
15604 +config GRKERNSEC_FLOODBURST
15605 +       int "Number of messages in a burst (maximum)"
15606 +       default 4
15607 +       help
15608 +         This option allows you to choose the maximum number of messages allowed
15609 +         within the flood time interval you chose in a separate option.  The
15610 +         default should be suitable for most people, however if you find that
15611 +         many of your logs are being interpreted as flooding, you may want to
15612 +         raise this value.
15613 +
15614 +endmenu
15615 +
15616 +menu "PaX"
15617 +depends on GRKERNSEC
15618 +
15619 +config PAX
15620 +       bool "Enable various PaX features"
15621 +       depends on ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64
15622 +       help
15623 +         This allows you to enable various PaX features.  PaX adds
15624 +         intrusion prevention mechanisms to the kernel that reduce
15625 +         the risks posed by exploitable memory corruption bugs.
15626 +
15627 +menu "PaX Control"
15628 +       depends on PAX
15629 +
15630 +config PAX_SOFTMODE
15631 +       bool 'Support soft mode'
15632 +       help
15633 +         Enabling this option will allow you to run PaX in soft mode, that
15634 +         is, PaX features will not be enforced by default, only on executables
15635 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
15636 +         is the only way to mark executables for soft mode use.
15637 +
15638 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
15639 +         line option on boot.  Furthermore you can control various PaX features
15640 +         at runtime via the entries in /proc/sys/kernel/pax.
15641 +
15642 +config PAX_EI_PAX
15643 +       bool 'Use legacy ELF header marking'
15644 +       help
15645 +         Enabling this option will allow you to control PaX features on
15646 +         a per executable basis via the 'chpax' utility available at
15647 +         http://pax.grsecurity.net/.  The control flags will be read from
15648 +         an otherwise reserved part of the ELF header.  This marking has
15649 +         numerous drawbacks (no support for soft-mode, toolchain does not
15650 +         know about the non-standard use of the ELF header) therefore it
15651 +         has been deprecated in favour of PT_PAX_FLAGS support.
15652 +
15653 +         You should enable this option only if your toolchain does not yet
15654 +         support the new control flag location (PT_PAX_FLAGS) or you still
15655 +         have applications not marked by PT_PAX_FLAGS.
15656 +
15657 +         Note that if you enable PT_PAX_FLAGS marking support as well,
15658 +         it will override the legacy EI_PAX marks.
15659 +
15660 +config PAX_PT_PAX_FLAGS
15661 +       bool 'Use ELF program header marking'
15662 +       help
15663 +         Enabling this option will allow you to control PaX features on
15664 +         a per executable basis via the 'paxctl' utility available at
15665 +         http://pax.grsecurity.net/.  The control flags will be read from
15666 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
15667 +         has the benefits of supporting both soft mode and being fully
15668 +         integrated into the toolchain (the binutils patch is available
15669 +         from http://pax.grsecurity.net).
15670 +
15671 +         Note that if you enable the legacy EI_PAX marking support as well,
15672 +         it will be overridden by the PT_PAX_FLAGS marking.
15673 +
15674 +choice
15675 +       prompt 'MAC system integration'
15676 +       default PAX_NO_ACL_FLAGS
15677 +       help
15678 +         Mandatory Access Control systems have the option of controlling
15679 +         PaX flags on a per executable basis, choose the method supported
15680 +         by your particular system.
15681 +
15682 +         - "none": if your MAC system does not interact with PaX,
15683 +         - "direct": if your MAC system defines pax_set_flags() itself,
15684 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
15685 +
15686 +         NOTE: this option is for developers/integrators only.
15687 +
15688 +config PAX_NO_ACL_FLAGS
15689 +       bool 'none'
15690 +
15691 +config PAX_HAVE_ACL_FLAGS
15692 +       bool 'direct'
15693 +
15694 +config PAX_HOOK_ACL_FLAGS
15695 +       bool 'hook'
15696 +endchoice
15697 +
15698 +endmenu
15699 +
15700 +menu "Non-executable pages"
15701 +       depends on PAX
15702 +
15703 +config PAX_NOEXEC
15704 +       bool "Enforce non-executable pages"
15705 +       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)
15706 +       help
15707 +         By design some architectures do not allow for protecting memory
15708 +         pages against execution or even if they do, Linux does not make
15709 +         use of this feature.  In practice this means that if a page is
15710 +         readable (such as the stack or heap) it is also executable.
15711 +
15712 +         There is a well known exploit technique that makes use of this
15713 +         fact and a common programming mistake where an attacker can
15714 +         introduce code of his choice somewhere in the attacked program's
15715 +         memory (typically the stack or the heap) and then execute it.
15716 +
15717 +         If the attacked program was running with different (typically
15718 +         higher) privileges than that of the attacker, then he can elevate
15719 +         his own privilege level (e.g. get a root shell, write to files for
15720 +         which he does not have write access to, etc).
15721 +
15722 +         Enabling this option will let you choose from various features
15723 +         that prevent the injection and execution of 'foreign' code in
15724 +         a program.
15725 +
15726 +         This will also break programs that rely on the old behaviour and
15727 +         expect that dynamically allocated memory via the malloc() family
15728 +         of functions is executable (which it is not).  Notable examples
15729 +         are the XFree86 4.x server, the java runtime and wine.
15730 +
15731 +config PAX_PAGEEXEC
15732 +       bool "Paging based non-executable pages"
15733 +       depends on PAX_NOEXEC && !HIGHPTE && (!X86 || X86_64 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUM4 || MK7 || MK8)
15734 +       select PAX_NOVSYSCALL if X86 && !X86_64
15735 +       help
15736 +         This implementation is based on the paging feature of the CPU.
15737 +         On i386 and ppc there is a variable but usually low performance
15738 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
15739 +         and x86_64 there is no performance impact.
15740 +
15741 +config PAX_SEGMEXEC
15742 +       bool "Segmentation based non-executable pages"
15743 +       depends on PAX_NOEXEC && X86 && !X86_64
15744 +       help
15745 +         This implementation is based on the segmentation feature of the
15746 +         CPU and has little performance impact, however applications will
15747 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
15748 +
15749 +choice
15750 +       prompt "Default non-executable page method"
15751 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
15752 +       default PAX_DEFAULT_SEGMEXEC
15753 +       help
15754 +         Select the default non-executable page method applied to applications
15755 +         that do not select one themselves.
15756 +
15757 +config PAX_DEFAULT_PAGEEXEC
15758 +       bool "PAGEEXEC"
15759 +
15760 +config PAX_DEFAULT_SEGMEXEC
15761 +       bool "SEGMEXEC"
15762 +endchoice
15763 +
15764 +config PAX_EMUTRAMP
15765 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86) && !X86_64
15766 +       default y if PARISC || PPC32
15767 +       help
15768 +         There are some programs and libraries that for one reason or
15769 +         another attempt to execute special small code snippets from
15770 +         non-executable memory pages.  Most notable examples are the
15771 +         signal handler return code generated by the kernel itself and
15772 +         the GCC trampolines.
15773 +
15774 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
15775 +         such programs will no longer work under your kernel.
15776 +
15777 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
15778 +         utilities to enable trampoline emulation for the affected programs
15779 +         yet still have the protection provided by the non-executable pages.
15780 +
15781 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
15782 +         well, otherwise your system will not even boot.
15783 +
15784 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
15785 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
15786 +         for the affected files.
15787 +
15788 +         NOTE: enabling this feature *may* open up a loophole in the
15789 +         protection provided by non-executable pages that an attacker
15790 +         could abuse.  Therefore the best solution is to not have any
15791 +         files on your system that would require this option.  This can
15792 +         be achieved by not using libc5 (which relies on the kernel
15793 +         signal handler return code) and not using or rewriting programs
15794 +         that make use of the nested function implementation of GCC.
15795 +         Skilled users can just fix GCC itself so that it implements
15796 +         nested function calls in a way that does not interfere with PaX.
15797 +
15798 +config PAX_EMUSIGRT
15799 +       bool "Automatically emulate sigreturn trampolines"
15800 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
15801 +       default y
15802 +       help
15803 +         Enabling this option will have the kernel automatically detect
15804 +         and emulate signal return trampolines executing on the stack
15805 +         that would otherwise lead to task termination.
15806 +
15807 +         This solution is intended as a temporary one for users with
15808 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
15809 +         Modula-3 runtime, etc) or executables linked to such, basically
15810 +         everything that does not specify its own SA_RESTORER function in
15811 +         normal executable memory like glibc 2.1+ does.
15812 +
15813 +         On parisc and ppc you MUST enable this option, otherwise your
15814 +         system will not even boot.
15815 +
15816 +         NOTE: this feature cannot be disabled on a per executable basis
15817 +         and since it *does* open up a loophole in the protection provided
15818 +         by non-executable pages, the best solution is to not have any
15819 +         files on your system that would require this option.
15820 +
15821 +config PAX_MPROTECT
15822 +       bool "Restrict mprotect()"
15823 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
15824 +       help
15825 +         Enabling this option will prevent programs from
15826 +          - changing the executable status of memory pages that were
15827 +            not originally created as executable,
15828 +          - making read-only executable pages writable again,
15829 +          - creating executable pages from anonymous memory.
15830 +
15831 +         You should say Y here to complete the protection provided by
15832 +         the enforcement of non-executable pages.
15833 +
15834 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
15835 +         this feature on a per file basis.
15836 +
15837 +config PAX_NOELFRELOCS
15838 +       bool "Disallow ELF text relocations"
15839 +       depends on PAX_MPROTECT && (IA64 || X86 || X86_64)
15840 +       help
15841 +         Non-executable pages and mprotect() restrictions are effective
15842 +         in preventing the introduction of new executable code into an
15843 +         attacked task's address space.  There remain only two venues
15844 +         for this kind of attack: if the attacker can execute already
15845 +         existing code in the attacked task then he can either have it
15846 +         create and mmap() a file containing his code or have it mmap()
15847 +         an already existing ELF library that does not have position
15848 +         independent code in it and use mprotect() on it to make it
15849 +         writable and copy his code there.  While protecting against
15850 +         the former approach is beyond PaX, the latter can be prevented
15851 +         by having only PIC ELF libraries on one's system (which do not
15852 +         need to relocate their code).  If you are sure this is your case,
15853 +         then enable this option otherwise be careful as you may not even
15854 +         be able to boot or log on your system (for example, some PAM
15855 +         modules are erroneously compiled as non-PIC by default).
15856 +
15857 +         NOTE: if you are using dynamic ELF executables (as suggested
15858 +         when using ASLR) then you must have made sure that you linked
15859 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
15860 +         referenced there has already been updated to support this).
15861 +
15862 +config PAX_ETEXECRELOCS
15863 +       bool "Allow ELF ET_EXEC text relocations"
15864 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
15865 +       default y
15866 +       help
15867 +         On some architectures there are incorrectly created applications
15868 +         that require text relocations and would not work without enabling
15869 +         this option.  If you are an alpha, ia64 or parisc user, you should
15870 +         enable this option and disable it once you have made sure that
15871 +         none of your applications need it.
15872 +
15873 +config PAX_EMUPLT
15874 +       bool "Automatically emulate ELF PLT"
15875 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
15876 +       default y
15877 +       help
15878 +         Enabling this option will have the kernel automatically detect
15879 +         and emulate the Procedure Linkage Table entries in ELF files.
15880 +         On some architectures such entries are in writable memory, and
15881 +         become non-executable leading to task termination.  Therefore
15882 +         it is mandatory that you enable this option on alpha, parisc, ppc,
15883 +         sparc and sparc64, otherwise your system would not even boot.
15884 +
15885 +         NOTE: this feature *does* open up a loophole in the protection
15886 +         provided by the non-executable pages, therefore the proper
15887 +         solution is to modify the toolchain to produce a PLT that does
15888 +         not need to be writable.
15889 +
15890 +config PAX_DLRESOLVE
15891 +       bool
15892 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
15893 +       default y
15894 +
15895 +config PAX_SYSCALL
15896 +       bool
15897 +       depends on PAX_PAGEEXEC && PPC32
15898 +       default y
15899 +
15900 +config PAX_KERNEXEC
15901 +       bool "Enforce non-executable kernel pages"
15902 +       depends on PAX_NOEXEC && X86 && !X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM
15903 +       help
15904 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
15905 +         that is, enabling this option will make it harder to inject
15906 +         and execute 'foreign' code in kernel memory itself.
15907 +
15908 +endmenu
15909 +
15910 +menu "Address Space Layout Randomization"
15911 +       depends on PAX
15912 +
15913 +config PAX_ASLR
15914 +       bool "Address Space Layout Randomization"
15915 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
15916 +       help
15917 +         Many if not most exploit techniques rely on the knowledge of
15918 +         certain addresses in the attacked program.  The following options
15919 +         will allow the kernel to apply a certain amount of randomization
15920 +         to specific parts of the program thereby forcing an attacker to
15921 +         guess them in most cases.  Any failed guess will most likely crash
15922 +         the attacked program which allows the kernel to detect such attempts
15923 +         and react on them.  PaX itself provides no reaction mechanisms,
15924 +         instead it is strongly encouraged that you make use of Nergal's
15925 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
15926 +         (http://www.grsecurity.net/) built-in crash detection features or
15927 +         develop one yourself.
15928 +
15929 +         By saying Y here you can choose to randomize the following areas:
15930 +          - top of the task's kernel stack
15931 +          - top of the task's userland stack
15932 +          - base address for mmap() requests that do not specify one
15933 +            (this includes all libraries)
15934 +          - base address of the main executable
15935 +
15936 +         It is strongly recommended to say Y here as address space layout
15937 +         randomization has negligible impact on performance yet it provides
15938 +         a very effective protection.
15939 +
15940 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
15941 +         this feature on a per file basis.
15942 +
15943 +config PAX_RANDKSTACK
15944 +       bool "Randomize kernel stack base"
15945 +       depends on PAX_ASLR && X86_TSC && !X86_64
15946 +       help
15947 +         By saying Y here the kernel will randomize every task's kernel
15948 +         stack on every system call.  This will not only force an attacker
15949 +         to guess it but also prevent him from making use of possible
15950 +         leaked information about it.
15951 +
15952 +         Since the kernel stack is a rather scarce resource, randomization
15953 +         may cause unexpected stack overflows, therefore you should very
15954 +         carefully test your system.  Note that once enabled in the kernel
15955 +         configuration, this feature cannot be disabled on a per file basis.
15956 +
15957 +config PAX_RANDUSTACK
15958 +       bool "Randomize user stack base"
15959 +       depends on PAX_ASLR
15960 +       help
15961 +         By saying Y here the kernel will randomize every task's userland
15962 +         stack.  The randomization is done in two steps where the second
15963 +         one may apply a big amount of shift to the top of the stack and
15964 +         cause problems for programs that want to use lots of memory (more
15965 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
15966 +         For this reason the second step can be controlled by 'chpax' or
15967 +         'paxctl' on a per file basis.
15968 +
15969 +config PAX_RANDMMAP
15970 +       bool "Randomize mmap() base"
15971 +       depends on PAX_ASLR
15972 +       help
15973 +         By saying Y here the kernel will use a randomized base address for
15974 +         mmap() requests that do not specify one themselves.  As a result
15975 +         all dynamically loaded libraries will appear at random addresses
15976 +         and therefore be harder to exploit by a technique where an attacker
15977 +         attempts to execute library code for his purposes (e.g. spawn a
15978 +         shell from an exploited program that is running at an elevated
15979 +         privilege level).
15980 +
15981 +         Furthermore, if a program is relinked as a dynamic ELF file, its
15982 +         base address will be randomized as well, completing the full
15983 +         randomization of the address space layout.  Attacking such programs
15984 +         becomes a guess game.  You can find an example of doing this at
15985 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
15986 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
15987 +
15988 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
15989 +         feature on a per file basis.
15990 +
15991 +config PAX_RANDEXEC
15992 +       bool "Randomize ET_EXEC base"
15993 +       depends on PAX_MPROTECT && PAX_RANDMMAP
15994 +       help
15995 +         By saying Y here the kernel will randomize the base address of normal
15996 +         ET_EXEC ELF executables as well.  This is accomplished by mapping the
15997 +         executable in memory in a special way which also allows for detecting
15998 +         attackers who attempt to execute its code for their purposes.  Since
15999 +         this special mapping causes performance degradation and the attack
16000 +         detection may create false alarms as well, you should carefully test
16001 +         your executables when this feature is enabled.
16002 +
16003 +         This solution is intended only as a temporary one until you relink
16004 +         your programs as a dynamic ELF file.
16005 +
16006 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
16007 +         feature on a per file basis.
16008 +
16009 +config PAX_NOVSYSCALL
16010 +       bool "Disable the vsyscall page"
16011 +       depends on PAX_ASLR && X86 && !X86_64
16012 +       help
16013 +         The Linux 2.6 kernel introduced a new feature that speeds up or
16014 +         simplifies certain operations, such as system calls or returns
16015 +         from signal handlers.
16016 +
16017 +         Unfortunately the implementation also gives a powerful instrument
16018 +         into the hands of exploit writers: the so-called vsyscall page exists
16019 +         in every task at the same fixed address and it contains machine code
16020 +         that is very useful in performing the return-to-libc style attack.
16021 +
16022 +         Since this exploit technique cannot in general be protected against
16023 +         via kernel solutions, this option will allow you to disable the use
16024 +         of the vsyscall page and revert back to the old behaviour.
16025 +
16026 +endmenu
16027 +
16028 +endmenu
16029 +
16030 +endmenu
16031 diff -uNr linux-2.6.8/grsecurity/Makefile linux-2.6.8.grsecurity/grsecurity/Makefile
16032 --- linux-2.6.8/grsecurity/Makefile     1970-01-01 01:00:00.000000000 +0100
16033 +++ linux-2.6.8.grsecurity/grsecurity/Makefile  2004-08-16 17:08:29.000000000 +0200
16034 @@ -0,0 +1,21 @@
16035 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
16036 +# during 2001, 2002, and 2003 it has been completely redesigned by
16037 +# Brad Spengler
16038 +#
16039 +# All code in this directory and various hooks inserted throughout the kernel
16040 +# are copyright Brad Spengler, and released under the GPL, unless otherwise
16041 +# noted (as in obsd_rand.c)
16042 +
16043 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
16044 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
16045 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
16046 +
16047 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
16048 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
16049 +       gracl_learn.o
16050 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
16051 +
16052 +ifndef CONFIG_GRKERNSEC
16053 +obj-y += grsec_disabled.o
16054 +endif
16055 +
16056 diff -uNr linux-2.6.8/grsecurity/obsd_rand.c linux-2.6.8.grsecurity/grsecurity/obsd_rand.c
16057 --- linux-2.6.8/grsecurity/obsd_rand.c  1970-01-01 01:00:00.000000000 +0100
16058 +++ linux-2.6.8.grsecurity/grsecurity/obsd_rand.c       2004-08-16 17:08:29.000000000 +0200
16059 @@ -0,0 +1,186 @@
16060 +
16061 +/*
16062 + * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
16063 + * 
16064 + * Version 1.89, last modified 19-Sep-99
16065 + *    
16066 + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
16067 + * All rights reserved.
16068 + *
16069 + * Copyright 1998 Niels Provos <provos@citi.umich.edu>
16070 + * All rights reserved.
16071 + * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
16072 + * such a mathematical system to generate more random (yet non-repeating)
16073 + * ids to solve the resolver/named problem.  But Niels designed the
16074 + * actual system based on the constraints.
16075 + *
16076 + * Redistribution and use in source and binary forms, with or without
16077 + * modification, are permitted provided that the following conditions
16078 + * are met:
16079 + * 1. Redistributions of source code must retain the above copyright
16080 + *    notice, this list of conditions and the following disclaimer,
16081 + * 2. Redistributions in binary form must reproduce the above copyright
16082 + *    notice, this list of conditions and the following disclaimer in the
16083 + *    documentation and/or other materials provided with the distribution.
16084 + *
16085 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16086 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16087 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16088 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16089 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16090 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
16091 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16092 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16093 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
16094 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16095 + */
16096 +
16097 +#include <linux/kernel.h>
16098 +#include <linux/sched.h>
16099 +#include <linux/time.h>
16100 +#include <linux/timer.h>
16101 +#include <linux/smp_lock.h>
16102 +#include <linux/random.h>
16103 +#include <linux/grsecurity.h>
16104 +
16105 +#define RU_OUT 180
16106 +#define RU_MAX 30000
16107 +#define RU_GEN 2
16108 +#define RU_N 32749
16109 +#define RU_AGEN 7
16110 +#define RU_M 31104
16111 +#define PFAC_N 3
16112 +const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
16113 +
16114 +static __u16 ru_x;
16115 +static __u16 ru_seed, ru_seed2;
16116 +static __u16 ru_a, ru_b;
16117 +static __u16 ru_g;
16118 +static __u16 ru_counter = 0;
16119 +static __u16 ru_msb = 0;
16120 +static unsigned long ru_reseed = 0;
16121 +static __u32 tmp;
16122 +
16123 +#define TCP_RNDISS_ROUNDS      15
16124 +#define TCP_RNDISS_OUT         7200
16125 +#define TCP_RNDISS_MAX         30000
16126 +
16127 +static __u8 tcp_rndiss_sbox[128];
16128 +static __u16 tcp_rndiss_msb;
16129 +static __u16 tcp_rndiss_cnt;
16130 +static unsigned long tcp_rndiss_reseed;
16131 +
16132 +static __u16 pmod(__u16, __u16, __u16);
16133 +static void ip_initid(void);
16134 +__u16 ip_randomid(void);
16135 +
16136 +static __u16
16137 +pmod(__u16 gen, __u16 exp, __u16 mod)
16138 +{
16139 +       __u16 s, t, u;
16140 +
16141 +       s = 1;
16142 +       t = gen;
16143 +       u = exp;
16144 +
16145 +       while (u) {
16146 +               if (u & 1)
16147 +                       s = (s * t) % mod;
16148 +               u >>= 1;
16149 +               t = (t * t) % mod;
16150 +       }
16151 +       return (s);
16152 +}
16153 +
16154 +static void
16155 +ip_initid(void)
16156 +{
16157 +       __u16 j, i;
16158 +       int noprime = 1;
16159 +
16160 +       ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
16161 +
16162 +       ru_seed = (tmp >> 16) & 0x7FFF;
16163 +       ru_seed2 = get_random_long() & 0x7FFF;
16164 +
16165 +       ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
16166 +       ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
16167 +       while (ru_b % 3 == 0)
16168 +               ru_b += 2;
16169 +
16170 +       j = (tmp = get_random_long()) % RU_N;
16171 +       tmp = tmp >> 16;
16172 +
16173 +       while (noprime) {
16174 +               for (i = 0; i < PFAC_N; i++)
16175 +                       if (j % pfacts[i] == 0)
16176 +                               break;
16177 +
16178 +               if (i >= PFAC_N)
16179 +                       noprime = 0;
16180 +               else
16181 +                       j = (j + 1) % RU_N;
16182 +       }
16183 +
16184 +       ru_g = pmod(RU_GEN, j, RU_N);
16185 +       ru_counter = 0;
16186 +
16187 +       ru_reseed = xtime.tv_sec + RU_OUT;
16188 +       ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
16189 +}
16190 +
16191 +__u16
16192 +ip_randomid(void)
16193 +{
16194 +       int i, n;
16195 +
16196 +       if (ru_counter >= RU_MAX || time_after(get_seconds(), ru_reseed))
16197 +               ip_initid();
16198 +
16199 +       if (!tmp)
16200 +               tmp = get_random_long();
16201 +
16202 +       n = tmp & 0x3;
16203 +       tmp = tmp >> 2;
16204 +       if (ru_counter + n >= RU_MAX)
16205 +               ip_initid();
16206 +       for (i = 0; i <= n; i++)
16207 +               ru_x = (ru_a * ru_x + ru_b) % RU_M;
16208 +       ru_counter += i;
16209 +
16210 +       return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
16211 +}
16212 +
16213 +__u16
16214 +tcp_rndiss_encrypt(__u16 val)
16215 +{
16216 +       __u16 sum = 0, i;
16217 +
16218 +       for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
16219 +               sum += 0x79b9;
16220 +               val ^= ((__u16) tcp_rndiss_sbox[(val ^ sum) & 0x7f]) << 7;
16221 +               val = ((val & 0xff) << 7) | (val >> 8);
16222 +       }
16223 +
16224 +       return val;
16225 +}
16226 +
16227 +static void
16228 +tcp_rndiss_init(void)
16229 +{
16230 +       get_random_bytes(tcp_rndiss_sbox, sizeof (tcp_rndiss_sbox));
16231 +       tcp_rndiss_reseed = get_seconds() + TCP_RNDISS_OUT;
16232 +       tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
16233 +       tcp_rndiss_cnt = 0;
16234 +}
16235 +
16236 +__u32
16237 +ip_randomisn(void)
16238 +{
16239 +       if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
16240 +           time_after(get_seconds(), tcp_rndiss_reseed))
16241 +               tcp_rndiss_init();
16242 +
16243 +       return (((tcp_rndiss_encrypt(tcp_rndiss_cnt++) |
16244 +                 tcp_rndiss_msb) << 16) | (get_random_long() & 0x7fff));
16245 +}
16246 diff -uNr linux-2.6.8/include/asm-alpha/a.out.h linux-2.6.8.grsecurity/include/asm-alpha/a.out.h
16247 --- linux-2.6.8/include/asm-alpha/a.out.h       2004-08-14 07:37:37.000000000 +0200
16248 +++ linux-2.6.8.grsecurity/include/asm-alpha/a.out.h    2004-08-16 17:08:29.000000000 +0200
16249 @@ -98,7 +98,7 @@
16250         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
16251                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
16252  
16253 -#define STACK_TOP \
16254 +#define __STACK_TOP \
16255    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
16256  
16257  #endif
16258 diff -uNr linux-2.6.8/include/asm-alpha/elf.h linux-2.6.8.grsecurity/include/asm-alpha/elf.h
16259 --- linux-2.6.8/include/asm-alpha/elf.h 2004-08-14 07:36:58.000000000 +0200
16260 +++ linux-2.6.8.grsecurity/include/asm-alpha/elf.h      2004-08-16 17:08:29.000000000 +0200
16261 @@ -89,6 +89,17 @@
16262  
16263  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
16264  
16265 +#ifdef CONFIG_PAX_ASLR
16266 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
16267 +
16268 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
16269 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
16270 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
16271 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
16272 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
16273 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
16274 +#endif
16275 +
16276  /* $0 is set by ld.so to a pointer to a function which might be 
16277     registered using atexit.  This provides a mean for the dynamic
16278     linker to call DT_FINI functions for shared libraries that have
16279 diff -uNr linux-2.6.8/include/asm-alpha/mman.h linux-2.6.8.grsecurity/include/asm-alpha/mman.h
16280 --- linux-2.6.8/include/asm-alpha/mman.h        2004-08-14 07:36:12.000000000 +0200
16281 +++ linux-2.6.8.grsecurity/include/asm-alpha/mman.h     2004-08-16 17:08:29.000000000 +0200
16282 @@ -29,6 +29,10 @@
16283  #define MAP_POPULATE   0x20000         /* populate (prefault) pagetables */
16284  #define MAP_NONBLOCK   0x40000         /* do not block on IO */
16285  
16286 +#ifdef CONFIG_PAX_RANDEXEC
16287 +#define MAP_MIRROR     0x20000
16288 +#endif
16289 +
16290  #define MS_ASYNC       1               /* sync memory asynchronously */
16291  #define MS_SYNC                2               /* synchronous memory sync */
16292  #define MS_INVALIDATE  4               /* invalidate the caches */
16293 diff -uNr linux-2.6.8/include/asm-alpha/page.h linux-2.6.8.grsecurity/include/asm-alpha/page.h
16294 --- linux-2.6.8/include/asm-alpha/page.h        2004-08-14 07:37:38.000000000 +0200
16295 +++ linux-2.6.8.grsecurity/include/asm-alpha/page.h     2004-08-16 17:08:29.000000000 +0200
16296 @@ -106,6 +106,15 @@
16297  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
16298                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16299  
16300 +#ifdef CONFIG_PAX_PAGEEXEC
16301 +#ifdef CONFIG_PAX_MPROTECT
16302 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
16303 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
16304 +#else
16305 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
16306 +#endif
16307 +#endif
16308 +
16309  #endif /* __KERNEL__ */
16310  
16311  #endif /* _ALPHA_PAGE_H */
16312 diff -uNr linux-2.6.8/include/asm-alpha/pgtable.h linux-2.6.8.grsecurity/include/asm-alpha/pgtable.h
16313 --- linux-2.6.8/include/asm-alpha/pgtable.h     2004-08-14 07:36:44.000000000 +0200
16314 +++ linux-2.6.8.grsecurity/include/asm-alpha/pgtable.h  2004-08-16 17:08:29.000000000 +0200
16315 @@ -96,6 +96,17 @@
16316  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
16317  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
16318  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
16319 +
16320 +#ifdef CONFIG_PAX_PAGEEXEC
16321 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
16322 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
16323 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
16324 +#else
16325 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
16326 +# define PAGE_COPY_NOEXEC      PAGE_COPY
16327 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
16328 +#endif
16329 +
16330  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
16331  
16332  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
16333 diff -uNr linux-2.6.8/include/asm-i386/a.out.h linux-2.6.8.grsecurity/include/asm-i386/a.out.h
16334 --- linux-2.6.8/include/asm-i386/a.out.h        2004-08-14 07:36:56.000000000 +0200
16335 +++ linux-2.6.8.grsecurity/include/asm-i386/a.out.h     2004-08-16 17:08:29.000000000 +0200
16336 @@ -19,7 +19,11 @@
16337  
16338  #ifdef __KERNEL__
16339  
16340 -#define STACK_TOP      TASK_SIZE
16341 +#ifdef CONFIG_PAX_SEGMEXEC
16342 +#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
16343 +#else
16344 +#define __STACK_TOP TASK_SIZE
16345 +#endif
16346  
16347  #endif
16348  
16349 diff -uNr linux-2.6.8/include/asm-i386/desc.h linux-2.6.8.grsecurity/include/asm-i386/desc.h
16350 --- linux-2.6.8/include/asm-i386/desc.h 2004-08-14 07:36:10.000000000 +0200
16351 +++ linux-2.6.8.grsecurity/include/asm-i386/desc.h      2004-08-16 18:09:30.000000000 +0200
16352 @@ -8,11 +8,71 @@
16353  
16354  #include <linux/preempt.h>
16355  #include <linux/smp.h>
16356 +#include <linux/sched.h>
16357  
16358  #include <asm/mmu.h>
16359 +#include <asm/pgtable.h>
16360 +#include <asm/tlbflush.h>
16361  
16362  extern struct desc_struct cpu_gdt_table[NR_CPUS][GDT_ENTRIES];
16363  
16364 +#define pax_open_kernel(flags, cr3)            \
16365 +do {                                           \
16366 +       typecheck(unsigned long,flags);         \
16367 +       typecheck(unsigned long,cr3);           \
16368 +       local_irq_save(flags);                  \
16369 +       asm("movl %%cr3,%0":"=r" (cr3));        \
16370 +       load_cr3(kernexec_pg_dir);              \
16371 +} while(0)
16372 +
16373 +#define pax_close_kernel(flags, cr3)           \
16374 +do {                                           \
16375 +       typecheck(unsigned long,flags);         \
16376 +       typecheck(unsigned long,cr3);           \
16377 +       asm("movl %0,%%cr3": :"r" (cr3));       \
16378 +       local_irq_restore(flags);               \
16379 +} while(0)
16380 +
16381 +#define pax_open_kernel_noirq(cr3)                     \
16382 +do {                                           \
16383 +       typecheck(unsigned long,cr3);           \
16384 +       asm("movl %%cr3,%0":"=r" (cr3));        \
16385 +       load_cr3(kernexec_pg_dir);              \
16386 +} while(0)
16387 +
16388 +#define pax_close_kernel_noirq(cr3)                    \
16389 +do {                                           \
16390 +       typecheck(unsigned long,cr3);           \
16391 +       asm("movl %0,%%cr3": :"r" (cr3));       \
16392 +} while(0)
16393 +
16394 +static inline void set_user_cs(struct mm_struct *mm, int cpu)
16395 +{
16396 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16397 +       unsigned long base = mm->context.user_cs_base;
16398 +       unsigned long limit = mm->context.user_cs_limit;
16399 +
16400 +#ifdef CONFIG_PAX_KERNEXEC
16401 +       unsigned long flags, cr3;
16402 +
16403 +       pax_open_kernel(flags, cr3);
16404 +#endif
16405 +
16406 +       if (limit) {
16407 +               limit -= 1UL;
16408 +               limit >>= 12;
16409 +       }
16410 +
16411 +       cpu_gdt_table[cpu][GDT_ENTRY_DEFAULT_USER_CS].a = (limit & 0xFFFFUL) | (base << 16);
16412 +       cpu_gdt_table[cpu][GDT_ENTRY_DEFAULT_USER_CS].b = (limit & 0xF0000UL) | 0xC0FB00UL | (base & 0xFF000000UL) | ((base >> 16) & 0xFFUL);
16413 +
16414 +#ifdef CONFIG_PAX_KERNEXEC
16415 +       pax_close_kernel(flags, cr3);
16416 +#endif
16417 +
16418 +#endif
16419 +}
16420 +
16421  struct Xgt_desc_struct {
16422         unsigned short size;
16423         unsigned long address __attribute__((packed));
16424 @@ -28,7 +88,7 @@
16425   * This is the ldt that every process will get unless we need
16426   * something other than this.
16427   */
16428 -extern struct desc_struct default_ldt[];
16429 +extern const struct desc_struct default_ldt[];
16430  extern void set_intr_gate(unsigned int irq, void * addr);
16431  
16432  #define _set_tssldt_desc(n,addr,limit,type) \
16433 @@ -42,7 +102,7 @@
16434         "rorl $16,%%eax" \
16435         : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
16436  
16437 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
16438 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
16439  {
16440         _set_tssldt_desc(&cpu_gdt_table[cpu][entry], (int)addr,
16441                 offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
16442 @@ -50,11 +110,27 @@
16443  
16444  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
16445  
16446 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
16447 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
16448  {
16449         _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
16450  }
16451  
16452 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
16453 +{
16454 +#ifdef CONFIG_PAX_KERNEXEC
16455 +       unsigned long flags, cr3;
16456 +
16457 +       pax_open_kernel(flags, cr3);
16458 +#endif
16459 +
16460 +       _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
16461 +
16462 +#ifdef CONFIG_PAX_KERNEXEC
16463 +       pax_close_kernel(flags, cr3);
16464 +#endif
16465 +
16466 +}
16467 +
16468  #define LDT_entry_a(info) \
16469         ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
16470  
16471 @@ -68,7 +144,7 @@
16472         ((info)->seg_32bit << 22) | \
16473         ((info)->limit_in_pages << 23) | \
16474         ((info)->useable << 20) | \
16475 -       0x7000)
16476 +       0x7100)
16477  
16478  #define LDT_empty(info) (\
16479         (info)->base_addr       == 0    && \
16480 @@ -105,7 +181,7 @@
16481   */
16482  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
16483  {
16484 -       void *segments = pc->ldt;
16485 +       const void *segments = pc->ldt;
16486         int count = pc->size;
16487  
16488         if (likely(!count)) {
16489 @@ -124,6 +200,22 @@
16490         put_cpu();
16491  }
16492  
16493 +static inline void _load_LDT(mm_context_t *pc)
16494 +{
16495 +       int cpu = get_cpu();
16496 +       const void *segments = pc->ldt;
16497 +       int count = pc->size;
16498 +
16499 +       if (likely(!count)) {
16500 +               segments = &default_ldt[0];
16501 +               count = 5;
16502 +       }
16503 +               
16504 +       __set_ldt_desc(cpu, segments, count);
16505 +       load_LDT_desc();
16506 +       put_cpu();
16507 +}
16508 +
16509  #endif /* !__ASSEMBLY__ */
16510  
16511  #endif
16512 diff -uNr linux-2.6.8/include/asm-i386/elf.h linux-2.6.8.grsecurity/include/asm-i386/elf.h
16513 --- linux-2.6.8/include/asm-i386/elf.h  2004-08-14 07:37:26.000000000 +0200
16514 +++ linux-2.6.8.grsecurity/include/asm-i386/elf.h       2004-08-16 17:08:29.000000000 +0200
16515 @@ -72,6 +72,19 @@
16516  
16517  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
16518  
16519 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16520 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
16521 +#endif
16522 +
16523 +#ifdef CONFIG_PAX_ASLR
16524 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
16525 +#define PAX_DELTA_MMAP_LEN(tsk)                15
16526 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
16527 +#define PAX_DELTA_EXEC_LEN(tsk)                15
16528 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
16529 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16)
16530 +#endif
16531 +
16532  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
16533     now struct_user_regs, they are different) */
16534  
16535 @@ -113,8 +126,11 @@
16536   * Architecture-neutral AT_ values in 0-17, leave some room
16537   * for more of them, start the x86-specific ones at 32.
16538   */
16539 +
16540 +#ifndef CONFIG_PAX_NOVSYSCALL
16541  #define AT_SYSINFO             32
16542  #define AT_SYSINFO_EHDR                33
16543 +#endif
16544  
16545  #ifdef __KERNEL__
16546  #define SET_PERSONALITY(ex, ibcs2) do { } while (0)
16547 @@ -135,7 +151,14 @@
16548  
16549  #define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
16550  #define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
16551 +
16552 +#ifndef CONFIG_PAX_NOVSYSCALL
16553 +#ifdef CONFIG_PAX_SEGMEXEC
16554 +#define VSYSCALL_ENTRY ((current->flags & PF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
16555 +#else
16556  #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
16557 +#endif
16558 +
16559  extern void __kernel_vsyscall;
16560  
16561  #define ARCH_DLINFO                                            \
16562 @@ -191,3 +214,5 @@
16563  #endif
16564  
16565  #endif
16566 +
16567 +#endif
16568 diff -uNr linux-2.6.8/include/asm-i386/mach-default/apm.h linux-2.6.8.grsecurity/include/asm-i386/mach-default/apm.h
16569 --- linux-2.6.8/include/asm-i386/mach-default/apm.h     2004-08-14 07:36:17.000000000 +0200
16570 +++ linux-2.6.8.grsecurity/include/asm-i386/mach-default/apm.h  2004-08-16 17:08:29.000000000 +0200
16571 @@ -36,7 +36,7 @@
16572         __asm__ __volatile__(APM_DO_ZERO_SEGS
16573                 "pushl %%edi\n\t"
16574                 "pushl %%ebp\n\t"
16575 -               "lcall *%%cs:apm_bios_entry\n\t"
16576 +               "lcall *%%ss:apm_bios_entry\n\t"
16577                 "setc %%al\n\t"
16578                 "popl %%ebp\n\t"
16579                 "popl %%edi\n\t"
16580 @@ -60,7 +60,7 @@
16581         __asm__ __volatile__(APM_DO_ZERO_SEGS
16582                 "pushl %%edi\n\t"
16583                 "pushl %%ebp\n\t"
16584 -               "lcall *%%cs:apm_bios_entry\n\t"
16585 +               "lcall *%%ss:apm_bios_entry\n\t"
16586                 "setc %%bl\n\t"
16587                 "popl %%ebp\n\t"
16588                 "popl %%edi\n\t"
16589 diff -uNr linux-2.6.8/include/asm-i386/mman.h linux-2.6.8.grsecurity/include/asm-i386/mman.h
16590 --- linux-2.6.8/include/asm-i386/mman.h 2004-08-14 07:36:17.000000000 +0200
16591 +++ linux-2.6.8.grsecurity/include/asm-i386/mman.h      2004-08-16 17:09:58.000000000 +0200
16592 @@ -23,6 +23,10 @@
16593  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
16594  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
16595  
16596 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
16597 +#define MAP_MIRROR     0x20000
16598 +#endif
16599 +
16600  #define MS_ASYNC       1               /* sync memory asynchronously */
16601  #define MS_INVALIDATE  2               /* invalidate the caches */
16602  #define MS_SYNC                4               /* synchronous memory sync */
16603 diff -uNr linux-2.6.8/include/asm-i386/mmu_context.h linux-2.6.8.grsecurity/include/asm-i386/mmu_context.h
16604 --- linux-2.6.8/include/asm-i386/mmu_context.h  2004-08-14 07:36:10.000000000 +0200
16605 +++ linux-2.6.8.grsecurity/include/asm-i386/mmu_context.h       2004-08-16 17:09:58.000000000 +0200
16606 @@ -46,6 +46,13 @@
16607                  */
16608                 if (unlikely(prev->context.ldt != next->context.ldt))
16609                         load_LDT_nolock(&next->context, cpu);
16610 +
16611 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
16612 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
16613 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
16614 +#endif
16615 +
16616 +               set_user_cs(next, cpu);
16617         }
16618  #ifdef CONFIG_SMP
16619         else {
16620 @@ -58,6 +65,12 @@
16621                          */
16622                         load_cr3(next->pgd);
16623                         load_LDT_nolock(&next->context, cpu);
16624 +
16625 +#ifdef CONFIG_PAX_PAGEEXEC
16626 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
16627 +#endif
16628 +
16629 +                       set_user_cs(next, cpu);
16630                 }
16631         }
16632  #endif
16633 diff -uNr linux-2.6.8/include/asm-i386/mmu.h linux-2.6.8.grsecurity/include/asm-i386/mmu.h
16634 --- linux-2.6.8/include/asm-i386/mmu.h  2004-08-14 07:37:15.000000000 +0200
16635 +++ linux-2.6.8.grsecurity/include/asm-i386/mmu.h       2004-08-16 17:09:58.000000000 +0200
16636 @@ -12,6 +12,17 @@
16637         int size;
16638         struct semaphore sem;
16639         void *ldt;
16640 +
16641 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16642 +       unsigned long user_cs_base;
16643 +       unsigned long user_cs_limit;
16644 +
16645 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
16646 +       cpumask_t cpu_user_cs_mask;
16647 +#endif
16648 +
16649 +#endif
16650 +
16651  } mm_context_t;
16652  
16653  #endif
16654 diff -uNr linux-2.6.8/include/asm-i386/module.h linux-2.6.8.grsecurity/include/asm-i386/module.h
16655 --- linux-2.6.8/include/asm-i386/module.h       2004-08-14 07:36:17.000000000 +0200
16656 +++ linux-2.6.8.grsecurity/include/asm-i386/module.h    2004-08-16 17:09:58.000000000 +0200
16657 @@ -66,6 +66,12 @@
16658  #define MODULE_STACKSIZE ""
16659  #endif
16660  
16661 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
16662 +#ifdef CONFIG_GRKERNSEC
16663 +#define MODULE_GRSEC "GRSECURITY "
16664 +#else
16665 +#define MODULE_GRSEC ""
16666 +#endif
16667 +
16668 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
16669  
16670  #endif /* _ASM_I386_MODULE_H */
16671 diff -uNr linux-2.6.8/include/asm-i386/page.h linux-2.6.8.grsecurity/include/asm-i386/page.h
16672 --- linux-2.6.8/include/asm-i386/page.h 2004-08-14 07:36:17.000000000 +0200
16673 +++ linux-2.6.8.grsecurity/include/asm-i386/page.h      2004-08-16 17:09:58.000000000 +0200
16674 @@ -124,6 +124,19 @@
16675  #define __PAGE_OFFSET          (0xC0000000UL)
16676  #endif
16677  
16678 +#ifdef CONFIG_PAX_KERNEXEC
16679 +#ifdef __ASSEMBLY__
16680 +#define __KERNEL_TEXT_OFFSET   (0xC0400000)
16681 +#else
16682 +#define __KERNEL_TEXT_OFFSET   (0xC0400000UL)
16683 +#endif
16684 +#else
16685 +#ifdef __ASSEMBLY__
16686 +#define __KERNEL_TEXT_OFFSET   (0)
16687 +#else
16688 +#define __KERNEL_TEXT_OFFSET   (0x0UL)
16689 +#endif
16690 +#endif
16691  
16692  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
16693  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
16694 @@ -145,6 +158,19 @@
16695         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
16696                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16697  
16698 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16699 +#ifdef CONFIG_PAX_MPROTECT
16700 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
16701 +                         ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
16702 +#else
16703 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
16704 +#endif
16705 +#endif
16706 +
16707 +#ifdef CONFIG_PAX_PAGEEXEC
16708 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
16709 +#endif
16710 +
16711  #endif /* __KERNEL__ */
16712  
16713  #endif /* _I386_PAGE_H */
16714 diff -uNr linux-2.6.8/include/asm-i386/pgalloc.h linux-2.6.8.grsecurity/include/asm-i386/pgalloc.h
16715 --- linux-2.6.8/include/asm-i386/pgalloc.h      2004-08-14 07:36:13.000000000 +0200
16716 +++ linux-2.6.8.grsecurity/include/asm-i386/pgalloc.h   2004-08-16 17:09:58.000000000 +0200
16717 @@ -8,7 +8,7 @@
16718  #include <linux/mm.h>          /* for struct page */
16719  
16720  #define pmd_populate_kernel(mm, pmd, pte) \
16721 -               set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
16722 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
16723  
16724  static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
16725  {
16726 diff -uNr linux-2.6.8/include/asm-i386/pgtable.h linux-2.6.8.grsecurity/include/asm-i386/pgtable.h
16727 --- linux-2.6.8/include/asm-i386/pgtable.h      2004-08-14 07:37:37.000000000 +0200
16728 +++ linux-2.6.8.grsecurity/include/asm-i386/pgtable.h   2004-08-16 18:14:49.000000000 +0200
16729 @@ -25,13 +25,6 @@
16730  #include <linux/list.h>
16731  #include <linux/spinlock.h>
16732  
16733 -/*
16734 - * ZERO_PAGE is a global shared page that is always zero: used
16735 - * for zero-mapped memory areas etc..
16736 - */
16737 -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
16738 -extern unsigned long empty_zero_page[1024];
16739 -extern pgd_t swapper_pg_dir[1024];
16740  extern kmem_cache_t *pgd_cache;
16741  extern kmem_cache_t *pmd_cache;
16742  extern spinlock_t pgd_lock;
16743 @@ -54,6 +47,17 @@
16744  # include <asm/pgtable-2level-defs.h>
16745  #endif
16746  
16747 +/*
16748 + * ZERO_PAGE is a global shared page that is always zero: used
16749 + * for zero-mapped memory areas etc..
16750 + */
16751 +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
16752 +extern unsigned long empty_zero_page[1024];
16753 +extern pgd_t swapper_pg_dir[PTRS_PER_PTE];
16754 +#ifdef CONFIG_PAX_KERNEXEC
16755 +extern pgd_t kernexec_pg_dir[PTRS_PER_PTE];
16756 +#endif
16757 +
16758  #define PMD_SIZE       (1UL << PMD_SHIFT)
16759  #define PMD_MASK       (~(PMD_SIZE-1))
16760  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
16761 @@ -133,21 +137,27 @@
16762  
16763  #define PAGE_NONE \
16764         __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
16765 -#define PAGE_SHARED \
16766 -       __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
16767  
16768 +#define PAGE_SHARED \
16769 +       __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
16770  #define PAGE_SHARED_EXEC \
16771         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
16772 -#define PAGE_COPY_NOEXEC \
16773 +#define PAGE_SHARED_NOEXEC \
16774 +       PAGE_SHARED
16775 +
16776 +#define PAGE_COPY \
16777         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
16778  #define PAGE_COPY_EXEC \
16779         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
16780 -#define PAGE_COPY \
16781 -       PAGE_COPY_NOEXEC
16782 +#define PAGE_COPY_NOEXEC \
16783 +       PAGE_COPY
16784 +
16785  #define PAGE_READONLY \
16786         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
16787  #define PAGE_READONLY_EXEC \
16788         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
16789 +#define PAGE_READONLY_NOEXEC \
16790 +       PAGE_READONLY
16791  
16792  #define _PAGE_KERNEL \
16793         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
16794 @@ -173,18 +183,18 @@
16795   * This is the closest we can get..
16796   */
16797  #define __P000 PAGE_NONE
16798 -#define __P001 PAGE_READONLY
16799 -#define __P010 PAGE_COPY
16800 -#define __P011 PAGE_COPY
16801 +#define __P001 PAGE_READONLY_NOEXEC
16802 +#define __P010 PAGE_COPY_NOEXEC
16803 +#define __P011 PAGE_COPY_NOEXEC
16804  #define __P100 PAGE_READONLY_EXEC
16805  #define __P101 PAGE_READONLY_EXEC
16806  #define __P110 PAGE_COPY_EXEC
16807  #define __P111 PAGE_COPY_EXEC
16808  
16809  #define __S000 PAGE_NONE
16810 -#define __S001 PAGE_READONLY
16811 -#define __S010 PAGE_SHARED
16812 -#define __S011 PAGE_SHARED
16813 +#define __S001 PAGE_READONLY_NOEXEC
16814 +#define __S010 PAGE_SHARED_NOEXEC
16815 +#define __S011 PAGE_SHARED_NOEXEC
16816  #define __S100 PAGE_READONLY_EXEC
16817  #define __S101 PAGE_READONLY_EXEC
16818  #define __S110 PAGE_SHARED_EXEC
16819 @@ -407,6 +417,8 @@
16820  
16821  #endif /* !__ASSEMBLY__ */
16822  
16823 +#define HAVE_ARCH_UNMAPPED_AREA
16824 +
16825  #ifndef CONFIG_DISCONTIGMEM
16826  #define kern_addr_valid(addr)  (1)
16827  #endif /* !CONFIG_DISCONTIGMEM */
16828 diff -uNr linux-2.6.8/include/asm-i386/processor.h linux-2.6.8.grsecurity/include/asm-i386/processor.h
16829 --- linux-2.6.8/include/asm-i386/processor.h    2004-08-14 07:36:13.000000000 +0200
16830 +++ linux-2.6.8.grsecurity/include/asm-i386/processor.h 2004-08-16 17:09:58.000000000 +0200
16831 @@ -28,7 +28,7 @@
16832  };
16833  
16834  #define desc_empty(desc) \
16835 -               (!((desc)->a + (desc)->b))
16836 +               (!((desc)->a | (desc)->b))
16837  
16838  #define desc_equal(desc1, desc2) \
16839                 (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
16840 @@ -291,10 +291,23 @@
16841   */
16842  #define TASK_SIZE      (PAGE_OFFSET)
16843  
16844 +#ifdef CONFIG_PAX_SEGMEXEC
16845 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
16846 +#endif
16847 +
16848  /* This decides where the kernel will search for a free chunk of vm
16849   * space during mmap's.
16850   */
16851 +
16852 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16853 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->flags & PF_PAX_PAGEEXEC)? 0x00110000UL : (current->flags & PF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
16854 +#elif defined(CONFIG_PAX_PAGEEXEC)
16855 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->flags & PF_PAX_PAGEEXEC)? 0x00110000UL : TASK_SIZE/3))
16856 +#elif defined(CONFIG_PAX_SEGMEXEC)
16857 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->flags & PF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
16858 +#else
16859  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
16860 +#endif
16861  
16862  /*
16863   * Size of io_bitmap.
16864 @@ -488,16 +501,12 @@
16865  unsigned long get_wchan(struct task_struct *p);
16866  
16867  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
16868 -#define KSTK_TOP(info)                                                 \
16869 -({                                                                     \
16870 -       unsigned long *__ptr = (unsigned long *)(info);                 \
16871 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
16872 -})
16873 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
16874  
16875  #define task_pt_regs(task)                                             \
16876  ({                                                                     \
16877         struct pt_regs *__regs__;                                       \
16878 -       __regs__ = (struct pt_regs *)KSTK_TOP((task)->thread_info);     \
16879 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
16880         __regs__ - 1;                                                   \
16881  })
16882  
16883 @@ -621,7 +630,7 @@
16884  extern inline void prefetch(const void *x)
16885  {
16886         alternative_input(ASM_NOP4,
16887 -                         "prefetchnta (%1)",
16888 +                         "prefetchnta (%2)",
16889                           X86_FEATURE_XMM,
16890                           "r" (x));
16891  }
16892 @@ -635,7 +644,7 @@
16893  extern inline void prefetchw(const void *x)
16894  {
16895         alternative_input(ASM_NOP4,
16896 -                         "prefetchw (%1)",
16897 +                         "prefetchw (%2)",
16898                           X86_FEATURE_3DNOW,
16899                           "r" (x));
16900  }
16901 diff -uNr linux-2.6.8/include/asm-i386/system.h linux-2.6.8.grsecurity/include/asm-i386/system.h
16902 --- linux-2.6.8/include/asm-i386/system.h       2004-08-14 07:36:11.000000000 +0200
16903 +++ linux-2.6.8.grsecurity/include/asm-i386/system.h    2004-08-16 17:09:58.000000000 +0200
16904 @@ -5,6 +5,7 @@
16905  #include <linux/kernel.h>
16906  #include <asm/segment.h>
16907  #include <asm/cpufeature.h>
16908 +#include <asm/page.h>
16909  #include <linux/bitops.h> /* for LOCK_PREFIX */
16910  
16911  #ifdef __KERNEL__
16912 @@ -301,7 +302,7 @@
16913         asm volatile ("661:\n\t" oldinstr "\n662:\n"                 \
16914                       ".section .altinstructions,\"a\"\n"            \
16915                       "  .align 4\n"                                   \
16916 -                     "  .long 661b\n"            /* label */          \
16917 +                     "  .long 661b + %c1\n"       /* label */          \
16918                       "  .long 663f\n"            /* new instruction */         \
16919                       "  .byte %c0\n"             /* feature bit */    \
16920                       "  .byte 662b-661b\n"       /* sourcelen */      \
16921 @@ -309,7 +310,7 @@
16922                       ".previous\n"                                             \
16923                       ".section .altinstr_replacement,\"ax\"\n"                 \
16924                       "663:\n\t" newinstr "\n664:\n"   /* replacement */    \
16925 -                     ".previous" :: "i" (feature) : "memory")  
16926 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET) : "memory")  
16927  
16928  /*
16929   * Alternative inline assembly with input.
16930 @@ -325,7 +326,7 @@
16931         asm volatile ("661:\n\t" oldinstr "\n662:\n"                            \
16932                       ".section .altinstructions,\"a\"\n"                       \
16933                       "  .align 4\n"                                            \
16934 -                     "  .long 661b\n"            /* label */                   \
16935 +                     "  .long 661b + %c1\n"      /* label */                   \
16936                       "  .long 663f\n"            /* new instruction */         \
16937                       "  .byte %c0\n"             /* feature bit */             \
16938                       "  .byte 662b-661b\n"       /* sourcelen */               \
16939 @@ -333,7 +334,7 @@
16940                       ".previous\n"                                             \
16941                       ".section .altinstr_replacement,\"ax\"\n"                 \
16942                       "663:\n\t" newinstr "\n664:\n"   /* replacement */        \
16943 -                     ".previous" :: "i" (feature), input)  
16944 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET), input)  
16945  
16946  /*
16947   * Force strict CPU ordering.
16948 diff -uNr linux-2.6.8/include/asm-ia64/elf.h linux-2.6.8.grsecurity/include/asm-ia64/elf.h
16949 --- linux-2.6.8/include/asm-ia64/elf.h  2004-08-14 07:37:26.000000000 +0200
16950 +++ linux-2.6.8.grsecurity/include/asm-ia64/elf.h       2004-08-16 17:09:58.000000000 +0200
16951 @@ -162,6 +162,16 @@
16952  typedef struct ia64_fpreg elf_fpreg_t;
16953  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
16954  
16955 +#ifdef CONFIG_PAX_ASLR
16956 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
16957 +
16958 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
16959 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
16960 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
16961 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
16962 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
16963 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
16964 +#endif
16965  
16966  
16967  struct pt_regs;        /* forward declaration... */
16968 diff -uNr linux-2.6.8/include/asm-ia64/mman.h linux-2.6.8.grsecurity/include/asm-ia64/mman.h
16969 --- linux-2.6.8/include/asm-ia64/mman.h 2004-08-14 07:36:58.000000000 +0200
16970 +++ linux-2.6.8.grsecurity/include/asm-ia64/mman.h      2004-08-16 17:09:58.000000000 +0200
16971 @@ -31,6 +31,10 @@
16972  #define MAP_POPULATE   0x08000         /* populate (prefault) pagetables */
16973  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
16974  
16975 +#ifdef CONFIG_PAX_RANDEXEC
16976 +#define MAP_MIRROR     0x40000
16977 +#endif
16978 +
16979  #define MS_ASYNC       1               /* sync memory asynchronously */
16980  #define MS_INVALIDATE  2               /* invalidate the caches */
16981  #define MS_SYNC                4               /* synchronous memory sync */
16982 diff -uNr linux-2.6.8/include/asm-ia64/page.h linux-2.6.8.grsecurity/include/asm-ia64/page.h
16983 --- linux-2.6.8/include/asm-ia64/page.h 2004-08-14 07:36:16.000000000 +0200
16984 +++ linux-2.6.8.grsecurity/include/asm-ia64/page.h      2004-08-16 17:09:58.000000000 +0200
16985 @@ -187,4 +187,13 @@
16986                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
16987                                           ? VM_EXEC : 0))
16988  
16989 +#ifdef CONFIG_PAX_PAGEEXEC
16990 +#ifdef CONFIG_PAX_MPROTECT
16991 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
16992 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
16993 +#else
16994 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
16995 +#endif
16996 +#endif
16997 +
16998  #endif /* _ASM_IA64_PAGE_H */
16999 diff -uNr linux-2.6.8/include/asm-ia64/pgtable.h linux-2.6.8.grsecurity/include/asm-ia64/pgtable.h
17000 --- linux-2.6.8/include/asm-ia64/pgtable.h      2004-08-14 07:36:44.000000000 +0200
17001 +++ linux-2.6.8.grsecurity/include/asm-ia64/pgtable.h   2004-08-16 17:09:58.000000000 +0200
17002 @@ -121,6 +121,17 @@
17003  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
17004  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
17005  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
17006 +
17007 +#ifdef CONFIG_PAX_PAGEEXEC
17008 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
17009 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
17010 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
17011 +#else
17012 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17013 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17014 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17015 +#endif
17016 +
17017  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
17018  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
17019  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
17020 diff -uNr linux-2.6.8/include/asm-ia64/ustack.h linux-2.6.8.grsecurity/include/asm-ia64/ustack.h
17021 --- linux-2.6.8/include/asm-ia64/ustack.h       2004-08-14 07:38:08.000000000 +0200
17022 +++ linux-2.6.8.grsecurity/include/asm-ia64/ustack.h    2004-08-16 17:09:58.000000000 +0200
17023 @@ -11,6 +11,6 @@
17024  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
17025  /* Make a default stack size of 2GB */
17026  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
17027 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
17028 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
17029  
17030  #endif /* _ASM_IA64_USTACK_H */
17031 diff -uNr linux-2.6.8/include/asm-mips/a.out.h linux-2.6.8.grsecurity/include/asm-mips/a.out.h
17032 --- linux-2.6.8/include/asm-mips/a.out.h        2004-08-14 07:36:48.000000000 +0200
17033 +++ linux-2.6.8.grsecurity/include/asm-mips/a.out.h     2004-08-16 17:09:58.000000000 +0200
17034 @@ -36,10 +36,10 @@
17035  #ifdef __KERNEL__
17036  
17037  #ifdef CONFIG_MIPS32
17038 -#define STACK_TOP      TASK_SIZE
17039 +#define __STACK_TOP    TASK_SIZE
17040  #endif
17041  #ifdef CONFIG_MIPS64
17042 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
17043 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
17044  #endif
17045  
17046  #endif
17047 diff -uNr linux-2.6.8/include/asm-mips/elf.h linux-2.6.8.grsecurity/include/asm-mips/elf.h
17048 --- linux-2.6.8/include/asm-mips/elf.h  2004-08-14 07:36:56.000000000 +0200
17049 +++ linux-2.6.8.grsecurity/include/asm-mips/elf.h       2004-08-16 17:09:58.000000000 +0200
17050 @@ -273,4 +273,15 @@
17051  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
17052  #endif
17053  
17054 +#ifdef CONFIG_PAX_ASLR
17055 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
17056 +
17057 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17058 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
17059 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17060 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
17061 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17062 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
17063 +#endif
17064 +
17065  #endif /* _ASM_ELF_H */
17066 diff -uNr linux-2.6.8/include/asm-mips/page.h linux-2.6.8.grsecurity/include/asm-mips/page.h
17067 --- linux-2.6.8/include/asm-mips/page.h 2004-08-14 07:36:48.000000000 +0200
17068 +++ linux-2.6.8.grsecurity/include/asm-mips/page.h      2004-08-16 17:09:58.000000000 +0200
17069 @@ -128,6 +128,15 @@
17070  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17071                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17072  
17073 +#ifdef CONFIG_PAX_PAGEEXEC
17074 +#ifdef CONFIG_PAX_MPROTECT
17075 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17076 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17077 +#else
17078 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17079 +#endif
17080 +#endif
17081 +
17082  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
17083  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
17084  
17085 diff -uNr linux-2.6.8/include/asm-parisc/a.out.h linux-2.6.8.grsecurity/include/asm-parisc/a.out.h
17086 --- linux-2.6.8/include/asm-parisc/a.out.h      2004-08-14 07:38:04.000000000 +0200
17087 +++ linux-2.6.8.grsecurity/include/asm-parisc/a.out.h   2004-08-16 17:09:58.000000000 +0200
17088 @@ -22,7 +22,7 @@
17089  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
17090   * prumpf */
17091  
17092 -#define STACK_TOP      TASK_SIZE
17093 +#define __STACK_TOP    TASK_SIZE
17094  
17095  #endif
17096  
17097 diff -uNr linux-2.6.8/include/asm-parisc/elf.h linux-2.6.8.grsecurity/include/asm-parisc/elf.h
17098 --- linux-2.6.8/include/asm-parisc/elf.h        2004-08-14 07:37:37.000000000 +0200
17099 +++ linux-2.6.8.grsecurity/include/asm-parisc/elf.h     2004-08-16 17:09:58.000000000 +0200
17100 @@ -337,6 +337,17 @@
17101  
17102  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
17103  
17104 +#ifdef CONFIG_PAX_ASLR
17105 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
17106 +
17107 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17108 +#define PAX_DELTA_MMAP_LEN(tsk)                16
17109 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT 
17110 +#define PAX_DELTA_EXEC_LEN(tsk)                16
17111 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17112 +#define PAX_DELTA_STACK_LEN(tsk)       16
17113 +#endif
17114 +
17115  /* This yields a mask that user programs can use to figure out what
17116     instruction set this CPU supports.  This could be done in user space,
17117     but it's not easy, and we've already done it here.  */
17118 diff -uNr linux-2.6.8/include/asm-parisc/mman.h linux-2.6.8.grsecurity/include/asm-parisc/mman.h
17119 --- linux-2.6.8/include/asm-parisc/mman.h       2004-08-14 07:37:15.000000000 +0200
17120 +++ linux-2.6.8.grsecurity/include/asm-parisc/mman.h    2004-08-16 17:09:58.000000000 +0200
17121 @@ -23,6 +23,10 @@
17122  #define MAP_POPULATE   0x10000         /* populate (prefault) pagetables */
17123  #define MAP_NONBLOCK   0x20000         /* do not block on IO */
17124  
17125 +#ifdef CONFIG_PAX_RANDEXEC
17126 +#define MAP_MIRROR     0x0400
17127 +#endif
17128 +
17129  #define MS_SYNC                1               /* synchronous memory sync */
17130  #define MS_ASYNC       2               /* sync memory asynchronously */
17131  #define MS_INVALIDATE  4               /* invalidate the caches */
17132 diff -uNr linux-2.6.8/include/asm-parisc/page.h linux-2.6.8.grsecurity/include/asm-parisc/page.h
17133 --- linux-2.6.8/include/asm-parisc/page.h       2004-08-14 07:36:32.000000000 +0200
17134 +++ linux-2.6.8.grsecurity/include/asm-parisc/page.h    2004-08-16 17:09:58.000000000 +0200
17135 @@ -157,6 +157,15 @@
17136  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17137                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17138  
17139 +#ifdef CONFIG_PAX_PAGEEXEC
17140 +#ifdef CONFIG_PAX_MPROTECT
17141 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17142 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17143 +#else
17144 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17145 +#endif
17146 +#endif
17147 +
17148  #endif /* __KERNEL__ */
17149  
17150  #endif /* _PARISC_PAGE_H */
17151 diff -uNr linux-2.6.8/include/asm-parisc/pgtable.h linux-2.6.8.grsecurity/include/asm-parisc/pgtable.h
17152 --- linux-2.6.8/include/asm-parisc/pgtable.h    2004-08-14 07:37:40.000000000 +0200
17153 +++ linux-2.6.8.grsecurity/include/asm-parisc/pgtable.h 2004-08-16 17:09:58.000000000 +0200
17154 @@ -208,6 +208,17 @@
17155  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
17156  #define PAGE_COPY       PAGE_EXECREAD
17157  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
17158 +
17159 +#ifdef CONFIG_PAX_PAGEEXEC
17160 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
17161 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
17162 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
17163 +#else
17164 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17165 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17166 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17167 +#endif
17168 +
17169  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
17170  #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
17171  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
17172 diff -uNr linux-2.6.8/include/asm-ppc/a.out.h linux-2.6.8.grsecurity/include/asm-ppc/a.out.h
17173 --- linux-2.6.8/include/asm-ppc/a.out.h 2004-08-14 07:36:58.000000000 +0200
17174 +++ linux-2.6.8.grsecurity/include/asm-ppc/a.out.h      2004-08-16 17:09:58.000000000 +0200
17175 @@ -2,7 +2,7 @@
17176  #define __PPC_A_OUT_H__
17177  
17178  /* grabbed from the intel stuff  */
17179 -#define STACK_TOP TASK_SIZE
17180 +#define __STACK_TOP TASK_SIZE
17181  
17182  
17183  struct exec
17184 diff -uNr linux-2.6.8/include/asm-ppc/elf.h linux-2.6.8.grsecurity/include/asm-ppc/elf.h
17185 --- linux-2.6.8/include/asm-ppc/elf.h   2004-08-14 07:36:10.000000000 +0200
17186 +++ linux-2.6.8.grsecurity/include/asm-ppc/elf.h        2004-08-16 17:09:58.000000000 +0200
17187 @@ -90,6 +90,17 @@
17188  
17189  #define ELF_ET_DYN_BASE         (0x08000000)
17190  
17191 +#ifdef CONFIG_PAX_ASLR
17192 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
17193 +
17194 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17195 +#define PAX_DELTA_MMAP_LEN(tsk)                15
17196 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17197 +#define PAX_DELTA_EXEC_LEN(tsk)                15
17198 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17199 +#define PAX_DELTA_STACK_LEN(tsk)       15
17200 +#endif
17201 +
17202  #define USE_ELF_CORE_DUMP
17203  #define ELF_EXEC_PAGESIZE      4096
17204  
17205 diff -uNr linux-2.6.8/include/asm-ppc/mman.h linux-2.6.8.grsecurity/include/asm-ppc/mman.h
17206 --- linux-2.6.8/include/asm-ppc/mman.h  2004-08-14 07:38:11.000000000 +0200
17207 +++ linux-2.6.8.grsecurity/include/asm-ppc/mman.h       2004-08-16 17:09:58.000000000 +0200
17208 @@ -24,6 +24,10 @@
17209  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
17210  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
17211  
17212 +#ifdef CONFIG_PAX_RANDEXEC
17213 +#define MAP_MIRROR     0x0200
17214 +#endif
17215 +
17216  #define MS_ASYNC       1               /* sync memory asynchronously */
17217  #define MS_INVALIDATE  2               /* invalidate the caches */
17218  #define MS_SYNC                4               /* synchronous memory sync */
17219 diff -uNr linux-2.6.8/include/asm-ppc/page.h linux-2.6.8.grsecurity/include/asm-ppc/page.h
17220 --- linux-2.6.8/include/asm-ppc/page.h  2004-08-14 07:36:33.000000000 +0200
17221 +++ linux-2.6.8.grsecurity/include/asm-ppc/page.h       2004-08-16 17:09:58.000000000 +0200
17222 @@ -163,5 +163,14 @@
17223  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17224                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17225  
17226 +#ifdef CONFIG_PAX_PAGEEXEC
17227 +#ifdef CONFIG_PAX_MPROTECT
17228 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17229 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17230 +#else
17231 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17232 +#endif
17233 +#endif
17234 +
17235  #endif /* __KERNEL__ */
17236  #endif /* _PPC_PAGE_H */
17237 diff -uNr linux-2.6.8/include/asm-ppc/pgtable.h linux-2.6.8.grsecurity/include/asm-ppc/pgtable.h
17238 --- linux-2.6.8/include/asm-ppc/pgtable.h       2004-08-14 07:36:32.000000000 +0200
17239 +++ linux-2.6.8.grsecurity/include/asm-ppc/pgtable.h    2004-08-16 17:09:58.000000000 +0200
17240 @@ -386,11 +386,21 @@
17241  
17242  #define PAGE_NONE      __pgprot(_PAGE_BASE)
17243  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
17244 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
17245 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
17246  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
17247 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
17248 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
17249  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
17250 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
17251 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
17252 +
17253 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
17254 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
17255 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17256 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17257 +#else
17258 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17259 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17260 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17261 +#endif
17262  
17263  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
17264  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
17265 @@ -402,21 +412,21 @@
17266   * This is the closest we can get..
17267   */
17268  #define __P000 PAGE_NONE
17269 -#define __P001 PAGE_READONLY_X
17270 -#define __P010 PAGE_COPY
17271 -#define __P011 PAGE_COPY_X
17272 -#define __P100 PAGE_READONLY
17273 +#define __P001 PAGE_READONLY_NOEXEC
17274 +#define __P010 PAGE_COPY_NOEXEC
17275 +#define __P011 PAGE_COPY_NOEXEC
17276 +#define __P100 PAGE_READONLY_X
17277  #define __P101 PAGE_READONLY_X
17278 -#define __P110 PAGE_COPY
17279 +#define __P110 PAGE_COPY_X
17280  #define __P111 PAGE_COPY_X
17281  
17282  #define __S000 PAGE_NONE
17283 -#define __S001 PAGE_READONLY_X
17284 -#define __S010 PAGE_SHARED
17285 -#define __S011 PAGE_SHARED_X
17286 -#define __S100 PAGE_READONLY
17287 +#define __S001 PAGE_READONLY_NOEXEC
17288 +#define __S010 PAGE_SHARED_NOEXEC
17289 +#define __S011 PAGE_SHARED_NOEXEC
17290 +#define __S100 PAGE_READONLY_X
17291  #define __S101 PAGE_READONLY_X
17292 -#define __S110 PAGE_SHARED
17293 +#define __S110 PAGE_SHARED_X
17294  #define __S111 PAGE_SHARED_X
17295  
17296  #ifndef __ASSEMBLY__
17297 diff -uNr linux-2.6.8/include/asm-ppc64/a.out.h linux-2.6.8.grsecurity/include/asm-ppc64/a.out.h
17298 --- linux-2.6.8/include/asm-ppc64/a.out.h       2004-08-14 07:36:12.000000000 +0200
17299 +++ linux-2.6.8.grsecurity/include/asm-ppc64/a.out.h    2004-08-16 17:09:58.000000000 +0200
17300 @@ -35,7 +35,7 @@
17301  /* Give 32-bit user space a full 4G address space to live in. */
17302  #define STACK_TOP_USER32 (TASK_SIZE_USER32)
17303  
17304 -#define STACK_TOP ((test_thread_flag(TIF_32BIT) || \
17305 +#define __STACK_TOP ((test_thread_flag(TIF_32BIT) || \
17306                 (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \
17307                 STACK_TOP_USER32 : STACK_TOP_USER64)
17308  
17309 diff -uNr linux-2.6.8/include/asm-ppc64/elf.h linux-2.6.8.grsecurity/include/asm-ppc64/elf.h
17310 --- linux-2.6.8/include/asm-ppc64/elf.h 2004-08-14 07:37:37.000000000 +0200
17311 +++ linux-2.6.8.grsecurity/include/asm-ppc64/elf.h      2004-08-16 17:09:58.000000000 +0200
17312 @@ -154,6 +154,17 @@
17313  
17314  #define ELF_ET_DYN_BASE         (0x08000000)
17315  
17316 +#ifdef CONFIG_PAX_ASLR
17317 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
17318 +
17319 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17320 +#define PAX_DELTA_MMAP_LEN(tsk)                ((test_thread_flag(TIF_32BIT) || (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? 16 : 24)
17321 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17322 +#define PAX_DELTA_EXEC_LEN(tsk)                ((test_thread_flag(TIF_32BIT) || (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? 16 : 24)
17323 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17324 +#define PAX_DELTA_STACK_LEN(tsk)       ((test_thread_flag(TIF_32BIT) || (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? 16 : 24)
17325 +#endif
17326 +
17327  #ifdef __KERNEL__
17328  
17329  /* Common routine for both 32-bit and 64-bit processes */
17330 diff -uNr linux-2.6.8/include/asm-ppc64/mman.h linux-2.6.8.grsecurity/include/asm-ppc64/mman.h
17331 --- linux-2.6.8/include/asm-ppc64/mman.h        2004-08-14 07:36:56.000000000 +0200
17332 +++ linux-2.6.8.grsecurity/include/asm-ppc64/mman.h     2004-08-16 17:09:58.000000000 +0200
17333 @@ -29,6 +29,10 @@
17334  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
17335  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
17336  
17337 +#ifdef CONFIG_PAX_RANDEXEC
17338 +#define MAP_MIRROR     0x0200
17339 +#endif
17340 +
17341  #define MS_ASYNC       1               /* sync memory asynchronously */
17342  #define MS_INVALIDATE  2               /* invalidate the caches */
17343  #define MS_SYNC                4               /* synchronous memory sync */
17344 diff -uNr linux-2.6.8/include/asm-ppc64/page.h linux-2.6.8.grsecurity/include/asm-ppc64/page.h
17345 --- linux-2.6.8/include/asm-ppc64/page.h        2004-08-14 07:36:11.000000000 +0200
17346 +++ linux-2.6.8.grsecurity/include/asm-ppc64/page.h     2004-08-16 17:09:58.000000000 +0200
17347 @@ -246,5 +246,14 @@
17348  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17349                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17350  
17351 +#ifdef CONFIG_PAX_PAGEEXEC
17352 +#ifdef CONFIG_PAX_MPROTECT
17353 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17354 +                        ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17355 +#else
17356 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17357 +#endif
17358 +#endif
17359 +
17360  #endif /* __KERNEL__ */
17361  #endif /* _PPC64_PAGE_H */
17362 diff -uNr linux-2.6.8/include/asm-ppc64/pgtable.h linux-2.6.8.grsecurity/include/asm-ppc64/pgtable.h
17363 --- linux-2.6.8/include/asm-ppc64/pgtable.h     2004-08-14 07:38:04.000000000 +0200
17364 +++ linux-2.6.8.grsecurity/include/asm-ppc64/pgtable.h  2004-08-16 17:09:58.000000000 +0200
17365 @@ -112,6 +112,17 @@
17366  #define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
17367  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
17368  #define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
17369 +
17370 +#ifdef CONFIG_PAX_PAGEEXEC
17371 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_GUARDED)
17372 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17373 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17374 +#else
17375 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17376 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17377 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17378 +#endif
17379 +
17380  #define PAGE_KERNEL    __pgprot(_PAGE_BASE | _PAGE_WRENABLE)
17381  #define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
17382                                _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
17383 @@ -123,21 +134,21 @@
17384   * This is the closest we can get..
17385   */
17386  #define __P000 PAGE_NONE
17387 -#define __P001 PAGE_READONLY_X
17388 -#define __P010 PAGE_COPY
17389 -#define __P011 PAGE_COPY_X
17390 -#define __P100 PAGE_READONLY
17391 +#define __P001 PAGE_READONLY_NOEXEC
17392 +#define __P010 PAGE_COPY_NOEXEC
17393 +#define __P011 PAGE_COPY_NOEXEC
17394 +#define __P100 PAGE_READONLY_X
17395  #define __P101 PAGE_READONLY_X
17396 -#define __P110 PAGE_COPY
17397 +#define __P110 PAGE_COPY_X
17398  #define __P111 PAGE_COPY_X
17399  
17400  #define __S000 PAGE_NONE
17401 -#define __S001 PAGE_READONLY_X
17402 -#define __S010 PAGE_SHARED
17403 -#define __S011 PAGE_SHARED_X
17404 -#define __S100 PAGE_READONLY
17405 +#define __S001 PAGE_READONLY_NOEXEC
17406 +#define __S010 PAGE_SHARED_NOEXEC
17407 +#define __S011 PAGE_SHARED_NOEXEC
17408 +#define __S100 PAGE_READONLY_X
17409  #define __S101 PAGE_READONLY_X
17410 -#define __S110 PAGE_SHARED
17411 +#define __S110 PAGE_SHARED_X
17412  #define __S111 PAGE_SHARED_X
17413  
17414  #ifndef __ASSEMBLY__
17415 diff -uNr linux-2.6.8/include/asm-sparc/a.out.h linux-2.6.8.grsecurity/include/asm-sparc/a.out.h
17416 --- linux-2.6.8/include/asm-sparc/a.out.h       2004-08-14 07:36:13.000000000 +0200
17417 +++ linux-2.6.8.grsecurity/include/asm-sparc/a.out.h    2004-08-16 17:09:59.000000000 +0200
17418 @@ -91,7 +91,7 @@
17419  
17420  #include <asm/page.h>
17421  
17422 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
17423 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
17424  
17425  #endif /* __KERNEL__ */
17426  
17427 diff -uNr linux-2.6.8/include/asm-sparc/elf.h linux-2.6.8.grsecurity/include/asm-sparc/elf.h
17428 --- linux-2.6.8/include/asm-sparc/elf.h 2004-08-14 07:37:38.000000000 +0200
17429 +++ linux-2.6.8.grsecurity/include/asm-sparc/elf.h      2004-08-16 17:09:59.000000000 +0200
17430 @@ -145,6 +145,17 @@
17431  
17432  #define ELF_ET_DYN_BASE         (0x08000000)
17433  
17434 +#ifdef CONFIG_PAX_ASLR
17435 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
17436 +
17437 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17438 +#define PAX_DELTA_MMAP_LEN(tsk)                16
17439 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17440 +#define PAX_DELTA_EXEC_LEN(tsk)                16
17441 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17442 +#define PAX_DELTA_STACK_LEN(tsk)       16
17443 +#endif
17444 +
17445  /* This yields a mask that user programs can use to figure out what
17446     instruction set this cpu supports.  This can NOT be done in userspace
17447     on Sparc.  */
17448 diff -uNr linux-2.6.8/include/asm-sparc/mman.h linux-2.6.8.grsecurity/include/asm-sparc/mman.h
17449 --- linux-2.6.8/include/asm-sparc/mman.h        2004-08-14 07:38:04.000000000 +0200
17450 +++ linux-2.6.8.grsecurity/include/asm-sparc/mman.h     2004-08-16 17:09:59.000000000 +0200
17451 @@ -27,6 +27,10 @@
17452  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
17453  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
17454  
17455 +#ifdef CONFIG_PAX_RANDEXEC
17456 +#define MAP_MIRROR     0x0400
17457 +#endif
17458 +
17459  #define MS_ASYNC       1               /* sync memory asynchronously */
17460  #define MS_INVALIDATE  2               /* invalidate the caches */
17461  #define MS_SYNC                4               /* synchronous memory sync */
17462 diff -uNr linux-2.6.8/include/asm-sparc/page.h linux-2.6.8.grsecurity/include/asm-sparc/page.h
17463 --- linux-2.6.8/include/asm-sparc/page.h        2004-08-14 07:36:33.000000000 +0200
17464 +++ linux-2.6.8.grsecurity/include/asm-sparc/page.h     2004-08-16 17:09:59.000000000 +0200
17465 @@ -176,6 +176,15 @@
17466  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17467                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17468  
17469 +#ifdef CONFIG_PAX_PAGEEXEC
17470 +#ifdef CONFIG_PAX_MPROTECT
17471 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17472 +                        ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17473 +#else
17474 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17475 +#endif
17476 +#endif
17477 +
17478  #endif /* __KERNEL__ */
17479  
17480  #endif /* _SPARC_PAGE_H */
17481 diff -uNr linux-2.6.8/include/asm-sparc/pgtable.h linux-2.6.8.grsecurity/include/asm-sparc/pgtable.h
17482 --- linux-2.6.8/include/asm-sparc/pgtable.h     2004-08-14 07:37:14.000000000 +0200
17483 +++ linux-2.6.8.grsecurity/include/asm-sparc/pgtable.h  2004-08-16 17:09:59.000000000 +0200
17484 @@ -48,6 +48,13 @@
17485  BTFIXUPDEF_INT(page_shared)
17486  BTFIXUPDEF_INT(page_copy)
17487  BTFIXUPDEF_INT(page_readonly)
17488 +
17489 +#ifdef CONFIG_PAX_PAGEEXEC
17490 +BTFIXUPDEF_INT(page_shared_noexec)
17491 +BTFIXUPDEF_INT(page_copy_noexec)
17492 +BTFIXUPDEF_INT(page_readonly_noexec)
17493 +#endif
17494 +
17495  BTFIXUPDEF_INT(page_kernel)
17496  
17497  #define PMD_SHIFT              SUN4C_PMD_SHIFT
17498 @@ -69,6 +76,16 @@
17499  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
17500  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
17501  
17502 +#ifdef CONFIG_PAX_PAGEEXEC
17503 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
17504 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
17505 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
17506 +#else
17507 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17508 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17509 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17510 +#endif
17511 +
17512  extern unsigned long page_kernel;
17513  
17514  #ifdef MODULE
17515 diff -uNr linux-2.6.8/include/asm-sparc/pgtsrmmu.h linux-2.6.8.grsecurity/include/asm-sparc/pgtsrmmu.h
17516 --- linux-2.6.8/include/asm-sparc/pgtsrmmu.h    2004-08-14 07:36:45.000000000 +0200
17517 +++ linux-2.6.8.grsecurity/include/asm-sparc/pgtsrmmu.h 2004-08-16 17:09:59.000000000 +0200
17518 @@ -114,6 +114,16 @@
17519                                     SRMMU_EXEC | SRMMU_REF)
17520  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17521                                     SRMMU_EXEC | SRMMU_REF)
17522 +
17523 +#ifdef CONFIG_PAX_PAGEEXEC
17524 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17525 +                                          SRMMU_WRITE | SRMMU_REF)
17526 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17527 +                                          SRMMU_REF)
17528 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17529 +                                          SRMMU_REF)
17530 +#endif
17531 +
17532  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
17533                                     SRMMU_DIRTY | SRMMU_REF)
17534  
17535 diff -uNr linux-2.6.8/include/asm-sparc/uaccess.h linux-2.6.8.grsecurity/include/asm-sparc/uaccess.h
17536 --- linux-2.6.8/include/asm-sparc/uaccess.h     2004-08-14 07:37:40.000000000 +0200
17537 +++ linux-2.6.8.grsecurity/include/asm-sparc/uaccess.h  2004-08-16 17:09:59.000000000 +0200
17538 @@ -41,7 +41,7 @@
17539   * No one can read/write anything from userland in the kernel space by setting
17540   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
17541   */
17542 -#define __user_ok(addr,size) ((addr) < STACK_TOP)
17543 +#define __user_ok(addr,size) ((addr) < __STACK_TOP)
17544  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
17545  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
17546  #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
17547 diff -uNr linux-2.6.8/include/asm-sparc64/a.out.h linux-2.6.8.grsecurity/include/asm-sparc64/a.out.h
17548 --- linux-2.6.8/include/asm-sparc64/a.out.h     2004-08-14 07:37:27.000000000 +0200
17549 +++ linux-2.6.8.grsecurity/include/asm-sparc64/a.out.h  2004-08-16 17:09:59.000000000 +0200
17550 @@ -95,7 +95,7 @@
17551  
17552  #ifdef __KERNEL__
17553  
17554 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
17555 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
17556  
17557  #endif
17558  
17559 diff -uNr linux-2.6.8/include/asm-sparc64/elf.h linux-2.6.8.grsecurity/include/asm-sparc64/elf.h
17560 --- linux-2.6.8/include/asm-sparc64/elf.h       2004-08-14 07:36:45.000000000 +0200
17561 +++ linux-2.6.8.grsecurity/include/asm-sparc64/elf.h    2004-08-16 17:09:59.000000000 +0200
17562 @@ -140,6 +140,16 @@
17563  #define ELF_ET_DYN_BASE         0x0000010000000000UL
17564  #endif
17565  
17566 +#ifdef CONFIG_PAX_ASLR
17567 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
17568 +
17569 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
17570 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
17571 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
17572 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
17573 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17574 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
17575 +#endif
17576  
17577  /* This yields a mask that user programs can use to figure out what
17578     instruction set this cpu supports.  */
17579 diff -uNr linux-2.6.8/include/asm-sparc64/mman.h linux-2.6.8.grsecurity/include/asm-sparc64/mman.h
17580 --- linux-2.6.8/include/asm-sparc64/mman.h      2004-08-14 07:36:57.000000000 +0200
17581 +++ linux-2.6.8.grsecurity/include/asm-sparc64/mman.h   2004-08-16 17:09:59.000000000 +0200
17582 @@ -27,6 +27,10 @@
17583  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
17584  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
17585  
17586 +#ifdef CONFIG_PAX_RANDEXEC
17587 +#define MAP_MIRROR     0x0400
17588 +#endif
17589 +
17590  #define MS_ASYNC       1               /* sync memory asynchronously */
17591  #define MS_INVALIDATE  2               /* invalidate the caches */
17592  #define MS_SYNC                4               /* synchronous memory sync */
17593 diff -uNr linux-2.6.8/include/asm-sparc64/page.h linux-2.6.8.grsecurity/include/asm-sparc64/page.h
17594 --- linux-2.6.8/include/asm-sparc64/page.h      2004-08-14 07:36:56.000000000 +0200
17595 +++ linux-2.6.8.grsecurity/include/asm-sparc64/page.h   2004-08-16 17:09:59.000000000 +0200
17596 @@ -165,6 +165,15 @@
17597  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
17598                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17599  
17600 +#ifdef CONFIG_PAX_PAGEEXEC
17601 +#ifdef CONFIG_PAX_MPROTECT
17602 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17603 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17604 +#else
17605 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17606 +#endif
17607 +#endif
17608 +
17609  #endif /* !(__KERNEL__) */
17610  
17611  #endif /* !(_SPARC64_PAGE_H) */
17612 diff -uNr linux-2.6.8/include/asm-sparc64/pgtable.h linux-2.6.8.grsecurity/include/asm-sparc64/pgtable.h
17613 --- linux-2.6.8/include/asm-sparc64/pgtable.h   2004-08-14 07:36:12.000000000 +0200
17614 +++ linux-2.6.8.grsecurity/include/asm-sparc64/pgtable.h        2004-08-16 18:20:22.000000000 +0200
17615 @@ -140,7 +140,7 @@
17616   * interpreted that way unless _PAGE_PRESENT is clear.
17617   */
17618  #define _PAGE_EXEC     _AC(0x0000000000001000,UL)      /* Executable SW bit */
17619 -#define _PAGE_MODIFIED _AC(0x0000000000000800,UL)      /* Modified (dirty)  */
17620 +#define _PAGE_MODIFIED _AC(0x0000000000000800,UL)      /* Modified (dirty)   */
17621  #define _PAGE_FILE     _AC(0x0000000000000800,UL)      /* Pagecache page    */
17622  #define _PAGE_ACCESSED _AC(0x0000000000000400,UL)      /* Accessed (ref'd)  */
17623  #define _PAGE_READ     _AC(0x0000000000000200,UL)      /* Readable SW Bit   */
17624 diff -uNr linux-2.6.8/include/asm-x86_64/a.out.h linux-2.6.8.grsecurity/include/asm-x86_64/a.out.h
17625 --- linux-2.6.8/include/asm-x86_64/a.out.h      2004-08-14 07:36:56.000000000 +0200
17626 +++ linux-2.6.8.grsecurity/include/asm-x86_64/a.out.h   2004-08-16 17:09:59.000000000 +0200
17627 @@ -21,7 +21,7 @@
17628  
17629  #ifdef __KERNEL__
17630  #include <linux/thread_info.h>
17631 -#define STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
17632 +#define __STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
17633  #endif
17634  
17635  #endif /* __A_OUT_GNU_H__ */
17636 diff -uNr linux-2.6.8/include/asm-x86_64/elf.h linux-2.6.8.grsecurity/include/asm-x86_64/elf.h
17637 --- linux-2.6.8/include/asm-x86_64/elf.h        2004-08-14 07:37:38.000000000 +0200
17638 +++ linux-2.6.8.grsecurity/include/asm-x86_64/elf.h     2004-08-16 17:09:59.000000000 +0200
17639 @@ -89,6 +89,17 @@
17640  
17641  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
17642  
17643 +#ifdef CONFIG_PAX_ASLR
17644 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
17645 +
17646 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
17647 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
17648 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
17649 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
17650 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
17651 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 24)
17652 +#endif
17653 +
17654  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
17655     now struct_user_regs, they are different). Assumes current is the process
17656     getting dumped. */
17657 diff -uNr linux-2.6.8/include/asm-x86_64/mman.h linux-2.6.8.grsecurity/include/asm-x86_64/mman.h
17658 --- linux-2.6.8/include/asm-x86_64/mman.h       2004-08-14 07:37:26.000000000 +0200
17659 +++ linux-2.6.8.grsecurity/include/asm-x86_64/mman.h    2004-08-16 17:09:59.000000000 +0200
17660 @@ -24,6 +24,10 @@
17661  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
17662  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
17663  
17664 +#ifdef CONFIG_PAX_RANDEXEC
17665 +#define MAP_MIRROR     0x8000
17666 +#endif
17667 +
17668  #define MS_ASYNC       1               /* sync memory asynchronously */
17669  #define MS_INVALIDATE  2               /* invalidate the caches */
17670  #define MS_SYNC                4               /* synchronous memory sync */
17671 diff -uNr linux-2.6.8/include/asm-x86_64/page.h linux-2.6.8.grsecurity/include/asm-x86_64/page.h
17672 --- linux-2.6.8/include/asm-x86_64/page.h       2004-08-14 07:36:13.000000000 +0200
17673 +++ linux-2.6.8.grsecurity/include/asm-x86_64/page.h    2004-08-16 17:09:59.000000000 +0200
17674 @@ -132,6 +132,16 @@
17675  
17676  #define __VM_DATA_DEFAULT_FLAGS        (VM_READ | VM_WRITE | VM_EXEC | \
17677                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17678 +
17679 +#ifdef CONFIG_PAX_PAGEEXEC
17680 +#define VM_DATA_DEFAULT_FLAGS __VM_DATA_DEFAULT_FLAGS
17681 +#ifdef CONFIG_PAX_MPROTECT
17682 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
17683 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17684 +#else
17685 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
17686 +#endif
17687 +#else
17688  #define __VM_STACK_FLAGS       (VM_GROWSDOWN | VM_READ | VM_WRITE | VM_EXEC | \
17689                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
17690  
17691 @@ -142,6 +152,8 @@
17692  #define VM_STACK_DEFAULT_FLAGS \
17693         (test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags) 
17694         
17695 +#endif
17696 +
17697  #define CONFIG_ARCH_GATE_AREA 1        
17698  
17699  #ifndef __ASSEMBLY__
17700 diff -uNr linux-2.6.8/include/asm-x86_64/pgalloc.h linux-2.6.8.grsecurity/include/asm-x86_64/pgalloc.h
17701 --- linux-2.6.8/include/asm-x86_64/pgalloc.h    2004-08-14 07:36:59.000000000 +0200
17702 +++ linux-2.6.8.grsecurity/include/asm-x86_64/pgalloc.h 2004-08-16 17:09:59.000000000 +0200
17703 @@ -8,7 +8,7 @@
17704  #include <linux/mm.h>
17705  
17706  #define pmd_populate_kernel(mm, pmd, pte) \
17707 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
17708 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
17709  #define pgd_populate(mm, pgd, pmd) \
17710                 set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pmd)))
17711  
17712 diff -uNr linux-2.6.8/include/asm-x86_64/pgtable.h linux-2.6.8.grsecurity/include/asm-x86_64/pgtable.h
17713 --- linux-2.6.8/include/asm-x86_64/pgtable.h    2004-08-14 07:37:30.000000000 +0200
17714 +++ linux-2.6.8.grsecurity/include/asm-x86_64/pgtable.h 2004-08-16 17:09:59.000000000 +0200
17715 @@ -170,6 +170,10 @@
17716  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
17717  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
17718  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
17719 +
17720 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
17721 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
17722 +
17723  #define __PAGE_KERNEL \
17724         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
17725  #define __PAGE_KERNEL_EXEC \
17726 diff -uNr linux-2.6.8/include/linux/a.out.h linux-2.6.8.grsecurity/include/linux/a.out.h
17727 --- linux-2.6.8/include/linux/a.out.h   2004-08-14 07:37:15.000000000 +0200
17728 +++ linux-2.6.8.grsecurity/include/linux/a.out.h        2004-08-16 17:09:59.000000000 +0200
17729 @@ -7,6 +7,16 @@
17730  
17731  #include <asm/a.out.h>
17732  
17733 +#ifdef CONFIG_PAX_RANDUSTACK
17734 +#define __DELTA_STACK (current->mm->delta_stack)
17735 +#else
17736 +#define __DELTA_STACK 0UL
17737 +#endif
17738 +
17739 +#ifndef STACK_TOP
17740 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
17741 +#endif
17742 +
17743  #endif /* __STRUCT_EXEC_OVERRIDE__ */
17744  
17745  /* these go in the N_MACHTYPE field */
17746 @@ -37,6 +47,14 @@
17747    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
17748  };
17749  
17750 +/* Constants for the N_FLAGS field */
17751 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
17752 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
17753 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
17754 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
17755 +#define F_PAX_RANDEXEC 16      /* Randomize ET_EXEC base */
17756 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
17757 +
17758  #if !defined (N_MAGIC)
17759  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
17760  #endif
17761 diff -uNr linux-2.6.8/include/linux/binfmts.h linux-2.6.8.grsecurity/include/linux/binfmts.h
17762 --- linux-2.6.8/include/linux/binfmts.h 2004-08-14 07:36:58.000000000 +0200
17763 +++ linux-2.6.8.grsecurity/include/linux/binfmts.h      2004-08-16 17:09:59.000000000 +0200
17764 @@ -38,6 +38,7 @@
17765         unsigned interp_flags;
17766         unsigned interp_data;
17767         unsigned long loader, exec;
17768 +       int misc;
17769  };
17770  
17771  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
17772 @@ -81,5 +82,8 @@
17773  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
17774  extern int set_binfmt(struct linux_binfmt *new);
17775  
17776 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
17777 +void pax_report_insns(void *pc, void *sp);
17778 +
17779  #endif /* __KERNEL__ */
17780  #endif /* _LINUX_BINFMTS_H */
17781 diff -uNr linux-2.6.8/include/linux/elf.h linux-2.6.8.grsecurity/include/linux/elf.h
17782 --- linux-2.6.8/include/linux/elf.h     2004-08-14 07:36:17.000000000 +0200
17783 +++ linux-2.6.8.grsecurity/include/linux/elf.h  2004-08-16 17:09:59.000000000 +0200
17784 @@ -44,6 +44,16 @@
17785  
17786  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
17787  
17788 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
17789 +
17790 +/* Constants for the e_flags field */
17791 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
17792 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
17793 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
17794 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
17795 +#define EF_PAX_RANDEXEC                16      /* Randomize ET_EXEC base */
17796 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
17797 +
17798  /* These constants define the different elf file types */
17799  #define ET_NONE   0
17800  #define ET_REL    1
17801 @@ -129,6 +139,8 @@
17802  #define DT_DEBUG       21
17803  #define DT_TEXTREL     22
17804  #define DT_JMPREL      23
17805 +#define DT_FLAGS       30
17806 +  #define DF_TEXTREL   0x00000004
17807  #define DT_LOPROC      0x70000000
17808  #define DT_HIPROC      0x7fffffff
17809  
17810 @@ -279,6 +291,19 @@
17811  #define PF_W           0x2
17812  #define PF_X           0x1
17813  
17814 +#define PF_PAGEEXEC    (1 << 4)        /* Enable  PAGEEXEC */
17815 +#define PF_NOPAGEEXEC  (1 << 5)        /* Disable PAGEEXEC */
17816 +#define PF_SEGMEXEC    (1 << 6)        /* Enable  SEGMEXEC */
17817 +#define PF_NOSEGMEXEC  (1 << 7)        /* Disable SEGMEXEC */
17818 +#define PF_MPROTECT    (1 << 8)        /* Enable  MPROTECT */
17819 +#define PF_NOMPROTECT  (1 << 9)        /* Disable MPROTECT */
17820 +#define PF_RANDEXEC    (1 << 10)       /* Enable  RANDEXEC */
17821 +#define PF_NORANDEXEC  (1 << 11)       /* Disable RANDEXEC */
17822 +#define PF_EMUTRAMP    (1 << 12)       /* Enable  EMUTRAMP */
17823 +#define PF_NOEMUTRAMP  (1 << 13)       /* Disable EMUTRAMP */
17824 +#define PF_RANDMMAP    (1 << 14)       /* Enable  RANDMMAP */
17825 +#define PF_NORANDMMAP  (1 << 15)       /* Disable RANDMMAP */
17826 +
17827  typedef struct elf32_phdr{
17828    Elf32_Word   p_type;
17829    Elf32_Off    p_offset;
17830 @@ -371,6 +396,8 @@
17831  #define        EI_OSABI        7
17832  #define        EI_PAD          8
17833  
17834 +#define        EI_PAX          14
17835 +
17836  #define        ELFMAG0         0x7f            /* EI_MAG */
17837  #define        ELFMAG1         'E'
17838  #define        ELFMAG2         'L'
17839 @@ -427,6 +454,7 @@
17840  #define elfhdr         elf32_hdr
17841  #define elf_phdr       elf32_phdr
17842  #define elf_note       elf32_note
17843 +#define elf_dyn                Elf32_Dyn
17844  
17845  #else
17846  
17847 @@ -434,6 +462,7 @@
17848  #define elfhdr         elf64_hdr
17849  #define elf_phdr       elf64_phdr
17850  #define elf_note       elf64_note
17851 +#define elf_dyn                Elf64_Dyn
17852  
17853  #endif
17854  
17855 diff -uNr linux-2.6.8/include/linux/fs.h linux-2.6.8.grsecurity/include/linux/fs.h
17856 --- linux-2.6.8/include/linux/fs.h      2004-08-14 07:36:32.000000000 +0200
17857 +++ linux-2.6.8.grsecurity/include/linux/fs.h   2004-08-16 17:09:59.000000000 +0200
17858 @@ -1203,7 +1203,7 @@
17859  
17860  /* fs/open.c */
17861  
17862 -extern int do_truncate(struct dentry *, loff_t start);
17863 +extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
17864  extern struct file *filp_open(const char *, int, int);
17865  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
17866  extern int filp_close(struct file *, fl_owner_t id);
17867 diff -uNr linux-2.6.8/include/linux/gracl.h linux-2.6.8.grsecurity/include/linux/gracl.h
17868 --- linux-2.6.8/include/linux/gracl.h   1970-01-01 01:00:00.000000000 +0100
17869 +++ linux-2.6.8.grsecurity/include/linux/gracl.h        2004-08-16 17:09:59.000000000 +0200
17870 @@ -0,0 +1,250 @@
17871 +#ifndef GR_ACL_H
17872 +#define GR_ACL_H
17873 +
17874 +#include <linux/grdefs.h>
17875 +#include <linux/resource.h>
17876 +#include <linux/dcache.h>
17877 +#include <asm/resource.h>
17878 +
17879 +/* Major status information */
17880 +
17881 +#define GR_VERSION  "grsecurity 2.0.1"
17882 +#define GRSECURITY_VERSION 0x201
17883 +
17884 +enum {
17885 +
17886 +       SHUTDOWN = 0,
17887 +       ENABLE = 1,
17888 +       SPROLE = 2,
17889 +       RELOAD = 3,
17890 +       SEGVMOD = 4,
17891 +       STATUS = 5,
17892 +       UNSPROLE = 6
17893 +};
17894 +
17895 +/* Password setup definitions
17896 + * kernel/grhash.c */
17897 +enum {
17898 +       GR_PW_LEN = 128,
17899 +       GR_SALT_LEN = 16,
17900 +       GR_SHA_LEN = 32,
17901 +};
17902 +
17903 +enum {
17904 +       GR_SPROLE_LEN = 64,
17905 +};
17906 +
17907 +/* Begin Data Structures */
17908 +
17909 +struct sprole_pw {
17910 +       unsigned char *rolename;
17911 +       unsigned char salt[GR_SALT_LEN];
17912 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
17913 +};
17914 +
17915 +struct name_entry {
17916 +       ino_t inode;
17917 +       dev_t device;
17918 +       char *name;
17919 +       __u16 len;
17920 +};
17921 +
17922 +struct acl_role_db {
17923 +       struct acl_role_label **r_hash;
17924 +       __u32 r_size;
17925 +};
17926 +
17927 +struct name_db {
17928 +       struct name_entry **n_hash;
17929 +       __u32 n_size;
17930 +};
17931 +
17932 +struct crash_uid {
17933 +       uid_t uid;
17934 +       unsigned long expires;
17935 +};
17936 +
17937 +struct gr_hash_struct {
17938 +       void **table;
17939 +       void **nametable;
17940 +       void *first;
17941 +       __u32 table_size;
17942 +       __u32 used_size;
17943 +       int type;
17944 +};
17945 +
17946 +/* Userspace Grsecurity ACL data structures */
17947 +struct acl_subject_label {
17948 +       char *filename;
17949 +       ino_t inode;
17950 +       dev_t device;
17951 +       __u32 mode;
17952 +       __u32 cap_mask;
17953 +       __u32 cap_lower;
17954 +
17955 +       struct rlimit res[RLIM_NLIMITS + 1];
17956 +       __u16 resmask;
17957 +
17958 +       __u8 user_trans_type;
17959 +       __u8 group_trans_type;
17960 +       uid_t *user_transitions;
17961 +       gid_t *group_transitions;
17962 +       __u16 user_trans_num;
17963 +       __u16 group_trans_num;
17964 +
17965 +       __u32 ip_proto[8];
17966 +       __u32 ip_type;
17967 +       struct acl_ip_label **ips;
17968 +       __u32 ip_num;
17969 +
17970 +       __u32 crashes;
17971 +       unsigned long expires;
17972 +
17973 +       struct acl_subject_label *parent_subject;
17974 +       struct gr_hash_struct *hash;
17975 +       struct acl_subject_label *prev;
17976 +       struct acl_subject_label *next;
17977 +
17978 +       struct acl_object_label **obj_hash;
17979 +       __u32 obj_hash_size;
17980 +};
17981 +
17982 +struct role_allowed_ip {
17983 +       __u32 addr;
17984 +       __u32 netmask;
17985 +
17986 +       struct role_allowed_ip *prev;
17987 +       struct role_allowed_ip *next;
17988 +};
17989 +
17990 +struct role_transition {
17991 +       char *rolename;
17992 +
17993 +       struct role_transition *prev;
17994 +       struct role_transition *next;
17995 +};
17996 +
17997 +struct acl_role_label {
17998 +       char *rolename;
17999 +       uid_t uidgid;
18000 +       __u16 roletype;
18001 +
18002 +       __u16 auth_attempts;
18003 +       unsigned long expires;
18004 +
18005 +       struct acl_subject_label *root_label;
18006 +       struct gr_hash_struct *hash;
18007 +
18008 +       struct acl_role_label *prev;
18009 +       struct acl_role_label *next;
18010 +
18011 +       struct role_transition *transitions;
18012 +       struct role_allowed_ip *allowed_ips;
18013 +       uid_t *domain_children;
18014 +       __u16 domain_child_num;
18015 +
18016 +       struct acl_subject_label **subj_hash;
18017 +       __u32 subj_hash_size;
18018 +};
18019 +
18020 +struct user_acl_role_db {
18021 +       struct acl_role_label **r_table;
18022 +       __u32 num_pointers;             /* Number of allocations to track */
18023 +       __u32 num_roles;                /* Number of roles */
18024 +       __u32 num_domain_children;      /* Number of domain children */
18025 +       __u32 num_subjects;             /* Number of subjects */
18026 +       __u32 num_objects;              /* Number of objects */
18027 +};
18028 +
18029 +struct acl_object_label {
18030 +       char *filename;
18031 +       ino_t inode;
18032 +       dev_t device;
18033 +       __u32 mode;
18034 +
18035 +       struct acl_subject_label *nested;
18036 +       struct acl_object_label *globbed;
18037 +
18038 +       /* next two structures not used */
18039 +
18040 +       struct acl_object_label *prev;
18041 +       struct acl_object_label *next;
18042 +};
18043 +
18044 +struct acl_ip_label {
18045 +       __u32 addr;
18046 +       __u32 netmask;
18047 +       __u16 low, high;
18048 +       __u8 mode;
18049 +       __u32 type;
18050 +       __u32 proto[8];
18051 +
18052 +       /* next two structures not used */
18053 +
18054 +       struct acl_ip_label *prev;
18055 +       struct acl_ip_label *next;
18056 +};
18057 +
18058 +struct gr_arg {
18059 +       struct user_acl_role_db role_db;
18060 +       unsigned char pw[GR_PW_LEN];
18061 +       unsigned char salt[GR_SALT_LEN];
18062 +       unsigned char sum[GR_SHA_LEN];
18063 +       unsigned char sp_role[GR_SPROLE_LEN];
18064 +       struct sprole_pw *sprole_pws;
18065 +       dev_t segv_device;
18066 +       ino_t segv_inode;
18067 +       uid_t segv_uid;
18068 +       __u16 num_sprole_pws;
18069 +       __u16 mode;
18070 +};
18071 +
18072 +struct gr_arg_wrapper {
18073 +       struct gr_arg *arg;
18074 +       __u32 version;
18075 +       __u32 size;
18076 +};
18077 +
18078 +struct subject_map {
18079 +       struct acl_subject_label *user;
18080 +       struct acl_subject_label *kernel;
18081 +};
18082 +
18083 +struct acl_subj_map_db {
18084 +       struct subject_map **s_hash;
18085 +       __u32 s_size;
18086 +};
18087 +
18088 +/* End Data Structures Section */
18089 +
18090 +/* Hash functions generated by empirical testing by Brad Spengler
18091 +   Makes good use of the low bits of the inode.  Generally 0-1 times
18092 +   in loop for successful match.  0-3 for unsuccessful match.
18093 +   Shift/add algorithm with modulus of table size and an XOR*/
18094 +
18095 +static __inline__ unsigned long
18096 +rhash(const uid_t uid, const __u16 type, const unsigned long sz)
18097 +{
18098 +       return (((uid << type) + (uid ^ type)) % sz);
18099 +}
18100 +
18101 + static __inline__ unsigned long
18102 +shash(const struct acl_subject_label *userp, const unsigned long sz)
18103 +{
18104 +       return ((const unsigned long)userp % sz);
18105 +}
18106 +
18107 +static __inline__ unsigned long
18108 +fhash(const ino_t ino, const dev_t dev, const unsigned long sz)
18109 +{
18110 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
18111 +}
18112 +
18113 +static __inline__ unsigned long
18114 +nhash(const char *name, const __u16 len, const unsigned long sz)
18115 +{
18116 +       return full_name_hash(name, len) % sz;
18117 +}
18118 +
18119 +#endif
18120 +
18121 diff -uNr linux-2.6.8/include/linux/gralloc.h linux-2.6.8.grsecurity/include/linux/gralloc.h
18122 --- linux-2.6.8/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100
18123 +++ linux-2.6.8.grsecurity/include/linux/gralloc.h      2004-08-16 17:09:59.000000000 +0200
18124 @@ -0,0 +1,8 @@
18125 +#ifndef __GRALLOC_H
18126 +#define __GRALLOC_H
18127 +
18128 +void acl_free_all(void);
18129 +int acl_alloc_stack_init(unsigned long size);
18130 +void *acl_alloc(unsigned long len);
18131 +
18132 +#endif
18133 diff -uNr linux-2.6.8/include/linux/grdefs.h linux-2.6.8.grsecurity/include/linux/grdefs.h
18134 --- linux-2.6.8/include/linux/grdefs.h  1970-01-01 01:00:00.000000000 +0100
18135 +++ linux-2.6.8.grsecurity/include/linux/grdefs.h       2004-08-16 17:09:59.000000000 +0200
18136 @@ -0,0 +1,117 @@
18137 +#ifndef GRDEFS_H
18138 +#define GRDEFS_H
18139 +
18140 +/* Begin grsecurity status declarations */
18141 +
18142 +enum {
18143 +       GR_READY = 0x01,
18144 +       GR_STATUS_INIT = 0x00   // disabled state
18145 +};
18146 +
18147 +/* Begin  ACL declarations */
18148 +
18149 +/* Role flags */
18150 +
18151 +enum {
18152 +       GR_ROLE_USER = 0x0001,
18153 +       GR_ROLE_GROUP = 0x0002,
18154 +       GR_ROLE_DEFAULT = 0x0004,
18155 +       GR_ROLE_SPECIAL = 0x0008,
18156 +       GR_ROLE_AUTH = 0x0010,
18157 +       GR_ROLE_NOPW = 0x0020,
18158 +       GR_ROLE_GOD = 0x0040,
18159 +       GR_ROLE_LEARN = 0x0080,
18160 +       GR_ROLE_TPE = 0x0100,
18161 +       GR_ROLE_DOMAIN = 0x0200
18162 +};
18163 +
18164 +/* ACL Subject and Object mode flags */
18165 +enum {
18166 +       GR_DELETED = 0x00000080
18167 +};
18168 +
18169 +/* ACL Object-only mode flags */
18170 +enum {
18171 +       GR_READ         = 0x00000001,
18172 +       GR_APPEND       = 0x00000002,
18173 +       GR_WRITE        = 0x00000004,
18174 +       GR_EXEC         = 0x00000008,
18175 +       GR_FIND         = 0x00000010,
18176 +       GR_INHERIT      = 0x00000040,
18177 +       GR_PTRACERD     = 0x00000100,
18178 +       GR_SETID        = 0x00000200,
18179 +       GR_CREATE       = 0x00000400,
18180 +       GR_DELETE       = 0x00000800,
18181 +       GR_NOPTRACE     = 0x00001000,
18182 +       GR_AUDIT_READ   = 0x00002000,
18183 +       GR_AUDIT_APPEND = 0x00004000,
18184 +       GR_AUDIT_WRITE  = 0x00008000,
18185 +       GR_AUDIT_EXEC   = 0x00010000,
18186 +       GR_AUDIT_FIND   = 0x00020000,
18187 +       GR_AUDIT_INHERIT= 0x00040000,
18188 +       GR_AUDIT_SETID  = 0x00080000,
18189 +       GR_AUDIT_CREATE = 0x00100000,
18190 +       GR_AUDIT_DELETE = 0x00200000,
18191 +       GR_SUPPRESS     = 0x00400000,
18192 +       GR_NOLEARN      = 0x00800000
18193 +};
18194 +
18195 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
18196 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
18197 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE)
18198 +
18199 +/* ACL subject-only mode flags */
18200 +enum {
18201 +       GR_KILL         = 0x00000001,
18202 +       GR_VIEW         = 0x00000002,
18203 +       GR_PROTECTED    = 0x00000100,
18204 +       GR_LEARN        = 0x00000200,
18205 +       GR_OVERRIDE     = 0x00000400,
18206 +       /* just a placeholder, this mode is only used in userspace */
18207 +       GR_DUMMY        = 0x00000800,
18208 +       GR_PAXPAGE      = 0x00001000,
18209 +       GR_PAXSEGM      = 0x00002000,
18210 +       GR_PAXGCC       = 0x00004000,
18211 +       GR_PAXRANDMMAP  = 0x00008000,
18212 +       GR_PAXRANDEXEC  = 0x00010000,
18213 +       GR_PAXMPROTECT  = 0x00020000,
18214 +       GR_PROTSHM      = 0x00040000,
18215 +       GR_KILLPROC     = 0x00080000,
18216 +       GR_KILLIPPROC   = 0x00100000,
18217 +       /* just a placeholder, this mode is only used in userspace */
18218 +       GR_NOTROJAN     = 0x00200000,
18219 +       GR_PROTPROCFD   = 0x00400000,
18220 +       GR_PROCACCT     = 0x00800000,
18221 +       GR_RELAXPTRACE  = 0x01000000,
18222 +       GR_NESTED       = 0x02000000
18223 +};
18224 +
18225 +enum {
18226 +       GR_ID_USER      = 0x01,
18227 +       GR_ID_GROUP     = 0x02,
18228 +};
18229 +
18230 +enum {
18231 +       GR_ID_ALLOW     = 0x01,
18232 +       GR_ID_DENY      = 0x02,
18233 +};
18234 +
18235 +#define GR_CRASH_RES   11
18236 +#define GR_UIDTABLE_MAX 500
18237 +
18238 +/* begin resource learning section */
18239 +enum {
18240 +       GR_RLIM_CPU_BUMP = 60,
18241 +       GR_RLIM_FSIZE_BUMP = 50000,
18242 +       GR_RLIM_DATA_BUMP = 10000,
18243 +       GR_RLIM_STACK_BUMP = 1000,
18244 +       GR_RLIM_CORE_BUMP = 10000,
18245 +       GR_RLIM_RSS_BUMP = 500000,
18246 +       GR_RLIM_NPROC_BUMP = 1,
18247 +       GR_RLIM_NOFILE_BUMP = 5,
18248 +       GR_RLIM_MEMLOCK_BUMP = 50000,
18249 +       GR_RLIM_AS_BUMP = 500000,
18250 +       GR_RLIM_LOCKS_BUMP = 2
18251 +};
18252 +
18253 +#endif
18254 diff -uNr linux-2.6.8/include/linux/grinternal.h linux-2.6.8.grsecurity/include/linux/grinternal.h
18255 --- linux-2.6.8/include/linux/grinternal.h      1970-01-01 01:00:00.000000000 +0100
18256 +++ linux-2.6.8.grsecurity/include/linux/grinternal.h   2004-08-16 17:09:59.000000000 +0200
18257 @@ -0,0 +1,202 @@
18258 +#ifndef __GRINTERNAL_H
18259 +#define __GRINTERNAL_H
18260 +
18261 +#ifdef CONFIG_GRKERNSEC
18262 +
18263 +#include <linux/fs.h>
18264 +#include <linux/gracl.h>
18265 +#include <linux/grdefs.h>
18266 +#include <linux/grmsg.h>
18267 +
18268 +extern void gr_add_learn_entry(const char *fmt, ...);
18269 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
18270 +                           const struct vfsmount *mnt);
18271 +extern __u32 gr_check_create(const struct dentry *new_dentry,
18272 +                            const struct dentry *parent,
18273 +                            const struct vfsmount *mnt, const __u32 mode);
18274 +extern int gr_check_protected_task(const struct task_struct *task);
18275 +extern __u32 to_gr_audit(const __u32 reqmode);
18276 +extern int gr_set_acls(const int type);
18277 +
18278 +extern int gr_acl_is_enabled(void);
18279 +extern char gr_roletype_to_char(void);
18280 +
18281 +extern void gr_handle_alertkill(void);
18282 +extern char *gr_to_filename(const struct dentry *dentry,
18283 +                           const struct vfsmount *mnt);
18284 +extern char *gr_to_filename1(const struct dentry *dentry,
18285 +                           const struct vfsmount *mnt);
18286 +extern char *gr_to_filename2(const struct dentry *dentry,
18287 +                           const struct vfsmount *mnt);
18288 +extern char *gr_to_filename3(const struct dentry *dentry,
18289 +                           const struct vfsmount *mnt);
18290 +
18291 +extern int grsec_enable_link;
18292 +extern int grsec_enable_fifo;
18293 +extern int grsec_enable_execve;
18294 +extern int grsec_enable_forkbomb;
18295 +extern int grsec_forkbomb_gid;
18296 +extern int grsec_forkbomb_sec;
18297 +extern int grsec_forkbomb_max;
18298 +extern int grsec_enable_execlog;
18299 +extern int grsec_enable_signal;
18300 +extern int grsec_enable_forkfail;
18301 +extern int grsec_enable_time;
18302 +extern int grsec_enable_chroot_shmat;
18303 +extern int grsec_enable_chroot_findtask;
18304 +extern int grsec_enable_chroot_mount;
18305 +extern int grsec_enable_chroot_double;
18306 +extern int grsec_enable_chroot_pivot;
18307 +extern int grsec_enable_chroot_chdir;
18308 +extern int grsec_enable_chroot_chmod;
18309 +extern int grsec_enable_chroot_mknod;
18310 +extern int grsec_enable_chroot_fchdir;
18311 +extern int grsec_enable_chroot_nice;
18312 +extern int grsec_enable_chroot_execlog;
18313 +extern int grsec_enable_chroot_caps;
18314 +extern int grsec_enable_chroot_sysctl;
18315 +extern int grsec_enable_chroot_unix;
18316 +extern int grsec_enable_tpe;
18317 +extern int grsec_tpe_gid;
18318 +extern int grsec_enable_tpe_all;
18319 +extern int grsec_enable_sidcaps;
18320 +extern int grsec_enable_randpid;
18321 +extern int grsec_enable_socket_all;
18322 +extern int grsec_socket_all_gid;
18323 +extern int grsec_enable_socket_client;
18324 +extern int grsec_socket_client_gid;
18325 +extern int grsec_enable_socket_server;
18326 +extern int grsec_socket_server_gid;
18327 +extern int grsec_audit_gid;
18328 +extern int grsec_enable_group;
18329 +extern int grsec_enable_audit_ipc;
18330 +extern int grsec_enable_audit_textrel;
18331 +extern int grsec_enable_mount;
18332 +extern int grsec_enable_chdir;
18333 +extern int grsec_lock;
18334 +
18335 +extern struct task_struct *child_reaper;
18336 +
18337 +extern spinlock_t grsec_alert_lock;
18338 +extern unsigned long grsec_alert_wtime;
18339 +extern unsigned long grsec_alert_fyet;
18340 +
18341 +extern spinlock_t grsec_audit_lock;
18342 +
18343 +extern rwlock_t grsec_exec_file_lock;
18344 +
18345 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
18346 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
18347 +                       tsk->exec_file->f_vfsmnt) : "/")
18348 +
18349 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
18350 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
18351 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
18352 +
18353 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
18354 +                       gr_to_filename(tsk->exec_file->f_dentry, \
18355 +                       tsk->exec_file->f_vfsmnt) : "/")
18356 +
18357 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
18358 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
18359 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
18360 +
18361 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && \
18362 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
18363 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
18364 +                         (tsk_a->fs->root->d_inode->i_ino != \
18365 +                         child_reaper->fs->root->d_inode->i_ino)))
18366 +
18367 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_sb->s_dev == \
18368 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
18369 +                         (tsk_a->fs->root->d_inode->i_ino == \
18370 +                         tsk_b->fs->root->d_inode->i_ino))
18371 +
18372 +#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
18373 +                      current->pid, current->uid, \
18374 +                      current->euid, current->gid, current->egid, \
18375 +                      gr_parent_task_fullpath(current), \
18376 +                      current->parent->comm, current->parent->pid, \
18377 +                      current->parent->uid, current->parent->euid, \
18378 +                      current->parent->gid, current->parent->egid
18379 +
18380 +#define GR_CHROOT_CAPS ( \
18381 +       CAP_TO_MASK(CAP_FOWNER) | \
18382 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
18383 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
18384 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
18385 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
18386 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
18387 +       CAP_TO_MASK(CAP_IPC_OWNER))
18388 +
18389 +#define security_alert_good(normal_msg,args...) \
18390 +({ \
18391 +       read_lock(&tasklist_lock); \
18392 +       read_lock(&grsec_exec_file_lock); \
18393 +       spin_lock(&grsec_alert_lock); \
18394 +       \
18395 +       if (!grsec_alert_wtime || get_seconds() - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME) { \
18396 +           grsec_alert_wtime = get_seconds(); grsec_alert_fyet = 0; \
18397 +           if (current->curr_ip && gr_acl_is_enabled()) \
18398 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) " normal_msg "\n", NIPQUAD(current->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename , ## args); \
18399 +           else if (current->curr_ip) \
18400 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
18401 +           else if (gr_acl_is_enabled()) \
18402 +               printk(KERN_ALERT "grsec: (%.64s:%c:%.950s) " normal_msg "\n", current->role->rolename, gr_roletype_to_char(), current->acl->filename , ## args); \
18403 +           else \
18404 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
18405 +       } else if((get_seconds() - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
18406 +           grsec_alert_fyet++; \
18407 +           if (current->curr_ip && gr_acl_is_enabled()) \
18408 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) " normal_msg "\n", NIPQUAD(current->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename , ## args); \
18409 +           else if (current->curr_ip) \
18410 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
18411 +           else if (gr_acl_is_enabled()) \
18412 +               printk(KERN_ALERT "grsec: (%.64s:%c:%.950s) " normal_msg "\n", current->role->rolename, gr_roletype_to_char(), current->acl->filename , ## args); \
18413 +           else \
18414 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
18415 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
18416 +           grsec_alert_wtime = get_seconds(); grsec_alert_fyet++; \
18417 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
18418 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
18419 +       } \
18420 +       \
18421 +       spin_unlock(&grsec_alert_lock); \
18422 +       read_unlock(&grsec_exec_file_lock); \
18423 +       read_unlock(&tasklist_lock); \
18424 +})
18425 +
18426 +#define security_alert(normal_msg,args...) \
18427 +({ \
18428 +       security_alert_good(normal_msg,args); \
18429 +       gr_handle_alertkill(); \
18430 +})
18431 +
18432 +#define security_audit(normal_msg,args...) \
18433 +({ \
18434 +       read_lock(&tasklist_lock); \
18435 +       read_lock(&grsec_exec_file_lock); \
18436 +       spin_lock(&grsec_audit_lock); \
18437 +       if (current->curr_ip && gr_acl_is_enabled()) \
18438 +           printk(KERN_INFO "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) " normal_msg "\n", NIPQUAD(current->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename , ## args); \
18439 +       else if (current->curr_ip) \
18440 +           printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
18441 +       else if (gr_acl_is_enabled()) \
18442 +           printk(KERN_INFO "grsec: (%.64s:%c:%.950s) " normal_msg "\n", current->role->rolename, gr_roletype_to_char(), current->acl->filename , ## args); \
18443 +       else \
18444 +           printk(KERN_INFO "grsec: " normal_msg "\n" , ## args); \
18445 +       spin_unlock(&grsec_audit_lock); \
18446 +       read_unlock(&grsec_exec_file_lock); \
18447 +       read_unlock(&tasklist_lock); \
18448 +})
18449 +
18450 +#define security_learn(normal_msg,args...) \
18451 +({ \
18452 +       preempt_disable(); \
18453 +       gr_add_learn_entry(normal_msg "\n", ## args); \
18454 +       preempt_enable(); \
18455 +})
18456 +
18457 +#endif
18458 +
18459 +#endif
18460 diff -uNr linux-2.6.8/include/linux/grmsg.h linux-2.6.8.grsecurity/include/linux/grmsg.h
18461 --- linux-2.6.8/include/linux/grmsg.h   1970-01-01 01:00:00.000000000 +0100
18462 +++ linux-2.6.8.grsecurity/include/linux/grmsg.h        2004-08-16 17:09:59.000000000 +0200
18463 @@ -0,0 +1,108 @@
18464 +#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d, parent %.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d"
18465 +#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%d/%d gid/egid:%d/%d 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:%d/%d gid/egid:%d/%d"
18466 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
18467 +#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
18468 +#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
18469 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
18470 +#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
18471 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
18472 +#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
18473 +#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
18474 +#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
18475 +#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
18476 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
18477 +#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"
18478 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
18479 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
18480 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
18481 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
18482 +#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
18483 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
18484 +#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
18485 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
18486 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
18487 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
18488 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
18489 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
18490 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
18491 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
18492 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
18493 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
18494 +#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
18495 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
18496 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
18497 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
18498 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution for %lu seconds"
18499 +#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
18500 +#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
18501 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
18502 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
18503 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
18504 +#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
18505 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
18506 +#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
18507 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
18508 +#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
18509 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
18510 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
18511 +#define GR_INITF_ACL_MSG "init_variables() failed %s"
18512 +#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"
18513 +#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
18514 +#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
18515 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
18516 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
18517 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
18518 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
18519 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
18520 +#define GR_ENABLE_ACL_MSG "Loaded %s"
18521 +#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
18522 +#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
18523 +#define GR_RELOAD_ACL_MSG "Reloaded %s"
18524 +#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
18525 +#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
18526 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
18527 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
18528 +#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
18529 +#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
18530 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
18531 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
18532 +#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
18533 +#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
18534 +#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
18535 +#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
18536 +#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
18537 +#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
18538 +#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
18539 +#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
18540 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
18541 +#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
18542 +#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
18543 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
18544 +#define GR_TIME_MSG "time set by " DEFAULTSECMSG
18545 +#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
18546 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
18547 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
18548 +#define GR_SOCK_MSG "attempted socket(%.16s,%.16s,%.16s) by " DEFAULTSECMSG
18549 +#define GR_SOCK2_MSG "attempted socket(%d,%.16s,%.16s) by " DEFAULTSECMSG
18550 +#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
18551 +#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
18552 +#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
18553 +#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
18554 +#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"
18555 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
18556 +#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
18557 +#define GR_USRCHANGE_ACL_MSG "change to uid %d denied for " DEFAULTSECMSG
18558 +#define GR_GRPCHANGE_ACL_MSG "change to gid %d denied for " DEFAULTSECMSG
18559 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
18560 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
18561 +#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
18562 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
18563 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
18564 +#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
18565 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
18566 +#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
18567 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
18568 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
18569 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
18570 +#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
18571 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " DEFAULTSECMSG
18572 diff -uNr linux-2.6.8/include/linux/grsecurity.h linux-2.6.8.grsecurity/include/linux/grsecurity.h
18573 --- linux-2.6.8/include/linux/grsecurity.h      1970-01-01 01:00:00.000000000 +0100
18574 +++ linux-2.6.8.grsecurity/include/linux/grsecurity.h   2004-08-16 17:09:59.000000000 +0200
18575 @@ -0,0 +1,192 @@
18576 +#ifndef GR_SECURITY_H
18577 +#define GR_SECURITY_H
18578 +#include <linux/fs.h>
18579 +#include <linux/binfmts.h>
18580 +#include <linux/gracl.h>
18581 +
18582 +extern void gr_handle_brute_attach(struct task_struct *p);
18583 +extern void gr_handle_brute_check(void);
18584 +
18585 +extern char gr_roletype_to_char(void);
18586 +
18587 +extern int gr_check_user_change(int real, int effective, int fs);
18588 +extern int gr_check_group_change(int real, int effective, int fs);
18589 +
18590 +extern void gr_add_to_task_ip_table(struct task_struct *p);
18591 +extern void gr_del_task_from_ip_table(struct task_struct *p);
18592 +
18593 +extern int gr_pid_is_chrooted(struct task_struct *p);
18594 +extern int gr_handle_chroot_nice(void);
18595 +extern int gr_handle_chroot_sysctl(const int op);
18596 +extern int gr_handle_chroot_capset(struct task_struct *target);
18597 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
18598 +                                       const int niceval);
18599 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
18600 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
18601 +                                  const struct vfsmount *mnt);
18602 +extern void gr_handle_chroot_caps(struct task_struct *task);
18603 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
18604 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
18605 +                                 const struct vfsmount *mnt, const int mode);
18606 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
18607 +                                 const struct vfsmount *mnt, const int mode);
18608 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
18609 +                                 const struct vfsmount *mnt,
18610 +                                 const char *dev_name);
18611 +extern int gr_handle_chroot_pivot(void);
18612 +extern int gr_handle_chroot_unix(const pid_t pid);
18613 +
18614 +extern int gr_handle_rawio(const struct inode *inode);
18615 +extern int gr_handle_nproc(void);
18616 +
18617 +extern void gr_handle_ioperm(void);
18618 +extern void gr_handle_iopl(void);
18619 +
18620 +extern int gr_tpe_allow(const struct file *file);
18621 +
18622 +extern int gr_random_pid(void);
18623 +
18624 +extern void gr_log_forkfail(const int retval);
18625 +extern void gr_log_timechange(void);
18626 +extern void gr_log_signal(const int sig, const struct task_struct *t);
18627 +extern void gr_log_chdir(const struct dentry *dentry,
18628 +                        const struct vfsmount *mnt);
18629 +extern void gr_log_chroot_exec(const struct dentry *dentry,
18630 +                              const struct vfsmount *mnt);
18631 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
18632 +extern void gr_log_remount(const char *devname, const int retval);
18633 +extern void gr_log_unmount(const char *devname, const int retval);
18634 +extern void gr_log_mount(const char *from, const char *to, const int retval);
18635 +extern void gr_log_msgget(const int ret, const int msgflg);
18636 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
18637 +extern void gr_log_semget(const int err, const int semflg);
18638 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
18639 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
18640 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
18641 +extern void gr_log_textrel(struct vm_area_struct *vma);
18642 +
18643 +extern int gr_handle_follow_link(const struct inode *parent,
18644 +                                const struct inode *inode,
18645 +                                const struct dentry *dentry,
18646 +                                const struct vfsmount *mnt);
18647 +extern int gr_handle_fifo(const struct dentry *dentry,
18648 +                         const struct vfsmount *mnt,
18649 +                         const struct dentry *dir, const int flag,
18650 +                         const int acc_mode);
18651 +extern int gr_handle_hardlink(const struct dentry *dentry,
18652 +                             const struct vfsmount *mnt,
18653 +                             struct inode *inode,
18654 +                             const int mode, const char *to);
18655 +
18656 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
18657 +extern int gr_is_capable_nolog(const int cap);
18658 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
18659 +                             const unsigned long wanted, const int gt);
18660 +extern void gr_copy_label(struct task_struct *tsk);
18661 +extern void gr_handle_crash(struct task_struct *task, const int sig);
18662 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
18663 +extern int gr_check_crash_uid(const uid_t uid);
18664 +extern int gr_check_protected_task(const struct task_struct *task);
18665 +extern int gr_acl_handle_mmap(const struct file *file,
18666 +                             const unsigned long prot);
18667 +extern int gr_acl_handle_mprotect(const struct file *file,
18668 +                                 const unsigned long prot);
18669 +extern int gr_check_hidden_task(const struct task_struct *tsk);
18670 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
18671 +                                   const struct vfsmount *mnt);
18672 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
18673 +                                const struct vfsmount *mnt);
18674 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
18675 +                                 const struct vfsmount *mnt, const int fmode);
18676 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
18677 +                                 const struct vfsmount *mnt, mode_t mode);
18678 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
18679 +                                const struct vfsmount *mnt, mode_t mode);
18680 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
18681 +                                const struct vfsmount *mnt);
18682 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
18683 +extern int gr_handle_proc_ptrace(struct task_struct *task);
18684 +extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
18685 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
18686 +                                 const struct vfsmount *mnt);
18687 +extern int gr_check_crash_exec(const struct file *filp);
18688 +extern int gr_acl_is_enabled(void);
18689 +extern void gr_set_kernel_label(struct task_struct *task);
18690 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
18691 +                             const gid_t gid);
18692 +extern int gr_set_proc_label(const struct dentry *dentry,
18693 +                             const struct vfsmount *mnt);
18694 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
18695 +                                      const struct vfsmount *mnt);
18696 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
18697 +                               const struct vfsmount *mnt, const int fmode);
18698 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
18699 +                                const struct dentry *p_dentry,
18700 +                                const struct vfsmount *p_mnt, const int fmode,
18701 +                                const int imode);
18702 +extern void gr_handle_create(const struct dentry *dentry,
18703 +                            const struct vfsmount *mnt);
18704 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
18705 +                                const struct dentry *parent_dentry,
18706 +                                const struct vfsmount *parent_mnt,
18707 +                                const int mode);
18708 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
18709 +                                const struct dentry *parent_dentry,
18710 +                                const struct vfsmount *parent_mnt);
18711 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
18712 +                                const struct vfsmount *mnt);
18713 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
18714 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
18715 +                                 const struct vfsmount *mnt);
18716 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
18717 +                                  const struct dentry *parent_dentry,
18718 +                                  const struct vfsmount *parent_mnt,
18719 +                                  const char *from);
18720 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
18721 +                               const struct dentry *parent_dentry,
18722 +                               const struct vfsmount *parent_mnt,
18723 +                               const struct dentry *old_dentry,
18724 +                               const struct vfsmount *old_mnt, const char *to);
18725 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
18726 +                               struct dentry *parent_dentry,
18727 +                               const struct vfsmount *parent_mnt,
18728 +                               struct dentry *old_dentry,
18729 +                               struct inode *old_parent_inode,
18730 +                               struct vfsmount *old_mnt, const char *newname);
18731 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
18732 +                               struct dentry *old_dentry,
18733 +                               struct dentry *new_dentry,
18734 +                               struct vfsmount *mnt, const __u8 replace);
18735 +extern __u32 gr_check_link(const struct dentry *new_dentry,
18736 +                          const struct dentry *parent_dentry,
18737 +                          const struct vfsmount *parent_mnt,
18738 +                          const struct dentry *old_dentry,
18739 +                          const struct vfsmount *old_mnt);
18740 +extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
18741 +                                  const struct vfsmount *mnt, const ino_t ino);
18742 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
18743 +                               const struct vfsmount *mnt);
18744 +extern void gr_acl_handle_exit(void);
18745 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
18746 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
18747 +extern __u32 gr_cap_rtnetlink(void);
18748 +
18749 +#ifdef CONFIG_GRKERNSEC
18750 +extern void gr_handle_mem_write(void);
18751 +extern void gr_handle_kmem_write(void);
18752 +extern void gr_handle_open_port(void);
18753 +extern int gr_handle_mem_mmap(const unsigned long offset,
18754 +                             struct vm_area_struct *vma);
18755 +
18756 +extern __u16 ip_randomid(void);
18757 +extern __u32 ip_randomisn(void);
18758 +extern unsigned long get_random_long(void);
18759 +
18760 +extern int grsec_enable_dmesg;
18761 +extern int grsec_enable_randid;
18762 +extern int grsec_enable_randisn;
18763 +extern int grsec_enable_randsrc;
18764 +extern int grsec_enable_randrpc;
18765 +#endif
18766 +
18767 +#endif
18768 diff -uNr linux-2.6.8/include/linux/mman.h linux-2.6.8.grsecurity/include/linux/mman.h
18769 --- linux-2.6.8/include/linux/mman.h    2004-08-14 07:36:16.000000000 +0200
18770 +++ linux-2.6.8.grsecurity/include/linux/mman.h 2004-08-16 17:09:59.000000000 +0200
18771 @@ -56,6 +56,11 @@
18772  calc_vm_flag_bits(unsigned long flags)
18773  {
18774         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
18775 +
18776 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18777 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
18778 +#endif
18779 +
18780                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
18781                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
18782                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
18783 diff -uNr linux-2.6.8/include/linux/mm.h linux-2.6.8.grsecurity/include/linux/mm.h
18784 --- linux-2.6.8/include/linux/mm.h      2004-08-14 07:36:13.000000000 +0200
18785 +++ linux-2.6.8.grsecurity/include/linux/mm.h   2004-08-16 17:09:59.000000000 +0200
18786 @@ -30,6 +30,7 @@
18787  #include <asm/pgtable.h>
18788  #include <asm/processor.h>
18789  #include <asm/atomic.h>
18790 +#include <asm/mman.h>
18791  
18792  #ifndef MM_VM_SIZE
18793  #define MM_VM_SIZE(mm) TASK_SIZE
18794 @@ -101,6 +102,11 @@
18795  #ifdef CONFIG_NUMA
18796         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
18797  #endif
18798 +
18799 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18800 +       unsigned long vm_mirror;        /* PaX: mirror distance */
18801 +#endif
18802 +
18803  };
18804  
18805  /*
18806 @@ -136,6 +142,18 @@
18807  #define VM_HUGETLB     0x00400000      /* Huge TLB Page VM */
18808  #define VM_NONLINEAR   0x00800000      /* Is non-linear (remap_file_pages) */
18809  
18810 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18811 +#define VM_MIRROR      0x01000000      /* vma is mirroring another */
18812 +#endif
18813 +
18814 +#ifdef CONFIG_PAX_MPROTECT
18815 +#define VM_MAYNOTWRITE 0x02000000      /* vma cannot be granted VM_WRITE any more */
18816 +#endif
18817 +
18818 +#ifdef __VM_STACK_FLAGS
18819 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
18820 +#endif
18821 +
18822  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
18823  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
18824  #endif
18825 @@ -637,6 +655,10 @@
18826         unsigned long len, unsigned long prot,
18827         unsigned long flag, unsigned long pgoff);
18828  
18829 +extern unsigned long __do_mmap_pgoff(struct file *file, unsigned long addr,
18830 +       unsigned long len, unsigned long prot,
18831 +       unsigned long flag, unsigned long pgoff);
18832 +
18833  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
18834         unsigned long len, unsigned long prot,
18835         unsigned long flag, unsigned long offset)
18836 @@ -724,5 +746,11 @@
18837  int in_gate_area(struct task_struct *task, unsigned long addr);
18838  #endif
18839  
18840 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
18841 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
18842 +#else
18843 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
18844 +#endif
18845 +
18846  #endif /* __KERNEL__ */
18847  #endif /* _LINUX_MM_H */
18848 diff -uNr linux-2.6.8/include/linux/proc_fs.h linux-2.6.8.grsecurity/include/linux/proc_fs.h
18849 --- linux-2.6.8/include/linux/proc_fs.h 2004-08-14 07:38:11.000000000 +0200
18850 +++ linux-2.6.8.grsecurity/include/linux/proc_fs.h      2004-08-16 17:09:59.000000000 +0200
18851 @@ -221,7 +221,7 @@
18852  
18853  #endif /* CONFIG_PROC_FS */
18854  
18855 -#if !defined(CONFIG_PROC_FS)
18856 +#if !defined(CONFIG_PROC_FS) || !defined(CONFIG_PROC_KCORE)
18857  static inline void kclist_add(struct kcore_list *new, void *addr, size_t size)
18858  {
18859  }
18860 diff -uNr linux-2.6.8/include/linux/random.h linux-2.6.8.grsecurity/include/linux/random.h
18861 --- linux-2.6.8/include/linux/random.h  2004-08-14 07:38:09.000000000 +0200
18862 +++ linux-2.6.8.grsecurity/include/linux/random.h       2004-08-16 17:09:59.000000000 +0200
18863 @@ -69,6 +69,8 @@
18864  
18865  extern __u32 secure_ipv6_id(__u32 *daddr);
18866  
18867 +extern unsigned long pax_get_random_long(void);
18868 +
18869  #ifndef MODULE
18870  extern struct file_operations random_fops, urandom_fops;
18871  #endif
18872 diff -uNr linux-2.6.8/include/linux/sched.h linux-2.6.8.grsecurity/include/linux/sched.h
18873 --- linux-2.6.8/include/linux/sched.h   2004-08-14 07:36:16.000000000 +0200
18874 +++ linux-2.6.8.grsecurity/include/linux/sched.h        2004-08-16 17:09:59.000000000 +0200
18875 @@ -31,6 +31,7 @@
18876  #include <linux/percpu.h>
18877  
18878  struct exec_domain;
18879 +struct linux_binprm;
18880  
18881  /*
18882   * cloning flags:
18883 @@ -229,6 +230,21 @@
18884         struct kioctx           *ioctx_list;
18885  
18886         struct kioctx           default_kioctx;
18887 +
18888 +#ifdef CONFIG_PAX_DLRESOLVE
18889 +       unsigned long call_dl_resolve;
18890 +#endif
18891 +
18892 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
18893 +       unsigned long call_syscall;
18894 +#endif
18895 +
18896 +#ifdef CONFIG_PAX_ASLR
18897 +       unsigned long delta_mmap;               /* randomized offset */
18898 +       unsigned long delta_exec;               /* randomized offset */
18899 +       unsigned long delta_stack;              /* randomized offset */
18900 +#endif
18901 +
18902  };
18903  
18904  extern int mmlist_nr;
18905 @@ -527,6 +543,23 @@
18906         struct mempolicy *mempolicy;
18907         short il_next;          /* could be shared with used_math */
18908  #endif
18909 +
18910 +#ifdef CONFIG_GRKERNSEC
18911 +       /* grsecurity */
18912 +       struct acl_subject_label *acl;
18913 +       struct acl_role_label *role;
18914 +       struct file *exec_file;
18915 +       u32 curr_ip;
18916 +       u32 gr_saddr;
18917 +       u32 gr_daddr;
18918 +       u16 gr_sport;
18919 +       u16 gr_dport;
18920 +       u16 acl_role_id;
18921 +       u8 acl_sp_role:1;
18922 +       u8 used_accept:1;
18923 +       u8 is_writable:1;
18924 +       u8 brute:1;
18925 +#endif
18926  };
18927  
18928  static inline pid_t process_group(struct task_struct *tsk)
18929 @@ -564,6 +597,29 @@
18930  #define PF_LESS_THROTTLE 0x00100000    /* Throttle me less: I clean memory */
18931  #define PF_SYNCWRITE   0x00200000      /* I am doing a sync write */
18932  
18933 +#define PF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
18934 +#define PF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
18935 +#define PF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
18936 +#define PF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
18937 +#define PF_PAX_RANDEXEC                0x10000000      /* Randomize ET_EXEC base */
18938 +#define PF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
18939 +
18940 +#ifdef CONFIG_PAX_SOFTMODE
18941 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
18942 +extern unsigned int pax_aslr;
18943 +#endif
18944 +
18945 +extern unsigned int pax_softmode;
18946 +#endif
18947 +
18948 +extern int pax_check_flags(unsigned long *);
18949 +
18950 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
18951 +extern void pax_set_flags(struct linux_binprm * bprm);
18952 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
18953 +extern void (*pax_set_flags_func)(struct linux_binprm * bprm);
18954 +#endif
18955 +
18956  #ifdef CONFIG_SMP
18957  #define SCHED_LOAD_SCALE       128UL   /* increase resolution of load */
18958  
18959 @@ -828,14 +884,29 @@
18960                 : on_sig_stack(sp) ? SS_ONSTACK : 0);
18961  }
18962  
18963 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
18964 +extern int gr_is_capable_nolog(const int cap);
18965  
18966  #ifdef CONFIG_SECURITY
18967  /* code is in security.c */
18968  extern int capable(int cap);
18969 +static inline int capable_nolog(int cap)
18970 +{
18971 +       return capable(cap);
18972 +}
18973  #else
18974  static inline int capable(int cap)
18975  {
18976 -       if (cap_raised(current->cap_effective, cap)) {
18977 +       if (cap_raised(current->cap_effective, cap) && gr_task_is_capable(current, cap)) {
18978 +               current->flags |= PF_SUPERPRIV;
18979 +               return 1;
18980 +       }
18981 +       return 0;
18982 +}
18983 +
18984 +static inline int capable_nolog(int cap)
18985 +{
18986 +       if (cap_raised(current->cap_effective, cap) && gr_is_capable_nolog(cap)) {
18987                 current->flags |= PF_SUPERPRIV;
18988                 return 1;
18989         }
18990 diff -uNr linux-2.6.8/include/linux/shm.h linux-2.6.8.grsecurity/include/linux/shm.h
18991 --- linux-2.6.8/include/linux/shm.h     2004-08-14 07:37:37.000000000 +0200
18992 +++ linux-2.6.8.grsecurity/include/linux/shm.h  2004-08-16 17:09:59.000000000 +0200
18993 @@ -84,6 +84,10 @@
18994         time_t                  shm_ctim;
18995         pid_t                   shm_cprid;
18996         pid_t                   shm_lprid;
18997 +#ifdef CONFIG_GRKERNSEC
18998 +       time_t                  shm_createtime;
18999 +       pid_t                   shm_lapid;
19000 +#endif
19001  };
19002  
19003  /* shm_mode upper byte flags */
19004 diff -uNr linux-2.6.8/include/linux/sysctl.h linux-2.6.8.grsecurity/include/linux/sysctl.h
19005 --- linux-2.6.8/include/linux/sysctl.h  2004-08-14 07:37:14.000000000 +0200
19006 +++ linux-2.6.8.grsecurity/include/linux/sysctl.h       2004-08-16 17:09:59.000000000 +0200
19007 @@ -133,7 +133,20 @@
19008         KERN_NGROUPS_MAX=63,    /* int: NGROUPS_MAX */
19009         KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
19010         KERN_HZ_TIMER=65,       /* int: hz timer on or off */
19011 +       KERN_GRSECURITY=68,     /* grsecurity */
19012 +
19013 +#ifdef CONFIG_PAX_SOFTMODE
19014 +       KERN_PAX=69,            /* PaX control */
19015 +#endif
19016 +
19017 +};
19018 +
19019 +#ifdef CONFIG_PAX_SOFTMODE
19020 +enum {
19021 +       PAX_ASLR=1,             /* PaX: disable/enable all randomization features */
19022 +       PAX_SOFTMODE=2          /* PaX: disable/enable soft mode */
19023  };
19024 +#endif
19025  
19026  
19027  /* CTL_VM names: */
19028 diff -uNr linux-2.6.8/include/net/ip.h linux-2.6.8.grsecurity/include/net/ip.h
19029 --- linux-2.6.8/include/net/ip.h        2004-08-14 07:37:26.000000000 +0200
19030 +++ linux-2.6.8.grsecurity/include/net/ip.h     2004-08-16 18:21:29.000000000 +0200
19031 @@ -34,6 +34,11 @@
19032  #include <net/arp.h>
19033  #include <net/snmp.h>
19034  
19035 +#ifdef CONFIG_GRKERNSEC_RANDID
19036 +extern int grsec_enable_randid;
19037 +extern __u16 ip_randomid(void);
19038 +#endif
19039 +
19040  struct sock;
19041  
19042  struct inet_skb_parm
19043 @@ -188,6 +193,13 @@
19044  
19045  static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
19046  {
19047 +
19048 +#ifdef CONFIG_GRKERNSEC_RANDID
19049 +       if (grsec_enable_randid)
19050 +               iph->id = htons(ip_randomid());
19051 +       else
19052 +#endif
19053 +
19054         if (iph->frag_off & htons(IP_DF)) {
19055                 /* This is only to work around buggy Windows95/2000
19056                  * VJ compression implementations.  If the ID field
19057 diff -uNr linux-2.6.8/init/do_mounts.c linux-2.6.8.grsecurity/init/do_mounts.c
19058 --- linux-2.6.8/init/do_mounts.c        2004-08-14 07:36:56.000000000 +0200
19059 +++ linux-2.6.8.grsecurity/init/do_mounts.c     2004-08-16 17:09:59.000000000 +0200
19060 @@ -291,6 +291,7 @@
19061                         case -EINVAL:
19062                                 continue;
19063                 }
19064 +
19065                 /*
19066                  * Allow the user to distinguish between failed sys_open
19067                  * and bad superblock on root device.
19068 diff -uNr linux-2.6.8/init/Kconfig linux-2.6.8.grsecurity/init/Kconfig
19069 --- linux-2.6.8/init/Kconfig    2004-08-14 07:37:38.000000000 +0200
19070 +++ linux-2.6.8.grsecurity/init/Kconfig 2004-08-16 17:09:59.000000000 +0200
19071 @@ -228,6 +228,7 @@
19072  config KALLSYMS
19073          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
19074          default y
19075 +        depends on !GRKERNSEC_HIDESYM
19076          help
19077            Say Y here to let the kernel print out symbolic crash information and
19078            symbolic stack backtraces. This increases the size of the kernel
19079 diff -uNr linux-2.6.8/init/main.c linux-2.6.8.grsecurity/init/main.c
19080 --- linux-2.6.8/init/main.c     2004-08-14 07:36:17.000000000 +0200
19081 +++ linux-2.6.8.grsecurity/init/main.c  2004-08-16 17:09:59.000000000 +0200
19082 @@ -93,6 +93,7 @@
19083  extern void populate_rootfs(void);
19084  extern void driver_init(void);
19085  extern void prepare_namespace(void);
19086 +extern void grsecurity_init(void);
19087  #ifdef CONFIG_ACPI
19088  extern void acpi_early_init(void);
19089  #else
19090 @@ -691,6 +692,7 @@
19091                 execute_command = "/init";
19092         else
19093                 prepare_namespace();
19094 +       grsecurity_init();
19095  
19096         /*
19097          * Ok, we have completed the initial bootup, and
19098 diff -uNr linux-2.6.8/ipc/msg.c linux-2.6.8.grsecurity/ipc/msg.c
19099 --- linux-2.6.8/ipc/msg.c       2004-08-14 07:36:11.000000000 +0200
19100 +++ linux-2.6.8.grsecurity/ipc/msg.c    2004-08-16 17:09:59.000000000 +0200
19101 @@ -24,6 +24,7 @@
19102  #include <linux/list.h>
19103  #include <linux/security.h>
19104  #include <linux/sched.h>
19105 +#include <linux/grsecurity.h>
19106  #include <asm/current.h>
19107  #include <asm/uaccess.h>
19108  #include "util.h"
19109 @@ -226,6 +227,9 @@
19110                 msg_unlock(msq);
19111         }
19112         up(&msg_ids.sem);
19113 +
19114 +       gr_log_msgget(ret, msgflg);
19115 +
19116         return ret;
19117  }
19118  
19119 @@ -475,6 +479,8 @@
19120                 break;
19121         }
19122         case IPC_RMID:
19123 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
19124 +
19125                 freeque (msq, msqid); 
19126                 break;
19127         }
19128 diff -uNr linux-2.6.8/ipc/sem.c linux-2.6.8.grsecurity/ipc/sem.c
19129 --- linux-2.6.8/ipc/sem.c       2004-08-14 07:36:56.000000000 +0200
19130 +++ linux-2.6.8.grsecurity/ipc/sem.c    2004-08-16 17:09:59.000000000 +0200
19131 @@ -71,6 +71,7 @@
19132  #include <linux/time.h>
19133  #include <linux/smp_lock.h>
19134  #include <linux/security.h>
19135 +#include <linux/grsecurity.h>
19136  #include <asm/uaccess.h>
19137  #include "util.h"
19138  
19139 @@ -238,6 +239,9 @@
19140         }
19141  
19142         up(&sem_ids.sem);
19143 +
19144 +       gr_log_semget(err, semflg);
19145 +
19146         return err;
19147  }
19148  
19149 @@ -804,6 +808,8 @@
19150  
19151         switch(cmd){
19152         case IPC_RMID:
19153 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
19154 +
19155                 freeary(sma, semid);
19156                 err = 0;
19157                 break;
19158 diff -uNr linux-2.6.8/ipc/shm.c linux-2.6.8.grsecurity/ipc/shm.c
19159 --- linux-2.6.8/ipc/shm.c       2004-08-14 07:36:58.000000000 +0200
19160 +++ linux-2.6.8.grsecurity/ipc/shm.c    2004-08-16 17:09:59.000000000 +0200
19161 @@ -26,6 +26,7 @@
19162  #include <linux/proc_fs.h>
19163  #include <linux/shmem_fs.h>
19164  #include <linux/security.h>
19165 +#include <linux/grsecurity.h>
19166  #include <asm/uaccess.h>
19167  
19168  #include "util.h"
19169 @@ -50,6 +51,14 @@
19170  static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
19171  #endif
19172  
19173 +#ifdef CONFIG_GRKERNSEC
19174 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
19175 +                          const time_t shm_createtime, const uid_t cuid,
19176 +                          const int shmid);
19177 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
19178 +                          const time_t shm_createtime);
19179 +#endif
19180 +
19181  size_t shm_ctlmax = SHMMAX;
19182  size_t         shm_ctlall = SHMALL;
19183  int    shm_ctlmni = SHMMNI;
19184 @@ -217,6 +226,9 @@
19185         shp->shm_lprid = 0;
19186         shp->shm_atim = shp->shm_dtim = 0;
19187         shp->shm_ctim = get_seconds();
19188 +#ifdef CONFIG_GRKERNSEC
19189 +       shp->shm_createtime = get_seconds();
19190 +#endif
19191         shp->shm_segsz = size;
19192         shp->shm_nattch = 0;
19193         shp->id = shm_buildid(id,shp->shm_perm.seq);
19194 @@ -271,6 +283,8 @@
19195         }
19196         up(&shm_ids.sem);
19197  
19198 +       gr_log_shmget(err, shmflg, size);
19199 +
19200         return err;
19201  }
19202  
19203 @@ -569,6 +583,8 @@
19204                 if (err)
19205                         goto out_unlock_up;
19206  
19207 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
19208 +
19209                 if (shp->shm_nattch){
19210                         shp->shm_flags |= SHM_DEST;
19211                         /* Do not find it any more */
19212 @@ -707,9 +723,27 @@
19213                 return err;
19214         }
19215                 
19216 +#ifdef CONFIG_GRKERNSEC
19217 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
19218 +                            shp->shm_perm.cuid, shmid)) {
19219 +               shm_unlock(shp);
19220 +               return -EACCES;
19221 +       }
19222 +
19223 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
19224 +               shm_unlock(shp);
19225 +               return -EACCES;
19226 +       }
19227 +#endif
19228 +
19229         file = shp->shm_file;
19230         size = i_size_read(file->f_dentry->d_inode);
19231         shp->shm_nattch++;
19232 +
19233 +#ifdef CONFIG_GRKERNSEC
19234 +       shp->shm_lapid = current->pid;
19235 +#endif
19236 +
19237         shm_unlock(shp);
19238  
19239         down_write(&current->mm->mmap_sem);
19240 diff -uNr linux-2.6.8/kernel/capability.c linux-2.6.8.grsecurity/kernel/capability.c
19241 --- linux-2.6.8/kernel/capability.c     2004-08-14 07:37:25.000000000 +0200
19242 +++ linux-2.6.8.grsecurity/kernel/capability.c  2004-08-16 17:09:59.000000000 +0200
19243 @@ -10,6 +10,7 @@
19244  #include <linux/mm.h>
19245  #include <linux/module.h>
19246  #include <linux/security.h>
19247 +#include <linux/grsecurity.h>
19248  #include <asm/uaccess.h>
19249  
19250  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
19251 @@ -168,6 +169,11 @@
19252       } else
19253                 target = current;
19254  
19255 +     if (gr_handle_chroot_capset(target)) {
19256 +               ret = -ESRCH;
19257 +               goto out;
19258 +     }
19259 +
19260       ret = -EPERM;
19261  
19262       if (security_capset_check(target, &effective, &inheritable, &permitted))
19263 diff -uNr linux-2.6.8/kernel/configs.c linux-2.6.8.grsecurity/kernel/configs.c
19264 --- linux-2.6.8/kernel/configs.c        2004-08-14 07:36:45.000000000 +0200
19265 +++ linux-2.6.8.grsecurity/kernel/configs.c     2004-08-16 17:09:59.000000000 +0200
19266 @@ -89,8 +89,16 @@
19267         struct proc_dir_entry *entry;
19268  
19269         /* create the current config file */
19270 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
19271 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19272 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
19273 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
19274 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
19275 +#endif
19276 +#else
19277         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
19278                                   &proc_root);
19279 +#endif
19280         if (!entry)
19281                 return -ENOMEM;
19282  
19283 diff -uNr linux-2.6.8/kernel/exit.c linux-2.6.8.grsecurity/kernel/exit.c
19284 --- linux-2.6.8/kernel/exit.c   2004-08-14 07:37:40.000000000 +0200
19285 +++ linux-2.6.8.grsecurity/kernel/exit.c        2004-08-16 17:09:59.000000000 +0200
19286 @@ -23,6 +23,11 @@
19287  #include <linux/mount.h>
19288  #include <linux/proc_fs.h>
19289  #include <linux/mempolicy.h>
19290 +#include <linux/grsecurity.h>
19291 +
19292 +#ifdef CONFIG_GRKERNSEC
19293 +extern rwlock_t grsec_exec_file_lock;
19294 +#endif
19295  
19296  #include <asm/uaccess.h>
19297  #include <asm/unistd.h>
19298 @@ -233,6 +238,15 @@
19299  {
19300         write_lock_irq(&tasklist_lock);
19301  
19302 +#ifdef CONFIG_GRKERNSEC
19303 +       write_lock(&grsec_exec_file_lock);
19304 +       if (current->exec_file) {
19305 +               fput(current->exec_file);
19306 +               current->exec_file = NULL;
19307 +       }
19308 +       write_unlock(&grsec_exec_file_lock);
19309 +#endif
19310 +
19311         ptrace_unlink(current);
19312         /* Reparent to init */
19313         REMOVE_LINKS(current);
19314 @@ -240,6 +254,8 @@
19315         current->real_parent = child_reaper;
19316         SET_LINKS(current);
19317  
19318 +       gr_set_kernel_label(current);
19319 +
19320         /* Set the exit signal to SIGCHLD so we signal init on exit */
19321         current->exit_signal = SIGCHLD;
19322  
19323 @@ -334,6 +350,17 @@
19324         vsnprintf(current->comm, sizeof(current->comm), name, args);
19325         va_end(args);
19326  
19327 +#ifdef CONFIG_GRKERNSEC
19328 +       write_lock(&grsec_exec_file_lock);
19329 +       if (current->exec_file) {
19330 +               fput(current->exec_file);
19331 +               current->exec_file = NULL;
19332 +       }
19333 +       write_unlock(&grsec_exec_file_lock);
19334 +#endif
19335 +
19336 +       gr_set_kernel_label(current);
19337 +
19338         /*
19339          * If we were started as result of loading a module, close all of the
19340          * user space pages.  We don't need them, and if we didn't close them
19341 @@ -821,6 +848,11 @@
19342         }
19343  
19344         acct_process(code);
19345 +
19346 +       gr_acl_handle_psacct(tsk, code);
19347 +       gr_acl_handle_exit();
19348 +       gr_del_task_from_ip_table(tsk);
19349 +
19350         __exit_mm(tsk);
19351  
19352         exit_sem(tsk);
19353 diff -uNr linux-2.6.8/kernel/fork.c linux-2.6.8.grsecurity/kernel/fork.c
19354 --- linux-2.6.8/kernel/fork.c   2004-08-14 07:36:16.000000000 +0200
19355 +++ linux-2.6.8.grsecurity/kernel/fork.c        2004-08-16 17:09:59.000000000 +0200
19356 @@ -36,6 +36,7 @@
19357  #include <linux/mount.h>
19358  #include <linux/audit.h>
19359  #include <linux/rmap.h>
19360 +#include <linux/grsecurity.h>
19361  
19362  #include <asm/pgtable.h>
19363  #include <asm/pgalloc.h>
19364 @@ -279,7 +280,7 @@
19365         mm->locked_vm = 0;
19366         mm->mmap = NULL;
19367         mm->mmap_cache = NULL;
19368 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
19369 +       mm->free_area_cache = oldmm->free_area_cache;
19370         mm->map_count = 0;
19371         mm->rss = 0;
19372         cpus_clear(mm->cpu_vm_mask);
19373 @@ -902,6 +903,9 @@
19374                 goto fork_out;
19375  
19376         retval = -EAGAIN;
19377 +
19378 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
19379 +
19380         if (atomic_read(&p->user->processes) >=
19381                         p->rlim[RLIMIT_NPROC].rlim_cur) {
19382                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
19383 @@ -997,6 +1001,8 @@
19384         if (retval)
19385                 goto bad_fork_cleanup_namespace;
19386  
19387 +       gr_copy_label(p);
19388 +
19389         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
19390         /*
19391          * Clear TID on mm_release()?
19392 @@ -1138,6 +1144,9 @@
19393         free_uid(p->user);
19394  bad_fork_free:
19395         free_task(p);
19396 +
19397 +       gr_log_forkfail(retval);
19398 +
19399         goto fork_out;
19400  }
19401  
19402 @@ -1174,6 +1183,8 @@
19403         int trace = 0;
19404         long pid;
19405  
19406 +       gr_handle_brute_check();
19407 +
19408         if (unlikely(current->ptrace)) {
19409                 trace = fork_traceflag (clone_flags);
19410                 if (trace)
19411 diff -uNr linux-2.6.8/kernel/kallsyms.c linux-2.6.8.grsecurity/kernel/kallsyms.c
19412 --- linux-2.6.8/kernel/kallsyms.c       2004-08-14 07:38:08.000000000 +0200
19413 +++ linux-2.6.8.grsecurity/kernel/kallsyms.c    2004-08-16 17:09:59.000000000 +0200
19414 @@ -302,7 +302,15 @@
19415  {
19416         struct proc_dir_entry *entry;
19417  
19418 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
19419 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19420 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
19421 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
19422 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
19423 +#endif
19424 +#else
19425         entry = create_proc_entry("kallsyms", 0444, NULL);
19426 +#endif
19427         if (entry)
19428                 entry->proc_fops = &kallsyms_operations;
19429         return 0;
19430 diff -uNr linux-2.6.8/kernel/pid.c linux-2.6.8.grsecurity/kernel/pid.c
19431 --- linux-2.6.8/kernel/pid.c    2004-08-14 07:37:14.000000000 +0200
19432 +++ linux-2.6.8.grsecurity/kernel/pid.c 2004-08-16 17:09:59.000000000 +0200
19433 @@ -25,6 +25,7 @@
19434  #include <linux/init.h>
19435  #include <linux/bootmem.h>
19436  #include <linux/hash.h>
19437 +#include <linux/grsecurity.h>
19438  
19439  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
19440  static struct list_head *pid_hash[PIDTYPE_MAX];
19441 @@ -99,10 +100,12 @@
19442  
19443  int alloc_pidmap(void)
19444  {
19445 -       int pid, offset, max_steps = PIDMAP_ENTRIES + 1;
19446 +       int pid = 0, offset, max_steps = PIDMAP_ENTRIES + 1;
19447         pidmap_t *map;
19448  
19449 -       pid = last_pid + 1;
19450 +       pid = gr_random_pid();
19451 +       if (!pid)
19452 +               pid = last_pid + 1;
19453         if (pid >= pid_max)
19454                 pid = RESERVED_PIDS;
19455  
19456 @@ -225,10 +228,16 @@
19457  task_t *find_task_by_pid(int nr)
19458  {
19459         struct pid *pid = find_pid(PIDTYPE_PID, nr);
19460 +       struct task_struct *task = NULL;
19461  
19462         if (!pid)
19463                 return NULL;
19464 -       return pid_task(pid->task_list.next, PIDTYPE_PID);
19465 +       task = pid_task(pid->task_list.next, PIDTYPE_PID);
19466 +
19467 +       if (gr_pid_is_chrooted(task))
19468 +               return NULL;
19469 +
19470 +       return task;
19471  }
19472  
19473  EXPORT_SYMBOL(find_task_by_pid);
19474 diff -uNr linux-2.6.8/kernel/printk.c linux-2.6.8.grsecurity/kernel/printk.c
19475 --- linux-2.6.8/kernel/printk.c 2004-08-14 07:38:10.000000000 +0200
19476 +++ linux-2.6.8.grsecurity/kernel/printk.c      2004-08-16 17:09:59.000000000 +0200
19477 @@ -30,6 +30,7 @@
19478  #include <linux/smp.h>
19479  #include <linux/security.h>
19480  #include <linux/bootmem.h>
19481 +#include <linux/grsecurity.h>
19482  
19483  #include <asm/uaccess.h>
19484  
19485 @@ -249,6 +250,11 @@
19486         char c;
19487         int error = 0;
19488  
19489 +#ifdef CONFIG_GRKERNSEC_DMESG
19490 +       if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
19491 +               return -EPERM;
19492 +#endif
19493 +
19494         error = security_syslog(type);
19495         if (error)
19496                 return error;
19497 diff -uNr linux-2.6.8/kernel/resource.c linux-2.6.8.grsecurity/kernel/resource.c
19498 --- linux-2.6.8/kernel/resource.c       2004-08-14 07:37:25.000000000 +0200
19499 +++ linux-2.6.8.grsecurity/kernel/resource.c    2004-08-16 17:09:59.000000000 +0200
19500 @@ -134,10 +134,27 @@
19501  {
19502         struct proc_dir_entry *entry;
19503  
19504 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
19505 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19506 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
19507 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
19508 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
19509 +#endif
19510 +#else
19511         entry = create_proc_entry("ioports", 0, NULL);
19512 +#endif
19513         if (entry)
19514                 entry->proc_fops = &proc_ioports_operations;
19515 +
19516 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
19517 +#ifdef CONFIG_GRKERNSEC_PROC_USER
19518 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
19519 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
19520 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
19521 +#endif
19522 +#else
19523         entry = create_proc_entry("iomem", 0, NULL);
19524 +#endif
19525         if (entry)
19526                 entry->proc_fops = &proc_iomem_operations;
19527         return 0;
19528 diff -uNr linux-2.6.8/kernel/sched.c linux-2.6.8.grsecurity/kernel/sched.c
19529 --- linux-2.6.8/kernel/sched.c  2004-08-14 07:37:38.000000000 +0200
19530 +++ linux-2.6.8.grsecurity/kernel/sched.c       2004-08-16 17:59:16.000000000 +0200
19531 @@ -40,6 +40,7 @@
19532  #include <linux/cpu.h>
19533  #include <linux/percpu.h>
19534  #include <linux/kthread.h>
19535 +#include <linux/grsecurity.h>
19536  #include <asm/tlb.h>
19537  
19538  #include <asm/unistd.h>
19539 @@ -2630,6 +2631,8 @@
19540                         return -EPERM;
19541                 if (increment < -40)
19542                         increment = -40;
19543 +               if (gr_handle_chroot_nice())
19544 +                       return -EPERM;
19545         }
19546         if (increment > 40)
19547                 increment = 40;
19548 diff -uNr linux-2.6.8/kernel/signal.c linux-2.6.8.grsecurity/kernel/signal.c
19549 --- linux-2.6.8/kernel/signal.c 2004-08-14 07:36:56.000000000 +0200
19550 +++ linux-2.6.8.grsecurity/kernel/signal.c      2004-08-16 17:09:59.000000000 +0200
19551 @@ -21,6 +21,7 @@
19552  #include <linux/binfmts.h>
19553  #include <linux/security.h>
19554  #include <linux/ptrace.h>
19555 +#include <linux/grsecurity.h>
19556  #include <asm/param.h>
19557  #include <asm/uaccess.h>
19558  #include <asm/unistd.h>
19559 @@ -613,6 +614,8 @@
19560             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
19561             && !capable(CAP_KILL))
19562                 return error;
19563 +       if (gr_handle_signal(t, sig))
19564 +               return error;
19565         return security_task_kill(t, info, sig);
19566  }
19567  
19568 @@ -773,11 +776,13 @@
19569         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
19570  
19571  
19572 -static int
19573 +int
19574  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
19575  {
19576         int ret = 0;
19577  
19578 +       gr_log_signal(sig, t);
19579 +
19580         if (!irqs_disabled())
19581                 BUG();
19582  #ifdef CONFIG_SMP
19583 @@ -828,6 +833,8 @@
19584         ret = specific_send_sig_info(sig, info, t);
19585         spin_unlock_irqrestore(&t->sighand->siglock, flags);
19586  
19587 +       gr_handle_crash(t, sig);
19588 +
19589         return ret;
19590  }
19591  
19592 diff -uNr linux-2.6.8/kernel/sys.c linux-2.6.8.grsecurity/kernel/sys.c
19593 --- linux-2.6.8/kernel/sys.c    2004-08-14 07:36:16.000000000 +0200
19594 +++ linux-2.6.8.grsecurity/kernel/sys.c 2004-08-16 17:09:59.000000000 +0200
19595 @@ -23,6 +23,7 @@
19596  #include <linux/security.h>
19597  #include <linux/dcookies.h>
19598  #include <linux/suspend.h>
19599 +#include <linux/grsecurity.h>
19600  
19601  #include <asm/uaccess.h>
19602  #include <asm/io.h>
19603 @@ -294,6 +295,12 @@
19604                 error = -EACCES;
19605                 goto out;
19606         }
19607 +
19608 +       if (gr_handle_chroot_setpriority(p, niceval)) {
19609 +               error = -EACCES;
19610 +               goto out;
19611 +       }
19612 +
19613         no_nice = security_task_setnice(p, niceval);
19614         if (no_nice) {
19615                 error = no_nice;
19616 @@ -598,6 +605,9 @@
19617         if (rgid != (gid_t) -1 ||
19618             (egid != (gid_t) -1 && egid != old_rgid))
19619                 current->sgid = new_egid;
19620 +
19621 +       gr_set_role_label(current, current->uid, new_rgid);
19622 +
19623         current->fsgid = new_egid;
19624         current->egid = new_egid;
19625         current->gid = new_rgid;
19626 @@ -625,6 +635,9 @@
19627                         current->mm->dumpable=0;
19628                         wmb();
19629                 }
19630 +
19631 +               gr_set_role_label(current, current->uid, gid);
19632 +
19633                 current->gid = current->egid = current->sgid = current->fsgid = gid;
19634         }
19635         else if ((gid == current->gid) || (gid == current->sgid))
19636 @@ -663,6 +676,9 @@
19637                 current->mm->dumpable = 0;
19638                 wmb();
19639         }
19640 +
19641 +       gr_set_role_label(current, new_ruid, current->gid);
19642 +
19643         current->uid = new_ruid;
19644         return 0;
19645  }
19646 @@ -763,6 +779,9 @@
19647         } else if ((uid != current->uid) && (uid != new_suid))
19648                 return -EPERM;
19649  
19650 +       if (gr_check_crash_uid(uid))
19651 +               return -EPERM;
19652 +
19653         if (old_euid != uid)
19654         {
19655                 current->mm->dumpable = 0;
19656 @@ -862,8 +881,10 @@
19657                 current->egid = egid;
19658         }
19659         current->fsgid = current->egid;
19660 -       if (rgid != (gid_t) -1)
19661 +       if (rgid != (gid_t) -1) {
19662 +               gr_set_role_label(current, current->uid, rgid);
19663                 current->gid = rgid;
19664 +       }
19665         if (sgid != (gid_t) -1)
19666                 current->sgid = sgid;
19667         return 0;
19668 diff -uNr linux-2.6.8/kernel/sysctl.c linux-2.6.8.grsecurity/kernel/sysctl.c
19669 --- linux-2.6.8/kernel/sysctl.c 2004-08-14 07:36:16.000000000 +0200
19670 +++ linux-2.6.8.grsecurity/kernel/sysctl.c      2004-08-16 17:09:59.000000000 +0200
19671 @@ -48,6 +48,14 @@
19672  #endif
19673  
19674  #if defined(CONFIG_SYSCTL)
19675 +#include <linux/grsecurity.h>
19676 +#include <linux/grinternal.h>
19677 +
19678 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
19679 +                             const void *newval);
19680 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
19681 +                               const int op);
19682 +extern int gr_handle_chroot_sysctl(const int op);
19683  
19684  /* External variables not in a header file. */
19685  extern int panic_timeout;
19686 @@ -142,6 +150,32 @@
19687  #ifdef CONFIG_UNIX98_PTYS
19688  extern ctl_table pty_table[];
19689  #endif
19690 +extern ctl_table grsecurity_table[];
19691 +
19692 +#ifdef CONFIG_PAX_SOFTMODE
19693 +static ctl_table pax_table[] = {
19694 +
19695 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
19696 +       {
19697 +               .ctl_name       = PAX_ASLR,
19698 +               .procname       = "aslr",
19699 +               .data           = &pax_aslr,
19700 +               .maxlen         = sizeof(unsigned int),
19701 +               .mode           = 0600,
19702 +               .proc_handler   = &proc_dointvec,
19703 +       },
19704 +#endif
19705 +
19706 +       {
19707 +               .ctl_name       = PAX_SOFTMODE,
19708 +               .procname       = "softmode",
19709 +               .data           = &pax_softmode,
19710 +               .maxlen         = sizeof(unsigned int),
19711 +               .mode           = 0600,
19712 +               .proc_handler   = &proc_dointvec,
19713 +       }
19714 +};
19715 +#endif
19716  
19717  /* /proc declarations: */
19718  
19719 @@ -620,6 +654,14 @@
19720                 .mode           = 0444,
19721                 .proc_handler   = &proc_dointvec,
19722         },
19723 +#ifdef CONFIG_GRKERNSEC_SYSCTL
19724 +       {
19725 +               .ctl_name       = KERN_GRSECURITY,
19726 +               .procname       = "grsecurity",
19727 +               .mode           = 0500,
19728 +               .child          = grsecurity_table,
19729 +       },
19730 +#endif
19731         { .ctl_name = 0 }
19732  };
19733  
19734 @@ -899,6 +941,16 @@
19735                 .mode           = 0644,
19736                 .proc_handler   = &proc_dointvec,
19737         },
19738 +
19739 +#ifdef CONFIG_PAX_SOFTMODE
19740 +       {
19741 +               .ctl_name       = KERN_PAX,
19742 +               .procname       = "pax",
19743 +               .mode           = 0500,
19744 +               .child          = pax_table,
19745 +       },
19746 +#endif
19747 +
19748         { .ctl_name = 0 }
19749  };
19750  
19751 @@ -983,6 +1035,10 @@
19752  static inline int ctl_perm(ctl_table *table, int op)
19753  {
19754         int error;
19755 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
19756 +               return -EACCES;
19757 +       if (gr_handle_chroot_sysctl(op))
19758 +               return -EACCES;
19759         error = security_sysctl(table, op);
19760         if (error)
19761                 return error;
19762 @@ -1019,6 +1075,10 @@
19763                                 table = table->child;
19764                                 goto repeat;
19765                         }
19766 +
19767 +                       if (!gr_handle_sysctl(table, oldval, newval))
19768 +                               return -EACCES;
19769 +
19770                         error = do_sysctl_strategy(table, name, nlen,
19771                                                    oldval, oldlenp,
19772                                                    newval, newlen, context);
19773 diff -uNr linux-2.6.8/kernel/time.c linux-2.6.8.grsecurity/kernel/time.c
19774 --- linux-2.6.8/kernel/time.c   2004-08-14 07:36:32.000000000 +0200
19775 +++ linux-2.6.8.grsecurity/kernel/time.c        2004-08-16 17:09:59.000000000 +0200
19776 @@ -28,6 +28,7 @@
19777  #include <linux/timex.h>
19778  #include <linux/errno.h>
19779  #include <linux/smp_lock.h>
19780 +#include <linux/grsecurity.h>
19781  #include <asm/uaccess.h>
19782  #include <asm/unistd.h>
19783  
19784 @@ -82,6 +83,9 @@
19785  
19786         tv.tv_nsec = 0;
19787         do_settimeofday(&tv);
19788 +
19789 +       gr_log_timechange();
19790 +
19791         return 0;
19792  }
19793  
19794 @@ -183,6 +187,8 @@
19795                         return -EFAULT;
19796         }
19797  
19798 +       gr_log_timechange();
19799 +
19800         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
19801  }
19802  
19803 diff -uNr linux-2.6.8/kernel/timer.c linux-2.6.8.grsecurity/kernel/timer.c
19804 --- linux-2.6.8/kernel/timer.c  2004-08-14 07:37:38.000000000 +0200
19805 +++ linux-2.6.8.grsecurity/kernel/timer.c       2004-08-16 18:00:05.000000000 +0200
19806 @@ -31,6 +31,7 @@
19807  #include <linux/time.h>
19808  #include <linux/jiffies.h>
19809  #include <linux/cpu.h>
19810 +#include <linux/grsecurity.h>
19811  
19812  #include <asm/uaccess.h>
19813  #include <asm/unistd.h>
19814 @@ -792,6 +793,9 @@
19815  
19816         psecs = (p->utime += user);
19817         psecs += (p->stime += system);
19818 +
19819 +       gr_learn_resource(p, RLIMIT_CPU, psecs / HZ, 1);
19820 +
19821         if (psecs / HZ >= p->rlim[RLIMIT_CPU].rlim_cur) {
19822                 /* Send SIGXCPU every second.. */
19823                 if (!(psecs % HZ))
19824 diff -uNr linux-2.6.8/Makefile linux-2.6.8.grsecurity/Makefile
19825 --- linux-2.6.8/Makefile        2004-08-16 16:56:47.000000000 +0200
19826 +++ linux-2.6.8.grsecurity/Makefile     2004-08-16 17:07:23.000000000 +0200
19827 @@ -478,7 +478,7 @@
19828  
19829  
19830  ifeq ($(KBUILD_EXTMOD),)
19831 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/
19832 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/
19833  
19834  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
19835                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
19836 diff -uNr linux-2.6.8/mm/filemap.c linux-2.6.8.grsecurity/mm/filemap.c
19837 --- linux-2.6.8/mm/filemap.c    2004-08-14 07:38:11.000000000 +0200
19838 +++ linux-2.6.8.grsecurity/mm/filemap.c 2004-08-16 17:09:59.000000000 +0200
19839 @@ -27,6 +27,8 @@
19840  #include <linux/pagevec.h>
19841  #include <linux/blkdev.h>
19842  #include <linux/security.h>
19843 +#include <linux/grsecurity.h>
19844 +
19845  /*
19846   * This is needed for the following functions:
19847   *  - try_to_release_page
19848 @@ -1444,6 +1446,12 @@
19849  
19850         if (!mapping->a_ops->readpage)
19851                 return -ENOEXEC;
19852 +
19853 +#ifdef CONFIG_PAX_PAGEEXEC
19854 +       if (current->flags & PF_PAX_PAGEEXEC)
19855 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
19856 +#endif
19857 +
19858         file_accessed(file);
19859         vma->vm_ops = &generic_file_vm_ops;
19860         return 0;
19861 @@ -1742,6 +1750,7 @@
19862                          *pos = i_size_read(inode);
19863  
19864                 if (limit != RLIM_INFINITY) {
19865 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
19866                         if (*pos >= limit) {
19867                                 send_sig(SIGXFSZ, current, 0);
19868                                 return -EFBIG;
19869 diff -uNr linux-2.6.8/mm/madvise.c linux-2.6.8.grsecurity/mm/madvise.c
19870 --- linux-2.6.8/mm/madvise.c    2004-08-14 07:36:32.000000000 +0200
19871 +++ linux-2.6.8.grsecurity/mm/madvise.c 2004-08-16 17:09:59.000000000 +0200
19872 @@ -13,8 +13,42 @@
19873   * We can potentially split a vm area into separate
19874   * areas, each area with its own behavior.
19875   */
19876 +
19877 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19878 +static long __madvise_behavior(struct vm_area_struct * vma, unsigned long start,
19879 +                            unsigned long end, int behavior);
19880 +
19881 +static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
19882 +                            unsigned long end, int behavior)
19883 +{
19884 +       if (vma->vm_flags & VM_MIRROR) {
19885 +               struct vm_area_struct * vma_m, * prev_m;
19886 +               unsigned long start_m, end_m;
19887 +               int error;
19888 +
19889 +               start_m = vma->vm_start + vma->vm_mirror;
19890 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
19891 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
19892 +                       start_m = start + vma->vm_mirror;
19893 +                       end_m = end + vma->vm_mirror;
19894 +                       error = __madvise_behavior(vma_m, start_m, end_m, behavior);
19895 +                       if (error)
19896 +                               return error;
19897 +               } else {
19898 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
19899 +                       return -ENOMEM;
19900 +               }
19901 +       }
19902 +
19903 +       return __madvise_behavior(vma, start, end, behavior);
19904 +}
19905 +
19906 +static long __madvise_behavior(struct vm_area_struct * vma, unsigned long start,
19907 +                            unsigned long end, int behavior)
19908 +#else
19909  static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
19910                              unsigned long end, int behavior)
19911 +#endif
19912  {
19913         struct mm_struct * mm = vma->vm_mm;
19914         int error;
19915 diff -uNr linux-2.6.8/mm/memory.c linux-2.6.8.grsecurity/mm/memory.c
19916 --- linux-2.6.8/mm/memory.c     2004-08-14 07:36:57.000000000 +0200
19917 +++ linux-2.6.8.grsecurity/mm/memory.c  2004-08-16 17:09:59.000000000 +0200
19918 @@ -46,6 +46,7 @@
19919  #include <linux/rmap.h>
19920  #include <linux/module.h>
19921  #include <linux/init.h>
19922 +#include <linux/grsecurity.h>
19923  
19924  #include <asm/pgalloc.h>
19925  #include <asm/uaccess.h>
19926 @@ -1018,6 +1019,81 @@
19927         update_mmu_cache(vma, address, entry);
19928  }
19929  
19930 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19931 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
19932 + *
19933 + * mm->page_table_lock is held on entry and is not released on exit or inside
19934 + * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
19935 + */
19936 +static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
19937 +       unsigned long address, pte_t *pte)
19938 +{
19939 +       unsigned long address_m;
19940 +       struct vm_area_struct * vma_m = NULL;
19941 +       pte_t * pte_m, entry_m;
19942 +       struct page * page_m;
19943 +
19944 +       address_m = vma->vm_start + vma->vm_mirror;
19945 +       vma_m = find_vma(mm, address_m);
19946 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
19947 +
19948 +       address_m = address + vma->vm_mirror;
19949 +
19950 +       {
19951 +               pgd_t *pgd_m;
19952 +               pmd_t *pmd_m;
19953 +
19954 +               pgd_m = pgd_offset(mm, address_m);
19955 +               pmd_m = pmd_offset(pgd_m, address_m);
19956 +               pte_m = pte_offset_map_nested(pmd_m, address_m);
19957 +       }
19958 +
19959 +       if (pte_present(*pte_m)) {
19960 +               flush_cache_page(vma_m, address_m);
19961 +               flush_icache_page(vma_m, pte_page(*pte_m));
19962 +       }
19963 +       entry_m = ptep_get_and_clear(pte_m);
19964 +       if (pte_present(entry_m))
19965 +               flush_tlb_page(vma_m, address_m);
19966 +
19967 +       if (pte_none(entry_m)) {
19968 +               ++mm->rss;
19969 +       } else if (pte_present(entry_m)) {
19970 +               page_m = pte_page(entry_m);
19971 +               if (PageReserved(page_m))
19972 +                       ++mm->rss;
19973 +               else
19974 +                       page_remove_rmap(page_m);
19975 +               page_cache_release(page_m);
19976 +       } else if (!pte_file(entry_m)) {
19977 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
19978 +               ++mm->rss;
19979 +       } else {
19980 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
19981 +                               address, vma->vm_start, address_m, vma_m->vm_start);
19982 +       }
19983 +
19984 +       page_m = pte_page(*pte);
19985 +       entry_m = mk_pte(page_m, vma_m->vm_page_prot);
19986 +       if (pte_write(*pte) && (vma_m->vm_flags & VM_WRITE))
19987 +               entry_m = pte_mkdirty(pte_mkwrite(entry_m));
19988 +       if (!PageReserved(page_m)) {
19989 +               page_cache_get(page_m);
19990 +               /*
19991 +                * we can test PG_anon without holding page_map_lock because
19992 +                * we hold the page table lock and have a reference to page_m
19993 +                */
19994 +               if (PageAnon(page_m))
19995 +                       page_add_anon_rmap(page_m, vma_m, address_m);
19996 +               else
19997 +                       page_add_file_rmap(page_m);
19998 +       }
19999 +       ptep_establish(vma_m, address_m, pte_m, entry_m);
20000 +       update_mmu_cache(vma_m, address_m, entry_m);
20001 +       pte_unmap_nested(pte_m);
20002 +}
20003 +#endif
20004 +
20005  /*
20006   * This routine handles present pages, when users try to write
20007   * to a shared page. It is done by copying the page to a new address
20008 @@ -1105,6 +1181,12 @@
20009  
20010                 /* Free the old page.. */
20011                 new_page = old_page;
20012 +
20013 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20014 +               if (vma->vm_flags & VM_MIRROR)
20015 +                       pax_mirror_fault(mm, vma, address, page_table);
20016 +#endif
20017 +
20018         }
20019         pte_unmap(page_table);
20020         page_cache_release(new_page);
20021 @@ -1237,6 +1319,7 @@
20022  
20023  do_expand:
20024         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
20025 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
20026         if (limit != RLIM_INFINITY && offset > limit)
20027                 goto out_sig;
20028         if (offset > inode->i_sb->s_maxbytes)
20029 @@ -1398,6 +1481,12 @@
20030  
20031         /* No need to invalidate - it was non-present before */
20032         update_mmu_cache(vma, address, pte);
20033 +
20034 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20035 +       if (vma->vm_flags & VM_MIRROR)
20036 +               pax_mirror_fault(mm, vma, address, page_table);
20037 +#endif
20038 +
20039         pte_unmap(page_table);
20040         spin_unlock(&mm->page_table_lock);
20041  out:
20042 @@ -1452,10 +1541,16 @@
20043         }
20044  
20045         set_pte(page_table, entry);
20046 -       pte_unmap(page_table);
20047  
20048         /* No need to invalidate - it was non-present before */
20049         update_mmu_cache(vma, addr, entry);
20050 +
20051 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20052 +       if (vma->vm_flags & VM_MIRROR)
20053 +               pax_mirror_fault(mm, vma, addr, page_table);
20054 +#endif
20055 +
20056 +       pte_unmap(page_table);
20057         spin_unlock(&mm->page_table_lock);
20058  out:
20059         return VM_FAULT_MINOR;
20060 @@ -1562,6 +1657,15 @@
20061                         page_add_anon_rmap(new_page, vma, address);
20062                 } else
20063                         page_add_file_rmap(new_page);
20064 +
20065 +               /* no need to invalidate: a not-present page shouldn't be cached */
20066 +               update_mmu_cache(vma, address, entry);
20067 +
20068 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20069 +               if (vma->vm_flags & VM_MIRROR)
20070 +                       pax_mirror_fault(mm, vma, address, page_table);
20071 +#endif
20072 +
20073                 pte_unmap(page_table);
20074         } else {
20075                 /* One of our sibling threads was faster, back out. */
20076 @@ -1571,8 +1675,6 @@
20077                 goto out;
20078         }
20079  
20080 -       /* no need to invalidate: a not-present page shouldn't be cached */
20081 -       update_mmu_cache(vma, address, entry);
20082         spin_unlock(&mm->page_table_lock);
20083  out:
20084         return ret;
20085 @@ -1681,6 +1783,11 @@
20086         pgd_t *pgd;
20087         pmd_t *pmd;
20088  
20089 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20090 +       unsigned long address_m = 0UL;
20091 +       struct vm_area_struct * vma_m = NULL;
20092 +#endif
20093 +
20094         __set_current_state(TASK_RUNNING);
20095         pgd = pgd_offset(mm, address);
20096  
20097 @@ -1694,6 +1801,45 @@
20098          * and the SMP-safe atomic PTE updates.
20099          */
20100         spin_lock(&mm->page_table_lock);
20101 +
20102 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20103 +       if (vma->vm_flags & VM_MIRROR) {
20104 +               pgd_t *pgd_m;
20105 +               pmd_t *pmd_m;
20106 +               pte_t *pte_m;
20107 +
20108 +               address_m = vma->vm_start + vma->vm_mirror;
20109 +               vma_m = find_vma(mm, address_m);
20110 +
20111 +               /* PaX: sanity checks */
20112 +               if (!vma_m) {
20113 +                       spin_unlock(&mm->page_table_lock);
20114 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
20115 +                              address, vma, address_m, vma_m);
20116 +                       return VM_FAULT_SIGBUS;
20117 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
20118 +                          vma_m->vm_start != address_m ||
20119 +                          vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
20120 +               {
20121 +                       spin_unlock(&mm->page_table_lock);
20122 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
20123 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
20124 +                       return VM_FAULT_SIGBUS;
20125 +               }
20126 +
20127 +               address_m = address + vma->vm_mirror;
20128 +               pgd_m = pgd_offset(mm, address_m);
20129 +               pmd_m = pmd_alloc(mm, pgd_m, address_m);
20130 +               if (pmd_m)
20131 +                       pte_m = pte_alloc_map(mm, pmd_m, address_m);
20132 +               if (!pmd_m || !pte_m) {
20133 +                       spin_unlock(&mm->page_table_lock);
20134 +                       return VM_FAULT_OOM;
20135 +               }
20136 +               pte_unmap(pte_m);
20137 +       }
20138 +#endif
20139 +
20140         pmd = pmd_alloc(mm, pgd, address);
20141  
20142         if (pmd) {
20143 diff -uNr linux-2.6.8/mm/mlock.c linux-2.6.8.grsecurity/mm/mlock.c
20144 --- linux-2.6.8/mm/mlock.c      2004-08-14 07:36:13.000000000 +0200
20145 +++ linux-2.6.8.grsecurity/mm/mlock.c   2004-08-16 17:09:59.000000000 +0200
20146 @@ -7,11 +7,43 @@
20147  
20148  #include <linux/mman.h>
20149  #include <linux/mm.h>
20150 +#include <linux/grsecurity.h>
20151  
20152 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20153 +static int __mlock_fixup(struct vm_area_struct * vma, 
20154 +       unsigned long start, unsigned long end, unsigned int newflags);
20155  
20156  static int mlock_fixup(struct vm_area_struct * vma, 
20157         unsigned long start, unsigned long end, unsigned int newflags)
20158  {
20159 +       if (vma->vm_flags & VM_MIRROR) {
20160 +               struct vm_area_struct * vma_m;
20161 +               unsigned long start_m, end_m;
20162 +               int error;
20163 +
20164 +               start_m = vma->vm_start + vma->vm_mirror;
20165 +               vma_m = find_vma(vma->vm_mm, start_m);
20166 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
20167 +                       start_m = start + vma->vm_mirror;
20168 +                       end_m = end + vma->vm_mirror;
20169 +                       error = __mlock_fixup(vma_m, start_m, end_m, newflags);
20170 +                       if (error)
20171 +                               return error;
20172 +               } else {
20173 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
20174 +                       return -ENOMEM;
20175 +               }
20176 +       }
20177 +       return __mlock_fixup(vma, start, end, newflags);
20178 +}
20179 +
20180 +static int __mlock_fixup(struct vm_area_struct * vma, 
20181 +       unsigned long start, unsigned long end, unsigned int newflags)
20182 +#else
20183 +static int mlock_fixup(struct vm_area_struct * vma, 
20184 +       unsigned long start, unsigned long end, unsigned int newflags)
20185 +#endif
20186 +{
20187         struct mm_struct * mm = vma->vm_mm;
20188         int pages;
20189         int ret = 0;
20190 @@ -68,6 +100,17 @@
20191                 return -EINVAL;
20192         if (end == start)
20193                 return 0;
20194 +
20195 +#ifdef CONFIG_PAX_SEGMEXEC
20196 +       if (current->flags & PF_PAX_SEGMEXEC) {
20197 +               if (end > SEGMEXEC_TASK_SIZE)
20198 +                       return -EINVAL;
20199 +       } else
20200 +#endif
20201 +
20202 +       if (end > TASK_SIZE)
20203 +               return -EINVAL;
20204 +
20205         vma = find_vma(current->mm, start);
20206         if (!vma || vma->vm_start > start)
20207                 return -ENOMEM;
20208 @@ -118,6 +161,7 @@
20209         lock_limit >>= PAGE_SHIFT;
20210  
20211         /* check against resource limits */
20212 +       gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
20213         if (locked <= lock_limit)
20214                 error = do_mlock(start, len, 1);
20215         up_write(&current->mm->mmap_sem);
20216 @@ -154,6 +198,16 @@
20217         for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
20218                 unsigned int newflags;
20219  
20220 +#ifdef CONFIG_PAX_SEGMEXEC
20221 +               if (current->flags & PF_PAX_SEGMEXEC) {
20222 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
20223 +                               break;
20224 +               } else
20225 +#endif
20226 +
20227 +               if (vma->vm_end > TASK_SIZE)
20228 +                       break;
20229 +
20230                 newflags = vma->vm_flags | VM_LOCKED;
20231                 if (!(flags & MCL_CURRENT))
20232                         newflags &= ~VM_LOCKED;
20233 @@ -177,6 +231,7 @@
20234         lock_limit >>= PAGE_SHIFT;
20235  
20236         ret = -ENOMEM;
20237 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
20238         if (current->mm->total_vm <= lock_limit)
20239                 ret = do_mlockall(flags);
20240  out:
20241 diff -uNr linux-2.6.8/mm/mmap.c linux-2.6.8.grsecurity/mm/mmap.c
20242 --- linux-2.6.8/mm/mmap.c       2004-08-14 07:37:15.000000000 +0200
20243 +++ linux-2.6.8.grsecurity/mm/mmap.c    2004-08-16 17:09:59.000000000 +0200
20244 @@ -23,6 +23,7 @@
20245  #include <linux/mount.h>
20246  #include <linux/mempolicy.h>
20247  #include <linux/rmap.h>
20248 +#include <linux/grsecurity.h>
20249  
20250  #include <asm/uaccess.h>
20251  #include <asm/cacheflush.h>
20252 @@ -136,6 +137,7 @@
20253  
20254         /* Check against rlimit.. */
20255         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
20256 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
20257         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
20258                 goto out;
20259  
20260 @@ -506,7 +508,11 @@
20261   * If the vma has a ->close operation then the driver probably needs to release
20262   * per-vma resources, so we don't attempt to merge those.
20263   */
20264 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20265 +#define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_MIRROR)
20266 +#else
20267  #define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
20268 +#endif
20269  
20270  static inline int is_mergeable_vma(struct vm_area_struct *vma,
20271                         struct file *file, unsigned long vm_flags)
20272 @@ -740,6 +746,42 @@
20273                         unsigned long len, unsigned long prot,
20274                         unsigned long flags, unsigned long pgoff)
20275  {
20276 +       unsigned long ret = -EINVAL;
20277 +
20278 +#ifdef CONFIG_PAX_SEGMEXEC
20279 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
20280 +           (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
20281 +               return ret;
20282 +#endif
20283 +
20284 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
20285 +
20286 +#ifdef CONFIG_PAX_SEGMEXEC
20287 +       if ((current->flags & PF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
20288 +
20289 +#ifdef CONFIG_PAX_MPROTECT
20290 +           && (!(current->flags & PF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
20291 +#endif
20292 +
20293 +          )
20294 +       {
20295 +               unsigned long ret_m;
20296 +               prot = prot & PROT_EXEC ? prot : PROT_NONE;
20297 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
20298 +               if (ret_m >= TASK_SIZE) {
20299 +                       do_munmap(current->mm, ret, len);
20300 +                       ret = ret_m;
20301 +               }
20302 +       }
20303 +#endif
20304 +
20305 +       return ret;
20306 +}
20307 +
20308 +unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
20309 +                       unsigned long len, unsigned long prot,
20310 +                       unsigned long flags, unsigned long pgoff)
20311 +{
20312         struct mm_struct * mm = current->mm;
20313         struct vm_area_struct * vma, * prev;
20314         struct inode *inode;
20315 @@ -757,6 +799,28 @@
20316                         (current->personality & READ_IMPLIES_EXEC)))
20317                 prot |= PROT_EXEC;
20318  
20319 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20320 +       struct vm_area_struct * vma_m = NULL;
20321 +
20322 +       if (flags & MAP_MIRROR) {
20323 +               /* PaX: sanity checks, to be removed when proved to be stable */
20324 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
20325 +                       return -EINVAL;
20326 +
20327 +               vma_m = find_vma(mm, pgoff);
20328 +
20329 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
20330 +                   vma_m->vm_start != pgoff ||
20331 +                   (vma_m->vm_flags & VM_MIRROR) ||
20332 +                   (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE)))
20333 +                       return -EINVAL;
20334 +
20335 +               file = vma_m->vm_file;
20336 +               pgoff = vma_m->vm_pgoff;
20337 +               len = vma_m->vm_end - vma_m->vm_start;
20338 +       }
20339 +#endif
20340 +
20341         if (file) {
20342                 if (is_file_hugepages(file))
20343                         accountable = 0;
20344 @@ -788,7 +852,7 @@
20345         /* Obtain the address to map to. we verify (or select) it and ensure
20346          * that it represents a valid section of the address space.
20347          */
20348 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
20349 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
20350         if (addr & ~PAGE_MASK)
20351                 return addr;
20352  
20353 @@ -799,6 +863,30 @@
20354         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
20355                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
20356  
20357 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
20358 +               vm_flags &= ~VM_MAYEXEC;
20359 +
20360 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20361 +       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
20362 +
20363 +#ifdef CONFIG_PAX_MPROTECT
20364 +               if (current->flags & PF_PAX_MPROTECT) {
20365 +                       if (!file || (prot & PROT_WRITE))
20366 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
20367 +                       else
20368 +                               vm_flags &= ~VM_MAYWRITE;
20369 +
20370 +#ifdef CONFIG_PAX_RANDEXEC
20371 +                       if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC))
20372 +                               vma_m->vm_flags &= ~VM_MAYWRITE;
20373 +#endif
20374 +
20375 +               }
20376 +#endif
20377 +
20378 +       }
20379 +#endif
20380 +
20381         if (flags & MAP_LOCKED) {
20382                 if (!capable(CAP_IPC_LOCK))
20383                         return -EPERM;
20384 @@ -808,6 +896,7 @@
20385         if (vm_flags & VM_LOCKED) {
20386                 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
20387                 locked += len;
20388 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
20389                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
20390                         return -EAGAIN;
20391         }
20392 @@ -855,6 +944,11 @@
20393                         /*
20394                          * Set pgoff according to addr for anon_vma.
20395                          */
20396 +
20397 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20398 +                       if (!(flags & MAP_MIRROR))
20399 +#endif
20400 +
20401                         pgoff = addr >> PAGE_SHIFT;
20402                         break;
20403                 default:
20404 @@ -866,6 +960,9 @@
20405         if (error)
20406                 return error;
20407                 
20408 +       if (!gr_acl_handle_mmap(file, prot))
20409 +               return -EACCES;
20410 +
20411         /* Clear old maps */
20412         error = -ENOMEM;
20413  munmap_back:
20414 @@ -877,6 +974,7 @@
20415         }
20416  
20417         /* Check against address space limit. */
20418 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
20419         if ((mm->total_vm << PAGE_SHIFT) + len
20420             > current->rlim[RLIMIT_AS].rlim_cur)
20421                 return -ENOMEM;
20422 @@ -923,6 +1021,13 @@
20423         vma->vm_start = addr;
20424         vma->vm_end = addr + len;
20425         vma->vm_flags = vm_flags;
20426 +
20427 +#ifdef CONFIG_PAX_PAGEEXEC
20428 +       if ((file || !(current->flags & PF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
20429 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
20430 +       else
20431 +#endif
20432 +
20433         vma->vm_page_prot = protection_map[vm_flags & 0x0f];
20434         vma->vm_pgoff = pgoff;
20435  
20436 @@ -947,6 +1052,14 @@
20437                         goto free_vma;
20438         }
20439  
20440 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20441 +       if (flags & MAP_MIRROR) {
20442 +               vma_m->vm_flags |= VM_MIRROR;
20443 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
20444 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
20445 +       }
20446 +#endif
20447 +
20448         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
20449          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
20450          * that memory reservation must be checked; but that reservation
20451 @@ -988,6 +1101,7 @@
20452                                         pgoff, flags & MAP_NONBLOCK);
20453                 down_write(&mm->mmap_sem);
20454         }
20455 +       track_exec_limit(mm, addr, addr + len, vm_flags);
20456         return addr;
20457  
20458  unmap_and_free_vma:
20459 @@ -1007,6 +1121,7 @@
20460  }
20461  
20462  EXPORT_SYMBOL(do_mmap_pgoff);
20463 +EXPORT_SYMBOL(__do_mmap_pgoff);
20464  
20465  /* Get an address range which is currently unmapped.
20466   * For shmat() with addr=0.
20467 @@ -1026,11 +1141,17 @@
20468  {
20469         struct mm_struct *mm = current->mm;
20470         struct vm_area_struct *vma;
20471 -       unsigned long start_addr;
20472 +       unsigned long start_addr, task_unmapped_base = TASK_UNMAPPED_BASE;
20473  
20474         if (len > TASK_SIZE)
20475                 return -ENOMEM;
20476  
20477 +#ifdef CONFIG_PAX_RANDMMAP
20478 +       if (current->flags & PF_PAX_RANDMMAP)
20479 +               task_unmapped_base += mm->delta_mmap;
20480 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
20481 +#endif
20482 +
20483         if (addr) {
20484                 addr = PAGE_ALIGN(addr);
20485                 vma = find_vma(mm, addr);
20486 @@ -1048,8 +1169,8 @@
20487                          * Start a new search - just in case we missed
20488                          * some holes.
20489                          */
20490 -                       if (start_addr != TASK_UNMAPPED_BASE) {
20491 -                               start_addr = addr = TASK_UNMAPPED_BASE;
20492 +                       if (start_addr != task_unmapped_base) {
20493 +                               start_addr = addr = task_unmapped_base;
20494                                 goto full_search;
20495                         }
20496                         return -ENOMEM;
20497 @@ -1190,6 +1311,11 @@
20498  {
20499         unsigned long grow;
20500  
20501 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20502 +       struct vm_area_struct * vma_m = NULL;
20503 +       unsigned long address_m = 0UL;
20504 +#endif
20505 +
20506         if (!(vma->vm_flags & VM_GROWSUP))
20507                 return -EFAULT;
20508  
20509 @@ -1216,17 +1342,76 @@
20510                 return -ENOMEM;
20511         }
20512         
20513 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20514 +       if (vma->vm_flags & VM_MIRROR) {
20515 +               address_m = vma->vm_start + vma->vm_mirror;
20516 +               vma_m = find_vma(vma->vm_mm, address_m);
20517 +               if (!vma_m || vma_m->vm_start != address_m ||
20518 +                               !(vma_m->vm_flags & VM_MIRROR) ||
20519 +                               vma->vm_end - vma->vm_start !=
20520 +                               vma_m->vm_end - vma_m->vm_start) {
20521 +                       anon_vma_unlock(vma);
20522 +                       vm_unacct_memory(grow);
20523 +                       printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
20524 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
20525 +                       return -ENOMEM;
20526 +               }
20527 +
20528 +               gr_learn_resource(current, RLIMIT_STACK, address_m - vma_m->vm_start, 1);
20529 +               gr_learn_resource(current, RLIMIT_AS, (vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT, 1);
20530 +               if (vma_m->vm_flags & VM_LOCKED)
20531 +                       gr_learn_resource(current, RLIMIT_MEMLOCK, (vma_->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT, 1);
20532 +
20533 +               address_m = address + vma->vm_mirror;
20534 +               if (address_m - vma_m->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
20535 +                               ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) >
20536 +                               current->rlim[RLIMIT_AS].rlim_cur ||
20537 +                               ((vma_m->vm_flags & VM_LOCKED) &&
20538 +                               ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
20539 +                               current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
20540 +                       anon_vma_unlock(vma);
20541 +                       vm_unacct_memory(grow);
20542 +                       return -ENOMEM;
20543 +               }
20544 +       } else {
20545 +#endif
20546 +
20547 +       gr_learn_resource(current, RLIMIT_STACK, address - vma->vm_start, 1);
20548 +       gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
20549 +       if (vma->vm_flags & VM_LOCKED)
20550 +               gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
20551 +
20552         if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
20553                         ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
20554 -                       current->rlim[RLIMIT_AS].rlim_cur) {
20555 +                       current->rlim[RLIMIT_AS].rlim_cur ||
20556 +                       ((vma->vm_flags & VM_LOCKED) &&
20557 +                       ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
20558 +                       current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
20559                 anon_vma_unlock(vma);
20560                 vm_unacct_memory(grow);
20561                 return -ENOMEM;
20562         }
20563 +
20564 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20565 +       }
20566 +#endif
20567 +
20568         vma->vm_end = address;
20569         vma->vm_mm->total_vm += grow;
20570         if (vma->vm_flags & VM_LOCKED)
20571                 vma->vm_mm->locked_vm += grow;
20572 +
20573 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20574 +       if (vma->vm_flags & VM_MIRROR) {
20575 +               vma_m->vm_end = address_m;
20576 +               vma_m->vm_mm->total_vm += grow;
20577 +               if (vma_m->vm_flags & VM_LOCKED)
20578 +                       vma_m->vm_mm->locked_vm += grow;
20579 +               track_exec_limit(vma_m->vm_mm, vma_m->vm_start, vma_m->vm_end, vma_m->vm_flags);
20580 +       }
20581 +#endif
20582 +
20583 +       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
20584         anon_vma_unlock(vma);
20585         return 0;
20586  }
20587 @@ -1255,6 +1440,11 @@
20588  {
20589         unsigned long grow;
20590  
20591 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20592 +       struct vm_area_struct * vma_m = NULL;
20593 +       unsigned long address_m = 0UL;
20594 +#endif
20595 +
20596         /*
20597          * We must make sure the anon_vma is allocated
20598          * so that the anon_vma locking is not a noop.
20599 @@ -1276,19 +1466,80 @@
20600                 anon_vma_unlock(vma);
20601                 return -ENOMEM;
20602         }
20603 -       
20604 +
20605 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20606 +       if (vma->vm_flags & VM_MIRROR) {
20607 +               address_m = vma->vm_start + vma->vm_mirror;
20608 +               vma_m = find_vma(vma->vm_mm, address_m);
20609 +               if (!vma_m || vma_m->vm_start != address_m ||
20610 +                               !(vma_m->vm_flags & VM_MIRROR) ||
20611 +                               vma->vm_end - vma->vm_start !=
20612 +                               vma_m->vm_end - vma_m->vm_start ||
20613 +                               vma->anon_vma != vma_m->anon_vma) {
20614 +                       anon_vma_unlock(vma);
20615 +                       vm_unacct_memory(grow);
20616 +                       printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
20617 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
20618 +                       return -ENOMEM;
20619 +               }
20620 +
20621 +               gr_learn_resource(current, RLIMIT_STACK, vma_m->vm_end - address_m, 1);
20622 +               gr_learn_resource(current, RLIMIT_AS, (vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT, 1);
20623 +               if (vma_m->vm_flags & VM_LOCKED)
20624 +                       gr_learn_resource(current, RLIMIT_MEMLOCK, (vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT, 1);
20625 +
20626 +               address_m = address + vma->vm_mirror;
20627 +               if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur ||
20628 +                               ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) >
20629 +                               current->rlim[RLIMIT_AS].rlim_cur ||
20630 +                               ((vma_m->vm_flags & VM_LOCKED) &&
20631 +                               ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
20632 +                               current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
20633 +                       anon_vma_unlock(vma);
20634 +                       vm_unacct_memory(grow);
20635 +                       return -ENOMEM;
20636 +               }
20637 +       } else {
20638 +#endif
20639 +
20640 +       gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address, 1);
20641 +       gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
20642 +       if (vma->vm_flags & VM_LOCKED)
20643 +               gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
20644 +
20645         if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
20646                         ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
20647 -                       current->rlim[RLIMIT_AS].rlim_cur) {
20648 +                       current->rlim[RLIMIT_AS].rlim_cur ||
20649 +                       ((vma->vm_flags & VM_LOCKED) &&
20650 +                       ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
20651 +                       current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
20652                 anon_vma_unlock(vma);
20653                 vm_unacct_memory(grow);
20654                 return -ENOMEM;
20655         }
20656 +
20657 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20658 +       }
20659 +#endif
20660 +
20661         vma->vm_start = address;
20662         vma->vm_pgoff -= grow;
20663         vma->vm_mm->total_vm += grow;
20664         if (vma->vm_flags & VM_LOCKED)
20665                 vma->vm_mm->locked_vm += grow;
20666 +
20667 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20668 +       if (vma->vm_flags & VM_MIRROR) {
20669 +               vma_m->vm_start = address_m;
20670 +               vma_m->vm_pgoff -= grow;
20671 +               vma_m->vm_mm->total_vm += grow;
20672 +               if (vma_m->vm_flags & VM_LOCKED)
20673 +                       vma_m->vm_mm->locked_vm += grow;
20674 +               track_exec_limit(vma_m->vm_mm, vma_m->vm_start, vma_m->vm_end, vma_m->vm_flags);
20675 +       }
20676 +#endif
20677 +
20678 +       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
20679         anon_vma_unlock(vma);
20680         return 0;
20681  }
20682 @@ -1391,15 +1642,15 @@
20683  {
20684         size_t len = area->vm_end - area->vm_start;
20685  
20686 -       area->vm_mm->total_vm -= len >> PAGE_SHIFT;
20687 +       mm->total_vm -= len >> PAGE_SHIFT;
20688         if (area->vm_flags & VM_LOCKED)
20689 -               area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
20690 +               mm->locked_vm -= len >> PAGE_SHIFT;
20691         /*
20692          * Is this a new hole at the lowest possible address?
20693          */
20694         if (area->vm_start >= TASK_UNMAPPED_BASE &&
20695 -                               area->vm_start < area->vm_mm->free_area_cache)
20696 -             area->vm_mm->free_area_cache = area->vm_start;
20697 +                               area->vm_start < mm->free_area_cache)
20698 +             mm->free_area_cache = area->vm_start;
20699  
20700         remove_vm_struct(area);
20701  }
20702 @@ -1453,21 +1704,73 @@
20703   */
20704  static void
20705  detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
20706 -       struct vm_area_struct *prev, unsigned long end)
20707 +       struct vm_area_struct *prev, unsigned long *start, unsigned long *end)
20708  {
20709         struct vm_area_struct **insertion_point;
20710         struct vm_area_struct *tail_vma = NULL;
20711  
20712 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20713 +       unsigned long start_m;
20714 +       struct vm_area_struct *vma_m, *head_vma = vma, *mirrors = NULL, *head_vma_m = NULL;
20715 +#endif
20716 +
20717         insertion_point = (prev ? &prev->vm_next : &mm->mmap);
20718         do {
20719                 rb_erase(&vma->vm_rb, &mm->mm_rb);
20720                 mm->map_count--;
20721 +
20722 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20723 +               if ((vma->vm_flags & VM_MIRROR) &&
20724 +                   vma->vm_start + vma->vm_mirror >= *start &&
20725 +                   vma->vm_start + vma->vm_mirror < *end)
20726 +               {
20727 +                       mm->mmap_cache = NULL;          /* Kill the cache. */
20728 +                       start_m = vma->vm_start + vma->vm_mirror;
20729 +                       vma_m = find_vma(mm, start_m);
20730 +                       if (vma_m && (vma_m->vm_flags & VM_MIRROR) && vma_m->vm_start == start_m) {
20731 +                               vma->vm_flags &= ~VM_MIRROR;
20732 +                               vma_m->vm_flags &= ~VM_MIRROR;
20733 +                       } else
20734 +                               printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, vma->vm_start);
20735 +               }
20736 +#endif
20737 +
20738                 tail_vma = vma;
20739                 vma = vma->vm_next;
20740 -       } while (vma && vma->vm_start < end);
20741 +       } while (vma && vma->vm_start < *end);
20742         *insertion_point = vma;
20743         tail_vma->vm_next = NULL;
20744         mm->mmap_cache = NULL;          /* Kill the cache. */
20745 +
20746 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20747 +       for (; head_vma; head_vma = head_vma->vm_next) {
20748 +               struct vm_area_struct *prev_m;
20749 +
20750 +               if (!(head_vma->vm_flags & VM_MIRROR))
20751 +                       continue;
20752 +
20753 +               start_m = head_vma->vm_start + head_vma->vm_mirror;
20754 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
20755 +               rb_erase(&vma_m->vm_rb, &mm->mm_rb);
20756 +               mm->map_count--;
20757 +               insertion_point = prev_m ? &prev_m->vm_next : &mm->mmap;
20758 +               *insertion_point = vma_m->vm_next;
20759 +               if (head_vma_m) {
20760 +                       mirrors->vm_next = vma_m;
20761 +                       mirrors = vma_m;
20762 +               } else
20763 +                       head_vma_m = mirrors = vma_m;
20764 +               mirrors->vm_next = NULL;
20765 +               if (vma_m->vm_start < *start)
20766 +                       *start = vma_m->vm_start;
20767 +               if (vma_m->vm_end > *end)
20768 +                       *end = vma_m->vm_end;
20769 +               mm->mmap_cache = NULL;          /* Kill the cache. */
20770 +       }
20771 +       if (head_vma_m)
20772 +               tail_vma->vm_next = head_vma_m;
20773 +#endif
20774 +
20775  }
20776  
20777  /*
20778 @@ -1530,6 +1833,10 @@
20779         unsigned long end;
20780         struct vm_area_struct *mpnt, *prev, *last;
20781  
20782 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20783 +       struct vm_area_struct *mpnt_m = NULL, *last_m;
20784 +#endif
20785 +
20786         if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
20787                 return -EINVAL;
20788  
20789 @@ -1566,6 +1873,20 @@
20790          * places tmp vma above, and higher split_vma places tmp vma below.
20791          */
20792         if (start > mpnt->vm_start) {
20793 +
20794 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20795 +               if (mpnt->vm_flags & VM_MIRROR) {
20796 +                       unsigned long start_m = mpnt->vm_start + mpnt->vm_mirror;
20797 +
20798 +                       mpnt_m = find_vma(mm, start_m);
20799 +                       if (!mpnt_m || (!mpnt_m->vm_flags & VM_MIRROR) || mpnt_m->vm_start != start_m)
20800 +                               return -EINVAL;
20801 +                       start_m = start + mpnt->vm_mirror;
20802 +                       if (split_vma(mm, mpnt_m, start_m, 0))
20803 +                               return -ENOMEM;
20804 +               }
20805 +#endif
20806 +
20807                 if (split_vma(mm, mpnt, start, 0))
20808                         return -ENOMEM;
20809                 prev = mpnt;
20810 @@ -1574,6 +1895,20 @@
20811         /* Does it split the last one? */
20812         last = find_vma(mm, end);
20813         if (last && end > last->vm_start) {
20814 +
20815 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
20816 +               if (last->vm_flags & VM_MIRROR) {
20817 +                       unsigned long end_m = last->vm_start + last->vm_mirror;
20818 +
20819 +                       last_m = find_vma(mm, end_m);
20820 +                       if (!last_m || (!last_m->vm_flags & VM_MIRROR) || last_m->vm_start != end_m)
20821 +                               return -EINVAL;
20822 +                       end_m = end + last->vm_mirror;
20823 +                       if (split_vma(mm, last_m, end_m, 1))
20824 +                               return -ENOMEM;
20825 +               }
20826 +#endif
20827 +
20828                 if (split_vma(mm, last, end, 1))
20829                         return -ENOMEM;
20830         }
20831 @@ -1582,7 +1917,7 @@
20832         /*
20833          * Remove the vma's, and unmap the actual pages
20834          */
20835 -       detach_vmas_to_be_unmapped(mm, mpnt, prev, end);
20836 +       detach_vmas_to_be_unmapped(mm, mpnt, prev, &start, &end);
20837         spin_lock(&mm->page_table_lock);
20838         unmap_region(mm, mpnt, prev, start, end);
20839         spin_unlock(&mm->page_table_lock);
20840 @@ -1590,6 +1925,8 @@
20841         /* Fix up all other VM information */
20842         unmap_vma_list(mm, mpnt);
20843  
20844 +       track_exec_limit(mm, start, end, 0UL);
20845 +
20846         return 0;
20847  }
20848  
20849 @@ -1600,6 +1937,12 @@
20850         int ret;
20851         struct mm_struct *mm = current->mm;
20852  
20853 +#ifdef CONFIG_PAX_SEGMEXEC
20854 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
20855 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
20856 +               return -EINVAL;
20857 +#endif
20858 +
20859         down_write(&mm->mmap_sem);
20860         ret = do_munmap(mm, addr, len);
20861         up_write(&mm->mmap_sem);
20862 @@ -1611,7 +1954,31 @@
20863   *  anonymous maps.  eventually we may be able to do some
20864   *  brk-specific accounting here.
20865   */
20866 +#if defined(CONFIG_PAX_SEGMEXEC) && defined(CONFIG_PAX_MPROTECT)
20867 +unsigned long __do_brk(unsigned long addr, unsigned long len);
20868 +
20869 +unsigned long do_brk(unsigned long addr, unsigned long len)
20870 +{
20871 +       unsigned long ret;
20872 +
20873 +       ret = __do_brk(addr, len);
20874 +       if (ret == addr && (current->flags & (PF_PAX_SEGMEXEC | PF_PAX_MPROTECT)) == PF_PAX_SEGMEXEC) {
20875 +               unsigned long ret_m;
20876 +
20877 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
20878 +               if (ret_m > TASK_SIZE) {
20879 +                       do_munmap(current->mm, addr, len);
20880 +                       ret = ret_m;
20881 +               }
20882 +       }
20883 +
20884 +       return ret;
20885 +}
20886 +
20887 +unsigned long __do_brk(unsigned long addr, unsigned long len)
20888 +#else
20889  unsigned long do_brk(unsigned long addr, unsigned long len)
20890 +#endif
20891  {
20892         struct mm_struct * mm = current->mm;
20893         struct vm_area_struct * vma, * prev;
20894 @@ -1623,6 +1990,13 @@
20895         if (!len)
20896                 return addr;
20897  
20898 +#ifdef CONFIG_PAX_SEGMEXEC
20899 +       if (current->flags & PF_PAX_SEGMEXEC) {
20900 +               if ((addr + len) > SEGMEXEC_TASK_SIZE || (addr + len) < addr)
20901 +                       return -EINVAL;
20902 +       } else
20903 +#endif
20904 +
20905         if ((addr + len) > TASK_SIZE || (addr + len) < addr)
20906                 return -EINVAL;
20907  
20908 @@ -1632,6 +2006,7 @@
20909         if (mm->def_flags & VM_LOCKED) {
20910                 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
20911                 locked += len;
20912 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
20913                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
20914                         return -EAGAIN;
20915         }
20916 @@ -1648,6 +2023,7 @@
20917         }
20918  
20919         /* Check against address space limits *after* clearing old maps... */
20920 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
20921         if ((mm->total_vm << PAGE_SHIFT) + len
20922             > current->rlim[RLIMIT_AS].rlim_cur)
20923                 return -ENOMEM;
20924 @@ -1660,6 +2036,18 @@
20925  
20926         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
20927  
20928 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20929 +       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
20930 +               flags &= ~VM_EXEC;
20931 +
20932 +#ifdef CONFIG_PAX_MPROTECT
20933 +               if (current->flags & PF_PAX_MPROTECT)
20934 +                       flags &= ~VM_MAYEXEC;
20935 +#endif
20936 +
20937 +       }
20938 +#endif
20939 +
20940         /* Can we just expand an old private anonymous mapping? */
20941         if (vma_merge(mm, prev, addr, addr + len, flags,
20942                                         NULL, NULL, pgoff, NULL))
20943 @@ -1680,6 +2068,13 @@
20944         vma->vm_end = addr + len;
20945         vma->vm_pgoff = pgoff;
20946         vma->vm_flags = flags;
20947 +
20948 +#ifdef CONFIG_PAX_PAGEEXEC
20949 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
20950 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
20951 +       else
20952 +#endif
20953 +
20954         vma->vm_page_prot = protection_map[flags & 0x0f];
20955         vma_link(mm, vma, prev, rb_link, rb_parent);
20956  out:
20957 @@ -1688,6 +2083,7 @@
20958                 mm->locked_vm += len >> PAGE_SHIFT;
20959                 make_pages_present(addr, addr + len);
20960         }
20961 +       track_exec_limit(mm, addr, addr + len, flags);
20962         return addr;
20963  }
20964  
20965 diff -uNr linux-2.6.8/mm/mprotect.c linux-2.6.8.grsecurity/mm/mprotect.c
20966 --- linux-2.6.8/mm/mprotect.c   2004-08-14 07:38:11.000000000 +0200
20967 +++ linux-2.6.8.grsecurity/mm/mprotect.c        2004-08-16 18:01:21.000000000 +0200
20968 @@ -18,11 +18,18 @@
20969  #include <linux/security.h>
20970  #include <linux/mempolicy.h>
20971  #include <linux/personality.h>
20972 +#include <linux/grsecurity.h>
20973 +
20974 +#ifdef CONFIG_PAX_MPROTECT
20975 +#include <linux/elf.h>
20976 +#include <linux/fs.h>
20977 +#endif
20978  
20979  #include <asm/uaccess.h>
20980  #include <asm/pgtable.h>
20981  #include <asm/cacheflush.h>
20982  #include <asm/tlbflush.h>
20983 +#include <asm/mmu_context.h>
20984  
20985  static inline void
20986  change_pte_range(pmd_t *pmd, unsigned long address,
20987 @@ -108,6 +115,90 @@
20988         return;
20989  }
20990  
20991 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
20992 +/* called while holding the mmap semaphor for writing */
20993 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
20994 +{
20995 +       struct vm_area_struct *vma = find_vma(mm, start);
20996 +
20997 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
20998 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
20999 +
21000 +}
21001 +
21002 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
21003 +{
21004 +       if (current->flags & PF_PAX_PAGEEXEC) {
21005 +               unsigned long oldlimit, newlimit = 0UL;
21006 +
21007 +               spin_lock(&mm->page_table_lock);
21008 +               oldlimit = mm->context.user_cs_limit;
21009 +               if ((prot & VM_EXEC) && oldlimit < end)
21010 +                       /* USER_CS limit moved up */
21011 +                       newlimit = end;
21012 +               else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
21013 +                       /* USER_CS limit moved down */
21014 +                       newlimit = start;
21015 +
21016 +               if (newlimit) {
21017 +                       mm->context.user_cs_limit = newlimit;
21018 +
21019 +#ifdef CONFIG_SMP
21020 +                       wmb();
21021 +                       cpus_clear(mm->context.cpu_user_cs_mask);
21022 +                       cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
21023 +#endif
21024 +
21025 +                       set_user_cs(mm, smp_processor_id());
21026 +               }
21027 +               spin_unlock(&mm->page_table_lock);
21028 +               if (newlimit == end)
21029 +                       establish_user_cs_limit(mm, oldlimit, end);
21030 +       }
21031 +}
21032 +#endif
21033 +
21034 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21035 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
21036 +       unsigned long start, unsigned long end, unsigned int newflags);
21037 +
21038 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
21039 +       unsigned long start, unsigned long end, unsigned int newflags)
21040 +{
21041 +       if (vma->vm_flags & VM_MIRROR) {
21042 +               struct vm_area_struct * vma_m, * prev_m;
21043 +               unsigned long start_m, end_m;
21044 +               int error;
21045 +
21046 +               start_m = vma->vm_start + vma->vm_mirror;
21047 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
21048 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
21049 +                       start_m = start + vma->vm_mirror;
21050 +                       end_m = end + vma->vm_mirror;
21051 +                       if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC))
21052 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
21053 +                       else
21054 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
21055 +                       if (error)
21056 +                               return error;
21057 +               } else {
21058 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
21059 +                       return -ENOMEM;
21060 +               }
21061 +       }
21062 +
21063 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
21064 +}
21065 +
21066 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
21067 +       unsigned long start, unsigned long end, unsigned int newflags)
21068 +{
21069 +       struct mm_struct * mm = vma->vm_mm;
21070 +       unsigned long charged = 0;
21071 +       pgprot_t newprot;
21072 +       pgoff_t pgoff;
21073 +       int error;
21074 +#else
21075  static int
21076  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
21077         unsigned long start, unsigned long end, unsigned int newflags)
21078 @@ -122,6 +213,7 @@
21079                 *pprev = vma;
21080                 return 0;
21081         }
21082 +#endif
21083  
21084         /*
21085          * If we make a private mapping writable we increase our commit;
21086 @@ -140,6 +232,12 @@
21087                 }
21088         }
21089  
21090 +#ifdef CONFIG_PAX_PAGEEXEC
21091 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
21092 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
21093 +       else
21094 +#endif
21095 +
21096         newprot = protection_map[newflags & 0xf];
21097  
21098         /*
21099 @@ -185,6 +283,69 @@
21100         return error;
21101  }
21102  
21103 +#ifdef CONFIG_PAX_MPROTECT
21104 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
21105 + * therefore we'll grant them VM_MAYWRITE once during their life.
21106 + *
21107 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
21108 + * basis because we want to allow the common case and not the special ones.
21109 + */
21110 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
21111 +{
21112 +       struct elfhdr elf_h;
21113 +       struct elf_phdr elf_p, p_dyn;
21114 +       elf_dyn dyn;
21115 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
21116 +
21117 +#ifndef CONFIG_PAX_NOELFRELOCS
21118 +       if ((vma->vm_start != start) ||
21119 +           !vma->vm_file ||
21120 +           !(vma->vm_flags & VM_MAYEXEC) ||
21121 +           (vma->vm_flags & VM_MAYNOTWRITE))
21122 +#endif
21123 +
21124 +               return;
21125 +
21126 +       if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
21127 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
21128 +
21129 +#ifdef CONFIG_PAX_ETEXECRELOCS
21130 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
21131 +#else
21132 +           elf_h.e_type != ET_DYN ||
21133 +#endif
21134 +
21135 +           !elf_check_arch(&elf_h) ||
21136 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
21137 +           elf_h.e_phnum > j)
21138 +               return;
21139 +
21140 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
21141 +               if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
21142 +                       return;
21143 +               if (elf_p.p_type == PT_DYNAMIC) {
21144 +                       p_dyn = elf_p;
21145 +                       j = i;
21146 +               }
21147 +       }
21148 +       if (elf_h.e_phnum <= j)
21149 +               return;
21150 +
21151 +       i = 0UL;
21152 +       do {
21153 +               if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
21154 +                       return;
21155 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
21156 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
21157 +                       gr_log_textrel(vma);
21158 +                       return;
21159 +               }
21160 +               i++;
21161 +       } while (dyn.d_tag != DT_NULL);
21162 +       return;
21163 +}
21164 +#endif
21165 +
21166  asmlinkage long
21167  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
21168  {
21169 @@ -202,6 +363,17 @@
21170         end = start + len;
21171         if (end < start)
21172                 return -ENOMEM;
21173 +
21174 +#ifdef CONFIG_PAX_SEGMEXEC
21175 +       if (current->flags & PF_PAX_SEGMEXEC) {
21176 +               if (end > SEGMEXEC_TASK_SIZE)
21177 +                       return -EINVAL;
21178 +       } else
21179 +#endif
21180 +
21181 +       if (end > TASK_SIZE)
21182 +               return -EINVAL;
21183 +
21184         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
21185                 return -EINVAL;
21186         if (end == start)
21187 @@ -242,6 +414,16 @@
21188         if (start > vma->vm_start)
21189                 prev = vma;
21190  
21191 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
21192 +               error = -EACCES;
21193 +               goto out;
21194 +       }
21195 +
21196 +#ifdef CONFIG_PAX_MPROTECT
21197 +       if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE))
21198 +               pax_handle_maywrite(vma, start);
21199 +#endif
21200 +
21201         for (nstart = start ; ; ) {
21202                 unsigned int newflags;
21203  
21204 @@ -259,6 +441,12 @@
21205                         goto out;
21206                 }
21207  
21208 +#ifdef CONFIG_PAX_MPROTECT
21209 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
21210 +               if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
21211 +                       newflags &= ~VM_MAYWRITE;
21212 +#endif
21213 +
21214                 error = security_file_mprotect(vma, prot);
21215                 if (error)
21216                         goto out;
21217 @@ -282,6 +470,9 @@
21218                         goto out;
21219                 }
21220         }
21221 +
21222 +       track_exec_limit(current->mm, start, end, vm_flags);
21223 +
21224  out:
21225         up_write(&current->mm->mmap_sem);
21226         return error;
21227 diff -uNr linux-2.6.8/mm/mremap.c linux-2.6.8.grsecurity/mm/mremap.c
21228 --- linux-2.6.8/mm/mremap.c     2004-08-14 07:36:59.000000000 +0200
21229 +++ linux-2.6.8.grsecurity/mm/mremap.c  2004-08-16 17:09:59.000000000 +0200
21230 @@ -128,6 +128,12 @@
21231                         if (dst) {
21232                                 pte_t pte;
21233                                 pte = ptep_clear_flush(vma, old_addr, src);
21234 +
21235 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
21236 +                               if ((current->flags & PF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
21237 +                                       pte_exprotect(pte);
21238 +#endif
21239 +
21240                                 set_pte(dst, pte);
21241                         } else
21242                                 error = -ENOMEM;
21243 @@ -266,6 +272,18 @@
21244         if (!new_len)
21245                 goto out;
21246  
21247 +#ifdef CONFIG_PAX_SEGMEXEC
21248 +       if (current->flags & PF_PAX_SEGMEXEC) {
21249 +               if (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
21250 +                   old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len)
21251 +                       goto out;
21252 +       } else
21253 +#endif
21254 +
21255 +       if (new_len > TASK_SIZE || addr > TASK_SIZE-new_len ||
21256 +           old_len > TASK_SIZE || addr > TASK_SIZE-old_len)
21257 +               goto out;
21258 +
21259         /* new_addr is only valid if MREMAP_FIXED is specified */
21260         if (flags & MREMAP_FIXED) {
21261                 if (new_addr & ~PAGE_MASK)
21262 @@ -273,6 +291,13 @@
21263                 if (!(flags & MREMAP_MAYMOVE))
21264                         goto out;
21265  
21266 +#ifdef CONFIG_PAX_SEGMEXEC
21267 +               if (current->flags & PF_PAX_SEGMEXEC) {
21268 +                       if (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len)
21269 +                               goto out;
21270 +               } else
21271 +#endif
21272 +
21273                 if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
21274                         goto out;
21275  
21276 @@ -316,6 +341,16 @@
21277                 ret = -EINVAL;
21278                 goto out;
21279         }
21280 +
21281 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21282 +       if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
21283 +           (vma->vm_flags & VM_MIRROR))
21284 +       {
21285 +               ret = -EINVAL;
21286 +               goto out;
21287 +       }
21288 +#endif
21289 +
21290         /* We can't remap across vm area boundaries */
21291         if (old_len > vma->vm_end - addr)
21292                 goto out;
21293 @@ -364,6 +399,7 @@
21294                                                    addr + new_len);
21295                         }
21296                         ret = addr;
21297 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
21298                         goto out;
21299                 }
21300         }
21301 @@ -374,8 +410,8 @@
21302          */
21303         ret = -ENOMEM;
21304         if (flags & MREMAP_MAYMOVE) {
21305 +               unsigned long map_flags = 0;
21306                 if (!(flags & MREMAP_FIXED)) {
21307 -                       unsigned long map_flags = 0;
21308                         if (vma->vm_flags & VM_MAYSHARE)
21309                                 map_flags |= MAP_SHARED;
21310  
21311 @@ -385,7 +421,12 @@
21312                         if (new_addr & ~PAGE_MASK)
21313                                 goto out;
21314                 }
21315 +               map_flags = vma->vm_flags;
21316                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
21317 +               if (!(ret & ~PAGE_MASK)) {
21318 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
21319 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
21320 +               }
21321         }
21322  out:
21323         if (ret & ~PAGE_MASK)
21324 diff -uNr linux-2.6.8/mm/rmap.c linux-2.6.8.grsecurity/mm/rmap.c
21325 --- linux-2.6.8/mm/rmap.c       2004-08-14 07:37:42.000000000 +0200
21326 +++ linux-2.6.8.grsecurity/mm/rmap.c    2004-08-16 17:09:59.000000000 +0200
21327 @@ -84,6 +84,19 @@
21328                                 spin_unlock(&anon_vma->lock);
21329                         allocated = NULL;
21330                 }
21331 +
21332 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
21333 +               if (vma->vm_flags & VM_MIRROR) {
21334 +                       struct vm_area_struct *vma_m;
21335 +
21336 +                       vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
21337 +                       BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
21338 +                       BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
21339 +                       vma_m->anon_vma = anon_vma;
21340 +                       __anon_vma_link(vma_m);
21341 +               }
21342 +#endif
21343 +
21344                 spin_unlock(&mm->page_table_lock);
21345                 if (unlikely(allocated))
21346                         anon_vma_free(allocated);
21347 diff -uNr linux-2.6.8/net/ipv4/af_inet.c linux-2.6.8.grsecurity/net/ipv4/af_inet.c
21348 --- linux-2.6.8/net/ipv4/af_inet.c      2004-08-14 07:36:17.000000000 +0200
21349 +++ linux-2.6.8.grsecurity/net/ipv4/af_inet.c   2004-08-16 17:09:59.000000000 +0200
21350 @@ -87,6 +87,7 @@
21351  #include <linux/init.h>
21352  #include <linux/poll.h>
21353  #include <linux/netfilter_ipv4.h>
21354 +#include <linux/grsecurity.h>
21355  
21356  #include <asm/uaccess.h>
21357  #include <asm/system.h>
21358 @@ -320,7 +321,12 @@
21359         else
21360                 inet->pmtudisc = IP_PMTUDISC_WANT;
21361  
21362 -       inet->id = 0;
21363 +#ifdef CONFIG_GRKERNSEC_RANDID
21364 +       if (grsec_enable_randid)
21365 +               inet->id = htons(ip_randomid());
21366 +       else
21367 +#endif
21368 +               inet->id = 0;
21369  
21370         sock_init_data(sock, sk);
21371         sk_set_owner(sk, THIS_MODULE);
21372 diff -uNr linux-2.6.8/net/ipv4/datagram.c linux-2.6.8.grsecurity/net/ipv4/datagram.c
21373 --- linux-2.6.8/net/ipv4/datagram.c     2004-08-14 07:36:09.000000000 +0200
21374 +++ linux-2.6.8.grsecurity/net/ipv4/datagram.c  2004-08-16 18:04:59.000000000 +0200
21375 @@ -63,7 +63,13 @@
21376         inet->daddr = rt->rt_dst;
21377         inet->dport = usin->sin_port;
21378         sk->sk_state = TCP_ESTABLISHED;
21379 -       inet->id = jiffies;
21380 +
21381 +#ifdef CONFIG_GRKERNSEC_RANDID
21382 +       if (grsec_enable_randid)
21383 +               inet->id = htons(ip_randomid());
21384 +       else
21385 +#endif
21386 +               inet->id = jiffies;
21387  
21388         sk_dst_set(sk, &rt->u.dst);
21389         return(0);
21390 diff -uNr linux-2.6.8/net/ipv4/ip_output.c linux-2.6.8.grsecurity/net/ipv4/ip_output.c
21391 --- linux-2.6.8/net/ipv4/ip_output.c    2004-08-14 07:38:08.000000000 +0200
21392 +++ linux-2.6.8.grsecurity/net/ipv4/ip_output.c 2004-08-16 17:10:00.000000000 +0200
21393 @@ -64,6 +64,7 @@
21394  #include <linux/proc_fs.h>
21395  #include <linux/stat.h>
21396  #include <linux/init.h>
21397 +#include <linux/grsecurity.h>
21398  
21399  #include <net/snmp.h>
21400  #include <net/ip.h>
21401 @@ -1147,6 +1148,12 @@
21402         iph->tos = inet->tos;
21403         iph->tot_len = htons(skb->len);
21404         iph->frag_off = df;
21405 +
21406 +#ifdef CONFIG_GRKERNSEC_RANDID
21407 +       if (grsec_enable_randid)
21408 +               iph->id = htons(ip_randomid());
21409 +       else
21410 +#endif
21411         if (!df) {
21412                 __ip_select_ident(iph, &rt->u.dst, 0);
21413         } else {
21414 diff -uNr linux-2.6.8/net/ipv4/netfilter/ipt_stealth.c linux-2.6.8.grsecurity/net/ipv4/netfilter/ipt_stealth.c
21415 --- linux-2.6.8/net/ipv4/netfilter/ipt_stealth.c        1970-01-01 01:00:00.000000000 +0100
21416 +++ linux-2.6.8.grsecurity/net/ipv4/netfilter/ipt_stealth.c     2004-08-16 17:10:00.000000000 +0200
21417 @@ -0,0 +1,112 @@
21418 +/* Kernel module to add stealth support.
21419 + *
21420 + * Copyright (C) 2002 Brad Spengler  <spender@grsecurity.net>
21421 + *
21422 + */
21423 +
21424 +#include <linux/kernel.h>
21425 +#include <linux/module.h>
21426 +#include <linux/skbuff.h>
21427 +#include <linux/net.h>
21428 +#include <linux/sched.h>
21429 +#include <linux/inet.h>
21430 +#include <linux/stddef.h>
21431 +
21432 +#include <net/ip.h>
21433 +#include <net/sock.h>
21434 +#include <net/tcp.h>
21435 +#include <net/udp.h>
21436 +#include <net/route.h>
21437 +#include <net/inet_common.h>
21438 +
21439 +#include <linux/netfilter_ipv4/ip_tables.h>
21440 +
21441 +MODULE_LICENSE("GPL");
21442 +
21443 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
21444 +
21445 +static int
21446 +match(const struct sk_buff *skb,
21447 +      const struct net_device *in,
21448 +      const struct net_device *out,
21449 +      const void *matchinfo,
21450 +      int offset,
21451 +      int *hotdrop)
21452 +{
21453 +       struct iphdr *ip = skb->nh.iph;
21454 +       struct tcphdr th;
21455 +       struct udphdr uh;
21456 +       struct sock *sk = NULL;
21457 +
21458 +       if (!ip || offset) return 0;
21459 +
21460 +       switch(ip->protocol) {
21461 +       case IPPROTO_TCP:
21462 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
21463 +                       *hotdrop = 1;
21464 +                       return 0;
21465 +               }
21466 +               if (!(th.syn && !th.ack)) return 0;
21467 +               sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);     
21468 +               break;
21469 +       case IPPROTO_UDP:
21470 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
21471 +                       *hotdrop = 1;
21472 +                       return 0;
21473 +               }
21474 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
21475 +               break;
21476 +       default:
21477 +               return 0;
21478 +       }
21479 +
21480 +       if(!sk) // port is being listened on, match this
21481 +               return 1;
21482 +       else {
21483 +               sock_put(sk);
21484 +               return 0;
21485 +       }
21486 +}
21487 +
21488 +/* Called when user tries to insert an entry of this type. */
21489 +static int
21490 +checkentry(const char *tablename,
21491 +           const struct ipt_ip *ip,
21492 +           void *matchinfo,
21493 +           unsigned int matchsize,
21494 +           unsigned int hook_mask)
21495 +{
21496 +        if (matchsize != IPT_ALIGN(0))
21497 +                return 0;
21498 +
21499 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
21500 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
21501 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
21502 +                       return 1;
21503 +
21504 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
21505 +
21506 +        return 0;
21507 +}
21508 +
21509 +
21510 +static struct ipt_match stealth_match = {
21511 +       .name = "stealth",
21512 +       .match = &match,
21513 +       .checkentry = &checkentry,
21514 +       .destroy = NULL,
21515 +       .me = THIS_MODULE
21516 +};
21517 +
21518 +static int __init init(void)
21519 +{
21520 +       return ipt_register_match(&stealth_match);
21521 +}
21522 +
21523 +static void __exit fini(void)
21524 +{
21525 +       ipt_unregister_match(&stealth_match);
21526 +}
21527 +
21528 +module_init(init);
21529 +module_exit(fini);
21530 diff -uNr linux-2.6.8/net/ipv4/netfilter/Kconfig linux-2.6.8.grsecurity/net/ipv4/netfilter/Kconfig
21531 --- linux-2.6.8/net/ipv4/netfilter/Kconfig      2004-08-14 07:37:38.000000000 +0200
21532 +++ linux-2.6.8.grsecurity/net/ipv4/netfilter/Kconfig   2004-08-16 17:10:00.000000000 +0200
21533 @@ -225,6 +225,21 @@
21534  
21535           To compile it as a module, choose M here.  If unsure, say N.
21536  
21537 +config IP_NF_MATCH_STEALTH
21538 +       tristate "stealth match support"
21539 +       depends on IP_NF_IPTABLES
21540 +       help
21541 +         Enabling this option will drop all syn packets coming to unserved tcp
21542 +         ports as well as all packets coming to unserved udp ports.  If you
21543 +         are using your system to route any type of packets (ie. via NAT)
21544 +         you should put this module at the end of your ruleset, since it will
21545 +         drop packets that aren't going to ports that are listening on your
21546 +         machine itself, it doesn't take into account that the packet might be
21547 +         destined for someone on your internal network if you're using NAT for
21548 +         instance.
21549 +
21550 +         To compile it as a module, choose M here.  If unsure, say N.
21551 +
21552  config IP_NF_MATCH_HELPER
21553         tristate "Helper match support"
21554         depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
21555 diff -uNr linux-2.6.8/net/ipv4/netfilter/Makefile linux-2.6.8.grsecurity/net/ipv4/netfilter/Makefile
21556 --- linux-2.6.8/net/ipv4/netfilter/Makefile     2004-08-14 07:36:32.000000000 +0200
21557 +++ linux-2.6.8.grsecurity/net/ipv4/netfilter/Makefile  2004-08-16 17:10:00.000000000 +0200
21558 @@ -67,6 +67,8 @@
21559  obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
21560  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
21561  
21562 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
21563 +
21564  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
21565  
21566  # targets
21567 diff -uNr linux-2.6.8/net/ipv4/tcp_ipv4.c linux-2.6.8.grsecurity/net/ipv4/tcp_ipv4.c
21568 --- linux-2.6.8/net/ipv4/tcp_ipv4.c     2004-08-14 07:36:44.000000000 +0200
21569 +++ linux-2.6.8.grsecurity/net/ipv4/tcp_ipv4.c  2004-08-16 17:10:00.000000000 +0200
21570 @@ -62,6 +62,7 @@
21571  #include <linux/jhash.h>
21572  #include <linux/init.h>
21573  #include <linux/times.h>
21574 +#include <linux/grsecurity.h>
21575  
21576  #include <net/icmp.h>
21577  #include <net/tcp.h>
21578 @@ -223,6 +224,10 @@
21579  
21580                 spin_lock(&tcp_portalloc_lock);
21581                 rover = tcp_port_rover;
21582 +#ifdef CONFIG_GRKERNSEC_RANDSRC
21583 +               if (grsec_enable_randsrc && (high > low))
21584 +                       rover = low + (get_random_long() % remaining);
21585 +#endif
21586                 do {
21587                         rover++;
21588                         if (rover < low || rover > high)
21589 @@ -537,6 +542,11 @@
21590  
21591  static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
21592  {
21593 +#ifdef CONFIG_GRKERNSEC_RANDISN
21594 +       if (likely(grsec_enable_randisn))
21595 +               return ip_randomisn();
21596 +       else
21597 +#endif
21598         return secure_tcp_sequence_number(skb->nh.iph->daddr,
21599                                           skb->nh.iph->saddr,
21600                                           skb->h.th->dest,
21601 @@ -669,12 +679,15 @@
21602                  */
21603                 spin_lock(&tcp_portalloc_lock);
21604                 rover = tcp_port_rover;
21605 -
21606 +#ifdef CONFIG_GRKERNSEC_RANDSRC
21607 +               if (grsec_enable_randsrc && (high > low))
21608 +                       rover = low + (get_random_long() % remaining);
21609 +#endif
21610                 do {
21611                         rover++;
21612                         if ((rover < low) || (rover > high))
21613                                 rover = low;
21614 -                       head = &tcp_bhash[tcp_bhashfn(rover)];
21615 +                       head = &tcp_bhash[tcp_bhashfn(rover)];
21616                         spin_lock(&head->lock);
21617  
21618                         /* Does not bother with rcv_saddr checks,
21619 @@ -724,6 +737,15 @@
21620                 }
21621                 spin_unlock(&head->lock);
21622  
21623 +#ifdef CONFIG_GRKERNSEC
21624 +               gr_del_task_from_ip_table(current);
21625 +               current->gr_saddr = inet_sk(sk)->rcv_saddr;
21626 +               current->gr_daddr = inet_sk(sk)->daddr;
21627 +               current->gr_sport = inet_sk(sk)->sport;
21628 +               current->gr_dport = inet_sk(sk)->dport;
21629 +               gr_add_to_task_ip_table(current);
21630 +#endif
21631 +
21632                 if (tw) {
21633                         tcp_tw_deschedule(tw);
21634                         tcp_tw_put(tw);
21635 @@ -843,13 +865,24 @@
21636         tcp_v4_setup_caps(sk, &rt->u.dst);
21637         tp->ext2_header_len = rt->u.dst.header_len;
21638  
21639 -       if (!tp->write_seq)
21640 +       if (!tp->write_seq) {
21641 +#ifdef CONFIG_GRKERNSEC_RANDISN
21642 +               if (likely(grsec_enable_randisn))
21643 +                       tp->write_seq = ip_randomisn();
21644 +               else
21645 +#endif
21646                 tp->write_seq = secure_tcp_sequence_number(inet->saddr,
21647                                                            inet->daddr,
21648                                                            inet->sport,
21649                                                            usin->sin_port);
21650 +       }
21651  
21652 -       inet->id = tp->write_seq ^ jiffies;
21653 +#ifdef CONFIG_GRKERNSEC_RANDID
21654 +       if (grsec_enable_randid)
21655 +               inet->id = htons(ip_randomid());
21656 +       else
21657 +#endif
21658 +               inet->id = tp->write_seq ^ jiffies;
21659  
21660         err = tcp_connect(sk);
21661         rt = NULL;
21662 @@ -1593,7 +1626,13 @@
21663         if (newinet->opt)
21664                 newtp->ext_header_len = newinet->opt->optlen;
21665         newtp->ext2_header_len = dst->header_len;
21666 -       newinet->id = newtp->write_seq ^ jiffies;
21667 +
21668 +#ifdef CONFIG_GRKERNSEC_RANDID
21669 +       if (grsec_enable_randid)
21670 +               newinet->id = htons(ip_randomid());
21671 +       else
21672 +#endif
21673 +               newinet->id = newtp->write_seq ^ jiffies;
21674  
21675         tcp_sync_mss(newsk, dst_pmtu(dst));
21676         newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
21677 diff -uNr linux-2.6.8/net/ipv4/udp.c linux-2.6.8.grsecurity/net/ipv4/udp.c
21678 --- linux-2.6.8/net/ipv4/udp.c  2004-08-14 07:36:17.000000000 +0200
21679 +++ linux-2.6.8.grsecurity/net/ipv4/udp.c       2004-08-16 17:10:00.000000000 +0200
21680 @@ -100,6 +100,7 @@
21681  #include <linux/skbuff.h>
21682  #include <linux/proc_fs.h>
21683  #include <linux/seq_file.h>
21684 +#include <linux/grsecurity.h>
21685  #include <net/sock.h>
21686  #include <net/udp.h>
21687  #include <net/icmp.h>
21688 @@ -108,6 +109,12 @@
21689  #include <net/checksum.h>
21690  #include <net/xfrm.h>
21691  
21692 +extern int gr_search_udp_recvmsg(const struct sock *sk,
21693 +                                const struct sk_buff *skb);
21694 +extern int gr_search_udp_sendmsg(const struct sock *sk,
21695 +                                const struct sockaddr_in *addr);
21696 +
21697 +
21698  /*
21699   *     Snmp MIB for the UDP layer
21700   */
21701 @@ -538,9 +545,16 @@
21702                 dport = usin->sin_port;
21703                 if (dport == 0)
21704                         return -EINVAL;
21705 +
21706 +               if (!gr_search_udp_sendmsg(sk, usin))
21707 +                       return -EPERM;
21708         } else {
21709                 if (sk->sk_state != TCP_ESTABLISHED)
21710                         return -EDESTADDRREQ;
21711 +
21712 +               if (!gr_search_udp_sendmsg(sk, NULL))
21713 +                       return -EPERM;
21714 +
21715                 daddr = inet->daddr;
21716                 dport = inet->dport;
21717                 /* Open fast path for connected socket.
21718 @@ -792,7 +806,12 @@
21719         if (!skb)
21720                 goto out;
21721    
21722 -       copied = skb->len - sizeof(struct udphdr);
21723 +       if (!gr_search_udp_recvmsg(sk, skb)) {
21724 +               err = -EPERM;
21725 +               goto out_free;
21726 +       }
21727 +
21728 +       copied = skb->len - sizeof(struct udphdr);
21729         if (copied > len) {
21730                 copied = len;
21731                 msg->msg_flags |= MSG_TRUNC;
21732 diff -uNr linux-2.6.8/net/socket.c linux-2.6.8.grsecurity/net/socket.c
21733 --- linux-2.6.8/net/socket.c    2004-08-14 07:36:45.000000000 +0200
21734 +++ linux-2.6.8.grsecurity/net/socket.c 2004-08-16 17:10:00.000000000 +0200
21735 @@ -81,6 +81,7 @@
21736  #include <linux/syscalls.h>
21737  #include <linux/compat.h>
21738  #include <linux/kmod.h>
21739 +#include <linux/in.h>
21740  
21741  #ifdef CONFIG_NET_RADIO
21742  #include <linux/wireless.h>            /* Note : will define WIRELESS_EXT */
21743 @@ -94,6 +95,18 @@
21744  #include <net/sock.h>
21745  #include <linux/netfilter.h>
21746  
21747 +extern void gr_attach_curr_ip(const struct sock *sk);
21748 +extern int gr_handle_sock_all(const int family, const int type,
21749 +                             const int protocol);
21750 +extern int gr_handle_sock_server(const struct sockaddr *sck);
21751 +extern int gr_handle_sock_client(const struct sockaddr *sck);
21752 +extern int gr_search_connect(const struct socket * sock,
21753 +                            const struct sockaddr_in * addr);
21754 +extern int gr_search_bind(const struct socket * sock,
21755 +                          const struct sockaddr_in * addr);
21756 +extern int gr_search_socket(const int domain, const int type,
21757 +                           const int protocol);
21758 +
21759  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
21760  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
21761                          size_t size, loff_t pos);
21762 @@ -960,6 +973,7 @@
21763                 printk(KERN_DEBUG "sock_close: NULL inode\n");
21764                 return 0;
21765         }
21766 +
21767         sock_fasync(-1, filp, 0);
21768         sock_release(SOCKET_I(inode));
21769         return 0;
21770 @@ -1189,6 +1203,16 @@
21771         int retval;
21772         struct socket *sock;
21773  
21774 +       if(!gr_search_socket(family, type, protocol)) {
21775 +               retval = -EACCES;
21776 +               goto out;
21777 +       }
21778 +
21779 +       if (gr_handle_sock_all(family, type, protocol)) {
21780 +               retval = -EACCES;
21781 +               goto out;
21782 +       }
21783 +
21784         retval = sock_create(family, type, protocol, &sock);
21785         if (retval < 0)
21786                 goto out;
21787 @@ -1284,11 +1308,23 @@
21788  {
21789         struct socket *sock;
21790         char address[MAX_SOCK_ADDR];
21791 +       struct sockaddr *sck;
21792         int err;
21793  
21794         if((sock = sockfd_lookup(fd,&err))!=NULL)
21795         {
21796                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
21797 +                       sck = (struct sockaddr *)address;
21798 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck)) {
21799 +                               sockfd_put(sock);
21800 +                               return -EACCES;
21801 +                       }
21802 +
21803 +                       if (gr_handle_sock_server(sck)) {
21804 +                               sockfd_put(sock);
21805 +                               return -EACCES;
21806 +                       }
21807 +
21808                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
21809                         if (err) {
21810                                 sockfd_put(sock);
21811 @@ -1391,6 +1427,7 @@
21812                 goto out_release;
21813  
21814         security_socket_post_accept(sock, newsock);
21815 +       gr_attach_curr_ip(newsock->sk);
21816  
21817  out_put:
21818         sockfd_put(sock);
21819 @@ -1418,6 +1455,7 @@
21820  {
21821         struct socket *sock;
21822         char address[MAX_SOCK_ADDR];
21823 +       struct sockaddr *sck;
21824         int err;
21825  
21826         sock = sockfd_lookup(fd, &err);
21827 @@ -1427,6 +1465,18 @@
21828         if (err < 0)
21829                 goto out_put;
21830  
21831 +       sck = (struct sockaddr *)address;
21832 +
21833 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck)) {
21834 +               err = -EACCES;
21835 +               goto out_put;
21836 +       }
21837 +
21838 +       if (gr_handle_sock_client(sck)) {
21839 +               err = -EACCES;
21840 +               goto out_put;
21841 +       }
21842 +
21843         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
21844         if (err)
21845                 goto out_put;
21846 @@ -1680,6 +1730,7 @@
21847                 err=sock->ops->shutdown(sock, how);
21848                 sockfd_put(sock);
21849         }
21850 +
21851         return err;
21852  }
21853  
21854 diff -uNr linux-2.6.8/net/sunrpc/xprt.c linux-2.6.8.grsecurity/net/sunrpc/xprt.c
21855 --- linux-2.6.8/net/sunrpc/xprt.c       2004-08-14 07:37:26.000000000 +0200
21856 +++ linux-2.6.8.grsecurity/net/sunrpc/xprt.c    2004-08-16 17:10:00.000000000 +0200
21857 @@ -58,6 +58,7 @@
21858  #include <linux/file.h>
21859  #include <linux/workqueue.h>
21860  #include <linux/random.h>
21861 +#include <linux/grsecurity.h>
21862  
21863  #include <net/sock.h>
21864  #include <net/checksum.h>
21865 @@ -1337,6 +1338,12 @@
21866   */
21867  static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
21868  {
21869 +
21870 +#ifdef CONFIG_GRKERNSEC_RANDRPC
21871 +       if (grsec_enable_randrpc)
21872 +               return (u32) get_random_long();
21873 +#endif
21874 +
21875         return xprt->xid++;
21876  }
21877  
21878 diff -uNr linux-2.6.8/net/unix/af_unix.c linux-2.6.8.grsecurity/net/unix/af_unix.c
21879 --- linux-2.6.8/net/unix/af_unix.c      2004-08-14 07:37:15.000000000 +0200
21880 +++ linux-2.6.8.grsecurity/net/unix/af_unix.c   2004-08-16 17:10:00.000000000 +0200
21881 @@ -118,6 +118,7 @@
21882  #include <linux/mount.h>
21883  #include <net/checksum.h>
21884  #include <linux/security.h>
21885 +#include <linux/grsecurity.h>
21886  
21887  int sysctl_unix_max_dgram_qlen = 10;
21888  
21889 @@ -681,6 +682,11 @@
21890                 if (err)
21891                         goto put_fail;
21892  
21893 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
21894 +                       err = -EACCES;
21895 +                       goto put_fail;
21896 +               }
21897 +
21898                 err = -ECONNREFUSED;
21899                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
21900                         goto put_fail;
21901 @@ -704,6 +710,13 @@
21902                 if (u) {
21903                         struct dentry *dentry;
21904                         dentry = unix_sk(u)->dentry;
21905 +
21906 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
21907 +                               err = -EPERM;
21908 +                               sock_put(u);
21909 +                               goto fail;
21910 +                       }
21911 +
21912                         if (dentry)
21913                                 touch_atime(unix_sk(u)->mnt, dentry);
21914                 } else
21915 @@ -803,9 +816,18 @@
21916                  */
21917                 mode = S_IFSOCK |
21918                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
21919 +
21920 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
21921 +                       err = -EACCES;
21922 +                       goto out_mknod_dput;
21923 +               }
21924 +
21925                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
21926                 if (err)
21927                         goto out_mknod_dput;
21928 +
21929 +               gr_handle_create(dentry, nd.mnt);
21930 +
21931                 up(&nd.dentry->d_inode->i_sem);
21932                 dput(nd.dentry);
21933                 nd.dentry = dentry;
21934 @@ -823,6 +845,10 @@
21935                         goto out_unlock;
21936                 }
21937  
21938 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
21939 +               sk->sk_peercred.pid = current->pid;
21940 +#endif
21941 +
21942                 list = &unix_socket_table[addr->hash];
21943         } else {
21944                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
21945 diff -uNr linux-2.6.8/security/commoncap.c linux-2.6.8.grsecurity/security/commoncap.c
21946 --- linux-2.6.8/security/commoncap.c    2004-08-14 07:36:56.000000000 +0200
21947 +++ linux-2.6.8.grsecurity/security/commoncap.c 2004-08-16 17:10:00.000000000 +0200
21948 @@ -23,11 +23,12 @@
21949  #include <linux/ptrace.h>
21950  #include <linux/xattr.h>
21951  #include <linux/hugetlb.h>
21952 +#include <linux/grsecurity.h>
21953  
21954  int cap_capable (struct task_struct *tsk, int cap)
21955  {
21956         /* Derived from include/linux/sched.h:capable. */
21957 -       if (cap_raised (tsk->cap_effective, cap))
21958 +       if (cap_raised (tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
21959                 return 0;
21960         else
21961                 return -EPERM;
21962 @@ -37,7 +38,7 @@
21963  {
21964         /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
21965         if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
21966 -           !capable (CAP_SYS_PTRACE))
21967 +           !capable_nolog (CAP_SYS_PTRACE))
21968                 return -EPERM;
21969         else
21970                 return 0;
21971 @@ -141,8 +142,11 @@
21972                 }
21973         }
21974  
21975 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
21976 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
21977 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
21978 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
21979 +
21980 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
21981 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
21982  
21983         /* For init, we want to retain the capabilities set
21984          * in the init_task struct. Thus we skip the usual
21985 @@ -153,6 +157,8 @@
21986                     cap_intersect (new_permitted, bprm->cap_effective);
21987         }
21988  
21989 +       gr_handle_chroot_caps(current);
21990 +
21991         /* AUD: Audit candidate if current->cap_effective is set */
21992  
21993         current->keep_capabilities = 0;
21994 @@ -334,7 +340,7 @@
21995                 /*
21996                  * Leave the last 3% for root
21997                  */
21998 -               if (!capable(CAP_SYS_ADMIN))
21999 +               if (!capable_nolog(CAP_SYS_ADMIN))
22000                         free -= free / 32;
22001  
22002                 if (free > pages)
22003 @@ -345,7 +351,7 @@
22004                  * only call if we're about to fail.
22005                  */
22006                 n = nr_free_pages();
22007 -               if (!capable(CAP_SYS_ADMIN))
22008 +               if (!capable_nolog(CAP_SYS_ADMIN))
22009                         n -= n / 32;
22010                 free += n;
22011  
22012 diff -uNr linux-2.6.8/security/dummy.c linux-2.6.8.grsecurity/security/dummy.c
22013 --- linux-2.6.8/security/dummy.c        2004-08-14 07:36:32.000000000 +0200
22014 +++ linux-2.6.8.grsecurity/security/dummy.c     2004-08-16 17:10:00.000000000 +0200
22015 @@ -28,6 +28,7 @@
22016  #include <linux/hugetlb.h>
22017  #include <linux/ptrace.h>
22018  #include <linux/file.h>
22019 +#include <linux/grsecurity.h>
22020  
22021  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
22022  {
22023 @@ -182,8 +183,11 @@
22024                 }
22025         }
22026  
22027 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
22028 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
22029 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
22030 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
22031 +
22032 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
22033 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
22034  }
22035  
22036  static int dummy_bprm_set_security (struct linux_binprm *bprm)
22037 diff -uNr linux-2.6.8/security/Kconfig linux-2.6.8.grsecurity/security/Kconfig
22038 --- linux-2.6.8/security/Kconfig        2004-08-14 07:37:26.000000000 +0200
22039 +++ linux-2.6.8.grsecurity/security/Kconfig     2004-08-16 17:10:00.000000000 +0200
22040 @@ -2,6 +2,8 @@
22041  # Security configuration
22042  #
22043  
22044 +source grsecurity/Kconfig
22045 +
22046  menu "Security options"
22047  
22048  config SECURITY
22049 diff -uNr linux-2.6.8/security/security.c linux-2.6.8.grsecurity/security/security.c
22050 --- linux-2.6.8/security/security.c     2004-08-14 07:36:11.000000000 +0200
22051 +++ linux-2.6.8.grsecurity/security/security.c  2004-08-16 17:10:00.000000000 +0200
22052 @@ -206,4 +206,5 @@
22053  EXPORT_SYMBOL_GPL(mod_reg_security);
22054  EXPORT_SYMBOL_GPL(mod_unreg_security);
22055  EXPORT_SYMBOL(capable);
22056 +EXPORT_SYMBOL(capable_nolog);
22057  EXPORT_SYMBOL(security_ops);
This page took 1.793814 seconds and 3 git commands to generate.