]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.0-2.6.6-unofficial.patch
- update for cset 20040707_...
[packages/kernel.git] / grsecurity-2.0-2.6.6-unofficial.patch
1 diff -uNr linux-2.6.6/arch/alpha/kernel/osf_sys.c linux-2.6.6.fixed/arch/alpha/kernel/osf_sys.c
2 --- linux-2.6.6/arch/alpha/kernel/osf_sys.c     2004-05-10 04:31:55.000000000 +0200
3 +++ linux-2.6.6.fixed/arch/alpha/kernel/osf_sys.c       2004-05-11 10:55:55.000000000 +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 @@ -1292,6 +1305,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 @@ -1299,8 +1316,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.6/arch/alpha/kernel/ptrace.c linux-2.6.6.fixed/arch/alpha/kernel/ptrace.c
69 --- linux-2.6.6/arch/alpha/kernel/ptrace.c      2004-05-10 04:33:19.000000000 +0200
70 +++ linux-2.6.6.fixed/arch/alpha/kernel/ptrace.c        2004-05-11 10:55:55.000000000 +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.6/arch/alpha/mm/fault.c linux-2.6.6.fixed/arch/alpha/mm/fault.c
90 --- linux-2.6.6/arch/alpha/mm/fault.c   2004-05-10 04:32:27.000000000 +0200
91 +++ linux-2.6.6.fixed/arch/alpha/mm/fault.c     2004-05-11 10:55:55.000000000 +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.6/arch/i386/Kconfig linux-2.6.6.fixed/arch/i386/Kconfig
280 --- linux-2.6.6/arch/i386/Kconfig       2004-05-10 04:32:01.000000000 +0200
281 +++ linux-2.6.6.fixed/arch/i386/Kconfig 2004-05-11 10:55:55.000000000 +0200
282 @@ -394,7 +394,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.6/arch/i386/kernel/apm.c linux-2.6.6.fixed/arch/i386/kernel/apm.c
292 --- linux-2.6.6/arch/i386/kernel/apm.c  2004-05-10 04:31:59.000000000 +0200
293 +++ linux-2.6.6.fixed/arch/i386/kernel/apm.c    2004-05-11 10:55:55.000000000 +0200
294 @@ -597,19 +597,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 @@ -639,20 +660,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.6/arch/i386/kernel/cpu/common.c linux-2.6.6.fixed/arch/i386/kernel/cpu/common.c
377 --- linux-2.6.6/arch/i386/kernel/cpu/common.c   2004-05-10 04:31:59.000000000 +0200
378 +++ linux-2.6.6.fixed/arch/i386/kernel/cpu/common.c     2004-05-11 10:55:55.000000000 +0200
379 @@ -320,6 +320,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 @@ -515,7 +519,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.6/arch/i386/kernel/entry.S linux-2.6.6.fixed/arch/i386/kernel/entry.S
400 --- linux-2.6.6/arch/i386/kernel/entry.S        2004-05-10 04:32:26.000000000 +0200
401 +++ linux-2.6.6.fixed/arch/i386/kernel/entry.S  2004-05-11 10:55:55.000000000 +0200
402 @@ -272,6 +272,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 @@ -299,6 +304,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 @@ -591,7 +601,13 @@
427         jmp error_code
428  
429  ENTRY(page_fault)
430 +#ifdef CONFIG_PAX_PAGEEXEC
431 +       ALIGN
432 +       pushl $pax_do_page_fault
433 +#else
434         pushl $do_page_fault
435 +#endif
436 +
437         jmp error_code
438  
439  #ifdef CONFIG_X86_MCE
440 @@ -606,7 +622,7 @@
441         pushl $do_spurious_interrupt_bug
442         jmp error_code
443  
444 -.data
445 +.section .rodata,"a",@progbits
446  ENTRY(sys_call_table)
447         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
448         .long sys_exit
449 diff -uNr linux-2.6.6/arch/i386/kernel/head.S linux-2.6.6.fixed/arch/i386/kernel/head.S
450 --- linux-2.6.6/arch/i386/kernel/head.S.orig    2004-05-10 04:32:00.000000000 +0200
451 +++ linux-2.6.6/arch/i386/kernel/head.S 2004-05-11 14:05:55.000000000 +0200
452 @@ -49,6 +49,12 @@
453  
454  
455  /*
456 + * Real beginning of normal "text" segment
457 + */
458 +ENTRY(stext)
459 +ENTRY(_stext)
460 +
461 +/*
462   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
463   * %esi points to the real-mode code as a 32-bit pointer.
464   * CS and DS must be 4 GB flat segments, but we don't depend on
465 @@ -93,9 +99,9 @@
466  
467         movl $(pg0 - __PAGE_OFFSET), %edi
468         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
469 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
470 +       movl $0x067, %eax                       /* 0x067 = DIRTY+ACCESSED+PRESENT+RW+USER */
471  10:
472 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
473 +       leal 0x067(%edi),%ecx                   /* Create PDE entry */
474         movl %ecx,(%edx)                        /* Store identity PDE entry */
475         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
476         addl $4,%edx
477 @@ -105,8 +111,8 @@
478         addl $0x1000,%eax
479         loop 11b
480         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
481 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
482 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
483 +       /* bytes beyond the end of our own page tables; the +0x067 is the attribute bits */
484 +       leal (INIT_MAP_BEYOND_END+0x067)(%edi),%ebp
485         cmpl %ebp,%eax
486         jb 10b
487         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
488 @@ -165,7 +171,7 @@
489         movl %cr0,%eax
490         orl $0x80000000,%eax
491         movl %eax,%cr0          /* ..and set paging (PG) bit */
492 -       ljmp $__BOOT_CS,$1f     /* Clear prefetch and normalize %eip */
493 +       ljmp $__BOOT_CS,$1f + __KERNEL_TEXT_OFFSET      /* Clear prefetch and normalize %eip */
494  1:
495         /* Set up the stack pointer */
496         lss stack_start,%esp
497 @@ -380,31 +386,52 @@
498         iret
499  
500  /*
501 - * Real beginning of normal "text" segment
502 + * This starts the data section. Note that the above is all
503 + * in the text section because it has alignment requirements
504 + * that we cannot fulfill any other way except for PaX ;-).
505   */
506 -ENTRY(stext)
507 -ENTRY(_stext)
508 +.data
509 +ready: .byte 0
510  
511  /*
512 - * BSS section
513 + * swapper_pg_dir is the main page directory, address 0x00101000
514 + *
515 + * This is initialized to create an identity-mapping at 0 (for bootup
516 + * purposes) and another mapping at virtual address PAGE_OFFSET.  The
517 + * values put here should be all invalid (zero); the valid
518 + * entries are created dynamically at boot time.
519 + *
520 + * The code creates enough page tables to map 0-_end, the page tables
521 + * themselves, plus INIT_MAP_BEYOND_END bytes; see comment at beginning.
522   */
523 -.section ".bss.page_aligned","w"
524 +.section .data.swapper_pg_dir,"a",@progbits
525  ENTRY(swapper_pg_dir)
526         .fill 1024,4,0
527 +
528 +#ifdef CONFIG_PAX_KERNEXEC
529 +ENTRY(kernexec_pg_dir)
530 +       .fill 1024,4,0
531 +#endif
532 +
533 +.section .rodata.empty_zero_page,"a",@progbits
534  ENTRY(empty_zero_page)
535         .fill 4096,1,0
536  
537  /*
538 - * This starts the data section.
539 - */
540 -.data
541 + * The IDT has to be page-aligned to simplify the Pentium
542 + * F0 0F bug workaround.. We have a special link segment
543 + * for this.
544 + */
545 +.section .rodata.idt,"a",@progbits
546 +ENTRY(idt_table)
547 +       .fill 256,8,0
548  
549 +.section .rodata,"a",@progbits
550  ENTRY(stack_start)
551         .long init_thread_union+THREAD_SIZE
552         .long __BOOT_DS
553  
554 -ready: .byte 0
555 -
556 +/* This is the default interrupt "handler" :-) */
557  int_msg:
558         .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
559  
560 @@ -446,8 +473,8 @@
561         .align L1_CACHE_BYTES
562  ENTRY(boot_gdt_table)
563         .fill GDT_ENTRY_BOOT_CS,8,0
564 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
565 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
566 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
567 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
568  
569  /*
570   * The Global Descriptor Table contains 28 quadwords, per-CPU.
571 @@ -458,7 +485,13 @@
572         .quad 0x0000000000000000        /* 0x0b reserved */
573         .quad 0x0000000000000000        /* 0x13 reserved */
574         .quad 0x0000000000000000        /* 0x1b reserved */
575 +
576 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
577 +       .quad 0x00cf9b000000ffff        /* 0x20 kernel 4GB code at 0x00000000 */
578 +#else
579         .quad 0x0000000000000000        /* 0x20 unused */
580 +#endif
581 +
582         .quad 0x0000000000000000        /* 0x28 unused */
583         .quad 0x0000000000000000        /* 0x33 TLS entry 1 */
584         .quad 0x0000000000000000        /* 0x3b TLS entry 2 */
585 @@ -467,27 +500,32 @@
586         .quad 0x0000000000000000        /* 0x53 reserved */
587         .quad 0x0000000000000000        /* 0x5b reserved */
588  
589 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
590 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
591 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
592 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
593 +#ifdef CONFIG_PAX_KERNEXEC
594 +       .quad 0xc0cf9b400000ffff        /* 0x60 kernel 4GB code at 0xc0400000 */
595 +#else
596 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
597 +#endif
598 +
599 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
600 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
601 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
602  
603         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
604         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
605  
606         /* Segments used for calling PnP BIOS */
607 -       .quad 0x00c09a0000000000        /* 0x90 32-bit code */
608 -       .quad 0x00809a0000000000        /* 0x98 16-bit code */
609 -       .quad 0x0080920000000000        /* 0xa0 16-bit data */
610 -       .quad 0x0080920000000000        /* 0xa8 16-bit data */
611 -       .quad 0x0080920000000000        /* 0xb0 16-bit data */
612 +       .quad 0x00c09b0000000000        /* 0x90 32-bit code */
613 +       .quad 0x00809b0000000000        /* 0x98 16-bit code */
614 +       .quad 0x0080930000000000        /* 0xa0 16-bit data */
615 +       .quad 0x0080930000000000        /* 0xa8 16-bit data */
616 +       .quad 0x0080930000000000        /* 0xb0 16-bit data */
617         /*
618          * The APM segments have byte granularity and their bases
619          * and limits are set at run time.
620          */
621 -       .quad 0x00409a0000000000        /* 0xb8 APM CS    code */
622 -       .quad 0x00009a0000000000        /* 0xc0 APM CS 16 code (16 bit) */
623 -       .quad 0x0040920000000000        /* 0xc8 APM DS    data */
624 +       .quad 0x00409b0000000000        /* 0xb8 APM CS    code */
625 +       .quad 0x00009b0000000000        /* 0xc0 APM CS 16 code (16 bit) */
626 +       .quad 0x0040930000000000        /* 0xc8 APM DS    data */
627  
628         .quad 0x0000000000000000        /* 0xd0 - unused */
629         .quad 0x0000000000000000        /* 0xd8 - unused */
630 diff -uNr linux-2.6.6/arch/i386/kernel/ioport.c linux-2.6.6.fixed/arch/i386/kernel/ioport.c
631 --- linux-2.6.6/arch/i386/kernel/ioport.c       2004-05-10 04:32:29.000000000 +0200
632 +++ linux-2.6.6.fixed/arch/i386/kernel/ioport.c 2004-05-11 10:55:55.000000000 +0200
633 @@ -15,6 +15,7 @@
634  #include <linux/stddef.h>
635  #include <linux/slab.h>
636  #include <linux/thread_info.h>
637 +#include <linux/grsecurity.h>
638  
639  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
640  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
641 @@ -62,9 +63,16 @@
642  
643         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
644                 return -EINVAL;
645 +#ifdef CONFIG_GRKERNSEC_IO
646 +       if (turn_on) {
647 +               gr_handle_ioperm();
648 +#else
649         if (turn_on && !capable(CAP_SYS_RAWIO))
650 +#endif
651                 return -EPERM;
652 -
653 +#ifdef CONFIG_GRKERNSEC_IO
654 +       }
655 +#endif
656         /*
657          * If it's the first ioperm() call in this thread's lifetime, set the
658          * IO bitmap up. ioperm() is much less timing critical than clone(),
659 @@ -115,8 +123,13 @@
660                 return -EINVAL;
661         /* Trying to gain more privileges? */
662         if (level > old) {
663 +#ifdef CONFIG_GRKERNSEC_IO
664 +               gr_handle_iopl();
665 +               return -EPERM;
666 +#else
667                 if (!capable(CAP_SYS_RAWIO))
668                         return -EPERM;
669 +#endif
670         }
671         regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
672         /* Make sure we return the long way (not sysenter) */
673 diff -uNr linux-2.6.6/arch/i386/kernel/ldt.c linux-2.6.6.fixed/arch/i386/kernel/ldt.c
674 --- linux-2.6.6/arch/i386/kernel/ldt.c  2004-05-10 04:32:54.000000000 +0200
675 +++ linux-2.6.6.fixed/arch/i386/kernel/ldt.c    2004-05-11 10:55:55.000000000 +0200
676 @@ -154,7 +154,7 @@
677  {
678         int err;
679         unsigned long size;
680 -       void *address;
681 +       const void *address;
682  
683         err = 0;
684         address = &default_ldt[0];
685 @@ -211,6 +211,13 @@
686                 }
687         }
688  
689 +#ifdef CONFIG_PAX_SEGMEXEC
690 +       if ((current->flags & PF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) {
691 +               error = -EINVAL;
692 +               goto out_unlock;
693 +       }
694 +#endif
695 +
696         entry_1 = LDT_entry_a(&ldt_info);
697         entry_2 = LDT_entry_b(&ldt_info);
698         if (oldmode)
699 diff -uNr linux-2.6.6/arch/i386/kernel/process.c linux-2.6.6.fixed/arch/i386/kernel/process.c
700 --- linux-2.6.6/arch/i386/kernel/process.c      2004-05-10 04:31:54.000000000 +0200
701 +++ linux-2.6.6.fixed/arch/i386/kernel/process.c        2004-05-11 10:55:55.000000000 +0200
702 @@ -348,7 +348,7 @@
703         struct task_struct *tsk;
704         int err;
705  
706 -       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
707 +       childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info - sizeof(unsigned long))) - 1;
708         struct_cpy(childregs, regs);
709         childregs->eax = 0;
710         childregs->esp = esp;
711 @@ -450,9 +450,8 @@
712  int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
713  {
714         struct pt_regs ptregs;
715 -       
716 -       ptregs = *(struct pt_regs *)
717 -               ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs));
718 +
719 +       ptregs = *(struct pt_regs *)(tsk->thread.esp0 - sizeof(ptregs));
720         ptregs.xcs &= 0xffff;
721         ptregs.xds &= 0xffff;
722         ptregs.xes &= 0xffff;
723 @@ -505,10 +504,22 @@
724         int cpu = smp_processor_id();
725         struct tss_struct *tss = init_tss + cpu;
726  
727 +#ifdef CONFIG_PAX_KERNEXEC
728 +       unsigned long flags, cr3;
729 +#endif
730 +
731         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
732  
733         __unlazy_fpu(prev_p);
734  
735 +#ifdef CONFIG_PAX_KERNEXEC
736 +       pax_open_kernel(flags, cr3);
737 +#endif
738 +
739 +#ifdef CONFIG_PAX_SEGMEXEC
740 +       pax_switch_segments(next_p, cpu);
741 +#endif
742 +
743         /*
744          * Reload esp0, LDT and the page table pointer:
745          */
746 @@ -519,6 +530,10 @@
747          */
748         load_TLS(next, cpu);
749  
750 +#ifdef CONFIG_PAX_KERNEXEC
751 +       pax_close_kernel(flags, cr3);
752 +#endif
753 +
754         /*
755          * Save away %fs and %gs. No need to save %es and %ds, as
756          * those are always kernel segments while inside the kernel.
757 @@ -691,6 +706,10 @@
758         struct desc_struct *desc;
759         int cpu, idx;
760  
761 +#ifdef CONFIG_PAX_KERNEXEC
762 +       unsigned long flags, cr3;
763 +#endif
764 +
765         if (copy_from_user(&info, u_info, sizeof(info)))
766                 return -EFAULT;
767         idx = info.entry_number;
768 @@ -724,8 +743,17 @@
769                 desc->a = LDT_entry_a(&info);
770                 desc->b = LDT_entry_b(&info);
771         }
772 +
773 +#ifdef CONFIG_PAX_KERNEXEC
774 +       pax_open_kernel(flags, cr3);
775 +#endif
776 +
777         load_TLS(t, cpu);
778  
779 +#ifdef CONFIG_PAX_KERNEXEC
780 +       pax_close_kernel(flags, cr3);
781 +#endif
782 +
783         put_cpu();
784  
785         return 0;
786 @@ -779,3 +807,29 @@
787         return 0;
788  }
789  
790 +#ifdef CONFIG_PAX_RANDKSTACK
791 +asmlinkage void pax_randomize_kstack(void)
792 +{
793 +       struct tss_struct *tss = init_tss + smp_processor_id();
794 +       unsigned long time;
795 +
796 +#ifdef CONFIG_PAX_SOFTMODE
797 +       if (!pax_aslr)
798 +               return;
799 +#endif
800 +
801 +       rdtscl(time);
802 +
803 +       /* P4 seems to return a 0 LSB, ignore it */
804 +#ifdef CONFIG_MPENTIUM4
805 +       time &= 0x3EUL;
806 +       time <<= 1;
807 +#else
808 +       time &= 0x1FUL;
809 +       time <<= 2;
810 +#endif
811 +
812 +       tss->esp0 ^= time;
813 +       current->thread.esp0 = tss->esp0;
814 +}
815 +#endif
816 diff -uNr linux-2.6.6/arch/i386/kernel/ptrace.c linux-2.6.6.fixed/arch/i386/kernel/ptrace.c
817 --- linux-2.6.6/arch/i386/kernel/ptrace.c       2004-05-10 04:32:26.000000000 +0200
818 +++ linux-2.6.6.fixed/arch/i386/kernel/ptrace.c 2004-05-11 12:17:35.000000000 +0200
819 @@ -15,6 +15,7 @@
820  #include <linux/user.h>
821  #include <linux/security.h>
822  #include <linux/audit.h>
823 +#include <linux/grsecurity.h>
824  
825  #include <asm/uaccess.h>
826  #include <asm/pgtable.h>
827 @@ -263,6 +264,9 @@
828         if (pid == 1)           /* you may not mess with init */
829                 goto out_tsk;
830  
831 +       if (gr_handle_ptrace(child, request))
832 +               goto out_tsk;
833 +
834         if (request == PTRACE_ATTACH) {
835                 ret = ptrace_attach(child);
836                 goto out_tsk;
837 @@ -341,6 +345,17 @@
838                           if(addr == (long) &dummy->u_debugreg[5]) break;
839                           if(addr < (long) &dummy->u_debugreg[4] &&
840                              ((unsigned long) data) >= TASK_SIZE-3) break;
841 +
842 +#ifdef CONFIG_GRKERNSEC
843 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
844 +                            addr <= (long) &dummy->u_debugreg[3]){
845 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
846 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
847 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
848 +                               if((type & 1) && (data & align))
849 +                                       break;
850 +                         }
851 +#endif
852                           
853                           if(addr == (long) &dummy->u_debugreg[7]) {
854                                   data &= ~DR_CONTROL_RESERVED;
855 diff -uNr linux-2.6.6/arch/i386/kernel/reboot.c linux-2.6.6.fixed/arch/i386/kernel/reboot.c
856 --- linux-2.6.6/arch/i386/kernel/reboot.c       2004-05-10 04:32:27.000000000 +0200
857 +++ linux-2.6.6.fixed/arch/i386/kernel/reboot.c 2004-05-11 10:55:55.000000000 +0200
858 @@ -74,18 +74,18 @@
859     doesn't work with at least one type of 486 motherboard.  It is easy
860     to stop this code working; hence the copious comments. */
861  
862 -static unsigned long long
863 +static const unsigned long long
864  real_mode_gdt_entries [3] =
865  {
866         0x0000000000000000ULL,  /* Null descriptor */
867 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
868 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
869 +       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
870 +       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
871  };
872  
873  static struct
874  {
875         unsigned short       size __attribute__ ((packed));
876 -       unsigned long long * base __attribute__ ((packed));
877 +       const unsigned long long * base __attribute__ ((packed));
878  }
879  real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
880  real_mode_idt = { 0x3ff, 0 },
881 diff -uNr linux-2.6.6/arch/i386/kernel/setup.c linux-2.6.6.fixed/arch/i386/kernel/setup.c
882 --- linux-2.6.6/arch/i386/kernel/setup.c        2004-05-10 04:32:29.000000000 +0200
883 +++ linux-2.6.6.fixed/arch/i386/kernel/setup.c  2004-05-11 10:55:55.000000000 +0200
884 @@ -1196,6 +1196,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.6/arch/i386/kernel/signal.c linux-2.6.6.fixed/arch/i386/kernel/signal.c
901 --- linux-2.6.6/arch/i386/kernel/signal.c       2004-05-10 04:32:29.000000000 +0200
902 +++ linux-2.6.6.fixed/arch/i386/kernel/signal.c 2004-05-11 10:55:55.000000000 +0200
903 @@ -376,7 +376,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 @@ -459,7 +469,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.6/arch/i386/kernel/sysenter.c linux-2.6.6.fixed/arch/i386/kernel/sysenter.c
941 --- linux-2.6.6/arch/i386/kernel/sysenter.c     2004-05-10 04:33:21.000000000 +0200
942 +++ linux-2.6.6.fixed/arch/i386/kernel/sysenter.c       2004-05-11 10:55:55.000000000 +0200
943 @@ -41,13 +41,15 @@
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  
952         __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY);
953  
954 -       if (!boot_cpu_has(X86_FEATURE_SEP)) {
955 +       if (!boot_cpu_has(X86_FEATURE_SEP))
956 +       {
957                 memcpy((void *) page,
958                        &vsyscall_int80_start,
959                        &vsyscall_int80_end - &vsyscall_int80_start);
960 @@ -63,3 +65,4 @@
961  }
962  
963  __initcall(sysenter_setup);
964 +#endif
965 diff -uNr linux-2.6.6/arch/i386/kernel/sys_i386.c linux-2.6.6.fixed/arch/i386/kernel/sys_i386.c
966 --- linux-2.6.6/arch/i386/kernel/sys_i386.c     2004-05-10 04:33:20.000000000 +0200
967 +++ linux-2.6.6.fixed/arch/i386/kernel/sys_i386.c       2004-05-11 10:55:55.000000000 +0200
968 @@ -19,6 +19,7 @@
969  #include <linux/mman.h>
970  #include <linux/file.h>
971  #include <linux/utsname.h>
972 +#include <linux/grsecurity.h>
973  
974  #include <asm/uaccess.h>
975  #include <asm/ipc.h>
976 @@ -49,6 +50,11 @@
977         int error = -EBADF;
978         struct file * file = NULL;
979  
980 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
981 +       if (flags & MAP_MIRROR)
982 +               return -EINVAL;
983 +#endif
984 +
985         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
986         if (!(flags & MAP_ANONYMOUS)) {
987                 file = fget(fd);
988 @@ -56,6 +62,12 @@
989                         goto out;
990         }
991  
992 +       if (gr_handle_mmap(file, prot)) {
993 +               fput(file);
994 +               error = -EACCES;
995 +               goto out;
996 +       }
997 +
998         down_write(&current->mm->mmap_sem);
999         error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1000         up_write(&current->mm->mmap_sem);
1001 diff -uNr linux-2.6.6/arch/i386/kernel/trampoline.S linux-2.6.6.fixed/arch/i386/kernel/trampoline.S
1002 --- linux-2.6.6/arch/i386/kernel/trampoline.S   2004-05-10 04:32:28.000000000 +0200
1003 +++ linux-2.6.6.fixed/arch/i386/kernel/trampoline.S     2004-05-11 10:55:55.000000000 +0200
1004 @@ -58,7 +58,7 @@
1005         inc     %ax             # protected mode (PE) bit
1006         lmsw    %ax             # into protected mode
1007         # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S
1008 -       ljmpl   $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET)
1009 +       ljmpl   $__BOOT_CS, $(startup_32_smp+__KERNEL_TEXT_OFFSET-__PAGE_OFFSET)
1010  
1011         # These need to be in the same 64K segment as the above;
1012         # hence we don't use the boot_gdt_descr defined in head.S
1013 diff -uNr linux-2.6.6/arch/i386/kernel/traps.c linux-2.6.6.fixed/arch/i386/kernel/traps.c
1014 --- linux-2.6.6/arch/i386/kernel/traps.c        2004-05-10 04:32:02.000000000 +0200
1015 +++ linux-2.6.6.fixed/arch/i386/kernel/traps.c  2004-05-11 12:16:56.000000000 +0200
1016 @@ -59,18 +59,13 @@
1017  asmlinkage void lcall7(void);
1018  asmlinkage void lcall27(void);
1019  
1020 -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1021 +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1022                 { 0, 0 }, { 0, 0 } };
1023  
1024  /* Do we ignore FPU interrupts ? */
1025  char ignore_fpu_irq = 0;
1026  
1027 -/*
1028 - * The IDT has to be page-aligned to simplify the Pentium
1029 - * F0 0F bug workaround.. We have a special link segment
1030 - * for this.
1031 - */
1032 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
1033 +extern struct desc_struct idt_table[256];
1034  
1035  asmlinkage void divide_error(void);
1036  asmlinkage void debug(void);
1037 @@ -97,6 +92,7 @@
1038  void show_trace(struct task_struct *task, unsigned long * stack)
1039  {
1040         unsigned long addr;
1041 +       int i = kstack_depth_to_print;
1042  
1043         if (!stack)
1044                 stack = (unsigned long*)&stack;
1045 @@ -197,14 +194,23 @@
1046                 show_stack(NULL, (unsigned long*)esp);
1047  
1048                 printk("Code: ");
1049 +
1050 +#ifndef CONFIG_PAX_KERNEXEC
1051                 if(regs->eip < PAGE_OFFSET)
1052                         goto bad;
1053 +#endif
1054  
1055                 for(i=0;i<20;i++)
1056                 {
1057                         unsigned char c;
1058 +
1059 +#ifdef CONFIG_PAX_KERNEXEC
1060 +                       if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) {
1061 +#else
1062                         if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
1063  bad:
1064 +#endif
1065 +
1066                                 printk(" Bad EIP value.");
1067                                 break;
1068                         }
1069 @@ -227,8 +233,13 @@
1070  
1071         eip = regs->eip;
1072  
1073 +#ifdef CONFIG_PAX_KERNEXEC
1074 +       eip += __KERNEL_TEXT_OFFSET;
1075 +#else
1076         if (eip < PAGE_OFFSET)
1077                 goto no_bug;
1078 +#endif
1079 +
1080         if (__get_user(ud2, (unsigned short *)eip))
1081                 goto no_bug;
1082         if (ud2 != 0x0b0f)
1083 @@ -236,7 +247,13 @@
1084         if (__get_user(line, (unsigned short *)(eip + 2)))
1085                 goto bug;
1086         if (__get_user(file, (char **)(eip + 4)) ||
1087 +
1088 +#ifdef CONFIG_PAX_KERNEXEC
1089 +               __get_user(c, file + __KERNEL_TEXT_OFFSET))
1090 +#else
1091                 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
1092 +#endif
1093 +
1094                 file = "<bad filename>";
1095  
1096         printk("------------[ cut here ]------------\n");
1097 @@ -409,8 +426,16 @@
1098         return;
1099  
1100  gp_in_kernel:
1101 -       if (!fixup_exception(regs))
1102 +       if (!fixup_exception(regs)) {
1103 +
1104 +#ifdef CONFIG_PAX_KERNEXEC
1105 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
1106 +                       die("PAX: suspicious general protection fault", regs, error_code);
1107 +               else
1108 +#endif
1109 +
1110                 die("general protection fault", regs, error_code);
1111 +       }
1112  }
1113  
1114  static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
1115 @@ -843,7 +868,7 @@
1116         _set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
1117  }
1118  
1119 -static void __init set_call_gate(void *a, void *addr)
1120 +static void __init set_call_gate(const void *a, void *addr)
1121  {
1122         _set_gate(a,12,3,addr,__KERNEL_CS);
1123  }
1124 diff -uNr linux-2.6.6/arch/i386/kernel/vmlinux.lds.S linux-2.6.6.fixed/arch/i386/kernel/vmlinux.lds.S
1125 --- linux-2.6.6/arch/i386/kernel/vmlinux.lds.S  2004-05-10 04:32:02.000000000 +0200
1126 +++ linux-2.6.6.fixed/arch/i386/kernel/vmlinux.lds.S    2004-05-11 12:48:27.000000000 +0200
1127 @@ -2,7 +2,12 @@
1128   * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
1129   */
1130  
1131 +#include <linux/config.h>
1132 +
1133  #include <asm-generic/vmlinux.lds.h>
1134 +#include <asm-i386/page.h>
1135 +#include <asm-i386/segment.h>
1136 +
1137  #include <asm/thread_info.h>
1138  
1139  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
1140 @@ -11,26 +16,16 @@
1141  jiffies = jiffies_64;
1142  SECTIONS
1143  {
1144 -  . = 0xC0000000 + 0x100000;
1145 -  /* read-only */
1146 -  _text = .;                   /* Text and read-only data */
1147 -  .text : {
1148 -       *(.text)
1149 -       SCHED_TEXT
1150 -       *(.fixup)
1151 -       *(.gnu.warning)
1152 -       } = 0x9090
1153 -
1154 -  _etext = .;                  /* End of text section */
1155 -
1156 -  . = ALIGN(16);               /* Exception table */
1157 -  __start___ex_table = .;
1158 -  __ex_table : { *(__ex_table) }
1159 -  __stop___ex_table = .;
1160 -
1161 -  RODATA
1162 +  . = __PAGE_OFFSET + 0x100000;
1163 +  .text.startup : {
1164 +       BYTE(0xEA) /* jmp far */
1165 +       LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET)
1166 +       SHORT(__BOOT_CS)
1167 +       }
1168  
1169    /* writeable */
1170 +  . = ALIGN(32);
1171 +  _data = .;
1172    .data : {                    /* Data */
1173         *(.data)
1174         CONSTRUCTORS
1175 @@ -42,25 +37,28 @@
1176    . = ALIGN(4096);
1177    __nosave_end = .;
1178  
1179 -  . = ALIGN(4096);
1180 -  .data.page_aligned : { *(.data.idt) }
1181 -
1182    . = ALIGN(32);
1183    .data.cacheline_aligned : { *(.data.cacheline_aligned) }
1184  
1185 -  _edata = .;                  /* End of data section */
1186 -
1187    . = ALIGN(THREAD_SIZE);      /* init_task */
1188    .data.init_task : { *(.data.init_task) }
1189  
1190 +  . = ALIGN(4096);
1191 +  .data.page_aligned : { *(.data.swapper_pg_dir) }
1192 +
1193 +  _edata = .;                  /* End of data section */
1194 +
1195 +  __bss_start = .;             /* BSS */
1196 +  .bss : {
1197 +       *(.bss)
1198 +       LONG(0)
1199 +       }
1200 +  . = ALIGN(4);
1201 +  __bss_stop = .; 
1202 +
1203    /* will be freed after init */
1204    . = ALIGN(4096);             /* Init code and data */
1205    __init_begin = .;
1206 -  .init.text : { 
1207 -       _sinittext = .;
1208 -       *(.init.text)
1209 -       _einittext = .;
1210 -  }
1211    .init.data : { *(.init.data) }
1212    . = ALIGN(16);
1213    __setup_start = .;
1214 @@ -89,9 +87,13 @@
1215    .altinstructions : { *(.altinstructions) } 
1216    __alt_instructions_end = .; 
1217   .altinstr_replacement : { *(.altinstr_replacement) } 
1218 +
1219 +#ifndef CONFIG_PAX_KERNEXEC
1220    /* .exit.text is discard at runtime, not link time, to deal with references
1221       from .altinstructions and .eh_frame */
1222    .exit.text : { *(.exit.text) }
1223 +#endif
1224 +
1225    .exit.data : { *(.exit.data) }
1226    . = ALIGN(4096);
1227    __initramfs_start = .;
1228 @@ -101,19 +103,69 @@
1229    __per_cpu_start = .;
1230    .data.percpu  : { *(.data.percpu) }
1231    __per_cpu_end = .;
1232 +
1233 +  /* read-only */
1234 +
1235 +#ifdef CONFIG_PAX_KERNEXEC
1236 +  __init_text_start = .;
1237 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT (__init_text_start) {
1238 +       _sinittext = .;
1239 +       *(.init.text)
1240 +       _einittext = .;
1241 +       *(.exit.text)
1242 +       . = ALIGN(4*1024*1024) - 1;
1243 +       BYTE(0)
1244 +  }
1245    . = ALIGN(4096);
1246 -  __init_end = .;
1247 +  __init_end = . + __KERNEL_TEXT_OFFSET;
1248    /* freed after init ends here */
1249 -       
1250 -  __bss_start = .;             /* BSS */
1251 -  .bss : {
1252 -       *(.bss.page_aligned)
1253 -       *(.bss)
1254 +
1255 +/*
1256 + * PaX: this must be kept in synch with the KERNEL_CS base
1257 + * in the GDTs in arch/i386/kernel/head.S
1258 + */
1259 +  _text = .;                   /* Text and read-only data */
1260 +  .text : AT (. + __KERNEL_TEXT_OFFSET) {
1261 +#else
1262 +  .init.text : {
1263 +       _sinittext = .;
1264 +       *(.init.text)
1265 +       _einittext = .;
1266    }
1267 -  . = ALIGN(4);
1268 -  __bss_stop = .; 
1269 +  . = ALIGN(4096);
1270 +  __init_end = .;
1271 +  /* freed after init ends here */
1272 +
1273 +  _text = .;                   /* Text and read-only data */
1274 +  .text : {
1275 +#endif
1276 +
1277 +       *(.text)
1278 +       *(.fixup)
1279 +       *(.gnu.warning)
1280 +       } = 0x9090
1281 +
1282 +  _etext = .;                  /* End of text section */
1283 +  . += __KERNEL_TEXT_OFFSET;
1284 +  . = ALIGN(16);               /* Exception table */
1285 +  __start___ex_table = .;
1286 +  __ex_table : { *(__ex_table) }
1287 +  __stop___ex_table = .;
1288 +
1289 +  . = ALIGN(4096);
1290 +  .rodata.page_aligned : {
1291 +       *(.rodata.empty_zero_page)
1292 +       *(.rodata.idt)
1293 +       }
1294 +
1295 +  RODATA
1296  
1297 +#ifdef CONFIG_PAX_KERNEXEC
1298 +  _end = ALIGN(4*1024*1024);
1299 +  . = _end ;
1300 +#else
1301    _end = . ;
1302 +#endif
1303  
1304    /* This is where the kernel creates the early boot page tables */
1305    . = ALIGN(4096);
1306 diff -uNr linux-2.6.6/arch/i386/mm/fault.c linux-2.6.6.fixed/arch/i386/mm/fault.c
1307 --- linux-2.6.6/arch/i386/mm/fault.c    2004-05-10 04:31:57.000000000 +0200
1308 +++ linux-2.6.6.fixed/arch/i386/mm/fault.c      2004-05-11 10:55:55.000000000 +0200
1309 @@ -21,6 +21,9 @@
1310  #include <linux/vt_kern.h>             /* For unblank_screen() */
1311  #include <linux/highmem.h>
1312  #include <linux/module.h>
1313 +#include <linux/unistd.h>
1314 +#include <linux/compiler.h>
1315 +#include <linux/binfmts.h>
1316  
1317  #include <asm/system.h>
1318  #include <asm/uaccess.h>
1319 @@ -199,6 +202,10 @@
1320  
1321  asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
1322  
1323 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1324 +static int pax_handle_fetch_fault(struct pt_regs *regs);
1325 +#endif
1326 +
1327  /*
1328   * This routine handles page faults.  It determines the address,
1329   * and the problem, and then passes it off to one of the appropriate
1330 @@ -209,22 +216,31 @@
1331   *     bit 1 == 0 means read, 1 means write
1332   *     bit 2 == 0 means kernel, 1 means user-mode
1333   */
1334 +
1335 +#ifdef CONFIG_PAX_PAGEEXEC
1336 +static void do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
1337 +#else
1338  asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
1339 +#endif
1340  {
1341         struct task_struct *tsk;
1342         struct mm_struct *mm;
1343         struct vm_area_struct * vma;
1344 +#ifndef CONFIG_PAX_PAGEEXEC
1345         unsigned long address;
1346 +#endif
1347         unsigned long page;
1348         int write;
1349         siginfo_t info;
1350  
1351 +#ifndef CONFIG_PAX_PAGEEXEC
1352         /* get the address */
1353         __asm__("movl %%cr2,%0":"=r" (address));
1354  
1355         /* It's safe to allow irq's after cr2 has been saved */
1356         if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
1357                 local_irq_enable();
1358 +#endif
1359  
1360         tsk = current;
1361  
1362 @@ -358,6 +374,34 @@
1363                 if (is_prefetch(regs, address))
1364                         return;
1365  
1366 +#ifdef CONFIG_PAX_SEGMEXEC
1367 +               if (current->flags & PF_PAX_SEGMEXEC) {
1368 +
1369 +#if defined(CONFIG_PAX_EMUTRAMP) || defined(CONFIG_PAX_RANDEXEC)
1370 +                       if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
1371 +                               switch (pax_handle_fetch_fault(regs)) {
1372 +
1373 +#ifdef CONFIG_PAX_RANDEXEC
1374 +                               case 3:
1375 +                                       return;
1376 +#endif
1377 +
1378 +#ifdef CONFIG_PAX_EMUTRAMP
1379 +                               case 2:
1380 +                                       return;
1381 +#endif
1382 +
1383 +                               }
1384 +                       }
1385 +#endif
1386 +
1387 +                       if (address >= SEGMEXEC_TASK_SIZE) {
1388 +                               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1389 +                               do_exit(SIGKILL);
1390 +                       }
1391 +               }
1392 +#endif
1393 +
1394                 tsk->thread.cr2 = address;
1395                 /* Kernel addresses are always protection faults */
1396                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
1397 @@ -408,6 +452,13 @@
1398  
1399         if (address < PAGE_SIZE)
1400                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
1401 +
1402 +#ifdef CONFIG_PAX_KERNEXEC
1403 +       else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET)
1404 +               printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
1405 +                                tsk->comm, tsk->pid, tsk->uid, tsk->euid);
1406 +#endif
1407 +
1408         else
1409                 printk(KERN_ALERT "Unable to handle kernel paging request");
1410         printk(" at virtual address %08lx\n",address);
1411 @@ -509,3 +560,359 @@
1412                 return;
1413         }
1414  }
1415 +
1416 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1417 +/*
1418 + * PaX: decide what to do with offenders (regs->eip = fault address)
1419 + *
1420 + * returns 1 when task should be killed
1421 + *         2 when gcc trampoline was detected
1422 + *         3 when legitimate ET_EXEC was detected
1423 + */
1424 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1425 +{
1426 +
1427 +#ifdef CONFIG_PAX_EMUTRAMP
1428 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
1429 +#endif
1430 +
1431 +#if defined(CONFIG_PAX_RANDEXEC) || defined(CONFIG_PAX_EMUTRAMP)
1432 +       int err;
1433 +#endif
1434 +
1435 +#ifdef CONFIG_PAX_RANDEXEC
1436 +       if (current->flags & PF_PAX_RANDEXEC) {
1437 +               unsigned long esp_4;
1438 +
1439 +               if (regs->eip >= current->mm->start_code &&
1440 +                   regs->eip < current->mm->end_code)
1441 +               {
1442 +                       err = get_user(esp_4, (unsigned long*)(regs->esp-4UL));
1443 +                       if (err || esp_4 == regs->eip)
1444 +                               return 1;
1445 +
1446 +                       regs->eip += current->mm->delta_exec;
1447 +                       return 3;
1448 +               }
1449 +       }
1450 +#endif
1451 +
1452 +#ifdef CONFIG_PAX_EMUTRAMP
1453 +       do { /* PaX: gcc trampoline emulation #1 */
1454 +               unsigned char mov1, mov2;
1455 +               unsigned short jmp;
1456 +               unsigned long addr1, addr2, ret;
1457 +               unsigned short call;
1458 +
1459 +               err = get_user(mov1, (unsigned char *)regs->eip);
1460 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1461 +               err |= get_user(mov2, (unsigned char *)(regs->eip + 5));
1462 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1463 +               err |= get_user(jmp, (unsigned short *)(regs->eip + 10));
1464 +               err |= get_user(ret, (unsigned long *)regs->esp);
1465 +
1466 +               if (err)
1467 +                       break;
1468 +
1469 +               err = get_user(call, (unsigned short *)(ret-2));
1470 +               if (err)
1471 +                       break;
1472 +
1473 +               if ((mov1 & 0xF8) == 0xB8 &&
1474 +                   (mov2 & 0xF8) == 0xB8 &&
1475 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
1476 +                   (jmp & 0xF8FF) == 0xE0FF &&
1477 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07) &&
1478 +                   (call & 0xF8FF) == 0xD0FF &&
1479 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1480 +               {
1481 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
1482 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
1483 +                       regs->eip = addr2;
1484 +                       return 2;
1485 +               }
1486 +       } while (0);
1487 +
1488 +       do { /* PaX: gcc trampoline emulation #2 */
1489 +               unsigned char mov, jmp;
1490 +               unsigned long addr1, addr2, ret;
1491 +               unsigned short call;
1492 +
1493 +               err = get_user(mov, (unsigned char *)regs->eip);
1494 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1495 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1496 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1497 +               err |= get_user(ret, (unsigned long *)regs->esp);
1498 +
1499 +               if (err)
1500 +                       break;
1501 +
1502 +               err = get_user(call, (unsigned short *)(ret-2));
1503 +               if (err)
1504 +                       break;
1505 +
1506 +               if ((mov & 0xF8) == 0xB8 &&
1507 +                   jmp == 0xE9 &&
1508 +                   (call & 0xF8FF) == 0xD0FF &&
1509 +                   regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]])
1510 +               {
1511 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1512 +                       regs->eip += addr2 + 10;
1513 +                       return 2;
1514 +               }
1515 +       } while (0);
1516 +
1517 +       do { /* PaX: gcc trampoline emulation #3 */
1518 +               unsigned char mov, jmp;
1519 +               char offset;
1520 +               unsigned long addr1, addr2, ret;
1521 +               unsigned short call;
1522 +
1523 +               err = get_user(mov, (unsigned char *)regs->eip);
1524 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1525 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1526 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1527 +               err |= get_user(ret, (unsigned long *)regs->esp);
1528 +
1529 +               if (err)
1530 +                       break;
1531 +
1532 +               err = get_user(call, (unsigned short *)(ret-3));
1533 +               err |= get_user(offset, (char *)(ret-1));
1534 +               if (err)
1535 +                       break;
1536 +
1537 +               if ((mov & 0xF8) == 0xB8 &&
1538 +                   jmp == 0xE9 &&
1539 +                   call == 0x55FF)
1540 +               {
1541 +                       unsigned long addr;
1542 +
1543 +                       err = get_user(addr, (unsigned long*)(regs->ebp + (unsigned long)(long)offset));
1544 +                       if (err || regs->eip != addr)
1545 +                               break;
1546 +
1547 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1548 +                       regs->eip += addr2 + 10;
1549 +                       return 2;
1550 +               }
1551 +       } while (0);
1552 +
1553 +       do { /* PaX: gcc trampoline emulation #4 */
1554 +               unsigned char mov, jmp, sib;
1555 +               char offset;
1556 +               unsigned long addr1, addr2, ret;
1557 +               unsigned short call;
1558 +
1559 +               err = get_user(mov, (unsigned char *)regs->eip);
1560 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1561 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1562 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1563 +               err |= get_user(ret, (unsigned long *)regs->esp);
1564 +
1565 +               if (err)
1566 +                       break;
1567 +
1568 +               err = get_user(call, (unsigned short *)(ret-4));
1569 +               err |= get_user(sib, (unsigned char *)(ret-2));
1570 +               err |= get_user(offset, (char *)(ret-1));
1571 +               if (err)
1572 +                       break;
1573 +
1574 +               if ((mov & 0xF8) == 0xB8 &&
1575 +                   jmp == 0xE9 &&
1576 +                   call == 0x54FF &&
1577 +                   sib == 0x24)
1578 +               {
1579 +                       unsigned long addr;
1580 +
1581 +                       err = get_user(addr, (unsigned long*)(regs->esp + 4 + (unsigned long)(long)offset));
1582 +                       if (err || regs->eip != addr)
1583 +                               break;
1584 +
1585 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1586 +                       regs->eip += addr2 + 10;
1587 +                       return 2;
1588 +               }
1589 +       } while (0);
1590 +
1591 +       do { /* PaX: gcc trampoline emulation #5 */
1592 +               unsigned char mov, jmp, sib;
1593 +               unsigned long addr1, addr2, ret, offset;
1594 +               unsigned short call;
1595 +
1596 +               err = get_user(mov, (unsigned char *)regs->eip);
1597 +               err |= get_user(addr1, (unsigned long *)(regs->eip + 1));
1598 +               err |= get_user(jmp, (unsigned char *)(regs->eip + 5));
1599 +               err |= get_user(addr2, (unsigned long *)(regs->eip + 6));
1600 +               err |= get_user(ret, (unsigned long *)regs->esp);
1601 +
1602 +               if (err)
1603 +                       break;
1604 +
1605 +               err = get_user(call, (unsigned short *)(ret-7));
1606 +               err |= get_user(sib, (unsigned char *)(ret-5));
1607 +               err |= get_user(offset, (unsigned long *)(ret-4));
1608 +               if (err)
1609 +                       break;
1610 +
1611 +               if ((mov & 0xF8) == 0xB8 &&
1612 +                   jmp == 0xE9 &&
1613 +                   call == 0x94FF &&
1614 +                   sib == 0x24)
1615 +               {
1616 +                       unsigned long addr;
1617 +
1618 +                       err = get_user(addr, (unsigned long*)(regs->esp + 4 + offset));
1619 +                       if (err || regs->eip != addr)
1620 +                               break;
1621 +
1622 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
1623 +                       regs->eip += addr2 + 10;
1624 +                       return 2;
1625 +               }
1626 +       } while (0);
1627 +#endif
1628 +
1629 +       return 1; /* PaX in action */
1630 +}
1631 +
1632 +void pax_report_insns(void *pc, void *sp)
1633 +{
1634 +       unsigned long i;
1635 +
1636 +       printk(KERN_ERR "PAX: bytes at PC: ");
1637 +       for (i = 0; i < 20; i++) {
1638 +               unsigned char c;
1639 +               if (get_user(c, (unsigned char*)pc+i)) {
1640 +                       printk("<invalid address>.");
1641 +                       break;
1642 +               }
1643 +               printk("%02x ", c);
1644 +       }
1645 +       printk("\n");
1646 +
1647 +       printk(KERN_ERR "PAX: bytes at SP: ");
1648 +       for (i = 0; i < 20; i++) {
1649 +               unsigned long c;
1650 +               if (get_user(c, (unsigned long*)sp+i)) {
1651 +                       printk("<invalid address>.");
1652 +                       break;
1653 +               }
1654 +               printk("%08lx ", c);
1655 +       }
1656 +       printk("\n");
1657 +}
1658 +#endif
1659 +
1660 +#ifdef CONFIG_PAX_PAGEEXEC
1661 +/* PaX: called with the page_table_lock spinlock held */
1662 +static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address)
1663 +{
1664 +       pgd_t *pgd;
1665 +       pmd_t *pmd;
1666 +
1667 +       pgd = pgd_offset(mm, address);
1668 +       if (!pgd || !pgd_present(*pgd))
1669 +               return 0;
1670 +       pmd = pmd_offset(pgd, address);
1671 +       if (!pmd || !pmd_present(*pmd))
1672 +               return 0;
1673 +       return pte_offset_map(pmd, address);
1674 +}
1675 +
1676 +/*
1677 + * PaX: handle the extra page faults or pass it down to the original handler
1678 + */
1679 +asmlinkage void pax_do_page_fault(struct pt_regs *regs, unsigned long error_code)
1680 +{
1681 +       struct mm_struct *mm = current->mm;
1682 +       unsigned long address;
1683 +       pte_t *pte;
1684 +       unsigned char pte_mask;
1685 +       int ret;
1686 +
1687 +       __asm__("movl %%cr2,%0":"=r" (address));
1688 +
1689 +       /* It's safe to allow irq's after cr2 has been saved */
1690 +       if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
1691 +               local_irq_enable();
1692 +
1693 +       if (unlikely((error_code & 5) != 5 ||
1694 +                    address >= TASK_SIZE ||
1695 +                    !(current->flags & PF_PAX_PAGEEXEC)))
1696 +               return do_page_fault(regs, error_code, address);
1697 +
1698 +       /* PaX: it's our fault, let's handle it if we can */
1699 +
1700 +       /* PaX: take a look at read faults before acquiring any locks */
1701 +       if (unlikely((error_code == 5) && (regs->eip == address))) {
1702 +               /* instruction fetch attempt from a protected page in user mode */
1703 +               ret = pax_handle_fetch_fault(regs);
1704 +               switch (ret) {
1705 +
1706 +#ifdef CONFIG_PAX_RANDEXEC
1707 +               case 3:
1708 +                       return;
1709 +#endif
1710 +
1711 +#ifdef CONFIG_PAX_EMUTRAMP
1712 +               case 2:
1713 +                       return;
1714 +#endif
1715 +
1716 +               }
1717 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
1718 +               do_exit(SIGKILL);
1719 +       }
1720 +
1721 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
1722 +
1723 +       spin_lock(&mm->page_table_lock);
1724 +       pte = pax_get_pte(mm, address);
1725 +       if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) {
1726 +               pte_unmap(pte);
1727 +               spin_unlock(&mm->page_table_lock);
1728 +               do_page_fault(regs, error_code, address);
1729 +               return;
1730 +       }
1731 +
1732 +       if (unlikely((error_code == 7) && !pte_write(*pte))) {
1733 +               /* write attempt to a protected page in user mode */
1734 +               pte_unmap(pte);
1735 +               spin_unlock(&mm->page_table_lock);
1736 +               do_page_fault(regs, error_code, address);
1737 +               return;
1738 +       }
1739 +
1740 +       /*
1741 +        * PaX: fill DTLB with user rights and retry
1742 +        */
1743 +       __asm__ __volatile__ (
1744 +               "orb %2,%1\n"
1745 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
1746 +/*
1747 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
1748 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
1749 + * page fault when examined during a TLB load attempt. this is true not only
1750 + * for PTEs holding a non-present entry but also present entries that will
1751 + * raise a page fault (such as those set up by PaX, or the copy-on-write
1752 + * mechanism). in effect it means that we do *not* need to flush the TLBs
1753 + * for our target pages since their PTEs are simply not in the TLBs at all.
1754 +
1755 + * the best thing in omitting it is that we gain around 15-20% speed in the
1756 + * fast path of the page fault handler and can get rid of tracing since we
1757 + * can no longer flush unintended entries.
1758 + */
1759 +               "invlpg %0\n"
1760 +#endif
1761 +               "testb $0,%0\n"
1762 +               "xorb %3,%1\n"
1763 +               :
1764 +               : "m" (*(char*)address), "m" (*(char*)pte), "q" (pte_mask), "i" (_PAGE_USER)
1765 +               : "memory", "cc");
1766 +       pte_unmap(pte);
1767 +       spin_unlock(&mm->page_table_lock);
1768 +       return;
1769 +}
1770 +#endif
1771 diff -uNr linux-2.6.6/arch/i386/mm/init.c linux-2.6.6.fixed/arch/i386/mm/init.c
1772 --- linux-2.6.6/arch/i386/mm/init.c     2004-05-10 04:33:08.000000000 +0200
1773 +++ linux-2.6.6.fixed/arch/i386/mm/init.c       2004-05-11 10:55:55.000000000 +0200
1774 @@ -40,6 +40,7 @@
1775  #include <asm/tlb.h>
1776  #include <asm/tlbflush.h>
1777  #include <asm/sections.h>
1778 +#include <asm/desc.h>
1779  
1780  DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
1781  unsigned long highstart_pfn, highend_pfn;
1782 @@ -394,6 +395,10 @@
1783  #endif
1784         __flush_tlb_all();
1785  
1786 +#ifdef CONFIG_PAX_KERNEXEC
1787 +       memcpy(kernexec_pg_dir, swapper_pg_dir, sizeof(kernexec_pg_dir));
1788 +#endif
1789 +
1790         kmap_init();
1791         zone_sizes_init();
1792  }
1793 @@ -488,7 +493,7 @@
1794         set_highmem_pages_init(bad_ppro);
1795  
1796         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
1797 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
1798 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
1799         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
1800  
1801         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
1802 @@ -587,6 +592,42 @@
1803                 totalram_pages++;
1804         }
1805         printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
1806 +
1807 +#ifdef CONFIG_PAX_KERNEXEC
1808 +       /* PaX: limit KERNEL_CS to actual size */
1809 +       {
1810 +               unsigned long limit;
1811 +               int cpu;
1812 +               pgd_t *pgd;
1813 +               pmd_t *pmd;
1814 +
1815 +               limit = (unsigned long)&_etext >> PAGE_SHIFT;
1816 +               for (cpu = 0; cpu < NR_CPUS; cpu++) {
1817 +                       cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].a = (cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL);
1818 +                       cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].b = (cpu_gdt_table[cpu][GDT_ENTRY_KERNEL_CS].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL);
1819 +
1820 +#ifdef CONFIG_PCI_BIOS
1821 +               printk(KERN_INFO "PAX: warning, PCI BIOS might still be in use, keeping flat KERNEL_CS.\n");
1822 +#endif
1823 +
1824 +               }
1825 +
1826 +       /* PaX: make KERNEL_CS read-only */
1827 +               for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
1828 +                       pgd = pgd_offset_k(addr);
1829 +                       pmd = pmd_offset(pgd, addr);
1830 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_GLOBAL));
1831 +               }
1832 +               memcpy(kernexec_pg_dir, swapper_pg_dir, sizeof(kernexec_pg_dir));
1833 +               for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) {
1834 +                       pgd = pgd_offset_k(addr);
1835 +                       pmd = pmd_offset(pgd, addr);
1836 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
1837 +               }
1838 +               flush_tlb_all();
1839 +       }
1840 +#endif
1841 +
1842  }
1843  
1844  #ifdef CONFIG_BLK_DEV_INITRD
1845 diff -uNr linux-2.6.6/arch/i386/pci/pcbios.c linux-2.6.6.fixed/arch/i386/pci/pcbios.c
1846 --- linux-2.6.6/arch/i386/pci/pcbios.c  2004-05-10 04:32:00.000000000 +0200
1847 +++ linux-2.6.6.fixed/arch/i386/pci/pcbios.c    2004-05-11 10:55:55.000000000 +0200
1848 @@ -6,7 +6,7 @@
1849  #include <linux/init.h>
1850  #include "pci.h"
1851  #include "pci-functions.h"
1852 -
1853 +#include <asm/desc.h>
1854  
1855  /* BIOS32 signature: "_32_" */
1856  #define BIOS32_SIGNATURE       (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
1857 @@ -33,6 +33,12 @@
1858   * and the PCI BIOS specification.
1859   */
1860  
1861 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_PCI_BIOS)
1862 +#define __FLAT_KERNEL_CS 0x20
1863 +#else
1864 +#define __FLAT_KERNEL_CS __KERNEL_CS
1865 +#endif
1866 +
1867  union bios32 {
1868         struct {
1869                 unsigned long signature;        /* _32_ */
1870 @@ -55,7 +61,7 @@
1871  static struct {
1872         unsigned long address;
1873         unsigned short segment;
1874 -} bios32_indirect = { 0, __KERNEL_CS };
1875 +} bios32_indirect = { 0, __FLAT_KERNEL_CS };
1876  
1877  /*
1878   * Returns the entry point for the given service, NULL on error
1879 @@ -96,7 +102,9 @@
1880  static struct {
1881         unsigned long address;
1882         unsigned short segment;
1883 -} pci_indirect = { 0, __KERNEL_CS };
1884 +} pci_indirect = { 0, __FLAT_KERNEL_CS };
1885 +
1886 +#undef __FLAT_KERNEL_CS
1887  
1888  static int pci_bios_present;
1889  
1890 diff -uNr linux-2.6.6/arch/ia64/ia32/binfmt_elf32.c linux-2.6.6.fixed/arch/ia64/ia32/binfmt_elf32.c
1891 --- linux-2.6.6/arch/ia64/ia32/binfmt_elf32.c   2004-05-10 04:33:20.000000000 +0200
1892 +++ linux-2.6.6.fixed/arch/ia64/ia32/binfmt_elf32.c     2004-05-11 12:12:42.000000000 +0200
1893 @@ -41,6 +41,17 @@
1894  #undef SET_PERSONALITY
1895  #define SET_PERSONALITY(ex, ibcs2)     elf32_set_personality()
1896  
1897 +#ifdef CONFIG_PAX_ASLR
1898 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
1899 +
1900 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
1901 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
1902 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
1903 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
1904 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
1905 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT)
1906 +#endif
1907 +
1908  /* Ugly but avoids duplication */
1909  #include "../../../fs/binfmt_elf.c"
1910  
1911 @@ -184,8 +195,7 @@
1912                         mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
1913                 else
1914                         mpnt->vm_flags = VM_STACK_FLAGS;
1915 -               mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC)?
1916 -                                       PAGE_COPY_EXEC: PAGE_COPY;
1917 +               mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7];
1918                 mpnt->vm_ops = NULL;
1919                 mpnt->vm_pgoff = 0;
1920                 mpnt->vm_file = NULL;
1921 diff -uNr linux-2.6.6/arch/ia64/ia32/ia32priv.h linux-2.6.6.fixed/arch/ia64/ia32/ia32priv.h
1922 --- linux-2.6.6/arch/ia64/ia32/ia32priv.h       2004-05-10 04:33:20.000000000 +0200
1923 +++ linux-2.6.6.fixed/arch/ia64/ia32/ia32priv.h 2004-05-11 10:55:55.000000000 +0200
1924 @@ -295,7 +295,14 @@
1925  #define ELF_ARCH       EM_386
1926  
1927  #define IA32_PAGE_OFFSET       0xc0000000
1928 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
1929 +
1930 +#ifdef CONFIG_PAX_RANDUSTACK
1931 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
1932 +#else
1933 +#define __IA32_DELTA_STACK 0UL
1934 +#endif
1935 +
1936 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
1937  
1938  /*
1939   * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
1940 diff -uNr linux-2.6.6/arch/ia64/ia32/sys_ia32.c linux-2.6.6.fixed/arch/ia64/ia32/sys_ia32.c
1941 --- linux-2.6.6/arch/ia64/ia32/sys_ia32.c       2004-05-10 04:32:39.000000000 +0200
1942 +++ linux-2.6.6.fixed/arch/ia64/ia32/sys_ia32.c 2004-05-11 10:55:55.000000000 +0200
1943 @@ -475,6 +475,11 @@
1944  
1945         flags = a.flags;
1946  
1947 +#ifdef CONFIG_PAX_RANDEXEC
1948 +       if (flags & MAP_MIRROR)
1949 +               return -EINVAL;
1950 +#endif
1951 +
1952         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1953         if (!(flags & MAP_ANONYMOUS)) {
1954                 file = fget(a.fd);
1955 @@ -496,6 +501,11 @@
1956         struct file *file = NULL;
1957         unsigned long retval;
1958  
1959 +#ifdef CONFIG_PAX_RANDEXEC
1960 +       if (flags & MAP_MIRROR)
1961 +               return -EINVAL;
1962 +#endif
1963 +
1964         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1965         if (!(flags & MAP_ANONYMOUS)) {
1966                 file = fget(fd);
1967 diff -uNr linux-2.6.6/arch/ia64/kernel/ptrace.c linux-2.6.6.fixed/arch/ia64/kernel/ptrace.c
1968 --- linux-2.6.6/arch/ia64/kernel/ptrace.c       2004-05-10 04:33:21.000000000 +0200
1969 +++ linux-2.6.6.fixed/arch/ia64/kernel/ptrace.c 2004-05-11 10:55:55.000000000 +0200
1970 @@ -17,6 +17,7 @@
1971  #include <linux/smp_lock.h>
1972  #include <linux/user.h>
1973  #include <linux/security.h>
1974 +#include <linux/grsecurity.h>
1975  
1976  #include <asm/pgtable.h>
1977  #include <asm/processor.h>
1978 @@ -1314,6 +1315,9 @@
1979         if (pid == 1)           /* no messing around with init! */
1980                 goto out_tsk;
1981  
1982 +       if (gr_handle_ptrace(child, request))
1983 +               goto out_tsk;
1984 +
1985         if (request == PTRACE_ATTACH) {
1986                 ret = ptrace_attach(child);
1987                 goto out_tsk;
1988 diff -uNr linux-2.6.6/arch/ia64/kernel/sys_ia64.c linux-2.6.6.fixed/arch/ia64/kernel/sys_ia64.c
1989 --- linux-2.6.6/arch/ia64/kernel/sys_ia64.c     2004-05-10 04:32:38.000000000 +0200
1990 +++ linux-2.6.6.fixed/arch/ia64/kernel/sys_ia64.c       2004-05-11 10:55:55.000000000 +0200
1991 @@ -18,6 +18,7 @@
1992  #include <linux/syscalls.h>
1993  #include <linux/highuid.h>
1994  #include <linux/hugetlb.h>
1995 +#include <linux/grsecurity.h>
1996  
1997  #include <asm/shmparam.h>
1998  #include <asm/uaccess.h>
1999 @@ -38,6 +39,13 @@
2000         if (REGION_NUMBER(addr) == REGION_HPAGE)
2001                 addr = 0;
2002  #endif
2003 +
2004 +#ifdef CONFIG_PAX_RANDMMAP
2005 +       if ((current->flags & PF_PAX_RANDMMAP) && addr && filp)
2006 +               addr = mm->free_area_cache;
2007 +       else
2008 +#endif
2009 +
2010         if (!addr)
2011                 addr = mm->free_area_cache;
2012  
2013 @@ -58,6 +66,13 @@
2014                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
2015                         if (start_addr != TASK_UNMAPPED_BASE) {
2016                                 /* Start a new search --- just in case we missed some holes.  */
2017 +
2018 +#ifdef CONFIG_PAX_RANDMMAP
2019 +                               if (current->flags & PF_PAX_RANDMMAP)
2020 +                                       addr = TASK_UNMAPPED_BASE + mm->delta_mmap;
2021 +                               else
2022 +#endif
2023 +
2024                                 addr = TASK_UNMAPPED_BASE;
2025                                 goto full_search;
2026                         }
2027 @@ -185,6 +200,11 @@
2028         unsigned long roff;
2029         struct file *file = 0;
2030  
2031 +#ifdef CONFIG_PAX_RANDEXEC
2032 +       if (flags & MAP_MIRROR)
2033 +               return -EINVAL;
2034 +#endif
2035 +
2036         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2037         if (!(flags & MAP_ANONYMOUS)) {
2038                 file = fget(fd);
2039 @@ -222,6 +242,11 @@
2040                 goto out;
2041         }
2042  
2043 +       if (gr_handle_mmap(file, prot)) {
2044 +               addr = -EACCES;
2045 +               goto out;
2046 +       }
2047 +
2048         down_write(&current->mm->mmap_sem);
2049         addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
2050         up_write(&current->mm->mmap_sem);
2051 diff -uNr linux-2.6.6/arch/ia64/mm/fault.c linux-2.6.6.fixed/arch/ia64/mm/fault.c
2052 --- linux-2.6.6/arch/ia64/mm/fault.c    2004-05-10 04:33:20.000000000 +0200
2053 +++ linux-2.6.6.fixed/arch/ia64/mm/fault.c      2004-05-11 10:55:55.000000000 +0200
2054 @@ -9,6 +9,7 @@
2055  #include <linux/mm.h>
2056  #include <linux/smp_lock.h>
2057  #include <linux/interrupt.h>
2058 +#include <linux/binfmts.h>
2059  
2060  #include <asm/pgtable.h>
2061  #include <asm/processor.h>
2062 @@ -70,6 +71,54 @@
2063         return pte_present(pte);
2064  }
2065  
2066 +#ifdef CONFIG_PAX_PAGEEXEC
2067 +/*
2068 + * PaX: decide what to do with offenders (regs->cr_iip = fault address)
2069 + *
2070 + * returns 1 when task should be killed
2071 + *         2 when legitimate ET_EXEC was detected
2072 + */
2073 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2074 +{
2075 +
2076 +#ifdef CONFIG_PAX_RANDEXEC
2077 +       int err;
2078 +
2079 +       if (current->flags & PF_PAX_RANDEXEC) {
2080 +               if (regs->cr_iip >= current->mm->start_code &&
2081 +                   regs->cr_iip < current->mm->end_code)
2082 +               {
2083 +#if 0
2084 +                       /* PaX: this needs fixing */
2085 +                       if (regs->b0 == regs->cr_iip)
2086 +                               return 1;
2087 +#endif
2088 +                       regs->cr_iip += current->mm->delta_exec;
2089 +                       return 2;
2090 +               }
2091 +       }
2092 +#endif
2093 +
2094 +       return 1;
2095 +}
2096 +
2097 +void pax_report_insns(void *pc, void *sp)
2098 +{
2099 +       unsigned long i;
2100 +
2101 +       printk(KERN_ERR "PAX: bytes at PC: ");
2102 +       for (i = 0; i < 8; i++) {
2103 +               unsigned int c;
2104 +               if (get_user(c, (unsigned int*)pc+i)) {
2105 +                       printk("<invalid address>.");
2106 +                       break;
2107 +               }
2108 +               printk("%08x ", c);
2109 +       }
2110 +       printk("\n");
2111 +}
2112 +#endif
2113 +
2114  void
2115  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
2116  {
2117 @@ -125,9 +174,31 @@
2118                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)
2119                 | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT));
2120  
2121 -       if ((vma->vm_flags & mask) != mask)
2122 +       if ((vma->vm_flags & mask) != mask) {
2123 +
2124 +#ifdef CONFIG_PAX_PAGEEXEC
2125 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
2126 +                       if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->cr_iip)
2127 +                               goto bad_area;
2128 +
2129 +                       up_read(&mm->mmap_sem);
2130 +                       switch(pax_handle_fetch_fault(regs)) {
2131 +
2132 +#ifdef CONFIG_PAX_RANDEXEC
2133 +                       case 2:
2134 +                               return;
2135 +#endif
2136 +
2137 +                       }
2138 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
2139 +                       do_exit(SIGKILL);
2140 +               }
2141 +#endif
2142 +
2143                 goto bad_area;
2144  
2145 +       }
2146 +
2147    survive:
2148         /*
2149          * If for any reason at all we couldn't handle the fault, make
2150 diff -uNr linux-2.6.6/arch/mips/kernel/binfmt_elfn32.c linux-2.6.6.fixed/arch/mips/kernel/binfmt_elfn32.c
2151 --- linux-2.6.6/arch/mips/kernel/binfmt_elfn32.c        2004-05-10 04:32:39.000000000 +0200
2152 +++ linux-2.6.6.fixed/arch/mips/kernel/binfmt_elfn32.c  2004-05-11 10:55:55.000000000 +0200
2153 @@ -50,6 +50,17 @@
2154  #undef ELF_ET_DYN_BASE
2155  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
2156  
2157 +#ifdef CONFIG_PAX_ASLR
2158 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
2159 +
2160 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
2161 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2162 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
2163 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2164 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
2165 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2166 +#endif
2167 +
2168  #include <asm/processor.h>
2169  #include <linux/module.h>
2170  #include <linux/config.h>
2171 diff -uNr linux-2.6.6/arch/mips/kernel/binfmt_elfo32.c linux-2.6.6.fixed/arch/mips/kernel/binfmt_elfo32.c
2172 --- linux-2.6.6/arch/mips/kernel/binfmt_elfo32.c        2004-05-10 04:32:27.000000000 +0200
2173 +++ linux-2.6.6.fixed/arch/mips/kernel/binfmt_elfo32.c  2004-05-11 10:55:55.000000000 +0200
2174 @@ -52,6 +52,17 @@
2175  #undef ELF_ET_DYN_BASE
2176  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
2177  
2178 +#ifdef CONFIG_PAX_ASLR
2179 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
2180 +
2181 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
2182 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2183 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
2184 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2185 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
2186 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2187 +#endif
2188 +
2189  #include <asm/processor.h>
2190  #include <linux/module.h>
2191  #include <linux/config.h>
2192 diff -uNr linux-2.6.6/arch/mips/kernel/syscall.c linux-2.6.6.fixed/arch/mips/kernel/syscall.c
2193 --- linux-2.6.6/arch/mips/kernel/syscall.c      2004-05-10 04:33:12.000000000 +0200
2194 +++ linux-2.6.6.fixed/arch/mips/kernel/syscall.c        2004-05-11 10:55:55.000000000 +0200
2195 @@ -86,6 +86,11 @@
2196         do_color_align = 0;
2197         if (filp || (flags & MAP_SHARED))
2198                 do_color_align = 1;
2199 +
2200 +#ifdef CONFIG_PAX_RANDMMAP
2201 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
2202 +#endif
2203 +
2204         if (addr) {
2205                 if (do_color_align)
2206                         addr = COLOUR_ALIGN(addr, pgoff);
2207 @@ -96,6 +101,13 @@
2208                     (!vmm || addr + len <= vmm->vm_start))
2209                         return addr;
2210         }
2211 +
2212 +#ifdef CONFIG_PAX_RANDMMAP
2213 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
2214 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
2215 +       else
2216 +#endif
2217 +
2218         addr = TASK_UNMAPPED_BASE;
2219         if (do_color_align)
2220                 addr = COLOUR_ALIGN(addr, pgoff);
2221 diff -uNr linux-2.6.6/arch/mips/mm/fault.c linux-2.6.6.fixed/arch/mips/mm/fault.c
2222 --- linux-2.6.6/arch/mips/mm/fault.c    2004-05-10 04:32:26.000000000 +0200
2223 +++ linux-2.6.6.fixed/arch/mips/mm/fault.c      2004-05-11 10:55:55.000000000 +0200
2224 @@ -27,6 +27,24 @@
2225  #include <asm/uaccess.h>
2226  #include <asm/ptrace.h>
2227  
2228 +#ifdef CONFIG_PAX_PAGEEXEC
2229 +void pax_report_insns(void *pc)
2230 +{
2231 +       unsigned long i;
2232 +
2233 +       printk(KERN_ERR "PAX: bytes at PC: ");
2234 +       for (i = 0; i < 5; i++) {
2235 +               unsigned int c;
2236 +               if (get_user(c, (unsigned int*)pc+i)) {
2237 +                       printk("<invalid address>.");
2238 +                       break;
2239 +               }
2240 +               printk("%08x ", c);
2241 +       }
2242 +       printk("\n");
2243 +}
2244 +#endif
2245 +
2246  /*
2247   * This routine handles page faults.  It determines the address,
2248   * and the problem, and then passes it off to one of the appropriate
2249 diff -uNr linux-2.6.6/arch/ppc/kernel/ptrace.c linux-2.6.6.fixed/arch/ppc/kernel/ptrace.c
2250 --- linux-2.6.6/arch/ppc/kernel/ptrace.c        2004-05-10 04:32:26.000000000 +0200
2251 +++ linux-2.6.6.fixed/arch/ppc/kernel/ptrace.c  2004-05-11 10:55:56.000000000 +0200
2252 @@ -26,6 +26,7 @@
2253  #include <linux/ptrace.h>
2254  #include <linux/user.h>
2255  #include <linux/security.h>
2256 +#include <linux/grsecurity.h>
2257  
2258  #include <asm/uaccess.h>
2259  #include <asm/page.h>
2260 @@ -202,6 +203,9 @@
2261         if (pid == 1)           /* you may not mess with init */
2262                 goto out_tsk;
2263  
2264 +       if (gr_handle_ptrace(child, request))
2265 +               goto out_tsk;
2266 +
2267         if (request == PTRACE_ATTACH) {
2268                 ret = ptrace_attach(child);
2269                 goto out_tsk;
2270 diff -uNr linux-2.6.6/arch/ppc/kernel/syscalls.c linux-2.6.6.fixed/arch/ppc/kernel/syscalls.c
2271 --- linux-2.6.6/arch/ppc/kernel/syscalls.c      2004-05-10 04:33:20.000000000 +0200
2272 +++ linux-2.6.6.fixed/arch/ppc/kernel/syscalls.c        2004-05-11 10:55:56.000000000 +0200
2273 @@ -36,6 +36,7 @@
2274  #include <linux/utsname.h>
2275  #include <linux/file.h>
2276  #include <linux/unistd.h>
2277 +#include <linux/grsecurity.h>
2278  
2279  #include <asm/uaccess.h>
2280  #include <asm/ipc.h>
2281 @@ -165,12 +166,23 @@
2282         struct file * file = NULL;
2283         int ret = -EBADF;
2284  
2285 +#ifdef CONFIG_PAX_RANDEXEC
2286 +       if (flags & MAP_MIRROR)
2287 +               return -EINVAL;
2288 +#endif
2289 +
2290         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2291         if (!(flags & MAP_ANONYMOUS)) {
2292                 if (!(file = fget(fd)))
2293                         goto out;
2294         }
2295  
2296 +       if (gr_handle_mmap(file, prot)) {
2297 +               fput(file);
2298 +               ret = -EACCES;
2299 +               goto out;
2300 +       }
2301 +
2302         down_write(&current->mm->mmap_sem);
2303         ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
2304         up_write(&current->mm->mmap_sem);
2305 diff -uNr linux-2.6.6/arch/ppc/mm/fault.c linux-2.6.6.fixed/arch/ppc/mm/fault.c
2306 --- linux-2.6.6/arch/ppc/mm/fault.c     2004-05-10 04:32:27.000000000 +0200
2307 +++ linux-2.6.6.fixed/arch/ppc/mm/fault.c       2004-05-11 10:55:56.000000000 +0200
2308 @@ -28,6 +28,11 @@
2309  #include <linux/interrupt.h>
2310  #include <linux/highmem.h>
2311  #include <linux/module.h>
2312 +#include <linux/slab.h>
2313 +#include <linux/pagemap.h>
2314 +#include <linux/compiler.h>
2315 +#include <linux/binfmts.h>
2316 +#include <linux/unistd.h>
2317  
2318  #include <asm/page.h>
2319  #include <asm/pgtable.h>
2320 @@ -56,6 +61,366 @@
2321  void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
2322  extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
2323  
2324 +#ifdef CONFIG_PAX_EMUSIGRT
2325 +void pax_syscall_close(struct vm_area_struct * vma)
2326 +{
2327 +       vma->vm_mm->call_syscall = 0UL;
2328 +}
2329 +
2330 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2331 +{
2332 +       struct page* page;
2333 +       unsigned int *kaddr;
2334 +
2335 +       page = alloc_page(GFP_HIGHUSER);
2336 +       if (!page)
2337 +               return NOPAGE_OOM;
2338 +
2339 +       kaddr = kmap(page);
2340 +       memset(kaddr, 0, PAGE_SIZE);
2341 +       kaddr[0] = 0x44000002U; /* sc */
2342 +       __flush_dcache_icache(kaddr);
2343 +       kunmap(page);
2344 +       if (type)
2345 +               *type = VM_FAULT_MAJOR;
2346 +       return page;
2347 +}
2348 +
2349 +static struct vm_operations_struct pax_vm_ops = {
2350 +       close:          pax_syscall_close,
2351 +       nopage:         pax_syscall_nopage,
2352 +};
2353 +
2354 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2355 +{
2356 +       vma->vm_mm = current->mm;
2357 +       vma->vm_start = addr;
2358 +       vma->vm_end = addr + PAGE_SIZE;
2359 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2360 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
2361 +       vma->vm_ops = &pax_vm_ops;
2362 +       vma->vm_pgoff = 0UL;
2363 +       vma->vm_file = NULL;
2364 +       vma->vm_private_data = NULL;
2365 +       INIT_LIST_HEAD(&vma->shared);
2366 +       insert_vm_struct(current->mm, vma);
2367 +       ++current->mm->total_vm;
2368 +}
2369 +#endif
2370 +
2371 +#ifdef CONFIG_PAX_PAGEEXEC
2372 +/*
2373 + * PaX: decide what to do with offenders (regs->nip = fault address)
2374 + *
2375 + * returns 1 when task should be killed
2376 + *         2 when patched GOT trampoline was detected
2377 + *         3 when patched PLT trampoline was detected
2378 + *         4 when unpatched PLT trampoline was detected
2379 + *         5 when legitimate ET_EXEC was detected
2380 + *         6 when sigreturn trampoline was detected
2381 + *         7 when rt_sigreturn trampoline was detected
2382 + */
2383 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2384 +{
2385 +
2386 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
2387 +       int err;
2388 +#endif
2389 +
2390 +#ifdef CONFIG_PAX_RANDEXEC
2391 +       if (current->flags & PF_PAX_RANDEXEC) {
2392 +               if (regs->nip >= current->mm->start_code &&
2393 +                   regs->nip < current->mm->end_code)
2394 +               {
2395 +                       if (regs->link == regs->nip)
2396 +                               return 1;
2397 +
2398 +                       regs->nip += current->mm->delta_exec;
2399 +                       return 5;
2400 +               }
2401 +       }
2402 +#endif
2403 +
2404 +#ifdef CONFIG_PAX_EMUPLT
2405 +       do { /* PaX: patched GOT emulation */
2406 +               unsigned int blrl;
2407 +
2408 +               err = get_user(blrl, (unsigned int*)regs->nip);
2409 +
2410 +               if (!err && blrl == 0x4E800021U) {
2411 +                       unsigned long temp = regs->nip;
2412 +
2413 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
2414 +                       regs->link = temp + 4UL;
2415 +                       return 2;
2416 +               }
2417 +       } while (0);
2418 +
2419 +       do { /* PaX: patched PLT emulation #1 */
2420 +               unsigned int b;
2421 +
2422 +               err = get_user(b, (unsigned int *)regs->nip);
2423 +
2424 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
2425 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
2426 +                       return 3;
2427 +               }
2428 +       } while (0);
2429 +
2430 +       do { /* PaX: unpatched PLT emulation #1 */
2431 +               unsigned int li, b;
2432 +
2433 +               err = get_user(li, (unsigned int *)regs->nip);
2434 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
2435 +
2436 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2437 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2438 +                       unsigned long addr = b | 0xFC000000UL;
2439 +
2440 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2441 +                       err = get_user(rlwinm, (unsigned int*)addr);
2442 +                       err |= get_user(add, (unsigned int*)(addr+4));
2443 +                       err |= get_user(li2, (unsigned int*)(addr+8));
2444 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
2445 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
2446 +                       err |= get_user(li3, (unsigned int*)(addr+20));
2447 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
2448 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
2449 +
2450 +                       if (err)
2451 +                               break;
2452 +
2453 +                       if (rlwinm == 0x556C083CU &&
2454 +                           add == 0x7D6C5A14U &&
2455 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2456 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2457 +                           mtctr == 0x7D8903A6U &&
2458 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2459 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2460 +                           bctr == 0x4E800420U)
2461 +                       {
2462 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2463 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2464 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2465 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2466 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
2467 +                               regs->nip = regs->ctr;
2468 +                               return 4;
2469 +                       }
2470 +               }
2471 +       } while (0);
2472 +
2473 +#if 0
2474 +       do { /* PaX: unpatched PLT emulation #2 */
2475 +               unsigned int lis, lwzu, b, bctr;
2476 +
2477 +               err = get_user(lis, (unsigned int *)regs->nip);
2478 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
2479 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
2480 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
2481 +
2482 +               if (err)
2483 +                       break;
2484 +
2485 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
2486 +                   (lwzu & 0xU) == 0xU &&
2487 +                   (b & 0xFC000003U) == 0x48000000U &&
2488 +                   bctr == 0x4E800420U)
2489 +               {
2490 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2491 +                       unsigned long addr = b | 0xFC000000UL;
2492 +
2493 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2494 +                       err = get_user(addis, (unsigned int*)addr);
2495 +                       err |= get_user(addi, (unsigned int*)(addr+4));
2496 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
2497 +                       err |= get_user(add, (unsigned int*)(addr+12));
2498 +                       err |= get_user(li2, (unsigned int*)(addr+16));
2499 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
2500 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
2501 +                       err |= get_user(li3, (unsigned int*)(addr+28));
2502 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
2503 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
2504 +
2505 +                       if (err)
2506 +                               break;
2507 +
2508 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2509 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
2510 +                           rlwinm == 0x556C083CU &&
2511 +                           add == 0x7D6C5A14U &&
2512 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
2513 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2514 +                           mtctr == 0x7D8903A6U &&
2515 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
2516 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2517 +                           bctr == 0x4E800420U)
2518 +                       {
2519 +                               regs->gpr[PT_R11] = 
2520 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2521 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2522 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2523 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2524 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
2525 +                               regs->nip = regs->ctr;
2526 +                               return 4;
2527 +                       }
2528 +               }
2529 +       } while (0);
2530 +#endif
2531 +
2532 +       do { /* PaX: unpatched PLT emulation #3 */
2533 +               unsigned int li, b;
2534 +
2535 +               err = get_user(li, (unsigned int *)regs->nip);
2536 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
2537 +
2538 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2539 +                       unsigned int addis, lwz, mtctr, bctr;
2540 +                       unsigned long addr = b | 0xFC000000UL;
2541 +
2542 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2543 +                       err = get_user(addis, (unsigned int*)addr);
2544 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
2545 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
2546 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
2547 +
2548 +                       if (err)
2549 +                               break;
2550 +
2551 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2552 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
2553 +                           mtctr == 0x7D6903A6U &&
2554 +                           bctr == 0x4E800420U)
2555 +                       {
2556 +                               unsigned int r11;
2557 +
2558 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2559 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2560 +
2561 +                               err = get_user(r11, (unsigned int*)addr);
2562 +                               if (err)
2563 +                                       break;
2564 +
2565 +                               regs->gpr[PT_R11] = r11;
2566 +                               regs->ctr = r11;
2567 +                               regs->nip = r11;
2568 +                               return 4;
2569 +                       }
2570 +               }
2571 +       } while (0);
2572 +#endif
2573 +
2574 +#ifdef CONFIG_PAX_EMUSIGRT
2575 +       do { /* PaX: sigreturn emulation */
2576 +               unsigned int li, sc;
2577 +
2578 +               err = get_user(li, (unsigned int *)regs->nip);
2579 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
2580 +
2581 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
2582 +                       struct vm_area_struct *vma;
2583 +                       unsigned long call_syscall;
2584 +
2585 +                       down_read(&current->mm->mmap_sem);
2586 +                       call_syscall = current->mm->call_syscall;
2587 +                       up_read(&current->mm->mmap_sem);
2588 +                       if (likely(call_syscall))
2589 +                               goto emulate;
2590 +
2591 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
2592 +
2593 +                       down_write(&current->mm->mmap_sem);
2594 +                       if (current->mm->call_syscall) {
2595 +                               call_syscall = current->mm->call_syscall;
2596 +                               up_write(&current->mm->mmap_sem);
2597 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2598 +                               goto emulate;
2599 +                       }
2600 +
2601 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2602 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
2603 +                               up_write(&current->mm->mmap_sem);
2604 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2605 +                               return 1;
2606 +                       }
2607 +
2608 +                       pax_insert_vma(vma, call_syscall);
2609 +                       current->mm->call_syscall = call_syscall;
2610 +                       up_write(&current->mm->mmap_sem);
2611 +
2612 +emulate:
2613 +                       regs->gpr[PT_R0] = __NR_sigreturn;
2614 +                       regs->nip = call_syscall;
2615 +                       return 6;
2616 +               }
2617 +       } while (0);
2618 +
2619 +       do { /* PaX: rt_sigreturn emulation */
2620 +               unsigned int li, sc;
2621 +
2622 +               err = get_user(li, (unsigned int *)regs->nip);
2623 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
2624 +
2625 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
2626 +                       struct vm_area_struct *vma;
2627 +                       unsigned int call_syscall;
2628 +
2629 +                       down_read(&current->mm->mmap_sem);
2630 +                       call_syscall = current->mm->call_syscall;
2631 +                       up_read(&current->mm->mmap_sem);
2632 +                       if (likely(call_syscall))
2633 +                               goto rt_emulate;
2634 +
2635 +                       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
2636 +
2637 +                       down_write(&current->mm->mmap_sem);
2638 +                       if (current->mm->call_syscall) {
2639 +                               call_syscall = current->mm->call_syscall;
2640 +                               up_write(&current->mm->mmap_sem);
2641 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2642 +                               goto rt_emulate;
2643 +                       }
2644 +
2645 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2646 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
2647 +                               up_write(&current->mm->mmap_sem);
2648 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
2649 +                               return 1;
2650 +                       }
2651 +
2652 +                       pax_insert_vma(vma, call_syscall);
2653 +                       current->mm->call_syscall = call_syscall;
2654 +                       up_write(&current->mm->mmap_sem);
2655 +
2656 +rt_emulate:
2657 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
2658 +                       regs->nip = call_syscall;
2659 +                       return 7;
2660 +               }
2661 +       } while (0);
2662 +#endif
2663 +
2664 +       return 1;
2665 +}
2666 +
2667 +void pax_report_insns(void *pc, void *sp)
2668 +{
2669 +       unsigned long i;
2670 +
2671 +       printk(KERN_ERR "PAX: bytes at PC: ");
2672 +       for (i = 0; i < 5; i++) {
2673 +               unsigned int c;
2674 +               if (get_user(c, (unsigned int*)pc+i)) {
2675 +                       printk("<invalid address>.");
2676 +                       break;
2677 +               }
2678 +               printk("%08x ", c);
2679 +       }
2680 +       printk("\n");
2681 +}
2682 +#endif
2683 +
2684  /*
2685   * Check whether the instruction at regs->nip is a store using
2686   * an update addressing form which will update r1.
2687 @@ -116,7 +481,7 @@
2688          * indicate errors in DSISR but can validly be set in SRR1.
2689          */
2690         if (TRAP(regs) == 0x400)
2691 -               error_code &= 0x48200000;
2692 +               error_code &= 0x58200000;
2693         else
2694                 is_write = error_code & 0x02000000;
2695  #endif /* CONFIG_4xx */
2696 @@ -211,15 +576,14 @@
2697         } else if (TRAP(regs) == 0x400) {
2698                 pte_t *ptep;
2699  
2700 -#if 0
2701 +#if 1
2702                 /* It would be nice to actually enforce the VM execute
2703                    permission on CPUs which can do so, but far too
2704                    much stuff in userspace doesn't get the permissions
2705                    right, so we let any page be executed for now. */
2706                 if (! (vma->vm_flags & VM_EXEC))
2707                         goto bad_area;
2708 -#endif
2709 -
2710 +#else
2711                 /* Since 4xx supports per-page execute permission,
2712                  * we lazily flush dcache to icache. */
2713                 ptep = NULL;
2714 @@ -240,6 +604,7 @@
2715                 if (ptep != NULL)
2716                         pte_unmap(ptep);
2717  #endif
2718 +#endif
2719         /* a read */
2720         } else {
2721                 /* protection fault */
2722 @@ -285,6 +650,38 @@
2723  
2724         /* User mode accesses cause a SIGSEGV */
2725         if (user_mode(regs)) {
2726 +
2727 +#ifdef CONFIG_PAX_PAGEEXEC
2728 +               if (current->flags & PF_PAX_PAGEEXEC) {
2729 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
2730 +                               switch (pax_handle_fetch_fault(regs)) {
2731 +
2732 +#ifdef CONFIG_PAX_EMUPLT
2733 +                               case 2:
2734 +                               case 3:
2735 +                               case 4:
2736 +                                       return;
2737 +#endif
2738 +
2739 +#ifdef CONFIG_PAX_RANDEXEC
2740 +                               case 5:
2741 +                                       return;
2742 +#endif
2743 +
2744 +#ifdef CONFIG_PAX_EMUSIGRT
2745 +                               case 6:
2746 +                               case 7:
2747 +                                       return;
2748 +#endif
2749 +
2750 +                               }
2751 +
2752 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
2753 +                               do_exit(SIGKILL);
2754 +                       }
2755 +               }
2756 +#endif
2757 +
2758                 info.si_signo = SIGSEGV;
2759                 info.si_errno = 0;
2760                 info.si_code = code;
2761 diff -uNr linux-2.6.6/arch/sparc/kernel/ptrace.c linux-2.6.6.fixed/arch/sparc/kernel/ptrace.c
2762 --- linux-2.6.6/arch/sparc/kernel/ptrace.c      2004-05-10 04:33:21.000000000 +0200
2763 +++ linux-2.6.6.fixed/arch/sparc/kernel/ptrace.c        2004-05-11 10:55:56.000000000 +0200
2764 @@ -18,6 +18,7 @@
2765  #include <linux/smp.h>
2766  #include <linux/smp_lock.h>
2767  #include <linux/security.h>
2768 +#include <linux/grsecurity.h>
2769  
2770  #include <asm/pgtable.h>
2771  #include <asm/system.h>
2772 @@ -320,6 +321,11 @@
2773                 goto out;
2774         }
2775  
2776 +       if (gr_handle_ptrace(child, request)) {
2777 +               pt_error_return(regs, EPERM);
2778 +               goto out_tsk;
2779 +       }
2780 +
2781         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
2782             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
2783                 if (ptrace_attach(child)) {
2784 diff -uNr linux-2.6.6/arch/sparc/kernel/sys_sparc.c linux-2.6.6.fixed/arch/sparc/kernel/sys_sparc.c
2785 --- linux-2.6.6/arch/sparc/kernel/sys_sparc.c   2004-05-10 04:32:28.000000000 +0200
2786 +++ linux-2.6.6.fixed/arch/sparc/kernel/sys_sparc.c     2004-05-11 10:55:56.000000000 +0200
2787 @@ -21,6 +21,7 @@
2788  #include <linux/utsname.h>
2789  #include <linux/smp.h>
2790  #include <linux/smp_lock.h>
2791 +#include <linux/grsecurity.h>
2792  
2793  #include <asm/uaccess.h>
2794  #include <asm/ipc.h>
2795 @@ -55,6 +56,13 @@
2796                 return -ENOMEM;
2797         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
2798                 return -ENOMEM;
2799 +
2800 +#ifdef CONFIG_PAX_RANDMMAP
2801 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp))
2802 +               addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap;
2803 +       else
2804 +#endif
2805 +
2806         if (!addr)
2807                 addr = TASK_UNMAPPED_BASE;
2808  
2809 @@ -224,6 +232,11 @@
2810         struct file * file = NULL;
2811         unsigned long retval = -EBADF;
2812  
2813 +#ifdef CONFIG_PAX_RANDEXEC
2814 +       if (flags & MAP_MIRROR)
2815 +               return -EINVAL;
2816 +#endif
2817 +
2818         if (!(flags & MAP_ANONYMOUS)) {
2819                 file = fget(fd);
2820                 if (!file)
2821 @@ -242,6 +255,12 @@
2822         if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
2823                 goto out_putf;
2824  
2825 +       if (gr_handle_mmap(file, prot)) {
2826 +               fput(file);
2827 +               retval = -EACCES;
2828 +               goto out;
2829 +       }
2830 +
2831         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2832  
2833         down_write(&current->mm->mmap_sem);
2834 diff -uNr linux-2.6.6/arch/sparc/kernel/sys_sunos.c linux-2.6.6.fixed/arch/sparc/kernel/sys_sunos.c
2835 --- linux-2.6.6/arch/sparc/kernel/sys_sunos.c   2004-05-10 04:32:28.000000000 +0200
2836 +++ linux-2.6.6.fixed/arch/sparc/kernel/sys_sunos.c     2004-05-11 10:55:56.000000000 +0200
2837 @@ -71,6 +71,11 @@
2838         struct file * file = NULL;
2839         unsigned long retval, ret_type;
2840  
2841 +#ifdef CONFIG_PAX_RANDEXEC
2842 +       if (flags & MAP_MIRROR)
2843 +               return -EINVAL;
2844 +#endif
2845 +
2846         if(flags & MAP_NORESERVE) {
2847                 static int cnt;
2848                 if (cnt++ < 10)
2849 diff -uNr linux-2.6.6/arch/sparc/mm/fault.c linux-2.6.6.fixed/arch/sparc/mm/fault.c
2850 --- linux-2.6.6/arch/sparc/mm/fault.c   2004-05-10 04:32:27.000000000 +0200
2851 +++ linux-2.6.6.fixed/arch/sparc/mm/fault.c     2004-05-11 10:55:56.000000000 +0200
2852 @@ -21,6 +21,10 @@
2853  #include <linux/smp_lock.h>
2854  #include <linux/interrupt.h>
2855  #include <linux/module.h>
2856 +#include <linux/slab.h>
2857 +#include <linux/pagemap.h>
2858 +#include <linux/compiler.h>
2859 +#include <linux/binfmts.h>
2860  
2861  #include <asm/system.h>
2862  #include <asm/segment.h>
2863 @@ -201,6 +205,272 @@
2864         return 0;
2865  }
2866  
2867 +#ifdef CONFIG_PAX_PAGEEXEC
2868 +void pax_emuplt_close(struct vm_area_struct * vma)
2869 +{
2870 +       vma->vm_mm->call_dl_resolve = 0UL;
2871 +}
2872 +
2873 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2874 +{
2875 +       struct page* page;
2876 +       unsigned int *kaddr;
2877 +
2878 +       page = alloc_page(GFP_HIGHUSER);
2879 +       if (!page)
2880 +               return NOPAGE_OOM;
2881 +
2882 +       kaddr = kmap(page);
2883 +       memset(kaddr, 0, PAGE_SIZE);
2884 +       kaddr[0] = 0x9DE3BFA8U; /* save */
2885 +       flush_dcache_page(page);
2886 +       kunmap(page);
2887 +       if (type)
2888 +               *type = VM_FAULT_MAJOR;
2889 +
2890 +       return page;
2891 +}
2892 +
2893 +static struct vm_operations_struct pax_vm_ops = {
2894 +       close:          pax_emuplt_close,
2895 +       nopage:         pax_emuplt_nopage,
2896 +};
2897 +
2898 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2899 +{
2900 +       vma->vm_mm = current->mm;
2901 +       vma->vm_start = addr;
2902 +       vma->vm_end = addr + PAGE_SIZE;
2903 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2904 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
2905 +       vma->vm_ops = &pax_vm_ops;
2906 +       vma->vm_pgoff = 0UL;
2907 +       vma->vm_file = NULL;
2908 +       vma->vm_private_data = NULL;
2909 +       INIT_LIST_HEAD(&vma->shared);
2910 +       insert_vm_struct(current->mm, vma);
2911 +       ++current->mm->total_vm;
2912 +}
2913 +
2914 +/*
2915 + * PaX: decide what to do with offenders (regs->pc = fault address)
2916 + *
2917 + * returns 1 when task should be killed
2918 + *         2 when patched PLT trampoline was detected
2919 + *         3 when unpatched PLT trampoline was detected
2920 + *         4 when legitimate ET_EXEC was detected
2921 + */
2922 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2923 +{
2924 +
2925 +#ifdef CONFIG_PAX_EMUPLT
2926 +       int err;
2927 +#endif
2928 +
2929 +#ifdef CONFIG_PAX_RANDEXEC
2930 +       if (current->flags & PF_PAX_RANDEXEC) {
2931 +               if (regs->pc >= current->mm->start_code &&
2932 +                   regs->pc < current->mm->end_code)
2933 +               {
2934 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc)
2935 +                               return 1;
2936 +
2937 +                       regs->pc += current->mm->delta_exec;
2938 +                       if (regs->npc >= current->mm->start_code &&
2939 +                           regs->npc < current->mm->end_code)
2940 +                               regs->npc += current->mm->delta_exec;
2941 +                       return 4;
2942 +               }
2943 +               if (regs->pc >= current->mm->start_code + current->mm->delta_exec &&
2944 +                   regs->pc < current->mm->end_code + current->mm->delta_exec)
2945 +               {
2946 +                       regs->pc -= current->mm->delta_exec;
2947 +                       if (regs->npc >= current->mm->start_code + current->mm->delta_exec &&
2948 +                           regs->npc < current->mm->end_code + current->mm->delta_exec)
2949 +                               regs->npc -= current->mm->delta_exec;
2950 +               }
2951 +       }
2952 +#endif
2953 +
2954 +#ifdef CONFIG_PAX_EMUPLT
2955 +       do { /* PaX: patched PLT emulation #1 */
2956 +               unsigned int sethi1, sethi2, jmpl;
2957 +
2958 +               err = get_user(sethi1, (unsigned int*)regs->pc);
2959 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
2960 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
2961 +
2962 +               if (err)
2963 +                       break;
2964 +
2965 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2966 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
2967 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
2968 +               {
2969 +                       unsigned int addr;
2970 +
2971 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2972 +                       addr = regs->u_regs[UREG_G1];
2973 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2974 +                       regs->pc = addr;
2975 +                       regs->npc = addr+4;
2976 +                       return 2;
2977 +               }
2978 +       } while (0);
2979 +
2980 +       { /* PaX: patched PLT emulation #2 */
2981 +               unsigned int ba;
2982 +
2983 +               err = get_user(ba, (unsigned int*)regs->pc);
2984 +
2985 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2986 +                       unsigned int addr;
2987 +
2988 +                       addr = regs->pc + 4 + (((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U);
2989 +                       regs->pc = addr;
2990 +                       regs->npc = addr+4;
2991 +                       return 2;
2992 +               }
2993 +       }
2994 +
2995 +       do { /* PaX: patched PLT emulation #3 */
2996 +               unsigned int sethi, jmpl, nop;
2997 +
2998 +               err = get_user(sethi, (unsigned int*)regs->pc);
2999 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
3000 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
3001 +
3002 +               if (err)
3003 +                       break;
3004 +
3005 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3006 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3007 +                   nop == 0x01000000U)
3008 +               {
3009 +                       unsigned int addr;
3010 +
3011 +                       addr = (sethi & 0x003FFFFFU) << 10;
3012 +                       regs->u_regs[UREG_G1] = addr;
3013 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3014 +                       regs->pc = addr;
3015 +                       regs->npc = addr+4;
3016 +                       return 2;
3017 +               }
3018 +       } while (0);
3019 +
3020 +       do { /* PaX: unpatched PLT emulation step 1 */
3021 +               unsigned int sethi, ba, nop;
3022 +
3023 +               err = get_user(sethi, (unsigned int*)regs->pc);
3024 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
3025 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
3026 +
3027 +               if (err)
3028 +                       break;
3029 +
3030 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3031 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
3032 +                   nop == 0x01000000U)
3033 +               {
3034 +                       unsigned int addr, save, call;
3035 +
3036 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
3037 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3038 +                       else
3039 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
3040 +
3041 +                       err = get_user(save, (unsigned int*)addr);
3042 +                       err |= get_user(call, (unsigned int*)(addr+4));
3043 +                       err |= get_user(nop, (unsigned int*)(addr+8));
3044 +                       if (err)
3045 +                               break;
3046 +
3047 +                       if (save == 0x9DE3BFA8U &&
3048 +                           (call & 0xC0000000U) == 0x40000000U &&
3049 +                           nop == 0x01000000U)
3050 +                       {
3051 +                               struct vm_area_struct *vma;
3052 +                               unsigned long call_dl_resolve;
3053 +
3054 +                               down_read(&current->mm->mmap_sem);
3055 +                               call_dl_resolve = current->mm->call_dl_resolve;
3056 +                               up_read(&current->mm->mmap_sem);
3057 +                               if (likely(call_dl_resolve))
3058 +                                       goto emulate;
3059 +
3060 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3061 +
3062 +                               down_write(&current->mm->mmap_sem);
3063 +                               if (current->mm->call_dl_resolve) {
3064 +                                       call_dl_resolve = current->mm->call_dl_resolve;
3065 +                                       up_write(&current->mm->mmap_sem);
3066 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3067 +                                       goto emulate;
3068 +                               }
3069 +
3070 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3071 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3072 +                                       up_write(&current->mm->mmap_sem);
3073 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3074 +                                       return 1;
3075 +                               }
3076 +
3077 +                               pax_insert_vma(vma, call_dl_resolve);
3078 +                               current->mm->call_dl_resolve = call_dl_resolve;
3079 +                               up_write(&current->mm->mmap_sem);
3080 +
3081 +emulate:
3082 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3083 +                               regs->pc = call_dl_resolve;
3084 +                               regs->npc = addr+4;
3085 +                               return 3;
3086 +                       }
3087 +               }
3088 +       } while (0);
3089 +
3090 +       do { /* PaX: unpatched PLT emulation step 2 */
3091 +               unsigned int save, call, nop;
3092 +
3093 +               err = get_user(save, (unsigned int*)(regs->pc-4));
3094 +               err |= get_user(call, (unsigned int*)regs->pc);
3095 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
3096 +               if (err)
3097 +                       break;
3098 +
3099 +               if (save == 0x9DE3BFA8U &&
3100 +                   (call & 0xC0000000U) == 0x40000000U &&
3101 +                   nop == 0x01000000U)
3102 +               {
3103 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
3104 +
3105 +                       regs->u_regs[UREG_RETPC] = regs->pc;
3106 +                       regs->pc = dl_resolve;
3107 +                       regs->npc = dl_resolve+4;
3108 +                       return 3;
3109 +               }
3110 +       } while (0);
3111 +#endif
3112 +
3113 +       return 1;
3114 +}
3115 +
3116 +void pax_report_insns(void *pc, void *sp)
3117 +{
3118 +       unsigned long i;
3119 +
3120 +       printk(KERN_ERR "PAX: bytes at PC: ");
3121 +       for (i = 0; i < 5; i++) {
3122 +               unsigned int c;
3123 +               if (get_user(c, (unsigned int*)pc+i)) {
3124 +                       printk("<invalid address>.");
3125 +                       break;
3126 +               }
3127 +               printk("%08x ", c);
3128 +       }
3129 +       printk("\n");
3130 +}
3131 +#endif
3132 +
3133  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
3134                                unsigned long address)
3135  {
3136 @@ -264,6 +534,29 @@
3137                 if(!(vma->vm_flags & VM_WRITE))
3138                         goto bad_area;
3139         } else {
3140 +
3141 +#ifdef CONFIG_PAX_PAGEEXEC
3142 +               if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
3143 +                       up_read(&mm->mmap_sem);
3144 +                       switch (pax_handle_fetch_fault(regs)) {
3145 +
3146 +#ifdef CONFIG_PAX_EMUPLT
3147 +                       case 2:
3148 +                       case 3:
3149 +                               return;
3150 +#endif
3151 +
3152 +#ifdef CONFIG_PAX_RANDEXEC
3153 +                       case 4:
3154 +                               return;
3155 +#endif
3156 +
3157 +                       }
3158 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
3159 +                       do_exit(SIGKILL);
3160 +               }
3161 +#endif
3162 +
3163                 /* Allow reads even for write-only mappings */
3164                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
3165                         goto bad_area;
3166 diff -uNr linux-2.6.6/arch/sparc/mm/init.c linux-2.6.6.fixed/arch/sparc/mm/init.c
3167 --- linux-2.6.6/arch/sparc/mm/init.c    2004-05-10 04:32:29.000000000 +0200
3168 +++ linux-2.6.6.fixed/arch/sparc/mm/init.c      2004-05-11 10:55:56.000000000 +0200
3169 @@ -337,17 +337,17 @@
3170  
3171         /* Initialize the protection map with non-constant, MMU dependent values. */
3172         protection_map[0] = PAGE_NONE;
3173 -       protection_map[1] = PAGE_READONLY;
3174 -       protection_map[2] = PAGE_COPY;
3175 -       protection_map[3] = PAGE_COPY;
3176 +       protection_map[1] = PAGE_READONLY_NOEXEC;
3177 +       protection_map[2] = PAGE_COPY_NOEXEC;
3178 +       protection_map[3] = PAGE_COPY_NOEXEC;
3179         protection_map[4] = PAGE_READONLY;
3180         protection_map[5] = PAGE_READONLY;
3181         protection_map[6] = PAGE_COPY;
3182         protection_map[7] = PAGE_COPY;
3183         protection_map[8] = PAGE_NONE;
3184 -       protection_map[9] = PAGE_READONLY;
3185 -       protection_map[10] = PAGE_SHARED;
3186 -       protection_map[11] = PAGE_SHARED;
3187 +       protection_map[9] = PAGE_READONLY_NOEXEC;
3188 +       protection_map[10] = PAGE_SHARED_NOEXEC;
3189 +       protection_map[11] = PAGE_SHARED_NOEXEC;
3190         protection_map[12] = PAGE_READONLY;
3191         protection_map[13] = PAGE_READONLY;
3192         protection_map[14] = PAGE_SHARED;
3193 diff -uNr linux-2.6.6/arch/sparc/mm/srmmu.c linux-2.6.6.fixed/arch/sparc/mm/srmmu.c
3194 --- linux-2.6.6/arch/sparc/mm/srmmu.c   2004-05-10 04:32:38.000000000 +0200
3195 +++ linux-2.6.6.fixed/arch/sparc/mm/srmmu.c     2004-05-11 10:55:56.000000000 +0200
3196 @@ -2155,6 +2155,13 @@
3197         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
3198         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
3199         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
3200 +
3201 +#ifdef CONFIG_PAX_PAGEEXEC
3202 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
3203 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
3204 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
3205 +#endif
3206 +
3207         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
3208         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
3209         pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
3210 diff -uNr linux-2.6.6/arch/sparc64/kernel/itlb_base.S linux-2.6.6.fixed/arch/sparc64/kernel/itlb_base.S
3211 --- linux-2.6.6/arch/sparc64/kernel/itlb_base.S 2004-05-10 04:32:01.000000000 +0200
3212 +++ linux-2.6.6.fixed/arch/sparc64/kernel/itlb_base.S   2004-05-11 10:55:56.000000000 +0200
3213 @@ -41,7 +41,9 @@
3214         CREATE_VPTE_OFFSET2(%g4, %g6)                   ! Create VPTE offset
3215         ldxa            [%g3 + %g6] ASI_P, %g5          ! Load VPTE
3216  1:     brgez,pn        %g5, 3f                         ! Not valid, branch out
3217 -        nop                                            ! Delay-slot
3218 +       and             %g5, _PAGE_EXEC, %g4
3219 +       brz,pn          %g4, 3f                         ! Not executable, branch out
3220 +       nop                                             ! Delay-slot
3221  2:     stxa            %g5, [%g0] ASI_ITLB_DATA_IN     ! Load PTE into TLB
3222         retry                                           ! Trap return
3223  3:     rdpr            %pstate, %g4                    ! Move into alternate globals
3224 @@ -74,8 +76,6 @@
3225         nop
3226         nop
3227         nop
3228 -       nop
3229 -       nop
3230         CREATE_VPTE_NOP
3231  
3232  #undef CREATE_VPTE_OFFSET1
3233 diff -uNr linux-2.6.6/arch/sparc64/kernel/ptrace.c linux-2.6.6.fixed/arch/sparc64/kernel/ptrace.c
3234 --- linux-2.6.6/arch/sparc64/kernel/ptrace.c    2004-05-10 04:33:21.000000000 +0200
3235 +++ linux-2.6.6.fixed/arch/sparc64/kernel/ptrace.c      2004-05-11 10:55:56.000000000 +0200
3236 @@ -19,6 +19,7 @@
3237  #include <linux/smp.h>
3238  #include <linux/smp_lock.h>
3239  #include <linux/security.h>
3240 +#include <linux/grsecurity.h>
3241  
3242  #include <asm/asi.h>
3243  #include <asm/pgtable.h>
3244 @@ -169,6 +170,11 @@
3245                 goto out;
3246         }
3247  
3248 +       if (gr_handle_ptrace(child, (long)request)) {
3249 +               pt_error_return(regs, EPERM);
3250 +               goto out_tsk;
3251 +       }
3252 +
3253         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
3254             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
3255                 if (ptrace_attach(child)) {
3256 diff -uNr linux-2.6.6/arch/sparc64/kernel/sys_sparc.c linux-2.6.6.fixed/arch/sparc64/kernel/sys_sparc.c
3257 --- linux-2.6.6/arch/sparc64/kernel/sys_sparc.c 2004-05-10 04:32:38.000000000 +0200
3258 +++ linux-2.6.6.fixed/arch/sparc64/kernel/sys_sparc.c   2004-05-11 10:55:56.000000000 +0200
3259 @@ -25,6 +25,7 @@
3260  #include <linux/syscalls.h>
3261  #include <linux/ipc.h>
3262  #include <linux/personality.h>
3263 +#include <linux/grsecurity.h>
3264  
3265  #include <asm/uaccess.h>
3266  #include <asm/ipc.h>
3267 @@ -72,6 +73,10 @@
3268         if (filp || (flags & MAP_SHARED))
3269                 do_color_align = 1;
3270  
3271 +#ifdef CONFIG_PAX_RANDMMAP
3272 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
3273 +#endif
3274 +
3275         if (addr) {
3276                 if (do_color_align)
3277                         addr = COLOUR_ALIGN(addr, pgoff);
3278 @@ -102,6 +107,13 @@
3279                 }
3280                 if (task_size < addr) {
3281                         if (start_addr != TASK_UNMAPPED_BASE) {
3282 +
3283 +#ifdef CONFIG_PAX_RANDMMAP
3284 +                               if (current->flags & PF_PAX_RANDMMAP)
3285 +                                       start_addr = addr = TASK_UNMAPPED_BASE + mm->delta_mmap;
3286 +                               else
3287 +#endif
3288 +
3289                                 start_addr = addr = TASK_UNMAPPED_BASE;
3290                                 goto full_search;
3291                         }
3292 @@ -311,11 +323,22 @@
3293         struct file * file = NULL;
3294         unsigned long retval = -EBADF;
3295  
3296 +#ifdef CONFIG_PAX_RANDEXEC
3297 +       if (flags & MAP_MIRROR)
3298 +               return -EINVAL;
3299 +#endif
3300 +
3301         if (!(flags & MAP_ANONYMOUS)) {
3302                 file = fget(fd);
3303                 if (!file)
3304                         goto out;
3305         }
3306 +
3307 +       if (gr_handle_mmap(file, prot)) {
3308 +               retval = -EACCES;
3309 +               goto out_putf;
3310 +       }
3311 +
3312         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3313         len = PAGE_ALIGN(len);
3314         retval = -EINVAL;
3315 diff -uNr linux-2.6.6/arch/sparc64/kernel/sys_sunos32.c linux-2.6.6.fixed/arch/sparc64/kernel/sys_sunos32.c
3316 --- linux-2.6.6/arch/sparc64/kernel/sys_sunos32.c       2004-05-10 04:32:51.000000000 +0200
3317 +++ linux-2.6.6.fixed/arch/sparc64/kernel/sys_sunos32.c 2004-05-11 10:55:56.000000000 +0200
3318 @@ -75,6 +75,11 @@
3319         struct file *file = NULL;
3320         unsigned long retval, ret_type;
3321  
3322 +#ifdef CONFIG_PAX_RANDEXEC
3323 +       if (flags & MAP_MIRROR)
3324 +               return -EINVAL;
3325 +#endif
3326 +
3327         if (flags & MAP_NORESERVE) {
3328                 static int cnt;
3329                 if (cnt++ < 10)
3330 diff -uNr linux-2.6.6/arch/sparc64/mm/fault.c linux-2.6.6.fixed/arch/sparc64/mm/fault.c
3331 --- linux-2.6.6/arch/sparc64/mm/fault.c 2004-05-10 04:33:20.000000000 +0200
3332 +++ linux-2.6.6.fixed/arch/sparc64/mm/fault.c   2004-05-11 10:55:56.000000000 +0200
3333 @@ -18,6 +18,10 @@
3334  #include <linux/smp_lock.h>
3335  #include <linux/init.h>
3336  #include <linux/interrupt.h>
3337 +#include <linux/slab.h>
3338 +#include <linux/pagemap.h>
3339 +#include <linux/compiler.h>
3340 +#include <linux/binfmts.h>
3341  
3342  #include <asm/page.h>
3343  #include <asm/pgtable.h>
3344 @@ -303,6 +307,364 @@
3345         unhandled_fault (address, current, regs);
3346  }
3347  
3348 +#ifdef CONFIG_PAX_PAGEEXEC
3349 +#ifdef CONFIG_PAX_EMUPLT
3350 +static void pax_emuplt_close(struct vm_area_struct * vma)
3351 +{
3352 +       vma->vm_mm->call_dl_resolve = 0UL;
3353 +}
3354 +
3355 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
3356 +{
3357 +       struct page* page;
3358 +       unsigned int *kaddr;
3359 +
3360 +       page = alloc_page(GFP_HIGHUSER);
3361 +       if (!page)
3362 +               return NOPAGE_OOM;
3363 +
3364 +       kaddr = kmap(page);
3365 +       memset(kaddr, 0, PAGE_SIZE);
3366 +       kaddr[0] = 0x9DE3BFA8U; /* save */
3367 +       flush_dcache_page(page);
3368 +       kunmap(page);
3369 +       if (type)
3370 +               *type = VM_FAULT_MAJOR;
3371 +       return page;
3372 +}
3373 +
3374 +static struct vm_operations_struct pax_vm_ops = {
3375 +       close:          pax_emuplt_close,
3376 +       nopage:         pax_emuplt_nopage,
3377 +};
3378 +
3379 +static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3380 +{
3381 +       vma->vm_mm = current->mm;
3382 +       vma->vm_start = addr;
3383 +       vma->vm_end = addr + PAGE_SIZE;
3384 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3385 +       vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
3386 +       vma->vm_ops = &pax_vm_ops;
3387 +       vma->vm_pgoff = 0UL;
3388 +       vma->vm_file = NULL;
3389 +       vma->vm_private_data = NULL;
3390 +       INIT_LIST_HEAD(&vma->shared);
3391 +       insert_vm_struct(current->mm, vma);
3392 +       ++current->mm->total_vm;
3393 +}
3394 +#endif
3395 +
3396 +/*
3397 + * PaX: decide what to do with offenders (regs->tpc = 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->tpc >= current->mm->start_code &&
3414 +                   regs->tpc < current->mm->end_code)
3415 +               {
3416 +                       if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc)
3417 +                               return 1;
3418 +
3419 +                       regs->tpc += current->mm->delta_exec;
3420 +                       if (regs->tnpc >= current->mm->start_code &&
3421 +                           regs->tnpc < current->mm->end_code)
3422 +                               regs->tnpc += current->mm->delta_exec;
3423 +                       return 4;
3424 +               }
3425 +               if (regs->tpc >= current->mm->start_code + current->mm->delta_exec &&
3426 +                   regs->tpc < current->mm->end_code + current->mm->delta_exec)
3427 +               {
3428 +                       regs->tpc -= current->mm->delta_exec;
3429 +                       if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec &&
3430 +                           regs->tnpc < current->mm->end_code + current->mm->delta_exec)
3431 +                               regs->tnpc -= 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->tpc);
3441 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
3442 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
3443 +
3444 +               if (err)
3445 +                       break;
3446 +
3447 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3448 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
3449 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
3450 +               {
3451 +                       unsigned long addr;
3452 +
3453 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3454 +                       addr = regs->u_regs[UREG_G1];
3455 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3456 +                       regs->tpc = addr;
3457 +                       regs->tnpc = 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->tpc);
3466 +
3467 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3468 +                       unsigned long addr;
3469 +
3470 +                       addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL);
3471 +                       regs->tpc = addr;
3472 +                       regs->tnpc = 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->tpc);
3481 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
3482 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
3483 +
3484 +               if (err)
3485 +                       break;
3486 +
3487 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3488 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3489 +                   nop == 0x01000000U)
3490 +               {
3491 +                       unsigned long addr;
3492 +
3493 +                       addr = (sethi & 0x003FFFFFU) << 10;
3494 +                       regs->u_regs[UREG_G1] = addr;
3495 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3496 +                       regs->tpc = addr;
3497 +                       regs->tnpc = addr+4;
3498 +                       return 2;
3499 +               }
3500 +       } while (0);
3501 +
3502 +       do { /* PaX: patched PLT emulation #4 */
3503 +               unsigned int mov1, call, mov2;
3504 +
3505 +               err = get_user(mov1, (unsigned int*)regs->tpc);
3506 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
3507 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
3508 +
3509 +               if (err)
3510 +                       break;
3511 +
3512 +               if (mov1 == 0x8210000FU &&
3513 +                   (call & 0xC0000000U) == 0x40000000U &&
3514 +                   mov2 == 0x9E100001U)
3515 +               {
3516 +                       unsigned long addr;
3517 +
3518 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
3519 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
3520 +                       regs->tpc = addr;
3521 +                       regs->tnpc = addr+4;
3522 +                       return 2;
3523 +               }
3524 +       } while (0);
3525 +
3526 +       do { /* PaX: patched PLT emulation #5 */
3527 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
3528 +
3529 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
3530 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
3531 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
3532 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
3533 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
3534 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
3535 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
3536 +
3537 +               if (err)
3538 +                       break;
3539 +
3540 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3541 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
3542 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
3543 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
3544 +                   sllx == 0x83287020 &&
3545 +                   jmpl == 0x81C04005U &&
3546 +                   nop == 0x01000000U)
3547 +               {
3548 +                       unsigned long addr;
3549 +
3550 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
3551 +                       regs->u_regs[UREG_G1] <<= 32;
3552 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
3553 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
3554 +                       regs->tpc = addr;
3555 +                       regs->tnpc = addr+4;
3556 +                       return 2;
3557 +               }
3558 +       } while (0);
3559 +
3560 +       do { /* PaX: patched PLT emulation #6 */
3561 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
3562 +
3563 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
3564 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
3565 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
3566 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
3567 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
3568 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
3569 +
3570 +               if (err)
3571 +                       break;
3572 +
3573 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3574 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
3575 +                   sllx == 0x83287020 &&
3576 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
3577 +                   jmpl == 0x81C04005U &&
3578 +                   nop == 0x01000000U)
3579 +               {
3580 +                       unsigned long addr;
3581 +
3582 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
3583 +                       regs->u_regs[UREG_G1] <<= 32;
3584 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
3585 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
3586 +                       regs->tpc = addr;
3587 +                       regs->tnpc = addr+4;
3588 +                       return 2;
3589 +               }
3590 +       } while (0);
3591 +
3592 +       do { /* PaX: unpatched PLT emulation step 1 */
3593 +               unsigned int sethi, ba, nop;
3594 +
3595 +               err = get_user(sethi, (unsigned int*)regs->tpc);
3596 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
3597 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
3598 +
3599 +               if (err)
3600 +                       break;
3601 +
3602 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
3603 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
3604 +                   nop == 0x01000000U)
3605 +               {
3606 +                       unsigned long addr;
3607 +                       unsigned int save, call;
3608 +
3609 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
3610 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
3611 +                       else
3612 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
3613 +
3614 +                       err = get_user(save, (unsigned int*)addr);
3615 +                       err |= get_user(call, (unsigned int*)(addr+4));
3616 +                       err |= get_user(nop, (unsigned int*)(addr+8));
3617 +                       if (err)
3618 +                               break;
3619 +
3620 +                       if (save == 0x9DE3BFA8U &&
3621 +                           (call & 0xC0000000U) == 0x40000000U &&
3622 +                           nop == 0x01000000U)
3623 +                       {
3624 +                               struct vm_area_struct *vma;
3625 +                               unsigned long call_dl_resolve;
3626 +
3627 +                               down_read(&current->mm->mmap_sem);
3628 +                               call_dl_resolve = current->mm->call_dl_resolve;
3629 +                               up_read(&current->mm->mmap_sem);
3630 +                               if (likely(call_dl_resolve))
3631 +                                       goto emulate;
3632 +
3633 +                               vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
3634 +
3635 +                               down_write(&current->mm->mmap_sem);
3636 +                               if (current->mm->call_dl_resolve) {
3637 +                                       call_dl_resolve = current->mm->call_dl_resolve;
3638 +                                       up_write(&current->mm->mmap_sem);
3639 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3640 +                                       goto emulate;
3641 +                               }
3642 +
3643 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3644 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3645 +                                       up_write(&current->mm->mmap_sem);
3646 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
3647 +                                       return 1;
3648 +                               }
3649 +
3650 +                               pax_insert_vma(vma, call_dl_resolve);
3651 +                               current->mm->call_dl_resolve = call_dl_resolve;
3652 +                               up_write(&current->mm->mmap_sem);
3653 +
3654 +emulate:
3655 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3656 +                               regs->tpc = call_dl_resolve;
3657 +                               regs->tnpc = addr+4;
3658 +                               return 3;
3659 +                       }
3660 +               }
3661 +       } while (0);
3662 +
3663 +       do { /* PaX: unpatched PLT emulation step 2 */
3664 +               unsigned int save, call, nop;
3665 +
3666 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
3667 +               err |= get_user(call, (unsigned int*)regs->tpc);
3668 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
3669 +               if (err)
3670 +                       break;
3671 +
3672 +               if (save == 0x9DE3BFA8U &&
3673 +                   (call & 0xC0000000U) == 0x40000000U &&
3674 +                   nop == 0x01000000U)
3675 +               {
3676 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
3677 +
3678 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
3679 +                       regs->tpc = dl_resolve;
3680 +                       regs->tnpc = dl_resolve+4;
3681 +                       return 3;
3682 +               }
3683 +       } while (0);
3684 +#endif
3685 +
3686 +       return 1;
3687 +}
3688 +
3689 +void pax_report_insns(void *pc, void *sp)
3690 +{
3691 +       unsigned long i;
3692 +
3693 +       printk(KERN_ERR "PAX: bytes at PC: ");
3694 +       for (i = 0; i < 5; i++) {
3695 +               unsigned int c;
3696 +               if (get_user(c, (unsigned int*)pc+i)) {
3697 +                       printk("<invalid address>.");
3698 +                       break;
3699 +               }
3700 +               printk("%08x ", c);
3701 +       }
3702 +       printk("\n");
3703 +}
3704 +#endif
3705 +
3706  asmlinkage void do_sparc64_fault(struct pt_regs *regs)
3707  {
3708         struct mm_struct *mm = current->mm;
3709 @@ -340,8 +702,10 @@
3710                 goto intr_or_no_mm;
3711  
3712         if (test_thread_flag(TIF_32BIT)) {
3713 -               if (!(regs->tstate & TSTATE_PRIV))
3714 +               if (!(regs->tstate & TSTATE_PRIV)) {
3715                         regs->tpc &= 0xffffffff;
3716 +                       regs->tnpc &= 0xffffffff;
3717 +               }
3718                 address &= 0xffffffff;
3719         }
3720  
3721 @@ -350,6 +714,34 @@
3722         if (!vma)
3723                 goto bad_area;
3724  
3725 +#ifdef CONFIG_PAX_PAGEEXEC
3726 +       /* PaX: detect ITLB misses on non-exec pages */
3727 +       if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address &&
3728 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
3729 +       {
3730 +               if (address != regs->tpc)
3731 +                       goto good_area;
3732 +
3733 +               up_read(&mm->mmap_sem);
3734 +               switch (pax_handle_fetch_fault(regs)) {
3735 +
3736 +#ifdef CONFIG_PAX_EMUPLT
3737 +               case 2:
3738 +               case 3:
3739 +                       goto fault_done;
3740 +#endif
3741 +
3742 +#ifdef CONFIG_PAX_RANDEXEC
3743 +               case 4:
3744 +                       goto fault_done;
3745 +#endif
3746 +
3747 +               }
3748 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
3749 +               do_exit(SIGKILL);
3750 +       }
3751 +#endif
3752 +
3753         /* Pure DTLB misses do not tell us whether the fault causing
3754          * load/store/atomic was a write or not, it only says that there
3755          * was no match.  So in such a case we (carefully) read the
3756 diff -uNr linux-2.6.6/arch/sparc64/solaris/misc.c linux-2.6.6.fixed/arch/sparc64/solaris/misc.c
3757 --- linux-2.6.6/arch/sparc64/solaris/misc.c     2004-05-10 04:33:20.000000000 +0200
3758 +++ linux-2.6.6.fixed/arch/sparc64/solaris/misc.c       2004-05-11 10:55:56.000000000 +0200
3759 @@ -56,6 +56,11 @@
3760         struct file *file = NULL;
3761         unsigned long retval, ret_type;
3762  
3763 +#ifdef CONFIG_PAX_RANDEXEC
3764 +       if (flags & MAP_MIRROR)
3765 +               return -EINVAL;
3766 +#endif
3767 +
3768         /* Do we need it here? */
3769         set_personality(PER_SVR4);
3770         if (flags & MAP_NORESERVE) {
3771 diff -uNr linux-2.6.6/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.6.fixed/arch/x86_64/ia32/ia32_binfmt.c
3772 --- linux-2.6.6/arch/x86_64/ia32/ia32_binfmt.c  2004-05-10 04:31:59.000000000 +0200
3773 +++ linux-2.6.6.fixed/arch/x86_64/ia32/ia32_binfmt.c    2004-05-11 12:05:06.000000000 +0200
3774 @@ -185,6 +185,17 @@
3775  //#include <asm/ia32.h>
3776  #include <linux/elf.h>
3777  
3778 +#ifdef CONFIG_PAX_ASLR
3779 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
3780 +
3781 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
3782 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
3783 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
3784 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
3785 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
3786 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 24)
3787 +#endif
3788 +
3789  typedef struct user_i387_ia32_struct elf_fpregset_t;
3790  typedef struct user32_fxsr_struct elf_fpxregset_t;
3791  
3792 @@ -354,6 +365,13 @@
3793                 mpnt->vm_mm = mm;
3794                 mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
3795                 mpnt->vm_end = IA32_STACK_TOP;
3796 +
3797 +#ifdef CONFIG_PAX_PAGEEXEC
3798 +               mpnt->vm_flags = VM_STACK_FLAGS;
3799 +#else
3800 +               mpnt->vm_flags = vm_stack_flags32;
3801 +#endif
3802 +
3803                 if (executable_stack == EXSTACK_ENABLE_X)
3804                         mpnt->vm_flags = vm_stack_flags32 |  VM_EXEC;
3805                 else if (executable_stack == EXSTACK_DISABLE_X)
3806 diff -uNr linux-2.6.6/arch/x86_64/ia32/sys_ia32.c linux-2.6.6.fixed/arch/x86_64/ia32/sys_ia32.c
3807 --- linux-2.6.6/arch/x86_64/ia32/sys_ia32.c     2004-05-10 04:32:29.000000000 +0200
3808 +++ linux-2.6.6.fixed/arch/x86_64/ia32/sys_ia32.c       2004-05-11 10:55:56.000000000 +0200
3809 @@ -212,6 +212,11 @@
3810         if (a.offset & ~PAGE_MASK)
3811                 return -EINVAL; 
3812  
3813 +#ifdef CONFIG_PAX_RANDEXEC
3814 +       if (a.flags & MAP_MIRROR)
3815 +               return -EINVAL;
3816 +#endif
3817 +
3818         if (!(a.flags & MAP_ANONYMOUS)) {
3819                 file = fget(a.fd);
3820                 if (!file)
3821 @@ -1236,6 +1241,11 @@
3822         unsigned long error;
3823         struct file * file = NULL;
3824  
3825 +#ifdef CONFIG_PAX_RANDEXEC
3826 +       if (flags & MAP_MIRROR)
3827 +               return -EINVAL;
3828 +#endif
3829 +
3830         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3831         if (!(flags & MAP_ANONYMOUS)) {
3832                 file = fget(fd);
3833 diff -uNr linux-2.6.6/arch/x86_64/kernel/ptrace.c linux-2.6.6.fixed/arch/x86_64/kernel/ptrace.c
3834 --- linux-2.6.6/arch/x86_64/kernel/ptrace.c     2004-05-10 04:32:27.000000000 +0200
3835 +++ linux-2.6.6.fixed/arch/x86_64/kernel/ptrace.c       2004-05-11 12:01:02.000000000 +0200
3836 @@ -17,6 +17,7 @@
3837  #include <linux/user.h>
3838  #include <linux/security.h>
3839  #include <linux/audit.h>
3840 +#include <linux/grsecurity.h>
3841  
3842  #include <asm/uaccess.h>
3843  #include <asm/pgtable.h>
3844 @@ -213,6 +214,9 @@
3845         if (pid == 1)           /* you may not mess with init */
3846                 goto out_tsk;
3847  
3848 +        if (gr_handle_ptrace(child, request))
3849 +                goto out_tsk;
3850 +
3851         if (request == PTRACE_ATTACH) {
3852                 ret = ptrace_attach(child);
3853                 goto out_tsk;
3854 diff -uNr linux-2.6.6/arch/x86_64/kernel/setup64.c linux-2.6.6.fixed/arch/x86_64/kernel/setup64.c
3855 --- linux-2.6.6/arch/x86_64/kernel/setup64.c    2004-05-10 04:32:26.000000000 +0200
3856 +++ linux-2.6.6.fixed/arch/x86_64/kernel/setup64.c      2004-05-11 10:55:56.000000000 +0200
3857 @@ -43,8 +43,15 @@
3858  
3859  unsigned long __supported_pte_mask = ~0UL;
3860  static int do_not_nx __initdata = 0;
3861 +
3862 +#ifdef CONFIG_PAX_PAGEEXEC
3863 +unsigned long vm_stack_flags = VM_GROWSDOWN | __VM_DATA_DEFAULT_FLAGS;
3864 +unsigned long vm_stack_flags32 = VM_GROWSDOWN | __VM_DATA_DEFAULT_FLAGS;
3865 +#else
3866  unsigned long vm_stack_flags = __VM_STACK_FLAGS; 
3867  unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; 
3868 +#endif
3869 +
3870  unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; 
3871  unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; 
3872  unsigned long vm_force_exec32 = PROT_EXEC; 
3873 diff -uNr linux-2.6.6/arch/x86_64/kernel/sys_x86_64.c linux-2.6.6.fixed/arch/x86_64/kernel/sys_x86_64.c
3874 --- linux-2.6.6/arch/x86_64/kernel/sys_x86_64.c 2004-05-10 04:32:52.000000000 +0200
3875 +++ linux-2.6.6.fixed/arch/x86_64/kernel/sys_x86_64.c   2004-05-11 10:55:56.000000000 +0200
3876 @@ -48,6 +48,11 @@
3877         if (off & ~PAGE_MASK)
3878                 goto out;
3879  
3880 +#ifdef CONFIG_PAX_RANDEXEC
3881 +       if (flags & MAP_MIRROR)
3882 +               goto out;
3883 +#endif
3884 +
3885         error = -EBADF;
3886         file = NULL;
3887         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
3888 @@ -102,6 +107,15 @@
3889         
3890         find_start_end(flags, &begin, &end); 
3891  
3892 +#ifdef CONFIG_PAX_RANDMMAP
3893 +       if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp)) {
3894 +               if (begin == 0x40000000)
3895 +                       begin += current->mm->delta_mmap & 0x0FFFFFFFU;
3896 +               else
3897 +                       begin += current->mm->delta_mmap;
3898 +       }
3899 +#endif
3900 +
3901         if (len > end)
3902                 return -ENOMEM;
3903  
3904 diff -uNr linux-2.6.6/arch/x86_64/mm/fault.c linux-2.6.6.fixed/arch/x86_64/mm/fault.c
3905 --- linux-2.6.6/arch/x86_64/mm/fault.c  2004-05-10 04:31:58.000000000 +0200
3906 +++ linux-2.6.6.fixed/arch/x86_64/mm/fault.c    2004-05-11 10:55:56.000000000 +0200
3907 @@ -23,6 +23,7 @@
3908  #include <linux/vt_kern.h>             /* For unblank_screen() */
3909  #include <linux/compiler.h>
3910  #include <linux/module.h>
3911 +#include <linux/binfmts.h>
3912  
3913  #include <asm/system.h>
3914  #include <asm/uaccess.h>
3915 @@ -217,6 +218,63 @@
3916                 (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
3917  }
3918  
3919 +#ifdef CONFIG_PAX_PAGEEXEC
3920 +/*
3921 + * PaX: decide what to do with offenders (regs->rip = fault address)
3922 + *
3923 + * returns 1 when task should be killed
3924 + *         2 when legitimate ET_EXEC was detected
3925 + */
3926 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3927 +{
3928 +
3929 +#ifdef CONFIG_PAX_RANDEXEC
3930 +       int err;
3931 +
3932 +       if (current->flags & PF_PAX_RANDEXEC) {
3933 +               if (regs->rip >= current->mm->start_code &&
3934 +                   regs->rip < current->mm->end_code)
3935 +               {
3936 +                       if (test_thread_flag(TIF_IA32)) {
3937 +                               unsigned int esp_4;
3938 +
3939 +                               err = get_user(esp_4, (unsigned int*)(regs->rsp-4UL));
3940 +                               if (err || esp_4 == regs->rip)
3941 +                                       return 1;
3942 +                       } else {
3943 +                               unsigned long esp_8;
3944 +
3945 +                               err = get_user(esp_8, (unsigned long*)(regs->rsp-8UL));
3946 +                               if (err || esp_8 == regs->rip)
3947 +                                       return 1;
3948 +                       }
3949 +
3950 +                       regs->rip += current->mm->delta_exec;
3951 +                       return 2;
3952 +               }
3953 +       }
3954 +#endif
3955 +
3956 +       return 1;
3957 +}
3958 +
3959 +void pax_report_insns(void *pc, void *sp)
3960 +{
3961 +       unsigned long i;
3962 +
3963 +       printk(KERN_ERR "PAX: bytes at PC: ");
3964 +       for (i = 0; i < 20; i++) {
3965 +               unsigned int c;
3966 +               if (get_user(c, (unsigned char*)pc+i)) {
3967 +                       printk("<invalid address>.");
3968 +                       break;
3969 +               }
3970 +               printk("%08x ", c);
3971 +       }
3972 +       printk("\n");
3973 +}
3974 +#endif
3975 +
3976  int page_fault_trace; 
3977  int exception_trace = 1;
3978  
3979 @@ -302,6 +360,23 @@
3980   * we can handle it..
3981   */
3982  good_area:
3983 +
3984 +#ifdef CONFIG_PAX_PAGEEXEC
3985 +       if ((current->flags & PF_PAX_PAGEEXEC) && (error_code & 16) && !(vma->vm_flags & VM_EXEC)) {
3986 +               up_read(&mm->mmap_sem);
3987 +               switch(pax_handle_fetch_fault(regs)) {
3988 +
3989 +#ifdef CONFIG_PAX_RANDEXEC
3990 +               case 2:
3991 +                       return;
3992 +#endif
3993 +
3994 +               }
3995 +               pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
3996 +               do_exit(SIGKILL);
3997 +       }
3998 +#endif
3999 +
4000         info.si_code = SEGV_ACCERR;
4001         write = 0;
4002         switch (error_code & 3) {
4003 diff -uNr linux-2.6.6/drivers/char/keyboard.c linux-2.6.6.fixed/drivers/char/keyboard.c
4004 --- linux-2.6.6/drivers/char/keyboard.c 2004-05-10 04:33:22.000000000 +0200
4005 +++ linux-2.6.6.fixed/drivers/char/keyboard.c   2004-05-11 10:55:56.000000000 +0200
4006 @@ -606,6 +606,16 @@
4007              kbd->kbdmode == VC_MEDIUMRAW) && 
4008              value != KVAL(K_SAK))
4009                 return;         /* SAK is allowed even in raw mode */
4010 +
4011 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
4012 +       {
4013 +               void *func = fn_handler[value];
4014 +               if (func == fn_show_state || func == fn_show_ptregs ||
4015 +                   func == fn_show_mem)
4016 +                       return;
4017 +       }
4018 +#endif
4019 +
4020         fn_handler[value](vc, regs);
4021  }
4022  
4023 diff -uNr linux-2.6.6/drivers/char/mem.c linux-2.6.6.fixed/drivers/char/mem.c
4024 --- linux-2.6.6/drivers/char/mem.c      2004-05-10 04:32:37.000000000 +0200
4025 +++ linux-2.6.6.fixed/drivers/char/mem.c        2004-05-11 11:59:26.000000000 +0200
4026 @@ -23,6 +23,7 @@
4027  #include <linux/devfs_fs_kernel.h>
4028  #include <linux/ptrace.h>
4029  #include <linux/device.h>
4030 +#include <linux/grsecurity.h>
4031  
4032  #include <asm/uaccess.h>
4033  #include <asm/io.h>
4034 @@ -39,6 +40,10 @@
4035  extern void tapechar_init(void);
4036  #endif
4037  
4038 +#ifdef CONFIG_GRKERNSEC
4039 +extern struct file_operations grsec_fops;
4040 +#endif
4041 +
4042  /*
4043   * Architectures vary in how they handle caching for addresses
4044   * outside of main memory.
4045 @@ -178,6 +183,12 @@
4046  
4047         if (!valid_phys_addr_range(p, &count))
4048                 return -EFAULT;
4049 +
4050 +#ifdef CONFIG_GRKERNSEC_KMEM
4051 +       gr_handle_mem_write();
4052 +       return -EPERM;
4053 +#endif
4054 +
4055         return do_write_mem(__va(p), p, buf, count, ppos);
4056  }
4057  
4058 @@ -192,6 +203,11 @@
4059                 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
4060  #endif
4061  
4062 +#ifdef CONFIG_GRKERNSEC_KMEM
4063 +       if (gr_handle_mem_mmap(offset, vma))
4064 +               return -EPERM;
4065 +#endif
4066 +
4067         /* Don't try to swap out physical pages.. */
4068         vma->vm_flags |= VM_RESERVED;
4069  
4070 @@ -285,6 +301,11 @@
4071         ssize_t written;
4072         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
4073  
4074 +#ifdef CONFIG_GRKERNSEC_KMEM
4075 +       gr_handle_kmem_write();
4076 +       return -EPERM;
4077 +#endif
4078 +
4079         if (p < (unsigned long) high_memory) {
4080  
4081                 wrote = count;
4082 @@ -411,7 +432,23 @@
4083                         count = size;
4084  
4085                 zap_page_range(vma, addr, count, NULL);
4086 -               zeromap_page_range(vma, addr, count, PAGE_COPY);
4087 +               zeromap_page_range(vma, addr, count, vma->vm_page_prot);
4088 +
4089 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
4090 +               if (vma->vm_flags & VM_MIRROR) {
4091 +                       unsigned long addr_m;
4092 +                       struct vm_area_struct * vma_m;
4093 +
4094 +                       addr_m = vma->vm_start + (unsigned long)vma->vm_private_data;
4095 +                       vma_m = find_vma(mm, addr_m);
4096 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
4097 +                               addr_m = addr + (unsigned long)vma->vm_private_data;
4098 +                               zap_page_range(vma_m, addr_m, count, NULL);
4099 +                       } else
4100 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
4101 +                                      addr, vma->vm_start);
4102 +               }
4103 +#endif
4104  
4105                 size -= count;
4106                 buf += count;
4107 @@ -560,6 +597,16 @@
4108  
4109  static int open_port(struct inode * inode, struct file * filp)
4110  {
4111 +#ifdef CONFIG_GRKERNSEC_KMEM
4112 +       gr_handle_open_port();
4113 +       return -EPERM;
4114 +#endif
4115 +
4116 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
4117 +}
4118 +
4119 +static int open_mem(struct inode * inode, struct file * filp)
4120 +{
4121         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
4122  }
4123  
4124 @@ -568,7 +615,6 @@
4125  #define full_lseek      null_lseek
4126  #define write_zero     write_null
4127  #define read_full       read_zero
4128 -#define open_mem       open_port
4129  #define open_kmem      open_mem
4130  
4131  static struct file_operations mem_fops = {
4132 @@ -666,6 +712,11 @@
4133                 case 9:
4134                         filp->f_op = &urandom_fops;
4135                         break;
4136 +#ifdef CONFIG_GRKERNSEC
4137 +               case 10:
4138 +                       filp->f_op = &grsec_fops;
4139 +                       break;
4140 +#endif
4141                 case 11:
4142                         filp->f_op = &kmsg_fops;
4143                         break;
4144 @@ -697,6 +748,9 @@
4145         {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
4146         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
4147         {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
4148 +#ifdef CONFIG_GRKERNSEC
4149 +       {10,"grsec",   S_IRUSR | S_IWUGO,           &grsec_fops},
4150 +#endif
4151         {11,"kmsg",    S_IRUGO | S_IWUSR,           &kmsg_fops},
4152  };
4153  
4154 diff -uNr linux-2.6.6/drivers/char/random.c linux-2.6.6.fixed/drivers/char/random.c
4155 --- linux-2.6.6/drivers/char/random.c   2004-05-10 04:32:00.000000000 +0200
4156 +++ linux-2.6.6.fixed/drivers/char/random.c     2004-05-11 10:55:56.000000000 +0200
4157 @@ -263,9 +263,15 @@
4158  /*
4159   * Configuration information
4160   */
4161 +#ifdef CONFIG_GRKERNSEC_RANDNET
4162 +#define DEFAULT_POOL_SIZE 1024
4163 +#define SECONDARY_POOL_SIZE 256
4164 +#define BATCH_ENTROPY_SIZE 512
4165 +#else
4166  #define DEFAULT_POOL_SIZE 512
4167  #define SECONDARY_POOL_SIZE 128
4168  #define BATCH_ENTROPY_SIZE 256
4169 +#endif
4170  #define USE_SHA
4171  
4172  /*
4173 @@ -2380,6 +2386,29 @@
4174         return halfMD4Transform(hash, keyptr->secret);
4175  }
4176  
4177 +#ifdef CONFIG_GRKERNSEC
4178 +/* the following function is provided by PaX under the GPL */
4179 +unsigned long get_random_long(void)
4180 +{
4181 +       static time_t rekey_time;
4182 +       static __u32 secret[12];
4183 +       time_t t;
4184 +
4185 +       /*
4186 +        * Pick a random secret every REKEY_INTERVAL seconds
4187 +        */
4188 +       t = get_seconds();
4189 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
4190 +               rekey_time = t;
4191 +               get_random_bytes(secret, sizeof(secret));
4192 +       }
4193 +
4194 +       secret[1] = halfMD4Transform(secret+8, secret);
4195 +       secret[0] = halfMD4Transform(secret+8, secret);
4196 +       return *(unsigned long *)secret;
4197 +}
4198 +#endif
4199 +
4200  #ifdef CONFIG_SYN_COOKIES
4201  /*
4202   * Secure SYN cookie computation. This is the algorithm worked out by
4203 @@ -2479,3 +2508,25 @@
4204         return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */
4205  }
4206  #endif
4207 +
4208 +#ifdef CONFIG_PAX_ASLR
4209 +unsigned long pax_get_random_long(void)
4210 +{
4211 +       static time_t   rekey_time;
4212 +       static __u32    secret[12];
4213 +       time_t          t;
4214 +
4215 +       /*
4216 +        * Pick a random secret every REKEY_INTERVAL seconds.
4217 +        */
4218 +       t = get_seconds();
4219 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
4220 +               rekey_time = t;
4221 +               get_random_bytes(secret, sizeof(secret));
4222 +       }
4223 +
4224 +       secret[1] = halfMD4Transform(secret+8, secret);
4225 +       secret[0] = halfMD4Transform(secret+8, secret);
4226 +       return *(unsigned long *)secret;
4227 +}
4228 +#endif
4229 diff -uNr linux-2.6.6/drivers/char/vt_ioctl.c linux-2.6.6.fixed/drivers/char/vt_ioctl.c
4230 --- linux-2.6.6/drivers/char/vt_ioctl.c 2004-05-10 04:32:54.000000000 +0200
4231 +++ linux-2.6.6.fixed/drivers/char/vt_ioctl.c   2004-05-11 10:55:56.000000000 +0200
4232 @@ -96,6 +96,12 @@
4233         case KDSKBENT:
4234                 if (!perm)
4235                         return -EPERM;
4236 +
4237 +#ifdef CONFIG_GRKERNSEC
4238 +               if (!capable(CAP_SYS_TTY_CONFIG))
4239 +                       return -EPERM;
4240 +#endif
4241 +
4242                 if (!i && v == K_NOSUCHMAP) {
4243                         /* disallocate map */
4244                         key_map = key_maps[s];
4245 @@ -232,6 +238,13 @@
4246                         goto reterr;
4247                 }
4248  
4249 +#ifdef CONFIG_GRKERNSEC
4250 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
4251 +                       return -EPERM;
4252 +                       goto reterr;
4253 +               }
4254 +#endif
4255 +
4256                 q = func_table[i];
4257                 first_free = funcbufptr + (funcbufsize - funcbufleft);
4258                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
4259 diff -uNr linux-2.6.6/drivers/pci/proc.c linux-2.6.6.fixed/drivers/pci/proc.c
4260 --- linux-2.6.6/drivers/pci/proc.c      2004-05-10 04:32:38.000000000 +0200
4261 +++ linux-2.6.6.fixed/drivers/pci/proc.c        2004-05-11 10:55:56.000000000 +0200
4262 @@ -565,7 +565,15 @@
4263  
4264  static void legacy_proc_init(void)
4265  {
4266 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
4267 +#ifdef CONFIG_GRKERNSEC_PROC_USER
4268 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR, NULL);
4269 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
4270 +       struct proc_dir_entry * entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
4271 +#endif
4272 +#else
4273         struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
4274 +#endif
4275         if (entry)
4276                 entry->proc_fops = &proc_pci_operations;
4277  }
4278 @@ -594,7 +602,15 @@
4279  {
4280         struct proc_dir_entry *entry;
4281         struct pci_dev *dev = NULL;
4282 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
4283 +#ifdef CONFIG_GRKERNSEC_PROC_USER
4284 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
4285 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
4286 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
4287 +#endif
4288 +#else
4289         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
4290 +#endif
4291         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
4292         if (entry)
4293                 entry->proc_fops = &proc_bus_pci_dev_operations;
4294 diff -uNr linux-2.6.6/drivers/pnp/pnpbios/bioscalls.c linux-2.6.6.fixed/drivers/pnp/pnpbios/bioscalls.c
4295 --- linux-2.6.6/drivers/pnp/pnpbios/bioscalls.c 2004-05-10 04:32:53.000000000 +0200
4296 +++ linux-2.6.6.fixed/drivers/pnp/pnpbios/bioscalls.c   2004-05-11 10:55:56.000000000 +0200
4297 @@ -79,7 +79,7 @@
4298  set_limit(cpu_gdt_table[cpu][(selname) >> 3], size); \
4299  } while(0)
4300  
4301 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
4302 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
4303  
4304  /*
4305   * At some point we want to use this stack frame pointer to unwind
4306 @@ -107,6 +107,10 @@
4307         struct desc_struct save_desc_40;
4308         int cpu;
4309  
4310 +#ifdef CONFIG_PAX_KERNEXEC
4311 +       unsigned long cr3;
4312 +#endif
4313 +
4314         /*
4315          * PnP BIOSes are generally not terribly re-entrant.
4316          * Also, don't rely on them to save everything correctly.
4317 @@ -115,11 +119,21 @@
4318                 return PNP_FUNCTION_NOT_SUPPORTED;
4319  
4320         cpu = get_cpu();
4321 +
4322 +#ifdef CONFIG_PAX_KERNEXEC
4323 +       pax_open_kernel(flags, cr3);
4324 +#endif
4325 +
4326         save_desc_40 = cpu_gdt_table[cpu][0x40 / 8];
4327         cpu_gdt_table[cpu][0x40 / 8] = bad_bios_desc;
4328  
4329         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
4330 +
4331 +#ifdef CONFIG_PAX_KERNEXEC
4332 +       spin_lock_irq(&pnp_bios_lock);
4333 +#else
4334         spin_lock_irqsave(&pnp_bios_lock, flags);
4335 +#endif
4336  
4337         /* The lock prevents us bouncing CPU here */
4338         if (ts1_size)
4339 @@ -156,9 +170,19 @@
4340                   "i" (0)
4341                 : "memory"
4342         );
4343 +
4344 +#ifdef CONFIG_PAX_KERNEXEC
4345 +       spin_unlock_irq(&pnp_bios_lock);
4346 +#else
4347         spin_unlock_irqrestore(&pnp_bios_lock, flags);
4348 +#endif
4349  
4350         cpu_gdt_table[cpu][0x40 / 8] = save_desc_40;
4351 +
4352 +#ifdef CONFIG_PAX_KERNEXEC
4353 +       pax_close_kernel(flags, cr3);
4354 +#endif
4355 +
4356         put_cpu();
4357  
4358         /* If we get here and this is set then the PnP BIOS faulted on us. */
4359 diff -uNr linux-2.6.6/drivers/scsi/scsi_devinfo.c linux-2.6.6.fixed/drivers/scsi/scsi_devinfo.c
4360 --- linux-2.6.6/drivers/scsi/scsi_devinfo.c     2004-05-10 04:32:27.000000000 +0200
4361 +++ linux-2.6.6.fixed/drivers/scsi/scsi_devinfo.c       2004-05-11 10:55:56.000000000 +0200
4362 @@ -27,7 +27,7 @@
4363  static const char spaces[] = "                "; /* 16 of them */
4364  static unsigned scsi_default_dev_flags;
4365  static LIST_HEAD(scsi_dev_info_list);
4366 -static __init char scsi_dev_flags[256];
4367 +static __initdata char scsi_dev_flags[256];
4368  
4369  /*
4370   * scsi_static_device_list: deprecated list of devices that require
4371 diff -uNr linux-2.6.6/drivers/video/vesafb.c linux-2.6.6.fixed/drivers/video/vesafb.c
4372 --- linux-2.6.6/drivers/video/vesafb.c  2004-05-10 04:32:00.000000000 +0200
4373 +++ linux-2.6.6.fixed/drivers/video/vesafb.c    2004-05-11 10:55:56.000000000 +0200
4374 @@ -239,7 +239,7 @@
4375         if (vesafb_fix.smem_len > 16 * 1024 * 1024)
4376                 vesafb_fix.smem_len = 16 * 1024 * 1024;
4377  
4378 -#ifndef __i386__
4379 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
4380         screen_info.vesapm_seg = 0;
4381  #endif
4382  
4383 diff -uNr linux-2.6.6/fs/binfmt_aout.c linux-2.6.6.fixed/fs/binfmt_aout.c
4384 --- linux-2.6.6/fs/binfmt_aout.c        2004-05-10 04:32:02.000000000 +0200
4385 +++ linux-2.6.6.fixed/fs/binfmt_aout.c  2004-05-11 10:55:56.000000000 +0200
4386 @@ -24,6 +24,7 @@
4387  #include <linux/binfmts.h>
4388  #include <linux/personality.h>
4389  #include <linux/init.h>
4390 +#include <linux/grsecurity.h>
4391  
4392  #include <asm/system.h>
4393  #include <asm/uaccess.h>
4394 @@ -118,10 +119,12 @@
4395  /* If the size of the dump file exceeds the rlimit, then see what would happen
4396     if we wrote the stack, but not the data area.  */
4397  #ifdef __sparc__
4398 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
4399         if ((dump.u_dsize+dump.u_ssize) >
4400             current->rlim[RLIMIT_CORE].rlim_cur)
4401                 dump.u_dsize = 0;
4402  #else
4403 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
4404         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
4405             current->rlim[RLIMIT_CORE].rlim_cur)
4406                 dump.u_dsize = 0;
4407 @@ -129,10 +132,12 @@
4408  
4409  /* Make sure we have enough room to write the stack and data areas. */
4410  #ifdef __sparc__
4411 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
4412         if ((dump.u_ssize) >
4413             current->rlim[RLIMIT_CORE].rlim_cur)
4414                 dump.u_ssize = 0;
4415  #else
4416 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
4417         if ((dump.u_ssize+1) * PAGE_SIZE >
4418             current->rlim[RLIMIT_CORE].rlim_cur)
4419                 dump.u_ssize = 0;
4420 @@ -281,6 +286,8 @@
4421         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
4422         if (rlim >= RLIM_INFINITY)
4423                 rlim = ~0;
4424 +
4425 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
4426         if (ex.a_data + ex.a_bss > rlim)
4427                 return -ENOMEM;
4428  
4429 @@ -309,10 +316,33 @@
4430                 (current->mm->start_brk = N_BSSADDR(ex));
4431         current->mm->free_area_cache = TASK_UNMAPPED_BASE;
4432  
4433 +#ifdef CONFIG_PAX_RANDMMAP
4434 +       if (current->flags & PF_PAX_RANDMMAP)
4435 +               current->mm->free_area_cache += current->mm->delta_mmap;
4436 +#endif
4437 +
4438         current->mm->rss = 0;
4439         current->mm->mmap = NULL;
4440         compute_creds(bprm);
4441         current->flags &= ~PF_FORKNOEXEC;
4442 +
4443 +#ifdef CONFIG_PAX_PAGEEXEC
4444 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
4445 +               current->flags |= PF_PAX_PAGEEXEC;
4446 +
4447 +#ifdef CONFIG_PAX_EMUTRAMP
4448 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
4449 +                       current->flags |= PF_PAX_EMUTRAMP;
4450 +#endif
4451 +
4452 +#ifdef CONFIG_PAX_MPROTECT
4453 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
4454 +                       current->flags |= PF_PAX_MPROTECT;
4455 +#endif
4456 +
4457 +       }
4458 +#endif
4459 +
4460  #ifdef __sparc__
4461         if (N_MAGIC(ex) == NMAGIC) {
4462                 loff_t pos = fd_offset;
4463 @@ -399,7 +429,7 @@
4464  
4465                 down_write(&current->mm->mmap_sem);
4466                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
4467 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
4468 +                               PROT_READ | PROT_WRITE,
4469                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
4470                                 fd_offset + ex.a_text);
4471                 up_write(&current->mm->mmap_sem);
4472 diff -uNr linux-2.6.6/fs/binfmt_elf.c linux-2.6.6.fixed/fs/binfmt_elf.c
4473 --- linux-2.6.6/fs/binfmt_elf.c 2004-05-10 04:32:29.000000000 +0200
4474 +++ linux-2.6.6.fixed/fs/binfmt_elf.c   2004-05-11 11:53:30.000000000 +0200
4475 @@ -37,11 +37,17 @@
4476  #include <linux/pagemap.h>
4477  #include <linux/security.h>
4478  #include <linux/syscalls.h>
4479 +#include <linux/random.h>
4480 +#include <linux/grsecurity.h>
4481  
4482  #include <asm/uaccess.h>
4483  #include <asm/param.h>
4484  #include <asm/pgalloc.h>
4485  
4486 +#ifdef CONFIG_PAX_SEGMEXEC
4487 +#include <asm/desc.h>
4488 +#endif
4489 +
4490  #include <linux/elf.h>
4491  
4492  static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
4493 @@ -85,14 +91,22 @@
4494  
4495  static int set_brk(unsigned long start, unsigned long end)
4496  {
4497 +       current->mm->start_brk = current->mm->brk = end;
4498         start = ELF_PAGEALIGN(start);
4499         end = ELF_PAGEALIGN(end);
4500         if (end > start) {
4501                 unsigned long addr = do_brk(start, end - start);
4502                 if (BAD_ADDR(addr))
4503                         return addr;
4504 +
4505 +#ifdef CONFIG_PAX_RANDEXEC
4506 +               if (current->flags & PF_PAX_RANDEXEC)
4507 +                       addr = __do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start);
4508 +               if (BAD_ADDR(addr))
4509 +                       return addr;
4510 +#endif
4511 +
4512         }
4513 -       current->mm->start_brk = current->mm->brk = end;
4514         return 0;
4515  }
4516  
4517 @@ -456,6 +470,203 @@
4518         return elf_entry;
4519  }
4520  
4521 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
4522 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
4523 +{
4524 +       unsigned long pax_flags = 0UL;
4525 +
4526 +#ifdef CONFIG_PAX_PAGEEXEC
4527 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
4528 +               pax_flags |= PF_PAX_PAGEEXEC;
4529 +#endif
4530 +
4531 +#ifdef CONFIG_PAX_SEGMEXEC
4532 +       if (elf_phdata->p_flags & PF_SEGMEXEC) {
4533 +               pax_flags &= ~PF_PAX_PAGEEXEC;
4534 +               pax_flags |= PF_PAX_SEGMEXEC;
4535 +       }
4536 +#endif
4537 +
4538 +#ifdef CONFIG_PAX_EMUTRAMP
4539 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
4540 +               pax_flags |= PF_PAX_EMUTRAMP;
4541 +#endif
4542 +
4543 +#ifdef CONFIG_PAX_MPROTECT
4544 +       if (elf_phdata->p_flags & PF_MPROTECT)
4545 +               pax_flags |= PF_PAX_MPROTECT;
4546 +#endif
4547 +
4548 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
4549 +
4550 +#ifdef CONFIG_PAX_SOFTMODE
4551 +       if (pax_aslr)
4552 +#endif
4553 +
4554 +       if (elf_phdata->p_flags & PF_RANDMMAP)
4555 +               pax_flags |= PF_PAX_RANDMMAP;
4556 +#endif
4557 +
4558 +#ifdef CONFIG_PAX_RANDEXEC
4559 +
4560 +#ifdef CONFIG_PAX_SOFTMODE
4561 +       if (pax_aslr)
4562 +#endif
4563 +
4564 +       if (elf_phdata->p_flags & PF_RANDEXEC)
4565 +               pax_flags |= PF_PAX_RANDEXEC;
4566 +#endif
4567 +
4568 +       return pax_flags;
4569 +}
4570 +#endif
4571 +
4572 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
4573 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
4574 +{
4575 +       unsigned long pax_flags = 0UL;
4576 +
4577 +#ifdef CONFIG_PAX_PAGEEXEC
4578 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
4579 +               pax_flags |= PF_PAX_PAGEEXEC;
4580 +#endif
4581 +
4582 +#ifdef CONFIG_PAX_SEGMEXEC
4583 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC)) {
4584 +               pax_flags &= ~PF_PAX_PAGEEXEC;
4585 +               pax_flags |= PF_PAX_SEGMEXEC;
4586 +       }
4587 +#endif
4588 +
4589 +#ifdef CONFIG_PAX_EMUTRAMP
4590 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
4591 +               pax_flags |= PF_PAX_EMUTRAMP;
4592 +#endif
4593 +
4594 +#ifdef CONFIG_PAX_MPROTECT
4595 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
4596 +               pax_flags |= PF_PAX_MPROTECT;
4597 +#endif
4598 +
4599 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
4600 +
4601 +#ifdef CONFIG_PAX_SOFTMODE
4602 +       if (pax_aslr)
4603 +#endif
4604 +
4605 +       if (!(elf_phdata->p_flags & PF_NORANDMMAP))
4606 +               pax_flags |= PF_PAX_RANDMMAP;
4607 +#endif
4608 +
4609 +#ifdef CONFIG_PAX_RANDEXEC
4610 +
4611 +#ifdef CONFIG_PAX_SOFTMODE
4612 +       if (pax_aslr)
4613 +#endif
4614 +
4615 +       if (!(elf_phdata->p_flags & PF_NORANDEXEC))
4616 +               pax_flags |= PF_PAX_RANDEXEC;
4617 +#endif
4618 +
4619 +       return pax_flags;
4620 +}
4621 +#endif
4622 +
4623 +#ifdef CONFIG_PAX_EI_PAX
4624 +static int pax_parse_ei_pax(const struct elfhdr * const elf_ex)
4625 +{
4626 +       unsigned long pax_flags = 0UL;
4627 +
4628 +#ifdef CONFIG_PAX_PAGEEXEC
4629 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
4630 +               pax_flags |= PF_PAX_PAGEEXEC;
4631 +#endif
4632 +
4633 +#ifdef CONFIG_PAX_SEGMEXEC
4634 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) {
4635 +               pax_flags &= ~PF_PAX_PAGEEXEC;
4636 +               pax_flags |= PF_PAX_SEGMEXEC;
4637 +       }
4638 +#endif
4639 +
4640 +#ifdef CONFIG_PAX_EMUTRAMP
4641 +       if ((pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
4642 +               pax_flags |= PF_PAX_EMUTRAMP;
4643 +#endif
4644 +
4645 +#ifdef CONFIG_PAX_MPROTECT
4646 +       if ((pax_flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
4647 +               pax_flags |= PF_PAX_MPROTECT;
4648 +#endif
4649 +
4650 +#ifdef CONFIG_PAX_ASLR
4651 +
4652 +#ifdef CONFIG_PAX_SOFTMODE
4653 +       if (pax_aslr)
4654 +#endif
4655 +
4656 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
4657 +               pax_flags |= PF_PAX_RANDMMAP;
4658 +#endif
4659 +
4660 +#ifdef CONFIG_PAX_RANDEXEC
4661 +
4662 +#ifdef CONFIG_PAX_SOFTMODE
4663 +       if (pax_aslr)
4664 +#endif
4665 +
4666 +       if ((elf_ex->e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex->e_type == ET_EXEC) && (pax_flags & PF_PAX_MPROTECT))
4667 +               pax_flags |= PF_PAX_RANDEXEC;
4668 +#endif
4669 +
4670 +       return pax_flags;
4671 +}
4672 +#endif
4673 +
4674 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
4675 +static int pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
4676 +{
4677 +       unsigned long pax_flags = 0UL;
4678 +
4679 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
4680 +       unsigned long i;
4681 +#endif
4682 +
4683 +#ifdef CONFIG_PAX_EI_PAX
4684 +       pax_flags = pax_parse_ei_pax(elf_ex);
4685 +#endif
4686 +
4687 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
4688 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
4689 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
4690 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
4691 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
4692 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
4693 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
4694 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)) ||
4695 +                           ((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))) ||
4696 +                           (!(elf_phdata[i].p_flags & PF_NORANDEXEC) && (elf_ex->e_type == ET_DYN || (elf_phdata[i].p_flags & PF_NOMPROTECT))))
4697 +                               return -EINVAL;
4698 +
4699 +#ifdef CONFIG_PAX_SOFTMODE
4700 +                       if (pax_softmode)
4701 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
4702 +                       else
4703 +#endif
4704 +
4705 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
4706 +                       break;
4707 +               }
4708 +#endif
4709 +
4710 +       if (0 > pax_check_flags(&pax_flags))
4711 +               return -EINVAL;
4712 +
4713 +       current->flags |= pax_flags;
4714 +       return 0;
4715 +}
4716 +#endif
4717 +
4718  /*
4719   * These are the functions used to load ELF style executables and shared
4720   * libraries.  There is no binary dependent code anywhere else.
4721 @@ -488,6 +699,12 @@
4722         struct exec interp_ex;
4723         char passed_fileno[6];
4724         struct files_struct *files;
4725 +
4726 +#ifdef CONFIG_PAX_RANDEXEC
4727 +       unsigned long load_addr_random = 0UL;
4728 +       unsigned long load_bias_random = 0UL;
4729 +#endif
4730 +
4731         int executable_stack = EXSTACK_DEFAULT;
4732         
4733         /* Get the exec-header */
4734 @@ -687,8 +904,52 @@
4735         current->mm->end_data = 0;
4736         current->mm->end_code = 0;
4737         current->mm->mmap = NULL;
4738 +
4739 +#ifdef CONFIG_PAX_DLRESOLVE
4740 +       current->mm->call_dl_resolve = 0UL;
4741 +#endif
4742 +
4743 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
4744 +       current->mm->call_syscall = 0UL;
4745 +#endif
4746 +
4747 +#ifdef CONFIG_PAX_ASLR
4748 +       current->mm->delta_mmap = 0UL;
4749 +       current->mm->delta_exec = 0UL;
4750 +       current->mm->delta_stack = 0UL;
4751 +#endif
4752 +
4753         current->flags &= ~PF_FORKNOEXEC;
4754  
4755 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
4756 +       if (0 > pax_parse_elf_flags(&elf_ex, elf_phdata)) {
4757 +               send_sig(SIGKILL, current, 0);
4758 +               goto out_free_dentry;
4759 +       }
4760 +#endif
4761 +
4762 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
4763 +       pax_set_flags(bprm);
4764 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
4765 +       if (pax_set_flags_func)
4766 +               (pax_set_flags_func)(bprm);
4767 +#endif
4768 +
4769 +#ifdef CONFIG_PAX_DLRESOLVE
4770 +       if (current->flags & PF_PAX_PAGEEXEC)
4771 +               current->mm->call_dl_resolve = 0UL;
4772 +#endif
4773 +
4774 +#ifdef CONFIG_PAX_ASLR
4775 +       if (current->flags & PF_PAX_RANDMMAP) {
4776 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
4777 +
4778 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
4779 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
4780 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
4781 +       }
4782 +#endif
4783 +
4784         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
4785            may depend on the personality.  */
4786         SET_PERSONALITY(elf_ex, ibcs2_interpreter);
4787 @@ -697,6 +958,12 @@
4788            change some of these later */
4789         current->mm->rss = 0;
4790         current->mm->free_area_cache = TASK_UNMAPPED_BASE;
4791 +
4792 +#ifdef CONFIG_PAX_RANDMMAP
4793 +       if (current->flags & PF_PAX_RANDMMAP)
4794 +               current->mm->free_area_cache += current->mm->delta_mmap;
4795 +#endif
4796 +
4797         retval = setup_arg_pages(bprm, executable_stack);
4798         if (retval < 0) {
4799                 send_sig(SIGKILL, current, 0);
4800 @@ -752,11 +1019,85 @@
4801                            base, as well as whatever program they might try to exec.  This
4802                            is because the brk will follow the loader, and is not movable.  */
4803                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
4804 +
4805 +#ifdef CONFIG_PAX_RANDMMAP
4806 +                       /* PaX: randomize base address at the default exe base if requested */
4807 +                       if (current->flags & PF_PAX_RANDMMAP) {
4808 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
4809 +                               elf_flags |= MAP_FIXED;
4810 +                       }
4811 +#endif
4812 +
4813                 }
4814  
4815 -               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
4816 -               if (BAD_ADDR(error))
4817 -                       continue;
4818 +#ifdef CONFIG_PAX_RANDEXEC
4819 +               if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) {
4820 +                       error = -ENOMEM;
4821 +
4822 +#ifdef CONFIG_PAX_PAGEEXEC
4823 +                       if (current->flags & PF_PAX_PAGEEXEC)
4824 +                               error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags);
4825 +#endif
4826 +
4827 +#ifdef CONFIG_PAX_SEGMEXEC
4828 +                       if (current->flags & PF_PAX_SEGMEXEC) {
4829 +                               unsigned long addr, len;
4830 +
4831 +                               addr = ELF_PAGESTART(load_bias + vaddr);
4832 +                               len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
4833 +                               if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)
4834 +                                       continue;
4835 +                               down_write(&current->mm->mmap_sem);
4836 +                               error = __do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT);
4837 +                               up_write(&current->mm->mmap_sem);
4838 +                       }
4839 +#endif
4840 +
4841 +                       if (BAD_ADDR(error))
4842 +                               continue;
4843 +
4844 +                       /* PaX: mirror at a randomized base */
4845 +                       down_write(&current->mm->mmap_sem);
4846 +
4847 +                       if (!load_addr_set) {
4848 +                               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);
4849 +                               if (BAD_ADDR(load_addr_random)) {
4850 +                                       up_write(&current->mm->mmap_sem);
4851 +                                       continue;
4852 +                               }
4853 +                               load_bias_random = load_addr_random - vaddr;
4854 +                       }
4855 +
4856 +#ifdef CONFIG_PAX_PAGEEXEC
4857 +                       if (current->flags & PF_PAX_PAGEEXEC)
4858 +                               load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
4859 +#endif
4860 +
4861 +#ifdef CONFIG_PAX_SEGMEXEC
4862 +                       if (current->flags & PF_PAX_SEGMEXEC) {
4863 +                               if (elf_prot & PROT_EXEC) {
4864 +                                       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);
4865 +                                       if (!BAD_ADDR(load_addr_random)) {
4866 +                                               load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
4867 +                                               if (!BAD_ADDR(load_addr_random))
4868 +                                                       load_addr_random -= SEGMEXEC_TASK_SIZE;
4869 +                                       }
4870 +                               } else
4871 +                                       load_addr_random = __do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error);
4872 +                       }
4873 +#endif
4874 +
4875 +                       up_write(&current->mm->mmap_sem);
4876 +                       if (BAD_ADDR(load_addr_random))
4877 +                               continue;
4878 +               } else
4879 +#endif
4880 +
4881 +               {
4882 +                       error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
4883 +                       if (BAD_ADDR(error))
4884 +                               continue;
4885 +               }
4886  
4887                 if (!load_addr_set) {
4888                         load_addr_set = 1;
4889 @@ -767,6 +1108,11 @@
4890                                 load_addr += load_bias;
4891                                 reloc_func_desc = load_bias;
4892                         }
4893 +
4894 +#ifdef CONFIG_PAX_RANDEXEC
4895 +                       current->mm->delta_exec = load_addr_random - load_addr;
4896 +#endif
4897 +
4898                 }
4899                 k = elf_ppnt->p_vaddr;
4900                 if (k < start_code) start_code = k;
4901 @@ -806,6 +1152,16 @@
4902         start_data += load_bias;
4903         end_data += load_bias;
4904  
4905 +#ifdef CONFIG_PAX_RANDMMAP
4906 +
4907 +#ifdef CONFIG_PAX_SOFTMODE
4908 +       if (pax_aslr)
4909 +#endif
4910 +
4911 +       elf_brk += pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
4912 +#undef pax_delta_mask
4913 +#endif
4914 +
4915         /* Calling set_brk effectively mmaps the pages that we need
4916          * for the bss and break sections.  We must do this before
4917          * mapping in the interpreter, to make sure it doesn't wind
4918 @@ -886,6 +1242,26 @@
4919         ELF_PLAT_INIT(regs, reloc_func_desc);
4920  #endif
4921  
4922 +#ifdef CONFIG_PAX_SEGMEXEC
4923 +       i = get_cpu();
4924 +
4925 +#ifdef CONFIG_PAX_KERNEXEC
4926 +       {
4927 +               unsigned long flags, cr3;
4928 +
4929 +               pax_open_kernel(flags, cr3);
4930 +#endif
4931 +
4932 +       pax_switch_segments(current, i);
4933 +
4934 +#ifdef CONFIG_PAX_KERNEXEC
4935 +               pax_close_kernel(flags, cr3);
4936 +       }
4937 +#endif
4938 +
4939 +       put_cpu();
4940 +#endif
4941 +
4942         start_thread(regs, elf_entry, bprm->p);
4943         if (unlikely(current->ptrace & PT_PTRACED)) {
4944                 if (current->ptrace & PT_TRACE_EXEC)
4945 @@ -1098,8 +1474,11 @@
4946  #undef DUMP_SEEK
4947  
4948  #define DUMP_WRITE(addr, nr)   \
4949 +       do { \
4950 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
4951         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
4952 -               goto end_coredump;
4953 +               goto end_coredump; \
4954 +       } while (0);
4955  #define DUMP_SEEK(off) \
4956         if (!dump_seek(file, (off))) \
4957                 goto end_coredump;
4958 diff -uNr linux-2.6.6/fs/binfmt_misc.c linux-2.6.6.fixed/fs/binfmt_misc.c
4959 --- linux-2.6.6/fs/binfmt_misc.c        2004-05-10 04:32:28.000000000 +0200
4960 +++ linux-2.6.6.fixed/fs/binfmt_misc.c  2004-05-11 10:55:56.000000000 +0200
4961 @@ -108,9 +108,11 @@
4962         int retval;
4963  
4964         retval = -ENOEXEC;
4965 -       if (!enabled)
4966 +       if (!enabled || bprm->misc)
4967                 goto _ret;
4968  
4969 +       bprm->misc++;
4970 +
4971         /* to keep locking time low, we copy the interpreter string */
4972         read_lock(&entries_lock);
4973         fmt = check_file(bprm);
4974 diff -uNr linux-2.6.6/fs/buffer.c linux-2.6.6.fixed/fs/buffer.c
4975 --- linux-2.6.6/fs/buffer.c     2004-05-10 04:32:38.000000000 +0200
4976 +++ linux-2.6.6.fixed/fs/buffer.c       2004-05-11 10:55:56.000000000 +0200
4977 @@ -37,6 +37,7 @@
4978  #include <linux/bio.h>
4979  #include <linux/notifier.h>
4980  #include <linux/cpu.h>
4981 +#include <linux/grsecurity.h>
4982  #include <asm/bitops.h>
4983  
4984  static void invalidate_bh_lrus(void);
4985 @@ -2168,6 +2169,9 @@
4986         int err;
4987  
4988         err = -EFBIG;
4989 +
4990 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
4991 +
4992          limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
4993         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
4994                 send_sig(SIGXFSZ, current, 0);
4995 diff -uNr linux-2.6.6/fs/dcache.c linux-2.6.6.fixed/fs/dcache.c
4996 --- linux-2.6.6/fs/dcache.c     2004-05-10 04:32:01.000000000 +0200
4997 +++ linux-2.6.6.fixed/fs/dcache.c       2004-05-11 10:55:56.000000000 +0200
4998 @@ -1262,7 +1262,7 @@
4999   *
5000   * "buflen" should be positive. Caller holds the dcache_lock.
5001   */
5002 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
5003 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
5004                         struct dentry *root, struct vfsmount *rootmnt,
5005                         char *buffer, int buflen)
5006  {
5007 diff -uNr linux-2.6.6/fs/exec.c linux-2.6.6.fixed/fs/exec.c
5008 --- linux-2.6.6/fs/exec.c       2004-05-10 04:32:28.000000000 +0200
5009 +++ linux-2.6.6.fixed/fs/exec.c 2004-05-11 11:44:39.000000000 +0200
5010 @@ -46,6 +46,8 @@
5011  #include <linux/security.h>
5012  #include <linux/syscalls.h>
5013  #include <linux/rmap.h>
5014 +#include <linux/random.h>
5015 +#include <linux/grsecurity.h>
5016  
5017  #include <asm/uaccess.h>
5018  #include <asm/pgalloc.h>
5019 @@ -62,6 +64,20 @@
5020  static struct linux_binfmt *formats;
5021  static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
5022  
5023 +#ifdef CONFIG_PAX_SOFTMODE
5024 +
5025 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
5026 +unsigned int pax_aslr=1;
5027 +#endif
5028 +
5029 +unsigned int pax_softmode;
5030 +#endif
5031 +
5032 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
5033 +void (*pax_set_flags_func)(struct linux_binprm * bprm);
5034 +EXPORT_SYMBOL(pax_set_flags_func);
5035 +#endif
5036 +
5037  int register_binfmt(struct linux_binfmt * fmt)
5038  {
5039         struct linux_binfmt ** tmp = &formats;
5040 @@ -303,7 +319,12 @@
5041         pte_t * pte;
5042         struct pte_chain *pte_chain;
5043  
5044 +#ifdef CONFIG_PAX_SEGMEXEC
5045 +       if (page_count(page) != 1 && (!(tsk->flags & PF_PAX_SEGMEXEC) || page_count(page) != 3))
5046 +#else
5047         if (page_count(page) != 1)
5048 +#endif
5049 +
5050                 printk(KERN_ERR "mem_map disagrees with %p at %08lx\n",
5051                                 page, address);
5052  
5053 @@ -322,8 +343,18 @@
5054                 pte_unmap(pte);
5055                 goto out;
5056         }
5057 +
5058 +#ifdef CONFIG_PAX_SEGMEXEC
5059 +       if (page_count(page) == 1) {
5060 +#endif
5061 +
5062         lru_cache_add_active(page);
5063         flush_dcache_page(page);
5064 +
5065 +#ifdef CONFIG_PAX_SEGMEXEC
5066 +       }
5067 +#endif
5068 +
5069         set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, prot))));
5070         pte_chain = page_add_rmap(page, pte, pte_chain);
5071         pte_unmap(pte);
5072 @@ -350,6 +381,10 @@
5073         int i;
5074         long arg_size;
5075  
5076 +#ifdef CONFIG_PAX_SEGMEXEC
5077 +       struct vm_area_struct *mpnt_m = NULL;
5078 +#endif
5079 +
5080  #ifdef CONFIG_STACK_GROWSUP
5081         /* Move the argument and environment strings to the bottom of the
5082          * stack space.
5083 @@ -409,6 +444,16 @@
5084         if (!mpnt)
5085                 return -ENOMEM;
5086  
5087 +#ifdef CONFIG_PAX_SEGMEXEC
5088 +       if ((current->flags & PF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
5089 +               mpnt_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
5090 +               if (!mpnt_m) {
5091 +                       kmem_cache_free(vm_area_cachep, mpnt);
5092 +                       return -ENOMEM;
5093 +               }
5094 +       }
5095 +#endif
5096 +
5097         if (security_vm_enough_memory(arg_size >> PAGE_SHIFT)) {
5098                 kmem_cache_free(vm_area_cachep, mpnt);
5099                 return -ENOMEM;
5100 @@ -425,6 +470,11 @@
5101                 mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
5102                 mpnt->vm_end = STACK_TOP;
5103  #endif
5104 +#ifdef CONFIG_PAX_PAGEEXEC
5105 +               if (!(current->flags & PF_PAX_PAGEEXEC))
5106 +                       mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7];
5107 +               else
5108 +#endif
5109                 /* Adjust stack execute permissions; explicitly enable
5110                  * for EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X
5111                  * and leave alone (arch default) otherwise. */
5112 @@ -442,6 +492,26 @@
5113                 mpnt->vm_private_data = (void *) 0;
5114                 insert_vm_struct(mm, mpnt);
5115                 mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
5116 +
5117 +#ifdef CONFIG_PAX_SEGMEXEC
5118 +               if (mpnt_m) {
5119 +                       *mpnt_m = *mpnt;
5120 +                       INIT_LIST_HEAD(&mpnt_m->shared);
5121 +                       if (!(VM_STACK_FLAGS & VM_EXEC)) {
5122 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
5123 +                               mpnt_m->vm_page_prot = PAGE_NONE;
5124 +                       }
5125 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
5126 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
5127 +                       mpnt_m->vm_flags |= VM_MIRROR;
5128 +                       mpnt->vm_flags |= VM_MIRROR;
5129 +                       mpnt_m->vm_private_data = (void *)(mpnt->vm_start - mpnt_m->vm_start);
5130 +                       mpnt->vm_private_data = (void *)(mpnt_m->vm_start - mpnt->vm_start);
5131 +                       insert_vm_struct(mm, mpnt_m);
5132 +                       current->mm->total_vm = (mpnt_m->vm_end - mpnt_m->vm_start) >> PAGE_SHIFT;
5133 +               }
5134 +#endif
5135 +
5136         }
5137  
5138         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
5139 @@ -450,6 +520,15 @@
5140                         bprm->page[i] = NULL;
5141                         put_dirty_page(current, page, stack_base,
5142                                         mpnt->vm_page_prot);
5143 +
5144 +#if defined(CONFIG_PAX_SEGMEXEC) && defined(CONFIG_PAX_MPROTECT)
5145 +                       if (mpnt_m) {
5146 +                               page_cache_get(page);
5147 +                               put_dirty_page(current, page, stack_base + SEGMEXEC_TASK_SIZE,
5148 +                                               mpnt_m->vm_page_prot);
5149 +                       }
5150 +#endif
5151 +
5152                 }
5153                 stack_base += PAGE_SIZE;
5154         }
5155 @@ -845,6 +924,30 @@
5156         }
5157         current->comm[i] = '\0';
5158  
5159 +#ifdef CONFIG_PAX_PAGEEXEC
5160 +       current->flags &= ~PF_PAX_PAGEEXEC;
5161 +#endif
5162 +
5163 +#ifdef CONFIG_PAX_EMUTRAMP
5164 +       current->flags &= ~PF_PAX_EMUTRAMP;
5165 +#endif
5166 +
5167 +#ifdef CONFIG_PAX_MPROTECT
5168 +       current->flags &= ~PF_PAX_MPROTECT;
5169 +#endif
5170 +
5171 +#ifdef CONFIG_PAX_ASLR
5172 +       current->flags &= ~PF_PAX_RANDMMAP;
5173 +#endif
5174 +
5175 +#ifdef CONFIG_PAX_RANDEXEC
5176 +       current->flags &= ~PF_PAX_RANDEXEC;
5177 +#endif
5178 +
5179 +#ifdef CONFIG_PAX_SEGMEXEC
5180 +       current->flags &= ~PF_PAX_SEGMEXEC;
5181 +#endif
5182 +
5183         flush_thread();
5184  
5185         if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
5186 @@ -913,6 +1016,9 @@
5187         if (retval)
5188                 return retval;
5189  
5190 +       if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
5191 +               return -EACCES;
5192 +
5193         memset(bprm->buf,0,BINPRM_BUF_SIZE);
5194         return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
5195  }
5196 @@ -942,6 +1048,7 @@
5197         task_lock(current);
5198         unsafe = unsafe_exec(current);
5199         security_bprm_apply_creds(bprm, unsafe);
5200 +       gr_handle_chroot_caps(current);
5201         task_unlock(current);
5202  }
5203  
5204 @@ -1082,6 +1189,11 @@
5205         struct file *file;
5206         int retval;
5207         int i;
5208 +#ifdef CONFIG_GRKERNSEC
5209 +       struct file *old_exec_file;
5210 +       struct acl_subject_label *old_acl;
5211 +       struct rlimit old_rlim[RLIM_NLIMITS];
5212 +#endif
5213  
5214         sched_balance_exec();
5215  
5216 @@ -1091,13 +1203,39 @@
5217         if (IS_ERR(file))
5218                 return retval;
5219  
5220 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
5221 +
5222 +       if (gr_handle_nproc()) {
5223 +               allow_write_access(file);
5224 +               fput(file);
5225 +               return -EAGAIN;
5226 +       }
5227 +
5228 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
5229 +               allow_write_access(file);
5230 +               fput(file);
5231 +               return -EACCES;
5232 +       }
5233 +
5234 +
5235         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
5236 +
5237 +#ifdef CONFIG_PAX_RANDUSTACK
5238 +
5239 +#ifdef CONFIG_PAX_SOFTMODE
5240 +       if (pax_aslr)
5241 +#endif
5242 +
5243 +       bprm.p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
5244 +#endif
5245 +
5246         memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
5247  
5248         bprm.file = file;
5249         bprm.filename = filename;
5250         bprm.interp = filename;
5251         bprm.sh_bang = 0;
5252 +       bprm.misc = 0;
5253         bprm.loader = 0;
5254         bprm.exec = 0;
5255         bprm.security = NULL;
5256 @@ -1126,11 +1264,26 @@
5257         if (retval < 0)
5258                 goto out;
5259  
5260 +       if (!gr_tpe_allow(file)) {
5261 +               retval = -EACCES;
5262 +               goto out;
5263 +       }
5264 +
5265 +       if (gr_check_crash_exec(file)) {
5266 +               retval = -EACCES;
5267 +               goto out;
5268 +       }
5269 +
5270         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
5271         if (retval < 0)
5272                 goto out;
5273  
5274         bprm.exec = bprm.p;
5275 +
5276 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
5277 +
5278 +       gr_handle_exec_args(&bprm, argv);
5279 +
5280         retval = copy_strings(bprm.envc, envp, &bprm);
5281         if (retval < 0)
5282                 goto out;
5283 @@ -1139,8 +1292,22 @@
5284         if (retval < 0)
5285                 goto out;
5286  
5287 +#ifdef CONFIG_GRKERNSEC
5288 +       old_acl = current->acl;
5289 +       memcpy(old_rlim, current->rlim, sizeof(old_rlim));
5290 +       old_exec_file = current->exec_file;
5291 +       get_file(file);
5292 +       current->exec_file = file;
5293 +#endif
5294 +
5295 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
5296 +
5297         retval = search_binary_handler(&bprm,regs);
5298         if (retval >= 0) {
5299 +#ifdef CONFIG_GRKERNSEC
5300 +               if (old_exec_file)
5301 +                       fput(old_exec_file);
5302 +#endif
5303                 free_arg_pages(&bprm);
5304  
5305                 /* execve success */
5306 @@ -1148,6 +1315,13 @@
5307                 return retval;
5308         }
5309  
5310 +#ifdef CONFIG_GRKERNSEC
5311 +       current->acl = old_acl;
5312 +       memcpy(current->rlim, old_rlim, sizeof(old_rlim));
5313 +       fput(current->exec_file);
5314 +       current->exec_file = old_exec_file;
5315 +#endif
5316 +
5317  out:
5318         /* Something went wrong, return the inode and free the argument pages*/
5319         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
5320 @@ -1305,6 +1479,128 @@
5321         *out_ptr = 0;
5322  }
5323  
5324 +int pax_check_flags(unsigned long * flags)
5325 +{
5326 +       int retval = 0;
5327 +
5328 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
5329 +       if (*flags & PF_PAX_SEGMEXEC)
5330 +       {
5331 +               *flags &= ~PF_PAX_SEGMEXEC;
5332 +               retval = -EINVAL;
5333 +       }
5334 +#endif
5335 +
5336 +       if ((*flags & PF_PAX_PAGEEXEC)
5337 +
5338 +#ifdef CONFIG_PAX_PAGEEXEC
5339 +           &&  (*flags & PF_PAX_SEGMEXEC)
5340 +#endif
5341 +
5342 +          )
5343 +       {
5344 +               *flags &= ~PF_PAX_PAGEEXEC;
5345 +               retval = -EINVAL;
5346 +       }
5347 +
5348 +       if ((*flags & PF_PAX_MPROTECT)
5349 +
5350 +#ifdef CONFIG_PAX_MPROTECT
5351 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
5352 +#endif
5353 +
5354 +          )
5355 +       {
5356 +               *flags &= ~PF_PAX_MPROTECT;
5357 +               retval = -EINVAL;
5358 +       }
5359 +
5360 +       if ((*flags & PF_PAX_EMUTRAMP)
5361 +
5362 +#ifdef CONFIG_PAX_EMUTRAMP
5363 +           && !(*flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))
5364 +#endif
5365 +
5366 +          )
5367 +       {
5368 +               *flags &= ~PF_PAX_EMUTRAMP;
5369 +               retval = -EINVAL;
5370 +       }
5371 +
5372 +       if ((*flags & PF_PAX_RANDEXEC)
5373 +
5374 +#ifdef CONFIG_PAX_RANDEXEC
5375 +           && !(*flags & PF_PAX_MPROTECT)
5376 +#endif
5377 +
5378 +          )
5379 +       {
5380 +               *flags &= ~PF_PAX_RANDEXEC;
5381 +               retval = -EINVAL;
5382 +       }
5383 +
5384 +       return retval;
5385 +}
5386 +
5387 +EXPORT_SYMBOL(pax_check_flags);
5388 +
5389 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5390 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
5391 +{
5392 +       struct task_struct *tsk = current;
5393 +       struct mm_struct *mm = current->mm;
5394 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
5395 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
5396 +       char* path_exec=NULL;
5397 +       char* path_fault=NULL;
5398 +       unsigned long start=0UL, end=0UL, offset=0UL;
5399 +
5400 +       if (buffer_exec && buffer_fault) {
5401 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
5402 +
5403 +               down_read(&mm->mmap_sem);
5404 +               vma = mm->mmap;
5405 +               while (vma && (!vma_exec || !vma_fault)) {
5406 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
5407 +                               vma_exec = vma;
5408 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
5409 +                               vma_fault = vma;
5410 +                       vma = vma->vm_next;
5411 +               }
5412 +               if (vma_exec) {
5413 +                       path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
5414 +                       if (IS_ERR(path_exec))
5415 +                               path_exec = "<path too long>";
5416 +               }
5417 +               if (vma_fault) {
5418 +                       start = vma_fault->vm_start;
5419 +                       end = vma_fault->vm_end;
5420 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
5421 +                       if (vma_fault->vm_file) {
5422 +                               path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
5423 +                               if (IS_ERR(path_fault))
5424 +                                       path_fault = "<path too long>";
5425 +                       } else
5426 +                               path_fault = "<anonymous mapping>";
5427 +               }
5428 +               up_read(&mm->mmap_sem);
5429 +       }
5430 +#ifdef CONFIG_GRKERNSEC
5431 +       if (tsk->curr_ip)
5432 +               printk(KERN_ERR "PAX: execution attempt from %u.%u.%u.%u in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->curr_ip), path_fault, start, end, offset);
5433 +       else
5434 +#endif
5435 +       printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
5436 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
5437 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
5438 +                       tsk->uid, tsk->euid, pc, sp);
5439 +       if (buffer_exec) free_page((unsigned long)buffer_exec);
5440 +       if (buffer_fault) free_page((unsigned long)buffer_fault);
5441 +       pax_report_insns(pc, sp);
5442 +       do_coredump(SIGKILL, SIGKILL, regs);
5443 +}
5444 +#endif
5445 +
5446  static void zap_threads (struct mm_struct *mm)
5447  {
5448         struct task_struct *g, *p;
5449 @@ -1374,6 +1670,7 @@
5450         current->signal->group_exit_code = exit_code;
5451         coredump_wait(mm);
5452  
5453 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
5454         if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
5455                 goto fail_unlock;
5456  
5457 @@ -1393,7 +1690,7 @@
5458                 goto close_fail;
5459         if (!file->f_op->write)
5460                 goto close_fail;
5461 -       if (do_truncate(file->f_dentry, 0) != 0)
5462 +       if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
5463                 goto close_fail;
5464  
5465         retval = binfmt->core_dump(signr, regs, file);
5466 diff -uNr linux-2.6.6/fs/fcntl.c linux-2.6.6.fixed/fs/fcntl.c
5467 --- linux-2.6.6/fs/fcntl.c      2004-05-10 04:32:53.000000000 +0200
5468 +++ linux-2.6.6.fixed/fs/fcntl.c        2004-05-11 10:55:56.000000000 +0200
5469 @@ -14,6 +14,7 @@
5470  #include <linux/module.h>
5471  #include <linux/security.h>
5472  #include <linux/ptrace.h>
5473 +#include <linux/grsecurity.h>
5474  
5475  #include <asm/poll.h>
5476  #include <asm/siginfo.h>
5477 @@ -86,6 +87,9 @@
5478         int error;
5479  
5480         error = -EINVAL;
5481 +
5482 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
5483 +
5484         if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
5485                 goto out;
5486  
5487 @@ -105,6 +109,9 @@
5488         }
5489         
5490         error = -EMFILE;
5491 +
5492 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
5493 +
5494         if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
5495                 goto out;
5496  
5497 @@ -154,6 +161,8 @@
5498         struct file * file, *tofree;
5499         struct files_struct * files = current->files;
5500  
5501 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
5502 +
5503         spin_lock(&files->file_lock);
5504         if (!(file = fcheck(oldfd)))
5505                 goto out_unlock;
5506 @@ -493,13 +502,15 @@
5507         if (pid > 0) {
5508                 p = find_task_by_pid(pid);
5509                 if (p) {
5510 -                       send_sigio_to_task(p, fown, fd, band);
5511 +                       if (!gr_check_protected_task(p))
5512 +                               send_sigio_to_task(p, fown, fd, band);
5513                 }
5514         } else {
5515                 struct list_head *l;
5516                 struct pid *pidptr;
5517                 for_each_task_pid(-pid, PIDTYPE_PGID, p, l, pidptr) {
5518 -                       send_sigio_to_task(p, fown, fd, band);
5519 +                       if (!gr_check_protected_task(p) && !gr_pid_is_chrooted(p))
5520 +                               send_sigio_to_task(p, fown, fd, band);
5521                 }
5522         }
5523         read_unlock(&tasklist_lock);
5524 diff -uNr linux-2.6.6/fs/Kconfig linux-2.6.6.fixed/fs/Kconfig
5525 --- linux-2.6.6/fs/Kconfig      2004-05-10 04:32:38.000000000 +0200
5526 +++ linux-2.6.6.fixed/fs/Kconfig        2004-05-11 10:55:56.000000000 +0200
5527 @@ -781,6 +781,7 @@
5528  
5529  config PROC_KCORE
5530         bool
5531 +       depends on !GRKERNSEC_PROC_ADD
5532         default y if !ARM
5533  
5534  config SYSFS
5535 diff -uNr linux-2.6.6/fs/namei.c linux-2.6.6.fixed/fs/namei.c
5536 --- linux-2.6.6/fs/namei.c      2004-05-10 04:32:27.000000000 +0200
5537 +++ linux-2.6.6.fixed/fs/namei.c        2004-05-11 11:29:49.000000000 +0200
5538 @@ -27,6 +27,7 @@
5539  #include <linux/security.h>
5540  #include <linux/mount.h>
5541  #include <linux/audit.h>
5542 +#include <linux/grsecurity.h>
5543  #include <asm/namei.h>
5544  #include <asm/uaccess.h>
5545  
5546 @@ -413,6 +414,13 @@
5547         err = security_inode_follow_link(dentry, nd);
5548         if (err)
5549                 goto loop;
5550 +
5551 +       if (gr_handle_follow_link(dentry->d_parent->d_inode,
5552 +                                 dentry->d_inode, dentry, nd->mnt)) {
5553 +               err = -EACCES;
5554 +               goto loop;
5555 +       }
5556 +
5557         current->link_count++;
5558         current->total_link_count++;
5559         touch_atime(nd->mnt, dentry);
5560 @@ -764,6 +772,10 @@
5561                                 break;
5562                 }
5563  return_base:
5564 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
5565 +                       path_release(nd);
5566 +                       return -ENOENT;
5567 +               }
5568                 return 0;
5569  out_dput:
5570                 dput(next.dentry);
5571 @@ -1225,7 +1237,7 @@
5572                 if (!error) {
5573                         DQUOT_INIT(inode);
5574                         
5575 -                       error = do_truncate(dentry, 0);
5576 +                       error = do_truncate(dentry, 0, nd->mnt);
5577                 }
5578                 put_write_access(inode);
5579                 if (error)
5580 @@ -1276,6 +1288,17 @@
5581                 error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
5582                 if (error)
5583                         return error;
5584 +
5585 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
5586 +                       error = -EPERM;
5587 +                       goto exit;
5588 +               }
5589 +
5590 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
5591 +                       error = -EACCES;
5592 +                       goto exit;
5593 +               }
5594 +
5595                 goto ok;
5596         }
5597  
5598 @@ -1309,9 +1332,19 @@
5599  
5600         /* Negative dentry, just create the file */
5601         if (!dentry->d_inode) {
5602 +               if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
5603 +                       error = -EACCES;
5604 +                       up(&dir->d_inode->i_sem);
5605 +                       goto exit_dput;
5606 +               }
5607 +
5608                 if (!IS_POSIXACL(dir->d_inode))
5609                         mode &= ~current->fs->umask;
5610                 error = vfs_create(dir->d_inode, dentry, mode, nd);
5611 +
5612 +               if (!error)
5613 +                       gr_handle_create(dentry, nd->mnt);
5614 +
5615                 up(&dir->d_inode->i_sem);
5616                 dput(nd->dentry);
5617                 nd->dentry = dentry;
5618 @@ -1326,6 +1359,25 @@
5619         /*
5620          * It already exists.
5621          */
5622 +
5623 +       if (gr_handle_rawio(dentry->d_inode)) {
5624 +               error = -EPERM;
5625 +               up(&dir->d_inode->i_sem);
5626 +               goto exit_dput;
5627 +       }
5628 +
5629 +       if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
5630 +               up(&dir->d_inode->i_sem);
5631 +               error = -EACCES;
5632 +               goto exit_dput;
5633 +       }
5634 +
5635 +       if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
5636 +               up(&dir->d_inode->i_sem);
5637 +               error = -EACCES;
5638 +               goto exit_dput;
5639 +       }
5640 +
5641         up(&dir->d_inode->i_sem);
5642  
5643         error = -EEXIST;
5644 @@ -1379,6 +1431,13 @@
5645         error = security_inode_follow_link(dentry, nd);
5646         if (error)
5647                 goto exit_dput;
5648 +
5649 +       if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
5650 +                                 dentry, nd->mnt)) {
5651 +               error = -EACCES;
5652 +               goto exit_dput;
5653 +       }
5654 +
5655         touch_atime(nd->mnt, dentry);
5656         error = dentry->d_inode->i_op->follow_link(dentry, nd);
5657         dput(dentry);
5658 @@ -1486,6 +1545,22 @@
5659         if (!IS_POSIXACL(nd.dentry->d_inode))
5660                 mode &= ~current->fs->umask;
5661         if (!IS_ERR(dentry)) {
5662 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
5663 +                       error = -EPERM;
5664 +                       dput(dentry);
5665 +                       up(&nd.dentry->d_inode->i_sem);
5666 +                       path_release(&nd);
5667 +                       goto out;
5668 +               }
5669 +
5670 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
5671 +                       error = -EACCES;
5672 +                       dput(dentry);
5673 +                       up(&nd.dentry->d_inode->i_sem);
5674 +                       path_release(&nd);
5675 +                       goto out;
5676 +               }
5677 +
5678                 switch (mode & S_IFMT) {
5679                 case 0: case S_IFREG:
5680                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
5681 @@ -1503,6 +1578,10 @@
5682                 default:
5683                         error = -EINVAL;
5684                 }
5685 +
5686 +               if (!error)
5687 +                       gr_handle_create(dentry, nd.mnt);
5688 +
5689                 dput(dentry);
5690         }
5691         up(&nd.dentry->d_inode->i_sem);
5692 @@ -1554,9 +1633,19 @@
5693                 dentry = lookup_create(&nd, 1);
5694                 error = PTR_ERR(dentry);
5695                 if (!IS_ERR(dentry)) {
5696 +                       error = 0;
5697                         if (!IS_POSIXACL(nd.dentry->d_inode))
5698                                 mode &= ~current->fs->umask;
5699 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
5700 +
5701 +                       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
5702 +                               error = -EACCES;
5703 +
5704 +                       if (!error)
5705 +                               error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
5706 +
5707 +                       if (!error)
5708 +                               gr_handle_create(dentry, nd.mnt);
5709 +
5710                         dput(dentry);
5711                 }
5712                 up(&nd.dentry->d_inode->i_sem);
5713 @@ -1640,6 +1729,8 @@
5714         char * name;
5715         struct dentry *dentry;
5716         struct nameidata nd;
5717 +       ino_t saved_ino = 0;
5718 +       dev_t saved_dev = 0;
5719  
5720         name = getname(pathname);
5721         if(IS_ERR(name))
5722 @@ -1664,7 +1755,21 @@
5723         dentry = lookup_hash(&nd.last, nd.dentry);
5724         error = PTR_ERR(dentry);
5725         if (!IS_ERR(dentry)) {
5726 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
5727 +               error = 0;
5728 +               if (dentry->d_inode) {
5729 +                       if (dentry->d_inode->i_nlink <= 1) {
5730 +                               saved_ino = dentry->d_inode->i_ino;
5731 +                               saved_dev = dentry->d_inode->i_sb->s_dev;
5732 +                       }
5733 +
5734 +                       if (!gr_acl_handle_rmdir(dentry, nd.mnt))
5735 +                               error = -EACCES;
5736 +               }
5737 +
5738 +               if (!error)
5739 +                       error = vfs_rmdir(nd.dentry->d_inode, dentry);
5740 +               if (!error && (saved_dev || saved_ino))
5741 +                       gr_handle_delete(saved_ino, saved_dev);
5742                 dput(dentry);
5743         }
5744         up(&nd.dentry->d_inode->i_sem);
5745 @@ -1718,6 +1823,8 @@
5746         struct dentry *dentry;
5747         struct nameidata nd;
5748         struct inode *inode = NULL;
5749 +       ino_t saved_ino = 0;
5750 +       dev_t saved_dev = 0;
5751  
5752         name = getname(pathname);
5753         if(IS_ERR(name))
5754 @@ -1733,13 +1840,26 @@
5755         dentry = lookup_hash(&nd.last, nd.dentry);
5756         error = PTR_ERR(dentry);
5757         if (!IS_ERR(dentry)) {
5758 +               error = 0;
5759                 /* Why not before? Because we want correct error value */
5760                 if (nd.last.name[nd.last.len])
5761                         goto slashes;
5762                 inode = dentry->d_inode;
5763 -               if (inode)
5764 +               if (inode) {
5765 +                       if (inode->i_nlink <= 1) {
5766 +                               saved_ino = inode->i_ino;
5767 +                               saved_dev = inode->i_sb->s_dev;
5768 +                       }
5769 +
5770 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
5771 +                               error = -EACCES;
5772 +
5773                         atomic_inc(&inode->i_count);
5774 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
5775 +               }
5776 +               if (!error)
5777 +                       error = vfs_unlink(nd.dentry->d_inode, dentry);
5778 +               if (!error && (saved_ino || saved_dev))
5779 +                       gr_handle_delete(saved_ino, saved_dev);
5780         exit2:
5781                 dput(dentry);
5782         }
5783 @@ -1803,7 +1923,15 @@
5784                 dentry = lookup_create(&nd, 0);
5785                 error = PTR_ERR(dentry);
5786                 if (!IS_ERR(dentry)) {
5787 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
5788 +                       error = 0;
5789 +                       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
5790 +                               error = -EACCES;
5791 +
5792 +                       if (!error)
5793 +                               error = vfs_symlink(nd.dentry->d_inode, dentry, from);
5794 +
5795 +                       if (!error)
5796 +                               gr_handle_create(dentry, nd.mnt);
5797                         dput(dentry);
5798                 }
5799                 up(&nd.dentry->d_inode->i_sem);
5800 @@ -1887,7 +2015,20 @@
5801         new_dentry = lookup_create(&nd, 0);
5802         error = PTR_ERR(new_dentry);
5803         if (!IS_ERR(new_dentry)) {
5804 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
5805 +               error = 0;
5806 +               if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
5807 +                                      old_nd.dentry->d_inode,
5808 +                                      old_nd.dentry->d_inode->i_mode, to))
5809 +                       error = -EPERM;
5810 +               if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
5811 +                                       old_nd.dentry, old_nd.mnt, to))
5812 +                       error = -EACCES;
5813 +               if (!error)
5814 +                       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
5815 +
5816 +               if (!error)
5817 +                       gr_handle_create(new_dentry, nd.mnt);
5818 +
5819                 dput(new_dentry);
5820         }
5821         up(&nd.dentry->d_inode->i_sem);
5822 @@ -2109,8 +2250,16 @@
5823         if (new_dentry == trap)
5824                 goto exit5;
5825  
5826 -       error = vfs_rename(old_dir->d_inode, old_dentry,
5827 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
5828 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
5829 +                                    newname);
5830 +
5831 +       if (!error)
5832 +               error = vfs_rename(old_dir->d_inode, old_dentry,
5833                                    new_dir->d_inode, new_dentry);
5834 +       if (!error)
5835 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
5836 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
5837  exit5:
5838         dput(new_dentry);
5839  exit4:
5840 diff -uNr linux-2.6.6/fs/namespace.c linux-2.6.6.fixed/fs/namespace.c
5841 --- linux-2.6.6/fs/namespace.c  2004-05-10 04:32:52.000000000 +0200
5842 +++ linux-2.6.6.fixed/fs/namespace.c    2004-05-11 10:55:56.000000000 +0200
5843 @@ -21,6 +21,8 @@
5844  #include <linux/namei.h>
5845  #include <linux/security.h>
5846  #include <linux/mount.h>
5847 +#include <linux/sched.h>
5848 +#include <linux/grsecurity.h>
5849  #include <asm/uaccess.h>
5850  
5851  extern int __init init_rootfs(void);
5852 @@ -342,6 +344,8 @@
5853                         lock_kernel();
5854                         retval = do_remount_sb(sb, MS_RDONLY, 0, 0);
5855                         unlock_kernel();
5856 +
5857 +                       gr_log_remount(mnt->mnt_devname, retval);
5858                 }
5859                 up_write(&sb->s_umount);
5860                 return retval;
5861 @@ -370,6 +374,9 @@
5862         if (retval)
5863                 security_sb_umount_busy(mnt);
5864         up_write(&current->namespace->sem);
5865 +
5866 +       gr_log_unmount(mnt->mnt_devname, retval);
5867 +
5868         return retval;
5869  }
5870  
5871 @@ -788,6 +795,11 @@
5872         if (retval)
5873                 goto dput_out;
5874  
5875 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
5876 +               retval = -EPERM;
5877 +               goto dput_out;
5878 +       }
5879 +
5880         if (flags & MS_REMOUNT)
5881                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
5882                                     data_page);
5883 @@ -800,6 +812,9 @@
5884                                       dev_name, data_page);
5885  dput_out:
5886         path_release(&nd);
5887 +
5888 +       gr_log_mount(dev_name, dir_name, retval);
5889 +
5890         return retval;
5891  }
5892  
5893 @@ -1022,6 +1037,9 @@
5894         if (!capable(CAP_SYS_ADMIN))
5895                 return -EPERM;
5896  
5897 +       if (gr_handle_chroot_pivot())
5898 +               return -EPERM;
5899 +
5900         lock_kernel();
5901  
5902         error = __user_walk(new_root, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
5903 diff -uNr linux-2.6.6/fs/open.c linux-2.6.6.fixed/fs/open.c
5904 --- linux-2.6.6/fs/open.c       2004-05-10 04:31:59.000000000 +0200
5905 +++ linux-2.6.6.fixed/fs/open.c 2004-05-11 10:55:56.000000000 +0200
5906 @@ -22,6 +22,7 @@
5907  #include <asm/uaccess.h>
5908  #include <linux/fs.h>
5909  #include <linux/pagemap.h>
5910 +#include <linux/grsecurity.h>
5911  
5912  int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
5913  {
5914 @@ -189,7 +190,7 @@
5915         return error;
5916  }
5917  
5918 -int do_truncate(struct dentry *dentry, loff_t length)
5919 +int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
5920  {
5921         int err;
5922         struct iattr newattrs;
5923 @@ -198,6 +199,9 @@
5924         if (length < 0)
5925                 return -EINVAL;
5926  
5927 +       if (!gr_acl_handle_truncate(dentry, mnt))
5928 +               return -EACCES;
5929 +
5930         newattrs.ia_size = length;
5931         newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
5932         down(&dentry->d_inode->i_sem);
5933 @@ -258,7 +262,7 @@
5934         error = locks_verify_truncate(inode, NULL, length);
5935         if (!error) {
5936                 DQUOT_INIT(inode);
5937 -               error = do_truncate(nd.dentry, length);
5938 +               error = do_truncate(nd.dentry, length, nd.mnt);
5939         }
5940         put_write_access(inode);
5941  
5942 @@ -310,7 +314,7 @@
5943  
5944         error = locks_verify_truncate(inode, file, length);
5945         if (!error)
5946 -               error = do_truncate(dentry, length);
5947 +               error = do_truncate(dentry, length, file->f_vfsmnt);
5948  out_putf:
5949         fput(file);
5950  out:
5951 @@ -389,6 +393,11 @@
5952                     (error = permission(inode,MAY_WRITE,&nd)) != 0)
5953                         goto dput_and_out;
5954         }
5955 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
5956 +               error = -EACCES;
5957 +               goto dput_and_out;
5958 +       }
5959 +
5960         down(&inode->i_sem);
5961         error = notify_change(nd.dentry, &newattrs);
5962         up(&inode->i_sem);
5963 @@ -442,6 +451,12 @@
5964                     (error = permission(inode,MAY_WRITE,&nd)) != 0)
5965                         goto dput_and_out;
5966         }
5967 +
5968 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
5969 +               error = -EACCES;
5970 +               goto dput_and_out;
5971 +       }
5972 +
5973         down(&inode->i_sem);
5974         error = notify_change(nd.dentry, &newattrs);
5975         up(&inode->i_sem);
5976 @@ -503,6 +518,10 @@
5977                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
5978                    && !special_file(nd.dentry->d_inode->i_mode))
5979                         res = -EROFS;
5980 +
5981 +               if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
5982 +                       res = -EACCES;
5983 +
5984                 path_release(&nd);
5985         }
5986  
5987 @@ -526,6 +545,8 @@
5988         if (error)
5989                 goto dput_and_out;
5990  
5991 +       gr_log_chdir(nd.dentry, nd.mnt);
5992 +
5993         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
5994  
5995  dput_and_out:
5996 @@ -556,6 +577,13 @@
5997                 goto out_putf;
5998  
5999         error = permission(inode, MAY_EXEC, NULL);
6000 +
6001 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
6002 +               error = -EPERM;
6003 +
6004 +       if (!error)
6005 +               gr_log_chdir(dentry, mnt);
6006 +
6007         if (!error)
6008                 set_fs_pwd(current->fs, mnt, dentry);
6009  out_putf:
6010 @@ -581,8 +609,16 @@
6011         if (!capable(CAP_SYS_CHROOT))
6012                 goto dput_and_out;
6013  
6014 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
6015 +               goto dput_and_out;
6016 +
6017         set_fs_root(current->fs, nd.mnt, nd.dentry);
6018         set_fs_altroot();
6019 +
6020 +       gr_handle_chroot_caps(current);
6021 +
6022 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
6023 +
6024         error = 0;
6025  dput_and_out:
6026         path_release(&nd);
6027 @@ -611,9 +647,22 @@
6028         err = -EPERM;
6029         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6030                 goto out_putf;
6031 +
6032 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
6033 +               err = -EACCES;
6034 +               goto out_putf;
6035 +       }
6036 +
6037         down(&inode->i_sem);
6038         if (mode == (mode_t) -1)
6039                 mode = inode->i_mode;
6040 +
6041 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
6042 +               err = -EPERM;
6043 +               up(&inode->i_sem);
6044 +               goto out_putf;
6045 +       }
6046 +
6047         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6048         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
6049         err = notify_change(dentry, &newattrs);
6050 @@ -645,9 +694,21 @@
6051         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6052                 goto dput_and_out;
6053  
6054 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
6055 +               error = -EACCES;
6056 +               goto dput_and_out;
6057 +       }
6058 +
6059         down(&inode->i_sem);
6060         if (mode == (mode_t) -1)
6061                 mode = inode->i_mode;
6062 +
6063 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
6064 +               error = -EACCES;
6065 +               up(&inode->i_sem);
6066 +               goto dput_and_out;
6067 +       }
6068 +
6069         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6070         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
6071         error = notify_change(nd.dentry, &newattrs);
6072 @@ -659,7 +720,7 @@
6073         return error;
6074  }
6075  
6076 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
6077 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
6078  {
6079         struct inode * inode;
6080         int error;
6081 @@ -676,6 +737,12 @@
6082         error = -EPERM;
6083         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6084                 goto out;
6085 +
6086 +       if (!gr_acl_handle_chown(dentry, mnt)) {
6087 +               error = -EACCES;
6088 +               goto out;
6089 +       }
6090 +
6091         newattrs.ia_valid =  ATTR_CTIME;
6092         if (user != (uid_t) -1) {
6093                 newattrs.ia_valid |= ATTR_UID;
6094 @@ -701,7 +768,7 @@
6095  
6096         error = user_path_walk(filename, &nd);
6097         if (!error) {
6098 -               error = chown_common(nd.dentry, user, group);
6099 +               error = chown_common(nd.dentry, user, group, nd.mnt);
6100                 path_release(&nd);
6101         }
6102         return error;
6103 @@ -714,7 +781,7 @@
6104  
6105         error = user_path_walk_link(filename, &nd);
6106         if (!error) {
6107 -               error = chown_common(nd.dentry, user, group);
6108 +               error = chown_common(nd.dentry, user, group, nd.mnt);
6109                 path_release(&nd);
6110         }
6111         return error;
6112 @@ -728,7 +795,8 @@
6113  
6114         file = fget(fd);
6115         if (file) {
6116 -               error = chown_common(file->f_dentry, user, group);
6117 +               error = chown_common(file->f_dentry, user,
6118 +                                    group, file->f_vfsmnt);
6119                 fput(file);
6120         }
6121         return error;
6122 @@ -850,6 +918,7 @@
6123          * N.B. For clone tasks sharing a files structure, this test
6124          * will limit the total number of files that can be opened.
6125          */
6126 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
6127         if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
6128                 goto out;
6129  
6130 diff -uNr linux-2.6.6/fs/proc/array.c linux-2.6.6.fixed/fs/proc/array.c
6131 --- linux-2.6.6/fs/proc/array.c 2004-05-10 04:32:39.000000000 +0200
6132 +++ linux-2.6.6.fixed/fs/proc/array.c   2004-05-11 10:55:56.000000000 +0200
6133 @@ -271,6 +271,19 @@
6134                             cap_t(p->cap_effective));
6135  }
6136  
6137 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
6138 +static inline char *task_pax(struct task_struct *p, char *buffer)
6139 +{
6140 +       return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c%c\n",
6141 +                               p->flags & PF_PAX_PAGEEXEC ? 'P' : 'p',
6142 +                               p->flags & PF_PAX_EMUTRAMP ? 'E' : 'e',
6143 +                               p->flags & PF_PAX_MPROTECT ? 'M' : 'm',
6144 +                               p->flags & PF_PAX_RANDMMAP ? 'R' : 'r',
6145 +                               p->flags & PF_PAX_RANDEXEC ? 'X' : 'x',
6146 +                               p->flags & PF_PAX_SEGMEXEC ? 'S' : 's');
6147 +}
6148 +#endif
6149 +
6150  extern char *task_mem(struct mm_struct *, char *);
6151  int proc_pid_status(struct task_struct *task, char * buffer)
6152  {
6153 @@ -289,9 +302,20 @@
6154  #if defined(CONFIG_ARCH_S390)
6155         buffer = task_show_regs(task, buffer);
6156  #endif
6157 +
6158 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
6159 +       buffer = task_pax(task, buffer);
6160 +#endif
6161 +
6162         return buffer - orig;
6163  }
6164  
6165 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6166 +#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
6167 +                       task->flags & PF_PAX_SEGMEXEC || \
6168 +                       task->flags & PF_PAX_RANDEXEC)
6169 +#endif
6170 +
6171  extern unsigned long task_vsize(struct mm_struct *);
6172  int proc_pid_stat(struct task_struct *task, char * buffer)
6173  {
6174 @@ -323,6 +347,19 @@
6175  
6176         wchan = get_wchan(task);
6177  
6178 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6179 +       if (PAX_RAND_FLAGS) {
6180 +               eip = 0;
6181 +               esp = 0;
6182 +               wchan = 0;
6183 +       }
6184 +#endif
6185 +#ifdef CONFIG_GRKERNSEC_HIDESYM
6186 +       wchan = 0;
6187 +       eip =0;
6188 +       esp =0;
6189 +#endif
6190 +
6191         sigemptyset(&sigign);
6192         sigemptyset(&sigcatch);
6193         read_lock(&tasklist_lock);
6194 @@ -382,9 +419,15 @@
6195                 vsize,
6196                 mm ? mm->rss : 0, /* you might want to shift this left 3 */
6197                 task->rlim[RLIMIT_RSS].rlim_cur,
6198 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6199 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0),
6200 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0),
6201 +               PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0),
6202 +#else
6203                 mm ? mm->start_code : 0,
6204                 mm ? mm->end_code : 0,
6205                 mm ? mm->start_stack : 0,
6206 +#endif
6207                 esp,
6208                 eip,
6209                 /* The signal information here is obsolete.
6210 @@ -424,3 +467,14 @@
6211         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
6212                        size, resident, shared, text, lib, data, 0);
6213  }
6214 +
6215 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6216 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
6217 +{
6218 +       int len;
6219 +
6220 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
6221 +       return len;
6222 +}
6223 +#endif
6224 +
6225 diff -uNr linux-2.6.6/fs/proc/base.c linux-2.6.6.fixed/fs/proc/base.c
6226 --- linux-2.6.6/fs/proc/base.c  2004-05-10 04:32:52.000000000 +0200
6227 +++ linux-2.6.6.fixed/fs/proc/base.c    2004-05-11 10:55:56.000000000 +0200
6228 @@ -32,6 +32,7 @@
6229  #include <linux/mount.h>
6230  #include <linux/security.h>
6231  #include <linux/ptrace.h>
6232 +#include <linux/grsecurity.h>
6233  
6234  /*
6235   * For hysterical raisins we keep the same inumbers as in the old procfs.
6236 @@ -67,6 +68,9 @@
6237         PROC_TGID_ATTR_EXEC,
6238         PROC_TGID_ATTR_FSCREATE,
6239  #endif
6240 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6241 +       PROC_TGID_IPADDR,
6242 +#endif
6243         PROC_TGID_FD_DIR,
6244         PROC_TID_INO,
6245         PROC_TID_STATUS,
6246 @@ -117,6 +121,9 @@
6247         E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
6248         E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
6249         E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
6250 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6251 +       E(PROC_TGID_IPADDR,     "ipaddr",  S_IFREG|S_IRUSR),
6252 +#endif
6253  #ifdef CONFIG_SECURITY
6254         E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
6255  #endif
6256 @@ -181,6 +188,9 @@
6257  int proc_pid_status(struct task_struct*,char*);
6258  int proc_pid_statm(struct task_struct*,char*);
6259  int proc_pid_cpu(struct task_struct*,char*);
6260 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6261 +int proc_pid_ipaddr(struct task_struct*,char*);
6262 +#endif
6263  
6264  static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
6265  {
6266 @@ -277,7 +287,7 @@
6267         (task == current || \
6268         (task->parent == current && \
6269         (task->ptrace & PT_PTRACED) &&  task->state == TASK_STOPPED && \
6270 -        security_ptrace(current,task) == 0))
6271 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
6272  
6273  static int may_ptrace_attach(struct task_struct *task)
6274  {
6275 @@ -292,13 +302,15 @@
6276              (current->uid != task->uid) ||
6277              (current->gid != task->egid) ||
6278              (current->gid != task->sgid) ||
6279 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
6280 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
6281                 goto out;
6282         rmb();
6283 -       if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
6284 +       if (!task->mm->dumpable && !capable_nolog(CAP_SYS_PTRACE))
6285                 goto out;
6286         if (security_ptrace(current, task))
6287                 goto out;
6288 +       if (gr_handle_proc_ptrace(task))
6289 +               goto out;
6290  
6291         retval = 1;
6292  out:
6293 @@ -445,9 +457,22 @@
6294  
6295  static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
6296  {
6297 +       int ret;
6298 +       struct task_struct *task;
6299 +
6300         if (vfs_permission(inode, mask) != 0)
6301                 return -EACCES;
6302 -       return proc_check_root(inode);
6303 +       ret = proc_check_root(inode);
6304 +
6305 +       if (ret)
6306 +               return ret;
6307 +
6308 +       task = proc_task(inode);
6309 +
6310 +       if (!task)
6311 +               return 0;
6312 +
6313 +       return gr_acl_handle_procpidmem(task);
6314  }
6315  
6316  extern struct seq_operations proc_pid_maps_op;
6317 @@ -954,6 +979,9 @@
6318                 inode->i_uid = task->euid;
6319                 inode->i_gid = task->egid;
6320         }
6321 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6322 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
6323 +#endif
6324         security_task_to_inode(task, inode);
6325  
6326  out:
6327 @@ -982,7 +1010,9 @@
6328         if (pid_alive(task)) {
6329                 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
6330                         inode->i_uid = task->euid;
6331 +#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
6332                         inode->i_gid = task->egid;
6333 +#endif
6334                 } else {
6335                         inode->i_uid = 0;
6336                         inode->i_gid = 0;
6337 @@ -1318,6 +1348,12 @@
6338                         inode->i_fop = &proc_info_file_operations;
6339                         ei->op.proc_read = proc_pid_status;
6340                         break;
6341 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
6342 +               case PROC_TGID_IPADDR:
6343 +                       inode->i_fop = &proc_info_file_operations;
6344 +                       ei->op.proc_read = proc_pid_ipaddr;
6345 +                       break;
6346 +#endif
6347                 case PROC_TID_STAT:
6348                 case PROC_TGID_STAT:
6349                         inode->i_fop = &proc_info_file_operations;
6350 @@ -1567,6 +1603,22 @@
6351         if (!task)
6352                 goto out;
6353  
6354 +       if (gr_check_hidden_task(task)) {
6355 +               put_task_struct(task);
6356 +               goto out;
6357 +       }
6358 +
6359 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
6360 +       if (current->uid && (task->uid != current->uid)
6361 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6362 +           && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
6363 +#endif
6364 +       ) {
6365 +               put_task_struct(task);
6366 +               goto out;
6367 +       }
6368 +#endif
6369 +
6370         inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
6371  
6372  
6373 @@ -1574,7 +1626,15 @@
6374                 put_task_struct(task);
6375                 goto out;
6376         }
6377 +
6378 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6379 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
6380 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6381 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
6382 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
6383 +#else
6384         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
6385 +#endif
6386         inode->i_op = &proc_tgid_base_inode_operations;
6387         inode->i_fop = &proc_tgid_base_operations;
6388         inode->i_nlink = 3;
6389 @@ -1658,6 +1718,9 @@
6390  static int get_tgid_list(int index, unsigned long version, unsigned int *tgids)
6391  {
6392         struct task_struct *p;
6393 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
6394 +       struct task_struct *tmp = current;
6395 +#endif
6396         int nr_tgids = 0;
6397  
6398         index--;
6399 @@ -1678,6 +1741,18 @@
6400                 int tgid = p->pid;
6401                 if (!pid_alive(p))
6402                         continue;
6403 +               if (gr_pid_is_chrooted(p))
6404 +                       continue;
6405 +               if (gr_check_hidden_task(p))
6406 +                       continue;
6407 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
6408 +               if (tmp->uid && (p->uid != tmp->uid)
6409 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6410 +                   && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
6411 +#endif
6412 +               )
6413 +                       continue;
6414 +#endif
6415                 if (--index >= 0)
6416                         continue;
6417                 tgids[nr_tgids] = tgid;
6418 diff -uNr linux-2.6.6/fs/proc/inode.c linux-2.6.6.fixed/fs/proc/inode.c
6419 --- linux-2.6.6/fs/proc/inode.c 2004-05-10 04:33:19.000000000 +0200
6420 +++ linux-2.6.6.fixed/fs/proc/inode.c   2004-05-11 10:55:56.000000000 +0200
6421 @@ -209,7 +209,11 @@
6422                 if (de->mode) {
6423                         inode->i_mode = de->mode;
6424                         inode->i_uid = de->uid;
6425 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
6426 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
6427 +#else
6428                         inode->i_gid = de->gid;
6429 +#endif
6430                 }
6431                 if (de->size)
6432                         inode->i_size = de->size;
6433 diff -uNr linux-2.6.6/fs/proc/proc_misc.c linux-2.6.6.fixed/fs/proc/proc_misc.c
6434 --- linux-2.6.6/fs/proc/proc_misc.c     2004-05-10 04:32:01.000000000 +0200
6435 +++ linux-2.6.6.fixed/fs/proc/proc_misc.c       2004-05-11 10:55:56.000000000 +0200
6436 @@ -654,6 +654,8 @@
6437  void __init proc_misc_init(void)
6438  {
6439         struct proc_dir_entry *entry;
6440 +       int gr_mode = 0;
6441 +
6442         static struct {
6443                 char *name;
6444                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
6445 @@ -668,9 +670,13 @@
6446  #ifdef CONFIG_STRAM_PROC
6447                 {"stram",       stram_read_proc},
6448  #endif
6449 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
6450                 {"devices",     devices_read_proc},
6451 +#endif
6452                 {"filesystems", filesystems_read_proc},
6453 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
6454                 {"cmdline",     cmdline_read_proc},
6455 +#endif
6456  #ifdef CONFIG_SGI_DS1286
6457                 {"rtc",         ds1286_read_proc},
6458  #endif
6459 @@ -681,24 +687,39 @@
6460         for (p = simple_ones; p->name; p++)
6461                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
6462  
6463 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6464 +       gr_mode = S_IRUSR;
6465 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6466 +       gr_mode = S_IRUSR | S_IRGRP;
6467 +#endif
6468 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6469 +       create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
6470 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
6471 +#endif 
6472 +
6473         proc_symlink("mounts", NULL, "self/mounts");
6474  
6475         /* And now for trickier ones */
6476         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
6477         if (entry)
6478                 entry->proc_fops = &proc_kmsg_operations;
6479 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6480 +       create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
6481 +       create_seq_entry("slabinfo",gr_mode,&proc_slabinfo_operations);
6482 +#else
6483         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
6484 +       create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
6485 +#endif
6486         create_seq_entry("partitions", 0, &proc_partitions_operations);
6487         create_seq_entry("stat", 0, &proc_stat_operations);
6488         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
6489 -       create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
6490         create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
6491         create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
6492         create_seq_entry("diskstats", 0, &proc_diskstats_operations);
6493  #ifdef CONFIG_MODULES
6494 -       create_seq_entry("modules", 0, &proc_modules_operations);
6495 +       create_seq_entry("modules", gr_mode, &proc_modules_operations);
6496  #endif
6497 -#ifdef CONFIG_PROC_KCORE
6498 +#if defined(CONFIG_PROC_KCORE)
6499         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
6500         if (proc_root_kcore) {
6501                 proc_root_kcore->proc_fops = &proc_kcore_operations;
6502 diff -uNr linux-2.6.6/fs/proc/root.c linux-2.6.6.fixed/fs/proc/root.c
6503 --- linux-2.6.6/fs/proc/root.c  2004-05-10 04:33:10.000000000 +0200
6504 +++ linux-2.6.6.fixed/fs/proc/root.c    2004-05-11 10:55:56.000000000 +0200
6505 @@ -52,13 +52,26 @@
6506                 return;
6507         }
6508         proc_misc_init();
6509 +
6510 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6511 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, 0);
6512 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6513 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
6514 +#else
6515         proc_net = proc_mkdir("net", 0);
6516 +#endif
6517  #ifdef CONFIG_SYSVIPC
6518         proc_mkdir("sysvipc", 0);
6519  #endif
6520  #ifdef CONFIG_SYSCTL
6521 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6522 +       proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR, 0);
6523 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6524 +       proc_sys_root = proc_mkdir_mode("sys", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
6525 +#else
6526         proc_sys_root = proc_mkdir("sys", 0);
6527  #endif
6528 +#endif
6529  #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
6530         proc_mkdir("sys/fs", 0);
6531         proc_mkdir("sys/fs/binfmt_misc", 0);
6532 @@ -74,7 +87,15 @@
6533  #ifdef CONFIG_PROC_DEVICETREE
6534         proc_device_tree_init();
6535  #endif
6536 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
6537 +#ifdef CONFIG_GRKERNSEC_PROC_USER
6538 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, 0);
6539 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
6540 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, 0);
6541 +#endif
6542 +#else
6543         proc_bus = proc_mkdir("bus", 0);
6544 +#endif
6545  }
6546  
6547  static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
6548 diff -uNr linux-2.6.6/fs/proc/task_mmu.c linux-2.6.6.fixed/fs/proc/task_mmu.c
6549 --- linux-2.6.6/fs/proc/task_mmu.c      2004-05-10 04:32:01.000000000 +0200
6550 +++ linux-2.6.6.fixed/fs/proc/task_mmu.c        2004-05-11 10:55:56.000000000 +0200
6551 @@ -76,8 +76,17 @@
6552         return size;
6553  }
6554  
6555 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6556 +#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \
6557 +                       task->flags & PF_PAX_SEGMEXEC || \
6558 +                       task->flags & PF_PAX_RANDEXEC)
6559 +#endif
6560 +
6561  static int show_map(struct seq_file *m, void *v)
6562  {
6563 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6564 +       struct task_struct *task = m->private;
6565 +#endif
6566         struct vm_area_struct *map = v;
6567         struct file *file = map->vm_file;
6568         int flags = map->vm_flags;
6569 @@ -92,8 +101,14 @@
6570         }
6571  
6572         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
6573 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
6574 +                       PAX_RAND_FLAGS ? 0UL : map->vm_start,
6575 +                       PAX_RAND_FLAGS ? 0UL : map->vm_end,
6576 +#else
6577                         map->vm_start,
6578                         map->vm_end,
6579 +#endif
6580 +
6581                         flags & VM_READ ? 'r' : '-',
6582                         flags & VM_WRITE ? 'w' : '-',
6583                         flags & VM_EXEC ? 'x' : '-',
6584 diff -uNr linux-2.6.6/fs/readdir.c linux-2.6.6.fixed/fs/readdir.c
6585 --- linux-2.6.6/fs/readdir.c    2004-05-10 04:32:29.000000000 +0200
6586 +++ linux-2.6.6.fixed/fs/readdir.c      2004-05-11 10:55:56.000000000 +0200
6587 @@ -14,6 +14,8 @@
6588  #include <linux/fs.h>
6589  #include <linux/dirent.h>
6590  #include <linux/security.h>
6591 +#include <linux/namei.h>
6592 +#include <linux/grsecurity.h>
6593  
6594  #include <asm/uaccess.h>
6595  
6596 @@ -64,6 +66,7 @@
6597  struct readdir_callback {
6598         struct old_linux_dirent __user * dirent;
6599         int result;
6600 +       struct nameidata nd;
6601  };
6602  
6603  static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
6604 @@ -74,6 +77,10 @@
6605  
6606         if (buf->result)
6607                 return -EINVAL;
6608 +
6609 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
6610 +               return 0;
6611 +
6612         buf->result++;
6613         dirent = buf->dirent;
6614         if (!access_ok(VERIFY_WRITE, (unsigned long)dirent,
6615 @@ -106,6 +113,9 @@
6616         buf.result = 0;
6617         buf.dirent = dirent;
6618  
6619 +       buf.nd.dentry = file->f_dentry;
6620 +       buf.nd.mnt = file->f_vfsmnt;
6621 +
6622         error = vfs_readdir(file, fillonedir, &buf);
6623         if (error >= 0)
6624                 error = buf.result;
6625 @@ -133,6 +143,7 @@
6626         struct linux_dirent __user * previous;
6627         int count;
6628         int error;
6629 +       struct nameidata nd;
6630  };
6631  
6632  static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
6633 @@ -145,6 +156,10 @@
6634         buf->error = -EINVAL;   /* only used if we fail.. */
6635         if (reclen > buf->count)
6636                 return -EINVAL;
6637 +
6638 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
6639 +               return 0;
6640 +
6641         dirent = buf->previous;
6642         if (dirent) {
6643                 if (__put_user(offset, &dirent->d_off))
6644 @@ -192,6 +207,9 @@
6645         buf.count = count;
6646         buf.error = 0;
6647  
6648 +       buf.nd.dentry = file->f_dentry;
6649 +       buf.nd.mnt = file->f_vfsmnt;
6650 +
6651         error = vfs_readdir(file, filldir, &buf);
6652         if (error < 0)
6653                 goto out_putf;
6654 @@ -217,6 +235,7 @@
6655         struct linux_dirent64 __user * previous;
6656         int count;
6657         int error;
6658 +       struct nameidata nd;
6659  };
6660  
6661  static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
6662 @@ -229,6 +248,10 @@
6663         buf->error = -EINVAL;   /* only used if we fail.. */
6664         if (reclen > buf->count)
6665                 return -EINVAL;
6666 +
6667 +       if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
6668 +               return 0;
6669 +
6670         dirent = buf->previous;
6671         if (dirent) {
6672                 if (__put_user(offset, &dirent->d_off))
6673 @@ -278,6 +301,9 @@
6674         buf.count = count;
6675         buf.error = 0;
6676  
6677 +       buf.nd.mnt = file->f_vfsmnt;
6678 +       buf.nd.dentry = file->f_dentry;
6679 +
6680         error = vfs_readdir(file, filldir64, &buf);
6681         if (error < 0)
6682                 goto out_putf;
6683 diff -uNr linux-2.6.6/grsecurity/gracl_alloc.c linux-2.6.6.fixed/grsecurity/gracl_alloc.c
6684 --- linux-2.6.6/grsecurity/gracl_alloc.c        1970-01-01 01:00:00.000000000 +0100
6685 +++ linux-2.6.6.fixed/grsecurity/gracl_alloc.c  2004-05-11 10:55:56.000000000 +0200
6686 @@ -0,0 +1,93 @@
6687 +/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
6688 +
6689 +#include <linux/kernel.h>
6690 +#include <linux/mm.h>
6691 +#include <linux/slab.h>
6692 +#include <linux/vmalloc.h>
6693 +#include <linux/gracl.h>
6694 +#include <linux/grsecurity.h>
6695 +
6696 +static unsigned long alloc_stack_next = 1;
6697 +static unsigned long alloc_stack_size = 1;
6698 +static void **alloc_stack;
6699 +
6700 +static __inline__ int
6701 +alloc_pop(void)
6702 +{
6703 +       if (alloc_stack_next == 1)
6704 +               return 0;
6705 +
6706 +       kfree(alloc_stack[alloc_stack_next - 2]);
6707 +
6708 +       alloc_stack_next--;
6709 +
6710 +       return 1;
6711 +}
6712 +
6713 +static __inline__ void
6714 +alloc_push(void *buf)
6715 +{
6716 +       if (alloc_stack_next >= alloc_stack_size)
6717 +               BUG();
6718 +
6719 +       alloc_stack[alloc_stack_next - 1] = buf;
6720 +
6721 +       alloc_stack_next++;
6722 +
6723 +       return;
6724 +}
6725 +
6726 +void *
6727 +acl_alloc(unsigned long len)
6728 +{
6729 +       void *ret;
6730 +
6731 +       if (len > PAGE_SIZE)
6732 +               BUG();
6733 +
6734 +       ret = kmalloc(len, GFP_KERNEL);
6735 +
6736 +       if (ret)
6737 +               alloc_push(ret);
6738 +
6739 +       return ret;
6740 +}
6741 +
6742 +void
6743 +acl_free_all(void)
6744 +{
6745 +       if (gr_acl_is_enabled() || !alloc_stack)
6746 +               return;
6747 +
6748 +       while (alloc_pop()) ;
6749 +
6750 +       if (alloc_stack) {
6751 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
6752 +                       kfree(alloc_stack);
6753 +               else
6754 +                       vfree(alloc_stack);
6755 +       }
6756 +
6757 +       alloc_stack = NULL;
6758 +       alloc_stack_size = 1;
6759 +       alloc_stack_next = 1;
6760 +
6761 +       return;
6762 +}
6763 +
6764 +int
6765 +acl_alloc_stack_init(unsigned long size)
6766 +{
6767 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
6768 +               alloc_stack =
6769 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
6770 +       else
6771 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
6772 +
6773 +       alloc_stack_size = size;
6774 +
6775 +       if (!alloc_stack)
6776 +               return 0;
6777 +       else
6778 +               return 1;
6779 +}
6780 diff -uNr linux-2.6.6/grsecurity/gracl.c linux-2.6.6.fixed/grsecurity/gracl.c
6781 --- linux-2.6.6/grsecurity/gracl.c      1970-01-01 01:00:00.000000000 +0100
6782 +++ linux-2.6.6.fixed/grsecurity/gracl.c        2004-05-11 10:55:56.000000000 +0200
6783 @@ -0,0 +1,3340 @@
6784 +/* 
6785 + * grsecurity/gracl.c
6786 + * Copyright Brad Spengler 2001, 2002, 2003
6787 + *
6788 + */
6789 +
6790 +#include <linux/kernel.h>
6791 +#include <linux/module.h>
6792 +#include <linux/sched.h>
6793 +#include <linux/mm.h>
6794 +#include <linux/file.h>
6795 +#include <linux/fs.h>
6796 +#include <linux/namei.h>
6797 +#include <linux/mount.h>
6798 +#include <linux/tty.h>
6799 +#include <linux/proc_fs.h>
6800 +#include <linux/smp_lock.h>
6801 +#include <linux/slab.h>
6802 +#include <linux/vmalloc.h>
6803 +#include <linux/types.h>
6804 +#include <linux/capability.h>
6805 +#include <linux/sysctl.h>
6806 +#include <linux/ptrace.h>
6807 +#include <linux/gracl.h>
6808 +#include <linux/gralloc.h>
6809 +#include <linux/grsecurity.h>
6810 +#include <linux/grinternal.h>
6811 +#include <linux/percpu.h>
6812 +
6813 +#include <asm/uaccess.h>
6814 +#include <asm/errno.h>
6815 +#include <asm/mman.h>
6816 +
6817 +static struct acl_role_db acl_role_set;
6818 +static struct acl_role_label *role_list_head;
6819 +static struct name_db name_set;
6820 +static struct name_db inodev_set;
6821 +
6822 +/* for keeping track of userspace pointers used for subjects, so we
6823 +   can share references in the kernel as well
6824 +*/
6825 +static struct acl_subj_map_db subj_map_set;
6826 +
6827 +static struct acl_role_label *default_role;
6828 +
6829 +static u16 acl_sp_role_value;
6830 +
6831 +extern char *gr_shared_page[4];
6832 +static DECLARE_MUTEX(gr_dev_sem);
6833 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
6834 +
6835 +struct gr_arg *gr_usermode;
6836 +
6837 +static unsigned long gr_status = GR_STATUS_INIT;
6838 +
6839 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
6840 +extern void gr_clear_learn_entries(void);
6841 +
6842 +#ifdef CONFIG_GRKERNSEC_RESLOG
6843 +extern void gr_log_resource(const struct task_struct *task,
6844 +                           const int res, const unsigned long wanted, const int gt);
6845 +#endif
6846 +
6847 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
6848 +                        struct dentry *root, struct vfsmount *rootmnt,
6849 +                        char *buffer, int buflen);
6850 +
6851 +unsigned char *gr_system_salt;
6852 +unsigned char *gr_system_sum;
6853 +
6854 +static struct sprole_pw **acl_special_roles = NULL;
6855 +static __u16 num_sprole_pws = 0;
6856 +
6857 +static struct acl_role_label *kernel_role = NULL;
6858 +
6859 +/* The following are used to keep a place held in the hash table when we move
6860 +   entries around.  They can be replaced during insert. */
6861 +
6862 +static struct acl_subject_label *deleted_subject;
6863 +static struct acl_object_label *deleted_object;
6864 +static struct name_entry *deleted_inodev;
6865 +
6866 +/* for keeping track of the last and final allocated subjects, since
6867 +   nested subject parsing is tricky
6868 +*/
6869 +static struct acl_subject_label *s_last = NULL;
6870 +static struct acl_subject_label *s_final = NULL;
6871 +
6872 +static unsigned int gr_auth_attempts = 0;
6873 +static unsigned long gr_auth_expires = 0UL;
6874 +
6875 +extern int gr_init_uidset(void);
6876 +extern void gr_free_uidset(void);
6877 +extern void gr_remove_uid(uid_t uid);
6878 +extern int gr_find_uid(uid_t uid);
6879 +
6880 +__inline__ int
6881 +gr_acl_is_enabled(void)
6882 +{
6883 +       return (gr_status & GR_READY);
6884 +}
6885 +
6886 +__inline__ int
6887 +gr_acl_tpe_check(void)
6888 +{
6889 +       if (unlikely(!(gr_status & GR_READY)))
6890 +               return 0;
6891 +       if (current->role->roletype & GR_ROLE_TPE)
6892 +               return 1;
6893 +       else
6894 +               return 0;
6895 +}
6896 +
6897 +int
6898 +gr_handle_rawio(const struct inode *inode)
6899 +{
6900 +       if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
6901 +           ((gr_status & GR_READY)
6902 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
6903 +            || (grsec_enable_chroot_caps && proc_is_chrooted(current))
6904 +#endif
6905 +           ))
6906 +               return 1;
6907 +       return 0;
6908 +}
6909 +
6910 +
6911 +static __inline__ int
6912 +gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
6913 +{
6914 +       int i;
6915 +       unsigned long *l1;
6916 +       unsigned long *l2;
6917 +       unsigned char *c1;
6918 +       unsigned char *c2;
6919 +       int num_longs;
6920 +
6921 +       if (likely(lena != lenb))
6922 +               return 0;
6923 +
6924 +       l1 = (unsigned long *)a;
6925 +       l2 = (unsigned long *)b;
6926 +
6927 +       num_longs = lena / sizeof(unsigned long);
6928 +
6929 +       for (i = num_longs; i--; l1++, l2++) {
6930 +               if (unlikely(*l1 != *l2))
6931 +                       return 0;
6932 +       }
6933 +
6934 +       c1 = (unsigned char *) l1;
6935 +       c2 = (unsigned char *) l2;
6936 +
6937 +       i = lena - (num_longs * sizeof(unsigned long)); 
6938 +
6939 +       for (; i--; c1++, c2++) {
6940 +               if (unlikely(*c1 != *c2))
6941 +                       return 0;
6942 +       }
6943 +
6944 +       return 1;
6945 +}
6946 +               
6947 +static __inline__ char *
6948 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
6949 +               char *buf, int buflen)
6950 +{
6951 +       char *res;
6952 +       struct dentry *our_dentry;
6953 +       struct vfsmount *our_mount;
6954 +       struct vfsmount *rootmnt;
6955 +       struct dentry *root;
6956 +
6957 +       our_dentry = (struct dentry *) dentry;
6958 +       our_mount = (struct vfsmount *) vfsmnt;
6959 +
6960 +       read_lock(&child_reaper->fs->lock);
6961 +       rootmnt = mntget(child_reaper->fs->rootmnt);
6962 +       root = dget(child_reaper->fs->root);
6963 +       read_unlock(&child_reaper->fs->lock);
6964 +
6965 +       res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
6966 +       if (unlikely(IS_ERR(res)))
6967 +               res = strcpy(buf, "<path too long>");
6968 +       dput(root);
6969 +       mntput(rootmnt);
6970 +       return res;
6971 +}
6972 +
6973 +char *
6974 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
6975 +{
6976 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
6977 +                               PAGE_SIZE);
6978 +}
6979 +
6980 +static __inline__ char *
6981 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
6982 +           char *buf, int buflen)
6983 +{
6984 +       char *res;
6985 +       struct dentry *our_dentry;
6986 +       struct vfsmount *our_mount;
6987 +       struct vfsmount *rootmnt;
6988 +       struct dentry *root;
6989 +
6990 +       our_dentry = (struct dentry *) dentry;
6991 +       our_mount = (struct vfsmount *) vfsmnt;
6992 +
6993 +       read_lock(&child_reaper->fs->lock);
6994 +       rootmnt = mntget(child_reaper->fs->rootmnt);
6995 +       root = dget(child_reaper->fs->root);
6996 +       read_unlock(&child_reaper->fs->lock);
6997 +
6998 +       spin_lock(&dcache_lock);
6999 +       res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
7000 +       spin_unlock(&dcache_lock);
7001 +       if (unlikely(IS_ERR(res)))
7002 +               res = strcpy(buf, "<path too long>");
7003 +       dput(root);
7004 +       mntput(rootmnt);
7005 +       return res;
7006 +}
7007 +
7008 +char *
7009 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
7010 +{
7011 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
7012 +                          PAGE_SIZE);
7013 +}
7014 +
7015 +char *
7016 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
7017 +{
7018 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
7019 +                          PAGE_SIZE);
7020 +}
7021 +
7022 +char *
7023 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
7024 +{
7025 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
7026 +                          PAGE_SIZE);
7027 +}
7028 +
7029 +char *
7030 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
7031 +{
7032 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
7033 +                          PAGE_SIZE);
7034 +}
7035 +
7036 +__inline__ __u32
7037 +to_gr_audit(const __u32 reqmode)
7038 +{
7039 +       __u32 retmode = 0;
7040 +
7041 +       retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
7042 +       retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
7043 +       retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
7044 +       retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
7045 +       retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
7046 +       retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
7047 +       retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
7048 +       retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
7049 +       retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
7050 +
7051 +       return retmode;
7052 +}
7053 +
7054 +__inline__ struct acl_subject_label *
7055 +lookup_subject_map(const struct acl_subject_label *userp)
7056 +{
7057 +       unsigned long index = shash(userp, subj_map_set.s_size);
7058 +       struct subject_map *match;
7059 +       __u8 i = 0;
7060 +
7061 +       match = subj_map_set.s_hash[index];
7062 +
7063 +       while (match && match->user != userp) {
7064 +               index = (index + (1 << i)) % subj_map_set.s_size;
7065 +               match = subj_map_set.s_hash[index];
7066 +               i = (i + 1) % 32;
7067 +       }
7068 +
7069 +       if (match)
7070 +               return match->kernel;
7071 +       else
7072 +               return NULL;
7073 +}
7074 +
7075 +static void
7076 +insert_subj_map_entry(struct subject_map *subjmap)
7077 +{
7078 +       unsigned long index = shash(subjmap->user, subj_map_set.s_size);
7079 +       struct subject_map **curr;
7080 +       __u8 i = 0;
7081 +
7082 +       curr = &subj_map_set.s_hash[index];
7083 +
7084 +       while (*curr) {
7085 +               index = (index + (1 << i)) % subj_map_set.s_size;
7086 +               curr = &subj_map_set.s_hash[index];
7087 +               i = (i + 1) % 32;
7088 +       }
7089 +
7090 +       *curr = subjmap;
7091 +
7092 +       return;
7093 +}
7094 +
7095 +__inline__ struct acl_role_label *
7096 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
7097 +                     const gid_t gid)
7098 +{
7099 +       unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
7100 +       struct acl_role_label *match;
7101 +       struct role_allowed_ip *ipp;
7102 +       __u8 i = 0;
7103 +
7104 +       match = acl_role_set.r_hash[index];
7105 +
7106 +       while (match
7107 +              && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
7108 +               index = (index + (1 << i)) % acl_role_set.r_size;
7109 +               match = acl_role_set.r_hash[index];
7110 +               i = (i + 1) % 32;
7111 +       }
7112 +
7113 +       if (match == NULL) {
7114 +             try_group:
7115 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
7116 +               match = acl_role_set.r_hash[index];
7117 +               i = 0;
7118 +
7119 +               while (match && (match->uidgid != gid
7120 +                          || !(match->roletype & GR_ROLE_GROUP))) {
7121 +                       index = (index + (1 << i)) % acl_role_set.r_size;
7122 +                       match = acl_role_set.r_hash[index];
7123 +                       i = (i + 1) % 32;
7124 +               }
7125 +
7126 +               if (match == NULL)
7127 +                       match = default_role;
7128 +               if (match->allowed_ips == NULL)
7129 +                       return match;
7130 +               else {
7131 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
7132 +                               if (likely
7133 +                                   ((task->curr_ip & ipp->netmask) ==
7134 +                                    (ipp->addr & ipp->netmask)))
7135 +                                       return match;
7136 +                       }
7137 +                       match = default_role;
7138 +               }
7139 +       } else if (match->allowed_ips == NULL) {
7140 +               return match;
7141 +       } else {
7142 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
7143 +                       if (likely
7144 +                           ((task->curr_ip & ipp->netmask) ==
7145 +                            (ipp->addr & ipp->netmask)))
7146 +                               return match;
7147 +               }
7148 +               goto try_group;
7149 +       }
7150 +
7151 +       return match;
7152 +}
7153 +
7154 +__inline__ struct acl_subject_label *
7155 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
7156 +                     const struct acl_role_label *role)
7157 +{
7158 +       unsigned long subj_size = role->subj_hash_size;
7159 +       struct acl_subject_label **s_hash = role->subj_hash;
7160 +       unsigned long index = fhash(ino, dev, subj_size);
7161 +       struct acl_subject_label *match;
7162 +       __u8 i = 0;
7163 +
7164 +       match = s_hash[index];
7165 +
7166 +       while (match && (match->inode != ino || match->device != dev ||
7167 +              (match->mode & GR_DELETED))) {
7168 +               index = (index + (1 << i)) % subj_size;
7169 +               match = s_hash[index];
7170 +               i = (i + 1) % 32;
7171 +       }
7172 +
7173 +       if (match && (match != deleted_subject) && !(match->mode & GR_DELETED))
7174 +               return match;
7175 +       else
7176 +               return NULL;
7177 +}
7178 +
7179 +static __inline__ struct acl_object_label *
7180 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
7181 +                    const struct acl_subject_label *subj)
7182 +{
7183 +       unsigned long obj_size = subj->obj_hash_size;
7184 +       struct acl_object_label **o_hash = subj->obj_hash;
7185 +       unsigned long index = fhash(ino, dev, obj_size);
7186 +       struct acl_object_label *match;
7187 +       __u8 i = 0;
7188 +
7189 +       match = o_hash[index];
7190 +
7191 +       while (match && (match->inode != ino || match->device != dev ||
7192 +              (match->mode & GR_DELETED))) {
7193 +               index = (index + (1 << i)) % obj_size;
7194 +               match = o_hash[index];
7195 +               i = (i + 1) % 32;
7196 +       }
7197 +
7198 +       if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
7199 +               return match;
7200 +       else
7201 +               return NULL;
7202 +}
7203 +
7204 +static __inline__ struct acl_object_label *
7205 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
7206 +                    const struct acl_subject_label *subj)
7207 +{
7208 +       unsigned long obj_size = subj->obj_hash_size;
7209 +       struct acl_object_label **o_hash = subj->obj_hash;
7210 +       unsigned long index = fhash(ino, dev, obj_size);
7211 +       struct acl_object_label *match;
7212 +       __u8 i = 0;
7213 +
7214 +       match = o_hash[index];
7215 +
7216 +       while (match && (match->inode != ino || match->device != dev ||
7217 +              !(match->mode & GR_DELETED))) {
7218 +               index = (index + (1 << i)) % obj_size;
7219 +               match = o_hash[index];
7220 +               i = (i + 1) % 32;
7221 +       }
7222 +
7223 +       if (match && (match != deleted_object) && (match->mode & GR_DELETED))
7224 +               return match;
7225 +
7226 +       i = 0;
7227 +       index = fhash(ino, dev, obj_size);
7228 +       match = o_hash[index];
7229 +
7230 +       while (match && (match->inode != ino || match->device != dev ||
7231 +              (match->mode & GR_DELETED))) {
7232 +               index = (index + (1 << i)) % obj_size;
7233 +               match = o_hash[index];
7234 +               i = (i + 1) % 32;
7235 +       }
7236 +
7237 +       if (match && (match != deleted_object) && !(match->mode & GR_DELETED))
7238 +               return match;
7239 +       else
7240 +               return NULL;
7241 +}
7242 +
7243 +static __inline__ struct name_entry *
7244 +lookup_name_entry(const char *name)
7245 +{
7246 +       __u16 len = strlen(name);
7247 +       unsigned long index = nhash(name, len, name_set.n_size);
7248 +       struct name_entry *match;
7249 +       __u8 i = 0;
7250 +
7251 +       match = name_set.n_hash[index];
7252 +
7253 +       while (match && !gr_streq(match->name, name, match->len, len)) {
7254 +               index = (index + (1 << i)) % name_set.n_size;
7255 +               match = name_set.n_hash[index];
7256 +               i = (i + 1) % 32;
7257 +       }
7258 +
7259 +       return match;
7260 +}
7261 +
7262 +static __inline__ struct name_entry *
7263 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
7264 +{
7265 +       unsigned long index = fhash(ino, dev, inodev_set.n_size);
7266 +       struct name_entry *match;
7267 +       __u8 i = 0;
7268 +
7269 +       match = inodev_set.n_hash[index];
7270 +
7271 +       while (match && (match->inode != ino || match->device != dev)) {
7272 +               index = (index + (1 << i)) % inodev_set.n_size;
7273 +               match = inodev_set.n_hash[index];
7274 +               i = (i + 1) % 32;
7275 +       }
7276 +
7277 +       if (match && (match != deleted_inodev))
7278 +               return match;
7279 +       else
7280 +               return NULL;
7281 +}
7282 +
7283 +static void
7284 +insert_inodev_entry(struct name_entry *nentry)
7285 +{
7286 +       unsigned long index = fhash(nentry->inode, nentry->device,
7287 +                                   inodev_set.n_size);
7288 +       struct name_entry **curr;
7289 +       __u8 i = 0;
7290 +
7291 +       curr = &inodev_set.n_hash[index];
7292 +
7293 +       while (*curr && *curr != deleted_inodev) {
7294 +               index = (index + (1 << i)) % inodev_set.n_size;
7295 +               curr = &inodev_set.n_hash[index];
7296 +               i = (i + 1) % 32;
7297 +       }
7298 +
7299 +       *curr = nentry;
7300 +
7301 +       return;
7302 +}
7303 +
7304 +static void
7305 +insert_acl_role_label(struct acl_role_label *role)
7306 +{
7307 +       unsigned long index =
7308 +           rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
7309 +       struct acl_role_label **curr;
7310 +       __u8 i = 0;
7311 +
7312 +       curr = &acl_role_set.r_hash[index];
7313 +
7314 +       while (*curr) {
7315 +               index = (index + (1 << i)) % acl_role_set.r_size;
7316 +               curr = &acl_role_set.r_hash[index];
7317 +               i = (i + 1) % 32;
7318 +       }
7319 +
7320 +       *curr = role;
7321 +
7322 +       return;
7323 +}
7324 +
7325 +static int
7326 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
7327 +{
7328 +       struct name_entry **curr;
7329 +       __u8 i = 0;
7330 +       __u16 len = strlen(name);
7331 +       unsigned long index = nhash(name, len, name_set.n_size);
7332 +
7333 +       curr = &name_set.n_hash[index];
7334 +
7335 +       while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
7336 +               index = (index + (1 << i)) % name_set.n_size;
7337 +               curr = &name_set.n_hash[index];
7338 +               i = (i + 1) % 32;
7339 +       }
7340 +
7341 +       if (!(*curr)) {
7342 +               struct name_entry *nentry =
7343 +                   acl_alloc(sizeof (struct name_entry));
7344 +               if (!nentry)
7345 +                       return 0;
7346 +               nentry->name = name;
7347 +               nentry->inode = inode;
7348 +               nentry->device = device;
7349 +               nentry->len = len;
7350 +               *curr = nentry;
7351 +               /* insert us into the table searchable by inode/dev */
7352 +               insert_inodev_entry(nentry);
7353 +       }
7354 +
7355 +       return 1;
7356 +}
7357 +
7358 +static void
7359 +insert_acl_obj_label(struct acl_object_label *obj,
7360 +                    struct acl_subject_label *subj)
7361 +{
7362 +       unsigned long index =
7363 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
7364 +       struct acl_object_label **curr;
7365 +       __u8 i = 0;
7366 +
7367 +       curr = &subj->obj_hash[index];
7368 +
7369 +       while (*curr && *curr != deleted_object) {
7370 +               index = (index + (1 << i)) % subj->obj_hash_size;
7371 +               curr = &subj->obj_hash[index];
7372 +               i = (i + 1) % 32;
7373 +       }
7374 +
7375 +       *curr = obj;
7376 +
7377 +       return;
7378 +}
7379 +
7380 +static void
7381 +insert_acl_subj_label(struct acl_subject_label *obj,
7382 +                     struct acl_role_label *role)
7383 +{
7384 +       unsigned long subj_size = role->subj_hash_size;
7385 +       struct acl_subject_label **s_hash = role->subj_hash;
7386 +       unsigned long index = fhash(obj->inode, obj->device, subj_size);
7387 +       struct acl_subject_label **curr;
7388 +       __u8 i = 0;
7389 +
7390 +       curr = &s_hash[index];
7391 +
7392 +       while (*curr && *curr != deleted_subject) {
7393 +               index = (index + (1 << i)) % subj_size;
7394 +               curr = &s_hash[index];
7395 +               i = (i + 1) % 32;
7396 +       }
7397 +
7398 +       *curr = obj;
7399 +
7400 +       return;
7401 +}
7402 +
7403 +static void **
7404 +create_table(__u32 * len)
7405 +{
7406 +       unsigned long table_sizes[] = {
7407 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
7408 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
7409 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
7410 +               268435399, 536870909, 1073741789, 2147483647
7411 +       };
7412 +       void *newtable = NULL;
7413 +       unsigned int pwr = 0;
7414 +
7415 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
7416 +              table_sizes[pwr] <= (2 * (*len)))
7417 +               pwr++;
7418 +
7419 +       if (table_sizes[pwr] <= (2 * (*len)))
7420 +               return newtable;
7421 +
7422 +       if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
7423 +               newtable =
7424 +                   kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
7425 +       else
7426 +               newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
7427 +
7428 +       *len = table_sizes[pwr];
7429 +
7430 +       return newtable;
7431 +}
7432 +
7433 +static int
7434 +init_variables(const unsigned long acl_obj_size,
7435 +              const unsigned long acl_glob_size,
7436 +              const unsigned long acl_subj_size,
7437 +              const unsigned long acl_ip_size,
7438 +              const unsigned long acl_role_size,
7439 +              const unsigned long allowed_ip_size,
7440 +              const unsigned long acl_trans_size,
7441 +              const __u16 num_sprole_pws)
7442 +{
7443 +       unsigned long stacksize;
7444 +
7445 +       subj_map_set.s_size = acl_subj_size;
7446 +       acl_role_set.r_size = acl_role_size;
7447 +       name_set.n_size = (acl_obj_size + acl_subj_size);
7448 +       inodev_set.n_size = (acl_obj_size + acl_subj_size);
7449 +
7450 +       if (!gr_init_uidset())
7451 +               return 1;
7452 +
7453 +       /* set up the stack that holds allocation info */
7454 +
7455 +       stacksize = (3 * acl_obj_size) + (3 * acl_role_size) +
7456 +           (6 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
7457 +           allowed_ip_size + (2 * num_sprole_pws) + (2 * acl_glob_size) + 5;
7458 +
7459 +       if (!acl_alloc_stack_init(stacksize))
7460 +               return 1;
7461 +
7462 +       /* create our empty, fake deleted acls */
7463 +       deleted_subject =
7464 +           (struct acl_subject_label *)
7465 +           acl_alloc(sizeof (struct acl_subject_label));
7466 +       deleted_object =
7467 +           (struct acl_object_label *)
7468 +           acl_alloc(sizeof (struct acl_object_label));
7469 +       deleted_inodev =
7470 +           (struct name_entry *) acl_alloc(sizeof (struct name_entry));
7471 +
7472 +       if (!deleted_subject || !deleted_object || !deleted_inodev)
7473 +               return 1;
7474 +
7475 +       memset(deleted_subject, 0, sizeof (struct acl_subject_label));
7476 +       memset(deleted_object, 0, sizeof (struct acl_object_label));
7477 +       memset(deleted_inodev, 0, sizeof (struct name_entry));
7478 +
7479 +       /* We only want 50% full tables for now */
7480 +
7481 +       subj_map_set.s_hash =
7482 +           (struct subject_map **) create_table(&subj_map_set.s_size);
7483 +       acl_role_set.r_hash =
7484 +           (struct acl_role_label **) create_table(&acl_role_set.r_size);
7485 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
7486 +       inodev_set.n_hash =
7487 +           (struct name_entry **) create_table(&inodev_set.n_size);
7488 +
7489 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
7490 +           !name_set.n_hash || !inodev_set.n_hash)
7491 +               return 1;
7492 +
7493 +       memset(subj_map_set.s_hash, 0,
7494 +              sizeof(struct subject_map *) * subj_map_set.s_size);
7495 +       memset(acl_role_set.r_hash, 0,
7496 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
7497 +       memset(name_set.n_hash, 0,
7498 +              sizeof (struct name_entry *) * name_set.n_size);
7499 +       memset(inodev_set.n_hash, 0,
7500 +              sizeof (struct name_entry *) * inodev_set.n_size);
7501 +
7502 +       return 0;
7503 +}
7504 +
7505 +/* free information not needed after startup
7506 +   currently contains user->kernel pointer mappings for subjects
7507 +*/
7508 +
7509 +static void
7510 +free_init_variables(void)
7511 +{
7512 +       __u32 i;
7513 +
7514 +       if (subj_map_set.s_hash) {
7515 +               for (i = 0; i < subj_map_set.s_size; i++) {
7516 +                       if (subj_map_set.s_hash[i]) {
7517 +                               kfree(subj_map_set.s_hash[i]);
7518 +                               subj_map_set.s_hash[i] = NULL;
7519 +                       }
7520 +               }
7521 +
7522 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
7523 +                   PAGE_SIZE)
7524 +                       kfree(subj_map_set.s_hash);
7525 +               else
7526 +                       vfree(subj_map_set.s_hash);
7527 +       }
7528 +
7529 +       return;
7530 +}
7531 +
7532 +static void
7533 +free_variables(void)
7534 +{
7535 +       struct acl_subject_label *s;
7536 +       struct acl_role_label *r;
7537 +       struct task_struct *task, *task2;
7538 +
7539 +       gr_clear_learn_entries();
7540 +
7541 +       read_lock(&tasklist_lock);
7542 +       for_each_process(task) {
7543 +               task2 = task;
7544 +               do {
7545 +                       task2->acl_sp_role = 0;
7546 +                       task2->acl_role_id = 0;
7547 +                       task2->acl = NULL;
7548 +                       task2->role = NULL;
7549 +               } while ((task2 = next_thread(task2)) != task);
7550 +       }
7551 +       read_unlock(&tasklist_lock);
7552 +
7553 +       /* free all object hash tables */
7554 +
7555 +       if (role_list_head) {
7556 +               for (r = role_list_head; r; r = r->next) {
7557 +                       if (!r->subj_hash)
7558 +                               break;
7559 +                       for (s = r->hash->first; s; s = s->next) {
7560 +                               if (!s->obj_hash)
7561 +                                       break;
7562 +                               if ((s->obj_hash_size *
7563 +                                    sizeof (struct acl_object_label *)) <=
7564 +                                   PAGE_SIZE)
7565 +                                       kfree(s->obj_hash);
7566 +                               else
7567 +                                       vfree(s->obj_hash);
7568 +                       }
7569 +                       if ((r->subj_hash_size *
7570 +                            sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
7571 +                               kfree(r->subj_hash);
7572 +                       else
7573 +                               vfree(r->subj_hash);
7574 +               }
7575 +       }
7576 +
7577 +       acl_free_all();
7578 +
7579 +       if (acl_role_set.r_hash) {
7580 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
7581 +                   PAGE_SIZE)
7582 +                       kfree(acl_role_set.r_hash);
7583 +               else
7584 +                       vfree(acl_role_set.r_hash);
7585 +       }
7586 +       if (name_set.n_hash) {
7587 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
7588 +                   PAGE_SIZE)
7589 +                       kfree(name_set.n_hash);
7590 +               else
7591 +                       vfree(name_set.n_hash);
7592 +       }
7593 +
7594 +       if (inodev_set.n_hash) {
7595 +               if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
7596 +                   PAGE_SIZE)
7597 +                       kfree(inodev_set.n_hash);
7598 +               else
7599 +                       vfree(inodev_set.n_hash);
7600 +       }
7601 +
7602 +       gr_free_uidset();
7603 +
7604 +       memset(&name_set, 0, sizeof (struct name_db));
7605 +       memset(&inodev_set, 0, sizeof (struct name_db));
7606 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
7607 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
7608 +
7609 +       role_list_head = NULL;
7610 +       default_role = NULL;
7611 +
7612 +       return;
7613 +}
7614 +
7615 +static __u32
7616 +count_user_objs(struct acl_object_label *userp)
7617 +{
7618 +       struct acl_object_label o_tmp;
7619 +       __u32 num = 0;
7620 +
7621 +       while (userp) {
7622 +               if (copy_from_user(&o_tmp, userp,
7623 +                                  sizeof (struct acl_object_label)))
7624 +                       break;
7625 +
7626 +               userp = o_tmp.prev;
7627 +               num++;
7628 +       }
7629 +
7630 +       return num;
7631 +}
7632 +
7633 +static struct acl_subject_label *
7634 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
7635 +
7636 +static int
7637 +copy_user_glob(struct acl_object_label *obj)
7638 +{
7639 +       struct acl_object_label *g_tmp, **guser, *glast = NULL;
7640 +       unsigned int len;
7641 +       char *tmp;
7642 +
7643 +       if (obj->globbed == NULL)
7644 +               return 0;
7645 +
7646 +       guser = &obj->globbed;
7647 +       while (*guser) {
7648 +               g_tmp = (struct acl_object_label *)
7649 +                       acl_alloc(sizeof (struct acl_object_label));
7650 +               if (g_tmp == NULL)
7651 +                       return -ENOMEM;
7652 +
7653 +               if (copy_from_user(g_tmp, *guser,
7654 +                                  sizeof (struct acl_object_label)))
7655 +                       return -EFAULT;
7656 +
7657 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
7658 +
7659 +               if (!len || len >= PATH_MAX)
7660 +                       return -EINVAL;
7661 +
7662 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
7663 +                       return -ENOMEM;
7664 +
7665 +               if (copy_from_user(tmp, g_tmp->filename, len))
7666 +                       return -EFAULT;
7667 +
7668 +               g_tmp->filename = tmp;
7669 +
7670 +               if (glast)
7671 +                       glast->next = g_tmp;
7672 +               g_tmp->prev = glast;
7673 +               *guser = g_tmp;
7674 +               glast = g_tmp;
7675 +               guser = &((*guser)->next);
7676 +       }
7677 +
7678 +       return 0;
7679 +}
7680 +
7681 +static int
7682 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
7683 +              struct acl_role_label *role)
7684 +{
7685 +       struct acl_object_label *o_tmp;
7686 +       unsigned int len;
7687 +       int ret;
7688 +       char *tmp;
7689 +
7690 +       while (userp) {
7691 +               if ((o_tmp = (struct acl_object_label *)
7692 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
7693 +                       return -ENOMEM;
7694 +
7695 +               if (copy_from_user(o_tmp, userp,
7696 +                                  sizeof (struct acl_object_label)))
7697 +                       return -EFAULT;
7698 +
7699 +               userp = o_tmp->prev;
7700 +
7701 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
7702 +
7703 +               if (!len || len >= PATH_MAX)
7704 +                       return -EINVAL;
7705 +
7706 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
7707 +                       return -ENOMEM;
7708 +
7709 +               if (copy_from_user(tmp, o_tmp->filename, len))
7710 +                       return -EFAULT;
7711 +
7712 +               o_tmp->filename = tmp;
7713 +
7714 +               insert_acl_obj_label(o_tmp, subj);
7715 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
7716 +                                      o_tmp->device))
7717 +                       return -ENOMEM;
7718 +
7719 +               ret = copy_user_glob(o_tmp);
7720 +               if (ret)
7721 +                       return ret;
7722 +
7723 +               if (o_tmp->nested) {
7724 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
7725 +                       if (IS_ERR(o_tmp->nested))
7726 +                               return PTR_ERR(o_tmp->nested);
7727 +
7728 +                       s_final = o_tmp->nested;
7729 +               }
7730 +       }
7731 +
7732 +       return 0;
7733 +}
7734 +
7735 +static __u32
7736 +count_user_subjs(struct acl_subject_label *userp)
7737 +{
7738 +       struct acl_subject_label s_tmp;
7739 +       __u32 num = 0;
7740 +
7741 +       while (userp) {
7742 +               if (copy_from_user(&s_tmp, userp,
7743 +                                  sizeof (struct acl_subject_label)))
7744 +                       break;
7745 +
7746 +               userp = s_tmp.prev;
7747 +               /* do not count nested subjects against this count, since
7748 +                  they are not included in the hash table, but are
7749 +                  attached to objects.  We have already counted
7750 +                  the subjects in userspace for the allocation 
7751 +                  stack
7752 +               */
7753 +               if (!(s_tmp.mode & GR_NESTED))
7754 +                       num++;
7755 +       }
7756 +
7757 +       return num;
7758 +}
7759 +
7760 +static int
7761 +copy_user_allowedips(struct acl_role_label *rolep)
7762 +{
7763 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
7764 +
7765 +       ruserip = rolep->allowed_ips;
7766 +
7767 +       while (ruserip) {
7768 +               rlast = rtmp;
7769 +
7770 +               if ((rtmp = (struct role_allowed_ip *)
7771 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
7772 +                       return -ENOMEM;
7773 +
7774 +               if (copy_from_user(rtmp, ruserip,
7775 +                                  sizeof (struct role_allowed_ip)))
7776 +                       return -EFAULT;
7777 +
7778 +               ruserip = rtmp->prev;
7779 +
7780 +               if (!rlast) {
7781 +                       rtmp->prev = NULL;
7782 +                       rolep->allowed_ips = rtmp;
7783 +               } else {
7784 +                       rlast->next = rtmp;
7785 +                       rtmp->prev = rlast;
7786 +               }
7787 +
7788 +               if (!ruserip)
7789 +                       rtmp->next = NULL;
7790 +       }
7791 +
7792 +       return 0;
7793 +}
7794 +
7795 +static int
7796 +copy_user_transitions(struct acl_role_label *rolep)
7797 +{
7798 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
7799 +       unsigned int len;
7800 +       char *tmp;
7801 +
7802 +       rusertp = rolep->transitions;
7803 +
7804 +       while (rusertp) {
7805 +               rlast = rtmp;
7806 +
7807 +               if ((rtmp = (struct role_transition *)
7808 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
7809 +                       return -ENOMEM;
7810 +
7811 +               if (copy_from_user(rtmp, rusertp,
7812 +                                  sizeof (struct role_transition)))
7813 +                       return -EFAULT;
7814 +
7815 +               rusertp = rtmp->prev;
7816 +
7817 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
7818 +
7819 +               if (!len || len >= GR_SPROLE_LEN)
7820 +                       return -EINVAL;
7821 +
7822 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
7823 +                       return -ENOMEM;
7824 +
7825 +               if (copy_from_user(tmp, rtmp->rolename, len))
7826 +                       return -EFAULT;
7827 +
7828 +               rtmp->rolename = tmp;
7829 +
7830 +               if (!rlast) {
7831 +                       rtmp->prev = NULL;
7832 +                       rolep->transitions = rtmp;
7833 +               } else {
7834 +                       rlast->next = rtmp;
7835 +                       rtmp->prev = rlast;
7836 +               }
7837 +
7838 +               if (!rusertp)
7839 +                       rtmp->next = NULL;
7840 +       }
7841 +
7842 +       return 0;
7843 +}
7844 +
7845 +static struct acl_subject_label *
7846 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
7847 +{
7848 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
7849 +       unsigned int len;
7850 +       char *tmp;
7851 +       __u32 num_objs;
7852 +       struct acl_ip_label **i_tmp, *i_utmp2;
7853 +       struct gr_hash_struct ghash;
7854 +       struct subject_map *subjmap;
7855 +       unsigned long i_num;
7856 +       int err;
7857 +
7858 +       s_tmp = lookup_subject_map(userp);
7859 +
7860 +       /* we've already copied this subject into the kernel, just return
7861 +          the reference to it, and don't copy it over again
7862 +       */
7863 +       if (s_tmp)
7864 +               return(s_tmp);
7865 +
7866 +
7867 +       if ((s_tmp = (struct acl_subject_label *)
7868 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
7869 +               return ERR_PTR(-ENOMEM);
7870 +
7871 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
7872 +       if (subjmap == NULL)
7873 +               return ERR_PTR(-ENOMEM);
7874 +
7875 +       subjmap->user = userp;
7876 +       subjmap->kernel = s_tmp;
7877 +       insert_subj_map_entry(subjmap);
7878 +
7879 +       if (copy_from_user(s_tmp, userp,
7880 +                          sizeof (struct acl_subject_label)))
7881 +               return ERR_PTR(-EFAULT);
7882 +
7883 +       if (!s_last) {
7884 +               s_tmp->prev = NULL;
7885 +               role->hash->first = s_tmp;
7886 +       } else {
7887 +               s_last->next = s_tmp;
7888 +               s_tmp->prev = s_last;
7889 +       }
7890 +
7891 +       s_last = s_tmp;
7892 +
7893 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
7894 +
7895 +       if (!len || len >= PATH_MAX)
7896 +               return ERR_PTR(-EINVAL);
7897 +
7898 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
7899 +               return ERR_PTR(-ENOMEM);
7900 +
7901 +       if (copy_from_user(tmp, s_tmp->filename, len))
7902 +               return ERR_PTR(-EFAULT);
7903 +
7904 +       s_tmp->filename = tmp;
7905 +
7906 +       if (!strcmp(s_tmp->filename, "/"))
7907 +               role->root_label = s_tmp;
7908 +
7909 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
7910 +               return ERR_PTR(-EFAULT);
7911 +
7912 +       /* copy user and group transition tables */
7913 +
7914 +       if (s_tmp->user_trans_num) {
7915 +               uid_t *uidlist;
7916 +
7917 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
7918 +               if (uidlist == NULL)
7919 +                       return ERR_PTR(-ENOMEM);
7920 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
7921 +                       return ERR_PTR(-EFAULT);
7922 +
7923 +               s_tmp->user_transitions = uidlist;
7924 +       }
7925 +
7926 +       if (s_tmp->group_trans_num) {
7927 +               gid_t *gidlist;
7928 +
7929 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
7930 +               if (gidlist == NULL)
7931 +                       return ERR_PTR(-ENOMEM);
7932 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
7933 +                       return ERR_PTR(-EFAULT);
7934 +
7935 +               s_tmp->group_transitions = gidlist;
7936 +       }
7937 +
7938 +       /* set up object hash table */
7939 +       num_objs = count_user_objs(ghash.first);
7940 +
7941 +       s_tmp->obj_hash_size = num_objs;
7942 +       s_tmp->obj_hash =
7943 +           (struct acl_object_label **)
7944 +           create_table(&(s_tmp->obj_hash_size));
7945 +
7946 +       if (!s_tmp->obj_hash)
7947 +               return ERR_PTR(-ENOMEM);
7948 +
7949 +       memset(s_tmp->obj_hash, 0,
7950 +              s_tmp->obj_hash_size *
7951 +              sizeof (struct acl_object_label *));
7952 +
7953 +       /* copy before adding in objects, since a nested
7954 +          acl could be found and be the final subject
7955 +          copied
7956 +       */
7957 +
7958 +       s_final = s_tmp;
7959 +
7960 +       /* add in objects */
7961 +       err = copy_user_objs(ghash.first, s_tmp, role);
7962 +
7963 +       if (err)
7964 +               return ERR_PTR(err);
7965 +
7966 +       /* set pointer for parent subject */
7967 +       if (s_tmp->parent_subject) {
7968 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
7969 +
7970 +               if (IS_ERR(s_tmp2))
7971 +                       return s_tmp2;
7972 +
7973 +               s_tmp->parent_subject = s_tmp2;
7974 +       }
7975 +
7976 +       /* add in ip acls */
7977 +
7978 +       if (!s_tmp->ip_num) {
7979 +               s_tmp->ips = NULL;
7980 +               goto insert;
7981 +       }
7982 +
7983 +       i_tmp =
7984 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
7985 +                                              sizeof (struct
7986 +                                                      acl_ip_label *));
7987 +
7988 +       if (!i_tmp)
7989 +               return ERR_PTR(-ENOMEM);
7990 +
7991 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
7992 +               *(i_tmp + i_num) =
7993 +                   (struct acl_ip_label *)
7994 +                   acl_alloc(sizeof (struct acl_ip_label));
7995 +               if (!*(i_tmp + i_num))
7996 +                       return ERR_PTR(-ENOMEM);
7997 +
7998 +               if (copy_from_user
7999 +                   (&i_utmp2, s_tmp->ips + i_num,
8000 +                    sizeof (struct acl_ip_label *)))
8001 +                       return ERR_PTR(-EFAULT);
8002 +
8003 +               if (copy_from_user
8004 +                   (*(i_tmp + i_num), i_utmp2,
8005 +                    sizeof (struct acl_ip_label)))
8006 +                       return ERR_PTR(-EFAULT);
8007 +       }
8008 +
8009 +       s_tmp->ips = i_tmp;
8010 +
8011 +insert:
8012 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
8013 +                              s_tmp->device))
8014 +               return ERR_PTR(-ENOMEM);
8015 +
8016 +       return s_tmp;
8017 +}
8018 +
8019 +static int
8020 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
8021 +{
8022 +       struct acl_subject_label s_pre;
8023 +       struct acl_subject_label * ret;
8024 +       int err;
8025 +
8026 +       while (userp) {
8027 +               if (copy_from_user(&s_pre, userp,
8028 +                                  sizeof (struct acl_subject_label)))
8029 +                       return -EFAULT;
8030 +               
8031 +               /* do not add nested subjects here, add
8032 +                  while parsing objects
8033 +               */
8034 +
8035 +               if (s_pre.mode & GR_NESTED) {
8036 +                       userp = s_pre.prev;
8037 +                       continue;
8038 +               }
8039 +
8040 +               ret = do_copy_user_subj(userp, role);
8041 +
8042 +               err = PTR_ERR(ret);
8043 +               if (IS_ERR(ret))
8044 +                       return err;
8045 +
8046 +               insert_acl_subj_label(ret, role);
8047 +
8048 +               userp = s_pre.prev;
8049 +       }
8050 +
8051 +       s_final->next = NULL;
8052 +
8053 +       return 0;
8054 +}
8055 +
8056 +static int
8057 +copy_user_acl(struct gr_arg *arg)
8058 +{
8059 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
8060 +       struct sprole_pw *sptmp;
8061 +       struct gr_hash_struct *ghash;
8062 +       unsigned long r_num;
8063 +       unsigned int len;
8064 +       char *tmp;
8065 +       int err = 0;
8066 +       __u16 i;
8067 +       __u32 num_subjs;
8068 +
8069 +       /* we need a default and kernel role */
8070 +       if (arg->role_db.r_entries < 2)
8071 +               return -EINVAL;
8072 +
8073 +       /* copy special role authentication info from userspace */
8074 +
8075 +       num_sprole_pws = arg->num_sprole_pws;
8076 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
8077 +
8078 +       if (!acl_special_roles) {
8079 +               err = -ENOMEM;
8080 +               goto cleanup;
8081 +       }
8082 +
8083 +       for (i = 0; i < num_sprole_pws; i++) {
8084 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
8085 +               if (!sptmp) {
8086 +                       err = -ENOMEM;
8087 +                       goto cleanup;
8088 +               }
8089 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
8090 +                                  sizeof (struct sprole_pw))) {
8091 +                       err = -EFAULT;
8092 +                       goto cleanup;
8093 +               }
8094 +
8095 +               len =
8096 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
8097 +
8098 +               if (!len || len >= GR_SPROLE_LEN) {
8099 +                       err = -EINVAL;
8100 +                       goto cleanup;
8101 +               }
8102 +
8103 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
8104 +                       err = -ENOMEM;
8105 +                       goto cleanup;
8106 +               }
8107 +
8108 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
8109 +                       err = -EFAULT;
8110 +                       goto cleanup;
8111 +               }
8112 +
8113 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
8114 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
8115 +#endif
8116 +               sptmp->rolename = tmp;
8117 +               acl_special_roles[i] = sptmp;
8118 +       }
8119 +
8120 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
8121 +
8122 +       for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
8123 +               r_last = r_tmp;
8124 +
8125 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
8126 +
8127 +               if (!r_tmp) {
8128 +                       err = -ENOMEM;
8129 +                       goto cleanup;
8130 +               }
8131 +
8132 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
8133 +                                  sizeof (struct acl_role_label *))) {
8134 +                       err = -EFAULT;
8135 +                       goto cleanup;
8136 +               }
8137 +
8138 +               if (copy_from_user(r_tmp, r_utmp2,
8139 +                                  sizeof (struct acl_role_label))) {
8140 +                       err = -EFAULT;
8141 +                       goto cleanup;
8142 +               }
8143 +
8144 +               if (!r_last) {
8145 +                       r_tmp->prev = NULL;
8146 +                       role_list_head = r_tmp;
8147 +               } else {
8148 +                       r_last->next = r_tmp;
8149 +                       r_tmp->prev = r_last;
8150 +               }
8151 +
8152 +               if (r_num == (arg->role_db.r_entries - 1))
8153 +                       r_tmp->next = NULL;
8154 +
8155 +               len = strnlen_user(r_tmp->rolename, PATH_MAX);
8156 +
8157 +               if (!len || len >= PATH_MAX) {
8158 +                       err = -EINVAL;
8159 +                       goto cleanup;
8160 +               }
8161 +
8162 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
8163 +                       err = -ENOMEM;
8164 +                       goto cleanup;
8165 +               }
8166 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
8167 +                       err = -EFAULT;
8168 +                       goto cleanup;
8169 +               }
8170 +               r_tmp->rolename = tmp;
8171 +
8172 +               if (!strcmp(r_tmp->rolename, "default")
8173 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
8174 +                       default_role = r_tmp;
8175 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
8176 +                       kernel_role = r_tmp;
8177 +               }
8178 +
8179 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
8180 +                       err = -ENOMEM;
8181 +                       goto cleanup;
8182 +               }
8183 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
8184 +                       err = -EFAULT;
8185 +                       goto cleanup;
8186 +               }
8187 +
8188 +               r_tmp->hash = ghash;
8189 +
8190 +               num_subjs = count_user_subjs(r_tmp->hash->first);
8191 +
8192 +               r_tmp->subj_hash_size = num_subjs;
8193 +               r_tmp->subj_hash =
8194 +                   (struct acl_subject_label **)
8195 +                   create_table(&(r_tmp->subj_hash_size));
8196 +
8197 +               if (!r_tmp->subj_hash) {
8198 +                       err = -ENOMEM;
8199 +                       goto cleanup;
8200 +               }
8201 +
8202 +               err = copy_user_allowedips(r_tmp);
8203 +               if (err)
8204 +                       goto cleanup;
8205 +
8206 +               err = copy_user_transitions(r_tmp);
8207 +               if (err)
8208 +                       goto cleanup;
8209 +
8210 +               memset(r_tmp->subj_hash, 0,
8211 +                      r_tmp->subj_hash_size *
8212 +                      sizeof (struct acl_subject_label *));
8213 +
8214 +               s_last = NULL;
8215 +
8216 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
8217 +
8218 +               if (err)
8219 +                       goto cleanup;
8220 +
8221 +               insert_acl_role_label(r_tmp);
8222 +       }
8223 +
8224 +       goto return_err;
8225 +      cleanup:
8226 +       free_variables();
8227 +      return_err:
8228 +       return err;
8229 +
8230 +}
8231 +
8232 +static int
8233 +gracl_init(struct gr_arg *args)
8234 +{
8235 +       int error = 0;
8236 +
8237 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
8238 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
8239 +
8240 +       if (init_variables(args->role_db.o_entries, args->role_db.g_entries,
8241 +                          args->role_db.s_entries, args->role_db.i_entries,
8242 +                          args->role_db.r_entries, args->role_db.a_entries,
8243 +                          args->role_db.t_entries, args->num_sprole_pws)) {
8244 +               security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
8245 +               error = -ENOMEM;
8246 +               free_variables();
8247 +               goto out;
8248 +       }
8249 +
8250 +       error = copy_user_acl(args);
8251 +       free_init_variables();
8252 +       if (error) {
8253 +               free_variables();
8254 +               goto out;
8255 +       }
8256 +
8257 +       if ((error = gr_set_acls(0))) {
8258 +               free_variables();
8259 +               goto out;
8260 +       }
8261 +
8262 +       gr_status |= GR_READY;
8263 +      out:
8264 +       return error;
8265 +}
8266 +
8267 +static int
8268 +glob_match(char *pattern, char *string)
8269 +{
8270 +       char *p1, *p2;
8271 +
8272 +       p1 = pattern;
8273 +       p2 = string;
8274 +
8275 +       while (*p1 != '\0' && *p2 != '\0' && *p1 != '*') {
8276 +               if (*p1 == *p2 || *p1 == '?') {
8277 +                       p1++;
8278 +                       p2++;
8279 +               } else
8280 +                       break;
8281 +       }
8282 +       if (*p1 == '*') {
8283 +               p1++;
8284 +               while (*p2 != '\0') {
8285 +                       if (!glob_match(p1, p2))
8286 +                               return 0;
8287 +                       else
8288 +                               p2++;
8289 +               }
8290 +       } 
8291 +
8292 +       if (*p2 == '\0' && *p1 == '*')
8293 +               while (*p1 == '*')
8294 +                       p1++;
8295 +
8296 +       if (*p1 == '\0' && *p2 == '\0')
8297 +               return 0;
8298 +       else
8299 +               return 1;
8300 +}
8301 +
8302 +static struct acl_object_label *
8303 +chk_glob_label(struct acl_object_label *globbed,
8304 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
8305 +{
8306 +       struct acl_object_label *tmp;
8307 +
8308 +       if (*path == NULL)
8309 +               *path = gr_to_filename_nolock(dentry, mnt);
8310 +
8311 +       tmp = globbed;
8312 +
8313 +       while (tmp) {
8314 +               if (!glob_match(tmp->filename, *path))
8315 +                       return tmp;
8316 +               tmp = tmp->next;
8317 +       }
8318 +
8319 +       return NULL;
8320 +}
8321 +
8322 +static __inline__ struct acl_object_label *
8323 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
8324 +           struct dentry *curr_dentry,
8325 +           const struct acl_subject_label *subj, char **path)
8326 +{
8327 +       struct acl_subject_label *tmpsubj;
8328 +       struct acl_object_label *retval;
8329 +       struct acl_object_label *retval2;
8330 +
8331 +       tmpsubj = (struct acl_subject_label *) subj;
8332 +       read_lock(&gr_inode_lock);
8333 +       do {
8334 +               retval = lookup_acl_obj_label(curr_dentry->d_inode->i_ino,
8335 +                                       curr_dentry->d_inode->i_sb->s_dev, tmpsubj);
8336 +               if (retval) {
8337 +                       if (retval->globbed) {
8338 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
8339 +                                               (struct vfsmount *)orig_mnt, path);
8340 +                               if (retval2)
8341 +                                       retval = retval2;
8342 +                       }
8343 +                       break;
8344 +               }
8345 +       } while ((tmpsubj = tmpsubj->parent_subject));
8346 +       read_unlock(&gr_inode_lock);
8347 +
8348 +       return retval;
8349 +}
8350 +
8351 +static struct acl_object_label *
8352 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
8353 +             const struct acl_subject_label *subj)
8354 +{
8355 +       struct dentry *dentry = (struct dentry *) l_dentry;
8356 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
8357 +       struct dentry *root;
8358 +       struct vfsmount *rootmnt;
8359 +       struct acl_object_label *retval;
8360 +       char *path = NULL;
8361 +
8362 +       read_lock(&child_reaper->fs->lock);
8363 +       rootmnt = mntget(child_reaper->fs->rootmnt);
8364 +       root = dget(child_reaper->fs->root);
8365 +       read_unlock(&child_reaper->fs->lock);
8366 +       spin_lock(&dcache_lock);
8367 +
8368 +       for (;;) {
8369 +               if (dentry == root && mnt == rootmnt)
8370 +                       break;
8371 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
8372 +                       if (mnt->mnt_parent == mnt)
8373 +                               break;
8374 +
8375 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
8376 +                       if (retval != NULL)
8377 +                               goto out;
8378 +
8379 +                       dentry = mnt->mnt_mountpoint;
8380 +                       mnt = mnt->mnt_parent;
8381 +                       continue;
8382 +               }
8383 +
8384 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
8385 +               if (retval != NULL)
8386 +                       goto out;
8387 +
8388 +               dentry = dentry->d_parent;
8389 +       }
8390 +
8391 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
8392 +
8393 +       if (retval == NULL)
8394 +               retval = full_lookup(l_dentry, l_mnt, root, subj, &path);
8395 +out:
8396 +       spin_unlock(&dcache_lock);
8397 +       dput(root);
8398 +       mntput(rootmnt);
8399 +
8400 +       return retval;
8401 +}
8402 +
8403 +static struct acl_object_label *
8404 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
8405 +             const struct acl_subject_label *subj, char *path)
8406 +{
8407 +       struct dentry *dentry = (struct dentry *) l_dentry;
8408 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
8409 +       struct dentry *root;
8410 +       struct vfsmount *rootmnt;
8411 +       struct acl_object_label *retval;
8412 +
8413 +       read_lock(&child_reaper->fs->lock);
8414 +       rootmnt = mntget(child_reaper->fs->rootmnt);
8415 +       root = dget(child_reaper->fs->root);
8416 +       read_unlock(&child_reaper->fs->lock);
8417 +       spin_lock(&dcache_lock);
8418 +
8419 +       for (;;) {
8420 +               if (dentry == root && mnt == rootmnt)
8421 +                       break;
8422 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
8423 +                       if (mnt->mnt_parent == mnt)
8424 +                               break;
8425 +
8426 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
8427 +                       if (retval != NULL)
8428 +                               goto out;
8429 +
8430 +                       dentry = mnt->mnt_mountpoint;
8431 +                       mnt = mnt->mnt_parent;
8432 +                       continue;
8433 +               }
8434 +
8435 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
8436 +               if (retval != NULL)
8437 +                       goto out;
8438 +
8439 +               dentry = dentry->d_parent;
8440 +       }
8441 +
8442 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
8443 +
8444 +       if (retval == NULL)
8445 +               retval = full_lookup(l_dentry, l_mnt, root, subj, &path);
8446 +out:
8447 +       spin_unlock(&dcache_lock);
8448 +       dput(root);
8449 +       mntput(rootmnt);
8450 +
8451 +       return retval;
8452 +}
8453 +
8454 +static struct acl_subject_label *
8455 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
8456 +              const struct acl_role_label *role)
8457 +{
8458 +       struct dentry *dentry = (struct dentry *) l_dentry;
8459 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
8460 +       struct dentry *root;
8461 +       struct vfsmount *rootmnt;
8462 +       struct acl_subject_label *retval;
8463 +
8464 +       read_lock(&child_reaper->fs->lock);
8465 +       rootmnt = mntget(child_reaper->fs->rootmnt);
8466 +       root = dget(child_reaper->fs->root);
8467 +       read_unlock(&child_reaper->fs->lock);
8468 +       spin_lock(&dcache_lock);
8469 +
8470 +       for (;;) {
8471 +               if (unlikely(dentry == root && mnt == rootmnt))
8472 +                       break;
8473 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
8474 +                       if (mnt->mnt_parent == mnt)
8475 +                               break;
8476 +
8477 +                       read_lock(&gr_inode_lock);
8478 +                       retval =
8479 +                           lookup_acl_subj_label(dentry->d_inode->i_ino,
8480 +                                                 dentry->d_inode->i_sb->s_dev, role);
8481 +                       read_unlock(&gr_inode_lock);
8482 +                       if (unlikely(retval != NULL))
8483 +                               goto out;
8484 +
8485 +                       dentry = mnt->mnt_mountpoint;
8486 +                       mnt = mnt->mnt_parent;
8487 +                       continue;
8488 +               }
8489 +
8490 +               read_lock(&gr_inode_lock);
8491 +               retval =
8492 +                   lookup_acl_subj_label(dentry->d_inode->i_ino,
8493 +                                         dentry->d_inode->i_sb->s_dev, role);
8494 +               read_unlock(&gr_inode_lock);
8495 +               if (unlikely(retval != NULL))
8496 +                       goto out;
8497 +
8498 +               dentry = dentry->d_parent;
8499 +       }
8500 +
8501 +       read_lock(&gr_inode_lock);
8502 +       retval =
8503 +           lookup_acl_subj_label(dentry->d_inode->i_ino,
8504 +                                 dentry->d_inode->i_sb->s_dev, role);
8505 +       read_unlock(&gr_inode_lock);
8506 +
8507 +       if (unlikely(retval == NULL)) {
8508 +               read_lock(&gr_inode_lock);
8509 +               retval =
8510 +                   lookup_acl_subj_label(root->d_inode->i_ino,
8511 +                                         root->d_inode->i_sb->s_dev, role);
8512 +               read_unlock(&gr_inode_lock);
8513 +       }
8514 +      out:
8515 +       spin_unlock(&dcache_lock);
8516 +       dput(root);
8517 +       mntput(rootmnt);
8518 +
8519 +       return retval;
8520 +}
8521 +
8522 +static __inline__ void
8523 +gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
8524 +            const struct task_struct *task, const char *pathname,
8525 +            const __u32 mode)
8526 +{
8527 +       security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
8528 +                      uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
8529 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
8530 +                      1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
8531 +
8532 +       return;
8533 +}
8534 +
8535 +__u32
8536 +gr_check_link(const struct dentry * new_dentry,
8537 +             const struct dentry * parent_dentry,
8538 +             const struct vfsmount * parent_mnt,
8539 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
8540 +{
8541 +       struct acl_object_label *obj;
8542 +       __u32 oldmode, newmode;
8543 +
8544 +       if (unlikely(!(gr_status & GR_READY)))
8545 +               return (GR_WRITE | GR_CREATE);
8546 +
8547 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
8548 +       oldmode = obj->mode;
8549 +
8550 +       if (current->acl->mode & GR_LEARN)
8551 +               oldmode |= (GR_WRITE | GR_CREATE);
8552 +       newmode =
8553 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
8554 +                           oldmode | GR_CREATE | GR_AUDIT_CREATE |
8555 +                           GR_AUDIT_WRITE | GR_SUPPRESS);
8556 +
8557 +       if ((newmode & oldmode) == oldmode)
8558 +               return newmode;
8559 +       else if (current->acl->mode & GR_LEARN) {
8560 +               gr_log_learn(current->role, current->uid, current->gid,
8561 +                       current, gr_to_filename(old_dentry, old_mnt), oldmode);
8562 +               return (GR_WRITE | GR_CREATE);
8563 +       } else if (newmode & GR_SUPPRESS)
8564 +               return GR_SUPPRESS;
8565 +       else
8566 +               return 0;
8567 +}
8568 +
8569 +__u32
8570 +gr_search_file(const struct dentry * dentry, const __u32 mode,
8571 +              const struct vfsmount * mnt)
8572 +{
8573 +       __u32 retval = mode;
8574 +       struct acl_subject_label *curracl;
8575 +       struct acl_object_label *currobj;
8576 +
8577 +       if (unlikely(!(gr_status & GR_READY)))
8578 +               return (mode & ~GR_AUDITS);
8579 +
8580 +       curracl = current->acl;
8581 +
8582 +       currobj = chk_obj_label(dentry, mnt, curracl);
8583 +       retval = currobj->mode & mode;
8584 +
8585 +       if (unlikely
8586 +           ((curracl->mode & GR_LEARN) && !(mode & GR_NOPTRACE)
8587 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
8588 +               __u32 new_mode = mode;
8589 +
8590 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
8591 +
8592 +               retval = new_mode;
8593 +
8594 +               if (!(mode & GR_NOLEARN))
8595 +                       gr_log_learn(current->role, current->uid, current->gid,
8596 +                                    current, gr_to_filename(dentry, mnt), new_mode);
8597 +       }
8598 +
8599 +       return retval;
8600 +}
8601 +
8602 +__u32
8603 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
8604 +               const struct vfsmount * mnt, const __u32 mode)
8605 +{
8606 +       struct name_entry *match;
8607 +       struct acl_object_label *matchpo;
8608 +       struct acl_subject_label *curracl;
8609 +       char *path;
8610 +       __u32 retval;
8611 +
8612 +       if (unlikely(!(gr_status & GR_READY)))
8613 +               return (mode & ~GR_AUDITS);
8614 +
8615 +       preempt_disable();
8616 +       path = gr_to_filename(new_dentry, mnt);
8617 +       match = lookup_name_entry(path);
8618 +
8619 +       if (!match)
8620 +               goto check_parent;
8621 +
8622 +       curracl = current->acl;
8623 +
8624 +       read_lock(&gr_inode_lock);
8625 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
8626 +       read_unlock(&gr_inode_lock);
8627 +
8628 +       if (matchpo) {
8629 +               if ((matchpo->mode & mode) !=
8630 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
8631 +                   && curracl->mode & GR_LEARN) {
8632 +                       __u32 new_mode = mode;
8633 +
8634 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
8635 +
8636 +                       gr_log_learn(current->role, current->uid, current->gid,
8637 +                                    current, gr_to_filename(new_dentry, mnt), new_mode);
8638 +
8639 +                       preempt_enable();
8640 +                       return new_mode;
8641 +               }
8642 +               preempt_enable();
8643 +               return (matchpo->mode & mode);
8644 +       }
8645 +
8646 +      check_parent:
8647 +       curracl = current->acl;
8648 +
8649 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
8650 +       retval = matchpo->mode & mode;
8651 +
8652 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
8653 +           && (curracl->mode & GR_LEARN)) {
8654 +               __u32 new_mode = mode;
8655 +
8656 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
8657 +
8658 +               gr_log_learn(current->role, current->uid, current->gid, 
8659 +                            current, gr_to_filename(new_dentry, mnt), new_mode);
8660 +               preempt_enable();
8661 +               return new_mode;
8662 +       }
8663 +
8664 +       preempt_enable();
8665 +       return retval;
8666 +}
8667 +
8668 +int
8669 +gr_check_hidden_task(const struct task_struct *task)
8670 +{
8671 +       if (unlikely(!(gr_status & GR_READY)))
8672 +               return 0;
8673 +
8674 +       if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
8675 +               return 1;
8676 +
8677 +       return 0;
8678 +}
8679 +
8680 +int
8681 +gr_check_protected_task(const struct task_struct *task)
8682 +{
8683 +       if (unlikely(!(gr_status & GR_READY) || !task))
8684 +               return 0;
8685 +
8686 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
8687 +               return 1;
8688 +
8689 +       return 0;
8690 +}
8691 +
8692 +__inline__ void
8693 +gr_copy_label(struct task_struct *tsk)
8694 +{
8695 +       tsk->used_accept = 0;
8696 +       tsk->acl_sp_role = 0;
8697 +       tsk->acl_role_id = current->acl_role_id;
8698 +       tsk->acl = current->acl;
8699 +       tsk->role = current->role;
8700 +       tsk->curr_ip = current->curr_ip;
8701 +       if (current->exec_file)
8702 +               get_file(current->exec_file);
8703 +       tsk->exec_file = current->exec_file;
8704 +       tsk->is_writable = current->is_writable;
8705 +       if (unlikely(current->used_accept))
8706 +               current->curr_ip = 0;
8707 +
8708 +       return;
8709 +}
8710 +
8711 +static __inline__ void
8712 +gr_set_proc_res(void)
8713 +{
8714 +       struct acl_subject_label *proc;
8715 +       unsigned short i;
8716 +
8717 +       proc = current->acl;
8718 +
8719 +       if (proc->mode & GR_LEARN)
8720 +               return;
8721 +
8722 +       for (i = 0; i < RLIM_NLIMITS; i++) {
8723 +               if (!(proc->resmask & (1 << i)))
8724 +                       continue;
8725 +
8726 +               current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
8727 +               current->rlim[i].rlim_max = proc->res[i].rlim_max;
8728 +       }
8729 +
8730 +       return;
8731 +}
8732 +
8733 +static __inline__ void
8734 +do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
8735 +{
8736 +       task->role = lookup_acl_role_label(task, uid, gid);
8737 +
8738 +       return;
8739 +}
8740 +
8741 +int
8742 +gr_check_user_change(int real, int effective, int fs)
8743 +{
8744 +       unsigned int i;
8745 +       __u16 num;
8746 +       uid_t *uidlist;
8747 +       int curuid;
8748 +       int realok = 0;
8749 +       int effectiveok = 0;
8750 +       int fsok = 0;
8751 +
8752 +       if (unlikely(!(gr_status & GR_READY)))
8753 +               return 0;
8754 +
8755 +       num = current->acl->user_trans_num;
8756 +       uidlist = current->acl->user_transitions;
8757 +
8758 +       if (uidlist == NULL)
8759 +               return 0;
8760 +
8761 +       if (real == -1)
8762 +               realok = 1;
8763 +       if (effective == -1)
8764 +               effectiveok = 1;
8765 +       if (fs == -1)
8766 +               fsok = 1;
8767 +
8768 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
8769 +               for (i = 0; i < num; i++) {
8770 +                       curuid = (int)uidlist[i];
8771 +                       if (real == curuid)
8772 +                               realok = 1;
8773 +                       if (effective == curuid)
8774 +                               effectiveok = 1;
8775 +                       if (fs == curuid)
8776 +                               fsok = 1;
8777 +               }
8778 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
8779 +               for (i = 0; i < num; i++) {
8780 +                       curuid = (int)uidlist[i];
8781 +                       if (real == curuid)
8782 +                               break;
8783 +                       if (effective == curuid)
8784 +                               break;
8785 +                       if (fs == curuid)
8786 +                               break;
8787 +               }
8788 +               /* not in deny list */
8789 +               if (i == num) {
8790 +                       realok = 1;
8791 +                       effectiveok = 1;
8792 +                       fsok = 1;
8793 +               }
8794 +       }
8795 +
8796 +       if (realok && effectiveok && fsok)
8797 +               return 0;
8798 +       else {
8799 +               security_alert(GR_USRCHANGE_ACL_MSG,
8800 +                       realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real, DEFAULTSECARGS);
8801 +               return 1;
8802 +       }
8803 +}
8804 +
8805 +int
8806 +gr_check_group_change(int real, int effective, int fs)
8807 +{
8808 +       unsigned int i;
8809 +       __u16 num;
8810 +       gid_t *gidlist;
8811 +       int curgid;
8812 +       int realok = 0;
8813 +       int effectiveok = 0;
8814 +       int fsok = 0;
8815 +
8816 +       if (unlikely(!(gr_status & GR_READY)))
8817 +               return 0;
8818 +
8819 +       num = current->acl->group_trans_num;
8820 +       gidlist = current->acl->group_transitions;
8821 +
8822 +       if (gidlist == NULL)
8823 +               return 0;
8824 +
8825 +       if (real == -1)
8826 +               realok = 1;
8827 +       if (effective == -1)
8828 +               effectiveok = 1;
8829 +       if (fs == -1)
8830 +               fsok = 1;
8831 +
8832 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
8833 +               for (i = 0; i < num; i++) {
8834 +                       curgid = (int)gidlist[i];
8835 +                       if (real == curgid)
8836 +                               realok = 1;
8837 +                       if (effective == curgid)
8838 +                               effectiveok = 1;
8839 +                       if (fs == curgid)
8840 +                               fsok = 1;
8841 +               }
8842 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
8843 +               for (i = 0; i < num; i++) {
8844 +                       curgid = (int)gidlist[i];
8845 +                       if (real == curgid)
8846 +                               break;
8847 +                       if (effective == curgid)
8848 +                               break;
8849 +                       if (fs == curgid)
8850 +                               break;
8851 +               }
8852 +               /* not in deny list */
8853 +               if (i == num) {
8854 +                       realok = 1;
8855 +                       effectiveok = 1;
8856 +                       fsok = 1;
8857 +               }
8858 +       }
8859 +
8860 +       if (realok && effectiveok && fsok)
8861 +               return 0;
8862 +       else {
8863 +               security_alert(GR_GRPCHANGE_ACL_MSG,
8864 +                       realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real, DEFAULTSECARGS);
8865 +               return 1;
8866 +       }
8867 +}
8868 +
8869 +void
8870 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
8871 +{
8872 +       struct acl_object_label *obj;
8873 +       struct file *filp;
8874 +
8875 +       if (unlikely(!(gr_status & GR_READY)))
8876 +               return;
8877 +
8878 +       filp = task->exec_file;
8879 +
8880 +       /* kernel process, we'll give them the kernel role */
8881 +       if (unlikely(!filp)) {
8882 +               task->role = kernel_role;
8883 +               task->acl = kernel_role->root_label;
8884 +               return;
8885 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
8886 +               do_set_role_label(task, uid, gid);
8887 +
8888 +       task->acl =
8889 +           chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
8890 +
8891 +       task->is_writable = 0;
8892 +
8893 +       /* ignore additional mmap checks for processes that are writable 
8894 +          by the default ACL */
8895 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
8896 +       if (unlikely(obj->mode & GR_WRITE))
8897 +               task->is_writable = 1;
8898 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
8899 +       if (unlikely(obj->mode & GR_WRITE))
8900 +               task->is_writable = 1;
8901 +
8902 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
8903 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
8904 +#endif
8905 +
8906 +       gr_set_proc_res();
8907 +
8908 +       return;
8909 +}
8910 +
8911 +void
8912 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
8913 +{
8914 +       struct acl_subject_label *newacl;
8915 +       struct acl_object_label *obj;
8916 +       __u32 retmode;
8917 +
8918 +       if (unlikely(!(gr_status & GR_READY)))
8919 +               return;
8920 +
8921 +       newacl = chk_subj_label(dentry, mnt, current->role);
8922 +
8923 +       obj = chk_obj_label(dentry, mnt, current->acl);
8924 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
8925 +
8926 +       if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
8927 +               if (obj->nested)
8928 +                       current->acl = obj->nested;
8929 +               else
8930 +                       current->acl = newacl;
8931 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
8932 +               security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
8933 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
8934 +
8935 +       current->is_writable = 0;
8936 +
8937 +       /* ignore additional mmap checks for processes that are writable 
8938 +          by the default ACL */
8939 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
8940 +       if (unlikely(obj->mode & GR_WRITE))
8941 +               current->is_writable = 1;
8942 +       obj = chk_obj_label(dentry, mnt, current->role->root_label);
8943 +       if (unlikely(obj->mode & GR_WRITE))
8944 +               current->is_writable = 1;
8945 +
8946 +       gr_set_proc_res();
8947 +
8948 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
8949 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
8950 +#endif
8951 +       return;
8952 +}
8953 +
8954 +static __inline__ void
8955 +do_handle_delete(const ino_t ino, const dev_t dev)
8956 +{
8957 +       struct acl_object_label *matchpo;
8958 +       struct acl_subject_label *matchps;
8959 +       struct acl_subject_label *i;
8960 +       struct acl_role_label *role;
8961 +
8962 +       for (role = role_list_head; role; role = role->next) {
8963 +               for (i = role->hash->first; i; i = i->next) {
8964 +                       if (unlikely((i->mode & GR_NESTED) &&
8965 +                                    (i->inode == ino) &&
8966 +                                    (i->device == dev)))
8967 +                               i->mode |= GR_DELETED;
8968 +                       if (unlikely((matchpo =
8969 +                            lookup_acl_obj_label(ino, dev, i)) != NULL))
8970 +                               matchpo->mode |= GR_DELETED;
8971 +               }
8972 +
8973 +               if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
8974 +                       matchps->mode |= GR_DELETED;
8975 +       }
8976 +
8977 +       return;
8978 +}
8979 +
8980 +void
8981 +gr_handle_delete(const ino_t ino, const dev_t dev)
8982 +{
8983 +       if (unlikely(!(gr_status & GR_READY)))
8984 +               return;
8985 +
8986 +       write_lock(&gr_inode_lock);
8987 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
8988 +               do_handle_delete(ino, dev);
8989 +       write_unlock(&gr_inode_lock);
8990 +
8991 +       return;
8992 +}
8993 +
8994 +static __inline__ void
8995 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
8996 +                    const ino_t newinode, const dev_t newdevice,
8997 +                    struct acl_subject_label *subj)
8998 +{
8999 +       unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
9000 +       struct acl_object_label **match;
9001 +       struct acl_object_label *tmp;
9002 +       __u8 i = 0;
9003 +
9004 +       match = &subj->obj_hash[index];
9005 +
9006 +       while (*match && ((*match)->inode != oldinode ||
9007 +              (*match)->device != olddevice ||
9008 +              !((*match)->mode & GR_DELETED))) {
9009 +               index = (index + (1 << i)) % subj->obj_hash_size;
9010 +               match = &subj->obj_hash[index];
9011 +               i = (i + 1) % 32;
9012 +       }
9013 +
9014 +       if (*match && ((*match) != deleted_object)
9015 +           && ((*match)->inode == oldinode)
9016 +           && ((*match)->device == olddevice)
9017 +           && ((*match)->mode & GR_DELETED)) {
9018 +               tmp = *match;
9019 +               tmp->inode = newinode;
9020 +               tmp->device = newdevice;
9021 +               tmp->mode &= ~GR_DELETED;
9022 +
9023 +               *match = deleted_object;
9024 +
9025 +               insert_acl_obj_label(tmp, subj);
9026 +       }
9027 +
9028 +       return;
9029 +}
9030 +
9031 +static __inline__ void
9032 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
9033 +                     const ino_t newinode, const dev_t newdevice,
9034 +                     struct acl_role_label *role)
9035 +{
9036 +       struct acl_subject_label **s_hash = role->subj_hash;
9037 +       unsigned long subj_size = role->subj_hash_size;
9038 +       unsigned long index = fhash(oldinode, olddevice, subj_size);
9039 +       struct acl_subject_label **match;
9040 +       struct acl_subject_label *tmp;
9041 +       __u8 i = 0;
9042 +
9043 +       match = &s_hash[index];
9044 +
9045 +       while (*match && ((*match)->inode != oldinode ||
9046 +              (*match)->device != olddevice ||
9047 +              !((*match)->mode & GR_DELETED))) {
9048 +               index = (index + (1 << i)) % subj_size;
9049 +               i = (i + 1) % 32;
9050 +               match = &s_hash[index];
9051 +       }
9052 +
9053 +       if (*match && (*match != deleted_subject)
9054 +           && ((*match)->inode == oldinode)
9055 +           && ((*match)->device == olddevice)
9056 +           && ((*match)->mode & GR_DELETED)) {
9057 +               tmp = *match;
9058 +
9059 +               tmp->inode = newinode;
9060 +               tmp->device = newdevice;
9061 +               tmp->mode &= ~GR_DELETED;
9062 +
9063 +               *match = deleted_subject;
9064 +
9065 +               insert_acl_subj_label(tmp, role);
9066 +       }
9067 +
9068 +       return;
9069 +}
9070 +
9071 +static __inline__ void
9072 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
9073 +                   const ino_t newinode, const dev_t newdevice)
9074 +{
9075 +       unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
9076 +       struct name_entry **match;
9077 +       struct name_entry *tmp;
9078 +       __u8 i = 0;
9079 +
9080 +       match = &inodev_set.n_hash[index];
9081 +
9082 +       while (*match
9083 +              && ((*match)->inode != oldinode
9084 +                  || (*match)->device != olddevice)) {
9085 +               index = (index + (1 << i)) % inodev_set.n_size;
9086 +               i = (i + 1) % 32;
9087 +               match = &inodev_set.n_hash[index];
9088 +       }
9089 +
9090 +       if (*match && (*match != deleted_inodev)
9091 +           && ((*match)->inode == oldinode)
9092 +           && ((*match)->device == olddevice)) {
9093 +               tmp = *match;
9094 +
9095 +               tmp->inode = newinode;
9096 +               tmp->device = newdevice;
9097 +
9098 +               *match = deleted_inodev;
9099 +
9100 +               insert_inodev_entry(tmp);
9101 +       }
9102 +
9103 +       return;
9104 +}
9105 +
9106 +static __inline__ void
9107 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
9108 +                const struct vfsmount *mnt)
9109 +{
9110 +       struct acl_subject_label *i;
9111 +       struct acl_role_label *role;
9112 +
9113 +       for (role = role_list_head; role; role = role->next) {
9114 +               update_acl_subj_label(matchn->inode, matchn->device,
9115 +                                     dentry->d_inode->i_ino,
9116 +                                     dentry->d_inode->i_sb->s_dev, role);
9117 +
9118 +               for (i = role->hash->first; i; i = i->next) {
9119 +                       if (unlikely((i->mode & GR_NESTED) &&
9120 +                                    (i->inode == dentry->d_inode->i_ino) &&
9121 +                                    (i->device == dentry->d_inode->i_sb->s_dev))) {
9122 +                               i->inode = dentry->d_inode->i_ino;
9123 +                               i->device = dentry->d_inode->i_sb->s_dev;
9124 +                       }
9125 +                       update_acl_obj_label(matchn->inode, matchn->device,
9126 +                                            dentry->d_inode->i_ino,
9127 +                                            dentry->d_inode->i_sb->s_dev, i);
9128 +               }
9129 +       }
9130 +
9131 +       update_inodev_entry(matchn->inode, matchn->device,
9132 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
9133 +
9134 +       return;
9135 +}
9136 +
9137 +void
9138 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
9139 +{
9140 +       struct name_entry *matchn;
9141 +
9142 +       if (unlikely(!(gr_status & GR_READY)))
9143 +               return;
9144 +
9145 +       preempt_disable();
9146 +       matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
9147 +       preempt_enable();
9148 +
9149 +       if (unlikely((unsigned long)matchn)) {
9150 +               write_lock(&gr_inode_lock);
9151 +               do_handle_create(matchn, dentry, mnt);
9152 +               write_unlock(&gr_inode_lock);
9153 +       }
9154 +
9155 +       return;
9156 +}
9157 +
9158 +void
9159 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
9160 +                struct dentry *old_dentry,
9161 +                struct dentry *new_dentry,
9162 +                struct vfsmount *mnt, const __u8 replace)
9163 +{
9164 +       struct name_entry *matchn;
9165 +
9166 +       if (unlikely(!(gr_status & GR_READY)))
9167 +               return;
9168 +
9169 +       preempt_disable();
9170 +       matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
9171 +       preempt_enable();
9172 +
9173 +       /* we wouldn't have to check d_inode if it weren't for
9174 +          NFS silly-renaming
9175 +        */
9176 +
9177 +       write_lock(&gr_inode_lock);
9178 +       if (unlikely(replace && new_dentry->d_inode)) {
9179 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
9180 +                                       new_dentry->d_inode->i_sb->s_dev) &&
9181 +                   (old_dentry->d_inode->i_nlink <= 1)))
9182 +                       do_handle_delete(new_dentry->d_inode->i_ino,
9183 +                                        new_dentry->d_inode->i_sb->s_dev);
9184 +       }
9185 +
9186 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
9187 +                               old_dentry->d_inode->i_sb->s_dev) &&
9188 +           (old_dentry->d_inode->i_nlink <= 1)))
9189 +               do_handle_delete(old_dentry->d_inode->i_ino,
9190 +                                old_dentry->d_inode->i_sb->s_dev);
9191 +
9192 +       if (unlikely((unsigned long)matchn))
9193 +               do_handle_create(matchn, old_dentry, mnt);
9194 +       write_unlock(&gr_inode_lock);
9195 +
9196 +       return;
9197 +}
9198 +
9199 +static int
9200 +lookup_special_role_auth(const char *rolename, unsigned char **salt,
9201 +                        unsigned char **sum)
9202 +{
9203 +       struct acl_role_label *r;
9204 +       struct role_transition *trans;
9205 +       __u16 i;
9206 +       int found = 0;
9207 +
9208 +       /* check transition table */
9209 +
9210 +       for (trans = current->role->transitions; trans; trans = trans->next) {
9211 +               if (!strcmp(rolename, trans->rolename)) {
9212 +                       found = 1;
9213 +                       break;
9214 +               }
9215 +       }
9216 +
9217 +       if (!found)
9218 +               return 0;
9219 +
9220 +       /* handle special roles that do not require authentication */
9221 +
9222 +       for (r = role_list_head; r; r = r->next) {
9223 +               if (!strcmp(rolename, r->rolename)
9224 +                   && (r->roletype & GR_ROLE_NOPW)) {
9225 +                       *salt = NULL;
9226 +                       *sum = NULL;
9227 +                       return 1;
9228 +               }
9229 +       }
9230 +
9231 +       for (i = 0; i < num_sprole_pws; i++) {
9232 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
9233 +                       *salt = acl_special_roles[i]->salt;
9234 +                       *sum = acl_special_roles[i]->sum;
9235 +                       return 1;
9236 +               }
9237 +       }
9238 +
9239 +       return 0;
9240 +}
9241 +
9242 +static void
9243 +assign_special_role(char *rolename)
9244 +{
9245 +       struct acl_object_label *obj;
9246 +       struct acl_role_label *r;
9247 +       struct acl_role_label *assigned = NULL;
9248 +       struct task_struct *tsk;
9249 +       struct file *filp;
9250 +
9251 +       for (r = role_list_head; r; r = r->next)
9252 +               if (!strcmp(rolename, r->rolename) &&
9253 +                   (r->roletype & GR_ROLE_SPECIAL))
9254 +                       assigned = r;
9255 +
9256 +       if (!assigned)
9257 +               return;
9258 +
9259 +       tsk = current->parent;
9260 +       filp = tsk->exec_file;
9261 +
9262 +       if (tsk && filp) {
9263 +               tsk->is_writable = 0;
9264 +
9265 +               acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
9266 +               tsk->acl_sp_role = 1;
9267 +               tsk->acl_role_id = acl_sp_role_value;
9268 +               tsk->role = assigned;
9269 +               tsk->acl =
9270 +                   chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
9271 +
9272 +               /* ignore additional mmap checks for processes that are writable 
9273 +                  by the default ACL */
9274 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9275 +               if (unlikely(obj->mode & GR_WRITE))
9276 +                       tsk->is_writable = 1;
9277 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
9278 +               if (unlikely(obj->mode & GR_WRITE))
9279 +                       tsk->is_writable = 1;
9280 +
9281 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9282 +               printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
9283 +#endif
9284 +       }
9285 +
9286 +       return;
9287 +}
9288 +
9289 +ssize_t
9290 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
9291 +{
9292 +       struct gr_arg *arg;
9293 +       unsigned char *sprole_salt;
9294 +       unsigned char *sprole_sum;
9295 +       int error = sizeof (struct gr_arg);
9296 +       int error2 = 0;
9297 +
9298 +       down(&gr_dev_sem);
9299 +
9300 +       arg = (struct gr_arg *) buf;
9301 +
9302 +       if (count != sizeof (struct gr_arg)) {
9303 +               security_alert_good(GR_DEV_ACL_MSG, count,
9304 +                                   (int) sizeof (struct gr_arg));
9305 +               error = -EINVAL;
9306 +               goto out;
9307 +       }
9308 +
9309 +       if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9310 +           && time_before_eq(gr_auth_expires, get_seconds())) {
9311 +               gr_auth_expires = 0;
9312 +               gr_auth_attempts = 0;
9313 +       }
9314 +
9315 +       if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
9316 +               error = -EFAULT;
9317 +               goto out;
9318 +       }
9319 +
9320 +       if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, get_seconds())) {
9321 +               error = -EBUSY;
9322 +               goto out;
9323 +       }
9324 +
9325 +       /* if non-root trying to do anything other than use a special role,
9326 +          do not attempt authentication, do not count towards authentication
9327 +          locking
9328 +        */
9329 +
9330 +       if (gr_usermode->mode != SPROLE && current->uid) {
9331 +               error = -EPERM;
9332 +               goto out;
9333 +       }
9334 +
9335 +       /* ensure pw and special role name are null terminated */
9336 +
9337 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
9338 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
9339 +
9340 +       /* Okay. 
9341 +        * We have our enough of the argument structure..(we have yet
9342 +        * to copy_from_user the tables themselves) . Copy the tables
9343 +        * only if we need them, i.e. for loading operations. */
9344 +
9345 +       switch (gr_usermode->mode) {
9346 +       case STATUS:
9347 +                       if (gr_status & GR_READY)
9348 +                               error = 1;
9349 +                       else
9350 +                               error = 2;
9351 +                       goto out;
9352 +       case SHUTDOWN:
9353 +               if ((gr_status & GR_READY)
9354 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9355 +                       gr_status &= ~GR_READY;
9356 +                       security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
9357 +                       free_variables();
9358 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
9359 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
9360 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
9361 +               } else if (gr_status & GR_READY) {
9362 +                       security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
9363 +                       error = -EPERM;
9364 +               } else {
9365 +                       security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
9366 +                       error = -EAGAIN;
9367 +               }
9368 +               break;
9369 +       case ENABLE:
9370 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
9371 +                       security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
9372 +               else {
9373 +                       if (gr_status & GR_READY)
9374 +                               error = -EAGAIN;
9375 +                       else
9376 +                               error = error2;
9377 +                       security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
9378 +                                      DEFAULTSECARGS);
9379 +               }
9380 +               break;
9381 +       case RELOAD:
9382 +               if (!(gr_status & GR_READY)) {
9383 +                       security_alert_good(GR_RELOADI_ACL_MSG);
9384 +                       error = -EAGAIN;
9385 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9386 +                       lock_kernel();
9387 +                       gr_status &= ~GR_READY;
9388 +                       free_variables();
9389 +                       if (!(error2 = gracl_init(gr_usermode))) {
9390 +                               unlock_kernel();
9391 +                               security_alert_good(GR_RELOAD_ACL_MSG,
9392 +                                                   GR_VERSION);
9393 +                       } else {
9394 +                               unlock_kernel();
9395 +                               error = error2;
9396 +                               security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
9397 +                                              DEFAULTSECARGS);
9398 +                       }
9399 +               } else {
9400 +                       security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
9401 +                                      DEFAULTSECARGS);
9402 +                       error = -EPERM;
9403 +               }
9404 +               break;
9405 +       case SEGVMOD:
9406 +               if (unlikely(!(gr_status & GR_READY))) {
9407 +                       security_alert_good(GR_SEGVMODI_ACL_MSG,
9408 +                                           DEFAULTSECARGS);
9409 +                       error = -EAGAIN;
9410 +                       break;
9411 +               }
9412 +
9413 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
9414 +                       security_alert_good(GR_SEGVMODS_ACL_MSG,
9415 +                                           DEFAULTSECARGS);
9416 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
9417 +                               struct acl_subject_label *segvacl;
9418 +                               segvacl =
9419 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
9420 +                                                         gr_usermode->segv_device,
9421 +                                                         current->role);
9422 +                               if (segvacl) {
9423 +                                       segvacl->crashes = 0;
9424 +                                       segvacl->expires = 0;
9425 +                               }
9426 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
9427 +                               gr_remove_uid(gr_usermode->segv_uid);
9428 +                       }
9429 +               } else {
9430 +                       security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
9431 +                       error = -EPERM;
9432 +               }
9433 +               break;
9434 +       case SPROLE:
9435 +               if (unlikely(!(gr_status & GR_READY))) {
9436 +                       security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
9437 +                       error = -EAGAIN;
9438 +                       break;
9439 +               }
9440 +
9441 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9442 +                   && time_before_eq(current->role->expires, get_seconds())) {
9443 +                       current->role->expires = 0;
9444 +                       current->role->auth_attempts = 0;
9445 +               }
9446 +
9447 +               if (time_after(current->role->expires, get_seconds())) {
9448 +                       error = -EBUSY;
9449 +                       goto out;
9450 +               }
9451 +
9452 +               if (lookup_special_role_auth
9453 +                   (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
9454 +                   && ((!sprole_salt && !sprole_sum)
9455 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
9456 +                       assign_special_role(gr_usermode->sp_role);
9457 +                       security_alert_good(GR_SPROLES_ACL_MSG,
9458 +                                           (current->parent) ? current->
9459 +                                           parent->role->rolename : "",
9460 +                                           acl_sp_role_value, DEFAULTSECARGS);
9461 +               } else {
9462 +                       security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
9463 +                                      DEFAULTSECARGS);
9464 +                       error = -EPERM;
9465 +                       current->role->auth_attempts++;
9466 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9467 +                               current->role->expires =
9468 +                                   get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
9469 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
9470 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
9471 +                                      gr_usermode->sp_role, DEFAULTSECARGS);
9472 +                       }
9473 +
9474 +                       goto out;
9475 +               }
9476 +               break;
9477 +       case UNSPROLE:
9478 +               if (unlikely(!(gr_status & GR_READY))) {
9479 +                       security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
9480 +                       error = -EAGAIN;
9481 +                       break;
9482 +               }
9483 +
9484 +               if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
9485 +                   && time_before_eq(current->role->expires, get_seconds())) {
9486 +                       current->role->expires = 0;
9487 +                       current->role->auth_attempts = 0;
9488 +               }
9489 +
9490 +               if (time_after(current->role->expires, get_seconds())) {
9491 +                       error = -EBUSY;
9492 +                       goto out;
9493 +               }
9494 +
9495 +               if ((current->role->roletype & GR_ROLE_SPECIAL) && 
9496 +                   lookup_special_role_auth
9497 +                   (current->role->rolename, &sprole_salt, &sprole_sum)
9498 +                   && ((!sprole_salt && !sprole_sum)
9499 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
9500 +                       security_alert_good(GR_UNSPROLES_ACL_MSG,
9501 +                                           (current->parent) ? current->
9502 +                                           parent->role->rolename : "",
9503 +                                           (current->parent) ? current->
9504 +                                           parent->acl_role_id : 0, DEFAULTSECARGS);
9505 +                       gr_set_acls(1);
9506 +                       if (current->parent)
9507 +                               current->parent->acl_sp_role = 0;
9508 +               } else {
9509 +                       security_alert(GR_UNSPROLEF_ACL_MSG, current->role->rolename,
9510 +                                      DEFAULTSECARGS);
9511 +                       error = -EPERM;
9512 +                       current->role->auth_attempts++;
9513 +                       if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9514 +                               current->role->expires =
9515 +                                   get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
9516 +                               security_alert(GR_MAXROLEPW_ACL_MSG,
9517 +                                      CONFIG_GRKERNSEC_ACL_MAXTRIES,
9518 +                                      current->role->rolename, DEFAULTSECARGS);
9519 +                       }
9520 +
9521 +                       goto out;
9522 +               }
9523 +               break;
9524 +       default:
9525 +               security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
9526 +                              DEFAULTSECARGS);
9527 +               error = -EINVAL;
9528 +               break;
9529 +       }
9530 +
9531 +       if (error != -EPERM)
9532 +               goto out;
9533 +
9534 +       gr_auth_attempts++;
9535 +
9536 +       if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
9537 +               security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
9538 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
9539 +       }
9540 +
9541 +      out:
9542 +       up(&gr_dev_sem);
9543 +       return error;
9544 +}
9545 +
9546 +int
9547 +gr_set_acls(const int type)
9548 +{
9549 +       struct acl_object_label *obj;
9550 +       struct task_struct *task, *task2;
9551 +       struct file *filp;
9552 +       unsigned short i;
9553 +
9554 +       read_lock(&tasklist_lock);
9555 +       for_each_process(task2) {
9556 +               task = task2;
9557 +               do {
9558 +               /* check to see if we're called from the exit handler,
9559 +                  if so, only replace ACLs that have inherited the admin
9560 +                  ACL */
9561 +
9562 +               if (type && (task->role != current->role ||
9563 +                            task->acl_role_id != current->acl_role_id))
9564 +                       continue;
9565 +
9566 +               task->acl_role_id = 0;
9567 +
9568 +               if ((filp = task->exec_file)) {
9569 +                       do_set_role_label(task, task->uid, task->gid);
9570 +
9571 +                       task->acl =
9572 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
9573 +                                          task->role);
9574 +                       if (task->acl) {
9575 +                               struct acl_subject_label *curr;
9576 +                               curr = task->acl;
9577 +
9578 +                               task->is_writable = 0;
9579 +                               /* ignore additional mmap checks for processes that are writable 
9580 +                                  by the default ACL */
9581 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9582 +                               if (unlikely(obj->mode & GR_WRITE))
9583 +                                       task->is_writable = 1;
9584 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
9585 +                               if (unlikely(obj->mode & GR_WRITE))
9586 +                                       task->is_writable = 1;
9587 +
9588 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
9589 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
9590 +#endif
9591 +                               if (!(curr->mode & GR_LEARN))
9592 +                                       for (i = 0; i < RLIM_NLIMITS; i++) {
9593 +                                               if (!(curr->resmask & (1 << i)))
9594 +                                                       continue;
9595 +
9596 +                                               task->rlim[i].rlim_cur =
9597 +                                                   curr->res[i].rlim_cur;
9598 +                                               task->rlim[i].rlim_max =
9599 +                                                   curr->res[i].rlim_max;
9600 +                                       }
9601 +                       } else {
9602 +                               read_unlock(&tasklist_lock);
9603 +                               security_alert_good(GR_DEFACL_MSG, task->comm,
9604 +                                                   task->pid);
9605 +                               return 1;
9606 +                       }
9607 +               } else {
9608 +                       // it's a kernel process
9609 +                       task->role = kernel_role;
9610 +                       task->acl = kernel_role->root_label;
9611 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
9612 +                       task->acl->mode &= ~GR_FIND;
9613 +#endif
9614 +               }
9615 +       } while ((task = next_thread(task)) != task2);
9616 +       }
9617 +       read_unlock(&tasklist_lock);
9618 +       return 0;
9619 +}
9620 +
9621 +EXPORT_SYMBOL(gr_learn_resource);
9622 +
9623 +void
9624 +gr_learn_resource(const struct task_struct *task,
9625 +                 const int res, const unsigned long wanted, const int gt)
9626 +{
9627 +       struct acl_subject_label *acl;
9628 +
9629 +       if (unlikely((gr_status & GR_READY) &&
9630 +                    task->acl && (task->acl->mode & GR_LEARN)))
9631 +               goto skip_reslog;
9632 +
9633 +#ifdef CONFIG_GRKERNSEC_RESLOG
9634 +       gr_log_resource(task, res, wanted, gt);
9635 +#endif
9636 +      skip_reslog:
9637 +
9638 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
9639 +               return;
9640 +
9641 +       acl = task->acl;
9642 +
9643 +       if (likely(!acl || !(acl->mode & GR_LEARN) ||
9644 +                  !(acl->resmask & (1 << (unsigned short) res))))
9645 +               return;
9646 +
9647 +       if (wanted >= acl->res[res].rlim_cur) {
9648 +               unsigned long res_add;
9649 +
9650 +               res_add = wanted;
9651 +               switch (res) {
9652 +               case RLIMIT_CPU:
9653 +                       res_add += GR_RLIM_CPU_BUMP;
9654 +                       break;
9655 +               case RLIMIT_FSIZE:
9656 +                       res_add += GR_RLIM_FSIZE_BUMP;
9657 +                       break;
9658 +               case RLIMIT_DATA:
9659 +                       res_add += GR_RLIM_DATA_BUMP;
9660 +                       break;
9661 +               case RLIMIT_STACK:
9662 +                       res_add += GR_RLIM_STACK_BUMP;
9663 +                       break;
9664 +               case RLIMIT_CORE:
9665 +                       res_add += GR_RLIM_CORE_BUMP;
9666 +                       break;
9667 +               case RLIMIT_RSS:
9668 +                       res_add += GR_RLIM_RSS_BUMP;
9669 +                       break;
9670 +               case RLIMIT_NPROC:
9671 +                       res_add += GR_RLIM_NPROC_BUMP;
9672 +                       break;
9673 +               case RLIMIT_NOFILE:
9674 +                       res_add += GR_RLIM_NOFILE_BUMP;
9675 +                       break;
9676 +               case RLIMIT_MEMLOCK:
9677 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
9678 +                       break;
9679 +               case RLIMIT_AS:
9680 +                       res_add += GR_RLIM_AS_BUMP;
9681 +                       break;
9682 +               case RLIMIT_LOCKS:
9683 +                       res_add += GR_RLIM_LOCKS_BUMP;
9684 +                       break;
9685 +               }
9686 +
9687 +               acl->res[res].rlim_cur = res_add;
9688 +
9689 +               if (wanted > acl->res[res].rlim_max)
9690 +                       acl->res[res].rlim_max = res_add;
9691 +
9692 +               security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
9693 +                              current->role->roletype, acl->filename,
9694 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
9695 +                              "", (unsigned long) res);
9696 +       }
9697 +
9698 +       return;
9699 +}
9700 +
9701 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
9702 +void
9703 +pax_set_flags(struct linux_binprm *bprm)
9704 +{
9705 +       struct task_struct *task = current;
9706 +        struct acl_subject_label *proc;
9707 +
9708 +        if (unlikely(!(gr_status & GR_READY)))
9709 +                return;
9710 +
9711 +        proc = task->acl;
9712 +
9713 +        if (proc->mode & GR_PAXPAGE)
9714 +                task->flags &= ~PF_PAX_PAGEEXEC;
9715 +        if (proc->mode & GR_PAXSEGM)
9716 +                task->flags &= ~PF_PAX_SEGMEXEC;
9717 +        if (proc->mode & GR_PAXGCC)
9718 +                task->flags |= PF_PAX_EMUTRAMP;
9719 +        if (proc->mode & GR_PAXMPROTECT)
9720 +                task->flags &= ~PF_PAX_MPROTECT;
9721 +        if (proc->mode & GR_PAXRANDMMAP)
9722 +                task->flags &= ~PF_PAX_RANDMMAP;
9723 +        if (proc->mode & GR_PAXRANDEXEC)
9724 +                task->flags |= PF_PAX_RANDEXEC;
9725 +
9726 +        return;
9727 +}
9728 +#endif
9729 +
9730 +#ifdef CONFIG_SYSCTL
9731 +extern struct proc_dir_entry *proc_sys_root;
9732 +
9733 +
9734 +/* the following function is called under the BKL */
9735 +
9736 +__u32
9737 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
9738 +                const void *newval)
9739 +{
9740 +       struct proc_dir_entry *tmp;
9741 +       struct nameidata nd;
9742 +       const char *proc_sys = "/proc/sys";
9743 +       char *path;
9744 +       struct acl_object_label *obj;
9745 +       unsigned short len = 0, pos = 0, depth = 0, i;
9746 +       __u32 err = 0;
9747 +       __u32 mode = 0;
9748 +
9749 +       if (unlikely(!(gr_status & GR_READY)))
9750 +               return 1;
9751 +
9752 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
9753 +
9754 +       if (oldval)
9755 +               mode |= GR_READ;
9756 +       if (newval)
9757 +               mode |= GR_WRITE;
9758 +
9759 +       /* convert the requested sysctl entry into a pathname */
9760 +
9761 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
9762 +               len += strlen(tmp->name);
9763 +               len++;
9764 +               depth++;
9765 +       }
9766 +
9767 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
9768 +               return 0;       /* deny */
9769 +
9770 +       memset(path, 0, PAGE_SIZE);
9771 +
9772 +       memcpy(path, proc_sys, strlen(proc_sys));
9773 +
9774 +       pos += strlen(proc_sys);
9775 +
9776 +       for (; depth > 0; depth--) {
9777 +               path[pos] = '/';
9778 +               pos++;
9779 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
9780 +                    tmp = tmp->parent) {
9781 +                       if (depth == i) {
9782 +                               memcpy(path + pos, tmp->name,
9783 +                                      strlen(tmp->name));
9784 +                               pos += strlen(tmp->name);
9785 +                       }
9786 +                       i++;
9787 +               }
9788 +       }
9789 +
9790 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
9791 +
9792 +       if (err)
9793 +               goto out;
9794 +
9795 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
9796 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
9797 +
9798 +       if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
9799 +               __u32 new_mode = mode;
9800 +
9801 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
9802 +
9803 +               err = new_mode;
9804 +               gr_log_learn(current->role, current->uid, current->gid,
9805 +                            current, path, new_mode);
9806 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
9807 +               security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
9808 +                              (mode & GR_READ) ? " reading" : "",
9809 +                              (mode & GR_WRITE) ? " writing" : "",
9810 +                              DEFAULTSECARGS);
9811 +               err = 0;
9812 +       } else if ((err & mode) != mode) {
9813 +               err = 0;
9814 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
9815 +               security_audit(GR_SYSCTL_ACL_MSG, "successful",
9816 +                              path, (mode & GR_READ) ? " reading" : "",
9817 +                              (mode & GR_WRITE) ? " writing" : "",
9818 +                              DEFAULTSECARGS);
9819 +       }
9820 +
9821 +       path_release(&nd);
9822 +
9823 +      out:
9824 +       return err;
9825 +}
9826 +#endif
9827 +
9828 +int
9829 +gr_handle_proc_ptrace(struct task_struct *task)
9830 +{
9831 +       struct file *filp;
9832 +       struct task_struct *tmp = task;
9833 +       struct task_struct *curtemp = current;
9834 +       __u32 retmode;
9835 +
9836 +       if (unlikely(!(gr_status & GR_READY)))
9837 +               return 0;
9838 +
9839 +       filp = task->exec_file;
9840 +
9841 +       read_lock(&tasklist_lock);
9842 +       while (tmp->pid > 0) {
9843 +               if (tmp == curtemp)
9844 +                       break;
9845 +               tmp = tmp->parent;
9846 +       }
9847 +       read_unlock(&tasklist_lock);
9848 +
9849 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))
9850 +               return 1;
9851 +
9852 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
9853 +
9854 +       if (retmode & GR_NOPTRACE)
9855 +               return 1;
9856 +
9857 +       if (!(current->acl->mode & GR_OVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
9858 +           && (current->acl != task->acl || (current->acl != current->role->root_label
9859 +           && current->pid != task->pid)))
9860 +               return 1;
9861 +
9862 +       return 0;
9863 +}
9864 +
9865 +int
9866 +gr_handle_ptrace(struct task_struct *task, const long request)
9867 +{
9868 +       struct file *filp;
9869 +       struct task_struct *tmp = task;
9870 +       struct task_struct *curtemp = current;
9871 +       __u32 retmode;
9872 +
9873 +       if (unlikely(!(gr_status & GR_READY)))
9874 +               return 0;
9875 +
9876 +       filp = task->exec_file;
9877 +
9878 +       if (task->acl->mode & GR_NOPTRACE) {
9879 +               security_alert(GR_PTRACE_ACL_MSG, filp ?
9880 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt)
9881 +                              : "(none)", task->comm, task->pid,
9882 +                              DEFAULTSECARGS);
9883 +               return 1;
9884 +       }
9885 +
9886 +       read_lock(&tasklist_lock);
9887 +       while (tmp->pid > 0) {
9888 +               if (tmp == curtemp)
9889 +                       break;
9890 +               tmp = tmp->parent;
9891 +       }
9892 +       read_unlock(&tasklist_lock);
9893 +
9894 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
9895 +               security_alert(GR_PTRACE_ACL_MSG, filp ?
9896 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt)
9897 +                              : "(none)", task->comm, task->pid,
9898 +                              DEFAULTSECARGS);
9899 +               return 1;
9900 +       }
9901 +
9902 +       if (unlikely(!filp))
9903 +               return 0;
9904 +
9905 +       retmode = gr_search_file(filp->f_dentry, GR_PTRACERD | GR_NOPTRACE, filp->f_vfsmnt);
9906 +
9907 +       if (retmode & GR_NOPTRACE) {
9908 +               security_alert(GR_PTRACE_ACL_MSG, gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
9909 +                              task->comm, task->pid, DEFAULTSECARGS);
9910 +               return 1;
9911 +       }
9912 +               
9913 +       if (retmode & GR_PTRACERD) {
9914 +               switch (request) {
9915 +               case PTRACE_POKETEXT:
9916 +               case PTRACE_POKEDATA:
9917 +               case PTRACE_POKEUSR:
9918 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
9919 +               case PTRACE_SETREGS:
9920 +               case PTRACE_SETFPREGS:
9921 +#endif
9922 +#ifdef CONFIG_X86
9923 +               case PTRACE_SETFPXREGS:
9924 +#endif
9925 +#ifdef CONFIG_ALTIVEC
9926 +               case PTRACE_SETVRREGS:
9927 +#endif
9928 +                       return 1;
9929 +               default:
9930 +                       return 0;
9931 +               }
9932 +       } else if (!(current->acl->mode & GR_OVERRIDE) &&
9933 +                  !(current->role->roletype & GR_ROLE_GOD)
9934 +                  && (current->acl != task->acl
9935 +                      || (current->acl != current->role->root_label
9936 +                          && current->pid != task->pid))) {
9937 +               security_alert(GR_PTRACE_ACL_MSG,
9938 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
9939 +                              task->comm, task->pid, DEFAULTSECARGS);
9940 +               return 1;
9941 +       }
9942 +
9943 +       return 0;
9944 +}
9945 +
9946 +int
9947 +gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
9948 +{
9949 +       __u32 retmode;
9950 +       struct acl_subject_label *subj;
9951 +
9952 +       if (unlikely(!(gr_status & GR_READY)))
9953 +               return 0;
9954 +
9955 +       if (unlikely
9956 +           ((current->ptrace & PT_PTRACED)
9957 +            && !(current->acl->mode & GR_OVERRIDE)))
9958 +               retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
9959 +       else
9960 +               return 0;
9961 +
9962 +       subj = chk_subj_label(dentry, mnt, current->role);
9963 +
9964 +       if (!(retmode & GR_PTRACERD) &&
9965 +           !(current->role->roletype & GR_ROLE_GOD) &&
9966 +           (current->acl != subj)) {
9967 +               security_alert(GR_PTRACE_EXEC_ACL_MSG,
9968 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
9969 +               return 1;
9970 +       }
9971 +
9972 +       return 0;
9973 +}
9974 +
9975 +int
9976 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
9977 +{
9978 +       struct acl_object_label *obj, *obj2;
9979 +
9980 +       if (unlikely(!(gr_status & GR_READY) ||
9981 +                    (current->acl->mode & GR_OVERRIDE) || !filp ||
9982 +                    !(prot & PROT_EXEC)))
9983 +               return 0;
9984 +
9985 +       if (unlikely(current->is_writable))
9986 +               return 0;
9987 +
9988 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
9989 +       obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
9990 +                            current->role->root_label);
9991 +       if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
9992 +               security_alert(GR_WRITLIB_ACL_MSG,
9993 +                              gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
9994 +                              DEFAULTSECARGS);
9995 +               return 1;
9996 +       }
9997 +
9998 +       return 0;
9999 +}
10000 +
10001 +int
10002 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
10003 +{
10004 +       __u32 mode;
10005 +
10006 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10007 +               return 1;
10008 +
10009 +       mode =
10010 +           gr_search_file(file->f_dentry,
10011 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10012 +                          file->f_vfsmnt);
10013 +
10014 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10015 +               security_alert(GR_MMAP_ACL_MSG, "denied",
10016 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10017 +                              DEFAULTSECARGS);
10018 +               return 0;
10019 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10020 +               return 0;
10021 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10022 +               security_audit(GR_MMAP_ACL_MSG, "successful",
10023 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10024 +                              DEFAULTSECARGS);
10025 +               return 1;
10026 +       }
10027 +
10028 +       return 1;
10029 +}
10030 +
10031 +int
10032 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
10033 +{
10034 +       __u32 mode;
10035 +
10036 +       if (unlikely(!file || !(prot & PROT_EXEC)))
10037 +               return 1;
10038 +
10039 +       mode =
10040 +           gr_search_file(file->f_dentry,
10041 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
10042 +                          file->f_vfsmnt);
10043 +
10044 +       if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
10045 +               security_alert(GR_MPROTECT_ACL_MSG, "denied",
10046 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10047 +                              DEFAULTSECARGS);
10048 +               return 0;
10049 +       } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
10050 +               return 0;
10051 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
10052 +               security_audit(GR_MPROTECT_ACL_MSG, "successful",
10053 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
10054 +                              DEFAULTSECARGS);
10055 +               return 1;
10056 +       }
10057 +
10058 +       return 1;
10059 +}
10060 +
10061 +void
10062 +gr_acl_handle_psacct(struct task_struct *task, const long code)
10063 +{
10064 +       u64 runtime64;
10065 +       unsigned long runtime;
10066 +       unsigned long cputime;
10067 +       unsigned int wday, cday;
10068 +       __u8 whr, chr;
10069 +       __u8 wmin, cmin;
10070 +       __u8 wsec, csec;
10071 +       char cur_tty[64] = { 0 };
10072 +       char parent_tty[64] = { 0 };
10073 +
10074 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
10075 +                    !(task->acl->mode & GR_PROCACCT)))
10076 +               return;
10077 +
10078 +       runtime64 = get_jiffies_64() - task->start_time;
10079 +       do_div(runtime64, HZ);
10080 +       runtime = (unsigned long)runtime64;
10081 +       wday = runtime / (3600 * 24);
10082 +       runtime -= wday * (3600 * 24);
10083 +       whr = runtime / 3600;
10084 +       runtime -= whr * 3600;
10085 +       wmin = runtime / 60;
10086 +       runtime -= wmin * 60;
10087 +       wsec = runtime;
10088 +
10089 +       cputime = (task->utime + task->stime) / HZ;
10090 +       cday = cputime / (3600 * 24);
10091 +       cputime -= cday * (3600 * 24);
10092 +       chr = cputime / 3600;
10093 +       cputime -= chr * 3600;
10094 +       cmin = cputime / 60;
10095 +       cputime -= cmin * 60;
10096 +       csec = cputime;
10097 +
10098 +       security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
10099 +                      task->pid, NIPQUAD(task->curr_ip), tty_name(task->signal->tty,
10100 +                                                                  cur_tty),
10101 +                      task->uid, task->euid, task->gid, task->egid, wday, whr,
10102 +                      wmin, wsec, cday, chr, cmin, csec,
10103 +                      (task->flags & PF_SIGNALED) ? "killed by signal" : "exited",
10104 +                      code, gr_parent_task_fullpath(task), 
10105 +                      task->parent->comm, task->parent->pid,
10106 +                      NIPQUAD(task->parent->curr_ip),
10107 +                      tty_name(task->parent->signal->tty, parent_tty),
10108 +                      task->parent->uid, task->parent->euid, task->parent->gid,
10109 +                      task->parent->egid);
10110 +
10111 +       return;
10112 +}
10113 +
10114 +EXPORT_SYMBOL(gr_set_kernel_label);
10115 +
10116 +void gr_set_kernel_label(struct task_struct *task)
10117 +{
10118 +       if (gr_status & GR_READY) {
10119 +               task->role = kernel_role;
10120 +               task->acl = kernel_role->root_label;
10121 +       }
10122 +       return;
10123 +}
10124 diff -uNr linux-2.6.6/grsecurity/gracl_cap.c linux-2.6.6.fixed/grsecurity/gracl_cap.c
10125 --- linux-2.6.6/grsecurity/gracl_cap.c  1970-01-01 01:00:00.000000000 +0100
10126 +++ linux-2.6.6.fixed/grsecurity/gracl_cap.c    2004-05-11 10:55:56.000000000 +0200
10127 @@ -0,0 +1,115 @@
10128 +/* capability handling routines, (c) Brad Spengler 2002,2003 */
10129 +
10130 +#include <linux/kernel.h>
10131 +#include <linux/module.h>
10132 +#include <linux/sched.h>
10133 +#include <linux/capability.h>
10134 +#include <linux/gracl.h>
10135 +#include <linux/grsecurity.h>
10136 +#include <linux/grinternal.h>
10137 +
10138 +static const char *captab_log[29] = {
10139 +       "CAP_CHOWN",
10140 +       "CAP_DAC_OVERRIDE",
10141 +       "CAP_DAC_READ_SEARCH",
10142 +       "CAP_FOWNER",
10143 +       "CAP_FSETID",
10144 +       "CAP_KILL",
10145 +       "CAP_SETGID",
10146 +       "CAP_SETUID",
10147 +       "CAP_SETPCAP",
10148 +       "CAP_LINUX_IMMUTABLE",
10149 +       "CAP_NET_BIND_SERVICE",
10150 +       "CAP_NET_BROADCAST",
10151 +       "CAP_NET_ADMIN",
10152 +       "CAP_NET_RAW",
10153 +       "CAP_IPC_LOCK",
10154 +       "CAP_IPC_OWNER",
10155 +       "CAP_SYS_MODULE",
10156 +       "CAP_SYS_RAWIO",
10157 +       "CAP_SYS_CHROOT",
10158 +       "CAP_SYS_PTRACE",
10159 +       "CAP_SYS_PACCT",
10160 +       "CAP_SYS_ADMIN",
10161 +       "CAP_SYS_BOOT",
10162 +       "CAP_SYS_NICE",
10163 +       "CAP_SYS_RESOURCE",
10164 +       "CAP_SYS_TIME",
10165 +       "CAP_SYS_TTY_CONFIG",
10166 +       "CAP_MKNOD",
10167 +       "CAP_LEASE"
10168 +};
10169 +
10170 +EXPORT_SYMBOL(gr_task_is_capable);
10171 +
10172 +int
10173 +gr_task_is_capable(struct task_struct *task, const int cap)
10174 +{
10175 +       struct acl_subject_label *curracl;
10176 +       __u32 cap_drop = 0, cap_mask = 0;
10177 +
10178 +       if (!gr_acl_is_enabled())
10179 +               return 1;
10180 +
10181 +       curracl = task->acl;
10182 +
10183 +       cap_drop = curracl->cap_lower;
10184 +       cap_mask = curracl->cap_mask;
10185 +
10186 +       while ((curracl = curracl->parent_subject)) {
10187 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
10188 +               cap_mask |= curracl->cap_mask;
10189 +       }
10190 +
10191 +       if (!cap_raised(cap_drop, cap))
10192 +               return 1;
10193 +
10194 +       curracl = task->acl;
10195 +
10196 +       if ((curracl->mode & GR_LEARN)
10197 +           && cap_raised(task->cap_effective, cap)) {
10198 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
10199 +                              task->role->roletype, task->uid,
10200 +                              task->gid, task->exec_file ?
10201 +                              gr_to_filename(task->exec_file->f_dentry,
10202 +                              task->exec_file->f_vfsmnt) : curracl->filename,
10203 +                              curracl->filename, 0UL,
10204 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->curr_ip));
10205 +               return 1;
10206 +       }
10207 +
10208 +       if ((cap >= 0) && (cap < 29) && cap_raised(task->cap_effective, cap))
10209 +               security_alert(GR_CAP_ACL_MSG, captab_log[cap],
10210 +                               gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid,
10211 +                               task->gid, task->egid, gr_parent_task_fullpath(task),
10212 +                               task->parent->comm, task->parent->pid, task->parent->uid,
10213 +                               task->parent->euid, task->parent->gid, task->parent->egid);
10214 +
10215 +       return 0;
10216 +}
10217 +
10218 +int
10219 +gr_is_capable_nolog(const int cap)
10220 +{
10221 +       struct acl_subject_label *curracl;
10222 +       __u32 cap_drop = 0, cap_mask = 0;
10223 +
10224 +       if (!gr_acl_is_enabled())
10225 +               return 1;
10226 +
10227 +       curracl = current->acl;
10228 +
10229 +       cap_drop = curracl->cap_lower;
10230 +       cap_mask = curracl->cap_mask;
10231 +
10232 +       while ((curracl = curracl->parent_subject)) {
10233 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
10234 +               cap_mask |= curracl->cap_mask;
10235 +       }
10236 +
10237 +       if (!cap_raised(cap_drop, cap))
10238 +               return 1;
10239 +
10240 +       return 0;
10241 +}
10242 +
10243 diff -uNr linux-2.6.6/grsecurity/gracl_fs.c linux-2.6.6.fixed/grsecurity/gracl_fs.c
10244 --- linux-2.6.6/grsecurity/gracl_fs.c   1970-01-01 01:00:00.000000000 +0100
10245 +++ linux-2.6.6.fixed/grsecurity/gracl_fs.c     2004-05-11 10:55:56.000000000 +0200
10246 @@ -0,0 +1,460 @@
10247 +#include <linux/kernel.h>
10248 +#include <linux/sched.h>
10249 +#include <linux/types.h>
10250 +#include <linux/fs.h>
10251 +#include <linux/file.h>
10252 +#include <linux/grsecurity.h>
10253 +#include <linux/grinternal.h>
10254 +#include <linux/gracl.h>
10255 +
10256 +__u32
10257 +gr_acl_handle_hidden_file(const struct dentry * dentry,
10258 +                         const struct vfsmount * mnt)
10259 +{
10260 +       __u32 mode;
10261 +
10262 +       if (unlikely(!dentry->d_inode))
10263 +               return GR_FIND;
10264 +
10265 +       mode =
10266 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
10267 +
10268 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
10269 +               security_audit(GR_HIDDEN_ACL_MSG, "successful",
10270 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
10271 +               return mode;
10272 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
10273 +               security_alert(GR_HIDDEN_ACL_MSG, "denied",
10274 +                              gr_to_filename(dentry, mnt),
10275 +                              DEFAULTSECARGS);
10276 +               return 0;
10277 +       } else if (unlikely(!(mode & GR_FIND)))
10278 +               return 0;
10279 +
10280 +       return GR_FIND;
10281 +}
10282 +
10283 +__u32
10284 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
10285 +                  const int fmode)
10286 +{
10287 +       __u32 reqmode = GR_FIND;
10288 +       __u32 mode;
10289 +
10290 +       if (unlikely(!dentry->d_inode))
10291 +               return reqmode;
10292 +
10293 +       if (unlikely(fmode & O_APPEND))
10294 +               reqmode |= GR_APPEND;
10295 +       else if (unlikely(fmode & FMODE_WRITE))
10296 +               reqmode |= GR_WRITE;
10297 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
10298 +               reqmode |= GR_READ;
10299 +
10300 +       mode =
10301 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
10302 +                          mnt);
10303 +
10304 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10305 +               security_audit(GR_OPEN_ACL_MSG, "successful",
10306 +                              gr_to_filename(dentry, mnt),
10307 +                              reqmode & GR_READ ? " reading" : "",
10308 +                              reqmode & GR_WRITE ? " writing" :
10309 +                              reqmode & GR_APPEND ? " appending" : "",
10310 +                              DEFAULTSECARGS);
10311 +               return reqmode;
10312 +       } else
10313 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10314 +       {
10315 +               security_alert(GR_OPEN_ACL_MSG, "denied",
10316 +                              gr_to_filename(dentry, mnt),
10317 +                              reqmode & GR_READ ? " reading" : "",
10318 +                              reqmode & GR_WRITE ? " writing" : reqmode &
10319 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
10320 +               return 0;
10321 +       } else if (unlikely((mode & reqmode) != reqmode))
10322 +               return 0;
10323 +
10324 +       return reqmode;
10325 +}
10326 +
10327 +__u32
10328 +gr_acl_handle_creat(const struct dentry * dentry,
10329 +                   const struct dentry * p_dentry,
10330 +                   const struct vfsmount * p_mnt, const int fmode,
10331 +                   const int imode)
10332 +{
10333 +       __u32 reqmode = GR_WRITE | GR_CREATE;
10334 +       __u32 mode;
10335 +
10336 +       if (unlikely(fmode & O_APPEND))
10337 +               reqmode |= GR_APPEND;
10338 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
10339 +               reqmode |= GR_READ;
10340 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
10341 +               reqmode |= GR_SETID;
10342 +
10343 +       mode =
10344 +           gr_check_create(dentry, p_dentry, p_mnt,
10345 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
10346 +
10347 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10348 +               security_audit(GR_CREATE_ACL_MSG, "successful",
10349 +                              gr_to_filename(dentry, p_mnt),
10350 +                              reqmode & GR_READ ? " reading" : "",
10351 +                              reqmode & GR_WRITE ? " writing" :
10352 +                              reqmode & GR_APPEND ? " appending" : "",
10353 +                              DEFAULTSECARGS);
10354 +               return reqmode;
10355 +       } else
10356 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10357 +       {
10358 +               security_alert(GR_CREATE_ACL_MSG, "denied",
10359 +                              gr_to_filename(dentry, p_mnt),
10360 +                              reqmode & GR_READ ? " reading" : "",
10361 +                              reqmode & GR_WRITE ? " writing" : reqmode &
10362 +                              GR_APPEND ? " appending" : "", DEFAULTSECARGS);
10363 +               return 0;
10364 +       } else if (unlikely((mode & reqmode) != reqmode))
10365 +               return 0;
10366 +
10367 +       return reqmode;
10368 +}
10369 +
10370 +__u32
10371 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
10372 +                    const int fmode)
10373 +{
10374 +       __u32 mode, reqmode = GR_FIND;
10375 +
10376 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
10377 +               reqmode |= GR_EXEC;
10378 +       if (fmode & S_IWOTH)
10379 +               reqmode |= GR_WRITE;
10380 +       if (fmode & S_IROTH)
10381 +               reqmode |= GR_READ;
10382 +
10383 +       mode =
10384 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
10385 +                          mnt);
10386 +
10387 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
10388 +               security_audit(GR_ACCESS_ACL_MSG, "successful",
10389 +                              gr_to_filename(dentry, mnt),
10390 +                              reqmode & GR_READ ? " reading" : "",
10391 +                              reqmode & GR_WRITE ? " writing" : "",
10392 +                              reqmode & GR_EXEC ? " executing" : "",
10393 +                              DEFAULTSECARGS);
10394 +               return reqmode;
10395 +       } else
10396 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
10397 +       {
10398 +               security_alert(GR_ACCESS_ACL_MSG, "denied",
10399 +                              gr_to_filename(dentry, mnt),
10400 +                              reqmode & GR_READ ? " reading" : "",
10401 +                              reqmode & GR_WRITE ? " writing" : "",
10402 +                              reqmode & GR_EXEC ? " executing" : "",
10403 +                              DEFAULTSECARGS);
10404 +               return 0;
10405 +       } else if (unlikely((mode & reqmode) != reqmode))
10406 +               return 0;
10407 +
10408 +       return reqmode;
10409 +}
10410 +
10411 +#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
10412 +{ \
10413 +       __u32 mode; \
10414 +       \
10415 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
10416 +       \
10417 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
10418 +               security_audit(fmt, "successful", \
10419 +                               gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
10420 +               return mode; \
10421 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
10422 +               security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
10423 +                               DEFAULTSECARGS); \
10424 +               return 0; \
10425 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
10426 +               return 0; \
10427 +       \
10428 +       return (reqmode); \
10429 +}
10430 +
10431 +__u32
10432 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
10433 +{
10434 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
10435 +}
10436 +
10437 +__u32
10438 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
10439 +{
10440 +       generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
10441 +}
10442 +
10443 +__u32
10444 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
10445 +{
10446 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
10447 +}
10448 +
10449 +__u32
10450 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
10451 +{
10452 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
10453 +}
10454 +
10455 +__u32
10456 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
10457 +                    mode_t mode)
10458 +{
10459 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
10460 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
10461 +                                  GR_FCHMOD_ACL_MSG);
10462 +       } else {
10463 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
10464 +       }
10465 +}
10466 +
10467 +__u32
10468 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
10469 +                   mode_t mode)
10470 +{
10471 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
10472 +               generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
10473 +                                  GR_CHMOD_ACL_MSG);
10474 +       } else {
10475 +               generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
10476 +       }
10477 +}
10478 +
10479 +__u32
10480 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
10481 +{
10482 +       generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
10483 +}
10484 +
10485 +__u32
10486 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
10487 +{
10488 +       generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
10489 +}
10490 +
10491 +__u32
10492 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
10493 +{
10494 +       generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
10495 +                          GR_UNIXCONNECT_ACL_MSG);
10496 +}
10497 +
10498 +__u32
10499 +gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
10500 +                     const ino_t ino)
10501 +{
10502 +       if (likely((unsigned long)(dentry->d_inode))) {
10503 +               struct dentry d = *dentry;
10504 +               struct inode inode = *(dentry->d_inode);
10505 +
10506 +               inode.i_ino = ino;
10507 +               d.d_inode = &inode;
10508 +
10509 +               if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
10510 +                       return 0;
10511 +       }
10512 +
10513 +       return 1;
10514 +}
10515 +
10516 +__u32
10517 +gr_acl_handle_link(const struct dentry * new_dentry,
10518 +                  const struct dentry * parent_dentry,
10519 +                  const struct vfsmount * parent_mnt,
10520 +                  const struct dentry * old_dentry,
10521 +                  const struct vfsmount * old_mnt, const char *to)
10522 +{
10523 +       __u32 needmode = GR_WRITE | GR_CREATE;
10524 +       __u32 mode;
10525 +
10526 +       mode =
10527 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
10528 +                         old_mnt);
10529 +
10530 +       if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
10531 +               security_audit(GR_LINK_ACL_MSG, "successful",
10532 +                              gr_to_filename(old_dentry, old_mnt), to,
10533 +                              DEFAULTSECARGS);
10534 +               return mode;
10535 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
10536 +               security_alert(GR_LINK_ACL_MSG, "denied",
10537 +                              gr_to_filename(old_dentry, old_mnt), to,
10538 +                              DEFAULTSECARGS);
10539 +               return 0;
10540 +       } else if (unlikely((mode & needmode) != needmode))
10541 +               return 0;
10542 +
10543 +       return (GR_WRITE | GR_CREATE);
10544 +}
10545 +
10546 +__u32
10547 +gr_acl_handle_symlink(const struct dentry * new_dentry,
10548 +                     const struct dentry * parent_dentry,
10549 +                     const struct vfsmount * parent_mnt, const char *from)
10550 +{
10551 +       __u32 needmode = GR_WRITE | GR_CREATE;
10552 +       __u32 mode;
10553 +
10554 +       mode =
10555 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
10556 +                           GR_CREATE | GR_AUDIT_CREATE |
10557 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
10558 +
10559 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
10560 +               security_audit(GR_SYMLINK_ACL_MSG, "successful",
10561 +                              from, gr_to_filename(new_dentry, parent_mnt),
10562 +                              DEFAULTSECARGS);
10563 +               return mode;
10564 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
10565 +               security_alert(GR_SYMLINK_ACL_MSG, "denied",
10566 +                              from, gr_to_filename(new_dentry, parent_mnt),
10567 +                              DEFAULTSECARGS);
10568 +               return 0;
10569 +       } else if (unlikely((mode & needmode) != needmode))
10570 +               return 0;
10571 +
10572 +       return (GR_WRITE | GR_CREATE);
10573 +}
10574 +
10575 +#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
10576 +{ \
10577 +       __u32 mode; \
10578 +       \
10579 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
10580 +       \
10581 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
10582 +               security_audit(fmt, "successful", \
10583 +                               gr_to_filename(new_dentry, parent_mnt), \
10584 +                               DEFAULTSECARGS); \
10585 +               return mode; \
10586 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
10587 +               security_alert(fmt, "denied", \
10588 +                               gr_to_filename(new_dentry, parent_mnt), \
10589 +                               DEFAULTSECARGS); \
10590 +               return 0; \
10591 +       } else if (unlikely((mode & (reqmode)) != (reqmode))) \
10592 +               return 0; \
10593 +       \
10594 +       return (reqmode); \
10595 +}
10596 +
10597 +__u32
10598 +gr_acl_handle_mknod(const struct dentry * new_dentry,
10599 +                   const struct dentry * parent_dentry,
10600 +                   const struct vfsmount * parent_mnt,
10601 +                   const int mode)
10602 +{
10603 +       __u32 reqmode = GR_WRITE | GR_CREATE;
10604 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
10605 +               reqmode |= GR_SETID;
10606 +
10607 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
10608 +                                 reqmode, GR_MKNOD_ACL_MSG);
10609 +}
10610 +
10611 +__u32
10612 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
10613 +                   const struct dentry *parent_dentry,
10614 +                   const struct vfsmount *parent_mnt)
10615 +{
10616 +       generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
10617 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
10618 +}
10619 +
10620 +#define RENAME_CHECK_SUCCESS(old, new) \
10621 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
10622 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
10623 +
10624 +int
10625 +gr_acl_handle_rename(struct dentry *new_dentry,
10626 +                    struct dentry *parent_dentry,
10627 +                    const struct vfsmount *parent_mnt,
10628 +                    struct dentry *old_dentry,
10629 +                    struct inode *old_parent_inode,
10630 +                    struct vfsmount *old_mnt, const char *newname)
10631 +{
10632 +       __u32 comp1, comp2;
10633 +       int error = 0;
10634 +
10635 +       if (unlikely(!gr_acl_is_enabled()))
10636 +               return 0;
10637 +
10638 +       if (!new_dentry->d_inode) {
10639 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
10640 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
10641 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
10642 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
10643 +                                      GR_DELETE | GR_AUDIT_DELETE |
10644 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
10645 +                                      GR_SUPPRESS, old_mnt);
10646 +       } else {
10647 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
10648 +                                      GR_CREATE | GR_DELETE |
10649 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
10650 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
10651 +                                      GR_SUPPRESS, parent_mnt);
10652 +               comp2 =
10653 +                   gr_search_file(old_dentry,
10654 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
10655 +                                  GR_DELETE | GR_AUDIT_DELETE |
10656 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
10657 +       }
10658 +
10659 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
10660 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
10661 +               security_audit(GR_RENAME_ACL_MSG, "successful",
10662 +                              gr_to_filename(old_dentry, old_mnt),
10663 +                              newname, DEFAULTSECARGS);
10664 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
10665 +                && !(comp2 & GR_SUPPRESS)) {
10666 +               security_alert(GR_RENAME_ACL_MSG, "denied",
10667 +                              gr_to_filename(old_dentry, old_mnt), newname,
10668 +                              DEFAULTSECARGS);
10669 +               error = -EACCES;
10670 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
10671 +               error = -EACCES;
10672 +
10673 +       return error;
10674 +}
10675 +
10676 +void
10677 +gr_acl_handle_exit(void)
10678 +{
10679 +       u16 id;
10680 +       char *rolename;
10681 +
10682 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
10683 +               id = current->acl_role_id;
10684 +               rolename = current->role->rolename;
10685 +               gr_set_acls(1);
10686 +               security_alert_good(GR_SPROLEL_ACL_MSG,
10687 +                                   rolename, id, DEFAULTSECARGS);
10688 +       }
10689 +
10690 +       if (current->exec_file) {
10691 +               fput(current->exec_file);
10692 +               current->exec_file = NULL;
10693 +       }
10694 +}
10695 +
10696 +int
10697 +gr_acl_handle_procpidmem(const struct task_struct *task)
10698 +{
10699 +       if (unlikely(!gr_acl_is_enabled()))
10700 +               return 0;
10701 +
10702 +       if (task->acl->mode & GR_PROTPROCFD)
10703 +               return -EACCES;
10704 +
10705 +       return 0;
10706 +}
10707 diff -uNr linux-2.6.6/grsecurity/gracl_ip.c linux-2.6.6.fixed/grsecurity/gracl_ip.c
10708 --- linux-2.6.6/grsecurity/gracl_ip.c   1970-01-01 01:00:00.000000000 +0100
10709 +++ linux-2.6.6.fixed/grsecurity/gracl_ip.c     2004-05-11 10:55:56.000000000 +0200
10710 @@ -0,0 +1,236 @@
10711 +/* 
10712 + * grsecurity/gracl_ip.c
10713 + * Copyright Brad Spengler 2002, 2003
10714 + *
10715 + */
10716 +
10717 +#include <linux/kernel.h>
10718 +#include <asm/uaccess.h>
10719 +#include <asm/errno.h>
10720 +#include <net/sock.h>
10721 +#include <linux/file.h>
10722 +#include <linux/fs.h>
10723 +#include <linux/net.h>
10724 +#include <linux/in.h>
10725 +#include <linux/skbuff.h>
10726 +#include <linux/ip.h>
10727 +#include <linux/udp.h>
10728 +#include <linux/smp_lock.h>
10729 +#include <linux/types.h>
10730 +#include <linux/sched.h>
10731 +#include <linux/gracl.h>
10732 +#include <linux/grsecurity.h>
10733 +#include <linux/grinternal.h>
10734 +
10735 +#define GR_BIND        0x01
10736 +#define GR_CONNECT     0x02
10737 +
10738 +static const char * gr_protocols[256] = {
10739 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
10740 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
10741 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
10742 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
10743 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
10744 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
10745 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
10746 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
10747 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
10748 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
10749 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
10750 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
10751 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
10752 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
10753 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
10754 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
10755 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
10756 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
10757 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
10758 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
10759 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
10760 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
10761 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
10762 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
10763 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
10764 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
10765 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
10766 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
10767 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
10768 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
10769 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
10770 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
10771 +       };
10772 +
10773 +static const char * gr_socktypes[11] = {
10774 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
10775 +       "unknown:7", "unknown:8", "unknown:9", "packet"
10776 +       };
10777 +
10778 +__inline__ const char *
10779 +gr_proto_to_name(unsigned char proto)
10780 +{
10781 +       return gr_protocols[proto];
10782 +}
10783 +
10784 +__inline__ const char *
10785 +gr_socktype_to_name(unsigned char type)
10786 +{
10787 +       return gr_socktypes[type];
10788 +}
10789 +
10790 +int
10791 +gr_search_socket(const int domain, const int type, const int protocol)
10792 +{
10793 +       struct acl_subject_label *curr;
10794 +
10795 +       if (unlikely(!gr_acl_is_enabled()))
10796 +               goto exit;
10797 +
10798 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
10799 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
10800 +               goto exit;      // let the kernel handle it
10801 +
10802 +       curr = current->acl;
10803 +
10804 +       if (!curr->ips)
10805 +               goto exit;
10806 +
10807 +       if ((curr->ip_type & (1 << type)) &&
10808 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
10809 +               goto exit;
10810 +
10811 +       if (curr->mode & GR_LEARN) {
10812 +               /* we don't place acls on raw sockets , and sometimes
10813 +                  dgram/ip sockets are opened for ioctl and not
10814 +                  bind/connect, so we'll fake a bind learn log */
10815 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
10816 +                       __u32 fakeip = 0;
10817 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
10818 +                                      current->role->roletype, current->uid,
10819 +                                      current->gid, current->exec_file ?
10820 +                                      gr_to_filename(current->exec_file->f_dentry,
10821 +                                      current->exec_file->f_vfsmnt) :
10822 +                                      curr->filename, curr->filename,
10823 +                                      NIPQUAD(fakeip), 0, type,
10824 +                                      protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
10825 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
10826 +                       __u32 fakeip = 0;
10827 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
10828 +                                      current->role->roletype, current->uid,
10829 +                                      current->gid, current->exec_file ?
10830 +                                      gr_to_filename(current->exec_file->f_dentry,
10831 +                                      current->exec_file->f_vfsmnt) :
10832 +                                      curr->filename, curr->filename,
10833 +                                      NIPQUAD(fakeip), 0, type,
10834 +                                      protocol, GR_BIND, NIPQUAD(current->curr_ip));
10835 +               }
10836 +               /* we'll log when they use connect or bind */
10837 +               goto exit;
10838 +       }
10839 +
10840 +       security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
10841 +                      gr_proto_to_name(protocol), DEFAULTSECARGS);
10842 +
10843 +       return 0;
10844 +      exit:
10845 +       return 1;
10846 +}
10847 +
10848 +static __inline__ int
10849 +gr_search_connectbind(const int mode, const struct sock *sk,
10850 +                     const struct sockaddr_in *addr, const int type)
10851 +{
10852 +       struct acl_subject_label *curr;
10853 +       struct acl_ip_label *ip;
10854 +       unsigned long i;
10855 +       __u32 ip_addr = 0;
10856 +       __u16 ip_port = 0;
10857 +
10858 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
10859 +               return 1;
10860 +
10861 +       curr = current->acl;
10862 +
10863 +       if (!curr->ips)
10864 +               return 1;
10865 +
10866 +       ip_addr = addr->sin_addr.s_addr;
10867 +       ip_port = ntohs(addr->sin_port);
10868 +
10869 +       for (i = 0; i < curr->ip_num; i++) {
10870 +               ip = *(curr->ips + i);
10871 +               if ((ip->mode & mode) &&
10872 +                   (ip_port >= ip->low) &&
10873 +                   (ip_port <= ip->high) &&
10874 +                   ((ntohl(ip_addr) & ip->netmask) ==
10875 +                    (ntohl(ip->addr) & ip->netmask))
10876 +                   && (ip->
10877 +                       proto[sk->sk_protocol / 32] & (1 << (sk->sk_protocol % 32)))
10878 +                   && (ip->type & (1 << type)))
10879 +                       return 1;
10880 +       }
10881 +
10882 +       if (curr->mode & GR_LEARN) {
10883 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
10884 +                              current->role->roletype, current->uid,
10885 +                              current->gid, current->exec_file ?
10886 +                              gr_to_filename(current->exec_file->f_dentry,
10887 +                              current->exec_file->f_vfsmnt) :
10888 +                              curr->filename, curr->filename,
10889 +                              NIPQUAD(ip_addr), ip_port, type,
10890 +                              sk->sk_protocol, mode, NIPQUAD(current->curr_ip));
10891 +               return 1;
10892 +       }
10893 +
10894 +       if (mode == GR_BIND)
10895 +               security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
10896 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol),
10897 +                              DEFAULTSECARGS);
10898 +       else if (mode == GR_CONNECT)
10899 +               security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
10900 +                              gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol),
10901 +                              DEFAULTSECARGS);
10902 +
10903 +       return 0;
10904 +}
10905 +
10906 +int
10907 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
10908 +{
10909 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
10910 +}
10911 +
10912 +int
10913 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
10914 +{
10915 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
10916 +}
10917 +
10918 +int
10919 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
10920 +{
10921 +       if (addr)
10922 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
10923 +       else {
10924 +               struct sockaddr_in sin;
10925 +               const struct inet_opt *inet = inet_sk(sk);
10926 +
10927 +               sin.sin_addr.s_addr = inet->daddr;
10928 +               sin.sin_port = inet->dport;
10929 +
10930 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
10931 +       }
10932 +}
10933 +
10934 +int
10935 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
10936 +{
10937 +       struct sockaddr_in sin;
10938 +
10939 +       if (unlikely(skb->len < sizeof (struct udphdr)))
10940 +               return 1;       // skip this packet
10941 +
10942 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
10943 +       sin.sin_port = skb->h.uh->source;
10944 +
10945 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
10946 +}
10947 diff -uNr linux-2.6.6/grsecurity/gracl_learn.c linux-2.6.6.fixed/grsecurity/gracl_learn.c
10948 --- linux-2.6.6/grsecurity/gracl_learn.c        1970-01-01 01:00:00.000000000 +0100
10949 +++ linux-2.6.6.fixed/grsecurity/gracl_learn.c  2004-05-11 10:55:56.000000000 +0200
10950 @@ -0,0 +1,204 @@
10951 +#include <linux/kernel.h>
10952 +#include <linux/mm.h>
10953 +#include <linux/sched.h>
10954 +#include <linux/poll.h>
10955 +#include <linux/smp_lock.h>
10956 +#include <linux/string.h>
10957 +#include <linux/file.h>
10958 +#include <linux/types.h>
10959 +#include <linux/vmalloc.h>
10960 +#include <linux/grinternal.h>
10961 +
10962 +extern ssize_t write_grsec_handler(struct file * file, const char * buf,
10963 +                                  size_t count, loff_t *ppos);
10964 +extern int gr_acl_is_enabled(void);
10965 +
10966 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
10967 +static int gr_learn_attached;
10968 +
10969 +/* use a 512k buffer */
10970 +#define LEARN_BUFFER_SIZE (512 * 1024)
10971 +
10972 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
10973 +static DECLARE_MUTEX(gr_learn_user_sem);
10974 +
10975 +/* we need to maintain two buffers, so that the kernel context of grlearn
10976 +   uses a semaphore around the userspace copying, and the other kernel contexts
10977 +   use a spinlock when copying into the buffer, since they cannot sleep
10978 +*/
10979 +static char *learn_buffer;
10980 +static char *learn_buffer_user;
10981 +static int learn_buffer_len;
10982 +static int learn_buffer_user_len;
10983 +
10984 +static ssize_t
10985 +read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
10986 +{
10987 +       DECLARE_WAITQUEUE(wait, current);
10988 +       ssize_t retval = 0;
10989 +
10990 +       add_wait_queue(&learn_wait, &wait);
10991 +       set_current_state(TASK_INTERRUPTIBLE);
10992 +       do {
10993 +               down(&gr_learn_user_sem);
10994 +               spin_lock(&gr_learn_lock);
10995 +               if (learn_buffer_len)
10996 +                       break;
10997 +               spin_unlock(&gr_learn_lock);
10998 +               up(&gr_learn_user_sem);
10999 +               if (file->f_flags & O_NONBLOCK) {
11000 +                       retval = -EAGAIN;
11001 +                       goto out;
11002 +               }
11003 +               if (signal_pending(current)) {
11004 +                       retval = -ERESTARTSYS;
11005 +                       goto out;
11006 +               }
11007 +
11008 +               schedule();
11009 +       } while (1);
11010 +
11011 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
11012 +       learn_buffer_user_len = learn_buffer_len;
11013 +       retval = learn_buffer_len;
11014 +       learn_buffer_len = 0;
11015 +
11016 +       spin_unlock(&gr_learn_lock);
11017 +
11018 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
11019 +               retval = -EFAULT;
11020 +
11021 +       up(&gr_learn_user_sem);
11022 +out:
11023 +       set_current_state(TASK_RUNNING);
11024 +       remove_wait_queue(&learn_wait, &wait);
11025 +       return retval;
11026 +}
11027 +
11028 +static unsigned int
11029 +poll_learn(struct file * file, poll_table * wait)
11030 +{
11031 +       poll_wait(file, &learn_wait, wait);
11032 +
11033 +       if (learn_buffer_len)
11034 +               return (POLLIN | POLLRDNORM);
11035 +
11036 +       return 0;
11037 +}
11038 +
11039 +void
11040 +gr_clear_learn_entries(void)
11041 +{
11042 +       char *tmp;
11043 +
11044 +       down(&gr_learn_user_sem);
11045 +       if (learn_buffer != NULL) {
11046 +               spin_lock(&gr_learn_lock);
11047 +               tmp = learn_buffer;
11048 +               learn_buffer = NULL;
11049 +               spin_unlock(&gr_learn_lock);
11050 +               vfree(learn_buffer);
11051 +       }
11052 +       if (learn_buffer_user != NULL) {
11053 +               vfree(learn_buffer_user);
11054 +               learn_buffer_user = NULL;
11055 +       }
11056 +       learn_buffer_len = 0;
11057 +       up(&gr_learn_user_sem);
11058 +
11059 +       return;
11060 +}
11061 +
11062 +void
11063 +gr_add_learn_entry(const char *fmt, ...)
11064 +{
11065 +       va_list args;
11066 +       unsigned int len;
11067 +
11068 +       if (!gr_learn_attached)
11069 +               return;
11070 +
11071 +       spin_lock(&gr_learn_lock);
11072 +
11073 +       /* leave a gap at the end so we know when it's "full" but don't have to
11074 +          compute the exact length of the string we're trying to append
11075 +       */
11076 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
11077 +               spin_unlock(&gr_learn_lock);
11078 +               wake_up_interruptible(&learn_wait);
11079 +               return;
11080 +       }
11081 +       if (learn_buffer == NULL) {
11082 +               spin_unlock(&gr_learn_lock);
11083 +               return;
11084 +       }
11085 +
11086 +       va_start(args, fmt);
11087 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
11088 +       va_end(args);
11089 +
11090 +       learn_buffer_len += len + 1;
11091 +
11092 +       spin_unlock(&gr_learn_lock);
11093 +       wake_up_interruptible(&learn_wait);
11094 +
11095 +       return;
11096 +}
11097 +
11098 +static int
11099 +open_learn(struct inode *inode, struct file *file)
11100 +{
11101 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
11102 +               return -EBUSY;
11103 +       if (file->f_mode & FMODE_READ) {
11104 +               down(&gr_learn_user_sem);
11105 +               if (learn_buffer == NULL)
11106 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
11107 +               if (learn_buffer_user == NULL)
11108 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
11109 +               if (learn_buffer == NULL)
11110 +                       return -ENOMEM;
11111 +               if (learn_buffer_user == NULL)
11112 +                       return -ENOMEM;
11113 +               learn_buffer_len = 0;
11114 +               learn_buffer_user_len = 0;
11115 +               gr_learn_attached = 1;
11116 +               up(&gr_learn_user_sem);
11117 +       }
11118 +       return 0;
11119 +}
11120 +
11121 +static int
11122 +close_learn(struct inode *inode, struct file *file)
11123 +{
11124 +       char *tmp;
11125 +
11126 +       if (file->f_mode & FMODE_READ) {
11127 +               down(&gr_learn_user_sem);
11128 +               if (learn_buffer != NULL) {
11129 +                       spin_lock(&gr_learn_lock);
11130 +                       tmp = learn_buffer;
11131 +                       learn_buffer = NULL;
11132 +                       spin_unlock(&gr_learn_lock);
11133 +                       vfree(tmp);
11134 +               }
11135 +               if (learn_buffer_user != NULL) {
11136 +                       vfree(learn_buffer_user);
11137 +                       learn_buffer_user = NULL;
11138 +               }
11139 +               learn_buffer_len = 0;
11140 +               learn_buffer_user_len = 0;
11141 +               gr_learn_attached = 0;
11142 +               up(&gr_learn_user_sem);
11143 +       }
11144 +
11145 +       return 0;
11146 +}
11147 +               
11148 +struct file_operations grsec_fops = {
11149 +       read:           read_learn,
11150 +       write:          write_grsec_handler,
11151 +       open:           open_learn,
11152 +       release:        close_learn,
11153 +       poll:           poll_learn,
11154 +};
11155 diff -uNr linux-2.6.6/grsecurity/gracl_res.c linux-2.6.6.fixed/grsecurity/gracl_res.c
11156 --- linux-2.6.6/grsecurity/gracl_res.c  1970-01-01 01:00:00.000000000 +0100
11157 +++ linux-2.6.6.fixed/grsecurity/gracl_res.c    2004-05-11 10:55:56.000000000 +0200
11158 @@ -0,0 +1,50 @@
11159 +/* resource handling routines (c) Brad Spengler 2002, 2003 */
11160 +
11161 +#include <linux/kernel.h>
11162 +#include <linux/sched.h>
11163 +#include <linux/gracl.h>
11164 +#include <linux/grinternal.h>
11165 +
11166 +static const char *restab_log[11] = {
11167 +       "RLIMIT_CPU",
11168 +       "RLIMIT_FSIZE",
11169 +       "RLIMIT_DATA",
11170 +       "RLIMIT_STACK",
11171 +       "RLIMIT_CORE",
11172 +       "RLIMIT_RSS",
11173 +       "RLIMIT_NPROC",
11174 +       "RLIMIT_NOFILE",
11175 +       "RLIMIT_MEMLOCK",
11176 +       "RLIMIT_AS",
11177 +       "RLIMIT_LOCKS"
11178 +};
11179 +
11180 +__inline__ void
11181 +gr_log_resource(const struct task_struct *task,
11182 +               const int res, const unsigned long wanted, const int gt)
11183 +{
11184 +       if (unlikely(res == RLIMIT_NPROC && 
11185 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
11186 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
11187 +               return;
11188 +
11189 +       preempt_disable();
11190 +
11191 +       if (unlikely(((gt && wanted > task->rlim[res].rlim_cur) ||
11192 +                     (!gt && wanted >= task->rlim[res].rlim_cur)) &&
11193 +                    task->rlim[res].rlim_cur != RLIM_INFINITY))
11194 +               security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
11195 +                              task->rlim[res].rlim_cur,
11196 +                              gr_task_fullpath(task), task->comm,
11197 +                              task->pid, task->uid, task->euid,
11198 +                              task->gid, task->egid,
11199 +                              gr_parent_task_fullpath(task),
11200 +                              task->parent->comm,
11201 +                              task->parent->pid, task->parent->uid, 
11202 +                              task->parent->euid, task->parent->gid,
11203 +                              task->parent->egid);
11204 +
11205 +       preempt_enable_no_resched();
11206 +
11207 +       return;
11208 +}
11209 diff -uNr linux-2.6.6/grsecurity/gracl_segv.c linux-2.6.6.fixed/grsecurity/gracl_segv.c
11210 --- linux-2.6.6/grsecurity/gracl_segv.c 1970-01-01 01:00:00.000000000 +0100
11211 +++ linux-2.6.6.fixed/grsecurity/gracl_segv.c   2004-05-11 10:55:56.000000000 +0200
11212 @@ -0,0 +1,330 @@
11213 +/* 
11214 + * grsecurity/gracl_segv.c
11215 + * Copyright Brad Spengler 2002, 2003
11216 + *
11217 + */
11218 +
11219 +#include <linux/kernel.h>
11220 +#include <linux/mm.h>
11221 +#include <asm/uaccess.h>
11222 +#include <asm/errno.h>
11223 +#include <asm/mman.h>
11224 +#include <net/sock.h>
11225 +#include <linux/file.h>
11226 +#include <linux/fs.h>
11227 +#include <linux/net.h>
11228 +#include <linux/in.h>
11229 +#include <linux/smp_lock.h>
11230 +#include <linux/slab.h>
11231 +#include <linux/types.h>
11232 +#include <linux/sched.h>
11233 +#include <linux/timer.h>
11234 +#include <linux/gracl.h>
11235 +#include <linux/grsecurity.h>
11236 +#include <linux/grinternal.h>
11237 +
11238 +static struct crash_uid *uid_set;
11239 +static unsigned short uid_used;
11240 +static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
11241 +extern rwlock_t gr_inode_lock;
11242 +extern struct acl_subject_label *
11243 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
11244 +                             struct acl_role_label *role);
11245 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
11246 +
11247 +int
11248 +gr_init_uidset(void)
11249 +{
11250 +       uid_set =
11251 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
11252 +       uid_used = 0;
11253 +
11254 +       return uid_set ? 1 : 0;
11255 +}
11256 +
11257 +void
11258 +gr_free_uidset(void)
11259 +{
11260 +       if (uid_set)
11261 +               kfree(uid_set);
11262 +
11263 +       return;
11264 +}
11265 +
11266 +int
11267 +gr_find_uid(const uid_t uid)
11268 +{
11269 +       struct crash_uid *tmp = uid_set;
11270 +       uid_t buid;
11271 +       int low = 0, high = uid_used - 1, mid;
11272 +
11273 +       while (high >= low) {
11274 +               mid = (low + high) >> 1;
11275 +               buid = tmp[mid].uid;
11276 +               if (buid == uid)
11277 +                       return mid;
11278 +               if (buid > uid)
11279 +                       high = mid - 1;
11280 +               if (buid < uid)
11281 +                       low = mid + 1;
11282 +       }
11283 +
11284 +       return -1;
11285 +}
11286 +
11287 +static __inline__ void
11288 +gr_insertsort(void)
11289 +{
11290 +       unsigned short i, j;
11291 +       struct crash_uid index;
11292 +
11293 +       for (i = 1; i < uid_used; i++) {
11294 +               index = uid_set[i];
11295 +               j = i;
11296 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
11297 +                       uid_set[j] = uid_set[j - 1];
11298 +                       j--;
11299 +               }
11300 +               uid_set[j] = index;
11301 +       }
11302 +
11303 +       return;
11304 +}
11305 +
11306 +static __inline__ void
11307 +gr_insert_uid(const uid_t uid, const unsigned long expires)
11308 +{
11309 +       int loc;
11310 +
11311 +       if (uid_used == GR_UIDTABLE_MAX)
11312 +               return;
11313 +
11314 +       loc = gr_find_uid(uid);
11315 +
11316 +       if (loc >= 0) {
11317 +               uid_set[loc].expires = expires;
11318 +               return;
11319 +       }
11320 +
11321 +       uid_set[uid_used].uid = uid;
11322 +       uid_set[uid_used].expires = expires;
11323 +       uid_used++;
11324 +
11325 +       gr_insertsort();
11326 +
11327 +       return;
11328 +}
11329 +
11330 +void
11331 +gr_remove_uid(const unsigned short loc)
11332 +{
11333 +       unsigned short i;
11334 +
11335 +       for (i = loc + 1; i < uid_used; i++)
11336 +               uid_set[i - i] = uid_set[i];
11337 +
11338 +       uid_used--;
11339 +
11340 +       return;
11341 +}
11342 +
11343 +int
11344 +gr_check_crash_uid(const uid_t uid)
11345 +{
11346 +       int loc;
11347 +
11348 +       if (unlikely(!gr_acl_is_enabled()))
11349 +               return 0;
11350 +
11351 +       read_lock(&gr_uid_lock);
11352 +       loc = gr_find_uid(uid);
11353 +       read_unlock(&gr_uid_lock);
11354 +
11355 +       if (loc < 0)
11356 +               return 0;
11357 +
11358 +       write_lock(&gr_uid_lock);
11359 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
11360 +               gr_remove_uid(loc);
11361 +       else {
11362 +               write_unlock(&gr_uid_lock);
11363 +               return 1;
11364 +       }
11365 +
11366 +       write_unlock(&gr_uid_lock);
11367 +       return 0;
11368 +}
11369 +
11370 +static __inline__ int
11371 +proc_is_setxid(const struct task_struct *task)
11372 +{
11373 +       if (task->uid != task->euid || task->uid != task->suid ||
11374 +           task->uid != task->fsuid)
11375 +               return 1;
11376 +       if (task->gid != task->egid || task->gid != task->sgid ||
11377 +           task->gid != task->fsgid)
11378 +               return 1;
11379 +
11380 +       return 0;
11381 +}
11382 +static __inline__ int
11383 +gr_fake_force_sig(int sig, struct task_struct *t)
11384 +{
11385 +       unsigned long int flags;
11386 +       int ret;
11387 +
11388 +       spin_lock_irqsave(&t->sighand->siglock, flags);
11389 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
11390 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
11391 +               sigdelset(&t->blocked, sig);
11392 +               recalc_sigpending_tsk(t);
11393 +       }
11394 +       ret = specific_send_sig_info(sig, (void*)1L, t);
11395 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
11396 +
11397 +       return ret;
11398 +}
11399 +
11400 +void
11401 +gr_handle_crash(struct task_struct *task, const int sig)
11402 +{
11403 +       struct acl_subject_label *curr;
11404 +       struct acl_subject_label *curr2;
11405 +       struct task_struct *tsk, *tsk2;
11406 +
11407 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
11408 +               return;
11409 +
11410 +       if (unlikely(!gr_acl_is_enabled()))
11411 +               return;
11412 +
11413 +       curr = task->acl;
11414 +
11415 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
11416 +               return;
11417 +
11418 +       if (time_before_eq(curr->expires, get_seconds())) {
11419 +               curr->expires = 0;
11420 +               curr->crashes = 0;
11421 +       }
11422 +
11423 +       curr->crashes++;
11424 +
11425 +       if (!curr->expires)
11426 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
11427 +
11428 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
11429 +           time_after(curr->expires, get_seconds())) {
11430 +               if (task->uid && proc_is_setxid(task)) {
11431 +                       security_alert(GR_SEGVSTART_ACL_MSG,
11432 +                                      gr_task_fullpath(task), task->comm,
11433 +                                      task->pid, task->uid, task->euid,
11434 +                                      task->gid, task->egid,
11435 +                                      gr_parent_task_fullpath(task),
11436 +                                      task->parent->comm, task->parent->pid,
11437 +                                      task->parent->uid, task->parent->euid,
11438 +                                      task->parent->gid, task->parent->egid,
11439 +                                      task->uid,
11440 +                                      curr->res[GR_CRASH_RES].rlim_max);
11441 +                       write_lock(&gr_uid_lock);
11442 +                       gr_insert_uid(task->uid, curr->expires);
11443 +                       write_unlock(&gr_uid_lock);
11444 +                       curr->expires = 0;
11445 +                       curr->crashes = 0;
11446 +                       read_lock(&tasklist_lock);
11447 +                       for_each_process(tsk) {
11448 +                               tsk2 = tsk;
11449 +                               do {
11450 +                                       if (tsk2 != task && tsk2->uid == task->uid)
11451 +                                       gr_fake_force_sig(SIGKILL, tsk2);
11452 +                               } while ((tsk2 = next_thread(tsk2)) != tsk);
11453 +                       }
11454 +                       read_unlock(&tasklist_lock);
11455 +               } else {
11456 +                       security_alert(GR_SEGVNOSUID_ACL_MSG,
11457 +                                      gr_task_fullpath(task), task->comm,
11458 +                                      task->pid, task->uid, task->euid,
11459 +                                      task->gid, task->egid,
11460 +                                      gr_parent_task_fullpath(task),
11461 +                                      task->parent->comm, task->parent->pid,
11462 +                                      task->parent->uid, task->parent->euid,
11463 +                                      task->parent->gid, task->parent->egid,
11464 +                                      curr->res[GR_CRASH_RES].rlim_max);
11465 +                       read_lock(&tasklist_lock);
11466 +                       for_each_process(tsk) {
11467 +                               tsk2 = tsk;
11468 +                               do {
11469 +                                       if (likely(tsk2 != task)) {
11470 +                                               curr2 = tsk2->acl;
11471 +
11472 +                                               if (curr2->device == curr->device &&
11473 +                                                   curr2->inode == curr->inode)
11474 +                                                       gr_fake_force_sig(SIGKILL, tsk2);
11475 +                                       }
11476 +                               } while ((tsk2 = next_thread(tsk2)) != tsk);
11477 +                       }
11478 +                       read_unlock(&tasklist_lock);
11479 +               }
11480 +       }
11481 +
11482 +       return;
11483 +}
11484 +
11485 +int
11486 +gr_check_crash_exec(const struct file *filp)
11487 +{
11488 +       struct acl_subject_label *curr;
11489 +
11490 +       if (unlikely(!gr_acl_is_enabled()))
11491 +               return 0;
11492 +
11493 +       read_lock(&gr_inode_lock);
11494 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
11495 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
11496 +                                    current->role);
11497 +       read_unlock(&gr_inode_lock);
11498 +
11499 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
11500 +           (!curr->crashes && !curr->expires))
11501 +               return 0;
11502 +
11503 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
11504 +           time_after(curr->expires, get_seconds()))
11505 +               return 1;
11506 +       else if (time_before_eq(curr->expires, get_seconds())) {
11507 +               curr->crashes = 0;
11508 +               curr->expires = 0;
11509 +       }
11510 +
11511 +       return 0;
11512 +}
11513 +
11514 +void
11515 +gr_handle_alertkill(void)
11516 +{
11517 +       struct acl_subject_label *curracl;
11518 +       __u32 curr_ip;
11519 +       struct task_struct *task, *task2;
11520 +
11521 +       if (unlikely(!gr_acl_is_enabled()))
11522 +               return;
11523 +
11524 +       curracl = current->acl;
11525 +       curr_ip = current->curr_ip;
11526 +
11527 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
11528 +           (curr_ip != 0xffffffff)) {
11529 +               read_lock(&tasklist_lock);
11530 +               for_each_process(task) {
11531 +                       task2 = task;
11532 +                       do {
11533 +                               if (task2->curr_ip == curr_ip)
11534 +                                       gr_fake_force_sig(SIGKILL, task2);
11535 +                       } while ((task2 = next_thread(task2)) != task);
11536 +               }
11537 +               read_unlock(&tasklist_lock);
11538 +       } else if (curracl->mode & GR_KILLPROC)
11539 +               gr_fake_force_sig(SIGKILL, current);
11540 +
11541 +       return;
11542 +}
11543 diff -uNr linux-2.6.6/grsecurity/gracl_shm.c linux-2.6.6.fixed/grsecurity/gracl_shm.c
11544 --- linux-2.6.6/grsecurity/gracl_shm.c  1970-01-01 01:00:00.000000000 +0100
11545 +++ linux-2.6.6.fixed/grsecurity/gracl_shm.c    2004-05-11 10:55:56.000000000 +0200
11546 @@ -0,0 +1,36 @@
11547 +/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
11548 +
11549 +#include <linux/kernel.h>
11550 +#include <linux/mm.h>
11551 +#include <linux/sched.h>
11552 +#include <linux/file.h>
11553 +#include <linux/ipc.h>
11554 +#include <linux/gracl.h>
11555 +#include <linux/grsecurity.h>
11556 +#include <linux/grinternal.h>
11557 +
11558 +int
11559 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
11560 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
11561 +{
11562 +       struct task_struct *task;
11563 +
11564 +       if (!gr_acl_is_enabled())
11565 +               return 1;
11566 +
11567 +       task = find_task_by_pid(shm_cprid);
11568 +
11569 +       if (unlikely(!task))
11570 +               task = find_task_by_pid(shm_lapid);
11571 +
11572 +       if (unlikely(task && ((task->start_time < shm_createtime) ||
11573 +                             (task->pid == shm_lapid)) &&
11574 +                    (task->acl->mode & GR_PROTSHM) &&
11575 +                    (task->acl != current->acl))) {
11576 +               security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
11577 +                              DEFAULTSECARGS);
11578 +               return 0;
11579 +       }
11580 +
11581 +       return 1;
11582 +}
11583 diff -uNr linux-2.6.6/grsecurity/grsec_chdir.c linux-2.6.6.fixed/grsecurity/grsec_chdir.c
11584 --- linux-2.6.6/grsecurity/grsec_chdir.c        1970-01-01 01:00:00.000000000 +0100
11585 +++ linux-2.6.6.fixed/grsecurity/grsec_chdir.c  2004-05-11 10:55:56.000000000 +0200
11586 @@ -0,0 +1,20 @@
11587 +#include <linux/kernel.h>
11588 +#include <linux/sched.h>
11589 +#include <linux/fs.h>
11590 +#include <linux/file.h>
11591 +#include <linux/grsecurity.h>
11592 +#include <linux/grinternal.h>
11593 +
11594 +void
11595 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
11596 +{
11597 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
11598 +       if ((grsec_enable_chdir && grsec_enable_group &&
11599 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
11600 +                                             !grsec_enable_group)) {
11601 +               security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
11602 +                              DEFAULTSECARGS);
11603 +       }
11604 +#endif
11605 +       return;
11606 +}
11607 diff -uNr linux-2.6.6/grsecurity/grsec_chroot.c linux-2.6.6.fixed/grsecurity/grsec_chroot.c
11608 --- linux-2.6.6/grsecurity/grsec_chroot.c       1970-01-01 01:00:00.000000000 +0100
11609 +++ linux-2.6.6.fixed/grsecurity/grsec_chroot.c 2004-05-11 10:55:56.000000000 +0200
11610 @@ -0,0 +1,346 @@
11611 +#include <linux/kernel.h>
11612 +#include <linux/module.h>
11613 +#include <linux/sched.h>
11614 +#include <linux/file.h>
11615 +#include <linux/fs.h>
11616 +#include <linux/mount.h>
11617 +#include <linux/types.h>
11618 +#include <linux/grinternal.h>
11619 +
11620 +int
11621 +gr_handle_chroot_unix(const pid_t pid)
11622 +{
11623 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
11624 +       struct pid *spid = NULL;
11625 +
11626 +       if (unlikely(!grsec_enable_chroot_unix))
11627 +               return 1;
11628 +
11629 +       if (likely(!proc_is_chrooted(current)))
11630 +               return 1;
11631 +
11632 +       read_lock(&tasklist_lock);
11633 +
11634 +       spid = find_pid(PIDTYPE_PID, pid);
11635 +       if (spid) {
11636 +               struct task_struct *p;
11637 +               p = pid_task(spid->task_list.next, PIDTYPE_PID);
11638 +               if (unlikely(!have_same_root(current, p))) {
11639 +                       read_unlock(&tasklist_lock);
11640 +                       security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
11641 +                       return 0;
11642 +               }
11643 +       }
11644 +       read_unlock(&tasklist_lock);
11645 +#endif
11646 +       return 1;
11647 +}
11648 +
11649 +int
11650 +gr_handle_chroot_nice(void)
11651 +{
11652 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
11653 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
11654 +               security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
11655 +               return -EPERM;
11656 +       }
11657 +#endif
11658 +       return 0;
11659 +}
11660 +
11661 +int
11662 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
11663 +{
11664 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
11665 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
11666 +                       && proc_is_chrooted(current)) {
11667 +               security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
11668 +                              DEFAULTSECARGS);
11669 +               return -EACCES;
11670 +       }
11671 +#endif
11672 +       return 0;
11673 +}
11674 +
11675 +int
11676 +gr_handle_chroot_capset(const struct task_struct *target)
11677 +{
11678 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11679 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
11680 +           !have_same_root(current, target)) {
11681 +               security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
11682 +                              DEFAULTSECARGS);
11683 +               return 1;
11684 +       }
11685 +#endif
11686 +       return 0;
11687 +}
11688 +
11689 +int
11690 +gr_handle_chroot_rawio(const struct inode *inode)
11691 +{
11692 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11693 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
11694 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
11695 +               return 1;
11696 +#endif
11697 +       return 0;
11698 +}
11699 +
11700 +int
11701 +gr_pid_is_chrooted(const struct task_struct *p)
11702 +{
11703 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
11704 +       if (!grsec_enable_chroot_findtask || (current->pid <= 1))
11705 +               return 0;
11706 +
11707 +       if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
11708 +           child_reaper && child_reaper->fs && child_reaper->fs->root &&
11709 +           child_reaper->fs->root->d_inode && current && current->fs &&
11710 +           current->fs->root && current->fs->root->d_inode) {
11711 +               if (proc_is_chrooted(current) && !have_same_root(current, p))
11712 +                       return 1;
11713 +       }
11714 +#endif
11715 +       return 0;
11716 +}
11717 +
11718 +EXPORT_SYMBOL(gr_pid_is_chrooted);
11719 +
11720 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
11721 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
11722 +{
11723 +       struct dentry *dentry = (struct dentry *)u_dentry;
11724 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
11725 +       struct dentry *realroot;
11726 +       struct vfsmount *realrootmnt;
11727 +       struct dentry *currentroot;
11728 +       struct vfsmount *currentmnt;
11729 +
11730 +       read_lock(&child_reaper->fs->lock);
11731 +       realrootmnt = mntget(child_reaper->fs->rootmnt);
11732 +       realroot = dget(child_reaper->fs->root);
11733 +       read_unlock(&child_reaper->fs->lock);
11734 +
11735 +       read_lock(&current->fs->lock);
11736 +       currentmnt = mntget(current->fs->rootmnt);
11737 +       currentroot = dget(current->fs->root);
11738 +       read_unlock(&current->fs->lock);
11739 +
11740 +       spin_lock(&dcache_lock);
11741 +       for (;;) {
11742 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
11743 +                    || (dentry == currentroot && mnt == currentmnt)))
11744 +                       break;
11745 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
11746 +                       if (mnt->mnt_parent == mnt)
11747 +                               break;
11748 +                       dentry = mnt->mnt_mountpoint;
11749 +                       mnt = mnt->mnt_parent;
11750 +                       continue;
11751 +               }
11752 +               dentry = dentry->d_parent;
11753 +       }
11754 +       spin_unlock(&dcache_lock);
11755 +
11756 +       dput(currentroot);
11757 +       mntput(currentmnt);
11758 +
11759 +       if (dentry == realroot && mnt == realrootmnt) {
11760 +               /* access is outside of chroot */
11761 +               dput(realroot);
11762 +               mntput(realrootmnt);
11763 +               return 0;
11764 +       }
11765 +
11766 +       dput(realroot);
11767 +       mntput(realrootmnt);
11768 +       return 1;
11769 +}
11770 +#endif
11771 +
11772 +int
11773 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
11774 +{
11775 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
11776 +       if (!grsec_enable_chroot_fchdir)
11777 +               return 1;
11778 +
11779 +       if (!proc_is_chrooted(current))
11780 +               return 1;
11781 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
11782 +               security_alert(GR_CHROOT_FCHDIR_MSG,
11783 +                              gr_to_filename(u_dentry, u_mnt),
11784 +                              DEFAULTSECARGS);
11785 +               return 0;
11786 +       }
11787 +#endif
11788 +       return 1;
11789 +}
11790 +
11791 +int
11792 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
11793 +               const time_t shm_createtime)
11794 +{
11795 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
11796 +       struct pid *pid = NULL;
11797 +       u64 starttime64;
11798 +       time_t starttime;
11799 +
11800 +       if (unlikely(!grsec_enable_chroot_shmat))
11801 +               return 1;
11802 +
11803 +       if (likely(!proc_is_chrooted(current)))
11804 +               return 1;
11805 +
11806 +       read_lock(&tasklist_lock);
11807 +
11808 +       pid = find_pid(PIDTYPE_PID, shm_cprid);
11809 +       if (pid) {
11810 +               struct task_struct *p;
11811 +               p = pid_task(pid->task_list.next, PIDTYPE_PID);
11812 +               starttime64 = p->start_time;
11813 +               do_div(starttime64, HZ);
11814 +               starttime = (time_t) starttime64;
11815 +               if (unlikely(!have_same_root(current, p) &&
11816 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
11817 +                       read_unlock(&tasklist_lock);
11818 +                       security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
11819 +                       return 0;
11820 +               }
11821 +       } else {
11822 +               pid = find_pid(PIDTYPE_PID, shm_lapid);
11823 +               if (pid) {
11824 +                       struct task_struct *p;
11825 +                       p = pid_task(pid->task_list.next, PIDTYPE_PID);
11826 +                       if (unlikely(!have_same_root(current, p))) {
11827 +                               read_unlock(&tasklist_lock);
11828 +                               security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
11829 +                               return 0;
11830 +                       }
11831 +               }
11832 +       }
11833 +
11834 +       read_unlock(&tasklist_lock);
11835 +#endif
11836 +       return 1;
11837 +}
11838 +
11839 +void
11840 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
11841 +{
11842 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
11843 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
11844 +               security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
11845 +                              DEFAULTSECARGS);
11846 +#endif
11847 +       return;
11848 +}
11849 +
11850 +int
11851 +gr_handle_chroot_mknod(const struct dentry *dentry,
11852 +                      const struct vfsmount *mnt, const int mode)
11853 +{
11854 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
11855 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
11856 +           proc_is_chrooted(current)) {
11857 +               security_alert(GR_MKNOD_CHROOT_MSG,
11858 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
11859 +               return -EPERM;
11860 +       }
11861 +#endif
11862 +       return 0;
11863 +}
11864 +
11865 +int
11866 +gr_handle_chroot_mount(const struct dentry *dentry,
11867 +                      const struct vfsmount *mnt, const char *dev_name)
11868 +{
11869 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
11870 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
11871 +               security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
11872 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
11873 +               return -EPERM;
11874 +       }
11875 +#endif
11876 +       return 0;
11877 +}
11878 +
11879 +int
11880 +gr_handle_chroot_pivot(void)
11881 +{
11882 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
11883 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
11884 +               security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
11885 +               return -EPERM;
11886 +       }
11887 +#endif
11888 +       return 0;
11889 +}
11890 +
11891 +int
11892 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
11893 +{
11894 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
11895 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
11896 +           !gr_is_outside_chroot(dentry, mnt)) {
11897 +               security_alert(GR_CHROOT_CHROOT_MSG,
11898 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
11899 +               return -EPERM;
11900 +       }
11901 +#endif
11902 +       return 0;
11903 +}
11904 +
11905 +void
11906 +gr_handle_chroot_caps(struct task_struct *task)
11907 +{
11908 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11909 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
11910 +               task->cap_permitted =
11911 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
11912 +               task->cap_inheritable =
11913 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
11914 +               task->cap_effective =
11915 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
11916 +       }
11917 +#endif
11918 +       return;
11919 +}
11920 +
11921 +int
11922 +gr_handle_chroot_sysctl(const int op)
11923 +{
11924 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
11925 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
11926 +           && (op & 002))
11927 +               return -EACCES;
11928 +#endif
11929 +       return 0;
11930 +}
11931 +
11932 +void
11933 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
11934 +{
11935 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
11936 +       if (grsec_enable_chroot_chdir)
11937 +               set_fs_pwd(current->fs, mnt, dentry);
11938 +#endif
11939 +       return;
11940 +}
11941 +
11942 +int
11943 +gr_handle_chroot_chmod(const struct dentry *dentry,
11944 +                      const struct vfsmount *mnt, const int mode)
11945 +{
11946 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
11947 +       if (grsec_enable_chroot_chmod &&
11948 +           ((mode & S_ISUID) || (mode & S_ISGID)) &&
11949 +           proc_is_chrooted(current)) {
11950 +               security_alert(GR_CHMOD_CHROOT_MSG,
11951 +                              gr_to_filename(dentry, mnt), DEFAULTSECARGS);
11952 +               return -EPERM;
11953 +       }
11954 +#endif
11955 +       return 0;
11956 +}
11957 diff -uNr linux-2.6.6/grsecurity/grsec_disabled.c linux-2.6.6.fixed/grsecurity/grsec_disabled.c
11958 --- linux-2.6.6/grsecurity/grsec_disabled.c     1970-01-01 01:00:00.000000000 +0100
11959 +++ linux-2.6.6.fixed/grsecurity/grsec_disabled.c       2004-05-11 10:55:56.000000000 +0200
11960 @@ -0,0 +1,419 @@
11961 +/* 
11962 + * when grsecurity is disabled, compile all external functions into nothing
11963 + */
11964 +
11965 +#include <linux/kernel.h>
11966 +#include <linux/module.h>
11967 +#include <linux/config.h>
11968 +#include <linux/sched.h>
11969 +#include <linux/file.h>
11970 +#include <linux/fs.h>
11971 +#include <linux/kdev_t.h>
11972 +#include <linux/net.h>
11973 +#include <linux/in.h>
11974 +#include <linux/ip.h>
11975 +#include <linux/skbuff.h>
11976 +#include <linux/sysctl.h>
11977 +
11978 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
11979 +__inline__ void
11980 +pax_set_flags(struct linux_binprm *bprm)
11981 +{
11982 +       return;
11983 +}
11984 +#endif
11985 +
11986 +#ifdef CONFIG_SYSCTL
11987 +__inline__ __u32
11988 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
11989 +{
11990 +       return mode;
11991 +}
11992 +#endif
11993 +
11994 +__inline__ int
11995 +gr_acl_is_enabled(void)
11996 +{
11997 +       return 0;
11998 +}
11999 +
12000 +__inline__ int
12001 +gr_handle_rawio(const struct inode *inode)
12002 +{
12003 +       return 0;
12004 +}
12005 +
12006 +__inline__ void
12007 +gr_acl_handle_psacct(struct task_struct *task, const long code)
12008 +{
12009 +       return;
12010 +}
12011 +
12012 +__inline__ int
12013 +gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
12014 +{
12015 +       return 0;
12016 +}
12017 +
12018 +__inline__ int
12019 +gr_handle_mmap(const struct file *filp, const unsigned long prot)
12020 +{
12021 +       return 0;
12022 +}
12023 +
12024 +__inline__ int
12025 +gr_handle_ptrace(struct task_struct *task, const long request)
12026 +{
12027 +       return 0;
12028 +}
12029 +
12030 +__inline__ int
12031 +gr_handle_proc_ptrace(struct task_struct *task)
12032 +{
12033 +       return 0;
12034 +}
12035 +
12036 +__inline__ void
12037 +gr_learn_resource(const struct task_struct *task,
12038 +                 const int res, const unsigned long wanted, const int gt)
12039 +{
12040 +       return;
12041 +}
12042 +
12043 +__inline__ int
12044 +gr_set_acls(const int type)
12045 +{
12046 +       return 0;
12047 +}
12048 +
12049 +__inline__ int
12050 +gr_check_hidden_task(const struct task_struct *tsk)
12051 +{
12052 +       return 0;
12053 +}
12054 +
12055 +__inline__ int
12056 +gr_check_protected_task(const struct task_struct *task)
12057 +{
12058 +       return 0;
12059 +}
12060 +
12061 +__inline__ void
12062 +gr_copy_label(struct task_struct *tsk)
12063 +{
12064 +       return;
12065 +}
12066 +
12067 +__inline__ void
12068 +gr_set_pax_flags(struct task_struct *task)
12069 +{
12070 +       return;
12071 +}
12072 +
12073 +__inline__ void
12074 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
12075 +{
12076 +       return;
12077 +}
12078 +
12079 +__inline__ void
12080 +gr_handle_delete(const ino_t ino, const dev_t dev)
12081 +{
12082 +       return;
12083 +}
12084 +
12085 +__inline__ void
12086 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
12087 +{
12088 +       return;
12089 +}
12090 +
12091 +__inline__ void
12092 +gr_handle_crash(struct task_struct *task, const int sig)
12093 +{
12094 +       return;
12095 +}
12096 +
12097 +__inline__ int
12098 +gr_check_crash_exec(const struct file *filp)
12099 +{
12100 +       return 0;
12101 +}
12102 +
12103 +__inline__ int
12104 +gr_check_crash_uid(const uid_t uid)
12105 +{
12106 +       return 0;
12107 +}
12108 +
12109 +__inline__ void
12110 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
12111 +                struct dentry *old_dentry,
12112 +                struct dentry *new_dentry,
12113 +                struct vfsmount *mnt, const __u8 replace)
12114 +{
12115 +       return;
12116 +}
12117 +
12118 +__inline__ int
12119 +gr_search_socket(const int family, const int type, const int protocol)
12120 +{
12121 +       return 1;
12122 +}
12123 +
12124 +__inline__ int
12125 +gr_search_connectbind(const int mode, const struct socket *sock,
12126 +                     const struct sockaddr_in *addr)
12127 +{
12128 +       return 1;
12129 +}
12130 +
12131 +__inline__ int
12132 +gr_task_is_capable(struct task_struct *task, const int cap)
12133 +{
12134 +       return 1;
12135 +}
12136 +
12137 +__inline__ int
12138 +gr_is_capable_nolog(const int cap)
12139 +{
12140 +       return 1;
12141 +}
12142 +
12143 +__inline__ void
12144 +gr_handle_alertkill(void)
12145 +{
12146 +       return;
12147 +}
12148 +
12149 +__inline__ __u32
12150 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
12151 +{
12152 +       return 1;
12153 +}
12154 +
12155 +__inline__ __u32
12156 +gr_acl_handle_hidden_file(const struct dentry * dentry,
12157 +                         const struct vfsmount * mnt)
12158 +{
12159 +       return 1;
12160 +}
12161 +
12162 +__inline__ __u32
12163 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
12164 +                  const int fmode)
12165 +{
12166 +       return 1;
12167 +}
12168 +
12169 +__inline__ __u32
12170 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
12171 +{
12172 +       return 1;
12173 +}
12174 +
12175 +__inline__ __u32
12176 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
12177 +{
12178 +       return 1;
12179 +}
12180 +
12181 +__inline__ int
12182 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
12183 +                  unsigned int *vm_flags)
12184 +{
12185 +       return 1;
12186 +}
12187 +
12188 +__inline__ __u32
12189 +gr_acl_handle_truncate(const struct dentry * dentry,
12190 +                      const struct vfsmount * mnt)
12191 +{
12192 +       return 1;
12193 +}
12194 +
12195 +__inline__ __u32
12196 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
12197 +{
12198 +       return 1;
12199 +}
12200 +
12201 +__inline__ __u32
12202 +gr_acl_handle_access(const struct dentry * dentry,
12203 +                    const struct vfsmount * mnt, const int fmode)
12204 +{
12205 +       return 1;
12206 +}
12207 +
12208 +__inline__ __u32
12209 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
12210 +                    mode_t mode)
12211 +{
12212 +       return 1;
12213 +}
12214 +
12215 +__inline__ __u32
12216 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
12217 +                   mode_t mode)
12218 +{
12219 +       return 1;
12220 +}
12221 +
12222 +__inline__ __u32
12223 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
12224 +{
12225 +       return 1;
12226 +}
12227 +
12228 +__inline__ void
12229 +grsecurity_init(void)
12230 +{
12231 +       return;
12232 +}
12233 +
12234 +__inline__ __u32
12235 +gr_acl_handle_mknod(const struct dentry * new_dentry,
12236 +                   const struct dentry * parent_dentry,
12237 +                   const struct vfsmount * parent_mnt,
12238 +                   const int mode)
12239 +{
12240 +       return 1;
12241 +}
12242 +
12243 +__inline__ __u32
12244 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
12245 +                   const struct dentry * parent_dentry,
12246 +                   const struct vfsmount * parent_mnt)
12247 +{
12248 +       return 1;
12249 +}
12250 +
12251 +__inline__ __u32
12252 +gr_acl_handle_symlink(const struct dentry * new_dentry,
12253 +                     const struct dentry * parent_dentry,
12254 +                     const struct vfsmount * parent_mnt, const char *from)
12255 +{
12256 +       return 1;
12257 +}
12258 +
12259 +__inline__ __u32
12260 +gr_acl_handle_link(const struct dentry * new_dentry,
12261 +                  const struct dentry * parent_dentry,
12262 +                  const struct vfsmount * parent_mnt,
12263 +                  const struct dentry * old_dentry,
12264 +                  const struct vfsmount * old_mnt, const char *to)
12265 +{
12266 +       return 1;
12267 +}
12268 +
12269 +__inline__ int
12270 +gr_acl_handle_rename(const struct dentry *new_dentry,
12271 +                    const struct dentry *parent_dentry,
12272 +                    const struct vfsmount *parent_mnt,
12273 +                    const struct dentry *old_dentry,
12274 +                    const struct inode *old_parent_inode,
12275 +                    const struct vfsmount *old_mnt, const char *newname)
12276 +{
12277 +       return 0;
12278 +}
12279 +
12280 +__inline__ __u32
12281 +gr_acl_handle_filldir(const struct dentry * dentry,
12282 +                     const struct vfsmount * mnt, const ino_t ino)
12283 +{
12284 +       return 1;
12285 +}
12286 +
12287 +__inline__ int
12288 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
12289 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
12290 +{
12291 +       return 1;
12292 +}
12293 +
12294 +__inline__ int
12295 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
12296 +{
12297 +       return 1;
12298 +}
12299 +
12300 +__inline__ int
12301 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
12302 +{
12303 +       return 1;
12304 +}
12305 +
12306 +__inline__ __u32
12307 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
12308 +{
12309 +       return 1;
12310 +}
12311 +
12312 +__inline__ __u32
12313 +gr_acl_handle_creat(const struct dentry * dentry,
12314 +                   const struct dentry * p_dentry,
12315 +                   const struct vfsmount * p_mnt, const int fmode,
12316 +                   const int imode)
12317 +{
12318 +       return 1;
12319 +}
12320 +
12321 +__inline__ void
12322 +gr_acl_handle_exit(void)
12323 +{
12324 +       return;
12325 +}
12326 +
12327 +__inline__ int
12328 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
12329 +{
12330 +       return 1;
12331 +}
12332 +
12333 +__inline__ void
12334 +gr_set_role_label(const uid_t uid, const gid_t gid)
12335 +{
12336 +       return;
12337 +}
12338 +
12339 +__inline__ int
12340 +gr_acl_handle_procpidmem(const struct task_struct *task)
12341 +{
12342 +       return 0;
12343 +}
12344 +
12345 +__inline__ int
12346 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
12347 +{
12348 +       return 1;
12349 +}
12350 +
12351 +__inline__ int
12352 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
12353 +{
12354 +       return 1;
12355 +}
12356 +
12357 +__inline__ void
12358 +gr_set_kernel_label(struct task_struct *task)
12359 +{
12360 +       return;
12361 +}
12362 +
12363 +__inline__ int
12364 +gr_check_user_change(int real, int effective, int fs)
12365 +{
12366 +       return 0;
12367 +}
12368 +
12369 +__inline__ int
12370 +gr_check_group_change(int real, int effective, int fs)
12371 +{
12372 +       return 0;
12373 +}
12374 +
12375 +
12376 +EXPORT_SYMBOL(gr_task_is_capable);
12377 +EXPORT_SYMBOL(gr_learn_resource);
12378 +EXPORT_SYMBOL(gr_set_kernel_label);
12379 +
12380 diff -uNr linux-2.6.6/grsecurity/grsec_exec.c linux-2.6.6.fixed/grsecurity/grsec_exec.c
12381 --- linux-2.6.6/grsecurity/grsec_exec.c 1970-01-01 01:00:00.000000000 +0100
12382 +++ linux-2.6.6.fixed/grsecurity/grsec_exec.c   2004-05-11 10:55:56.000000000 +0200
12383 @@ -0,0 +1,71 @@
12384 +#include <linux/kernel.h>
12385 +#include <linux/sched.h>
12386 +#include <linux/file.h>
12387 +#include <linux/binfmts.h>
12388 +#include <linux/fs.h>
12389 +#include <linux/types.h>
12390 +#include <linux/grdefs.h>
12391 +#include <linux/grinternal.h>
12392 +#include <linux/capability.h>
12393 +
12394 +#include <asm/uaccess.h>
12395 +
12396 +int
12397 +gr_handle_nproc(void)
12398 +{
12399 +#ifdef CONFIG_GRKERNSEC_EXECVE
12400 +       if (grsec_enable_execve && current->user &&
12401 +           (atomic_read(&current->user->processes) >
12402 +            current->rlim[RLIMIT_NPROC].rlim_cur) &&
12403 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
12404 +               security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
12405 +               return -EAGAIN;
12406 +       }
12407 +#endif
12408 +       return 0;
12409 +}
12410 +
12411 +void
12412 +gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
12413 +{
12414 +#ifdef CONFIG_GRKERNSEC_EXECLOG
12415 +       char grarg[64] = { 0 };
12416 +       __u8 execlen = 0;
12417 +       unsigned int i;
12418 +
12419 +       if (!((grsec_enable_execlog && grsec_enable_group &&
12420 +              in_group_p(grsec_audit_gid))
12421 +             || (grsec_enable_execlog && !grsec_enable_group)))
12422 +               return;
12423 +
12424 +       if (unlikely(!argv))
12425 +               goto log;
12426 +
12427 +       for (i = 0; i < bprm->argc && execlen < 62; i++) {
12428 +               char *p;
12429 +               __u8 len;
12430 +
12431 +               if (get_user(p, argv + i))
12432 +                       goto log;
12433 +               if (!p)
12434 +                       goto log;
12435 +               len = strnlen_user(p, 62 - execlen);
12436 +               if (len > 62 - execlen)
12437 +                       len = 62 - execlen;
12438 +               else if (len > 0)
12439 +                       len--;
12440 +               if (copy_from_user(grarg + execlen, p, len))
12441 +                       goto log;
12442 +               execlen += len;
12443 +               *(grarg + execlen) = ' ';
12444 +               *(grarg + execlen + 1) = '\0';
12445 +               execlen++;
12446 +       }
12447 +
12448 +      log:
12449 +       security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
12450 +                                                        bprm->file->f_vfsmnt),
12451 +                      grarg, DEFAULTSECARGS);
12452 +#endif
12453 +       return;
12454 +}
12455 diff -uNr linux-2.6.6/grsecurity/grsec_fifo.c linux-2.6.6.fixed/grsecurity/grsec_fifo.c
12456 --- linux-2.6.6/grsecurity/grsec_fifo.c 1970-01-01 01:00:00.000000000 +0100
12457 +++ linux-2.6.6.fixed/grsecurity/grsec_fifo.c   2004-05-11 10:55:56.000000000 +0200
12458 @@ -0,0 +1,24 @@
12459 +#include <linux/kernel.h>
12460 +#include <linux/sched.h>
12461 +#include <linux/fs.h>
12462 +#include <linux/file.h>
12463 +#include <linux/grinternal.h>
12464 +
12465 +int
12466 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
12467 +              const struct dentry *dir, const int flag, const int acc_mode)
12468 +{
12469 +#ifdef CONFIG_GRKERNSEC_FIFO
12470 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
12471 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
12472 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
12473 +           (current->fsuid != dentry->d_inode->i_uid)) {
12474 +               if (!vfs_permission(dentry->d_inode, acc_mode))
12475 +                       security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
12476 +                                      dentry->d_inode->i_uid,
12477 +                                      dentry->d_inode->i_gid, DEFAULTSECARGS);
12478 +               return -EACCES;
12479 +       }
12480 +#endif
12481 +       return 0;
12482 +}
12483 diff -uNr linux-2.6.6/grsecurity/grsec_fork.c linux-2.6.6.fixed/grsecurity/grsec_fork.c
12484 --- linux-2.6.6/grsecurity/grsec_fork.c 1970-01-01 01:00:00.000000000 +0100
12485 +++ linux-2.6.6.fixed/grsecurity/grsec_fork.c   2004-05-11 10:55:56.000000000 +0200
12486 @@ -0,0 +1,14 @@
12487 +#include <linux/kernel.h>
12488 +#include <linux/sched.h>
12489 +#include <linux/grsecurity.h>
12490 +#include <linux/grinternal.h>
12491 +
12492 +void
12493 +gr_log_forkfail(const int retval)
12494 +{
12495 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
12496 +       if (grsec_enable_forkfail)
12497 +               security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
12498 +#endif
12499 +       return;
12500 +}
12501 diff -uNr linux-2.6.6/grsecurity/grsec_init.c linux-2.6.6.fixed/grsecurity/grsec_init.c
12502 --- linux-2.6.6/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100
12503 +++ linux-2.6.6.fixed/grsecurity/grsec_init.c   2004-05-11 10:55:56.000000000 +0200
12504 @@ -0,0 +1,227 @@
12505 +#include <linux/kernel.h>
12506 +#include <linux/sched.h>
12507 +#include <linux/mm.h>
12508 +#include <linux/smp_lock.h>
12509 +#include <linux/gracl.h>
12510 +#include <linux/slab.h>
12511 +#include <linux/vmalloc.h>
12512 +#include <linux/percpu.h>
12513 +
12514 +int grsec_enable_link;
12515 +int grsec_enable_dmesg;
12516 +int grsec_enable_fifo;
12517 +int grsec_enable_execve;
12518 +int grsec_enable_execlog;
12519 +int grsec_enable_signal;
12520 +int grsec_enable_forkfail;
12521 +int grsec_enable_time;
12522 +int grsec_enable_audit_textrel;
12523 +int grsec_enable_group;
12524 +int grsec_audit_gid;
12525 +int grsec_enable_chdir;
12526 +int grsec_enable_audit_ipc;
12527 +int grsec_enable_mount;
12528 +int grsec_enable_chroot_findtask;
12529 +int grsec_enable_chroot_mount;
12530 +int grsec_enable_chroot_shmat;
12531 +int grsec_enable_chroot_fchdir;
12532 +int grsec_enable_chroot_double;
12533 +int grsec_enable_chroot_pivot;
12534 +int grsec_enable_chroot_chdir;
12535 +int grsec_enable_chroot_chmod;
12536 +int grsec_enable_chroot_mknod;
12537 +int grsec_enable_chroot_nice;
12538 +int grsec_enable_chroot_execlog;
12539 +int grsec_enable_chroot_caps;
12540 +int grsec_enable_chroot_sysctl;
12541 +int grsec_enable_chroot_unix;
12542 +int grsec_enable_tpe;
12543 +int grsec_tpe_gid;
12544 +int grsec_enable_tpe_all;
12545 +int grsec_enable_randpid;
12546 +int grsec_enable_randid;
12547 +int grsec_enable_randisn;
12548 +int grsec_enable_randsrc;
12549 +int grsec_enable_randrpc;
12550 +int grsec_enable_socket_all;
12551 +int grsec_socket_all_gid;
12552 +int grsec_enable_socket_client;
12553 +int grsec_socket_client_gid;
12554 +int grsec_enable_socket_server;
12555 +int grsec_socket_server_gid;
12556 +int grsec_lock;
12557 +
12558 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
12559 +unsigned long grsec_alert_wtime = 0;
12560 +unsigned long grsec_alert_fyet = 0;
12561 +
12562 +spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
12563 +unsigned long grsec_alertgood_wtime = 0;
12564 +unsigned long grsec_alertgood_fyet = 0;
12565 +
12566 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
12567 +
12568 +char *gr_shared_page[4];
12569 +extern struct gr_arg *gr_usermode;
12570 +extern unsigned char *gr_system_salt;
12571 +extern unsigned char *gr_system_sum;
12572 +extern struct task_struct **gr_conn_table;
12573 +extern const unsigned int gr_conn_table_size;
12574 +
12575 +void
12576 +grsecurity_init(void)
12577 +{
12578 +       int j;
12579 +       /* create the per-cpu shared pages */
12580 +
12581 +       preempt_disable();
12582 +       for (j = 0; j < 4; j++) {
12583 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(char *));
12584 +               if (gr_shared_page[j] == NULL) {
12585 +                       panic("Unable to allocate grsecurity shared page");
12586 +                       return;
12587 +               }
12588 +       }
12589 +       preempt_enable();
12590 +
12591 +       /* create hash tables for ip tagging */
12592 +
12593 +       gr_conn_table = (struct task_struct **) vmalloc(gr_conn_table_size * sizeof(struct task_struct *));
12594 +       if (gr_conn_table == NULL) {
12595 +               panic("Unable to allocate grsecurity IP tagging table");
12596 +               return;
12597 +       }
12598 +       memset(gr_conn_table, 0, gr_conn_table_size * sizeof(struct task_struct *));
12599 +
12600 +       /* allocate memory for authentication structure */
12601 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
12602 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
12603 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
12604 +
12605 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
12606 +               panic("Unable to allocate grsecurity authentication structure");
12607 +               return;
12608 +       }
12609 +
12610 +#ifndef CONFIG_GRKERNSEC_SYSCTL
12611 +       grsec_lock = 1;
12612 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
12613 +       grsec_enable_audit_textrel = 1;
12614 +#endif
12615 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
12616 +       grsec_enable_group = 1;
12617 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
12618 +#endif
12619 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
12620 +       grsec_enable_chdir = 1;
12621 +#endif
12622 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12623 +       grsec_enable_audit_ipc = 1;
12624 +#endif
12625 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
12626 +       grsec_enable_mount = 1;
12627 +#endif
12628 +#ifdef CONFIG_GRKERNSEC_LINK
12629 +       grsec_enable_link = 1;
12630 +#endif
12631 +#ifdef CONFIG_GRKERNSEC_DMESG
12632 +       grsec_enable_dmesg = 1;
12633 +#endif
12634 +#ifdef CONFIG_GRKERNSEC_FIFO
12635 +       grsec_enable_fifo = 1;
12636 +#endif
12637 +#ifdef CONFIG_GRKERNSEC_EXECVE
12638 +       grsec_enable_execve = 1;
12639 +#endif
12640 +#ifdef CONFIG_GRKERNSEC_EXECLOG
12641 +       grsec_enable_execlog = 1;
12642 +#endif
12643 +#ifdef CONFIG_GRKERNSEC_SIGNAL
12644 +       grsec_enable_signal = 1;
12645 +#endif
12646 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
12647 +       grsec_enable_forkfail = 1;
12648 +#endif
12649 +#ifdef CONFIG_GRKERNSEC_TIME
12650 +       grsec_enable_time = 1;
12651 +#endif
12652 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
12653 +       grsec_enable_chroot_findtask = 1;
12654 +#endif
12655 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
12656 +       grsec_enable_chroot_unix = 1;
12657 +#endif
12658 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
12659 +       grsec_enable_chroot_mount = 1;
12660 +#endif
12661 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
12662 +       grsec_enable_chroot_fchdir = 1;
12663 +#endif
12664 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
12665 +       grsec_enable_chroot_shmat = 1;
12666 +#endif
12667 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
12668 +       grsec_enable_chroot_double = 1;
12669 +#endif
12670 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
12671 +       grsec_enable_chroot_pivot = 1;
12672 +#endif
12673 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
12674 +       grsec_enable_chroot_chdir = 1;
12675 +#endif
12676 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
12677 +       grsec_enable_chroot_chmod = 1;
12678 +#endif
12679 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
12680 +       grsec_enable_chroot_mknod = 1;
12681 +#endif
12682 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
12683 +       grsec_enable_chroot_nice = 1;
12684 +#endif
12685 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
12686 +       grsec_enable_chroot_execlog = 1;
12687 +#endif
12688 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12689 +       grsec_enable_chroot_caps = 1;
12690 +#endif
12691 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
12692 +       grsec_enable_chroot_sysctl = 1;
12693 +#endif
12694 +#ifdef CONFIG_GRKERNSEC_TPE
12695 +       grsec_enable_tpe = 1;
12696 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
12697 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
12698 +       grsec_enable_tpe_all = 1;
12699 +#endif
12700 +#endif
12701 +#ifdef CONFIG_GRKERNSEC_RANDPID
12702 +       grsec_enable_randpid = 1;
12703 +#endif
12704 +#ifdef CONFIG_GRKERNSEC_RANDID
12705 +       grsec_enable_randid = 1;
12706 +#endif
12707 +#ifdef CONFIG_GRKERNSEC_RANDISN
12708 +       grsec_enable_randisn = 1;
12709 +#endif
12710 +#ifdef CONFIG_GRKERNSEC_RANDSRC
12711 +       grsec_enable_randsrc = 1;
12712 +#endif
12713 +#ifdef CONFIG_GRKERNSEC_RANDRPC
12714 +       grsec_enable_randrpc = 1;
12715 +#endif
12716 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
12717 +       grsec_enable_socket_all = 1;
12718 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
12719 +#endif
12720 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
12721 +       grsec_enable_socket_client = 1;
12722 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
12723 +#endif
12724 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
12725 +       grsec_enable_socket_server = 1;
12726 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
12727 +#endif
12728 +#endif
12729 +
12730 +       return;
12731 +}
12732 diff -uNr linux-2.6.6/grsecurity/grsec_ipc.c linux-2.6.6.fixed/grsecurity/grsec_ipc.c
12733 --- linux-2.6.6/grsecurity/grsec_ipc.c  1970-01-01 01:00:00.000000000 +0100
12734 +++ linux-2.6.6.fixed/grsecurity/grsec_ipc.c    2004-05-11 10:55:56.000000000 +0200
12735 @@ -0,0 +1,81 @@
12736 +#include <linux/kernel.h>
12737 +#include <linux/sched.h>
12738 +#include <linux/types.h>
12739 +#include <linux/ipc.h>
12740 +#include <linux/grsecurity.h>
12741 +#include <linux/grinternal.h>
12742 +
12743 +void
12744 +gr_log_msgget(const int ret, const int msgflg)
12745 +{
12746 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12747 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12748 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
12749 +                                         !grsec_enable_group)) && (ret >= 0)
12750 +           && (msgflg & IPC_CREAT))
12751 +               security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
12752 +#endif
12753 +       return;
12754 +}
12755 +
12756 +void
12757 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
12758 +{
12759 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12760 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12761 +            grsec_enable_audit_ipc) ||
12762 +           (grsec_enable_audit_ipc && !grsec_enable_group))
12763 +               security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
12764 +#endif
12765 +       return;
12766 +}
12767 +
12768 +void
12769 +gr_log_semget(const int err, const int semflg)
12770 +{
12771 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12772 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12773 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
12774 +                                         !grsec_enable_group)) && (err >= 0)
12775 +           && (semflg & IPC_CREAT))
12776 +               security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
12777 +#endif
12778 +       return;
12779 +}
12780 +
12781 +void
12782 +gr_log_semrm(const uid_t uid, const uid_t cuid)
12783 +{
12784 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12785 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12786 +            grsec_enable_audit_ipc) ||
12787 +           (grsec_enable_audit_ipc && !grsec_enable_group))
12788 +               security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
12789 +#endif
12790 +       return;
12791 +}
12792 +
12793 +void
12794 +gr_log_shmget(const int err, const int shmflg, const size_t size)
12795 +{
12796 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12797 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12798 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
12799 +                                         !grsec_enable_group)) && (err >= 0)
12800 +           && (shmflg & IPC_CREAT))
12801 +               security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
12802 +#endif
12803 +       return;
12804 +}
12805 +
12806 +void
12807 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
12808 +{
12809 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
12810 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
12811 +            grsec_enable_audit_ipc) ||
12812 +           (grsec_enable_audit_ipc && !grsec_enable_group))
12813 +               security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
12814 +#endif
12815 +       return;
12816 +}
12817 diff -uNr linux-2.6.6/grsecurity/grsec_link.c linux-2.6.6.fixed/grsecurity/grsec_link.c
12818 --- linux-2.6.6/grsecurity/grsec_link.c 1970-01-01 01:00:00.000000000 +0100
12819 +++ linux-2.6.6.fixed/grsecurity/grsec_link.c   2004-05-11 10:55:56.000000000 +0200
12820 @@ -0,0 +1,41 @@
12821 +#include <linux/kernel.h>
12822 +#include <linux/sched.h>
12823 +#include <linux/fs.h>
12824 +#include <linux/file.h>
12825 +#include <linux/grinternal.h>
12826 +
12827 +int
12828 +gr_handle_follow_link(const struct inode *parent,
12829 +                     const struct inode *inode,
12830 +                     const struct dentry *dentry, const struct vfsmount *mnt)
12831 +{
12832 +#ifdef CONFIG_GRKERNSEC_LINK
12833 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
12834 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
12835 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
12836 +               security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
12837 +                              inode->i_uid, inode->i_gid, DEFAULTSECARGS);
12838 +               return -EACCES;
12839 +       }
12840 +#endif
12841 +       return 0;
12842 +}
12843 +
12844 +int
12845 +gr_handle_hardlink(const struct dentry *dentry,
12846 +                  const struct vfsmount *mnt,
12847 +                  struct inode *inode, const int mode, const char *to)
12848 +{
12849 +#ifdef CONFIG_GRKERNSEC_LINK
12850 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
12851 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
12852 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
12853 +            (vfs_permission(inode, MAY_READ | MAY_WRITE))) &&
12854 +           !capable(CAP_FOWNER) && current->uid) {
12855 +               security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
12856 +                              inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
12857 +               return -EPERM;
12858 +       }
12859 +#endif
12860 +       return 0;
12861 +}
12862 diff -uNr linux-2.6.6/grsecurity/grsec_mem.c linux-2.6.6.fixed/grsecurity/grsec_mem.c
12863 --- linux-2.6.6/grsecurity/grsec_mem.c  1970-01-01 01:00:00.000000000 +0100
12864 +++ linux-2.6.6.fixed/grsecurity/grsec_mem.c    2004-05-11 10:55:56.000000000 +0200
12865 @@ -0,0 +1,54 @@
12866 +#include <linux/kernel.h>
12867 +#include <linux/sched.h>
12868 +#include <linux/mm.h>
12869 +#include <linux/mman.h>
12870 +#include <linux/grinternal.h>
12871 +
12872 +void
12873 +gr_handle_ioperm(void)
12874 +{
12875 +       security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
12876 +       return;
12877 +}
12878 +
12879 +void
12880 +gr_handle_iopl(void)
12881 +{
12882 +       security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
12883 +       return;
12884 +}
12885 +
12886 +void
12887 +gr_handle_mem_write(void)
12888 +{
12889 +       security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
12890 +       return;
12891 +}
12892 +
12893 +void
12894 +gr_handle_kmem_write(void)
12895 +{
12896 +       security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
12897 +       return;
12898 +}
12899 +
12900 +void
12901 +gr_handle_open_port(void)
12902 +{
12903 +       security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
12904 +       return;
12905 +}
12906 +
12907 +int
12908 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
12909 +{
12910 +       if (offset < __pa(high_memory) && (vma->vm_flags & VM_WRITE) &&
12911 +           !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
12912 +           !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
12913 +               security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
12914 +               return -EPERM;
12915 +       } else if (offset < __pa(high_memory))
12916 +               vma->vm_flags &= ~VM_MAYWRITE;
12917 +
12918 +       return 0;
12919 +}
12920 diff -uNr linux-2.6.6/grsecurity/grsec_mount.c linux-2.6.6.fixed/grsecurity/grsec_mount.c
12921 --- linux-2.6.6/grsecurity/grsec_mount.c        1970-01-01 01:00:00.000000000 +0100
12922 +++ linux-2.6.6.fixed/grsecurity/grsec_mount.c  2004-05-11 10:55:56.000000000 +0200
12923 @@ -0,0 +1,34 @@
12924 +#include <linux/kernel.h>
12925 +#include <linux/sched.h>
12926 +#include <linux/grsecurity.h>
12927 +#include <linux/grinternal.h>
12928 +
12929 +void
12930 +gr_log_remount(const char *devname, const int retval)
12931 +{
12932 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
12933 +       if (grsec_enable_mount && (retval >= 0))
12934 +               security_audit(GR_REMOUNT_AUDIT_MSG, devname ? devname : "none", DEFAULTSECARGS);
12935 +#endif
12936 +       return;
12937 +}
12938 +
12939 +void
12940 +gr_log_unmount(const char *devname, const int retval)
12941 +{
12942 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
12943 +       if (grsec_enable_mount && (retval >= 0))
12944 +               security_audit(GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none", DEFAULTSECARGS);
12945 +#endif
12946 +       return;
12947 +}
12948 +
12949 +void
12950 +gr_log_mount(const char *from, const char *to, const int retval)
12951 +{
12952 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
12953 +       if (grsec_enable_mount && (retval >= 0))
12954 +               security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
12955 +#endif
12956 +       return;
12957 +}
12958 diff -uNr linux-2.6.6/grsecurity/grsec_rand.c linux-2.6.6.fixed/grsecurity/grsec_rand.c
12959 --- linux-2.6.6/grsecurity/grsec_rand.c 1970-01-01 01:00:00.000000000 +0100
12960 +++ linux-2.6.6.fixed/grsecurity/grsec_rand.c   2004-05-11 10:55:56.000000000 +0200
12961 @@ -0,0 +1,22 @@
12962 +#include <linux/kernel.h>
12963 +#include <linux/sched.h>
12964 +#include <linux/smp_lock.h>
12965 +#include <linux/grsecurity.h>
12966 +#include <linux/grinternal.h>
12967 +
12968 +extern int pid_max;
12969 +
12970 +int
12971 +gr_random_pid(void)
12972 +{
12973 +#ifdef CONFIG_GRKERNSEC_RANDPID
12974 +       int pid;
12975 +
12976 +       if (grsec_enable_randpid && current->fs->root) {
12977 +
12978 +               pid = 1 + (get_random_long() % pid_max);
12979 +               return pid;
12980 +       }
12981 +#endif
12982 +       return 0;
12983 +}
12984 diff -uNr linux-2.6.6/grsecurity/grsec_sig.c linux-2.6.6.fixed/grsecurity/grsec_sig.c
12985 --- linux-2.6.6/grsecurity/grsec_sig.c  1970-01-01 01:00:00.000000000 +0100
12986 +++ linux-2.6.6.fixed/grsecurity/grsec_sig.c    2004-05-11 10:55:56.000000000 +0200
12987 @@ -0,0 +1,48 @@
12988 +#include <linux/kernel.h>
12989 +#include <linux/sched.h>
12990 +#include <linux/grsecurity.h>
12991 +#include <linux/grinternal.h>
12992 +
12993 +void
12994 +gr_log_signal(const int sig, const struct task_struct *t)
12995 +{
12996 +#ifdef CONFIG_GRKERNSEC_SIGNAL
12997 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
12998 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
12999 +               if (t->pid == current->pid) {
13000 +                       security_alert_good(GR_UNISIGLOG_MSG, sig,
13001 +                                           DEFAULTSECARGS);
13002 +               } else {
13003 +                       security_alert_good(GR_DUALSIGLOG_MSG, sig,
13004 +                                           gr_task_fullpath0(t), t->comm,
13005 +                                           t->pid, t->uid, t->euid, t->gid,
13006 +                                           t->egid, gr_parent_task_fullpath0(t),
13007 +                                           t->parent->comm,
13008 +                                           t->parent->pid, t->parent->uid,
13009 +                                           t->parent->euid, t->parent->gid,
13010 +                                           t->parent->egid, DEFAULTSECARGS);
13011 +               }
13012 +       }
13013 +#endif
13014 +       return;
13015 +}
13016 +
13017 +int
13018 +gr_handle_signal(const struct task_struct *p, const int sig)
13019 +{
13020 +#ifdef CONFIG_GRKERNSEC
13021 +       if (current->pid > 1 && gr_check_protected_task(p)) {
13022 +               security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath0(p),
13023 +                              p->comm, p->pid, p->uid,
13024 +                              p->euid, p->gid, p->egid,
13025 +                              gr_parent_task_fullpath0(p), p->parent->comm,
13026 +                              p->parent->pid, p->parent->uid,
13027 +                              p->parent->euid, p->parent->gid,
13028 +                              p->parent->egid, DEFAULTSECARGS);
13029 +               return -EPERM;
13030 +       } else if (gr_pid_is_chrooted(p)) {
13031 +               return -EPERM;
13032 +       }
13033 +#endif
13034 +       return 0;
13035 +}
13036 diff -uNr linux-2.6.6/grsecurity/grsec_sock.c linux-2.6.6.fixed/grsecurity/grsec_sock.c
13037 --- linux-2.6.6/grsecurity/grsec_sock.c 1970-01-01 01:00:00.000000000 +0100
13038 +++ linux-2.6.6.fixed/grsecurity/grsec_sock.c   2004-05-11 10:55:56.000000000 +0200
13039 @@ -0,0 +1,255 @@
13040 +#include <linux/kernel.h>
13041 +#include <linux/module.h>
13042 +#include <linux/sched.h>
13043 +#include <linux/file.h>
13044 +#include <linux/net.h>
13045 +#include <linux/in.h>
13046 +#include <linux/ip.h>
13047 +#include <net/sock.h>
13048 +#include <linux/grsecurity.h>
13049 +#include <linux/grinternal.h>
13050 +#include <linux/gracl.h>
13051 +
13052 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
13053 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
13054 +#endif
13055 +#if defined(CONFIG_GRKERNSEC_RANDID)
13056 +EXPORT_SYMBOL(ip_randomid);
13057 +#endif
13058 +#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
13059 +EXPORT_SYMBOL(get_random_long);
13060 +#endif
13061 +#ifdef CONFIG_GRKERNSEC_RANDISN
13062 +EXPORT_SYMBOL(ip_randomisn);
13063 +EXPORT_SYMBOL(grsec_enable_randisn);
13064 +#endif
13065 +#ifdef CONFIG_GRKERNSEC_RANDID
13066 +EXPORT_SYMBOL(grsec_enable_randid);
13067 +#endif
13068 +#ifdef CONFIG_GRKERNSEC_RANDSRC
13069 +EXPORT_SYMBOL(grsec_enable_randsrc);
13070 +#endif
13071 +#ifdef CONFIG_GRKERNSEC_RANDRPC
13072 +EXPORT_SYMBOL(grsec_enable_randrpc);
13073 +#endif
13074 +
13075 +EXPORT_SYMBOL(gr_cap_rtnetlink);
13076 +
13077 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
13078 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
13079 +
13080 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
13081 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
13082 +
13083 +#ifdef CONFIG_UNIX_MODULE
13084 +EXPORT_SYMBOL(gr_acl_handle_unix);
13085 +EXPORT_SYMBOL(gr_acl_handle_mknod);
13086 +EXPORT_SYMBOL(gr_handle_chroot_unix);
13087 +EXPORT_SYMBOL(gr_handle_create);
13088 +#endif
13089 +
13090 +#ifdef CONFIG_GRKERNSEC
13091 +struct task_struct **gr_conn_table;
13092 +const unsigned int gr_conn_table_size = 65521;
13093 +struct task_struct *deleted_conn = (struct task_struct *)~0;
13094 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
13095 +
13096 +extern __inline__ const char * gr_socktype_to_name(unsigned char type);
13097 +extern __inline__ const char * gr_proto_to_name(unsigned char proto);
13098 +
13099 +static __inline__ int 
13100 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
13101 +{
13102 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
13103 +}
13104 +
13105 +static __inline__ int
13106 +conn_match(const struct task_struct *task, __u32 saddr, __u32 daddr, 
13107 +          __u16 sport, __u16 dport)
13108 +{
13109 +       if (unlikely(task != deleted_conn && task->gr_saddr == saddr && 
13110 +                    task->gr_daddr == daddr && task->gr_sport == sport &&
13111 +                    task->gr_dport == dport))
13112 +               return 1;
13113 +       else
13114 +               return 0;
13115 +}
13116 +
13117 +void gr_add_to_task_ip_table(struct task_struct *task)
13118 +{
13119 +       unsigned int index;
13120 +
13121 +       if (unlikely(gr_conn_table == NULL))
13122 +               return;
13123 +
13124 +       if (!thread_group_leader(task))
13125 +               task = task->group_leader;
13126 +
13127 +       index = conn_hash(task->gr_saddr, task->gr_daddr, 
13128 +                         task->gr_sport, task->gr_dport, 
13129 +                         gr_conn_table_size);
13130 +
13131 +       spin_lock(&gr_conn_table_lock);
13132 +
13133 +       while (gr_conn_table[index] && gr_conn_table[index] != deleted_conn) {
13134 +               index = (index + 1) % gr_conn_table_size;
13135 +       }
13136 +
13137 +       gr_conn_table[index] = task;
13138 +
13139 +       spin_unlock(&gr_conn_table_lock);
13140 +
13141 +       return;
13142 +}
13143 +
13144 +void gr_del_task_from_ip_table_nolock(struct task_struct *task)
13145 +{
13146 +       unsigned int index;
13147 +
13148 +       if (unlikely(gr_conn_table == NULL))
13149 +               return;
13150 +
13151 +       if (!thread_group_leader(task))
13152 +               task = task->group_leader;
13153 +
13154 +       index = conn_hash(task->gr_saddr, task->gr_daddr, 
13155 +                         task->gr_sport, task->gr_dport, 
13156 +                         gr_conn_table_size);
13157 +
13158 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
13159 +               task->gr_saddr, task->gr_daddr, task->gr_sport, 
13160 +               task->gr_dport)) {
13161 +               index = (index + 1) % gr_conn_table_size;
13162 +       }
13163 +
13164 +       if (gr_conn_table[index]) {
13165 +               if (gr_conn_table[(index + 1) % gr_conn_table_size])
13166 +                       gr_conn_table[index] = deleted_conn;
13167 +               else
13168 +                       gr_conn_table[index] = NULL;
13169 +       }
13170 +
13171 +       return;
13172 +}
13173 +
13174 +struct task_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
13175 +                                            __u16 sport, __u16 dport)
13176 +{
13177 +       unsigned int index;
13178 +
13179 +       if (unlikely(gr_conn_table == NULL))
13180 +               return NULL;
13181 +
13182 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
13183 +
13184 +       while (gr_conn_table[index] && !conn_match(gr_conn_table[index], 
13185 +               saddr, daddr, sport, dport)) {
13186 +               index = (index + 1) % gr_conn_table_size;
13187 +       }
13188 +
13189 +       return gr_conn_table[index];
13190 +}
13191 +
13192 +#endif
13193 +
13194 +void gr_del_task_from_ip_table(struct task_struct *task)
13195 +{
13196 +#ifdef CONFIG_GRKERNSEC
13197 +       spin_lock(&gr_conn_table_lock);
13198 +       if (!thread_group_leader(task))
13199 +               gr_del_task_from_ip_table_nolock(task->group_leader);
13200 +       else
13201 +               gr_del_task_from_ip_table_nolock(task);
13202 +       spin_unlock(&gr_conn_table_lock);
13203 +#endif
13204 +       return;
13205 +}
13206 +
13207 +void
13208 +gr_attach_curr_ip(const struct sock *sk)
13209 +{
13210 +#ifdef CONFIG_GRKERNSEC
13211 +       struct task_struct *p;
13212 +       struct task_struct *set;
13213 +       const struct inet_opt *inet = inet_sk(sk);      
13214 +
13215 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
13216 +               return;
13217 +
13218 +       set = current;
13219 +       if (!thread_group_leader(set))
13220 +               set = set->group_leader;
13221 +
13222 +       spin_lock(&gr_conn_table_lock);
13223 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
13224 +                                   inet->dport, inet->sport);
13225 +       if (unlikely(p != NULL)) {
13226 +               set->curr_ip = p->curr_ip;
13227 +               set->used_accept = 1;
13228 +               gr_del_task_from_ip_table_nolock(p);
13229 +               spin_unlock(&gr_conn_table_lock);
13230 +               return;
13231 +       }
13232 +       spin_unlock(&gr_conn_table_lock);
13233 +
13234 +       set->curr_ip = inet->daddr;
13235 +       set->used_accept = 1;
13236 +#endif
13237 +       return;
13238 +}
13239 +
13240 +int
13241 +gr_handle_sock_all(const int family, const int type, const int protocol)
13242 +{
13243 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13244 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
13245 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
13246 +               security_alert(GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol),
13247 +                              DEFAULTSECARGS);
13248 +               return -EACCES;
13249 +       }
13250 +#endif
13251 +       return 0;
13252 +}
13253 +
13254 +int
13255 +gr_handle_sock_server(const struct sockaddr *sck)
13256 +{
13257 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13258 +       if (grsec_enable_socket_server &&
13259 +           in_group_p(grsec_socket_server_gid) &&
13260 +           sck && (sck->sa_family != AF_UNIX) &&
13261 +           (sck->sa_family != AF_LOCAL)) {
13262 +               security_alert(GR_BIND_MSG, DEFAULTSECARGS);
13263 +               return -EACCES;
13264 +       }
13265 +#endif
13266 +       return 0;
13267 +}
13268 +
13269 +int
13270 +gr_handle_sock_client(const struct sockaddr *sck)
13271 +{
13272 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13273 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
13274 +           sck && (sck->sa_family != AF_UNIX) &&
13275 +           (sck->sa_family != AF_LOCAL)) {
13276 +               security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
13277 +               return -EACCES;
13278 +       }
13279 +#endif
13280 +       return 0;
13281 +}
13282 +
13283 +__u32
13284 +gr_cap_rtnetlink(void)
13285 +{
13286 +#ifdef CONFIG_GRKERNSEC
13287 +       if (!gr_acl_is_enabled())
13288 +               return current->cap_effective;
13289 +       else
13290 +               return (current->cap_effective & ~(current->acl->cap_lower));
13291 +#else
13292 +       return current->cap_effective;
13293 +#endif
13294 +}
13295 diff -uNr linux-2.6.6/grsecurity/grsec_sysctl.c linux-2.6.6.fixed/grsecurity/grsec_sysctl.c
13296 --- linux-2.6.6/grsecurity/grsec_sysctl.c       1970-01-01 01:00:00.000000000 +0100
13297 +++ linux-2.6.6.fixed/grsecurity/grsec_sysctl.c 2004-05-11 10:55:56.000000000 +0200
13298 @@ -0,0 +1,453 @@
13299 +#include <linux/kernel.h>
13300 +#include <linux/sched.h>
13301 +#include <linux/sysctl.h>
13302 +#include <linux/grsecurity.h>
13303 +#include <linux/grinternal.h>
13304 +
13305 +int
13306 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
13307 +{
13308 +#ifdef CONFIG_GRKERNSEC_SYSCTL
13309 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
13310 +               security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
13311 +               return -EACCES;
13312 +       }
13313 +#endif
13314 +       return 0;
13315 +}
13316 +
13317 +#ifdef CONFIG_GRKERNSEC_SYSCTL
13318 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
13319 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
13320 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
13321 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
13322 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
13323 +GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
13324 +GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
13325 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS,
13326 +GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
13327 +GS_TEXTREL, GS_FINDTASK, GS_LOCK};
13328 +
13329 +
13330 +ctl_table grsecurity_table[] = {
13331 +#ifdef CONFIG_GRKERNSEC_LINK
13332 +       {
13333 +               .ctl_name       = GS_LINK,
13334 +               .procname       = "linking_restrictions",
13335 +               .data           = &grsec_enable_link,
13336 +               .maxlen         = sizeof(int),
13337 +               .mode           = 0600,
13338 +               .proc_handler   = &proc_dointvec,
13339 +       },
13340 +#endif
13341 +#ifdef CONFIG_GRKERNSEC_FIFO
13342 +       {
13343 +               .ctl_name       = GS_FIFO,
13344 +               .procname       = "fifo_restrictions",
13345 +               .data           = &grsec_enable_fifo,
13346 +               .maxlen         = sizeof(int),
13347 +               .mode           = 0600,
13348 +               .proc_handler   = &proc_dointvec,
13349 +       },
13350 +#endif
13351 +#ifdef CONFIG_GRKERNSEC_EXECVE
13352 +       {
13353 +               .ctl_name       = GS_EXECVE,
13354 +               .procname       = "execve_limiting",
13355 +               .data           = &grsec_enable_execve,
13356 +               .maxlen         = sizeof(int),
13357 +               .mode           = 0600,
13358 +               .proc_handler   = &proc_dointvec,
13359 +       },
13360 +#endif
13361 +#ifdef CONFIG_GRKERNSEC_EXECLOG
13362 +       {
13363 +               .ctl_name       = GS_EXECLOG,
13364 +               .procname       = "exec_logging",
13365 +               .data           = &grsec_enable_execlog,
13366 +               .maxlen         = sizeof(int),
13367 +               .mode           = 0600,
13368 +               .proc_handler   = &proc_dointvec,
13369 +       },
13370 +#endif
13371 +#ifdef CONFIG_GRKERNSEC_SIGNAL
13372 +       {
13373 +               .ctl_name       = GS_SIGNAL,
13374 +               .procname       = "signal_logging",
13375 +               .data           = &grsec_enable_signal,
13376 +               .maxlen         = sizeof(int),
13377 +               .mode           = 0600,
13378 +               .proc_handler   = &proc_dointvec,
13379 +       },
13380 +#endif
13381 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
13382 +       {
13383 +               .ctl_name       = GS_FORKFAIL,
13384 +               .procname       = "forkfail_logging",
13385 +               .data           = &grsec_enable_forkfail,
13386 +               .maxlen         = sizeof(int),
13387 +               .mode           = 0600,
13388 +               .proc_handler   = &proc_dointvec,
13389 +       },
13390 +#endif
13391 +#ifdef CONFIG_GRKERNSEC_TIME
13392 +       {
13393 +               .ctl_name       = GS_TIME,
13394 +               .procname       = "timechange_logging",
13395 +               .data           = &grsec_enable_time,
13396 +               .maxlen         = sizeof(int),
13397 +               .mode           = 0600,
13398 +               .proc_handler   = &proc_dointvec,
13399 +       },
13400 +#endif
13401 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
13402 +       {
13403 +               .ctl_name       = GS_CHROOT_SHMAT,
13404 +               .procname       = "chroot_deny_shmat",
13405 +               .data           = &grsec_enable_chroot_shmat,
13406 +               .maxlen         = sizeof(int),
13407 +               .mode           = 0600,
13408 +               .proc_handler   = &proc_dointvec,
13409 +       },
13410 +#endif
13411 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
13412 +       {
13413 +               .ctl_name       = GS_CHROOT_UNIX,
13414 +               .procname       = "chroot_deny_unix",
13415 +               .data           = &grsec_enable_chroot_unix,
13416 +               .maxlen         = sizeof(int),
13417 +               .mode           = 0600,
13418 +               .proc_handler   = &proc_dointvec,
13419 +       },
13420 +#endif
13421 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
13422 +       {
13423 +               .ctl_name       = GS_CHROOT_MNT,
13424 +               .procname       = "chroot_deny_mount",
13425 +               .data           = &grsec_enable_chroot_mount,
13426 +               .maxlen         = sizeof(int),
13427 +               .mode           = 0600,
13428 +               .proc_handler   = &proc_dointvec,
13429 +       },
13430 +#endif
13431 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
13432 +       {
13433 +               .ctl_name       = GS_CHROOT_FCHDIR,
13434 +               .procname       = "chroot_deny_fchdir",
13435 +               .data           = &grsec_enable_chroot_fchdir,
13436 +               .maxlen         = sizeof(int),
13437 +               .mode           = 0600,
13438 +               .proc_handler   = &proc_dointvec,
13439 +       },
13440 +#endif
13441 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
13442 +       {
13443 +               .ctl_name       = GS_CHROOT_DBL,
13444 +               .procname       = "chroot_deny_chroot",
13445 +               .data           = &grsec_enable_chroot_double,
13446 +               .maxlen         = sizeof(int),
13447 +               .mode           = 0600,
13448 +               .proc_handler   = &proc_dointvec,
13449 +       },
13450 +#endif
13451 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
13452 +       {
13453 +               .ctl_name       = GS_CHROOT_PVT,
13454 +               .procname       = "chroot_deny_pivot",
13455 +               .data           = &grsec_enable_chroot_pivot,
13456 +               .maxlen         = sizeof(int),
13457 +               .mode           = 0600,
13458 +               .proc_handler   = &proc_dointvec,
13459 +       },
13460 +#endif
13461 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
13462 +       {
13463 +               .ctl_name       = GS_CHROOT_CD,
13464 +               .procname       = "chroot_enforce_chdir",
13465 +               .data           = &grsec_enable_chroot_chdir,
13466 +               .maxlen         = sizeof(int),
13467 +               .mode           = 0600,
13468 +               .proc_handler   = &proc_dointvec,
13469 +       },
13470 +#endif
13471 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
13472 +       {
13473 +               .ctl_name       = GS_CHROOT_CM,
13474 +               .procname       = "chroot_deny_chmod",
13475 +               .data           = &grsec_enable_chroot_chmod,
13476 +               .maxlen         = sizeof(int),
13477 +               .mode           = 0600,
13478 +               .proc_handler   = &proc_dointvec,
13479 +       },
13480 +#endif
13481 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
13482 +       {
13483 +               .ctl_name       = GS_CHROOT_MK,
13484 +               .procname       = "chroot_deny_mknod",
13485 +               .data           = &grsec_enable_chroot_mknod,
13486 +               .maxlen         = sizeof(int),
13487 +               .mode           = 0600,
13488 +               .proc_handler   = &proc_dointvec,
13489 +       },
13490 +#endif
13491 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
13492 +       {
13493 +               .ctl_name       = GS_CHROOT_NI,
13494 +               .procname       = "chroot_restrict_nice",
13495 +               .data           = &grsec_enable_chroot_nice,
13496 +               .maxlen         = sizeof(int),
13497 +               .mode           = 0600,
13498 +               .proc_handler   = &proc_dointvec,
13499 +       },
13500 +#endif
13501 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
13502 +       {
13503 +               .ctl_name       = GS_CHROOT_EXECLOG,
13504 +               .procname       = "chroot_execlog",
13505 +               .data           = &grsec_enable_chroot_execlog,
13506 +               .maxlen         = sizeof(int),
13507 +               .mode           = 0600,
13508 +               .proc_handler   = &proc_dointvec,
13509 +       },
13510 +#endif
13511 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
13512 +       {
13513 +               .ctl_name       = GS_CHROOT_CAPS,
13514 +               .procname       = "chroot_caps",
13515 +               .data           = &grsec_enable_chroot_caps,
13516 +               .maxlen         = sizeof(int),
13517 +               .mode           = 0600,
13518 +               .proc_handler   = &proc_dointvec,
13519 +       },
13520 +#endif
13521 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
13522 +       {
13523 +               .ctl_name       = GS_CHROOT_SYSCTL,
13524 +               .procname       = "chroot_deny_sysctl",
13525 +               .data           = &grsec_enable_chroot_sysctl,
13526 +               .maxlen         = sizeof(int),
13527 +               .mode           = 0600,
13528 +               .proc_handler   = &proc_dointvec,
13529 +       },
13530 +#endif
13531 +#ifdef CONFIG_GRKERNSEC_TPE
13532 +       {
13533 +               .ctl_name       = GS_TPE,
13534 +               .procname       = "tpe",
13535 +               .data           = &grsec_enable_tpe,
13536 +               .maxlen         = sizeof(int),
13537 +               .mode           = 0600,
13538 +               .proc_handler   = &proc_dointvec,
13539 +       },
13540 +       {
13541 +               .ctl_name       = GS_TPE_GID,
13542 +               .procname       = "tpe_gid",
13543 +               .data           = &grsec_tpe_gid,
13544 +               .maxlen         = sizeof(int),
13545 +               .mode           = 0600,
13546 +               .proc_handler   = &proc_dointvec,
13547 +       },
13548 +#endif
13549 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
13550 +       {
13551 +               .ctl_name       = GS_TPE_ALL,
13552 +               .procname       = "tpe_restrict_all",
13553 +               .data           = &grsec_enable_tpe_all,
13554 +               .maxlen         = sizeof(int),
13555 +               .mode           = 0600,
13556 +               .proc_handler   = &proc_dointvec,
13557 +       },
13558 +#endif
13559 +#ifdef CONFIG_GRKERNSEC_RANDPID
13560 +       {
13561 +               .ctl_name       = GS_RANDPID,
13562 +               .procname       = "rand_pids",
13563 +               .data           = &grsec_enable_randpid,
13564 +               .maxlen         = sizeof(int),
13565 +               .mode           = 0600,
13566 +               .proc_handler   = &proc_dointvec,
13567 +       },
13568 +#endif
13569 +#ifdef CONFIG_GRKERNSEC_RANDID
13570 +       {
13571 +               .ctl_name       = GS_RANDID,
13572 +               .procname       = "rand_ip_ids",
13573 +               .data           = &grsec_enable_randid,
13574 +               .maxlen         = sizeof(int),
13575 +               .mode           = 0600,
13576 +               .proc_handler   = &proc_dointvec,
13577 +       },
13578 +#endif
13579 +#ifdef CONFIG_GRKERNSEC_RANDSRC
13580 +       {
13581 +               .ctl_name       = GS_RANDSRC,
13582 +               .procname       = "rand_tcp_src_ports",
13583 +               .data           = &grsec_enable_randsrc,
13584 +               .maxlen         = sizeof(int),
13585 +               .mode           = 0600,
13586 +               .proc_handler   = &proc_dointvec,
13587 +       },
13588 +#endif
13589 +#ifdef CONFIG_GRKERNSEC_RANDISN
13590 +       {
13591 +               .ctl_name       = GS_RANDISN,
13592 +               .procname       = "rand_isns",
13593 +               .data           = &grsec_enable_randisn,
13594 +               .maxlen         = sizeof(int),
13595 +               .mode           = 0600,
13596 +               .proc_handler   = &proc_dointvec,
13597 +       },
13598 +#endif
13599 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
13600 +       {
13601 +               .ctl_name       = GS_SOCKET_ALL,
13602 +               .procname       = "socket_all",
13603 +               .data           = &grsec_enable_socket_all,
13604 +               .maxlen         = sizeof(int),
13605 +               .mode           = 0600,
13606 +               .proc_handler   = &proc_dointvec,
13607 +       },
13608 +       {
13609 +               .ctl_name       = GS_SOCKET_ALL_GID,
13610 +               .procname       = "socket_all_gid",
13611 +               .data           = &grsec_socket_all_gid,
13612 +               .maxlen         = sizeof(int),
13613 +               .mode           = 0600,
13614 +               .proc_handler   = &proc_dointvec,
13615 +       },
13616 +#endif
13617 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
13618 +       {
13619 +               .ctl_name       = GS_SOCKET_CLIENT,
13620 +               .procname       = "socket_client",
13621 +               .data           = &grsec_enable_socket_client,
13622 +               .maxlen         = sizeof(int),
13623 +               .mode           = 0600,
13624 +               .proc_handler   = &proc_dointvec,
13625 +       },
13626 +       {
13627 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
13628 +               .procname       = "socket_client_gid",
13629 +               .data           = &grsec_socket_client_gid,
13630 +               .maxlen         = sizeof(int),
13631 +               .mode           = 0600,
13632 +               .proc_handler   = &proc_dointvec,
13633 +       },
13634 +#endif
13635 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
13636 +       {
13637 +               .ctl_name       = GS_SOCKET_SERVER,
13638 +               .procname       = "socket_server",
13639 +               .data           = &grsec_enable_socket_server,
13640 +               .maxlen         = sizeof(int),
13641 +               .mode           = 0600,
13642 +               .proc_handler   = &proc_dointvec,
13643 +       },
13644 +       {
13645 +               .ctl_name       = GS_SOCKET_SERVER_GID,
13646 +               .procname       = "socket_server_gid",
13647 +               .data           = &grsec_socket_server_gid,
13648 +               .maxlen         = sizeof(int),
13649 +               .mode           = 0600,
13650 +               .proc_handler   = &proc_dointvec,
13651 +       },
13652 +#endif
13653 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
13654 +       {
13655 +               .ctl_name       = GS_GROUP,
13656 +               .procname       = "audit_group",
13657 +               .data           = &grsec_enable_group,
13658 +               .maxlen         = sizeof(int),
13659 +               .mode           = 0600,
13660 +               .proc_handler   = &proc_dointvec,
13661 +       },
13662 +       {
13663 +               .ctl_name       = GS_GID,
13664 +               .procname       = "audit_gid",
13665 +               .data           = &grsec_audit_gid,
13666 +               .maxlen         = sizeof(int),
13667 +               .mode           = 0600,
13668 +               .proc_handler   = &proc_dointvec,
13669 +       },
13670 +#endif
13671 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
13672 +       {
13673 +               .ctl_name       = GS_ACHDIR,
13674 +               .procname       = "audit_chdir",
13675 +               .data           = &grsec_enable_chdir,
13676 +               .maxlen         = sizeof(int),
13677 +               .mode           = 0600,
13678 +               .proc_handler   = &proc_dointvec,
13679 +       },
13680 +#endif
13681 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
13682 +       {
13683 +               .ctl_name       = GS_AMOUNT,
13684 +               .procname       = "audit_mount",
13685 +               .data           = &grsec_enable_mount,
13686 +               .maxlen         = sizeof(int),
13687 +               .mode           = 0600,
13688 +               .proc_handler   = &proc_dointvec,
13689 +       },
13690 +#endif
13691 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
13692 +       {
13693 +               .ctl_name       = GS_AIPC,
13694 +               .procname       = "audit_ipc",
13695 +               .data           = &grsec_enable_audit_ipc,
13696 +               .maxlen         = sizeof(int),
13697 +               .mode           = 0600,
13698 +               .proc_handler   = &proc_dointvec,
13699 +       },
13700 +#endif
13701 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
13702 +       {
13703 +               .ctl_name       = GS_TEXTREL,
13704 +               .procname       = "audit_textrel",
13705 +               .data           = &grsec_enable_audit_textrel,
13706 +               .maxlen         = sizeof(int),
13707 +               .mode           = 0600,
13708 +               .proc_handler   = &proc_dointvec,
13709 +       },
13710 +#endif
13711 +#ifdef CONFIG_GRKERNSEC_DMESG
13712 +       {
13713 +               .ctl_name       = GS_DMSG,
13714 +               .procname       = "dmesg",
13715 +               .data           = &grsec_enable_dmesg,
13716 +               .maxlen         = sizeof(int),
13717 +               .mode           = 0600,
13718 +               .proc_handler   = &proc_dointvec,
13719 +       },
13720 +#endif
13721 +#ifdef CONFIG_GRKERNSEC_RANDRPC
13722 +       {
13723 +               .ctl_name       = GS_RANDRPC,
13724 +               .procname       = "rand_rpc",
13725 +               .data           = &grsec_enable_randrpc,
13726 +               .maxlen         = sizeof(int),
13727 +               .mode           = 0600,
13728 +               .proc_handler   = &proc_dointvec,
13729 +       },
13730 +#endif
13731 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
13732 +       {
13733 +               .ctl_name       = GS_FINDTASK,
13734 +               .procname       = "chroot_findtask",
13735 +               .data           = &grsec_enable_chroot_findtask,
13736 +               .maxlen         = sizeof(int),
13737 +               .mode           = 0600,
13738 +               .proc_handler   = &proc_dointvec,
13739 +       },
13740 +#endif
13741 +       {
13742 +               .ctl_name       = GS_LOCK,
13743 +               .procname       = "grsec_lock",
13744 +               .data           = &grsec_lock,
13745 +               .maxlen         = sizeof(int),
13746 +               .mode           = 0600,
13747 +               .proc_handler   = &proc_dointvec,
13748 +       },
13749 +       { .ctl_name = 0 }
13750 +};
13751 +#endif
13752 diff -uNr linux-2.6.6/grsecurity/grsec_textrel.c linux-2.6.6.fixed/grsecurity/grsec_textrel.c
13753 --- linux-2.6.6/grsecurity/grsec_textrel.c      1970-01-01 01:00:00.000000000 +0100
13754 +++ linux-2.6.6.fixed/grsecurity/grsec_textrel.c        2004-05-11 10:55:56.000000000 +0200
13755 @@ -0,0 +1,19 @@
13756 +#include <linux/kernel.h>
13757 +#include <linux/sched.h>
13758 +#include <linux/mm.h>
13759 +#include <linux/file.h>
13760 +#include <linux/grinternal.h>
13761 +#include <linux/grsecurity.h>
13762 +
13763 +void
13764 +gr_log_textrel(struct vm_area_struct * vma)
13765 +{
13766 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
13767 +       if (grsec_enable_audit_textrel)
13768 +               security_audit(GR_TEXTREL_AUDIT_MSG, vma->vm_file ? 
13769 +                               gr_to_filename(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt)
13770 +                               : "<anonymous mapping>", vma->vm_start, 
13771 +                               vma->vm_pgoff, DEFAULTSECARGS);
13772 +#endif
13773 +       return;
13774 +}
13775 diff -uNr linux-2.6.6/grsecurity/grsec_time.c linux-2.6.6.fixed/grsecurity/grsec_time.c
13776 --- linux-2.6.6/grsecurity/grsec_time.c 1970-01-01 01:00:00.000000000 +0100
13777 +++ linux-2.6.6.fixed/grsecurity/grsec_time.c   2004-05-11 10:55:56.000000000 +0200
13778 @@ -0,0 +1,13 @@
13779 +#include <linux/kernel.h>
13780 +#include <linux/sched.h>
13781 +#include <linux/grinternal.h>
13782 +
13783 +void
13784 +gr_log_timechange(void)
13785 +{
13786 +#ifdef CONFIG_GRKERNSEC_TIME
13787 +       if (grsec_enable_time)
13788 +               security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
13789 +#endif
13790 +       return;
13791 +}
13792 diff -uNr linux-2.6.6/grsecurity/grsec_tpe.c linux-2.6.6.fixed/grsecurity/grsec_tpe.c
13793 --- linux-2.6.6/grsecurity/grsec_tpe.c  1970-01-01 01:00:00.000000000 +0100
13794 +++ linux-2.6.6.fixed/grsecurity/grsec_tpe.c    2004-05-11 10:55:56.000000000 +0200
13795 @@ -0,0 +1,35 @@
13796 +#include <linux/kernel.h>
13797 +#include <linux/sched.h>
13798 +#include <linux/file.h>
13799 +#include <linux/fs.h>
13800 +#include <linux/grinternal.h>
13801 +
13802 +extern int gr_acl_tpe_check(void);
13803 +
13804 +int
13805 +gr_tpe_allow(const struct file *file)
13806 +{
13807 +#ifdef CONFIG_GRKERNSEC
13808 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
13809 +
13810 +       if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
13811 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
13812 +                                               (inode->i_mode & S_IWOTH))))) {
13813 +               security_alert(GR_EXEC_TPE_MSG,
13814 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
13815 +                              DEFAULTSECARGS);
13816 +               return 0;
13817 +       }
13818 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
13819 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
13820 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
13821 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
13822 +               security_alert(GR_EXEC_TPE_MSG,
13823 +                              gr_to_filename(file->f_dentry, file->f_vfsmnt),
13824 +                              DEFAULTSECARGS);
13825 +               return 0;
13826 +       }
13827 +#endif
13828 +#endif
13829 +       return 1;
13830 +}
13831 diff -uNr linux-2.6.6/grsecurity/grsum.c linux-2.6.6.fixed/grsecurity/grsum.c
13832 --- linux-2.6.6/grsecurity/grsum.c      1970-01-01 01:00:00.000000000 +0100
13833 +++ linux-2.6.6.fixed/grsecurity/grsum.c        2004-05-11 10:55:56.000000000 +0200
13834 @@ -0,0 +1,59 @@
13835 +#include <linux/kernel.h>
13836 +#include <linux/sched.h>
13837 +#include <linux/mm.h>
13838 +#include <asm/scatterlist.h>
13839 +#include <linux/crypto.h>
13840 +#include <linux/gracl.h>
13841 +
13842 +
13843 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
13844 +#error "crypto and sha256 must be built into the kernel"
13845 +#endif
13846 +
13847 +int
13848 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
13849 +{
13850 +       char *p;
13851 +       struct crypto_tfm *tfm;
13852 +       unsigned char temp_sum[GR_SHA_LEN];
13853 +       struct scatterlist sg[2];
13854 +       volatile int retval = 0;
13855 +       volatile int dummy = 0;
13856 +       unsigned int i;
13857 +
13858 +       tfm = crypto_alloc_tfm("sha256", 0);
13859 +       if (tfm == NULL) {
13860 +               /* should never happen, since sha256 should be built in */
13861 +               return 1;
13862 +       }
13863 +
13864 +       crypto_digest_init(tfm);
13865 +
13866 +       p = salt;
13867 +       sg[0].page = virt_to_page(p);
13868 +       sg[0].offset = ((long) p & ~PAGE_MASK);
13869 +       sg[0].length = GR_SALT_LEN;
13870 +       
13871 +       crypto_digest_update(tfm, sg, 1);
13872 +
13873 +       p = entry->pw;
13874 +       sg[0].page = virt_to_page(p);
13875 +       sg[0].offset = ((long) p & ~PAGE_MASK);
13876 +       sg[0].length = strlen(entry->pw);
13877 +
13878 +       crypto_digest_update(tfm, sg, 1);
13879 +
13880 +       crypto_digest_final(tfm, temp_sum);
13881 +
13882 +       memset(entry->pw, 0, GR_PW_LEN);
13883 +
13884 +       for (i = 0; i < GR_SHA_LEN; i++)
13885 +               if (sum[i] != temp_sum[i])
13886 +                       retval = 1;
13887 +               else
13888 +                       dummy = 1;      // waste a cycle
13889 +
13890 +       crypto_free_tfm(tfm);
13891 +
13892 +       return retval;
13893 +}
13894 diff -uNr linux-2.6.6/grsecurity/Kconfig linux-2.6.6.fixed/grsecurity/Kconfig
13895 --- linux-2.6.6/grsecurity/Kconfig      1970-01-01 01:00:00.000000000 +0100
13896 +++ linux-2.6.6.fixed/grsecurity/Kconfig        2004-05-11 10:55:56.000000000 +0200
13897 @@ -0,0 +1,864 @@
13898 +#
13899 +# grecurity configuration
13900 +#
13901 +
13902 +menu "Grsecurity"
13903 +
13904 +config GRKERNSEC
13905 +       bool "Grsecurity"
13906 +       select CRYPTO
13907 +       select CRYPTO_SHA256
13908 +       help
13909 +         If you say Y here, you will be able to configure many features
13910 +         that will enhance the security of your system.  It is highly
13911 +         recommended that you say Y here and read through the help
13912 +         for each option so that you fully understand the features and
13913 +         can evaluate their usefulness for your machine.
13914 +
13915 +choice
13916 +       prompt "Security Level"
13917 +       depends GRKERNSEC
13918 +       default GRKERNSEC_CUSTOM
13919 +
13920 +config GRKERNSEC_LOW
13921 +       bool "Low"
13922 +       select GRKERNSEC_LINK
13923 +       select GRKERNSEC_FIFO
13924 +       select GRKERNSEC_RANDPID
13925 +       select GRKERNSEC_EXECVE
13926 +       select GRKERNSEC_RANDNET
13927 +       select GRKERNSEC_RANDISN
13928 +       select GRKERNSEC_DMESG
13929 +       select GRKERNSEC_RANDID
13930 +       select GRKERNSEC_CHROOT_CHDIR
13931 +       help
13932 +         If you choose this option, several of the grsecurity options will
13933 +         be enabled that will give you greater protection against a number
13934 +         of attacks, while assuring that none of your software will have any
13935 +         conflicts with the additional security measures.  If you run a lot
13936 +         of unusual software, or you are having problems with the higher
13937 +         security levels, you should say Y here.  With this option, the
13938 +         following features are enabled:
13939 +
13940 +         - Linking Restrictions
13941 +         - FIFO Restrictions
13942 +         - Randomized PIDs
13943 +         - Enforcing RLIMIT_NPROC on execve
13944 +         - Restricted dmesg
13945 +         - Randomized IP IDs
13946 +         - Enforced chdir("/") on chroot
13947 +
13948 +config GRKERNSEC_MEDIUM
13949 +       bool "Medium"
13950 +       select PAX_EI_PAX
13951 +       select PAX_PT_PAX_FLAGS
13952 +       select PAX_HAVE_ACL_FLAGS
13953 +       select GRKERNSEC_PROC_MEMMAP
13954 +       select GRKERNSEC_CHROOT_SYSCTL
13955 +       select GRKERNSEC_LINK
13956 +       select GRKERNSEC_FIFO
13957 +       select GRKERNSEC_RANDPID
13958 +       select GRKERNSEC_EXECVE
13959 +       select GRKERNSEC_DMESG
13960 +       select GRKERNSEC_RANDID
13961 +       select GRKERNSEC_RANDNET
13962 +       select GRKERNSEC_RANDISN
13963 +       select GRKERNSEC_RANDSRC
13964 +       select GRKERNSEC_RANDRPC
13965 +       select GRKERNSEC_FORKFAIL
13966 +       select GRKERNSEC_TIME
13967 +       select GRKERNSEC_SIGNAL
13968 +       select GRKERNSEC_CHROOT
13969 +       select GRKERNSEC_CHROOT_UNIX
13970 +       select GRKERNSEC_CHROOT_MOUNT
13971 +       select GRKERNSEC_CHROOT_PIVOT
13972 +       select GRKERNSEC_CHROOT_DOUBLE
13973 +       select GRKERNSEC_CHROOT_CHDIR
13974 +       select GRKERNSEC_CHROOT_MKNOD
13975 +       select GRKERNSEC_PROC
13976 +       select GRKERNSEC_PROC_USERGROUP
13977 +       select PAX_RANDUSTACK
13978 +       select PAX_ASLR
13979 +       select PAX_RANDMMAP
13980 +
13981 +       help
13982 +         If you say Y here, several features in addition to those included
13983 +         in the low additional security level will be enabled.  These
13984 +         features provide even more security to your system, though in rare
13985 +         cases they may be incompatible with very old or poorly written
13986 +         software.  If you enable this option, make sure that your auth
13987 +         service (identd) is running as gid 1001.  With this option, 
13988 +         the following features (in addition to those provided in the 
13989 +         low additional security level) will be enabled:
13990 +
13991 +         - Randomized TCP Source Ports
13992 +         - Failed Fork Logging
13993 +         - Time Change Logging
13994 +         - Signal Logging
13995 +         - Deny Mounts in chroot
13996 +         - Deny Double chrooting
13997 +         - Deny Sysctl Writes in chroot
13998 +         - Deny Mknod in chroot
13999 +         - Deny Access to Abstract AF_UNIX Sockets out of chroot
14000 +         - Deny pivot_root in chroot
14001 +         - Denied Writes of /dev/kmem, /dev/mem, and /dev/port
14002 +         - /proc restrictions with special GID set to 10 (usually wheel)
14003 +         - Address Space Layout Randomization (ASLR)
14004 +
14005 +config GRKERNSEC_HIGH
14006 +       bool "High"
14007 +       select GRKERNSEC_LINK
14008 +       select GRKERNSEC_FIFO
14009 +       select GRKERNSEC_RANDPID
14010 +       select GRKERNSEC_EXECVE
14011 +       select GRKERNSEC_DMESG
14012 +       select GRKERNSEC_RANDID
14013 +       select GRKERNSEC_RANDSRC
14014 +       select GRKERNSEC_RANDRPC
14015 +       select GRKERNSEC_FORKFAIL
14016 +       select GRKERNSEC_TIME
14017 +       select GRKERNSEC_SIGNAL
14018 +       select GRKERNSEC_CHROOT_SHMAT
14019 +       select GRKERNSEC_CHROOT_UNIX
14020 +       select GRKERNSEC_CHROOT_MOUNT
14021 +       select GRKERNSEC_CHROOT_FCHDIR
14022 +       select GRKERNSEC_CHROOT_PIVOT
14023 +       select GRKERNSEC_CHROOT_DOUBLE
14024 +       select GRKERNSEC_CHROOT_CHDIR
14025 +       select GRKERNSEC_CHROOT_MKNOD
14026 +       select GRKERNSEC_CHROOT_CAPS
14027 +       select GRKERNSEC_CHROOT_SYSCTL
14028 +       select GRKERNSEC_CHROOT_FINDTASK
14029 +       select GRKERNSEC_PROC
14030 +       select GRKERNSEC_PROC_MEMMAP
14031 +       select GRKERNSEC_HIDESYM
14032 +       select GRKERNSEC_PROC_USERGROUP
14033 +       select GRKERNSEC_KMEM
14034 +       select GRKERNSEC_RESLOG
14035 +       select GRKERNSEC_RANDNET
14036 +       select GRKERNSEC_RANDISN
14037 +       select GRKERNSEC_PROC_ADD
14038 +       select GRKERNSEC_CHROOT_CHMOD
14039 +       select GRKERNSEC_CHROOT_NICE
14040 +       select GRKERNSEC_AUDIT_MOUNT
14041 +       select PAX_RANDUSTACK
14042 +       select PAX_ASLR
14043 +       select PAX_RANDMMAP
14044 +       select PAX_NOEXEC
14045 +       select PAX_MPROTECT
14046 +       select PAX_EI_PAX
14047 +       select PAX_PT_PAX_FLAGS
14048 +       select PAX_HAVE_ACL_FLAGS
14049 +       select PAX_KERNEXEC
14050 +       select PAX_RANDKSTACK
14051 +       select PAX_RANDEXEC
14052 +       select PAX_SEGMEXEC
14053 +       select PAX_EMUTRAMP
14054 +       select PAX_NOVSYSCALL
14055 +       help
14056 +         If you say Y here, many of the features of grsecurity will be
14057 +         enabled, which will protect you against many kinds of attacks
14058 +         against your system.  The heightened security comes at a cost
14059 +         of an increased chance of incompatibilities with rare software
14060 +         on your machine.  Since this security level enables PaX, you should
14061 +         view <http://pax.grsecurity.net> and read about the PaX
14062 +         project.  While you are there, download chpax and run it on
14063 +         binaries that cause problems with PaX.  Also remember that
14064 +         since the /proc restrictions are enabled, you must run your
14065 +         identd as gid 1001.  This security level enables the following 
14066 +         features in addition to those listed in the low and medium 
14067 +         security levels:
14068 +
14069 +         - Additional /proc Restrictions
14070 +         - Chmod Restrictions in chroot
14071 +         - No Signals, Ptrace, or Viewing of Processes Outside of chroot
14072 +         - Capability Restrictions in chroot
14073 +         - Deny fchdir out of chroot
14074 +         - Priority Restrictions in chroot
14075 +         - Segmentation-based Implementation of PaX
14076 +         - Mprotect Restrictions
14077 +         - Removal of Addresses from /proc/<pid>/[maps|stat]
14078 +         - Kernel Stack Randomization
14079 +         - Mount/Unmount/Remount Logging
14080 +         - Kernel Symbol Hiding
14081 +       
14082 +config GRKERNSEC_CUSTOM
14083 +       bool "Custom"
14084 +       help
14085 +         If you say Y here, you will be able to configure every grsecurity
14086 +         option, which allows you to enable many more features that aren't
14087 +         covered in the basic security levels.  These additional features
14088 +         include TPE, socket restrictions, and the sysctl system for
14089 +         grsecurity.  It is advised that you read through the help for
14090 +         each option to determine its usefulness in your situation.
14091 +
14092 +endchoice
14093 +
14094 +menu "Address Space Protection"
14095 +depends on GRKERNSEC
14096 +
14097 +config GRKERNSEC_KMEM
14098 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
14099 +       help
14100 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
14101 +         be written to via mmap or otherwise to modify the running kernel.
14102 +         /dev/port will also not be allowed to be opened. If you have module
14103 +         support disabled, enabling this will close up four ways that are
14104 +         currently used  to insert malicious code into the running kernel.
14105 +         Even with all these features enabled, we still highly recommend that
14106 +         you use the ACL system, as it is still possible for an attacker to
14107 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
14108 +         If you are not using XFree86, you may be able to stop this additional
14109 +         case by enabling the 'Disable privileged I/O' option. Though nothing
14110 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
14111 +         but only to video memory, which is the only writing we allow in this
14112 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
14113 +         not be allowed to mprotect it with PROT_WRITE later.
14114 +         Enabling this feature could make certain apps like VMWare stop working,
14115 +         as they need to write to other locations in /dev/mem.
14116 +         It is highly recommended that you say Y here if you meet all the
14117 +         conditions above.
14118 +
14119 +config GRKERNSEC_IO
14120 +       bool "Disable privileged I/O"
14121 +       depends on X86
14122 +       select RTC
14123 +       help
14124 +         If you say Y here, all ioperm and iopl calls will return an error.
14125 +         Ioperm and iopl can be used to modify the running kernel.
14126 +         Unfortunately, some programs need this access to operate properly,
14127 +         the most notable of which are XFree86 and hwclock.  hwclock can be
14128 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
14129 +         enabled if this option is enabled, to ensure that hwclock operates
14130 +         correctly.  XFree86 still will not operate correctly with this option
14131 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
14132 +         and you still want to protect your kernel against modification,
14133 +         use the ACL system.
14134 +
14135 +config GRKERNSEC_PROC_MEMMAP
14136 +       bool "Remove addresses from /proc/<pid>/[maps|stat]"
14137 +       help
14138 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
14139 +         give no information about the addresses of its mappings if
14140 +         PaX features that rely on random addresses are enabled on the task.
14141 +         If you use PaX it is greatly recommended that you say Y here as it
14142 +         closes up a hole that makes the full ASLR useless for suid
14143 +         binaries.
14144 +
14145 +config GRKERNSEC_HIDESYM
14146 +       bool "Hide kernel symbols"
14147 +       help
14148 +         If you say Y here, getting information on loaded modules, and
14149 +         displaying all kernel symbols through a syscall will be restricted
14150 +         to users with CAP_SYS_MODULE.  This option is only effective
14151 +         provided the following conditions are met:
14152 +         1) The kernel using grsecurity is not precompiled by some distribution
14153 +         2) You are using the ACL system and hiding other files such as your
14154 +            kernel image and System.map
14155 +         3) You have the additional /proc restrictions enabled, which removes
14156 +            /proc/kcore
14157 +         If the above conditions are met, this option will aid to provide a
14158 +         useful protection against local and remote kernel exploitation of
14159 +         overflows and arbitrary read/write vulnerabilities.
14160 +
14161 +endmenu
14162 +menu "Role Based Access Control Options"
14163 +depends on GRKERNSEC
14164 +
14165 +config GRKERNSEC_ACL_HIDEKERN
14166 +       bool "Hide kernel processes"
14167 +       help
14168 +         If you say Y here, when the RBAC system is enabled via gradm -E,
14169 +         an additional ACL will be passed to the kernel that hides all kernel
14170 +         processes.  These processes will only be viewable by the authenticated
14171 +         admin, or processes that have viewing access set.
14172 +
14173 +config GRKERNSEC_ACL_MAXTRIES
14174 +       int "Maximum tries before password lockout"
14175 +       default 3
14176 +       help
14177 +         This option enforces the maximum number of times a user can attempt
14178 +         to authorize themselves with the grsecurity ACL system before being
14179 +         denied the ability to attempt authorization again for a specified time.
14180 +         The lower the number, the harder it will be to brute-force a password.
14181 +
14182 +config GRKERNSEC_ACL_TIMEOUT
14183 +       int "Time to wait after max password tries, in seconds"
14184 +       default 30
14185 +       help
14186 +         This option specifies the time the user must wait after attempting to
14187 +         authorize to the ACL system with the maximum number of invalid
14188 +         passwords.  The higher the number, the harder it will be to brute-force
14189 +         a password.
14190 +
14191 +endmenu
14192 +menu "Filesystem Protections"
14193 +depends on GRKERNSEC
14194 +
14195 +config GRKERNSEC_PROC
14196 +       bool "Proc restrictions"
14197 +       help
14198 +         If you say Y here, the permissions of the /proc filesystem
14199 +         will be altered to enhance system security and privacy.  Depending
14200 +         upon the options you choose, you can either restrict users to see
14201 +         only the processes they themselves run, or choose a group that can
14202 +         view all processes and files normally restricted to root if you choose
14203 +         the "restrict to user only" option.  NOTE: If you're running identd as
14204 +         a non-root user, you will have to run it as the group you specify here.
14205 +
14206 +config GRKERNSEC_PROC_USER
14207 +       bool "Restrict /proc to user only"
14208 +       depends on GRKERNSEC_PROC
14209 +       help
14210 +         If you say Y here, non-root users will only be able to view their own
14211 +         processes, and restricts them from viewing network-related information,
14212 +         and viewing kernel symbol and module information.
14213 +
14214 +config GRKERNSEC_PROC_USERGROUP
14215 +       bool "Allow special group"
14216 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
14217 +       help
14218 +         If you say Y here, you will be able to select a group that will be
14219 +         able to view all processes, network-related information, and
14220 +         kernel and symbol information.  This option is useful if you want
14221 +         to run identd as a non-root user.
14222 +
14223 +config GRKERNSEC_PROC_GID
14224 +       int "GID for special group"
14225 +       depends on GRKERNSEC_PROC_USERGROUP
14226 +       default 1001
14227 +
14228 +config GRKERNSEC_PROC_ADD
14229 +       bool "Additional restrictions"
14230 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
14231 +       help
14232 +         If you say Y here, additional restrictions will be placed on
14233 +         /proc that keep normal users from viewing cpu and device information.
14234 +
14235 +config GRKERNSEC_LINK
14236 +       bool "Linking restrictions"
14237 +       help
14238 +         If you say Y here, /tmp race exploits will be prevented, since users
14239 +         will no longer be able to follow symlinks owned by other users in
14240 +         world-writable +t directories (i.e. /tmp), unless the owner of the
14241 +         symlink is the owner of the directory. users will also not be
14242 +         able to hardlink to files they do not own.  If the sysctl option is
14243 +         enabled, a sysctl option with name "linking_restrictions" is created.
14244 +
14245 +config GRKERNSEC_FIFO
14246 +       bool "FIFO restrictions"
14247 +       help
14248 +         If you say Y here, users will not be able to write to FIFOs they don't
14249 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
14250 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
14251 +         option is enabled, a sysctl option with name "fifo_restrictions" is
14252 +         created.
14253 +
14254 +config GRKERNSEC_CHROOT
14255 +       bool "Chroot jail restrictions"
14256 +       help
14257 +         If you say Y here, you will be able to choose several options that will
14258 +         make breaking out of a chrooted jail much more difficult.  If you
14259 +         encounter no software incompatibilities with the following options, it
14260 +         is recommended that you enable each one.
14261 +
14262 +config GRKERNSEC_CHROOT_MOUNT
14263 +       bool "Deny mounts"
14264 +       depends on GRKERNSEC_CHROOT
14265 +       help
14266 +         If you say Y here, processes inside a chroot will not be able to
14267 +         mount or remount filesystems.  If the sysctl option is enabled, a
14268 +         sysctl option with name "chroot_deny_mount" is created.
14269 +
14270 +config GRKERNSEC_CHROOT_DOUBLE
14271 +       bool "Deny double-chroots"
14272 +       depends on GRKERNSEC_CHROOT
14273 +       help
14274 +         If you say Y here, processes inside a chroot will not be able to chroot
14275 +         again outside the chroot.  This is a widely used method of breaking
14276 +         out of a chroot jail and should not be allowed.  If the sysctl 
14277 +         option is enabled, a sysctl option with name 
14278 +         "chroot_deny_chroot" is created.
14279 +
14280 +config GRKERNSEC_CHROOT_PIVOT
14281 +       bool "Deny pivot_root in chroot"
14282 +       depends on GRKERNSEC_CHROOT
14283 +       help
14284 +         If you say Y here, processes inside a chroot will not be able to use
14285 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
14286 +         works similar to chroot in that it changes the root filesystem.  This
14287 +         function could be misused in a chrooted process to attempt to break out
14288 +         of the chroot, and therefore should not be allowed.  If the sysctl
14289 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
14290 +         created.
14291 +
14292 +config GRKERNSEC_CHROOT_CHDIR
14293 +       bool "Enforce chdir(\"/\") on all chroots"
14294 +       depends on GRKERNSEC_CHROOT
14295 +       help
14296 +         If you say Y here, the current working directory of all newly-chrooted
14297 +         applications will be set to the the root directory of the chroot.
14298 +         The man page on chroot(2) states:
14299 +         Note that this call does not change  the  current  working
14300 +         directory,  so  that `.' can be outside the tree rooted at
14301 +         `/'.  In particular, the  super-user  can  escape  from  a
14302 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
14303 +
14304 +         It is recommended that you say Y here, since it's not known to break
14305 +         any software.  If the sysctl option is enabled, a sysctl option with
14306 +         name "chroot_enforce_chdir" is created.
14307 +
14308 +config GRKERNSEC_CHROOT_CHMOD
14309 +       bool "Deny (f)chmod +s"
14310 +       depends on GRKERNSEC_CHROOT
14311 +       help
14312 +         If you say Y here, processes inside a chroot will not be able to chmod
14313 +         or fchmod files to make them have suid or sgid bits.  This protects
14314 +         against another published method of breaking a chroot.  If the sysctl
14315 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
14316 +         created.
14317 +
14318 +config GRKERNSEC_CHROOT_FCHDIR
14319 +       bool "Deny fchdir out of chroot"
14320 +       depends on GRKERNSEC_CHROOT
14321 +       help
14322 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
14323 +         to a file descriptor of the chrooting process that points to a directory
14324 +         outside the filesystem will be stopped.  If the sysctl option
14325 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
14326 +
14327 +config GRKERNSEC_CHROOT_MKNOD
14328 +       bool "Deny mknod"
14329 +       depends on GRKERNSEC_CHROOT
14330 +       help
14331 +         If you say Y here, processes inside a chroot will not be allowed to
14332 +         mknod.  The problem with using mknod inside a chroot is that it
14333 +         would allow an attacker to create a device entry that is the same
14334 +         as one on the physical root of your system, which could range from
14335 +         anything from the console device to a device for your harddrive (which
14336 +         they could then use to wipe the drive or steal data).  It is recommended
14337 +         that you say Y here, unless you run into software incompatibilities.
14338 +         If the sysctl option is enabled, a sysctl option with name
14339 +         "chroot_deny_mknod" is created.
14340 +
14341 +config GRKERNSEC_CHROOT_SHMAT
14342 +       bool "Deny shmat() out of chroot"
14343 +       depends on GRKERNSEC_CHROOT
14344 +       help
14345 +         If you say Y here, processes inside a chroot will not be able to attach
14346 +         to shared memory segments that were created outside of the chroot jail.
14347 +         It is recommended that you say Y here.  If the sysctl option is enabled,
14348 +         a sysctl option with name "chroot_deny_shmat" is created.
14349 +
14350 +config GRKERNSEC_CHROOT_UNIX
14351 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
14352 +       depends on GRKERNSEC_CHROOT
14353 +       help
14354 +         If you say Y here, processes inside a chroot will not be able to
14355 +         connect to abstract (meaning not belonging to a filesystem) Unix
14356 +         domain sockets that were bound outside of a chroot.  It is recommended
14357 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
14358 +         with name "chroot_deny_unix" is created.
14359 +
14360 +config GRKERNSEC_CHROOT_FINDTASK
14361 +       bool "Protect outside processes"
14362 +       depends on GRKERNSEC_CHROOT
14363 +       help
14364 +         If you say Y here, processes inside a chroot will not be able to
14365 +         kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
14366 +         getsid, or view any process outside of the chroot.  If the sysctl
14367 +         option is enabled, a sysctl option with name "chroot_findtask" is
14368 +         created.
14369 +
14370 +config GRKERNSEC_CHROOT_NICE
14371 +       bool "Restrict priority changes"
14372 +       depends on GRKERNSEC_CHROOT
14373 +       help
14374 +         If you say Y here, processes inside a chroot will not be able to raise
14375 +         the priority of processes in the chroot, or alter the priority of
14376 +         processes outside the chroot.  This provides more security than simply
14377 +         removing CAP_SYS_NICE from the process' capability set.  If the
14378 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
14379 +         is created.
14380 +
14381 +config GRKERNSEC_CHROOT_SYSCTL
14382 +       bool "Deny sysctl writes"
14383 +       depends on GRKERNSEC_CHROOT
14384 +       help
14385 +         If you say Y here, an attacker in a chroot will not be able to
14386 +         write to sysctl entries, either by sysctl(2) or through a /proc
14387 +         interface.  It is strongly recommended that you say Y here. If the
14388 +         sysctl option is enabled, a sysctl option with name
14389 +         "chroot_deny_sysctl" is created.
14390 +
14391 +config GRKERNSEC_CHROOT_CAPS
14392 +       bool "Capability restrictions"
14393 +       depends on GRKERNSEC_CHROOT
14394 +       help
14395 +         If you say Y here, the capabilities on all root processes within a
14396 +         chroot jail will be lowered to stop module insertion, raw i/o,
14397 +         system and net admin tasks, rebooting the system, modifying immutable
14398 +         files, modifying IPC owned by another, and changing the system time.
14399 +         This is left an option because it can break some apps.  Disable this
14400 +         if your chrooted apps are having problems performing those kinds of
14401 +         tasks.  If the sysctl option is enabled, a sysctl option with
14402 +         name "chroot_caps" is created.
14403 +
14404 +endmenu
14405 +menu "Kernel Auditing"
14406 +depends on GRKERNSEC
14407 +
14408 +config GRKERNSEC_AUDIT_GROUP
14409 +       bool "Single group for auditing"
14410 +       help
14411 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
14412 +         will only operate on a group you specify.  This option is recommended
14413 +         if you only want to watch certain users instead of having a large
14414 +         amount of logs from the entire system.  If the sysctl option is enabled,
14415 +         a sysctl option with name "audit_group" is created.
14416 +
14417 +config GRKERNSEC_AUDIT_GID
14418 +       int "GID for auditing"
14419 +       depends on GRKERNSEC_AUDIT_GROUP
14420 +       default 1007
14421 +
14422 +config GRKERNSEC_EXECLOG
14423 +       bool "Exec logging"
14424 +       help
14425 +         If you say Y here, all execve() calls will be logged (since the
14426 +         other exec*() calls are frontends to execve(), all execution
14427 +         will be logged).  Useful for shell-servers that like to keep track
14428 +         of their users.  If the sysctl option is enabled, a sysctl option with
14429 +         name "exec_logging" is created.
14430 +         WARNING: This option when enabled will produce a LOT of logs, especially
14431 +         on an active system.
14432 +
14433 +config GRKERNSEC_RESLOG
14434 +       bool "Resource logging"
14435 +       help
14436 +         If you say Y here, all attempts to overstep resource limits will
14437 +         be logged with the resource name, the requested size, and the current
14438 +         limit.  It is highly recommended that you say Y here.
14439 +
14440 +config GRKERNSEC_CHROOT_EXECLOG
14441 +       bool "Log execs within chroot"
14442 +       help
14443 +         If you say Y here, all executions inside a chroot jail will be logged
14444 +         to syslog.  This can cause a large amount of logs if certain
14445 +         applications (eg. djb's daemontools) are installed on the system, and
14446 +         is therefore left as an option.  If the sysctl option is enabled, a
14447 +         sysctl option with name "chroot_execlog" is created.
14448 +
14449 +config GRKERNSEC_AUDIT_CHDIR
14450 +       bool "Chdir logging"
14451 +       help
14452 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
14453 +         option is enabled, a sysctl option with name "audit_chdir" is created.
14454 +
14455 +config GRKERNSEC_AUDIT_MOUNT
14456 +       bool "(Un)Mount logging"
14457 +       help
14458 +         If you say Y here, all mounts and unmounts will be logged.  If the
14459 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
14460 +         created.
14461 +
14462 +config GRKERNSEC_AUDIT_IPC
14463 +       bool "IPC logging"
14464 +       help
14465 +         If you say Y here, creation and removal of message queues, semaphores,
14466 +         and shared memory will be logged.  If the sysctl option is enabled, a
14467 +         sysctl option with name "audit_ipc" is created.
14468 +
14469 +config GRKERNSEC_SIGNAL
14470 +       bool "Signal logging"
14471 +       help
14472 +         If you say Y here, certain important signals will be logged, such as
14473 +         SIGSEGV, which will as a result inform you of when a error in a program
14474 +         occurred, which in some cases could mean a possible exploit attempt.
14475 +         If the sysctl option is enabled, a sysctl option with name
14476 +         "signal_logging" is created.
14477 +
14478 +config GRKERNSEC_FORKFAIL
14479 +       bool "Fork failure logging"
14480 +       help
14481 +         If you say Y here, all failed fork() attempts will be logged.
14482 +         This could suggest a fork bomb, or someone attempting to overstep
14483 +         their process limit.  If the sysctl option is enabled, a sysctl option
14484 +         with name "forkfail_logging" is created.
14485 +
14486 +config GRKERNSEC_TIME
14487 +       bool "Time change logging"
14488 +       help
14489 +         If you say Y here, any changes of the system clock will be logged.
14490 +         If the sysctl option is enabled, a sysctl option with name
14491 +         "timechange_logging" is created.
14492 +
14493 +config GRKERNSEC_PROC_IPADDR
14494 +       bool "/proc/<pid>/ipaddr support"
14495 +       help
14496 +         If you say Y here, a new entry will be added to each /proc/<pid>
14497 +         directory that contains the IP address of the person using the task.
14498 +         The IP is carried across local TCP and AF_UNIX stream sockets.
14499 +         This information can be useful for IDS/IPSes to perform remote response
14500 +         to a local attack.  The entry is readable by only the owner of the
14501 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
14502 +         the RBAC system), and thus does not create privacy concerns.
14503 +
14504 +config GRKERNSEC_AUDIT_TEXTREL
14505 +       bool 'ELF text relocations logging (READ HELP)'
14506 +       depends on PAX_MPROTECT
14507 +       help
14508 +         If you say Y here, text relocations will be logged with the filename
14509 +         of the offending library or binary.  The purpose of the feature is
14510 +         to help Linux distribution developers get rid of libraries and
14511 +         binaries that need text relocations which hinder the future progress
14512 +         of PaX.  Only Linux distribution developers should say Y here, and
14513 +         never on a production machine, as this option creates an information
14514 +         leak that could aid an attacker in defeating the randomization of
14515 +         a single memory region.  If the sysctl option is enabled, a sysctl
14516 +         option with name "audit_textrel" is created.
14517 +
14518 +endmenu
14519 +
14520 +menu "Executable Protections"
14521 +depends on GRKERNSEC
14522 +
14523 +config GRKERNSEC_EXECVE
14524 +       bool "Enforce RLIMIT_NPROC on execs"
14525 +       help
14526 +         If you say Y here, users with a resource limit on processes will
14527 +         have the value checked during execve() calls.  The current system
14528 +         only checks the system limit during fork() calls.  If the sysctl option
14529 +         is enabled, a sysctl option with name "execve_limiting" is created.
14530 +
14531 +config GRKERNSEC_DMESG
14532 +       bool "Dmesg(8) restriction"
14533 +       help
14534 +         If you say Y here, non-root users will not be able to use dmesg(8)
14535 +         to view up to the last 4kb of messages in the kernel's log buffer.
14536 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
14537 +         created.
14538 +
14539 +config GRKERNSEC_RANDPID
14540 +       bool "Randomized PIDs"
14541 +       help
14542 +         If you say Y here, all PIDs created on the system will be
14543 +         pseudo-randomly generated.  This is extremely effective along
14544 +         with the /proc restrictions to disallow an attacker from guessing
14545 +         pids of daemons, etc.  PIDs are also used in some cases as part
14546 +         of a naming system for temporary files, so this option would keep
14547 +         those filenames from being predicted as well.  We also use code
14548 +         to make sure that PID numbers aren't reused too soon.  If the sysctl
14549 +         option is enabled, a sysctl option with name "rand_pids" is created.
14550 +
14551 +config GRKERNSEC_TPE
14552 +       bool "Trusted Path Execution (TPE)"
14553 +       help
14554 +         If you say Y here, you will be able to choose a gid to add to the
14555 +         supplementary groups of users you want to mark as "untrusted."
14556 +         These users will not be able to execute any files that are not in
14557 +         root-owned directories writable only by root.  If the sysctl option
14558 +         is enabled, a sysctl option with name "tpe" is created.
14559 +
14560 +config GRKERNSEC_TPE_ALL
14561 +       bool "Partially restrict non-root users"
14562 +       depends on GRKERNSEC_TPE
14563 +       help
14564 +         If you say Y here, All non-root users other than the ones in the
14565 +         group specified in the main TPE option will only be allowed to
14566 +         execute files in directories they own that are not group or
14567 +         world-writable, or in directories owned by root and writable only by
14568 +         root.  If the sysctl option is enabled, a sysctl option with name
14569 +         "tpe_restrict_all" is created.
14570 +
14571 +config GRKERNSEC_TPE_GID
14572 +       int "GID for untrusted users"
14573 +       depends on GRKERNSEC_TPE
14574 +       default 1005
14575 +       help
14576 +         Here you can choose the GID to enable trusted path protection for.
14577 +         Remember to add the users you want protection enabled for to the GID
14578 +         specified here.  If the sysctl option is enabled, whatever you choose
14579 +         here won't matter. You'll have to specify the GID in your bootup
14580 +         script by echoing the GID to the proper /proc entry.  View the help
14581 +         on the sysctl option for more information.  If the sysctl option is
14582 +         enabled, a sysctl option with name "tpe_gid" is created.
14583 +
14584 +endmenu
14585 +menu "Network Protections"
14586 +depends on GRKERNSEC
14587 +
14588 +config GRKERNSEC_RANDNET
14589 +       bool "Larger entropy pools"
14590 +       help
14591 +         If you say Y here, the entropy pools used for many features of Linux
14592 +         and grsecurity will be doubled in size.  Since several grsecurity
14593 +         features use additional randomness, it is recommended that you say Y
14594 +         here.  Saying Y here has a similar effect as modifying
14595 +         /proc/sys/kernel/random/poolsize.
14596 +
14597 +config GRKERNSEC_RANDISN
14598 +       bool "Truly random TCP ISN selection"
14599 +       help
14600 +         If you say Y here, Linux's default selection of TCP Initial Sequence
14601 +         Numbers (ISNs) will be replaced with that of OpenBSD.  Linux uses
14602 +         an MD4 hash based on the connection plus a time value to create the
14603 +         ISN, while OpenBSD's selection is random.  If the sysctl option is
14604 +         enabled, a sysctl option with name "rand_isns" is created.
14605 +
14606 +config GRKERNSEC_RANDID
14607 +       bool "Randomized IP IDs"
14608 +       help
14609 +         If you say Y here, all the id field on all outgoing packets
14610 +         will be randomized.  This hinders os fingerprinters and
14611 +         keeps your machine from being used as a bounce for an untraceable
14612 +         portscan.  Ids are used for fragmented packets, fragments belonging
14613 +         to the same packet have the same id.  By default linux only
14614 +         increments the id value on each packet sent to an individual host.
14615 +         We use a port of the OpenBSD random ip id code to achieve the
14616 +         randomness, while keeping the possibility of id duplicates to
14617 +         near none.  If the sysctl option is enabled, a sysctl option with name
14618 +         "rand_ip_ids" is created.
14619 +
14620 +config GRKERNSEC_RANDSRC
14621 +       bool "Randomized TCP source ports"
14622 +       default n if GRKERNSEC_LOW || GRKERNSEC_MID
14623 +       default y if GRKERNSEC_HIGH
14624 +       help
14625 +         If you say Y here, situations where a source port is generated on the
14626 +         fly for the TCP protocol (ie. with connect() ) will be altered so that
14627 +         the source port is generated at random, instead of a simple incrementing
14628 +         algorithm.  If the sysctl option is enabled, a sysctl option with name
14629 +         "rand_tcp_src_ports" is created.
14630 +
14631 +config GRKERNSEC_RANDRPC
14632 +       bool "Randomized RPC XIDs"
14633 +       help
14634 +         If you say Y here, the method of determining XIDs for RPC requests will
14635 +         be randomized, instead of using linux's default behavior of simply
14636 +         incrementing the XID.  If you want your RPC connections to be more
14637 +         secure, say Y here.  If the sysctl option is enabled, a sysctl option
14638 +         with name "rand_rpc" is created.
14639 +
14640 +config GRKERNSEC_SOCKET
14641 +       bool "Socket restrictions"
14642 +       help
14643 +         If you say Y here, you will be able to choose from several options.
14644 +         If you assign a GID on your system and add it to the supplementary
14645 +         groups of users you want to restrict socket access to, this patch
14646 +         will perform up to three things, based on the option(s) you choose.
14647 +
14648 +config GRKERNSEC_SOCKET_ALL
14649 +       bool "Deny any sockets to group"
14650 +       depends on GRKERNSEC_SOCKET
14651 +       help
14652 +         If you say Y here, you will be able to choose a GID of whose users will
14653 +         be unable to connect to other hosts from your machine or run server
14654 +         applications from your machine.  If the sysctl option is enabled, a
14655 +         sysctl option with name "socket_all" is created.
14656 +
14657 +config GRKERNSEC_SOCKET_ALL_GID
14658 +       int "GID to deny all sockets for"
14659 +       depends on GRKERNSEC_SOCKET_ALL
14660 +       default 1004
14661 +       help
14662 +         Here you can choose the GID to disable socket access for. Remember to
14663 +         add the users you want socket access disabled for to the GID
14664 +         specified here.  If the sysctl option is enabled, whatever you choose
14665 +         here won't matter. You'll have to specify the GID in your bootup
14666 +         script by echoing the GID to the proper /proc entry.  View the help
14667 +         on the sysctl option for more information.  If the sysctl option is
14668 +         enabled, a sysctl option with name "socket_all_gid" is created.
14669 +
14670 +config GRKERNSEC_SOCKET_CLIENT
14671 +       bool "Deny client sockets to group"
14672 +       depends on GRKERNSEC_SOCKET
14673 +       help
14674 +         If you say Y here, you will be able to choose a GID of whose users will
14675 +         be unable to connect to other hosts from your machine, but will be
14676 +         able to run servers.  If this option is enabled, all users in the group
14677 +         you specify will have to use passive mode when initiating ftp transfers
14678 +         from the shell on your machine.  If the sysctl option is enabled, a
14679 +         sysctl option with name "socket_client" is created.
14680 +
14681 +config GRKERNSEC_SOCKET_CLIENT_GID
14682 +       int "GID to deny client sockets for"
14683 +       depends on GRKERNSEC_SOCKET_CLIENT
14684 +       default 1003
14685 +       help
14686 +         Here you can choose the GID to disable client socket access for.
14687 +         Remember to add the users you want client socket access disabled for to
14688 +         the GID specified here.  If the sysctl option is enabled, whatever you
14689 +         choose here won't matter. You'll have to specify the GID in your bootup
14690 +         script by echoing the GID to the proper /proc entry.  View the help
14691 +         on the sysctl option for more information.  If the sysctl option is
14692 +         enabled, a sysctl option with name "socket_client_gid" is created.
14693 +
14694 +config GRKERNSEC_SOCKET_SERVER
14695 +       bool "Deny server sockets to group"
14696 +       depends on GRKERNSEC_SOCKET
14697 +       help
14698 +         If you say Y here, you will be able to choose a GID of whose users will
14699 +         be unable to run server applications from your machine.  If the sysctl
14700 +         option is enabled, a sysctl option with name "socket_server" is created.
14701 +
14702 +config GRKERNSEC_SOCKET_SERVER_GID
14703 +       int "GID to deny server sockets for"
14704 +       depends on GRKERNSEC_SOCKET_SERVER
14705 +       default 1002
14706 +       help
14707 +         Here you can choose the GID to disable server socket access for.
14708 +         Remember to add the users you want server socket access disabled for to
14709 +         the GID specified here.  If the sysctl option is enabled, whatever you
14710 +         choose here won't matter. You'll have to specify the GID in your bootup
14711 +         script by echoing the GID to the proper /proc entry.  View the help
14712 +         on the sysctl option for more information.  If the sysctl option is
14713 +         enabled, a sysctl option with name "socket_server_gid" is created.
14714 +
14715 +endmenu
14716 +menu "Sysctl support"
14717 +depends on GRKERNSEC && SYSCTL
14718 +
14719 +config GRKERNSEC_SYSCTL
14720 +       bool "Sysctl support"
14721 +       help
14722 +         If you say Y here, you will be able to change the options that
14723 +         grsecurity runs with at bootup, without having to recompile your
14724 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
14725 +         to enable (1) or disable (0) various features.  All the sysctl entries
14726 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
14727 +         All features are disabled by default. Please note that this option could
14728 +         reduce the effectiveness of the added security of this patch if an ACL
14729 +         system is not put in place.  Your init scripts should be read-only, and
14730 +         root should not have access to adding modules or performing raw i/o
14731 +         operations.  All options should be set at startup, and the grsec_lock
14732 +         entry should be set to a non-zero value after all the options are set.
14733 +         *THIS IS EXTREMELY IMPORTANT*
14734 +
14735 +endmenu
14736 +menu "Logging Options"
14737 +depends on GRKERNSEC
14738 +
14739 +config GRKERNSEC_FLOODTIME
14740 +       int "Seconds in between log messages (minimum)"
14741 +       default 10
14742 +       help
14743 +         This option allows you to enforce the number of seconds between
14744 +         grsecurity log messages.  The default should be suitable for most
14745 +         people, however, if you choose to change it, choose a value small enough
14746 +         to allow informative logs to be produced, but large enough to
14747 +         prevent flooding.
14748 +
14749 +config GRKERNSEC_FLOODBURST
14750 +       int "Number of messages in a burst (maximum)"
14751 +       default 4
14752 +       help
14753 +         This option allows you to choose the maximum number of messages allowed
14754 +         within the flood time interval you chose in a separate option.  The
14755 +         default should be suitable for most people, however if you find that
14756 +         many of your logs are being interpreted as flooding, you may want to
14757 +         raise this value.
14758 +
14759 +endmenu
14760 +
14761 +endmenu
14762 diff -uNr linux-2.6.6/grsecurity/Makefile linux-2.6.6.fixed/grsecurity/Makefile
14763 --- linux-2.6.6/grsecurity/Makefile     1970-01-01 01:00:00.000000000 +0100
14764 +++ linux-2.6.6.fixed/grsecurity/Makefile       2004-05-11 10:55:56.000000000 +0200
14765 @@ -0,0 +1,21 @@
14766 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
14767 +# during 2001, 2002, and 2003 it has been completely redesigned by
14768 +# Brad Spengler
14769 +#
14770 +# All code in this directory and various hooks inserted throughout the kernel
14771 +# are copyright Brad Spengler, and released under the GPL, unless otherwise
14772 +# noted (as in obsd_rand.c)
14773 +
14774 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
14775 +       grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
14776 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
14777 +
14778 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
14779 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
14780 +       gracl_learn.o
14781 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
14782 +
14783 +ifndef CONFIG_GRKERNSEC
14784 +obj-y += grsec_disabled.o
14785 +endif
14786 +
14787 diff -uNr linux-2.6.6/grsecurity/obsd_rand.c linux-2.6.6.fixed/grsecurity/obsd_rand.c
14788 --- linux-2.6.6/grsecurity/obsd_rand.c  1970-01-01 01:00:00.000000000 +0100
14789 +++ linux-2.6.6.fixed/grsecurity/obsd_rand.c    2004-05-11 10:55:56.000000000 +0200
14790 @@ -0,0 +1,186 @@
14791 +
14792 +/*
14793 + * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
14794 + * 
14795 + * Version 1.89, last modified 19-Sep-99
14796 + *    
14797 + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
14798 + * All rights reserved.
14799 + *
14800 + * Copyright 1998 Niels Provos <provos@citi.umich.edu>
14801 + * All rights reserved.
14802 + * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
14803 + * such a mathematical system to generate more random (yet non-repeating)
14804 + * ids to solve the resolver/named problem.  But Niels designed the
14805 + * actual system based on the constraints.
14806 + *
14807 + * Redistribution and use in source and binary forms, with or without
14808 + * modification, are permitted provided that the following conditions
14809 + * are met:
14810 + * 1. Redistributions of source code must retain the above copyright
14811 + *    notice, this list of conditions and the following disclaimer,
14812 + * 2. Redistributions in binary form must reproduce the above copyright
14813 + *    notice, this list of conditions and the following disclaimer in the
14814 + *    documentation and/or other materials provided with the distribution.
14815 + *
14816 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14817 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
14818 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
14819 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14820 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14821 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
14822 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
14823 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14824 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
14825 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14826 + */
14827 +
14828 +#include <linux/kernel.h>
14829 +#include <linux/sched.h>
14830 +#include <linux/time.h>
14831 +#include <linux/timer.h>
14832 +#include <linux/smp_lock.h>
14833 +#include <linux/random.h>
14834 +#include <linux/grsecurity.h>
14835 +
14836 +#define RU_OUT 180
14837 +#define RU_MAX 30000
14838 +#define RU_GEN 2
14839 +#define RU_N 32749
14840 +#define RU_AGEN 7
14841 +#define RU_M 31104
14842 +#define PFAC_N 3
14843 +const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
14844 +
14845 +static __u16 ru_x;
14846 +static __u16 ru_seed, ru_seed2;
14847 +static __u16 ru_a, ru_b;
14848 +static __u16 ru_g;
14849 +static __u16 ru_counter = 0;
14850 +static __u16 ru_msb = 0;
14851 +static unsigned long ru_reseed = 0;
14852 +static __u32 tmp;
14853 +
14854 +#define TCP_RNDISS_ROUNDS      15
14855 +#define TCP_RNDISS_OUT         7200
14856 +#define TCP_RNDISS_MAX         30000
14857 +
14858 +static __u8 tcp_rndiss_sbox[128];
14859 +static __u16 tcp_rndiss_msb;
14860 +static __u16 tcp_rndiss_cnt;
14861 +static unsigned long tcp_rndiss_reseed;
14862 +
14863 +static __u16 pmod(__u16, __u16, __u16);
14864 +static void ip_initid(void);
14865 +__u16 ip_randomid(void);
14866 +
14867 +static __u16
14868 +pmod(__u16 gen, __u16 exp, __u16 mod)
14869 +{
14870 +       __u16 s, t, u;
14871 +
14872 +       s = 1;
14873 +       t = gen;
14874 +       u = exp;
14875 +
14876 +       while (u) {
14877 +               if (u & 1)
14878 +                       s = (s * t) % mod;
14879 +               u >>= 1;
14880 +               t = (t * t) % mod;
14881 +       }
14882 +       return (s);
14883 +}
14884 +
14885 +static void
14886 +ip_initid(void)
14887 +{
14888 +       __u16 j, i;
14889 +       int noprime = 1;
14890 +
14891 +       ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
14892 +
14893 +       ru_seed = (tmp >> 16) & 0x7FFF;
14894 +       ru_seed2 = get_random_long() & 0x7FFF;
14895 +
14896 +       ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
14897 +       ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
14898 +       while (ru_b % 3 == 0)
14899 +               ru_b += 2;
14900 +
14901 +       j = (tmp = get_random_long()) % RU_N;
14902 +       tmp = tmp >> 16;
14903 +
14904 +       while (noprime) {
14905 +               for (i = 0; i < PFAC_N; i++)
14906 +                       if (j % pfacts[i] == 0)
14907 +                               break;
14908 +
14909 +               if (i >= PFAC_N)
14910 +                       noprime = 0;
14911 +               else
14912 +                       j = (j + 1) % RU_N;
14913 +       }
14914 +
14915 +       ru_g = pmod(RU_GEN, j, RU_N);
14916 +       ru_counter = 0;
14917 +
14918 +       ru_reseed = xtime.tv_sec + RU_OUT;
14919 +       ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
14920 +}
14921 +
14922 +__u16
14923 +ip_randomid(void)
14924 +{
14925 +       int i, n;
14926 +
14927 +       if (ru_counter >= RU_MAX || time_after(get_seconds(), ru_reseed))
14928 +               ip_initid();
14929 +
14930 +       if (!tmp)
14931 +               tmp = get_random_long();
14932 +
14933 +       n = tmp & 0x3;
14934 +       tmp = tmp >> 2;
14935 +       if (ru_counter + n >= RU_MAX)
14936 +               ip_initid();
14937 +       for (i = 0; i <= n; i++)
14938 +               ru_x = (ru_a * ru_x + ru_b) % RU_M;
14939 +       ru_counter += i;
14940 +
14941 +       return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
14942 +}
14943 +
14944 +__u16
14945 +tcp_rndiss_encrypt(__u16 val)
14946 +{
14947 +       __u16 sum = 0, i;
14948 +
14949 +       for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
14950 +               sum += 0x79b9;
14951 +               val ^= ((__u16) tcp_rndiss_sbox[(val ^ sum) & 0x7f]) << 7;
14952 +               val = ((val & 0xff) << 7) | (val >> 8);
14953 +       }
14954 +
14955 +       return val;
14956 +}
14957 +
14958 +static void
14959 +tcp_rndiss_init(void)
14960 +{
14961 +       get_random_bytes(tcp_rndiss_sbox, sizeof (tcp_rndiss_sbox));
14962 +       tcp_rndiss_reseed = get_seconds() + TCP_RNDISS_OUT;
14963 +       tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
14964 +       tcp_rndiss_cnt = 0;
14965 +}
14966 +
14967 +__u32
14968 +ip_randomisn(void)
14969 +{
14970 +       if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
14971 +           time_after(get_seconds(), tcp_rndiss_reseed))
14972 +               tcp_rndiss_init();
14973 +
14974 +       return (((tcp_rndiss_encrypt(tcp_rndiss_cnt++) |
14975 +                 tcp_rndiss_msb) << 16) | (get_random_long() & 0x7fff));
14976 +}
14977 diff -uNr linux-2.6.6/include/asm-alpha/a.out.h linux-2.6.6.fixed/include/asm-alpha/a.out.h
14978 --- linux-2.6.6/include/asm-alpha/a.out.h       2004-05-10 04:32:54.000000000 +0200
14979 +++ linux-2.6.6.fixed/include/asm-alpha/a.out.h 2004-05-11 10:55:56.000000000 +0200
14980 @@ -98,7 +98,7 @@
14981         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
14982                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
14983  
14984 -#define STACK_TOP \
14985 +#define __STACK_TOP \
14986    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
14987  
14988  #endif
14989 diff -uNr linux-2.6.6/include/asm-alpha/elf.h linux-2.6.6.fixed/include/asm-alpha/elf.h
14990 --- linux-2.6.6/include/asm-alpha/elf.h 2004-05-10 04:32:37.000000000 +0200
14991 +++ linux-2.6.6.fixed/include/asm-alpha/elf.h   2004-05-11 10:55:57.000000000 +0200
14992 @@ -84,6 +84,17 @@
14993  
14994  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
14995  
14996 +#ifdef CONFIG_PAX_ASLR
14997 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
14998 +
14999 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
15000 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
15001 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
15002 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
15003 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
15004 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
15005 +#endif
15006 +
15007  /* $0 is set by ld.so to a pointer to a function which might be 
15008     registered using atexit.  This provides a mean for the dynamic
15009     linker to call DT_FINI functions for shared libraries that have
15010 diff -uNr linux-2.6.6/include/asm-alpha/mman.h linux-2.6.6.fixed/include/asm-alpha/mman.h
15011 --- linux-2.6.6/include/asm-alpha/mman.h        2004-05-10 04:31:58.000000000 +0200
15012 +++ linux-2.6.6.fixed/include/asm-alpha/mman.h  2004-05-11 10:55:57.000000000 +0200
15013 @@ -29,6 +29,10 @@
15014  #define MAP_POPULATE   0x20000         /* populate (prefault) pagetables */
15015  #define MAP_NONBLOCK   0x40000         /* do not block on IO */
15016  
15017 +#ifdef CONFIG_PAX_RANDEXEC
15018 +#define MAP_MIRROR     0x20000
15019 +#endif
15020 +
15021  #define MS_ASYNC       1               /* sync memory asynchronously */
15022  #define MS_SYNC                2               /* synchronous memory sync */
15023  #define MS_INVALIDATE  4               /* invalidate the caches */
15024 diff -uNr linux-2.6.6/include/asm-alpha/page.h linux-2.6.6.fixed/include/asm-alpha/page.h
15025 --- linux-2.6.6/include/asm-alpha/page.h        2004-05-10 04:33:10.000000000 +0200
15026 +++ linux-2.6.6.fixed/include/asm-alpha/page.h  2004-05-11 10:55:57.000000000 +0200
15027 @@ -98,6 +98,15 @@
15028  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
15029                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15030  
15031 +#ifdef CONFIG_PAX_PAGEEXEC
15032 +#ifdef CONFIG_PAX_MPROTECT
15033 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15034 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15035 +#else
15036 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15037 +#endif
15038 +#endif
15039 +
15040  #endif /* __KERNEL__ */
15041  
15042  #endif /* _ALPHA_PAGE_H */
15043 diff -uNr linux-2.6.6/include/asm-alpha/pgtable.h linux-2.6.6.fixed/include/asm-alpha/pgtable.h
15044 --- linux-2.6.6/include/asm-alpha/pgtable.h     2004-05-10 04:32:27.000000000 +0200
15045 +++ linux-2.6.6.fixed/include/asm-alpha/pgtable.h       2004-05-11 10:55:57.000000000 +0200
15046 @@ -96,6 +96,17 @@
15047  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
15048  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
15049  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
15050 +
15051 +#ifdef CONFIG_PAX_PAGEEXEC
15052 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
15053 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
15054 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
15055 +#else
15056 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
15057 +# define PAGE_COPY_NOEXEC      PAGE_COPY
15058 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
15059 +#endif
15060 +
15061  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
15062  
15063  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
15064 diff -uNr linux-2.6.6/include/asm-i386/a.out.h linux-2.6.6.fixed/include/asm-i386/a.out.h
15065 --- linux-2.6.6/include/asm-i386/a.out.h        2004-05-10 04:32:28.000000000 +0200
15066 +++ linux-2.6.6.fixed/include/asm-i386/a.out.h  2004-05-11 10:55:57.000000000 +0200
15067 @@ -19,7 +19,11 @@
15068  
15069  #ifdef __KERNEL__
15070  
15071 -#define STACK_TOP      TASK_SIZE
15072 +#ifdef CONFIG_PAX_SEGMEXEC
15073 +#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
15074 +#else
15075 +#define __STACK_TOP TASK_SIZE
15076 +#endif
15077  
15078  #endif
15079  
15080 diff -uNr linux-2.6.6/include/asm-i386/desc.h linux-2.6.6.fixed/include/asm-i386/desc.h
15081 --- linux-2.6.6/include/asm-i386/desc.h 2004-05-10 04:31:55.000000000 +0200
15082 +++ linux-2.6.6.fixed/include/asm-i386/desc.h   2004-05-11 10:55:57.000000000 +0200
15083 @@ -8,11 +8,19 @@
15084  
15085  #include <linux/preempt.h>
15086  #include <linux/smp.h>
15087 +#include <linux/sched.h>
15088  
15089  #include <asm/mmu.h>
15090 +#include <asm/pgtable.h>
15091 +#include <asm/tlbflush.h>
15092  
15093  extern struct desc_struct cpu_gdt_table[NR_CPUS][GDT_ENTRIES];
15094  
15095 +static inline void pax_switch_segments(struct task_struct * tsk, int cpu)
15096 +{
15097 +       cpu_gdt_table[cpu][GDT_ENTRY_DEFAULT_USER_CS].b = tsk->flags & PF_PAX_SEGMEXEC ? 0x60c9fb00U : 0x00cffb00U;
15098 +}
15099 +
15100  struct Xgt_desc_struct {
15101         unsigned short size;
15102         unsigned long address __attribute__((packed));
15103 @@ -28,7 +36,7 @@
15104   * This is the ldt that every process will get unless we need
15105   * something other than this.
15106   */
15107 -extern struct desc_struct default_ldt[];
15108 +extern const struct desc_struct default_ldt[];
15109  extern void set_intr_gate(unsigned int irq, void * addr);
15110  
15111  #define _set_tssldt_desc(n,addr,limit,type) \
15112 @@ -42,16 +50,50 @@
15113         "rorl $16,%%eax" \
15114         : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
15115  
15116 -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
15117 +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
15118  {
15119         _set_tssldt_desc(&cpu_gdt_table[cpu][entry], (int)addr, 235, 0x89);
15120  }
15121  
15122  #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
15123  
15124 -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
15125 +static inline void __set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
15126 +{
15127 +       _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
15128 +}
15129 +
15130 +#define pax_open_kernel(flags, cr3)            \
15131 +do {                                           \
15132 +       typecheck(unsigned long,flags);         \
15133 +       typecheck(unsigned long,cr3);           \
15134 +       local_irq_save(flags);                  \
15135 +       asm("movl %%cr3,%0":"=r" (cr3));        \
15136 +       load_cr3(kernexec_pg_dir);              \
15137 +} while(0)
15138 +
15139 +#define pax_close_kernel(flags, cr3)           \
15140 +do {                                           \
15141 +       typecheck(unsigned long,flags);         \
15142 +       typecheck(unsigned long,cr3);           \
15143 +       asm("movl %0,%%cr3": :"r" (cr3));       \
15144 +       local_irq_restore(flags);               \
15145 +} while(0)
15146 +
15147 +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int size)
15148  {
15149 +
15150 +#ifdef CONFIG_PAX_KERNEXEC
15151 +       unsigned long flags, cr3;
15152 +
15153 +       pax_open_kernel(flags, cr3);
15154 +#endif
15155 +
15156         _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
15157 +
15158 +#ifdef CONFIG_PAX_KERNEXEC
15159 +       pax_close_kernel(flags, cr3);
15160 +#endif
15161 +
15162  }
15163  
15164  #define LDT_entry_a(info) \
15165 @@ -67,7 +109,7 @@
15166         ((info)->seg_32bit << 22) | \
15167         ((info)->limit_in_pages << 23) | \
15168         ((info)->useable << 20) | \
15169 -       0x7000)
15170 +       0x7100)
15171  
15172  #define LDT_empty(info) (\
15173         (info)->base_addr       == 0    && \
15174 @@ -104,7 +146,7 @@
15175   */
15176  static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
15177  {
15178 -       void *segments = pc->ldt;
15179 +       const void *segments = pc->ldt;
15180         int count = pc->size;
15181  
15182         if (likely(!count)) {
15183 @@ -123,6 +165,22 @@
15184         put_cpu();
15185  }
15186  
15187 +static inline void _load_LDT(mm_context_t *pc)
15188 +{
15189 +       int cpu = get_cpu();
15190 +       const void *segments = pc->ldt;
15191 +       int count = pc->size;
15192 +
15193 +       if (likely(!count)) {
15194 +               segments = &default_ldt[0];
15195 +               count = 5;
15196 +       }
15197 +               
15198 +       __set_ldt_desc(cpu, segments, count);
15199 +       load_LDT_desc();
15200 +       put_cpu();
15201 +}
15202 +
15203  #endif /* !__ASSEMBLY__ */
15204  
15205  #endif
15206 diff -uNr linux-2.6.6/include/asm-i386/elf.h linux-2.6.6.fixed/include/asm-i386/elf.h
15207 --- linux-2.6.6/include/asm-i386/elf.h  2004-05-10 04:32:53.000000000 +0200
15208 +++ linux-2.6.6.fixed/include/asm-i386/elf.h    2004-05-11 10:55:57.000000000 +0200
15209 @@ -70,7 +70,22 @@
15210     the loader.  We need to make sure that it is out of the way of the program
15211     that it will "exec", and that there is sufficient room for the brk.  */
15212  
15213 +#ifdef CONFIG_PAX_SEGMEXEC
15214 +#define ELF_ET_DYN_BASE                ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3*2:TASK_SIZE/3*2)
15215 +#else
15216  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
15217 +#endif
15218 +
15219 +#ifdef CONFIG_PAX_ASLR
15220 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
15221 +
15222 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
15223 +#define PAX_DELTA_MMAP_LEN(tsk)                16
15224 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
15225 +#define PAX_DELTA_EXEC_LEN(tsk)                16
15226 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
15227 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16)
15228 +#endif
15229  
15230  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
15231     now struct_user_regs, they are different) */
15232 @@ -113,8 +128,11 @@
15233   * Architecture-neutral AT_ values in 0-17, leave some room
15234   * for more of them, start the x86-specific ones at 32.
15235   */
15236 +
15237 +#ifndef CONFIG_PAX_NOVSYSCALL
15238  #define AT_SYSINFO             32
15239  #define AT_SYSINFO_EHDR                33
15240 +#endif
15241  
15242  #ifdef __KERNEL__
15243  #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
15244 @@ -129,7 +147,14 @@
15245  
15246  #define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
15247  #define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
15248 +
15249 +#ifndef CONFIG_PAX_NOVSYSCALL
15250 +#ifdef CONFIG_PAX_SEGMEXEC
15251 +#define VSYSCALL_ENTRY ((current->flags & PF_PAX_SEGMEXEC) ? (unsigned long) &__kernel_vsyscall - SEGMEXEC_TASK_SIZE : (unsigned long) &__kernel_vsyscall)
15252 +#else
15253  #define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
15254 +#endif
15255 +
15256  extern void __kernel_vsyscall;
15257  
15258  #define ARCH_DLINFO                                            \
15259 @@ -185,3 +210,5 @@
15260  #endif
15261  
15262  #endif
15263 +
15264 +#endif
15265 diff -uNr linux-2.6.6/include/asm-i386/mach-default/apm.h linux-2.6.6.fixed/include/asm-i386/mach-default/apm.h
15266 --- linux-2.6.6/include/asm-i386/mach-default/apm.h     2004-05-10 04:32:02.000000000 +0200
15267 +++ linux-2.6.6.fixed/include/asm-i386/mach-default/apm.h       2004-05-11 10:55:57.000000000 +0200
15268 @@ -36,7 +36,7 @@
15269         __asm__ __volatile__(APM_DO_ZERO_SEGS
15270                 "pushl %%edi\n\t"
15271                 "pushl %%ebp\n\t"
15272 -               "lcall *%%cs:apm_bios_entry\n\t"
15273 +               "lcall *%%ss:apm_bios_entry\n\t"
15274                 "setc %%al\n\t"
15275                 "popl %%ebp\n\t"
15276                 "popl %%edi\n\t"
15277 @@ -60,7 +60,7 @@
15278         __asm__ __volatile__(APM_DO_ZERO_SEGS
15279                 "pushl %%edi\n\t"
15280                 "pushl %%ebp\n\t"
15281 -               "lcall *%%cs:apm_bios_entry\n\t"
15282 +               "lcall *%%ss:apm_bios_entry\n\t"
15283                 "setc %%bl\n\t"
15284                 "popl %%ebp\n\t"
15285                 "popl %%edi\n\t"
15286 diff -uNr linux-2.6.6/include/asm-i386/mach-pc9800/apm.h linux-2.6.6.fixed/include/asm-i386/mach-pc9800/apm.h
15287 --- linux-2.6.6/include/asm-i386/mach-pc9800/apm.h      2004-05-10 04:32:28.000000000 +0200
15288 +++ linux-2.6.6.fixed/include/asm-i386/mach-pc9800/apm.h        2004-05-11 10:55:57.000000000 +0200
15289 @@ -39,7 +39,7 @@
15290                 "pushl %%edi\n\t"
15291                 "pushl %%ebp\n\t"
15292                 "pushfl\n\t"
15293 -               "lcall *%%cs:apm_bios_entry\n\t"
15294 +               "lcall *%%ss:apm_bios_entry\n\t"
15295                 "setc %%al\n\t"
15296                 "popl %%ebp\n\t"
15297                 "popl %%edi\n\t"
15298 @@ -64,7 +64,7 @@
15299                 "pushl %%edi\n\t"
15300                 "pushl %%ebp\n\t"
15301                 "pushfl\n\t"
15302 -               "lcall *%%cs:apm_bios_entry\n\t"
15303 +               "lcall *%%ss:apm_bios_entry\n\t"
15304                 "setc %%bl\n\t"
15305                 "popl %%ebp\n\t"
15306                 "popl %%edi\n\t"
15307 diff -uNr linux-2.6.6/include/asm-i386/mman.h linux-2.6.6.fixed/include/asm-i386/mman.h
15308 --- linux-2.6.6/include/asm-i386/mman.h 2004-05-10 04:32:01.000000000 +0200
15309 +++ linux-2.6.6.fixed/include/asm-i386/mman.h   2004-05-11 10:55:57.000000000 +0200
15310 @@ -23,6 +23,10 @@
15311  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
15312  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
15313  
15314 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
15315 +#define MAP_MIRROR     0x20000
15316 +#endif
15317 +
15318  #define MS_ASYNC       1               /* sync memory asynchronously */
15319  #define MS_INVALIDATE  2               /* invalidate the caches */
15320  #define MS_SYNC                4               /* synchronous memory sync */
15321 diff -uNr linux-2.6.6/include/asm-i386/module.h linux-2.6.6.fixed/include/asm-i386/module.h
15322 --- linux-2.6.6/include/asm-i386/module.h       2004-05-10 04:32:01.000000000 +0200
15323 +++ linux-2.6.6.fixed/include/asm-i386/module.h 2004-05-11 11:28:59.000000000 +0200
15324 @@ -60,12 +60,18 @@
15325  #define MODULE_REGPARM ""
15326  #endif
15327  
15328 +#ifdef CONFIG_GRKERNSEC
15329 +#define MODULE_GRSEC "GRSECURITY "
15330 +#else
15331 +#define MODULE_GRSEC ""
15332 +#endif
15333 +  
15334  #ifdef CONFIG_4KSTACKS
15335  #define MODULE_STACKSIZE "4KSTACKS "
15336  #else
15337  #define MODULE_STACKSIZE ""
15338  #endif
15339  
15340 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
15341 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
15342  
15343  #endif /* _ASM_I386_MODULE_H */
15344 diff -uNr linux-2.6.6/include/asm-i386/page.h linux-2.6.6.fixed/include/asm-i386/page.h
15345 --- linux-2.6.6/include/asm-i386/page.h 2004-05-10 04:32:01.000000000 +0200
15346 +++ linux-2.6.6.fixed/include/asm-i386/page.h   2004-05-11 10:55:57.000000000 +0200
15347 @@ -120,6 +120,19 @@
15348  #define __PAGE_OFFSET          (0xC0000000UL)
15349  #endif
15350  
15351 +#ifdef CONFIG_PAX_KERNEXEC
15352 +#ifdef __ASSEMBLY__
15353 +#define __KERNEL_TEXT_OFFSET   (0xC0400000)
15354 +#else
15355 +#define __KERNEL_TEXT_OFFSET   (0xC0400000UL)
15356 +#endif
15357 +#else
15358 +#ifdef __ASSEMBLY__
15359 +#define __KERNEL_TEXT_OFFSET   (0)
15360 +#else
15361 +#define __KERNEL_TEXT_OFFSET   (0x0UL)
15362 +#endif
15363 +#endif
15364  
15365  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
15366  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
15367 @@ -139,6 +152,15 @@
15368  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
15369                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15370  
15371 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15372 +#ifdef CONFIG_PAX_MPROTECT
15373 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15374 +                         ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
15375 +#else
15376 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC))
15377 +#endif
15378 +#endif
15379 +
15380  #endif /* __KERNEL__ */
15381  
15382  #endif /* _I386_PAGE_H */
15383 diff -uNr linux-2.6.6/include/asm-i386/pgalloc.h linux-2.6.6.fixed/include/asm-i386/pgalloc.h
15384 --- linux-2.6.6/include/asm-i386/pgalloc.h      2004-05-10 04:31:59.000000000 +0200
15385 +++ linux-2.6.6.fixed/include/asm-i386/pgalloc.h        2004-05-11 10:55:57.000000000 +0200
15386 @@ -8,7 +8,7 @@
15387  #include <linux/mm.h>          /* for struct page */
15388  
15389  #define pmd_populate_kernel(mm, pmd, pte) \
15390 -               set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
15391 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
15392  
15393  static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
15394  {
15395 diff -uNr linux-2.6.6/include/asm-i386/pgtable.h linux-2.6.6.fixed/include/asm-i386/pgtable.h
15396 --- linux-2.6.6/include/asm-i386/pgtable.h      2004-05-10 04:32:54.000000000 +0200
15397 +++ linux-2.6.6.fixed/include/asm-i386/pgtable.h        2004-05-11 10:55:57.000000000 +0200
15398 @@ -32,6 +32,11 @@
15399  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
15400  extern unsigned long empty_zero_page[1024];
15401  extern pgd_t swapper_pg_dir[1024];
15402 +
15403 +#ifdef CONFIG_PAX_KERNEXEC
15404 +extern pgd_t kernexec_pg_dir[1024];
15405 +#endif
15406 +
15407  extern kmem_cache_t *pgd_cache;
15408  extern kmem_cache_t *pmd_cache;
15409  extern spinlock_t pgd_lock;
15410 @@ -136,6 +141,16 @@
15411  #define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
15412  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
15413  
15414 +#ifdef CONFIG_PAX_PAGEEXEC
15415 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
15416 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
15417 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
15418 +#else
15419 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
15420 +# define PAGE_COPY_NOEXEC      PAGE_COPY
15421 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
15422 +#endif
15423 +
15424  #define _PAGE_KERNEL \
15425         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
15426  
15427 @@ -155,18 +170,18 @@
15428   * This is the closest we can get..
15429   */
15430  #define __P000 PAGE_NONE
15431 -#define __P001 PAGE_READONLY
15432 -#define __P010 PAGE_COPY
15433 -#define __P011 PAGE_COPY
15434 +#define __P001 PAGE_READONLY_NOEXEC
15435 +#define __P010 PAGE_COPY_NOEXEC
15436 +#define __P011 PAGE_COPY_NOEXEC
15437  #define __P100 PAGE_READONLY
15438  #define __P101 PAGE_READONLY
15439  #define __P110 PAGE_COPY
15440  #define __P111 PAGE_COPY
15441  
15442  #define __S000 PAGE_NONE
15443 -#define __S001 PAGE_READONLY
15444 -#define __S010 PAGE_SHARED
15445 -#define __S011 PAGE_SHARED
15446 +#define __S001 PAGE_READONLY_NOEXEC
15447 +#define __S010 PAGE_SHARED_NOEXEC
15448 +#define __S011 PAGE_SHARED_NOEXEC
15449  #define __S100 PAGE_READONLY
15450  #define __S101 PAGE_READONLY
15451  #define __S110 PAGE_SHARED
15452 diff -uNr linux-2.6.6/include/asm-i386/processor.h linux-2.6.6.fixed/include/asm-i386/processor.h
15453 --- linux-2.6.6/include/asm-i386/processor.h    2004-05-10 04:31:59.000000000 +0200
15454 +++ linux-2.6.6.fixed/include/asm-i386/processor.h      2004-05-11 10:55:57.000000000 +0200
15455 @@ -296,10 +296,19 @@
15456   */
15457  #define TASK_SIZE      (PAGE_OFFSET)
15458  
15459 +#ifdef CONFIG_PAX_SEGMEXEC
15460 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
15461 +#endif
15462 +
15463  /* This decides where the kernel will search for a free chunk of vm
15464   * space during mmap's.
15465   */
15466 +
15467 +#ifdef CONFIG_PAX_SEGMEXEC
15468 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3:TASK_SIZE/3))
15469 +#else
15470  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
15471 +#endif
15472  
15473  /*
15474   * Size of io_bitmap, covering ports 0 to 0x3ff.
15475 @@ -626,7 +635,7 @@
15476  extern inline void prefetch(const void *x)
15477  {
15478         alternative_input(ASM_NOP4,
15479 -                         "prefetchnta (%1)",
15480 +                         "prefetchnta (%2)",
15481                           X86_FEATURE_XMM,
15482                           "r" (x));
15483  }
15484 @@ -640,7 +649,7 @@
15485  extern inline void prefetchw(const void *x)
15486  {
15487         alternative_input(ASM_NOP4,
15488 -                         "prefetchw (%1)",
15489 +                         "prefetchw (%2)",
15490                           X86_FEATURE_3DNOW,
15491                           "r" (x));
15492  }
15493 diff -uNr linux-2.6.6/include/asm-i386/system.h linux-2.6.6.fixed/include/asm-i386/system.h
15494 --- linux-2.6.6/include/asm-i386/system.h       2004-05-10 04:31:58.000000000 +0200
15495 +++ linux-2.6.6.fixed/include/asm-i386/system.h 2004-05-11 10:55:57.000000000 +0200
15496 @@ -5,6 +5,7 @@
15497  #include <linux/kernel.h>
15498  #include <asm/segment.h>
15499  #include <asm/cpufeature.h>
15500 +#include <asm/page.h>
15501  #include <linux/bitops.h> /* for LOCK_PREFIX */
15502  
15503  #ifdef __KERNEL__
15504 @@ -301,7 +302,7 @@
15505         asm volatile ("661:\n\t" oldinstr "\n662:\n"                 \
15506                       ".section .altinstructions,\"a\"\n"            \
15507                       "  .align 4\n"                                   \
15508 -                     "  .long 661b\n"            /* label */          \
15509 +                     "  .long 661b + %c1\n"       /* label */          \
15510                       "  .long 663f\n"            /* new instruction */         \
15511                       "  .byte %c0\n"             /* feature bit */    \
15512                       "  .byte 662b-661b\n"       /* sourcelen */      \
15513 @@ -309,7 +310,7 @@
15514                       ".previous\n"                                             \
15515                       ".section .altinstr_replacement,\"ax\"\n"                 \
15516                       "663:\n\t" newinstr "\n664:\n"   /* replacement */    \
15517 -                     ".previous" :: "i" (feature) : "memory")  
15518 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET) : "memory")  
15519  
15520  /*
15521   * Alternative inline assembly with input.
15522 @@ -325,7 +326,7 @@
15523         asm volatile ("661:\n\t" oldinstr "\n662:\n"                            \
15524                       ".section .altinstructions,\"a\"\n"                       \
15525                       "  .align 4\n"                                            \
15526 -                     "  .long 661b\n"            /* label */                   \
15527 +                     "  .long 661b + %c1\n"      /* label */                   \
15528                       "  .long 663f\n"            /* new instruction */         \
15529                       "  .byte %c0\n"             /* feature bit */             \
15530                       "  .byte 662b-661b\n"       /* sourcelen */               \
15531 @@ -333,7 +334,7 @@
15532                       ".previous\n"                                             \
15533                       ".section .altinstr_replacement,\"ax\"\n"                 \
15534                       "663:\n\t" newinstr "\n664:\n"   /* replacement */        \
15535 -                     ".previous" :: "i" (feature), input)  
15536 +                     ".previous" :: "i" (feature), "i" (__KERNEL_TEXT_OFFSET), input)  
15537  
15538  /*
15539   * Force strict CPU ordering.
15540 diff -uNr linux-2.6.6/include/asm-ia64/elf.h linux-2.6.6.fixed/include/asm-ia64/elf.h
15541 --- linux-2.6.6/include/asm-ia64/elf.h  2004-05-10 04:32:53.000000000 +0200
15542 +++ linux-2.6.6.fixed/include/asm-ia64/elf.h    2004-05-11 10:55:57.000000000 +0200
15543 @@ -162,6 +162,16 @@
15544  typedef struct ia64_fpreg elf_fpreg_t;
15545  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
15546  
15547 +#ifdef CONFIG_PAX_ASLR
15548 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
15549 +
15550 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
15551 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
15552 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
15553 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
15554 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
15555 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 43 - PAGE_SHIFT)
15556 +#endif
15557  
15558  
15559  struct pt_regs;        /* forward declaration... */
15560 diff -uNr linux-2.6.6/include/asm-ia64/mman.h linux-2.6.6.fixed/include/asm-ia64/mman.h
15561 --- linux-2.6.6/include/asm-ia64/mman.h 2004-05-10 04:32:37.000000000 +0200
15562 +++ linux-2.6.6.fixed/include/asm-ia64/mman.h   2004-05-11 10:55:57.000000000 +0200
15563 @@ -31,6 +31,10 @@
15564  #define MAP_POPULATE   0x08000         /* populate (prefault) pagetables */
15565  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
15566  
15567 +#ifdef CONFIG_PAX_RANDEXEC
15568 +#define MAP_MIRROR     0x40000
15569 +#endif
15570 +
15571  #define MS_ASYNC       1               /* sync memory asynchronously */
15572  #define MS_INVALIDATE  2               /* invalidate the caches */
15573  #define MS_SYNC                4               /* synchronous memory sync */
15574 diff -uNr linux-2.6.6/include/asm-ia64/page.h linux-2.6.6.fixed/include/asm-ia64/page.h
15575 --- linux-2.6.6/include/asm-ia64/page.h 2004-05-10 04:32:01.000000000 +0200
15576 +++ linux-2.6.6.fixed/include/asm-ia64/page.h   2004-05-11 10:55:57.000000000 +0200
15577 @@ -187,4 +187,13 @@
15578                                          (((current->thread.flags & IA64_THREAD_XSTACK) != 0)   \
15579                                           ? VM_EXEC : 0))
15580  
15581 +#ifdef CONFIG_PAX_PAGEEXEC
15582 +#ifdef CONFIG_PAX_MPROTECT
15583 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15584 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15585 +#else
15586 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15587 +#endif
15588 +#endif
15589 +
15590  #endif /* _ASM_IA64_PAGE_H */
15591 diff -uNr linux-2.6.6/include/asm-ia64/pgtable.h linux-2.6.6.fixed/include/asm-ia64/pgtable.h
15592 --- linux-2.6.6/include/asm-ia64/pgtable.h      2004-05-10 04:32:27.000000000 +0200
15593 +++ linux-2.6.6.fixed/include/asm-ia64/pgtable.h        2004-05-11 11:26:44.000000000 +0200
15594 @@ -120,6 +120,17 @@
15595  #define PAGE_SHARED    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
15596  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
15597  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
15598 +
15599 +#ifdef CONFIG_PAX_PAGEEXEC
15600 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
15601 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
15602 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
15603 +#else
15604 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
15605 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
15606 +# define PAGE_COPY_NOEXEC      PAGE_COPY
15607 +#endif
15608 +
15609  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
15610  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
15611  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
15612 diff -uNr linux-2.6.6/include/asm-ia64/ustack.h linux-2.6.6.fixed/include/asm-ia64/ustack.h
15613 --- linux-2.6.6/include/asm-ia64/ustack.h       2004-05-10 04:33:20.000000000 +0200
15614 +++ linux-2.6.6.fixed/include/asm-ia64/ustack.h 2004-05-11 10:55:57.000000000 +0200
15615 @@ -11,6 +11,6 @@
15616  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
15617  /* Make a default stack size of 2GB */
15618  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
15619 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
15620 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
15621  
15622  #endif /* _ASM_IA64_USTACK_H */
15623 diff -uNr linux-2.6.6/include/asm-mips/a.out.h linux-2.6.6.fixed/include/asm-mips/a.out.h
15624 --- linux-2.6.6/include/asm-mips/a.out.h        2004-05-10 04:32:28.000000000 +0200
15625 +++ linux-2.6.6.fixed/include/asm-mips/a.out.h  2004-05-11 10:55:57.000000000 +0200
15626 @@ -36,10 +36,10 @@
15627  #ifdef __KERNEL__
15628  
15629  #ifdef CONFIG_MIPS32
15630 -#define STACK_TOP      TASK_SIZE
15631 +#define __STACK_TOP    TASK_SIZE
15632  #endif
15633  #ifdef CONFIG_MIPS64
15634 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
15635 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
15636  #endif
15637  
15638  #endif
15639 diff -uNr linux-2.6.6/include/asm-mips/elf.h linux-2.6.6.fixed/include/asm-mips/elf.h
15640 --- linux-2.6.6/include/asm-mips/elf.h  2004-05-10 04:32:29.000000000 +0200
15641 +++ linux-2.6.6.fixed/include/asm-mips/elf.h    2004-05-11 10:55:57.000000000 +0200
15642 @@ -273,4 +273,15 @@
15643  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
15644  #endif
15645  
15646 +#ifdef CONFIG_PAX_ASLR
15647 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
15648 +
15649 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
15650 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
15651 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
15652 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
15653 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
15654 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
15655 +#endif
15656 +
15657  #endif /* _ASM_ELF_H */
15658 diff -uNr linux-2.6.6/include/asm-mips/page.h linux-2.6.6.fixed/include/asm-mips/page.h
15659 --- linux-2.6.6/include/asm-mips/page.h 2004-05-10 04:32:28.000000000 +0200
15660 +++ linux-2.6.6.fixed/include/asm-mips/page.h   2004-05-11 10:55:57.000000000 +0200
15661 @@ -124,6 +124,15 @@
15662  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
15663                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15664  
15665 +#ifdef CONFIG_PAX_PAGEEXEC
15666 +#ifdef CONFIG_PAX_MPROTECT
15667 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15668 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15669 +#else
15670 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15671 +#endif
15672 +#endif
15673 +
15674  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
15675  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
15676  
15677 diff -uNr linux-2.6.6/include/asm-parisc/a.out.h linux-2.6.6.fixed/include/asm-parisc/a.out.h
15678 --- linux-2.6.6/include/asm-parisc/a.out.h      2004-05-10 04:33:20.000000000 +0200
15679 +++ linux-2.6.6.fixed/include/asm-parisc/a.out.h        2004-05-11 10:55:57.000000000 +0200
15680 @@ -22,7 +22,7 @@
15681  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
15682   * prumpf */
15683  
15684 -#define STACK_TOP      TASK_SIZE
15685 +#define __STACK_TOP    TASK_SIZE
15686  
15687  #endif
15688  
15689 diff -uNr linux-2.6.6/include/asm-parisc/elf.h linux-2.6.6.fixed/include/asm-parisc/elf.h
15690 --- linux-2.6.6/include/asm-parisc/elf.h        2004-05-10 04:32:54.000000000 +0200
15691 +++ linux-2.6.6.fixed/include/asm-parisc/elf.h  2004-05-11 10:55:57.000000000 +0200
15692 @@ -337,6 +337,17 @@
15693  
15694  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
15695  
15696 +#ifdef CONFIG_PAX_ASLR
15697 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
15698 +
15699 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
15700 +#define PAX_DELTA_MMAP_LEN(tsk)                16
15701 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT 
15702 +#define PAX_DELTA_EXEC_LEN(tsk)                16
15703 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
15704 +#define PAX_DELTA_STACK_LEN(tsk)       16
15705 +#endif
15706 +
15707  /* This yields a mask that user programs can use to figure out what
15708     instruction set this CPU supports.  This could be done in user space,
15709     but it's not easy, and we've already done it here.  */
15710 diff -uNr linux-2.6.6/include/asm-parisc/mman.h linux-2.6.6.fixed/include/asm-parisc/mman.h
15711 --- linux-2.6.6/include/asm-parisc/mman.h       2004-05-10 04:32:52.000000000 +0200
15712 +++ linux-2.6.6.fixed/include/asm-parisc/mman.h 2004-05-11 10:55:57.000000000 +0200
15713 @@ -23,6 +23,10 @@
15714  #define MAP_POPULATE   0x10000         /* populate (prefault) pagetables */
15715  #define MAP_NONBLOCK   0x20000         /* do not block on IO */
15716  
15717 +#ifdef CONFIG_PAX_RANDEXEC
15718 +#define MAP_MIRROR     0x0400
15719 +#endif
15720 +
15721  #define MS_SYNC                1               /* synchronous memory sync */
15722  #define MS_ASYNC       2               /* sync memory asynchronously */
15723  #define MS_INVALIDATE  4               /* invalidate the caches */
15724 diff -uNr linux-2.6.6/include/asm-parisc/page.h linux-2.6.6.fixed/include/asm-parisc/page.h
15725 --- linux-2.6.6/include/asm-parisc/page.h       2004-05-10 04:32:19.000000000 +0200
15726 +++ linux-2.6.6.fixed/include/asm-parisc/page.h 2004-05-11 10:55:57.000000000 +0200
15727 @@ -113,6 +113,15 @@
15728  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
15729                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15730  
15731 +#ifdef CONFIG_PAX_PAGEEXEC
15732 +#ifdef CONFIG_PAX_MPROTECT
15733 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15734 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15735 +#else
15736 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15737 +#endif
15738 +#endif
15739 +
15740  #endif /* __KERNEL__ */
15741  
15742  #endif /* _PARISC_PAGE_H */
15743 diff -uNr linux-2.6.6/include/asm-parisc/pgtable.h linux-2.6.6.fixed/include/asm-parisc/pgtable.h
15744 --- linux-2.6.6/include/asm-parisc/pgtable.h    2004-05-10 04:33:19.000000000 +0200
15745 +++ linux-2.6.6.fixed/include/asm-parisc/pgtable.h      2004-05-11 10:55:57.000000000 +0200
15746 @@ -179,6 +179,17 @@
15747  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
15748  #define PAGE_COPY       PAGE_EXECREAD
15749  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
15750 +
15751 +#ifdef CONFIG_PAX_PAGEEXEC
15752 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
15753 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
15754 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
15755 +#else
15756 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
15757 +# define PAGE_COPY_NOEXEC      PAGE_COPY
15758 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
15759 +#endif
15760 +
15761  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
15762  #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
15763  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
15764 diff -uNr linux-2.6.6/include/asm-ppc/a.out.h linux-2.6.6.fixed/include/asm-ppc/a.out.h
15765 --- linux-2.6.6/include/asm-ppc/a.out.h 2004-05-10 04:32:37.000000000 +0200
15766 +++ linux-2.6.6.fixed/include/asm-ppc/a.out.h   2004-05-11 10:55:57.000000000 +0200
15767 @@ -2,7 +2,7 @@
15768  #define __PPC_A_OUT_H__
15769  
15770  /* grabbed from the intel stuff  */
15771 -#define STACK_TOP TASK_SIZE
15772 +#define __STACK_TOP TASK_SIZE
15773  
15774  
15775  struct exec
15776 diff -uNr linux-2.6.6/include/asm-ppc/elf.h linux-2.6.6.fixed/include/asm-ppc/elf.h
15777 --- linux-2.6.6/include/asm-ppc/elf.h   2004-05-10 04:31:57.000000000 +0200
15778 +++ linux-2.6.6.fixed/include/asm-ppc/elf.h     2004-05-11 10:55:57.000000000 +0200
15779 @@ -89,6 +89,17 @@
15780  
15781  #define ELF_ET_DYN_BASE         (0x08000000)
15782  
15783 +#ifdef CONFIG_PAX_ASLR
15784 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
15785 +
15786 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
15787 +#define PAX_DELTA_MMAP_LEN(tsk)                15
15788 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
15789 +#define PAX_DELTA_EXEC_LEN(tsk)                15
15790 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
15791 +#define PAX_DELTA_STACK_LEN(tsk)       15
15792 +#endif
15793 +
15794  #define USE_ELF_CORE_DUMP
15795  #define ELF_EXEC_PAGESIZE      4096
15796  
15797 diff -uNr linux-2.6.6/include/asm-ppc/mman.h linux-2.6.6.fixed/include/asm-ppc/mman.h
15798 --- linux-2.6.6/include/asm-ppc/mman.h  2004-05-10 04:33:22.000000000 +0200
15799 +++ linux-2.6.6.fixed/include/asm-ppc/mman.h    2004-05-11 10:55:57.000000000 +0200
15800 @@ -24,6 +24,10 @@
15801  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
15802  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
15803  
15804 +#ifdef CONFIG_PAX_RANDEXEC
15805 +#define MAP_MIRROR     0x0200
15806 +#endif
15807 +
15808  #define MS_ASYNC       1               /* sync memory asynchronously */
15809  #define MS_INVALIDATE  2               /* invalidate the caches */
15810  #define MS_SYNC                4               /* synchronous memory sync */
15811 diff -uNr linux-2.6.6/include/asm-ppc/page.h linux-2.6.6.fixed/include/asm-ppc/page.h
15812 --- linux-2.6.6/include/asm-ppc/page.h  2004-05-10 04:32:26.000000000 +0200
15813 +++ linux-2.6.6.fixed/include/asm-ppc/page.h    2004-05-11 10:55:57.000000000 +0200
15814 @@ -163,5 +163,14 @@
15815  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
15816                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15817  
15818 +#ifdef CONFIG_PAX_PAGEEXEC
15819 +#ifdef CONFIG_PAX_MPROTECT
15820 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15821 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15822 +#else
15823 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15824 +#endif
15825 +#endif
15826 +
15827  #endif /* __KERNEL__ */
15828  #endif /* _PPC_PAGE_H */
15829 diff -uNr linux-2.6.6/include/asm-ppc/pgtable.h linux-2.6.6.fixed/include/asm-ppc/pgtable.h
15830 --- linux-2.6.6/include/asm-ppc/pgtable.h       2004-05-10 04:32:25.000000000 +0200
15831 +++ linux-2.6.6.fixed/include/asm-ppc/pgtable.h 2004-05-11 10:55:57.000000000 +0200
15832 @@ -349,11 +349,21 @@
15833  
15834  #define PAGE_NONE      __pgprot(_PAGE_BASE)
15835  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
15836 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
15837 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
15838  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
15839 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
15840 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
15841  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
15842 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
15843 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
15844 +
15845 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
15846 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
15847 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
15848 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
15849 +#else
15850 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
15851 +# define PAGE_COPY_NOEXEC      PAGE_COPY
15852 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
15853 +#endif
15854  
15855  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
15856  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
15857 @@ -365,21 +375,21 @@
15858   * This is the closest we can get..
15859   */
15860  #define __P000 PAGE_NONE
15861 -#define __P001 PAGE_READONLY_X
15862 -#define __P010 PAGE_COPY
15863 -#define __P011 PAGE_COPY_X
15864 -#define __P100 PAGE_READONLY
15865 +#define __P001 PAGE_READONLY_NOEXEC
15866 +#define __P010 PAGE_COPY_NOEXEC
15867 +#define __P011 PAGE_COPY_NOEXEC
15868 +#define __P100 PAGE_READONLY_X
15869  #define __P101 PAGE_READONLY_X
15870 -#define __P110 PAGE_COPY
15871 +#define __P110 PAGE_COPY_X
15872  #define __P111 PAGE_COPY_X
15873  
15874  #define __S000 PAGE_NONE
15875 -#define __S001 PAGE_READONLY_X
15876 -#define __S010 PAGE_SHARED
15877 -#define __S011 PAGE_SHARED_X
15878 -#define __S100 PAGE_READONLY
15879 +#define __S001 PAGE_READONLY_NOEXEC
15880 +#define __S010 PAGE_SHARED_NOEXEC
15881 +#define __S011 PAGE_SHARED_NOEXEC
15882 +#define __S100 PAGE_READONLY_X
15883  #define __S101 PAGE_READONLY_X
15884 -#define __S110 PAGE_SHARED
15885 +#define __S110 PAGE_SHARED_X
15886  #define __S111 PAGE_SHARED_X
15887  
15888  #ifndef __ASSEMBLY__
15889 diff -uNr linux-2.6.6/include/asm-sparc/a.out.h linux-2.6.6.fixed/include/asm-sparc/a.out.h
15890 --- linux-2.6.6/include/asm-sparc/a.out.h       2004-05-10 04:31:59.000000000 +0200
15891 +++ linux-2.6.6.fixed/include/asm-sparc/a.out.h 2004-05-11 10:55:57.000000000 +0200
15892 @@ -91,7 +91,7 @@
15893  
15894  #include <asm/page.h>
15895  
15896 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
15897 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
15898  
15899  #endif /* __KERNEL__ */
15900  
15901 diff -uNr linux-2.6.6/include/asm-sparc/elf.h linux-2.6.6.fixed/include/asm-sparc/elf.h
15902 --- linux-2.6.6/include/asm-sparc/elf.h 2004-05-10 04:33:13.000000000 +0200
15903 +++ linux-2.6.6.fixed/include/asm-sparc/elf.h   2004-05-11 10:55:57.000000000 +0200
15904 @@ -145,6 +145,17 @@
15905  
15906  #define ELF_ET_DYN_BASE         (0x08000000)
15907  
15908 +#ifdef CONFIG_PAX_ASLR
15909 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
15910 +
15911 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
15912 +#define PAX_DELTA_MMAP_LEN(tsk)                16
15913 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
15914 +#define PAX_DELTA_EXEC_LEN(tsk)                16
15915 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
15916 +#define PAX_DELTA_STACK_LEN(tsk)       16
15917 +#endif
15918 +
15919  /* This yields a mask that user programs can use to figure out what
15920     instruction set this cpu supports.  This can NOT be done in userspace
15921     on Sparc.  */
15922 diff -uNr linux-2.6.6/include/asm-sparc/mman.h linux-2.6.6.fixed/include/asm-sparc/mman.h
15923 --- linux-2.6.6/include/asm-sparc/mman.h        2004-05-10 04:33:20.000000000 +0200
15924 +++ linux-2.6.6.fixed/include/asm-sparc/mman.h  2004-05-11 10:55:57.000000000 +0200
15925 @@ -27,6 +27,10 @@
15926  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
15927  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
15928  
15929 +#ifdef CONFIG_PAX_RANDEXEC
15930 +#define MAP_MIRROR     0x0400
15931 +#endif
15932 +
15933  #define MS_ASYNC       1               /* sync memory asynchronously */
15934  #define MS_INVALIDATE  2               /* invalidate the caches */
15935  #define MS_SYNC                4               /* synchronous memory sync */
15936 diff -uNr linux-2.6.6/include/asm-sparc/page.h linux-2.6.6.fixed/include/asm-sparc/page.h
15937 --- linux-2.6.6/include/asm-sparc/page.h        2004-05-10 04:32:26.000000000 +0200
15938 +++ linux-2.6.6.fixed/include/asm-sparc/page.h  2004-05-11 10:55:57.000000000 +0200
15939 @@ -176,6 +176,15 @@
15940  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
15941                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15942  
15943 +#ifdef CONFIG_PAX_PAGEEXEC
15944 +#ifdef CONFIG_PAX_MPROTECT
15945 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
15946 +                        ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15947 +#else
15948 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
15949 +#endif
15950 +#endif
15951 +
15952  #endif /* __KERNEL__ */
15953  
15954  #endif /* _SPARC_PAGE_H */
15955 diff -uNr linux-2.6.6/include/asm-sparc/pgtable.h linux-2.6.6.fixed/include/asm-sparc/pgtable.h
15956 --- linux-2.6.6/include/asm-sparc/pgtable.h     2004-05-10 04:32:38.000000000 +0200
15957 +++ linux-2.6.6.fixed/include/asm-sparc/pgtable.h       2004-05-11 10:55:57.000000000 +0200
15958 @@ -110,6 +110,13 @@
15959  BTFIXUPDEF_INT(page_shared)
15960  BTFIXUPDEF_INT(page_copy)
15961  BTFIXUPDEF_INT(page_readonly)
15962 +
15963 +#ifdef CONFIG_PAX_PAGEEXEC
15964 +BTFIXUPDEF_INT(page_shared_noexec)
15965 +BTFIXUPDEF_INT(page_copy_noexec)
15966 +BTFIXUPDEF_INT(page_readonly_noexec)
15967 +#endif
15968 +
15969  BTFIXUPDEF_INT(page_kernel)
15970  
15971  #define PMD_SHIFT              BTFIXUP_SIMM13(pmd_shift)
15972 @@ -131,6 +138,16 @@
15973  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
15974  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
15975  
15976 +#ifdef CONFIG_PAX_PAGEEXEC
15977 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
15978 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
15979 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
15980 +#else
15981 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
15982 +# define PAGE_COPY_NOEXEC      PAGE_COPY
15983 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
15984 +#endif
15985 +
15986  extern unsigned long page_kernel;
15987  
15988  #ifdef MODULE
15989 diff -uNr linux-2.6.6/include/asm-sparc/pgtsrmmu.h linux-2.6.6.fixed/include/asm-sparc/pgtsrmmu.h
15990 --- linux-2.6.6/include/asm-sparc/pgtsrmmu.h    2004-05-10 04:32:27.000000000 +0200
15991 +++ linux-2.6.6.fixed/include/asm-sparc/pgtsrmmu.h      2004-05-11 10:55:57.000000000 +0200
15992 @@ -119,6 +119,16 @@
15993                                     SRMMU_EXEC | SRMMU_REF)
15994  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
15995                                     SRMMU_EXEC | SRMMU_REF)
15996 +
15997 +#ifdef CONFIG_PAX_PAGEEXEC
15998 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
15999 +                                          SRMMU_WRITE | SRMMU_REF)
16000 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
16001 +                                          SRMMU_REF)
16002 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
16003 +                                          SRMMU_REF)
16004 +#endif
16005 +
16006  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
16007                                     SRMMU_DIRTY | SRMMU_REF)
16008  
16009 diff -uNr linux-2.6.6/include/asm-sparc/uaccess.h linux-2.6.6.fixed/include/asm-sparc/uaccess.h
16010 --- linux-2.6.6/include/asm-sparc/uaccess.h     2004-05-10 04:33:19.000000000 +0200
16011 +++ linux-2.6.6.fixed/include/asm-sparc/uaccess.h       2004-05-11 10:55:57.000000000 +0200
16012 @@ -41,7 +41,7 @@
16013   * No one can read/write anything from userland in the kernel space by setting
16014   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
16015   */
16016 -#define __user_ok(addr,size) ((addr) < STACK_TOP)
16017 +#define __user_ok(addr,size) ((addr) < __STACK_TOP)
16018  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
16019  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
16020  #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
16021 diff -uNr linux-2.6.6/include/asm-sparc64/a.out.h linux-2.6.6.fixed/include/asm-sparc64/a.out.h
16022 --- linux-2.6.6/include/asm-sparc64/a.out.h     2004-05-10 04:32:54.000000000 +0200
16023 +++ linux-2.6.6.fixed/include/asm-sparc64/a.out.h       2004-05-11 10:55:57.000000000 +0200
16024 @@ -95,7 +95,7 @@
16025  
16026  #ifdef __KERNEL__
16027  
16028 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
16029 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
16030  
16031  #endif
16032  
16033 diff -uNr linux-2.6.6/include/asm-sparc64/elf.h linux-2.6.6.fixed/include/asm-sparc64/elf.h
16034 --- linux-2.6.6/include/asm-sparc64/elf.h       2004-05-10 04:32:27.000000000 +0200
16035 +++ linux-2.6.6.fixed/include/asm-sparc64/elf.h 2004-05-11 10:55:57.000000000 +0200
16036 @@ -140,6 +140,16 @@
16037  #define ELF_ET_DYN_BASE         0x0000010000000000UL
16038  #endif
16039  
16040 +#ifdef CONFIG_PAX_ASLR
16041 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
16042 +
16043 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
16044 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
16045 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
16046 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
16047 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
16048 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
16049 +#endif
16050  
16051  /* This yields a mask that user programs can use to figure out what
16052     instruction set this cpu supports.  */
16053 diff -uNr linux-2.6.6/include/asm-sparc64/mman.h linux-2.6.6.fixed/include/asm-sparc64/mman.h
16054 --- linux-2.6.6/include/asm-sparc64/mman.h      2004-05-10 04:32:29.000000000 +0200
16055 +++ linux-2.6.6.fixed/include/asm-sparc64/mman.h        2004-05-11 10:55:57.000000000 +0200
16056 @@ -27,6 +27,10 @@
16057  #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
16058  #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
16059  
16060 +#ifdef CONFIG_PAX_RANDEXEC
16061 +#define MAP_MIRROR     0x0400
16062 +#endif
16063 +
16064  #define MS_ASYNC       1               /* sync memory asynchronously */
16065  #define MS_INVALIDATE  2               /* invalidate the caches */
16066  #define MS_SYNC                4               /* synchronous memory sync */
16067 diff -uNr linux-2.6.6/include/asm-sparc64/page.h linux-2.6.6.fixed/include/asm-sparc64/page.h
16068 --- linux-2.6.6/include/asm-sparc64/page.h      2004-05-10 04:32:28.000000000 +0200
16069 +++ linux-2.6.6.fixed/include/asm-sparc64/page.h        2004-05-11 10:55:57.000000000 +0200
16070 @@ -174,6 +174,15 @@
16071  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
16072                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16073  
16074 +#ifdef CONFIG_PAX_PAGEEXEC
16075 +#ifdef CONFIG_PAX_MPROTECT
16076 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
16077 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
16078 +#else
16079 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
16080 +#endif
16081 +#endif
16082 +
16083  #endif /* !(__KERNEL__) */
16084  
16085  #endif /* !(_SPARC64_PAGE_H) */
16086 diff -uNr linux-2.6.6/include/asm-sparc64/pgtable.h linux-2.6.6.fixed/include/asm-sparc64/pgtable.h
16087 --- linux-2.6.6/include/asm-sparc64/pgtable.h   2004-05-10 04:31:58.000000000 +0200
16088 +++ linux-2.6.6.fixed/include/asm-sparc64/pgtable.h     2004-05-11 10:55:57.000000000 +0200
16089 @@ -124,7 +124,8 @@
16090  
16091  /* Here are the SpitFire software bits we use in the TTE's. */
16092  #define _PAGE_FILE     0x0000000000001000      /* Pagecache page                     */
16093 -#define _PAGE_MODIFIED 0x0000000000000800      /* Modified Page (ie. dirty)          */
16094 +#define _PAGE_MODIFIED 0x0000000000001000      /* Modified Page (ie. dirty)          */
16095 +#define _PAGE_EXEC     0x0000000000000800      /* Executable SW Bit                  */
16096  #define _PAGE_ACCESSED 0x0000000000000400      /* Accessed Page (ie. referenced)     */
16097  #define _PAGE_READ     0x0000000000000200      /* Readable SW Bit                    */
16098  #define _PAGE_WRITE    0x0000000000000100      /* Writable SW Bit                    */
16099 @@ -160,34 +161,48 @@
16100  
16101  /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
16102  #define PAGE_SHARED    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
16103 -                                 __ACCESS_BITS | _PAGE_WRITE)
16104 +                                 __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
16105  
16106  #define PAGE_COPY      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
16107 -                                 __ACCESS_BITS)
16108 +                                 __ACCESS_BITS | _PAGE_EXEC)
16109  
16110  #define PAGE_READONLY  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
16111 -                                 __ACCESS_BITS)
16112 +                                 __ACCESS_BITS | _PAGE_EXEC)
16113  
16114  #define PAGE_KERNEL    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
16115 -                                 __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
16116 +                                 __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS | \
16117 +                                 _PAGE_EXEC)
16118 +
16119 +#ifdef CONFIG_PAX_PAGEEXEC
16120 +# define PAGE_SHARED_NOEXEC    __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
16121 +                                         __ACCESS_BITS | _PAGE_WRITE)
16122 +# define PAGE_COPY_NOEXEC      __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
16123 +                                         __ACCESS_BITS)
16124 +# define PAGE_READONLY_NOEXEC  __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
16125 +                                         __ACCESS_BITS)
16126 +#else
16127 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
16128 +# define PAGE_COPY_NOEXEC      PAGE_COPY
16129 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
16130 +#endif
16131  
16132  #define _PFN_MASK      _PAGE_PADDR
16133  
16134  #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
16135  
16136  #define __P000 PAGE_NONE
16137 -#define __P001 PAGE_READONLY
16138 -#define __P010 PAGE_COPY
16139 -#define __P011 PAGE_COPY
16140 +#define __P001 PAGE_READONLY_NOEXEC
16141 +#define __P010 PAGE_COPY_NOEXEC
16142 +#define __P011 PAGE_COPY_NOEXEC
16143  #define __P100 PAGE_READONLY
16144  #define __P101 PAGE_READONLY
16145  #define __P110 PAGE_COPY
16146  #define __P111 PAGE_COPY
16147  
16148  #define __S000 PAGE_NONE
16149 -#define __S001 PAGE_READONLY
16150 -#define __S010 PAGE_SHARED
16151 -#define __S011 PAGE_SHARED
16152 +#define __S001 PAGE_READONLY_NOEXEC
16153 +#define __S010 PAGE_SHARED_NOEXEC
16154 +#define __S011 PAGE_SHARED_NOEXEC
16155  #define __S100 PAGE_READONLY
16156  #define __S101 PAGE_READONLY
16157  #define __S110 PAGE_SHARED
16158 diff -uNr linux-2.6.6/include/asm-x86_64/a.out.h linux-2.6.6.fixed/include/asm-x86_64/a.out.h
16159 --- linux-2.6.6/include/asm-x86_64/a.out.h      2004-05-10 04:32:29.000000000 +0200
16160 +++ linux-2.6.6.fixed/include/asm-x86_64/a.out.h        2004-05-11 10:55:57.000000000 +0200
16161 @@ -21,7 +21,7 @@
16162  
16163  #ifdef __KERNEL__
16164  #include <linux/thread_info.h>
16165 -#define STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
16166 +#define __STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
16167  #endif
16168  
16169  #endif /* __A_OUT_GNU_H__ */
16170 diff -uNr linux-2.6.6/include/asm-x86_64/elf.h linux-2.6.6.fixed/include/asm-x86_64/elf.h
16171 --- linux-2.6.6/include/asm-x86_64/elf.h        2004-05-10 04:33:13.000000000 +0200
16172 +++ linux-2.6.6.fixed/include/asm-x86_64/elf.h  2004-05-11 10:55:58.000000000 +0200
16173 @@ -89,6 +89,17 @@
16174  
16175  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
16176  
16177 +#ifdef CONFIG_PAX_ASLR
16178 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
16179 +
16180 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
16181 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
16182 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
16183 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 24)
16184 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
16185 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 24)
16186 +#endif
16187 +
16188  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
16189     now struct_user_regs, they are different). Assumes current is the process
16190     getting dumped. */
16191 diff -uNr linux-2.6.6/include/asm-x86_64/mman.h linux-2.6.6.fixed/include/asm-x86_64/mman.h
16192 --- linux-2.6.6/include/asm-x86_64/mman.h       2004-05-10 04:32:53.000000000 +0200
16193 +++ linux-2.6.6.fixed/include/asm-x86_64/mman.h 2004-05-11 10:55:58.000000000 +0200
16194 @@ -24,6 +24,10 @@
16195  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
16196  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
16197  
16198 +#ifdef CONFIG_PAX_RANDEXEC
16199 +#define MAP_MIRROR     0x8000
16200 +#endif
16201 +
16202  #define MS_ASYNC       1               /* sync memory asynchronously */
16203  #define MS_INVALIDATE  2               /* invalidate the caches */
16204  #define MS_SYNC                4               /* synchronous memory sync */
16205 diff -uNr linux-2.6.6/include/asm-x86_64/page.h linux-2.6.6.fixed/include/asm-x86_64/page.h
16206 --- linux-2.6.6/include/asm-x86_64/page.h       2004-05-10 04:31:59.000000000 +0200
16207 +++ linux-2.6.6.fixed/include/asm-x86_64/page.h 2004-05-11 10:55:58.000000000 +0200
16208 @@ -127,6 +127,16 @@
16209  
16210  #define __VM_DATA_DEFAULT_FLAGS        (VM_READ | VM_WRITE | VM_EXEC | \
16211                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16212 +
16213 +#ifdef CONFIG_PAX_PAGEEXEC
16214 +#define VM_DATA_DEFAULT_FLAGS __VM_DATA_DEFAULT_FLAGS
16215 +#ifdef CONFIG_PAX_MPROTECT
16216 +#define __VM_STACK_FLAGS (((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
16217 +                         ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
16218 +#else
16219 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->flags & PF_PAX_PAGEEXEC)?0:VM_EXEC))
16220 +#endif
16221 +#else
16222  #define __VM_STACK_FLAGS       (VM_GROWSDOWN | VM_READ | VM_WRITE | VM_EXEC | \
16223                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16224  
16225 @@ -137,6 +147,8 @@
16226  #define VM_STACK_DEFAULT_FLAGS \
16227         (test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags) 
16228         
16229 +#endif
16230 +
16231  #define CONFIG_ARCH_GATE_AREA 1        
16232  
16233  #ifndef __ASSEMBLY__
16234 diff -uNr linux-2.6.6/include/asm-x86_64/pgalloc.h linux-2.6.6.fixed/include/asm-x86_64/pgalloc.h
16235 --- linux-2.6.6/include/asm-x86_64/pgalloc.h    2004-05-10 04:32:37.000000000 +0200
16236 +++ linux-2.6.6.fixed/include/asm-x86_64/pgalloc.h      2004-05-11 10:55:58.000000000 +0200
16237 @@ -8,7 +8,7 @@
16238  #include <linux/mm.h>
16239  
16240  #define pmd_populate_kernel(mm, pmd, pte) \
16241 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
16242 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
16243  #define pgd_populate(mm, pgd, pmd) \
16244                 set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pmd)))
16245  
16246 diff -uNr linux-2.6.6/include/asm-x86_64/pgtable.h linux-2.6.6.fixed/include/asm-x86_64/pgtable.h
16247 --- linux-2.6.6/include/asm-x86_64/pgtable.h    2004-05-10 04:32:54.000000000 +0200
16248 +++ linux-2.6.6.fixed/include/asm-x86_64/pgtable.h      2004-05-11 10:55:58.000000000 +0200
16249 @@ -170,6 +170,10 @@
16250  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
16251  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
16252  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
16253 +
16254 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
16255 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
16256 +
16257  #define __PAGE_KERNEL \
16258         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
16259  #define __PAGE_KERNEL_EXECUTABLE \
16260 diff -uNr linux-2.6.6/include/linux/a.out.h linux-2.6.6.fixed/include/linux/a.out.h
16261 --- linux-2.6.6/include/linux/a.out.h   2004-05-10 04:32:52.000000000 +0200
16262 +++ linux-2.6.6.fixed/include/linux/a.out.h     2004-05-11 10:55:58.000000000 +0200
16263 @@ -7,6 +7,16 @@
16264  
16265  #include <asm/a.out.h>
16266  
16267 +#ifdef CONFIG_PAX_RANDUSTACK
16268 +#define __DELTA_STACK (current->mm->delta_stack)
16269 +#else
16270 +#define __DELTA_STACK 0UL
16271 +#endif
16272 +
16273 +#ifndef STACK_TOP
16274 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
16275 +#endif
16276 +
16277  #endif /* __STRUCT_EXEC_OVERRIDE__ */
16278  
16279  /* these go in the N_MACHTYPE field */
16280 @@ -37,6 +47,14 @@
16281    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
16282  };
16283  
16284 +/* Constants for the N_FLAGS field */
16285 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
16286 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
16287 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
16288 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
16289 +#define F_PAX_RANDEXEC 16      /* Randomize ET_EXEC base */
16290 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
16291 +
16292  #if !defined (N_MAGIC)
16293  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
16294  #endif
16295 diff -uNr linux-2.6.6/include/linux/binfmts.h linux-2.6.6.fixed/include/linux/binfmts.h
16296 --- linux-2.6.6/include/linux/binfmts.h 2004-05-10 04:32:37.000000000 +0200
16297 +++ linux-2.6.6.fixed/include/linux/binfmts.h   2004-05-11 10:55:58.000000000 +0200
16298 @@ -36,6 +36,7 @@
16299                                    of the time same as filename, but could be
16300                                    different for binfmt_{misc,script} */
16301         unsigned long loader, exec;
16302 +       int misc;
16303  };
16304  
16305  /*
16306 @@ -71,5 +72,8 @@
16307  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
16308  extern int set_binfmt(struct linux_binfmt *new);
16309  
16310 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
16311 +void pax_report_insns(void *pc, void *sp);
16312 +
16313  #endif /* __KERNEL__ */
16314  #endif /* _LINUX_BINFMTS_H */
16315 diff -uNr linux-2.6.6/include/linux/elf.h linux-2.6.6.fixed/include/linux/elf.h
16316 --- linux-2.6.6/include/linux/elf.h     2004-05-10 04:32:01.000000000 +0200
16317 +++ linux-2.6.6.fixed/include/linux/elf.h       2004-05-11 10:55:58.000000000 +0200
16318 @@ -37,6 +37,17 @@
16319  
16320  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
16321  
16322 +#define PT_GNU_STACK   (PT_LOOS + 0x474e551)
16323 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
16324 +
16325 +/* Constants for the e_flags field */
16326 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
16327 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
16328 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
16329 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
16330 +#define EF_PAX_RANDEXEC                16      /* Randomize ET_EXEC base */
16331 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
16332 +
16333  /* These constants define the different elf file types */
16334  #define ET_NONE   0
16335  #define ET_REL    1
16336 @@ -123,6 +134,8 @@
16337  #define DT_DEBUG       21
16338  #define DT_TEXTREL     22
16339  #define DT_JMPREL      23
16340 +#define DT_FLAGS       30
16341 +  #define DF_TEXTREL   0x00000004
16342  #define DT_LOPROC      0x70000000
16343  #define DT_HIPROC      0x7fffffff
16344  
16345 @@ -273,6 +286,19 @@
16346  #define PF_W           0x2
16347  #define PF_X           0x1
16348  
16349 +#define PF_PAGEEXEC    (1 << 4)        /* Enable  PAGEEXEC */
16350 +#define PF_NOPAGEEXEC  (1 << 5)        /* Disable PAGEEXEC */
16351 +#define PF_SEGMEXEC    (1 << 6)        /* Enable  SEGMEXEC */
16352 +#define PF_NOSEGMEXEC  (1 << 7)        /* Disable SEGMEXEC */
16353 +#define PF_MPROTECT    (1 << 8)        /* Enable  MPROTECT */
16354 +#define PF_NOMPROTECT  (1 << 9)        /* Disable MPROTECT */
16355 +#define PF_RANDEXEC    (1 << 10)       /* Enable  RANDEXEC */
16356 +#define PF_NORANDEXEC  (1 << 11)       /* Disable RANDEXEC */
16357 +#define PF_EMUTRAMP    (1 << 12)       /* Enable  EMUTRAMP */
16358 +#define PF_NOEMUTRAMP  (1 << 13)       /* Disable EMUTRAMP */
16359 +#define PF_RANDMMAP    (1 << 14)       /* Enable  RANDMMAP */
16360 +#define PF_NORANDMMAP  (1 << 15)       /* Disable RANDMMAP */
16361 +
16362  typedef struct elf32_phdr{
16363    Elf32_Word   p_type;
16364    Elf32_Off    p_offset;
16365 @@ -365,6 +391,8 @@
16366  #define        EI_OSABI        7
16367  #define        EI_PAD          8
16368  
16369 +#define        EI_PAX          14
16370 +
16371  #define        ELFMAG0         0x7f            /* EI_MAG */
16372  #define        ELFMAG1         'E'
16373  #define        ELFMAG2         'L'
16374 @@ -421,6 +449,7 @@
16375  #define elfhdr         elf32_hdr
16376  #define elf_phdr       elf32_phdr
16377  #define elf_note       elf32_note
16378 +#define elf_dyn                Elf32_Dyn
16379  
16380  #else
16381  
16382 @@ -428,6 +457,7 @@
16383  #define elfhdr         elf64_hdr
16384  #define elf_phdr       elf64_phdr
16385  #define elf_note       elf64_note
16386 +#define elf_dyn                Elf64_Dyn
16387  
16388  #endif
16389  
16390 diff -uNr linux-2.6.6/include/linux/fs.h linux-2.6.6.fixed/include/linux/fs.h
16391 --- linux-2.6.6/include/linux/fs.h      2004-05-10 04:32:26.000000000 +0200
16392 +++ linux-2.6.6.fixed/include/linux/fs.h        2004-05-11 10:55:58.000000000 +0200
16393 @@ -1187,7 +1187,7 @@
16394  
16395  /* fs/open.c */
16396  
16397 -extern int do_truncate(struct dentry *, loff_t start);
16398 +extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
16399  extern struct file *filp_open(const char *, int, int);
16400  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
16401  extern int filp_close(struct file *, fl_owner_t id);
16402 diff -uNr linux-2.6.6/include/linux/gracl.h linux-2.6.6.fixed/include/linux/gracl.h
16403 --- linux-2.6.6/include/linux/gracl.h   1970-01-01 01:00:00.000000000 +0100
16404 +++ linux-2.6.6.fixed/include/linux/gracl.h     2004-05-11 10:55:58.000000000 +0200
16405 @@ -0,0 +1,246 @@
16406 +#ifndef GR_ACL_H
16407 +#define GR_ACL_H
16408 +#endif
16409 +#include <linux/grdefs.h>
16410 +#include <linux/resource.h>
16411 +#include <linux/dcache.h>
16412 +#include <asm/resource.h>
16413 +
16414 +/* * * * * * * * * * * * * * * * * * * * *
16415 + * grsecurity ACL System
16416 + * Main header file
16417 + * Purpose: define most gracl data structures 
16418 + * * * * * * * * * * * * * * * * * * * * */
16419 +
16420 +/* Major status information */
16421 +
16422 +#define GR_VERSION  "grsecurity 2.0"
16423 +
16424 +enum {
16425 +
16426 +       SHUTDOWN = 0,
16427 +       ENABLE = 1,
16428 +       SPROLE = 2,
16429 +       RELOAD = 3,
16430 +       SEGVMOD = 4,
16431 +       STATUS = 5,
16432 +       UNSPROLE = 6
16433 +};
16434 +
16435 +/* Password setup definitions
16436 + * kernel/grhash.c */
16437 +enum {
16438 +       GR_PW_LEN = 128,
16439 +       GR_SALT_LEN = 16,
16440 +       GR_SHA_LEN = 32,
16441 +};
16442 +
16443 +enum {
16444 +       GR_SPROLE_LEN = 64,
16445 +};
16446 +
16447 +/* Begin Data Structures */
16448 +
16449 +struct sprole_pw {
16450 +       unsigned char *rolename;
16451 +       unsigned char salt[GR_SALT_LEN];
16452 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
16453 +};
16454 +
16455 +struct name_entry {
16456 +       ino_t inode;
16457 +       dev_t device;
16458 +       char *name;
16459 +       __u16 len;
16460 +};
16461 +
16462 +struct acl_role_db {
16463 +       struct acl_role_label **r_hash;
16464 +       __u32 r_size;
16465 +};
16466 +
16467 +struct name_db {
16468 +       struct name_entry **n_hash;
16469 +       __u32 n_size;
16470 +};
16471 +
16472 +struct crash_uid {
16473 +       uid_t uid;
16474 +       unsigned long expires;
16475 +};
16476 +
16477 +struct gr_hash_struct {
16478 +       void **table;
16479 +       void **nametable;
16480 +       void *first;
16481 +       __u32 table_size;
16482 +       __u32 used_size;
16483 +       int type;
16484 +};
16485 +
16486 +/* Userspace Grsecurity ACL data structures */
16487 +struct acl_subject_label {
16488 +       char *filename;
16489 +       ino_t inode;
16490 +       dev_t device;
16491 +       __u32 mode;
16492 +       __u32 cap_mask;
16493 +       __u32 cap_lower;
16494 +
16495 +       struct rlimit res[RLIM_NLIMITS + 1];
16496 +       __u16 resmask;
16497 +
16498 +       __u8 user_trans_type;
16499 +       __u8 group_trans_type;
16500 +       uid_t *user_transitions;
16501 +       gid_t *group_transitions;
16502 +       __u16 user_trans_num;
16503 +       __u16 group_trans_num;
16504 +
16505 +       __u32 ip_proto[8];
16506 +       __u32 ip_type;
16507 +       struct acl_ip_label **ips;
16508 +       __u32 ip_num;
16509 +
16510 +       __u32 crashes;
16511 +       unsigned long expires;
16512 +
16513 +       struct acl_subject_label *parent_subject;
16514 +       struct gr_hash_struct *hash;
16515 +       struct acl_ip_label *ip_object;
16516 +       struct acl_subject_label *prev;
16517 +       struct acl_subject_label *next;
16518 +
16519 +       struct acl_object_label **obj_hash;
16520 +       __u32 obj_hash_size;
16521 +};
16522 +
16523 +struct role_allowed_ip {
16524 +       __u32 addr;
16525 +       __u32 netmask;
16526 +
16527 +       struct role_allowed_ip *prev;
16528 +       struct role_allowed_ip *next;
16529 +};
16530 +
16531 +struct role_transition {
16532 +       char *rolename;
16533 +
16534 +       struct role_transition *prev;
16535 +       struct role_transition *next;
16536 +};
16537 +
16538 +struct acl_role_label {
16539 +       char *rolename;
16540 +       uid_t uidgid;
16541 +       __u16 roletype;
16542 +
16543 +       __u16 auth_attempts;
16544 +       unsigned long expires;
16545 +
16546 +       struct acl_subject_label *root_label;
16547 +       struct gr_hash_struct *hash;
16548 +
16549 +       struct acl_role_label *prev;
16550 +       struct acl_role_label *next;
16551 +
16552 +       struct role_transition *transitions;
16553 +       struct role_allowed_ip *allowed_ips;
16554 +       struct acl_subject_label **subj_hash;
16555 +       __u32 subj_hash_size;
16556 +};
16557 +
16558 +struct user_acl_role_db {
16559 +       struct acl_role_label **r_table;
16560 +       __u32 r_entries;        /* number of entries in table */
16561 +       __u32 s_entries;        /* total number of subject acls */
16562 +       __u32 i_entries;        /* total number of ip acls */
16563 +       __u32 o_entries;        /* Total number of object acls */
16564 +       __u32 g_entries;        /* total number of globbed objects */
16565 +       __u32 a_entries;        /* total number of allowed ips */
16566 +       __u32 t_entries;        /* total number of transitions */
16567 +};
16568 +
16569 +struct acl_object_label {
16570 +       char *filename;
16571 +       ino_t inode;
16572 +       dev_t device;
16573 +       __u32 mode;
16574 +
16575 +       struct acl_subject_label *nested;
16576 +       struct acl_object_label *globbed;
16577 +
16578 +       /* next two structures not used */
16579 +
16580 +       struct acl_object_label *prev;
16581 +       struct acl_object_label *next;
16582 +};
16583 +
16584 +struct acl_ip_label {
16585 +       __u32 addr;
16586 +       __u32 netmask;
16587 +       __u16 low, high;
16588 +       __u8 mode;
16589 +       __u32 type;
16590 +       __u32 proto[8];
16591 +
16592 +       /* next two structures not used */
16593 +
16594 +       struct acl_ip_label *prev;
16595 +       struct acl_ip_label *next;
16596 +};
16597 +
16598 +struct gr_arg {
16599 +       struct user_acl_role_db role_db;
16600 +       unsigned char pw[GR_PW_LEN];
16601 +       unsigned char salt[GR_SALT_LEN];
16602 +       unsigned char sum[GR_SHA_LEN];
16603 +       unsigned char sp_role[GR_SPROLE_LEN];
16604 +       struct sprole_pw *sprole_pws;
16605 +       dev_t segv_device;
16606 +       ino_t segv_inode;
16607 +       uid_t segv_uid;
16608 +       __u16 num_sprole_pws;
16609 +       __u16 mode;
16610 +};
16611 +
16612 +struct subject_map {
16613 +       struct acl_subject_label *user;
16614 +       struct acl_subject_label *kernel;
16615 +};
16616 +
16617 +struct acl_subj_map_db {
16618 +       struct subject_map **s_hash;
16619 +       __u32 s_size;
16620 +};
16621 +
16622 +/* End Data Structures Section */
16623 +
16624 +/* Hash functions generated by empirical testing by Brad Spengler
16625 +   Makes good use of the low bits of the inode.  Generally 0-1 times
16626 +   in loop for successful match.  0-3 for unsuccessful match.
16627 +   Shift/add algorithm with modulus of table size and an XOR*/
16628 +
16629 +static __inline__ unsigned long
16630 +rhash(const uid_t uid, const __u16 type, const unsigned long sz)
16631 +{
16632 +       return (((uid << type) + (uid ^ type)) % sz);
16633 +}
16634 +
16635 + static __inline__ unsigned long
16636 +shash(const struct acl_subject_label *userp, const unsigned long sz)
16637 +{
16638 +       return ((const unsigned long)userp % sz);
16639 +}
16640 +
16641 +static __inline__ unsigned long
16642 +fhash(const ino_t ino, const dev_t dev, const unsigned long sz)
16643 +{
16644 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
16645 +}
16646 +
16647 +static __inline__ unsigned long
16648 +nhash(const char *name, const __u16 len, const unsigned long sz)
16649 +{
16650 +       return full_name_hash(name, len) % sz;
16651 +}
16652 diff -uNr linux-2.6.6/include/linux/gralloc.h linux-2.6.6.fixed/include/linux/gralloc.h
16653 --- linux-2.6.6/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100
16654 +++ linux-2.6.6.fixed/include/linux/gralloc.h   2004-05-11 10:55:58.000000000 +0200
16655 @@ -0,0 +1,8 @@
16656 +#ifndef __GRALLOC_H
16657 +#define __GRALLOC_H
16658 +
16659 +void acl_free_all(void);
16660 +int acl_alloc_stack_init(unsigned long size);
16661 +void *acl_alloc(unsigned long len);
16662 +
16663 +#endif
16664 diff -uNr linux-2.6.6/include/linux/grdefs.h linux-2.6.6.fixed/include/linux/grdefs.h
16665 --- linux-2.6.6/include/linux/grdefs.h  1970-01-01 01:00:00.000000000 +0100
16666 +++ linux-2.6.6.fixed/include/linux/grdefs.h    2004-05-11 10:55:58.000000000 +0200
16667 @@ -0,0 +1,116 @@
16668 +#ifndef GRDEFS_H
16669 +#define GRDEFS_H
16670 +
16671 +/* Begin grsecurity status declarations */
16672 +
16673 +enum {
16674 +       GR_READY = 0x01,
16675 +       GR_STATUS_INIT = 0x00   // disabled state
16676 +};
16677 +
16678 +/* Begin  ACL declarations */
16679 +
16680 +/* Role flags */
16681 +
16682 +enum {
16683 +       GR_ROLE_USER = 0x0001,
16684 +       GR_ROLE_GROUP = 0x0002,
16685 +       GR_ROLE_DEFAULT = 0x0004,
16686 +       GR_ROLE_SPECIAL = 0x0008,
16687 +       GR_ROLE_AUTH = 0x0010,
16688 +       GR_ROLE_NOPW = 0x0020,
16689 +       GR_ROLE_GOD = 0x0040,
16690 +       GR_ROLE_LEARN = 0x0080,
16691 +       GR_ROLE_TPE = 0x0100
16692 +};
16693 +
16694 +/* ACL Subject and Object mode flags */
16695 +enum {
16696 +       GR_DELETED = 0x00000080
16697 +};
16698 +
16699 +/* ACL Object-only mode flags */
16700 +enum {
16701 +       GR_READ         = 0x00000001,
16702 +       GR_APPEND       = 0x00000002,
16703 +       GR_WRITE        = 0x00000004,
16704 +       GR_EXEC         = 0x00000008,
16705 +       GR_FIND         = 0x00000010,
16706 +       GR_INHERIT      = 0x00000040,
16707 +       GR_PTRACERD     = 0x00000100,
16708 +       GR_SETID        = 0x00000200,
16709 +       GR_CREATE       = 0x00000400,
16710 +       GR_DELETE       = 0x00000800,
16711 +       GR_NOPTRACE     = 0x00001000,
16712 +       GR_AUDIT_READ   = 0x00002000,
16713 +       GR_AUDIT_APPEND = 0x00004000,
16714 +       GR_AUDIT_WRITE  = 0x00008000,
16715 +       GR_AUDIT_EXEC   = 0x00010000,
16716 +       GR_AUDIT_FIND   = 0x00020000,
16717 +       GR_AUDIT_INHERIT= 0x00040000,
16718 +       GR_AUDIT_SETID  = 0x00080000,
16719 +       GR_AUDIT_CREATE = 0x00100000,
16720 +       GR_AUDIT_DELETE = 0x00200000,
16721 +       GR_SUPPRESS     = 0x00400000,
16722 +       GR_NOLEARN      = 0x00800000
16723 +};
16724 +
16725 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
16726 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
16727 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE)
16728 +
16729 +/* ACL subject-only mode flags */
16730 +enum {
16731 +       GR_KILL         = 0x00000001,
16732 +       GR_VIEW         = 0x00000002,
16733 +       GR_PROTECTED    = 0x00000100,
16734 +       GR_LEARN        = 0x00000200,
16735 +       GR_OVERRIDE     = 0x00000400,
16736 +       /* just a placeholder, this mode is only used in userspace */
16737 +       GR_DUMMY        = 0x00000800,
16738 +       GR_PAXPAGE      = 0x00001000,
16739 +       GR_PAXSEGM      = 0x00002000,
16740 +       GR_PAXGCC       = 0x00004000,
16741 +       GR_PAXRANDMMAP  = 0x00008000,
16742 +       GR_PAXRANDEXEC  = 0x00010000,
16743 +       GR_PAXMPROTECT  = 0x00020000,
16744 +       GR_PROTSHM      = 0x00040000,
16745 +       GR_KILLPROC     = 0x00080000,
16746 +       GR_KILLIPPROC   = 0x00100000,
16747 +       /* just a placeholder, this mode is only used in userspace */
16748 +       GR_NOTROJAN     = 0x00200000,
16749 +       GR_PROTPROCFD   = 0x00400000,
16750 +       GR_PROCACCT     = 0x00800000,
16751 +       GR_RELAXPTRACE  = 0x01000000,
16752 +       GR_NESTED       = 0x02000000
16753 +};
16754 +
16755 +enum {
16756 +       GR_ID_USER      = 0x01,
16757 +       GR_ID_GROUP     = 0x02,
16758 +};
16759 +
16760 +enum {
16761 +       GR_ID_ALLOW     = 0x01,
16762 +       GR_ID_DENY      = 0x02,
16763 +};
16764 +
16765 +#define GR_CRASH_RES   11
16766 +#define GR_UIDTABLE_MAX 500
16767 +
16768 +/* begin resource learning section */
16769 +enum {
16770 +       GR_RLIM_CPU_BUMP = 60,
16771 +       GR_RLIM_FSIZE_BUMP = 50000,
16772 +       GR_RLIM_DATA_BUMP = 10000,
16773 +       GR_RLIM_STACK_BUMP = 1000,
16774 +       GR_RLIM_CORE_BUMP = 10000,
16775 +       GR_RLIM_RSS_BUMP = 500000,
16776 +       GR_RLIM_NPROC_BUMP = 1,
16777 +       GR_RLIM_NOFILE_BUMP = 5,
16778 +       GR_RLIM_MEMLOCK_BUMP = 50000,
16779 +       GR_RLIM_AS_BUMP = 500000,
16780 +       GR_RLIM_LOCKS_BUMP = 2
16781 +};
16782 +
16783 +#endif
16784 diff -uNr linux-2.6.6/include/linux/grinternal.h linux-2.6.6.fixed/include/linux/grinternal.h
16785 --- linux-2.6.6/include/linux/grinternal.h      1970-01-01 01:00:00.000000000 +0100
16786 +++ linux-2.6.6.fixed/include/linux/grinternal.h        2004-05-11 10:55:58.000000000 +0200
16787 @@ -0,0 +1,201 @@
16788 +#ifndef __GRINTERNAL_H
16789 +#define __GRINTERNAL_H
16790 +
16791 +#ifdef CONFIG_GRKERNSEC
16792 +
16793 +#include <linux/fs.h>
16794 +#include <linux/grdefs.h>
16795 +#include <linux/grmsg.h>
16796 +
16797 +extern void gr_add_learn_entry(const char *fmt, ...);
16798 +extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
16799 +                           const struct vfsmount *mnt);
16800 +extern __u32 gr_check_create(const struct dentry *new_dentry,
16801 +                            const struct dentry *parent,
16802 +                            const struct vfsmount *mnt, const __u32 mode);
16803 +extern int gr_check_protected_task(const struct task_struct *task);
16804 +extern __u32 to_gr_audit(const __u32 reqmode);
16805 +extern int gr_set_acls(const int type);
16806 +
16807 +extern void gr_handle_alertkill(void);
16808 +extern char *gr_to_filename(const struct dentry *dentry,
16809 +                           const struct vfsmount *mnt);
16810 +extern char *gr_to_filename1(const struct dentry *dentry,
16811 +                           const struct vfsmount *mnt);
16812 +extern char *gr_to_filename2(const struct dentry *dentry,
16813 +                           const struct vfsmount *mnt);
16814 +extern char *gr_to_filename3(const struct dentry *dentry,
16815 +                           const struct vfsmount *mnt);
16816 +
16817 +extern int grsec_enable_link;
16818 +extern int grsec_enable_fifo;
16819 +extern int grsec_enable_execve;
16820 +extern int grsec_enable_forkbomb;
16821 +extern int grsec_forkbomb_gid;
16822 +extern int grsec_forkbomb_sec;
16823 +extern int grsec_forkbomb_max;
16824 +extern int grsec_enable_execlog;
16825 +extern int grsec_enable_signal;
16826 +extern int grsec_enable_forkfail;
16827 +extern int grsec_enable_time;
16828 +extern int grsec_enable_chroot_shmat;
16829 +extern int grsec_enable_chroot_findtask;
16830 +extern int grsec_enable_chroot_mount;
16831 +extern int grsec_enable_chroot_double;
16832 +extern int grsec_enable_chroot_pivot;
16833 +extern int grsec_enable_chroot_chdir;
16834 +extern int grsec_enable_chroot_chmod;
16835 +extern int grsec_enable_chroot_mknod;
16836 +extern int grsec_enable_chroot_fchdir;
16837 +extern int grsec_enable_chroot_nice;
16838 +extern int grsec_enable_chroot_execlog;
16839 +extern int grsec_enable_chroot_caps;
16840 +extern int grsec_enable_chroot_sysctl;
16841 +extern int grsec_enable_chroot_unix;
16842 +extern int grsec_enable_tpe;
16843 +extern int grsec_tpe_gid;
16844 +extern int grsec_enable_tpe_all;
16845 +extern int grsec_enable_sidcaps;
16846 +extern int grsec_enable_randpid;
16847 +extern int grsec_enable_socket_all;
16848 +extern int grsec_socket_all_gid;
16849 +extern int grsec_enable_socket_client;
16850 +extern int grsec_socket_client_gid;
16851 +extern int grsec_enable_socket_server;
16852 +extern int grsec_socket_server_gid;
16853 +extern int grsec_audit_gid;
16854 +extern int grsec_enable_group;
16855 +extern int grsec_enable_audit_ipc;
16856 +extern int grsec_enable_audit_textrel;
16857 +extern int grsec_enable_mount;
16858 +extern int grsec_enable_chdir;
16859 +extern int grsec_lock;
16860 +
16861 +extern struct task_struct *child_reaper;
16862 +
16863 +extern spinlock_t grsec_alert_lock;
16864 +extern unsigned long grsec_alert_wtime;
16865 +extern unsigned long grsec_alert_fyet;
16866 +
16867 +extern spinlock_t grsec_alertgood_lock;
16868 +extern unsigned long grsec_alertgood_wtime;
16869 +extern unsigned long grsec_alertgood_fyet;
16870 +
16871 +extern spinlock_t grsec_audit_lock;
16872 +
16873 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
16874 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
16875 +                       tsk->exec_file->f_vfsmnt) : "/")
16876 +
16877 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
16878 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
16879 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
16880 +
16881 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
16882 +                       gr_to_filename(tsk->exec_file->f_dentry, \
16883 +                       tsk->exec_file->f_vfsmnt) : "/")
16884 +
16885 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
16886 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
16887 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
16888 +
16889 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && \
16890 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
16891 +                         child_reaper->fs->root->d_inode->i_sb->s_dev) || \
16892 +                         (tsk_a->fs->root->d_inode->i_ino != \
16893 +                         child_reaper->fs->root->d_inode->i_ino)))
16894 +
16895 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_sb->s_dev == \
16896 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
16897 +                         (tsk_a->fs->root->d_inode->i_ino == \
16898 +                         tsk_b->fs->root->d_inode->i_ino))
16899 +
16900 +#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
16901 +                      current->pid, current->uid, \
16902 +                      current->euid, current->gid, current->egid, \
16903 +                      gr_parent_task_fullpath(current), \
16904 +                      current->parent->comm, current->parent->pid, \
16905 +                      current->parent->uid, current->parent->euid, \
16906 +                      current->parent->gid, current->parent->egid
16907 +
16908 +#define GR_CHROOT_CAPS ( \
16909 +       CAP_TO_MASK(CAP_FOWNER) | \
16910 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
16911 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
16912 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
16913 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
16914 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
16915 +       CAP_TO_MASK(CAP_IPC_OWNER))
16916 +
16917 +#define security_alert_good(normal_msg,args...) \
16918 +({ \
16919 +       spin_lock(&grsec_alertgood_lock); \
16920 +       \
16921 +       if (!grsec_alertgood_wtime || get_seconds() - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME) { \
16922 +           grsec_alertgood_wtime = get_seconds(); grsec_alertgood_fyet = 0; \
16923 +           if (current->curr_ip) \
16924 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
16925 +           else \
16926 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
16927 +       } else if((get_seconds() - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
16928 +           grsec_alertgood_fyet++; \
16929 +           if (current->curr_ip) \
16930 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
16931 +           else \
16932 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
16933 +       } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
16934 +           grsec_alertgood_wtime = get_seconds(); grsec_alertgood_fyet++; \
16935 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
16936 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
16937 +       } \
16938 +       \
16939 +       spin_unlock(&grsec_alertgood_lock); \
16940 +})
16941 +
16942 +#define security_alert(normal_msg,args...) \
16943 +({ \
16944 +       spin_lock(&grsec_alert_lock); \
16945 +       \
16946 +       if (!grsec_alert_wtime || get_seconds() - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME) { \
16947 +           grsec_alert_wtime = get_seconds(); grsec_alert_fyet = 0; \
16948 +           if (current->curr_ip) \
16949 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
16950 +           else \
16951 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
16952 +       } else if((get_seconds() - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
16953 +           grsec_alert_fyet++; \
16954 +           if (current->curr_ip) \
16955 +               printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
16956 +           else \
16957 +               printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
16958 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
16959 +           grsec_alert_wtime = get_seconds(); grsec_alert_fyet++; \
16960 +           printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
16961 +                   "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
16962 +       } \
16963 +       \
16964 +       gr_handle_alertkill(); \
16965 +       spin_unlock(&grsec_alert_lock); \
16966 +})
16967 +
16968 +#define security_audit(normal_msg,args...) \
16969 +({ \
16970 +       spin_lock(&grsec_audit_lock); \
16971 +       if (current->curr_ip) \
16972 +               printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
16973 +                      NIPQUAD(current->curr_ip) , ## args); \
16974 +       else \
16975 +               printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
16976 +       spin_unlock(&grsec_audit_lock); \
16977 +})
16978 +
16979 +#define security_learn(normal_msg,args...) \
16980 +({ \
16981 +       preempt_disable(); \
16982 +       gr_add_learn_entry(normal_msg "\n", ## args); \
16983 +       preempt_enable(); \
16984 +})
16985 +
16986 +#endif
16987 +
16988 +#endif
16989 diff -uNr linux-2.6.6/include/linux/grmsg.h linux-2.6.6.fixed/include/linux/grmsg.h
16990 --- linux-2.6.6/include/linux/grmsg.h   1970-01-01 01:00:00.000000000 +0100
16991 +++ linux-2.6.6.fixed/include/linux/grmsg.h     2004-05-11 10:55:58.000000000 +0200
16992 @@ -0,0 +1,108 @@
16993 +#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"
16994 +#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"
16995 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
16996 +#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
16997 +#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
16998 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
16999 +#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
17000 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
17001 +#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
17002 +#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
17003 +#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
17004 +#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
17005 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
17006 +#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"
17007 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
17008 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
17009 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
17010 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
17011 +#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
17012 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
17013 +#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
17014 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
17015 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
17016 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
17017 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
17018 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
17019 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
17020 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
17021 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
17022 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
17023 +#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
17024 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
17025 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
17026 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
17027 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution for %lu seconds"
17028 +#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
17029 +#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
17030 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
17031 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
17032 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
17033 +#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
17034 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
17035 +#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
17036 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
17037 +#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
17038 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
17039 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
17040 +#define GR_INITF_ACL_MSG "init_variables() failed %s"
17041 +#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"
17042 +#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
17043 +#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
17044 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
17045 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
17046 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
17047 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
17048 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
17049 +#define GR_ENABLE_ACL_MSG "Loaded %s"
17050 +#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
17051 +#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
17052 +#define GR_RELOAD_ACL_MSG "Reloaded %s"
17053 +#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
17054 +#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
17055 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
17056 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
17057 +#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
17058 +#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
17059 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
17060 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
17061 +#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
17062 +#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
17063 +#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
17064 +#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
17065 +#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
17066 +#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
17067 +#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
17068 +#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
17069 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
17070 +#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
17071 +#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
17072 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
17073 +#define GR_TIME_MSG "time set by " DEFAULTSECMSG
17074 +#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
17075 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
17076 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
17077 +#define GR_SOCK_MSG "attempted socket(%.16s,%.16s,%.16s) by " DEFAULTSECMSG
17078 +#define GR_SOCK2_MSG "attempted socket(%d,%.16s,%.16s) by " DEFAULTSECMSG
17079 +#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
17080 +#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
17081 +#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
17082 +#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
17083 +#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"
17084 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
17085 +#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
17086 +#define GR_USRCHANGE_ACL_MSG "change to uid %d denied for " DEFAULTSECMSG
17087 +#define GR_GRPCHANGE_ACL_MSG "change to gid %d denied for " DEFAULTSECMSG
17088 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
17089 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
17090 +#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
17091 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
17092 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
17093 +#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
17094 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
17095 +#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
17096 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
17097 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
17098 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
17099 +#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
17100 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " DEFAULTSECMSG
17101 diff -uNr linux-2.6.6/include/linux/grsecurity.h linux-2.6.6.fixed/include/linux/grsecurity.h
17102 --- linux-2.6.6/include/linux/grsecurity.h      1970-01-01 01:00:00.000000000 +0100
17103 +++ linux-2.6.6.fixed/include/linux/grsecurity.h        2004-05-11 10:55:58.000000000 +0200
17104 @@ -0,0 +1,188 @@
17105 +#ifndef GR_SECURITY_H
17106 +#define GR_SECURITY_H
17107 +#include <linux/fs.h>
17108 +#include <linux/binfmts.h>
17109 +
17110 +extern int gr_check_user_change(int real, int effective, int fs);
17111 +extern int gr_check_group_change(int real, int effective, int fs);
17112 +
17113 +extern void gr_add_to_task_ip_table(struct task_struct *p);
17114 +extern void gr_del_task_from_ip_table(struct task_struct *p);
17115 +
17116 +extern int gr_pid_is_chrooted(const struct task_struct *p);
17117 +extern int gr_handle_chroot_nice(void);
17118 +extern int gr_handle_chroot_sysctl(const int op);
17119 +extern int gr_handle_chroot_capset(const struct task_struct *target);
17120 +extern int gr_handle_chroot_setpriority(struct task_struct *p,
17121 +                                       const int niceval);
17122 +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
17123 +extern int gr_handle_chroot_chroot(const struct dentry *dentry,
17124 +                                  const struct vfsmount *mnt);
17125 +extern void gr_handle_chroot_caps(struct task_struct *task);
17126 +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
17127 +extern int gr_handle_chroot_chmod(const struct dentry *dentry,
17128 +                                 const struct vfsmount *mnt, const int mode);
17129 +extern int gr_handle_chroot_mknod(const struct dentry *dentry,
17130 +                                 const struct vfsmount *mnt, const int mode);
17131 +extern int gr_handle_chroot_mount(const struct dentry *dentry,
17132 +                                 const struct vfsmount *mnt,
17133 +                                 const char *dev_name);
17134 +extern int gr_handle_chroot_pivot(void);
17135 +extern int gr_handle_chroot_unix(const pid_t pid);
17136 +
17137 +extern int gr_handle_rawio(const struct inode *inode);
17138 +extern int gr_handle_nproc(void);
17139 +
17140 +extern void gr_handle_ioperm(void);
17141 +extern void gr_handle_iopl(void);
17142 +
17143 +extern int gr_tpe_allow(const struct file *file);
17144 +
17145 +extern int gr_random_pid(void);
17146 +
17147 +extern void gr_log_forkfail(const int retval);
17148 +extern void gr_log_timechange(void);
17149 +extern void gr_log_signal(const int sig, const struct task_struct *t);
17150 +extern void gr_log_chdir(const struct dentry *dentry,
17151 +                        const struct vfsmount *mnt);
17152 +extern void gr_log_chroot_exec(const struct dentry *dentry,
17153 +                              const struct vfsmount *mnt);
17154 +extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
17155 +extern void gr_log_remount(const char *devname, const int retval);
17156 +extern void gr_log_unmount(const char *devname, const int retval);
17157 +extern void gr_log_mount(const char *from, const char *to, const int retval);
17158 +extern void gr_log_msgget(const int ret, const int msgflg);
17159 +extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
17160 +extern void gr_log_semget(const int err, const int semflg);
17161 +extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
17162 +extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
17163 +extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
17164 +extern void gr_log_textrel(struct vm_area_struct *vma);
17165 +
17166 +extern int gr_handle_follow_link(const struct inode *parent,
17167 +                                const struct inode *inode,
17168 +                                const struct dentry *dentry,
17169 +                                const struct vfsmount *mnt);
17170 +extern int gr_handle_fifo(const struct dentry *dentry,
17171 +                         const struct vfsmount *mnt,
17172 +                         const struct dentry *dir, const int flag,
17173 +                         const int acc_mode);
17174 +extern int gr_handle_hardlink(const struct dentry *dentry,
17175 +                             const struct vfsmount *mnt,
17176 +                             struct inode *inode,
17177 +                             const int mode, const char *to);
17178 +
17179 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
17180 +extern int gr_is_capable_nolog(const int cap);
17181 +extern void gr_learn_resource(const struct task_struct *task, const int limit,
17182 +                             const unsigned long wanted, const int gt);
17183 +extern void gr_copy_label(struct task_struct *tsk);
17184 +extern void gr_handle_crash(struct task_struct *task, const int sig);
17185 +extern int gr_handle_signal(const struct task_struct *p, const int sig);
17186 +extern int gr_check_crash_uid(const uid_t uid);
17187 +extern int gr_check_protected_task(const struct task_struct *task);
17188 +extern int gr_acl_handle_mmap(const struct file *file,
17189 +                             const unsigned long prot);
17190 +extern int gr_acl_handle_mprotect(const struct file *file,
17191 +                                 const unsigned long prot);
17192 +extern int gr_check_hidden_task(const struct task_struct *tsk);
17193 +extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
17194 +                                   const struct vfsmount *mnt);
17195 +extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
17196 +                                const struct vfsmount *mnt);
17197 +extern __u32 gr_acl_handle_access(const struct dentry *dentry,
17198 +                                 const struct vfsmount *mnt, const int fmode);
17199 +extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
17200 +                                 const struct vfsmount *mnt, mode_t mode);
17201 +extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
17202 +                                const struct vfsmount *mnt, mode_t mode);
17203 +extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
17204 +                                const struct vfsmount *mnt);
17205 +extern int gr_handle_ptrace_exec(const struct dentry *dentry,
17206 +                                const struct vfsmount *mnt);
17207 +extern int gr_handle_ptrace(struct task_struct *task, const long request);
17208 +extern int gr_handle_proc_ptrace(struct task_struct *task);
17209 +extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
17210 +extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
17211 +                                 const struct vfsmount *mnt);
17212 +extern int gr_check_crash_exec(const struct file *filp);
17213 +extern int gr_acl_is_enabled(void);
17214 +extern void gr_set_kernel_label(struct task_struct *task);
17215 +extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
17216 +                             const gid_t gid);
17217 +extern void gr_set_proc_label(const struct dentry *dentry,
17218 +                             const struct vfsmount *mnt);
17219 +extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
17220 +                                      const struct vfsmount *mnt);
17221 +extern __u32 gr_acl_handle_open(const struct dentry *dentry,
17222 +                               const struct vfsmount *mnt, const int fmode);
17223 +extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
17224 +                                const struct dentry *p_dentry,
17225 +                                const struct vfsmount *p_mnt, const int fmode,
17226 +                                const int imode);
17227 +extern void gr_handle_create(const struct dentry *dentry,
17228 +                            const struct vfsmount *mnt);
17229 +extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
17230 +                                const struct dentry *parent_dentry,
17231 +                                const struct vfsmount *parent_mnt,
17232 +                                const int mode);
17233 +extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
17234 +                                const struct dentry *parent_dentry,
17235 +                                const struct vfsmount *parent_mnt);
17236 +extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
17237 +                                const struct vfsmount *mnt);
17238 +extern void gr_handle_delete(const ino_t ino, const dev_t dev);
17239 +extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
17240 +                                 const struct vfsmount *mnt);
17241 +extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
17242 +                                  const struct dentry *parent_dentry,
17243 +                                  const struct vfsmount *parent_mnt,
17244 +                                  const char *from);
17245 +extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
17246 +                               const struct dentry *parent_dentry,
17247 +                               const struct vfsmount *parent_mnt,
17248 +                               const struct dentry *old_dentry,
17249 +                               const struct vfsmount *old_mnt, const char *to);
17250 +extern int gr_acl_handle_rename(struct dentry *new_dentry,
17251 +                               struct dentry *parent_dentry,
17252 +                               const struct vfsmount *parent_mnt,
17253 +                               struct dentry *old_dentry,
17254 +                               struct inode *old_parent_inode,
17255 +                               struct vfsmount *old_mnt, const char *newname);
17256 +extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
17257 +                               struct dentry *old_dentry,
17258 +                               struct dentry *new_dentry,
17259 +                               struct vfsmount *mnt, const __u8 replace);
17260 +extern __u32 gr_check_link(const struct dentry *new_dentry,
17261 +                          const struct dentry *parent_dentry,
17262 +                          const struct vfsmount *parent_mnt,
17263 +                          const struct dentry *old_dentry,
17264 +                          const struct vfsmount *old_mnt);
17265 +extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
17266 +                                  const struct vfsmount *mnt, const ino_t ino);
17267 +extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
17268 +                               const struct vfsmount *mnt);
17269 +extern void gr_acl_handle_exit(void);
17270 +extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
17271 +extern int gr_acl_handle_procpidmem(const struct task_struct *task);
17272 +extern __u32 gr_cap_rtnetlink(void);
17273 +
17274 +#ifdef CONFIG_GRKERNSEC
17275 +extern void gr_handle_mem_write(void);
17276 +extern void gr_handle_kmem_write(void);
17277 +extern void gr_handle_open_port(void);
17278 +extern int gr_handle_mem_mmap(const unsigned long offset,
17279 +                             struct vm_area_struct *vma);
17280 +
17281 +extern __u16 ip_randomid(void);
17282 +extern __u32 ip_randomisn(void);
17283 +extern unsigned long get_random_long(void);
17284 +
17285 +extern int grsec_enable_dmesg;
17286 +extern int grsec_enable_randid;
17287 +extern int grsec_enable_randisn;
17288 +extern int grsec_enable_randsrc;
17289 +extern int grsec_enable_randrpc;
17290 +#endif
17291 +
17292 +#endif
17293 diff -uNr linux-2.6.6/include/linux/mman.h linux-2.6.6.fixed/include/linux/mman.h
17294 --- linux-2.6.6/include/linux/mman.h    2004-05-10 04:32:01.000000000 +0200
17295 +++ linux-2.6.6.fixed/include/linux/mman.h      2004-05-11 10:55:58.000000000 +0200
17296 @@ -56,6 +56,11 @@
17297  calc_vm_flag_bits(unsigned long flags)
17298  {
17299         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
17300 +
17301 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
17302 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
17303 +#endif
17304 +
17305                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
17306                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
17307                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
17308 diff -uNr linux-2.6.6/include/linux/mm.h linux-2.6.6.fixed/include/linux/mm.h
17309 --- linux-2.6.6/include/linux/mm.h      2004-05-10 04:31:59.000000000 +0200
17310 +++ linux-2.6.6.fixed/include/linux/mm.h        2004-05-11 10:55:58.000000000 +0200
17311 @@ -25,6 +25,7 @@
17312  #include <asm/pgtable.h>
17313  #include <asm/processor.h>
17314  #include <asm/atomic.h>
17315 +#include <asm/mman.h>
17316  
17317  #ifndef MM_VM_SIZE
17318  #define MM_VM_SIZE(mm) TASK_SIZE
17319 @@ -115,6 +116,18 @@
17320  /* It makes sense to apply VM_ACCOUNT to this vma. */
17321  #define VM_MAYACCT(vma) (!!((vma)->vm_flags & VM_HUGETLB))
17322  
17323 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
17324 +#define VM_MIRROR      0x01000000      /* vma is mirroring another */
17325 +#endif
17326 +
17327 +#ifdef CONFIG_PAX_MPROTECT
17328 +#define VM_MAYNOTWRITE 0x02000000      /* vma cannot be granted VM_WRITE any more */
17329 +#endif
17330 +
17331 +#ifdef __VM_STACK_FLAGS
17332 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
17333 +#endif
17334 +
17335  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
17336  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
17337  #endif
17338 @@ -552,6 +565,10 @@
17339         unsigned long len, unsigned long prot,
17340         unsigned long flag, unsigned long pgoff);
17341  
17342 +extern unsigned long __do_mmap_pgoff(struct file *file, unsigned long addr,
17343 +       unsigned long len, unsigned long prot,
17344 +       unsigned long flag, unsigned long pgoff);
17345 +
17346  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
17347         unsigned long len, unsigned long prot,
17348         unsigned long flag, unsigned long offset)
17349 @@ -582,6 +599,12 @@
17350  static inline int
17351  can_vma_merge(struct vm_area_struct *vma, unsigned long vm_flags)
17352  {
17353 +
17354 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
17355 +       if ((vma->vm_flags | vm_flags) & VM_MIRROR)
17356 +               return 0;
17357 +#endif
17358 +
17359  #ifdef CONFIG_MMU
17360         if (!vma->vm_file && vma->vm_flags == vm_flags)
17361                 return 1;
17362 diff -uNr linux-2.6.6/include/linux/proc_fs.h linux-2.6.6.fixed/include/linux/proc_fs.h
17363 --- linux-2.6.6/include/linux/proc_fs.h 2004-05-10 04:33:22.000000000 +0200
17364 +++ linux-2.6.6.fixed/include/linux/proc_fs.h   2004-05-11 10:55:58.000000000 +0200
17365 @@ -221,7 +221,7 @@
17366  
17367  #endif /* CONFIG_PROC_FS */
17368  
17369 -#if !defined(CONFIG_PROC_FS)
17370 +#if !defined(CONFIG_PROC_FS) || !defined(CONFIG_PROC_KCORE)
17371  static inline void kclist_add(struct kcore_list *new, void *addr, size_t size)
17372  {
17373  }
17374 diff -uNr linux-2.6.6/include/linux/random.h linux-2.6.6.fixed/include/linux/random.h
17375 --- linux-2.6.6/include/linux/random.h  2004-05-10 04:33:21.000000000 +0200
17376 +++ linux-2.6.6.fixed/include/linux/random.h    2004-05-11 10:55:58.000000000 +0200
17377 @@ -69,6 +69,8 @@
17378  
17379  extern __u32 secure_ipv6_id(__u32 *daddr);
17380  
17381 +extern unsigned long pax_get_random_long(void);
17382 +
17383  #ifndef MODULE
17384  extern struct file_operations random_fops, urandom_fops;
17385  #endif
17386 diff -uNr linux-2.6.6/include/linux/sched.h linux-2.6.6.fixed/include/linux/sched.h
17387 --- linux-2.6.6/include/linux/sched.h   2004-05-10 04:32:00.000000000 +0200
17388 +++ linux-2.6.6.fixed/include/linux/sched.h     2004-05-11 10:55:58.000000000 +0200
17389 @@ -31,6 +31,7 @@
17390  #include <linux/percpu.h>
17391  
17392  struct exec_domain;
17393 +struct linux_binprm;
17394  
17395  /*
17396   * cloning flags:
17397 @@ -231,6 +232,21 @@
17398         struct kioctx           *ioctx_list;
17399  
17400         struct kioctx           default_kioctx;
17401 +
17402 +#ifdef CONFIG_PAX_DLRESOLVE
17403 +       unsigned long call_dl_resolve;
17404 +#endif
17405 +
17406 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
17407 +       unsigned long call_syscall;
17408 +#endif
17409 +
17410 +#ifdef CONFIG_PAX_ASLR
17411 +       unsigned long delta_mmap;               /* randomized offset */
17412 +       unsigned long delta_exec;               /* randomized offset */
17413 +       unsigned long delta_stack;              /* randomized offset */
17414 +#endif
17415 +
17416  };
17417  
17418  extern int mmlist_nr;
17419 @@ -504,6 +520,22 @@
17420  
17421         unsigned long ptrace_message;
17422         siginfo_t *last_siginfo; /* For ptrace use.  */
17423 +
17424 +#ifdef CONFIG_GRKERNSEC
17425 +       /* grsecurity */
17426 +       struct acl_subject_label *acl;
17427 +       struct acl_role_label *role;
17428 +       struct file *exec_file;
17429 +       u32 curr_ip;
17430 +       u32 gr_saddr;
17431 +       u32 gr_daddr;
17432 +       u16 gr_sport;
17433 +       u16 gr_dport;
17434 +       u16 acl_role_id;
17435 +       u8 acl_sp_role:1;
17436 +       u8 used_accept:1;
17437 +       u8 is_writable:1;
17438 +#endif
17439  };
17440  
17441  static inline pid_t process_group(struct task_struct *tsk)
17442 @@ -541,6 +573,29 @@
17443  #define PF_LESS_THROTTLE 0x00100000    /* Throttle me less: I clean memory */
17444  #define PF_SYNCWRITE   0x00200000      /* I am doing a sync write */
17445  
17446 +#define PF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
17447 +#define PF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
17448 +#define PF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
17449 +#define PF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
17450 +#define PF_PAX_RANDEXEC                0x10000000      /* Randomize ET_EXEC base */
17451 +#define PF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
17452 +
17453 +#ifdef CONFIG_PAX_SOFTMODE
17454 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
17455 +extern unsigned int pax_aslr;
17456 +#endif
17457 +
17458 +extern unsigned int pax_softmode;
17459 +#endif
17460 +
17461 +extern int pax_check_flags(unsigned long *);
17462 +
17463 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
17464 +extern void pax_set_flags(struct linux_binprm * bprm);
17465 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
17466 +extern void (*pax_set_flags_func)(struct linux_binprm * bprm);
17467 +#endif
17468 +
17469  #ifdef CONFIG_SMP
17470  extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
17471  #else
17472 @@ -686,14 +741,29 @@
17473                 : on_sig_stack(sp) ? SS_ONSTACK : 0);
17474  }
17475  
17476 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
17477 +extern int gr_is_capable_nolog(const int cap);
17478  
17479  #ifdef CONFIG_SECURITY
17480  /* code is in security.c */
17481  extern int capable(int cap);
17482 +static inline int capable_nolog(int cap)
17483 +{
17484 +       return capable(cap);
17485 +}
17486  #else
17487  static inline int capable(int cap)
17488  {
17489 -       if (cap_raised(current->cap_effective, cap)) {
17490 +       if (cap_raised(current->cap_effective, cap) && gr_task_is_capable(current, cap)) {
17491 +               current->flags |= PF_SUPERPRIV;
17492 +               return 1;
17493 +       }
17494 +       return 0;
17495 +}
17496 +
17497 +static inline int capable_nolog(int cap)
17498 +{
17499 +       if (cap_raised(current->cap_effective, cap) && gr_is_capable_nolog(cap)) {
17500                 current->flags |= PF_SUPERPRIV;
17501                 return 1;
17502         }
17503 diff -uNr linux-2.6.6/include/linux/shm.h linux-2.6.6.fixed/include/linux/shm.h
17504 --- linux-2.6.6/include/linux/shm.h     2004-05-10 04:32:54.000000000 +0200
17505 +++ linux-2.6.6.fixed/include/linux/shm.h       2004-05-11 10:55:58.000000000 +0200
17506 @@ -84,6 +84,10 @@
17507         time_t                  shm_ctim;
17508         pid_t                   shm_cprid;
17509         pid_t                   shm_lprid;
17510 +#ifdef CONFIG_GRKERNSEC
17511 +       time_t                  shm_createtime;
17512 +       pid_t                   shm_lapid;
17513 +#endif
17514  };
17515  
17516  /* shm_mode upper byte flags */
17517 diff -uNr linux-2.6.6/include/linux/sysctl.h linux-2.6.6.fixed/include/linux/sysctl.h
17518 --- linux-2.6.6/include/linux/sysctl.h  2004-05-10 04:32:38.000000000 +0200
17519 +++ linux-2.6.6.fixed/include/linux/sysctl.h    2004-05-11 11:16:39.000000000 +0200
17520 @@ -133,8 +133,20 @@
17521         KERN_NGROUPS_MAX=63,    /* int: NGROUPS_MAX */
17522         KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
17523         KERN_HZ_TIMER=65,       /* int: hz timer on or off */
17524 -};
17525 +       KERN_GRSECURITY=68,     /* grsecurity */
17526 +
17527  
17528 +#ifdef CONFIG_PAX_SOFTMODE
17529 +       KERN_PAX=69,            /* PaX control */
17530 +#endif
17531 +};
17532 +  
17533 +#ifdef CONFIG_PAX_SOFTMODE
17534 +enum {
17535 +       PAX_ASLR=1,             /* PaX: disable/enable all randomization features */
17536 +       PAX_SOFTMODE=2          /* PaX: disable/enable soft mode */
17537 +};
17538 +#endif
17539  
17540  /* CTL_VM names: */
17541  enum
17542 diff -uNr linux-2.6.6/include/net/ip.h linux-2.6.6.fixed/include/net/ip.h
17543 --- linux-2.6.6/include/net/ip.h        2004-05-10 04:32:53.000000000 +0200
17544 +++ linux-2.6.6.fixed/include/net/ip.h  2004-05-11 10:55:58.000000000 +0200
17545 @@ -33,6 +33,11 @@
17546  #include <net/route.h>
17547  #include <net/arp.h>
17548  
17549 +#ifdef CONFIG_GRKERNSEC_RANDID
17550 +extern int grsec_enable_randid;
17551 +extern __u16 ip_randomid(void);
17552 +#endif
17553 +
17554  #ifndef _SNMP_H
17555  #include <net/snmp.h>
17556  #endif
17557 @@ -188,6 +193,13 @@
17558  
17559  static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
17560  {
17561 +
17562 +#ifdef CONFIG_GRKERNSEC_RANDID
17563 +       if (grsec_enable_randid)
17564 +               iph->id = htons(ip_randomid());
17565 +       else
17566 +#endif
17567 +
17568         if (iph->frag_off & htons(IP_DF)) {
17569                 /* This is only to work around buggy Windows95/2000
17570                  * VJ compression implementations.  If the ID field
17571 diff -uNr linux-2.6.6/init/do_mounts.c linux-2.6.6.fixed/init/do_mounts.c
17572 --- linux-2.6.6/init/do_mounts.c        2004-05-10 04:32:28.000000000 +0200
17573 +++ linux-2.6.6.fixed/init/do_mounts.c  2004-05-11 10:55:58.000000000 +0200
17574 @@ -291,6 +291,7 @@
17575                         case -EINVAL:
17576                                 continue;
17577                 }
17578 +
17579                 /*
17580                  * Allow the user to distinguish between failed sys_open
17581                  * and bad superblock on root device.
17582 diff -uNr linux-2.6.6/init/Kconfig linux-2.6.6.fixed/init/Kconfig
17583 --- linux-2.6.6/init/Kconfig    2004-05-10 04:33:13.000000000 +0200
17584 +++ linux-2.6.6.fixed/init/Kconfig      2004-05-11 10:55:58.000000000 +0200
17585 @@ -230,6 +230,7 @@
17586  config KALLSYMS
17587          bool "Load all symbols for debugging/kksymoops" if EMBEDDED
17588          default y
17589 +        depends on !GRKERNSEC_HIDESYM
17590          help
17591            Say Y here to let the kernel print out symbolic crash information and
17592            symbolic stack backtraces. This increases the size of the kernel
17593 diff -uNr linux-2.6.6/init/main.c linux-2.6.6.fixed/init/main.c
17594 --- linux-2.6.6/init/main.c     2004-05-10 04:32:01.000000000 +0200
17595 +++ linux-2.6.6.fixed/init/main.c       2004-05-11 11:13:42.000000000 +0200
17596 @@ -90,6 +90,7 @@
17597  extern void populate_rootfs(void);
17598  extern void driver_init(void);
17599  extern void prepare_namespace(void);
17600 +extern void grsecurity_init(void);
17601  
17602  #ifdef CONFIG_TC
17603  extern void tc_init(void);
17604 @@ -614,6 +615,7 @@
17605         else
17606                 prepare_namespace();
17607  
17608 +       grsecurity_init();
17609         /*
17610          * Ok, we have completed the initial bootup, and
17611          * we're essentially up and running. Get rid of the
17612 diff -uNr linux-2.6.6/ipc/msg.c linux-2.6.6.fixed/ipc/msg.c
17613 --- linux-2.6.6/ipc/msg.c       2004-05-10 04:31:57.000000000 +0200
17614 +++ linux-2.6.6.fixed/ipc/msg.c 2004-05-11 10:55:58.000000000 +0200
17615 @@ -24,6 +24,7 @@
17616  #include <linux/list.h>
17617  #include <linux/security.h>
17618  #include <linux/sched.h>
17619 +#include <linux/grsecurity.h>
17620  #include <asm/current.h>
17621  #include <asm/uaccess.h>
17622  #include "util.h"
17623 @@ -226,6 +227,9 @@
17624                 msg_unlock(msq);
17625         }
17626         up(&msg_ids.sem);
17627 +
17628 +       gr_log_msgget(ret, msgflg);
17629 +
17630         return ret;
17631  }
17632  
17633 @@ -475,6 +479,8 @@
17634                 break;
17635         }
17636         case IPC_RMID:
17637 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
17638 +
17639                 freeque (msq, msqid); 
17640                 break;
17641         }
17642 diff -uNr linux-2.6.6/ipc/sem.c linux-2.6.6.fixed/ipc/sem.c
17643 --- linux-2.6.6/ipc/sem.c       2004-05-10 04:32:28.000000000 +0200
17644 +++ linux-2.6.6.fixed/ipc/sem.c 2004-05-11 10:55:58.000000000 +0200
17645 @@ -71,6 +71,7 @@
17646  #include <linux/time.h>
17647  #include <linux/smp_lock.h>
17648  #include <linux/security.h>
17649 +#include <linux/grsecurity.h>
17650  #include <asm/uaccess.h>
17651  #include "util.h"
17652  
17653 @@ -238,6 +239,9 @@
17654         }
17655  
17656         up(&sem_ids.sem);
17657 +
17658 +       gr_log_semget(err, semflg);
17659 +
17660         return err;
17661  }
17662  
17663 @@ -804,6 +808,8 @@
17664  
17665         switch(cmd){
17666         case IPC_RMID:
17667 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
17668 +
17669                 freeary(sma, semid);
17670                 err = 0;
17671                 break;
17672 diff -uNr linux-2.6.6/ipc/shm.c linux-2.6.6.fixed/ipc/shm.c
17673 --- linux-2.6.6/ipc/shm.c       2004-05-10 04:32:37.000000000 +0200
17674 +++ linux-2.6.6.fixed/ipc/shm.c 2004-05-11 10:55:58.000000000 +0200
17675 @@ -26,6 +26,7 @@
17676  #include <linux/proc_fs.h>
17677  #include <linux/shmem_fs.h>
17678  #include <linux/security.h>
17679 +#include <linux/grsecurity.h>
17680  #include <asm/uaccess.h>
17681  
17682  #include "util.h"
17683 @@ -50,6 +51,14 @@
17684  static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
17685  #endif
17686  
17687 +#ifdef CONFIG_GRKERNSEC
17688 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
17689 +                          const time_t shm_createtime, const uid_t cuid,
17690 +                          const int shmid);
17691 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
17692 +                          const time_t shm_createtime);
17693 +#endif
17694 +
17695  size_t shm_ctlmax = SHMMAX;
17696  size_t         shm_ctlall = SHMALL;
17697  int    shm_ctlmni = SHMMNI;
17698 @@ -213,6 +222,9 @@
17699         shp->shm_lprid = 0;
17700         shp->shm_atim = shp->shm_dtim = 0;
17701         shp->shm_ctim = get_seconds();
17702 +#ifdef CONFIG_GRKERNSEC
17703 +       shp->shm_createtime = get_seconds();
17704 +#endif
17705         shp->shm_segsz = size;
17706         shp->shm_nattch = 0;
17707         shp->id = shm_buildid(id,shp->shm_perm.seq);
17708 @@ -267,6 +279,8 @@
17709         }
17710         up(&shm_ids.sem);
17711  
17712 +       gr_log_shmget(err, shmflg, size);
17713 +
17714         return err;
17715  }
17716  
17717 @@ -565,6 +579,8 @@
17718                 if (err)
17719                         goto out_unlock_up;
17720  
17721 +               gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
17722 +
17723                 if (shp->shm_nattch){
17724                         shp->shm_flags |= SHM_DEST;
17725                         /* Do not find it any more */
17726 @@ -703,9 +719,27 @@
17727                 return err;
17728         }
17729                 
17730 +#ifdef CONFIG_GRKERNSEC
17731 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
17732 +                            shp->shm_perm.cuid, shmid)) {
17733 +               shm_unlock(shp);
17734 +               return -EACCES;
17735 +       }
17736 +
17737 +       if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
17738 +               shm_unlock(shp);
17739 +               return -EACCES;
17740 +       }
17741 +#endif
17742 +
17743         file = shp->shm_file;
17744         size = i_size_read(file->f_dentry->d_inode);
17745         shp->shm_nattch++;
17746 +
17747 +#ifdef CONFIG_GRKERNSEC
17748 +       shp->shm_lapid = current->pid;
17749 +#endif
17750 +
17751         shm_unlock(shp);
17752  
17753         down_write(&current->mm->mmap_sem);
17754 diff -uNr linux-2.6.6/kernel/capability.c linux-2.6.6.fixed/kernel/capability.c
17755 --- linux-2.6.6/kernel/capability.c     2004-05-10 04:32:53.000000000 +0200
17756 +++ linux-2.6.6.fixed/kernel/capability.c       2004-05-11 10:55:58.000000000 +0200
17757 @@ -10,6 +10,7 @@
17758  #include <linux/mm.h>
17759  #include <linux/module.h>
17760  #include <linux/security.h>
17761 +#include <linux/grsecurity.h>
17762  #include <asm/uaccess.h>
17763  
17764  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
17765 @@ -168,6 +169,11 @@
17766       } else
17767                 target = current;
17768  
17769 +     if (gr_handle_chroot_capset(target)) {
17770 +               ret = -ESRCH;
17771 +               goto out;
17772 +     }
17773 +
17774       ret = -EPERM;
17775  
17776       if (security_capset_check(target, &effective, &inheritable, &permitted))
17777 diff -uNr linux-2.6.6/kernel/configs.c linux-2.6.6.fixed/kernel/configs.c
17778 --- linux-2.6.6/kernel/configs.c        2004-05-10 04:32:27.000000000 +0200
17779 +++ linux-2.6.6.fixed/kernel/configs.c  2004-05-11 10:55:58.000000000 +0200
17780 @@ -78,8 +78,16 @@
17781         struct proc_dir_entry *entry;
17782  
17783         /* create the current config file */
17784 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17785 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17786 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
17787 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
17788 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
17789 +#endif
17790 +#else
17791         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
17792                                   &proc_root);
17793 +#endif
17794         if (!entry)
17795                 return -ENOMEM;
17796  
17797 diff -uNr linux-2.6.6/kernel/exit.c linux-2.6.6.fixed/kernel/exit.c
17798 --- linux-2.6.6/kernel/exit.c   2004-05-10 04:33:19.000000000 +0200
17799 +++ linux-2.6.6.fixed/kernel/exit.c     2004-05-11 10:55:58.000000000 +0200
17800 @@ -22,6 +22,7 @@
17801  #include <linux/profile.h>
17802  #include <linux/mount.h>
17803  #include <linux/proc_fs.h>
17804 +#include <linux/grsecurity.h>
17805  
17806  #include <asm/uaccess.h>
17807  #include <asm/pgtable.h>
17808 @@ -231,6 +232,13 @@
17809  {
17810         write_lock_irq(&tasklist_lock);
17811  
17812 +#ifdef CONFIG_GRKERNSEC
17813 +       if (current->exec_file) {
17814 +               fput(current->exec_file);
17815 +               current->exec_file = NULL;
17816 +       }
17817 +#endif
17818 +
17819         ptrace_unlink(current);
17820         /* Reparent to init */
17821         REMOVE_LINKS(current);
17822 @@ -238,6 +246,8 @@
17823         current->real_parent = child_reaper;
17824         SET_LINKS(current);
17825  
17826 +       gr_set_kernel_label(current);
17827 +
17828         /* Set the exit signal to SIGCHLD so we signal init on exit */
17829         current->exit_signal = SIGCHLD;
17830  
17831 @@ -332,6 +342,15 @@
17832         vsnprintf(current->comm, sizeof(current->comm), name, args);
17833         va_end(args);
17834  
17835 +#ifdef CONFIG_GRKERNSEC
17836 +       if (current->exec_file) {
17837 +               fput(current->exec_file);
17838 +               current->exec_file = NULL;
17839 +       }
17840 +#endif
17841 +
17842 +       gr_set_kernel_label(current);
17843 +
17844         /*
17845          * If we were started as result of loading a module, close all of the
17846          * user space pages.  We don't need them, and if we didn't close them
17847 @@ -783,6 +802,11 @@
17848         }
17849  
17850         acct_process(code);
17851 +
17852 +       gr_acl_handle_psacct(tsk, code);
17853 +       gr_acl_handle_exit();
17854 +       gr_del_task_from_ip_table(tsk);
17855 +
17856         __exit_mm(tsk);
17857  
17858         exit_sem(tsk);
17859 diff -uNr linux-2.6.6/kernel/fork.c linux-2.6.6.fixed/kernel/fork.c
17860 --- linux-2.6.6/kernel/fork.c   2004-05-10 04:32:00.000000000 +0200
17861 +++ linux-2.6.6.fixed/kernel/fork.c     2004-05-11 11:07:27.000000000 +0200
17862 @@ -33,6 +33,7 @@
17863  #include <linux/ptrace.h>
17864  #include <linux/mount.h>
17865  #include <linux/audit.h>
17866 +#include <linux/grsecurity.h>
17867  
17868  #include <asm/pgtable.h>
17869  #include <asm/pgalloc.h>
17870 @@ -278,7 +279,7 @@
17871         mm->locked_vm = 0;
17872         mm->mmap = NULL;
17873         mm->mmap_cache = NULL;
17874 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
17875 +       mm->free_area_cache = oldmm->free_area_cache;
17876         mm->map_count = 0;
17877         mm->rss = 0;
17878         cpus_clear(mm->cpu_vm_mask);
17879 @@ -890,6 +891,9 @@
17880                 goto fork_out;
17881  
17882         retval = -EAGAIN;
17883 +
17884 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
17885 +
17886         if (atomic_read(&p->user->processes) >=
17887                         p->rlim[RLIMIT_NPROC].rlim_cur) {
17888                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
17889 @@ -978,6 +982,8 @@
17890         if (retval)
17891                 goto bad_fork_cleanup_namespace;
17892  
17893 +       gr_copy_label(p);
17894 +
17895         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
17896         /*
17897          * Clear TID on mm_release()?
17898 @@ -1115,6 +1121,9 @@
17899         free_uid(p->user);
17900  bad_fork_free:
17901         free_task(p);
17902 +
17903 +       gr_log_forkfail(retval);
17904 +
17905         goto fork_out;
17906  }
17907  
17908 diff -uNr linux-2.6.6/kernel/kallsyms.c linux-2.6.6.fixed/kernel/kallsyms.c
17909 --- linux-2.6.6/kernel/kallsyms.c       2004-05-10 04:33:21.000000000 +0200
17910 +++ linux-2.6.6.fixed/kernel/kallsyms.c 2004-05-11 10:55:58.000000000 +0200
17911 @@ -301,7 +301,15 @@
17912  {
17913         struct proc_dir_entry *entry;
17914  
17915 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17916 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17917 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
17918 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
17919 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
17920 +#endif
17921 +#else
17922         entry = create_proc_entry("kallsyms", 0444, NULL);
17923 +#endif
17924         if (entry)
17925                 entry->proc_fops = &kallsyms_operations;
17926         return 0;
17927 diff -uNr linux-2.6.6/kernel/pid.c linux-2.6.6.fixed/kernel/pid.c
17928 --- linux-2.6.6/kernel/pid.c    2004-05-10 04:32:38.000000000 +0200
17929 +++ linux-2.6.6.fixed/kernel/pid.c      2004-05-11 10:55:58.000000000 +0200
17930 @@ -25,6 +25,7 @@
17931  #include <linux/init.h>
17932  #include <linux/bootmem.h>
17933  #include <linux/hash.h>
17934 +#include <linux/grsecurity.h>
17935  
17936  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
17937  static struct list_head *pid_hash[PIDTYPE_MAX];
17938 @@ -99,10 +100,12 @@
17939  
17940  int alloc_pidmap(void)
17941  {
17942 -       int pid, offset, max_steps = PIDMAP_ENTRIES + 1;
17943 +       int pid = 0, offset, max_steps = PIDMAP_ENTRIES + 1;
17944         pidmap_t *map;
17945  
17946 -       pid = last_pid + 1;
17947 +       pid = gr_random_pid();
17948 +       if (!pid)
17949 +               pid = last_pid + 1;
17950         if (pid >= pid_max)
17951                 pid = RESERVED_PIDS;
17952  
17953 @@ -225,10 +228,16 @@
17954  task_t *find_task_by_pid(int nr)
17955  {
17956         struct pid *pid = find_pid(PIDTYPE_PID, nr);
17957 +       struct task_struct *task = NULL;
17958  
17959         if (!pid)
17960                 return NULL;
17961 -       return pid_task(pid->task_list.next, PIDTYPE_PID);
17962 +       task = pid_task(pid->task_list.next, PIDTYPE_PID);
17963 +
17964 +       if (gr_pid_is_chrooted(task))
17965 +               return NULL;
17966 +
17967 +       return task;
17968  }
17969  
17970  EXPORT_SYMBOL(find_task_by_pid);
17971 diff -uNr linux-2.6.6/kernel/printk.c linux-2.6.6.fixed/kernel/printk.c
17972 --- linux-2.6.6/kernel/printk.c 2004-05-10 04:33:21.000000000 +0200
17973 +++ linux-2.6.6.fixed/kernel/printk.c   2004-05-11 10:55:58.000000000 +0200
17974 @@ -30,6 +30,7 @@
17975  #include <linux/smp.h>
17976  #include <linux/security.h>
17977  #include <linux/bootmem.h>
17978 +#include <linux/grsecurity.h>
17979  
17980  #include <asm/uaccess.h>
17981  
17982 @@ -249,6 +250,11 @@
17983         char c;
17984         int error = 0;
17985  
17986 +#ifdef CONFIG_GRKERNSEC_DMESG
17987 +       if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
17988 +               return -EPERM;
17989 +#endif
17990 +
17991         error = security_syslog(type);
17992         if (error)
17993                 return error;
17994 diff -uNr linux-2.6.6/kernel/resource.c linux-2.6.6.fixed/kernel/resource.c
17995 --- linux-2.6.6/kernel/resource.c       2004-05-10 04:32:53.000000000 +0200
17996 +++ linux-2.6.6.fixed/kernel/resource.c 2004-05-11 10:55:58.000000000 +0200
17997 @@ -134,10 +134,27 @@
17998  {
17999         struct proc_dir_entry *entry;
18000  
18001 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
18002 +#ifdef CONFIG_GRKERNSEC_PROC_USER
18003 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
18004 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
18005 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
18006 +#endif
18007 +#else
18008         entry = create_proc_entry("ioports", 0, NULL);
18009 +#endif
18010         if (entry)
18011                 entry->proc_fops = &proc_ioports_operations;
18012 +
18013 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
18014 +#ifdef CONFIG_GRKERNSEC_PROC_USER
18015 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
18016 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
18017 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
18018 +#endif
18019 +#else
18020         entry = create_proc_entry("iomem", 0, NULL);
18021 +#endif
18022         if (entry)
18023                 entry->proc_fops = &proc_iomem_operations;
18024         return 0;
18025 diff -uNr linux-2.6.6/kernel/sched.c linux-2.6.6.fixed/kernel/sched.c
18026 --- linux-2.6.6/kernel/sched.c.orig     2004-05-10 04:33:13.000000000 +0200
18027 +++ linux-2.6.6/kernel/sched.c  2004-05-11 16:57:32.559053240 +0200
18028 @@ -40,6 +40,7 @@
18029  #include <linux/cpu.h>
18030  #include <linux/percpu.h>
18031  #include <linux/kthread.h>
18032 +#include <linux/grsecurity.h>
18033  
18034  #ifdef CONFIG_NUMA
18035  #define cpu_to_node_mask(cpu) node_to_cpumask(cpu_to_node(cpu))
18036 @@ -2156,6 +2157,8 @@
18037  }
18038  #endif
18039  
18040 +void __sched_text_start(void) {}
18041 +
18042  /*
18043   * schedule() is the main scheduler function.
18044   */
18045 @@ -2535,6 +2538,8 @@
18046  
18047  EXPORT_SYMBOL(sleep_on_timeout);
18048  
18049 +void __sched_text_end(void) {}
18050 +
18051  void set_user_nice(task_t *p, long nice)
18052  {
18053         unsigned long flags;
18054 @@ -2608,6 +2613,8 @@
18055                         return -EPERM;
18056                 if (increment < -40)
18057                         increment = -40;
18058 +               if (gr_handle_chroot_nice())
18059 +                       return -EPERM;
18060         }
18061         if (increment > 40)
18062                 increment = 40;
18063 @@ -3865,8 +3872,6 @@
18064  
18065  int in_sched_functions(unsigned long addr)
18066  {
18067 -       /* Linker adds these: start and end of __sched functions */
18068 -       extern char __sched_text_start[], __sched_text_end[];
18069         return addr >= (unsigned long)__sched_text_start
18070                 && addr < (unsigned long)__sched_text_end;
18071  }
18072 diff -uNr linux-2.6.6/kernel/signal.c linux-2.6.6.fixed/kernel/signal.c
18073 --- linux-2.6.6/kernel/signal.c 2004-05-10 04:32:28.000000000 +0200
18074 +++ linux-2.6.6.fixed/kernel/signal.c   2004-05-11 10:55:58.000000000 +0200
18075 @@ -21,6 +21,7 @@
18076  #include <linux/binfmts.h>
18077  #include <linux/security.h>
18078  #include <linux/ptrace.h>
18079 +#include <linux/grsecurity.h>
18080  #include <asm/param.h>
18081  #include <asm/uaccess.h>
18082  #include <asm/siginfo.h>
18083 @@ -769,11 +770,13 @@
18084         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
18085  
18086  
18087 -static int
18088 +int
18089  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
18090  {
18091         int ret = 0;
18092  
18093 +       gr_log_signal(sig, t);
18094 +
18095         if (!irqs_disabled())
18096                 BUG();
18097  #ifdef CONFIG_SMP
18098 @@ -824,6 +827,8 @@
18099         ret = specific_send_sig_info(sig, info, t);
18100         spin_unlock_irqrestore(&t->sighand->siglock, flags);
18101  
18102 +       gr_handle_crash(t, sig);
18103 +
18104         return ret;
18105  }
18106  
18107 @@ -1082,9 +1087,14 @@
18108                 int err;
18109  
18110                 found = 1;
18111 -               err = group_send_sig_info(sig, info, p);
18112 -               if (!retval)
18113 -                       retval = err;
18114 +
18115 +               if (gr_handle_signal(p, sig))
18116 +                       retval = -EPERM;
18117 +               else {
18118 +                       err = group_send_sig_info(sig, info, p);
18119 +                       if (!retval)
18120 +                               retval = err;
18121 +               }
18122         }
18123         return found ? retval : -ESRCH;
18124  }
18125 @@ -1142,8 +1152,12 @@
18126         read_lock(&tasklist_lock);
18127         p = find_task_by_pid(pid);
18128         error = -ESRCH;
18129 -       if (p)
18130 -               error = group_send_sig_info(sig, info, p);
18131 +       if (p) {
18132 +               if (gr_handle_signal(p, sig))
18133 +                       error = -EPERM;
18134 +               else
18135 +                       error = group_send_sig_info(sig, info, p);
18136 +       }
18137         read_unlock(&tasklist_lock);
18138         return error;
18139  }
18140 @@ -1167,10 +1181,14 @@
18141                 read_lock(&tasklist_lock);
18142                 for_each_process(p) {
18143                         if (p->pid > 1 && p->tgid != current->tgid) {
18144 -                               int err = group_send_sig_info(sig, info, p);
18145 -                               ++count;
18146 -                               if (err != -EPERM)
18147 -                                       retval = err;
18148 +                               if (gr_handle_signal(p, sig))
18149 +                                       retval = -EPERM;
18150 +                               else { 
18151 +                                       int err = group_send_sig_info(sig, info, p);
18152 +                                       ++count;
18153 +                                       if (err != -EPERM)
18154 +                                               retval = err;
18155 +                               }
18156                         }
18157                 }
18158                 read_unlock(&tasklist_lock);
18159 diff -uNr linux-2.6.6/kernel/sys.c linux-2.6.6.fixed/kernel/sys.c
18160 --- linux-2.6.6/kernel/sys.c    2004-05-10 04:32:00.000000000 +0200
18161 +++ linux-2.6.6.fixed/kernel/sys.c      2004-05-11 10:55:58.000000000 +0200
18162 @@ -23,6 +23,7 @@
18163  #include <linux/security.h>
18164  #include <linux/dcookies.h>
18165  #include <linux/suspend.h>
18166 +#include <linux/grsecurity.h>
18167  
18168  #include <asm/uaccess.h>
18169  #include <asm/io.h>
18170 @@ -290,6 +291,12 @@
18171                 error = -EACCES;
18172                 goto out;
18173         }
18174 +
18175 +       if (gr_handle_chroot_setpriority(p, niceval)) {
18176 +               error = -EACCES;
18177 +               goto out;
18178 +       }
18179 +
18180         no_nice = security_task_setnice(p, niceval);
18181         if (no_nice) {
18182                 error = no_nice;
18183 @@ -590,6 +597,9 @@
18184         if (rgid != (gid_t) -1 ||
18185             (egid != (gid_t) -1 && egid != old_rgid))
18186                 current->sgid = new_egid;
18187 +
18188 +       gr_set_role_label(current, current->uid, new_rgid);
18189 +
18190         current->fsgid = new_egid;
18191         current->egid = new_egid;
18192         current->gid = new_rgid;
18193 @@ -617,6 +627,9 @@
18194                         current->mm->dumpable=0;
18195                         wmb();
18196                 }
18197 +
18198 +               gr_set_role_label(current, current->uid, gid);
18199 +
18200                 current->gid = current->egid = current->sgid = current->fsgid = gid;
18201         }
18202         else if ((gid == current->gid) || (gid == current->sgid))
18203 @@ -655,6 +668,9 @@
18204                 current->mm->dumpable = 0;
18205                 wmb();
18206         }
18207 +
18208 +       gr_set_role_label(current, new_ruid, current->gid);
18209 +
18210         current->uid = new_ruid;
18211         return 0;
18212  }
18213 @@ -755,6 +771,9 @@
18214         } else if ((uid != current->uid) && (uid != new_suid))
18215                 return -EPERM;
18216  
18217 +       if (gr_check_crash_uid(uid))
18218 +               return -EPERM;
18219 +
18220         if (old_euid != uid)
18221         {
18222                 current->mm->dumpable = 0;
18223 @@ -854,8 +873,10 @@
18224                 current->egid = egid;
18225         }
18226         current->fsgid = current->egid;
18227 -       if (rgid != (gid_t) -1)
18228 +       if (rgid != (gid_t) -1) {
18229 +               gr_set_role_label(current, current->uid, rgid);
18230                 current->gid = rgid;
18231 +       }
18232         if (sgid != (gid_t) -1)
18233                 current->sgid = sgid;
18234         return 0;
18235 diff -uNr linux-2.6.6/kernel/sysctl.c linux-2.6.6.fixed/kernel/sysctl.c
18236 --- linux-2.6.6/kernel/sysctl.c 2004-05-10 04:32:00.000000000 +0200
18237 +++ linux-2.6.6.fixed/kernel/sysctl.c   2004-05-11 10:55:58.000000000 +0200
18238 @@ -46,6 +46,14 @@
18239  #endif
18240  
18241  #if defined(CONFIG_SYSCTL)
18242 +#include <linux/grsecurity.h>
18243 +#include <linux/grinternal.h>
18244 +
18245 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
18246 +                             const void *newval);
18247 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
18248 +                               const int op);
18249 +extern int gr_handle_chroot_sysctl(const int op);
18250  
18251  /* External variables not in a header file. */
18252  extern int panic_timeout;
18253 @@ -142,6 +150,32 @@
18254  #ifdef CONFIG_UNIX98_PTYS
18255  extern ctl_table pty_table[];
18256  #endif
18257 +extern ctl_table grsecurity_table[];
18258 +
18259 +#ifdef CONFIG_PAX_SOFTMODE
18260 +static ctl_table pax_table[] = {
18261 +
18262 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) || defined(CONFIG_PAX_RANDKSTACK)
18263 +       {
18264 +               .ctl_name       = PAX_ASLR,
18265 +               .procname       = "aslr",
18266 +               .data           = &pax_aslr,
18267 +               .maxlen         = sizeof(unsigned int),
18268 +               .mode           = 0600,
18269 +               .proc_handler   = &proc_dointvec,
18270 +       },
18271 +#endif
18272 +
18273 +       {
18274 +               .ctl_name       = PAX_SOFTMODE,
18275 +               .procname       = "softmode",
18276 +               .data           = &pax_softmode,
18277 +               .maxlen         = sizeof(unsigned int),
18278 +               .mode           = 0600,
18279 +               .proc_handler   = &proc_dointvec,
18280 +       }
18281 +};
18282 +#endif
18283  
18284  /* /proc declarations: */
18285  
18286 @@ -636,6 +670,14 @@
18287                 .mode           = 0444,
18288                 .proc_handler   = &proc_dointvec,
18289         },
18290 +#ifdef CONFIG_GRKERNSEC_SYSCTL
18291 +       {
18292 +               .ctl_name       = KERN_GRSECURITY,
18293 +               .procname       = "grsecurity",
18294 +               .mode           = 0500,
18295 +               .child          = grsecurity_table,
18296 +       },
18297 +#endif
18298         { .ctl_name = 0 }
18299  };
18300  
18301 @@ -897,6 +939,16 @@
18302                 .mode           = 0644,
18303                 .proc_handler   = &proc_dointvec,
18304         },
18305 +
18306 +#ifdef CONFIG_PAX_SOFTMODE
18307 +       {
18308 +               .ctl_name       = KERN_PAX,
18309 +               .procname       = "pax",
18310 +               .mode           = 0500,
18311 +               .child          = pax_table,
18312 +       },
18313 +#endif
18314 +
18315         { .ctl_name = 0 }
18316  };
18317  
18318 @@ -981,6 +1033,10 @@
18319  static inline int ctl_perm(ctl_table *table, int op)
18320  {
18321         int error;
18322 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
18323 +               return -EACCES;
18324 +       if (gr_handle_chroot_sysctl(op))
18325 +               return -EACCES;
18326         error = security_sysctl(table, op);
18327         if (error)
18328                 return error;
18329 @@ -1017,6 +1073,10 @@
18330                                 table = table->child;
18331                                 goto repeat;
18332                         }
18333 +
18334 +                       if (!gr_handle_sysctl(table, oldval, newval))
18335 +                               return -EACCES;
18336 +
18337                         error = do_sysctl_strategy(table, name, nlen,
18338                                                    oldval, oldlenp,
18339                                                    newval, newlen, context);
18340 diff -uNr linux-2.6.6/kernel/time.c linux-2.6.6.fixed/kernel/time.c
18341 --- linux-2.6.6/kernel/time.c   2004-05-10 04:32:26.000000000 +0200
18342 +++ linux-2.6.6.fixed/kernel/time.c     2004-05-11 10:55:58.000000000 +0200
18343 @@ -28,6 +28,7 @@
18344  #include <linux/timex.h>
18345  #include <linux/errno.h>
18346  #include <linux/smp_lock.h>
18347 +#include <linux/grsecurity.h>
18348  #include <asm/uaccess.h>
18349  
18350  /* 
18351 @@ -81,6 +82,9 @@
18352  
18353         tv.tv_nsec = 0;
18354         do_settimeofday(&tv);
18355 +
18356 +       gr_log_timechange();
18357 +
18358         return 0;
18359  }
18360  
18361 @@ -182,6 +186,8 @@
18362                         return -EFAULT;
18363         }
18364  
18365 +       gr_log_timechange();
18366 +
18367         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
18368  }
18369  
18370 diff -uNr linux-2.6.6/kernel/timer.c linux-2.6.6.fixed/kernel/timer.c
18371 --- linux-2.6.6/kernel/timer.c  2004-05-10 04:33:13.000000000 +0200
18372 +++ linux-2.6.6.fixed/kernel/timer.c    2004-05-11 10:55:58.000000000 +0200
18373 @@ -31,6 +31,7 @@
18374  #include <linux/time.h>
18375  #include <linux/jiffies.h>
18376  #include <linux/cpu.h>
18377 +#include <linux/grsecurity.h>
18378  
18379  #include <asm/uaccess.h>
18380  #include <asm/div64.h>
18381 @@ -757,6 +758,9 @@
18382  
18383         psecs = (p->utime += user);
18384         psecs += (p->stime += system);
18385 +
18386 +       gr_learn_resource(p, RLIMIT_CPU, psecs / HZ, 1);
18387 +
18388         if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
18389                 /* Send SIGXCPU every second.. */
18390                 if (!(psecs % HZ))
18391 diff -uNr linux-2.6.6/Makefile linux-2.6.6.fixed/Makefile
18392 --- linux-2.6.6/Makefile        2004-05-10 04:32:53.000000000 +0200
18393 +++ linux-2.6.6.fixed/Makefile  2004-05-11 10:57:58.000000000 +0200
18394 @@ -1,7 +1,7 @@
18395  VERSION = 2
18396  PATCHLEVEL = 6
18397  SUBLEVEL = 6
18398 -EXTRAVERSION =
18399 +EXTRAVERSION = -grsec
18400  NAME=Zonked Quokka
18401  
18402  # *DOCUMENTATION*
18403 @@ -484,7 +484,7 @@
18404  
18405  
18406  ifeq ($(KBUILD_EXTMOD),)
18407 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/
18408 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/
18409  
18410  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
18411                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
18412 diff -uNr linux-2.6.6/mm/filemap.c linux-2.6.6.fixed/mm/filemap.c
18413 --- linux-2.6.6/mm/filemap.c    2004-05-10 04:32:27.000000000 +0200
18414 +++ linux-2.6.6.fixed/mm/filemap.c      2004-05-11 10:55:58.000000000 +0200
18415 @@ -27,6 +27,8 @@
18416  #include <linux/pagevec.h>
18417  #include <linux/blkdev.h>
18418  #include <linux/security.h>
18419 +#include <linux/grsecurity.h>
18420 +
18421  /*
18422   * This is needed for the following functions:
18423   *  - try_to_release_page
18424 @@ -1386,6 +1388,12 @@
18425  
18426         if (!mapping->a_ops->readpage)
18427                 return -ENOEXEC;
18428 +
18429 +#ifdef CONFIG_PAX_PAGEEXEC
18430 +       if (current->flags & PF_PAX_PAGEEXEC)
18431 +               vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
18432 +#endif
18433 +
18434         file_accessed(file);
18435         vma->vm_ops = &generic_file_vm_ops;
18436         return 0;
18437 @@ -1684,6 +1692,7 @@
18438                          *pos = i_size_read(inode);
18439  
18440                 if (limit != RLIM_INFINITY) {
18441 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
18442                         if (*pos >= limit) {
18443                                 send_sig(SIGXFSZ, current, 0);
18444                                 return -EFBIG;
18445 diff -uNr linux-2.6.6/mm/madvise.c linux-2.6.6.fixed/mm/madvise.c
18446 --- linux-2.6.6/mm/madvise.c    2004-05-10 04:32:26.000000000 +0200
18447 +++ linux-2.6.6.fixed/mm/madvise.c      2004-05-11 10:55:58.000000000 +0200
18448 @@ -13,8 +13,42 @@
18449   * We can potentially split a vm area into separate
18450   * areas, each area with its own behavior.
18451   */
18452 +
18453 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18454 +static long __madvise_behavior(struct vm_area_struct * vma, unsigned long start,
18455 +                            unsigned long end, int behavior);
18456 +
18457 +static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
18458 +                            unsigned long end, int behavior)
18459 +{
18460 +       if (vma->vm_flags & VM_MIRROR) {
18461 +               struct vm_area_struct * vma_m, * prev_m;
18462 +               unsigned long start_m, end_m;
18463 +               int error;
18464 +
18465 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
18466 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
18467 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
18468 +                       start_m = start + (unsigned long)vma->vm_private_data;
18469 +                       end_m = end + (unsigned long)vma->vm_private_data;
18470 +                       error = __madvise_behavior(vma_m, start_m, end_m, behavior);
18471 +                       if (error)
18472 +                               return error;
18473 +               } else {
18474 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
18475 +                       return -ENOMEM;
18476 +               }
18477 +       }
18478 +
18479 +       return __madvise_behavior(vma, start, end, behavior);
18480 +}
18481 +
18482 +static long __madvise_behavior(struct vm_area_struct * vma, unsigned long start,
18483 +                            unsigned long end, int behavior)
18484 +#else
18485  static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
18486                              unsigned long end, int behavior)
18487 +#endif
18488  {
18489         struct mm_struct * mm = vma->vm_mm;
18490         int error;
18491 diff -uNr linux-2.6.6/mm/memory.c linux-2.6.6.fixed/mm/memory.c
18492 --- linux-2.6.6/mm/memory.c     2004-05-10 04:32:29.000000000 +0200
18493 +++ linux-2.6.6.fixed/mm/memory.c       2004-05-11 10:55:58.000000000 +0200
18494 @@ -46,6 +46,7 @@
18495  #include <linux/rmap.h>
18496  #include <linux/module.h>
18497  #include <linux/init.h>
18498 +#include <linux/grsecurity.h>
18499  
18500  #include <asm/pgalloc.h>
18501  #include <asm/rmap.h>
18502 @@ -1045,6 +1046,69 @@
18503         update_mmu_cache(vma, address, entry);
18504  }
18505  
18506 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18507 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
18508 + *
18509 + * mm->page_table_lock is held on entry and is not released on exit or inside
18510 + * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
18511 + */
18512 +struct pte_chain * pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma,
18513 +       unsigned long address, pte_t *pte, struct pte_chain *pte_chain)
18514 +{
18515 +       unsigned long address_m;
18516 +       struct vm_area_struct * vma_m = NULL;
18517 +       pte_t * pte_m, entry_m;
18518 +       struct page * page_m;
18519 +
18520 +       address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
18521 +       vma_m = find_vma(mm, address_m);
18522 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
18523 +
18524 +       address_m = address + (unsigned long)vma->vm_private_data;
18525 +
18526 +       {
18527 +               pgd_t *pgd_m;
18528 +               pmd_t *pmd_m;
18529 +
18530 +               pgd_m = pgd_offset(mm, address_m);
18531 +               pmd_m = pmd_offset(pgd_m, address_m);
18532 +               pte_m = pte_offset_map_nested(pmd_m, address_m);
18533 +       }
18534 +
18535 +       if (pte_present(*pte_m)) {
18536 +               flush_cache_page(vma_m, address_m);
18537 +               flush_icache_page(vma_m, pte_page(*pte_m));
18538 +       }
18539 +       entry_m = ptep_get_and_clear(pte_m);
18540 +       if (pte_present(entry_m))
18541 +               flush_tlb_page(vma_m, address_m);
18542 +
18543 +       if (pte_none(entry_m)) {
18544 +               ++mm->rss;
18545 +       } else if (pte_present(entry_m)) {
18546 +               page_remove_rmap(pte_page(entry_m), pte_m);
18547 +               page_cache_release(pte_page(entry_m));
18548 +       } else if (!pte_file(entry_m)) {
18549 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
18550 +               ++mm->rss;
18551 +       } else {
18552 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
18553 +                               address, vma->vm_start, address_m, vma_m->vm_start);
18554 +       }
18555 +
18556 +       page_m = pte_page(*pte);
18557 +       page_cache_get(page_m);
18558 +       entry_m = mk_pte(page_m, vma_m->vm_page_prot);
18559 +       if (pte_write(*pte))
18560 +               entry_m = pte_mkdirty(pte_mkwrite(entry_m));
18561 +       pte_chain = page_add_rmap(page_m, pte_m, pte_chain);
18562 +       ptep_establish(vma_m, address_m, pte_m, entry_m);
18563 +       update_mmu_cache(vma_m, address_m, entry_m);
18564 +       pte_unmap_nested(pte_m);
18565 +       return pte_chain;
18566 +}
18567 +#endif
18568 +
18569  /*
18570   * This routine handles present pages, when users try to write
18571   * to a shared page. It is done by copying the page to a new address
18572 @@ -1073,6 +1137,10 @@
18573         struct pte_chain *pte_chain;
18574         pte_t entry;
18575  
18576 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18577 +       struct pte_chain *pte_chain_m = NULL;
18578 +#endif
18579 +
18580         if (unlikely(!pfn_valid(pfn))) {
18581                 /*
18582                  * This should really halt the system so it can be debugged or
18583 @@ -1112,6 +1180,13 @@
18584         pte_chain = pte_chain_alloc(GFP_KERNEL);
18585         if (!pte_chain)
18586                 goto no_pte_chain;
18587 +
18588 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18589 +       pte_chain_m = pte_chain_alloc(GFP_KERNEL);
18590 +       if (!pte_chain_m)
18591 +               goto no_new_page;
18592 +#endif
18593 +
18594         new_page = alloc_page(GFP_HIGHUSER);
18595         if (!new_page)
18596                 goto no_new_page;
18597 @@ -1132,16 +1207,32 @@
18598  
18599                 /* Free the old page.. */
18600                 new_page = old_page;
18601 +
18602 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18603 +               if (vma->vm_flags & VM_MIRROR)
18604 +                       pte_chain_m = pax_mirror_fault(mm, vma, address, page_table, pte_chain_m);
18605 +#endif
18606 +
18607         }
18608         pte_unmap(page_table);
18609         page_cache_release(new_page);
18610         page_cache_release(old_page);
18611         spin_unlock(&mm->page_table_lock);
18612         pte_chain_free(pte_chain);
18613 +
18614 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18615 +       pte_chain_free(pte_chain_m);
18616 +#endif
18617 +
18618         return VM_FAULT_MINOR;
18619  
18620  no_new_page:
18621         pte_chain_free(pte_chain);
18622 +
18623 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18624 +       pte_chain_free(pte_chain_m);
18625 +#endif
18626 +
18627  no_pte_chain:
18628         page_cache_release(old_page);
18629         return VM_FAULT_OOM;
18630 @@ -1257,6 +1348,7 @@
18631  
18632  do_expand:
18633         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
18634 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
18635         if (limit != RLIM_INFINITY && offset > limit)
18636                 goto out_sig;
18637         if (offset > inode->i_sb->s_maxbytes)
18638 @@ -1316,6 +1408,10 @@
18639         int ret = VM_FAULT_MINOR;
18640         struct pte_chain *pte_chain = NULL;
18641  
18642 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18643 +       struct pte_chain *pte_chain_m = NULL;
18644 +#endif
18645 +
18646         pte_unmap(page_table);
18647         spin_unlock(&mm->page_table_lock);
18648         page = lookup_swap_cache(entry);
18649 @@ -1349,6 +1445,15 @@
18650                 ret = VM_FAULT_OOM;
18651                 goto out;
18652         }
18653 +
18654 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18655 +       pte_chain_m = pte_chain_alloc(GFP_KERNEL);
18656 +       if (!pte_chain_m) {
18657 +               ret = -ENOMEM;
18658 +               goto out;
18659 +       }
18660 +#endif
18661 +
18662         lock_page(page);
18663  
18664         /*
18665 @@ -1384,10 +1489,21 @@
18666  
18667         /* No need to invalidate - it was non-present before */
18668         update_mmu_cache(vma, address, pte);
18669 +
18670 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18671 +       if (vma->vm_flags & VM_MIRROR)
18672 +               pte_chain_m = pax_mirror_fault(mm, vma, address, page_table, pte_chain_m);
18673 +#endif
18674 +
18675         pte_unmap(page_table);
18676         spin_unlock(&mm->page_table_lock);
18677  out:
18678         pte_chain_free(pte_chain);
18679 +
18680 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18681 +       pte_chain_free(pte_chain_m);
18682 +#endif
18683 +
18684         return ret;
18685  }
18686  
18687 @@ -1406,13 +1522,38 @@
18688         struct pte_chain *pte_chain;
18689         int ret;
18690  
18691 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18692 +       struct pte_chain *pte_chain_m = NULL;
18693 +#endif
18694 +
18695         pte_chain = pte_chain_alloc(GFP_ATOMIC | __GFP_NOWARN);
18696 +
18697 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18698 +       pte_chain_m = pte_chain_alloc(GFP_ATOMIC | __GFP_NOWARN);
18699 +#endif
18700 +
18701 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18702 +       if (!pte_chain || !pte_chain_m) {
18703 +#else
18704         if (!pte_chain) {
18705 +#endif
18706 +
18707                 pte_unmap(page_table);
18708                 spin_unlock(&mm->page_table_lock);
18709 +
18710 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18711 +               if (!pte_chain)
18712 +                       pte_chain = pte_chain_alloc(GFP_KERNEL);
18713 +               if (!pte_chain_m)
18714 +                       pte_chain_m = pte_chain_alloc(GFP_KERNEL);
18715 +               if (!pte_chain || !pte_chain_m)
18716 +                       goto no_mem;
18717 +#else
18718                 pte_chain = pte_chain_alloc(GFP_KERNEL);
18719                 if (!pte_chain)
18720                         goto no_mem;
18721 +#endif
18722 +
18723                 spin_lock(&mm->page_table_lock);
18724                 page_table = pte_offset_map(pmd, addr);
18725         }
18726 @@ -1452,10 +1593,16 @@
18727         set_pte(page_table, entry);
18728         /* ignores ZERO_PAGE */
18729         pte_chain = page_add_rmap(page, page_table, pte_chain);
18730 -       pte_unmap(page_table);
18731  
18732         /* No need to invalidate - it was non-present before */
18733         update_mmu_cache(vma, addr, entry);
18734 +
18735 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18736 +       if (vma->vm_flags & VM_MIRROR)
18737 +               pte_chain_m = pax_mirror_fault(mm, vma, addr, page_table, pte_chain_m);
18738 +#endif
18739 +
18740 +       pte_unmap(page_table);
18741         spin_unlock(&mm->page_table_lock);
18742         ret = VM_FAULT_MINOR;
18743         goto out;
18744 @@ -1464,6 +1611,11 @@
18745         ret = VM_FAULT_OOM;
18746  out:
18747         pte_chain_free(pte_chain);
18748 +
18749 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18750 +       pte_chain_free(pte_chain_m);
18751 +#endif
18752 +
18753         return ret;
18754  }
18755  
18756 @@ -1490,6 +1642,10 @@
18757         int sequence = 0;
18758         int ret = VM_FAULT_MINOR;
18759  
18760 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18761 +       struct pte_chain *pte_chain_m = NULL;
18762 +#endif
18763 +
18764         if (!vma->vm_ops || !vma->vm_ops->nopage)
18765                 return do_anonymous_page(mm, vma, page_table,
18766                                         pmd, write_access, address);
18767 @@ -1514,6 +1670,12 @@
18768         if (!pte_chain)
18769                 goto oom;
18770  
18771 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18772 +       pte_chain_m = pte_chain_alloc(GFP_KERNEL);
18773 +       if (!pte_chain_m)
18774 +               goto oom;
18775 +#endif
18776 +
18777         /*
18778          * Should we do an early C-O-W break?
18779          */
18780 @@ -1539,6 +1701,11 @@
18781                 spin_unlock(&mm->page_table_lock);
18782                 page_cache_release(new_page);
18783                 pte_chain_free(pte_chain);
18784 +
18785 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18786 +               pte_chain_free(pte_chain_m);
18787 +#endif
18788 +
18789                 goto retry;
18790         }
18791         page_table = pte_offset_map(pmd, address);
18792 @@ -1563,6 +1730,15 @@
18793                         entry = maybe_mkwrite(pte_mkdirty(entry), vma);
18794                 set_pte(page_table, entry);
18795                 pte_chain = page_add_rmap(new_page, page_table, pte_chain);
18796 +
18797 +               /* no need to invalidate: a not-present page shouldn't be cached */
18798 +               update_mmu_cache(vma, address, entry);
18799 +
18800 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18801 +               if (vma->vm_flags & VM_MIRROR)
18802 +                       pte_chain_m = pax_mirror_fault(mm, vma, address, page_table, pte_chain_m);
18803 +#endif
18804 +
18805                 pte_unmap(page_table);
18806         } else {
18807                 /* One of our sibling threads was faster, back out. */
18808 @@ -1572,8 +1748,6 @@
18809                 goto out;
18810         }
18811  
18812 -       /* no need to invalidate: a not-present page shouldn't be cached */
18813 -       update_mmu_cache(vma, address, entry);
18814         spin_unlock(&mm->page_table_lock);
18815         goto out;
18816  oom:
18817 @@ -1581,6 +1755,11 @@
18818         ret = VM_FAULT_OOM;
18819  out:
18820         pte_chain_free(pte_chain);
18821 +
18822 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18823 +       pte_chain_free(pte_chain_m);
18824 +#endif
18825 +
18826         return ret;
18827  }
18828  
18829 @@ -1683,6 +1862,11 @@
18830         pgd_t *pgd;
18831         pmd_t *pmd;
18832  
18833 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18834 +       unsigned long address_m = 0UL;
18835 +       struct vm_area_struct * vma_m = NULL;
18836 +#endif
18837 +
18838         __set_current_state(TASK_RUNNING);
18839         pgd = pgd_offset(mm, address);
18840  
18841 @@ -1696,6 +1880,48 @@
18842          * and the SMP-safe atomic PTE updates.
18843          */
18844         spin_lock(&mm->page_table_lock);
18845 +
18846 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18847 +       if (vma->vm_flags & VM_MIRROR) {
18848 +               pgd_t *pgd_m;
18849 +               pmd_t *pmd_m;
18850 +               pte_t *pte_m;
18851 +
18852 +               address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
18853 +               vma_m = find_vma(mm, address_m);
18854 +
18855 +               /* PaX: sanity checks */
18856 +               if (!vma_m) {
18857 +                       spin_unlock(&mm->page_table_lock);
18858 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
18859 +                              address, vma, address_m, vma_m);
18860 +                       return VM_FAULT_SIGBUS;
18861 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
18862 +                          vma_m->vm_start != address_m ||
18863 +                          vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
18864 +               {
18865 +                       spin_unlock(&mm->page_table_lock);
18866 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
18867 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
18868 +                       return VM_FAULT_SIGBUS;
18869 +               }
18870 +
18871 +               address_m = address + (unsigned long)vma->vm_private_data;
18872 +               pgd_m = pgd_offset(mm, address_m);
18873 +               pmd_m = pmd_alloc(mm, pgd_m, address_m);
18874 +               if (!pmd_m) {
18875 +                       spin_unlock(&mm->page_table_lock);
18876 +                       return VM_FAULT_OOM;
18877 +               }
18878 +               pte_m = pte_alloc_map(mm, pmd_m, address_m);
18879 +               if (!pte_m) {
18880 +                       spin_unlock(&mm->page_table_lock);
18881 +                       return VM_FAULT_OOM;
18882 +               }
18883 +               pte_unmap(pte_m);
18884 +       }
18885 +#endif
18886 +
18887         pmd = pmd_alloc(mm, pgd, address);
18888  
18889         if (pmd) {
18890 diff -uNr linux-2.6.6/mm/mlock.c linux-2.6.6.fixed/mm/mlock.c
18891 --- linux-2.6.6/mm/mlock.c      2004-05-10 04:31:59.000000000 +0200
18892 +++ linux-2.6.6.fixed/mm/mlock.c        2004-05-11 10:55:58.000000000 +0200
18893 @@ -7,11 +7,43 @@
18894  
18895  #include <linux/mman.h>
18896  #include <linux/mm.h>
18897 +#include <linux/grsecurity.h>
18898  
18899 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
18900 +static int __mlock_fixup(struct vm_area_struct * vma, 
18901 +       unsigned long start, unsigned long end, unsigned int newflags);
18902  
18903  static int mlock_fixup(struct vm_area_struct * vma, 
18904         unsigned long start, unsigned long end, unsigned int newflags)
18905  {
18906 +       if (vma->vm_flags & VM_MIRROR) {
18907 +               struct vm_area_struct * vma_m;
18908 +               unsigned long start_m, end_m;
18909 +               int error;
18910 +
18911 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
18912 +               vma_m = find_vma(vma->vm_mm, start_m);
18913 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
18914 +                       start_m = start + (unsigned long)vma->vm_private_data;
18915 +                       end_m = end + (unsigned long)vma->vm_private_data;
18916 +                       error = __mlock_fixup(vma_m, start_m, end_m, newflags);
18917 +                       if (error)
18918 +                               return error;
18919 +               } else {
18920 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
18921 +                       return -ENOMEM;
18922 +               }
18923 +       }
18924 +       return __mlock_fixup(vma, start, end, newflags);
18925 +}
18926 +
18927 +static int __mlock_fixup(struct vm_area_struct * vma, 
18928 +       unsigned long start, unsigned long end, unsigned int newflags)
18929 +#else
18930 +static int mlock_fixup(struct vm_area_struct * vma, 
18931 +       unsigned long start, unsigned long end, unsigned int newflags)
18932 +#endif
18933 +{
18934         struct mm_struct * mm = vma->vm_mm;
18935         int pages;
18936         int ret = 0;
18937 @@ -65,6 +97,17 @@
18938                 return -EINVAL;
18939         if (end == start)
18940                 return 0;
18941 +
18942 +#ifdef CONFIG_PAX_SEGMEXEC
18943 +       if (current->flags & PF_PAX_SEGMEXEC) {
18944 +               if (end > SEGMEXEC_TASK_SIZE)
18945 +                       return -EINVAL;
18946 +       } else
18947 +#endif
18948 +
18949 +       if (end > TASK_SIZE)
18950 +               return -EINVAL;
18951 +
18952         vma = find_vma(current->mm, start);
18953         if (!vma || vma->vm_start > start)
18954                 return -ENOMEM;
18955 @@ -115,6 +158,7 @@
18956         lock_limit >>= PAGE_SHIFT;
18957  
18958         /* check against resource limits */
18959 +       gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
18960         if (locked <= lock_limit)
18961                 error = do_mlock(start, len, 1);
18962         up_write(&current->mm->mmap_sem);
18963 @@ -151,6 +195,16 @@
18964         for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
18965                 unsigned int newflags;
18966  
18967 +#ifdef CONFIG_PAX_SEGMEXEC
18968 +               if (current->flags & PF_PAX_SEGMEXEC) {
18969 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
18970 +                               break;
18971 +               } else
18972 +#endif
18973 +
18974 +               if (vma->vm_end > TASK_SIZE)
18975 +                       break;
18976 +
18977                 newflags = vma->vm_flags | VM_LOCKED;
18978                 if (!(flags & MCL_CURRENT))
18979                         newflags &= ~VM_LOCKED;
18980 @@ -174,6 +228,7 @@
18981         lock_limit >>= PAGE_SHIFT;
18982  
18983         ret = -ENOMEM;
18984 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
18985         if (current->mm->total_vm <= lock_limit)
18986                 ret = do_mlockall(flags);
18987  out:
18988 diff -uNr linux-2.6.6/mm/mmap.c linux-2.6.6.fixed/mm/mmap.c
18989 --- linux-2.6.6/mm/mmap.c       2004-05-10 04:32:52.000000000 +0200
18990 +++ linux-2.6.6.fixed/mm/mmap.c 2004-05-11 10:55:58.000000000 +0200
18991 @@ -21,6 +21,7 @@
18992  #include <linux/profile.h>
18993  #include <linux/module.h>
18994  #include <linux/mount.h>
18995 +#include <linux/grsecurity.h>
18996  
18997  #include <asm/uaccess.h>
18998  #include <asm/pgalloc.h>
18999 @@ -121,6 +122,7 @@
19000  
19001         /* Check against rlimit.. */
19002         rlim = current->rlim[RLIMIT_DATA].rlim_cur;
19003 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
19004         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
19005                 goto out;
19006  
19007 @@ -327,6 +329,12 @@
19008  static inline int is_mergeable_vma(struct vm_area_struct *vma,
19009                         struct file *file, unsigned long vm_flags)
19010  {
19011 +
19012 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19013 +       if ((vma->vm_flags | vm_flags) & VM_MIRROR)
19014 +               return 0;
19015 +#endif
19016 +
19017         if (vma->vm_ops && vma->vm_ops->close)
19018                 return 0;
19019         if (vma->vm_file != file)
19020 @@ -484,6 +492,43 @@
19021                         unsigned long len, unsigned long prot,
19022                         unsigned long flags, unsigned long pgoff)
19023  {
19024 +       unsigned long ret = -EINVAL;
19025 +
19026 +#ifdef CONFIG_PAX_SEGMEXEC
19027 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
19028 +           (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len)))
19029 +               goto out;
19030 +#endif
19031 +
19032 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
19033 +
19034 +#ifdef CONFIG_PAX_SEGMEXEC
19035 +       if ((current->flags & PF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
19036 +
19037 +#ifdef CONFIG_PAX_MPROTECT
19038 +           && (!(current->flags & PF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
19039 +#endif
19040 +
19041 +          )
19042 +       {
19043 +               unsigned long ret_m;
19044 +               prot = prot & PROT_EXEC ? prot : PROT_NONE;
19045 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
19046 +               if (ret_m >= TASK_SIZE) {
19047 +                       do_munmap(current->mm, ret, len);
19048 +                       ret = ret_m;
19049 +               }
19050 +       }
19051 +#endif
19052 +
19053 +out:
19054 +       return ret;
19055 +}
19056 +
19057 +unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
19058 +                       unsigned long len, unsigned long prot,
19059 +                       unsigned long flags, unsigned long pgoff)
19060 +{
19061         struct mm_struct * mm = current->mm;
19062         struct vm_area_struct * vma, * prev;
19063         struct inode *inode;
19064 @@ -494,6 +539,28 @@
19065         int accountable = 1;
19066         unsigned long charged = 0;
19067  
19068 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19069 +       struct vm_area_struct * vma_m = NULL;
19070 +
19071 +       if (flags & MAP_MIRROR) {
19072 +               /* PaX: sanity checks, to be removed when proved to be stable */
19073 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
19074 +                       return -EINVAL;
19075 +
19076 +               vma_m = find_vma(mm, pgoff);
19077 +
19078 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
19079 +                   vma_m->vm_start != pgoff ||
19080 +                   (vma_m->vm_flags & VM_MIRROR) ||
19081 +                   (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE)))
19082 +                       return -EINVAL;
19083 +
19084 +               file = vma_m->vm_file;
19085 +               pgoff = vma_m->vm_pgoff;
19086 +               len = vma_m->vm_end - vma_m->vm_start;
19087 +       }
19088 +#endif
19089 +
19090         if (file) {
19091                 if (is_file_hugepages(file))
19092                         accountable = 0;
19093 @@ -535,6 +602,30 @@
19094         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
19095                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
19096  
19097 +       if (file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
19098 +               vm_flags &= ~VM_MAYEXEC;
19099 +
19100 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19101 +       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
19102 +
19103 +#ifdef CONFIG_PAX_MPROTECT
19104 +               if (current->flags & PF_PAX_MPROTECT) {
19105 +                       if (!file || (prot & PROT_WRITE))
19106 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
19107 +                       else
19108 +                               vm_flags &= ~VM_MAYWRITE;
19109 +
19110 +#ifdef CONFIG_PAX_RANDEXEC
19111 +                       if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC))
19112 +                               vma_m->vm_flags &= ~VM_MAYWRITE;
19113 +#endif
19114 +
19115 +               }
19116 +#endif
19117 +
19118 +       }
19119 +#endif
19120 +
19121         if (flags & MAP_LOCKED) {
19122                 if (!capable(CAP_IPC_LOCK))
19123                         return -EPERM;
19124 @@ -544,6 +635,7 @@
19125         if (vm_flags & VM_LOCKED) {
19126                 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
19127                 locked += len;
19128 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
19129                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
19130                         return -EAGAIN;
19131         }
19132 @@ -599,6 +691,9 @@
19133         if (error)
19134                 return error;
19135                 
19136 +       if (!gr_acl_handle_mmap(file, prot))
19137 +               return -EACCES;
19138 +
19139         /* Clear old maps */
19140         error = -ENOMEM;
19141  munmap_back:
19142 @@ -610,6 +705,7 @@
19143         }
19144  
19145         /* Check against address space limit. */
19146 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
19147         if ((mm->total_vm << PAGE_SHIFT) + len
19148             > current->rlim[RLIMIT_AS].rlim_cur)
19149                 return -ENOMEM;
19150 @@ -650,6 +746,13 @@
19151         vma->vm_start = addr;
19152         vma->vm_end = addr + len;
19153         vma->vm_flags = vm_flags;
19154 +
19155 +#ifdef CONFIG_PAX_PAGEEXEC
19156 +       if ((file || !(current->flags & PF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
19157 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f];
19158 +       else
19159 +#endif
19160 +
19161         vma->vm_page_prot = protection_map[vm_flags & 0x0f];
19162         vma->vm_ops = NULL;
19163         vma->vm_pgoff = pgoff;
19164 @@ -679,6 +782,14 @@
19165                         goto free_vma;
19166         }
19167  
19168 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19169 +       if (flags & MAP_MIRROR) {
19170 +               vma_m->vm_flags |= VM_MIRROR;
19171 +               vma_m->vm_private_data = (void *)(vma->vm_start - vma_m->vm_start);
19172 +               vma->vm_private_data = (void *)(vma_m->vm_start - vma->vm_start);
19173 +       }
19174 +#endif
19175 +
19176         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
19177          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
19178          * that memory reservation must be checked; but that reservation
19179 @@ -738,6 +849,7 @@
19180  }
19181  
19182  EXPORT_SYMBOL(do_mmap_pgoff);
19183 +EXPORT_SYMBOL(__do_mmap_pgoff);
19184  
19185  /* Get an address range which is currently unmapped.
19186   * For shmat() with addr=0.
19187 @@ -759,12 +871,28 @@
19188         struct vm_area_struct *vma;
19189         unsigned long start_addr;
19190  
19191 +#ifdef CONFIG_PAX_SEGMEXEC
19192 +       if ((current->flags & PF_PAX_SEGMEXEC) && len > SEGMEXEC_TASK_SIZE)
19193 +               return -ENOMEM;
19194 +       else
19195 +#endif
19196 +
19197         if (len > TASK_SIZE)
19198                 return -ENOMEM;
19199  
19200 +#ifdef CONFIG_PAX_RANDMMAP
19201 +       if (!(current->flags & PF_PAX_RANDMMAP) || !filp)
19202 +#endif
19203 +
19204         if (addr) {
19205                 addr = PAGE_ALIGN(addr);
19206                 vma = find_vma(mm, addr);
19207 +
19208 +#ifdef CONFIG_PAX_SEGMEXEC
19209 +               if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr)
19210 +                       return -ENOMEM;
19211 +#endif
19212 +
19213                 if (TASK_SIZE - len >= addr &&
19214                     (!vma || addr + len <= vma->vm_start))
19215                         return addr;
19216 @@ -779,6 +907,17 @@
19217                          * Start a new search - just in case we missed
19218                          * some holes.
19219                          */
19220 +
19221 +#ifdef CONFIG_PAX_RANDMMAP
19222 +                       if (current->flags & PF_PAX_RANDMMAP) {
19223 +                               if (start_addr != TASK_UNMAPPED_BASE + mm->delta_mmap) {
19224 +                                       start_addr = addr = TASK_UNMAPPED_BASE + mm->delta_mmap;
19225 +                                       goto full_search;
19226 +                               }
19227 +                               return -ENOMEM;
19228 +                       } else
19229 +#endif
19230 +
19231                         if (start_addr != TASK_UNMAPPED_BASE) {
19232                                 start_addr = addr = TASK_UNMAPPED_BASE;
19233                                 goto full_search;
19234 @@ -939,10 +1078,18 @@
19235                 spin_unlock(&vma->vm_mm->page_table_lock);
19236                 return -ENOMEM;
19237         }
19238 -       
19239 +
19240 +       gr_learn_resource(current, RLIMIT_STACK, address - vma->vm_start, 1);
19241 +       gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
19242 +       if (vma->vm_flags & VM_LOCKED)
19243 +               gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);    
19244 +
19245         if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
19246                         ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
19247 -                       current->rlim[RLIMIT_AS].rlim_cur) {
19248 +                       current->rlim[RLIMIT_AS].rlim_cur ||
19249 +                       ((vma->vm_flags & VM_LOCKED) &&
19250 +                       ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
19251 +                       current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
19252                 spin_unlock(&vma->vm_mm->page_table_lock);
19253                 vm_unacct_memory(grow);
19254                 return -ENOMEM;
19255 @@ -993,10 +1140,62 @@
19256                 spin_unlock(&vma->vm_mm->page_table_lock);
19257                 return -ENOMEM;
19258         }
19259 -       
19260 +
19261 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19262 +       if (vma->vm_flags & VM_MIRROR) {
19263 +               struct vm_area_struct * vma_m;
19264 +               unsigned long address_m;
19265 +
19266 +               address_m = vma->vm_start + (unsigned long)vma->vm_private_data;
19267 +               vma_m = find_vma(vma->vm_mm, address_m);
19268 +               if (!vma_m || vma_m->vm_start != address_m ||
19269 +                               !(vma_m->vm_flags & VM_MIRROR) ||
19270 +                               vma->vm_end - vma->vm_start !=
19271 +                               vma_m->vm_end - vma_m->vm_start) {
19272 +                       spin_unlock(&vma->vm_mm->page_table_lock);
19273 +                       vm_unacct_memory(grow);
19274 +                       printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
19275 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
19276 +                       return -ENOMEM;
19277 +               }
19278 +
19279 +               address_m = address + (unsigned long)vma->vm_private_data;
19280 +
19281 +               gr_learn_resource(current, RLIMIT_STACK, vma_m->vm_end - address_m, 1);
19282 +               gr_learn_resource(current, RLIMIT_AS, (vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT, 1);
19283 +               if (vma_m->vm_flags & VM_LOCKED)
19284 +                       gr_learn_resource(current, RLIMIT_MEMLOCK, (vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT, 1);
19285 +
19286 +               if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur ||
19287 +                               ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) >
19288 +                               current->rlim[RLIMIT_AS].rlim_cur ||
19289 +                               ((vma_m->vm_flags & VM_LOCKED) &&
19290 +                               ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) >
19291 +                               current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
19292 +                       spin_unlock(&vma->vm_mm->page_table_lock);
19293 +                       vm_unacct_memory(grow);
19294 +                       return -ENOMEM;
19295 +               }
19296 +
19297 +               vma_m->vm_start = address_m;
19298 +               vma_m->vm_pgoff -= grow;
19299 +               vma_m->vm_mm->total_vm += grow;
19300 +               if (vma_m->vm_flags & VM_LOCKED)
19301 +                       vma_m->vm_mm->locked_vm += grow;
19302 +       } else
19303 +#endif
19304 +
19305 +       gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address, 1);
19306 +       gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT, 1);
19307 +       if (vma->vm_flags & VM_LOCKED)
19308 +               gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT, 1);
19309 +
19310         if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
19311                         ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
19312 -                       current->rlim[RLIMIT_AS].rlim_cur) {
19313 +                       current->rlim[RLIMIT_AS].rlim_cur ||
19314 +                       ((vma->vm_flags & VM_LOCKED) &&
19315 +                       ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
19316 +                       current->rlim[RLIMIT_MEMLOCK].rlim_cur)) {
19317                 spin_unlock(&vma->vm_mm->page_table_lock);
19318                 vm_unacct_memory(grow);
19319                 return -ENOMEM;
19320 @@ -1108,15 +1307,15 @@
19321  {
19322         size_t len = area->vm_end - area->vm_start;
19323  
19324 -       area->vm_mm->total_vm -= len >> PAGE_SHIFT;
19325 +       mm->total_vm -= len >> PAGE_SHIFT;
19326         if (area->vm_flags & VM_LOCKED)
19327 -               area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
19328 +               mm->locked_vm -= len >> PAGE_SHIFT;
19329         /*
19330          * Is this a new hole at the lowest possible address?
19331          */
19332         if (area->vm_start >= TASK_UNMAPPED_BASE &&
19333 -                               area->vm_start < area->vm_mm->free_area_cache)
19334 -             area->vm_mm->free_area_cache = area->vm_start;
19335 +                               area->vm_start < mm->free_area_cache)
19336 +             mm->free_area_cache = area->vm_start;
19337  
19338         remove_shared_vm_struct(area);
19339  
19340 @@ -1178,21 +1377,73 @@
19341   */
19342  static void
19343  detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
19344 -       struct vm_area_struct *prev, unsigned long end)
19345 +       struct vm_area_struct *prev, unsigned long *start, unsigned long *end)
19346  {
19347         struct vm_area_struct **insertion_point;
19348         struct vm_area_struct *tail_vma = NULL;
19349  
19350 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19351 +       unsigned long start_m;
19352 +       struct vm_area_struct *vma_m, *head_vma = vma, *mirrors = NULL, *head_vma_m = NULL;
19353 +#endif
19354 +
19355         insertion_point = (prev ? &prev->vm_next : &mm->mmap);
19356         do {
19357                 rb_erase(&vma->vm_rb, &mm->mm_rb);
19358                 mm->map_count--;
19359 +
19360 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19361 +               if ((vma->vm_flags & VM_MIRROR) &&
19362 +                   vma->vm_start + (unsigned long)vma->vm_private_data >= *start &&
19363 +                   vma->vm_start + (unsigned long)vma->vm_private_data < *end)
19364 +               {
19365 +                       mm->mmap_cache = NULL;          /* Kill the cache. */
19366 +                       start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
19367 +                       vma_m = find_vma(mm, start_m);
19368 +                       if (vma_m && (vma_m->vm_flags & VM_MIRROR) && vma_m->vm_start == start_m) {
19369 +                               vma->vm_flags &= ~VM_MIRROR;
19370 +                               vma_m->vm_flags &= ~VM_MIRROR;
19371 +                       } else
19372 +                               printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, vma->vm_start);
19373 +               }
19374 +#endif
19375 +
19376                 tail_vma = vma;
19377                 vma = vma->vm_next;
19378 -       } while (vma && vma->vm_start < end);
19379 +       } while (vma && vma->vm_start < *end);
19380         *insertion_point = vma;
19381         tail_vma->vm_next = NULL;
19382         mm->mmap_cache = NULL;          /* Kill the cache. */
19383 +
19384 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19385 +       for (; head_vma; head_vma = head_vma->vm_next) {
19386 +               struct vm_area_struct *prev_m;
19387 +
19388 +               if (!(head_vma->vm_flags & VM_MIRROR))
19389 +                       continue;
19390 +
19391 +               start_m = head_vma->vm_start + (unsigned long)head_vma->vm_private_data;
19392 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
19393 +               rb_erase(&vma_m->vm_rb, &mm->mm_rb);
19394 +               mm->map_count--;
19395 +               insertion_point = prev_m ? &prev_m->vm_next : &mm->mmap;
19396 +               *insertion_point = vma_m->vm_next;
19397 +               if (head_vma_m) {
19398 +                       mirrors->vm_next = vma_m;
19399 +                       mirrors = vma_m;
19400 +               } else
19401 +                       head_vma_m = mirrors = vma_m;
19402 +               mirrors->vm_next = NULL;
19403 +               if (vma_m->vm_start < *start)
19404 +                       *start = vma_m->vm_start;
19405 +               if (vma_m->vm_end > *end)
19406 +                       *end = vma_m->vm_end;
19407 +               mm->mmap_cache = NULL;          /* Kill the cache. */
19408 +       }
19409 +       if (head_vma_m)
19410 +               tail_vma->vm_next = head_vma_m;
19411 +#endif
19412 +
19413  }
19414  
19415  /*
19416 @@ -1262,6 +1513,10 @@
19417         unsigned long end;
19418         struct vm_area_struct *mpnt, *prev, *last;
19419  
19420 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19421 +       struct vm_area_struct *mpnt_m = NULL, *last_m;
19422 +#endif
19423 +
19424         if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
19425                 return -EINVAL;
19426  
19427 @@ -1298,6 +1553,20 @@
19428          * places tmp vma above, and higher split_vma places tmp vma below.
19429          */
19430         if (start > mpnt->vm_start) {
19431 +
19432 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19433 +               if (mpnt->vm_flags & VM_MIRROR) {
19434 +                       unsigned long start_m = mpnt->vm_start + (unsigned long)mpnt->vm_private_data;
19435 +
19436 +                       mpnt_m = find_vma(mm, start_m);
19437 +                       if (!mpnt_m || (!mpnt_m->vm_flags & VM_MIRROR) || mpnt_m->vm_start != start_m)
19438 +                               return -EINVAL;
19439 +                       start_m = start + (unsigned long)mpnt->vm_private_data;
19440 +                       if (split_vma(mm, mpnt_m, start_m, 0))
19441 +                               return -ENOMEM;
19442 +               }
19443 +#endif
19444 +
19445                 if (split_vma(mm, mpnt, start, 0))
19446                         return -ENOMEM;
19447                 prev = mpnt;
19448 @@ -1306,6 +1575,20 @@
19449         /* Does it split the last one? */
19450         last = find_vma(mm, end);
19451         if (last && end > last->vm_start) {
19452 +
19453 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19454 +               if (last->vm_flags & VM_MIRROR) {
19455 +                       unsigned long end_m = last->vm_start + (unsigned long)last->vm_private_data;
19456 +
19457 +                       last_m = find_vma(mm, end_m);
19458 +                       if (!last_m || (!last_m->vm_flags & VM_MIRROR) || last_m->vm_start != end_m)
19459 +                               return -EINVAL;
19460 +                       end_m = end + (unsigned long)last->vm_private_data;
19461 +                       if (split_vma(mm, last_m, end_m, 1))
19462 +                               return -ENOMEM;
19463 +               }
19464 +#endif
19465 +
19466                 if (split_vma(mm, last, end, 1))
19467                         return -ENOMEM;
19468         }
19469 @@ -1315,7 +1598,7 @@
19470          * Remove the vma's, and unmap the actual pages
19471          */
19472         spin_lock(&mm->page_table_lock);
19473 -       detach_vmas_to_be_unmapped(mm, mpnt, prev, end);
19474 +       detach_vmas_to_be_unmapped(mm, mpnt, prev, &start, &end);
19475         unmap_region(mm, mpnt, prev, start, end);
19476         spin_unlock(&mm->page_table_lock);
19477  
19478 @@ -1332,6 +1615,12 @@
19479         int ret;
19480         struct mm_struct *mm = current->mm;
19481  
19482 +#ifdef CONFIG_PAX_SEGMEXEC
19483 +       if ((current->flags & PF_PAX_SEGMEXEC) &&
19484 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
19485 +               return -EINVAL;
19486 +#endif
19487 +
19488         down_write(&mm->mmap_sem);
19489         ret = do_munmap(mm, addr, len);
19490         up_write(&mm->mmap_sem);
19491 @@ -1343,7 +1632,31 @@
19492   *  anonymous maps.  eventually we may be able to do some
19493   *  brk-specific accounting here.
19494   */
19495 +#if defined(CONFIG_PAX_SEGMEXEC) && defined(CONFIG_PAX_MPROTECT)
19496 +unsigned long __do_brk(unsigned long addr, unsigned long len);
19497 +
19498 +unsigned long do_brk(unsigned long addr, unsigned long len)
19499 +{
19500 +       unsigned long ret;
19501 +
19502 +       ret = __do_brk(addr, len);
19503 +       if (ret == addr && (current->flags & (PF_PAX_SEGMEXEC | PF_PAX_MPROTECT)) == PF_PAX_SEGMEXEC) {
19504 +               unsigned long ret_m;
19505 +
19506 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
19507 +               if (ret_m > TASK_SIZE) {
19508 +                       do_munmap(current->mm, addr, len);
19509 +                       ret = ret_m;
19510 +               }
19511 +       }
19512 +
19513 +       return ret;
19514 +}
19515 +
19516 +unsigned long __do_brk(unsigned long addr, unsigned long len)
19517 +#else
19518  unsigned long do_brk(unsigned long addr, unsigned long len)
19519 +#endif
19520  {
19521         struct mm_struct * mm = current->mm;
19522         struct vm_area_struct * vma, * prev;
19523 @@ -1354,6 +1667,13 @@
19524         if (!len)
19525                 return addr;
19526  
19527 +#ifdef CONFIG_PAX_SEGMEXEC
19528 +       if (current->flags & PF_PAX_SEGMEXEC) {
19529 +               if ((addr + len) > SEGMEXEC_TASK_SIZE || (addr + len) < addr)
19530 +                       return -EINVAL;
19531 +       } else
19532 +#endif
19533 +
19534         if ((addr + len) > TASK_SIZE || (addr + len) < addr)
19535                 return -EINVAL;
19536  
19537 @@ -1363,6 +1683,7 @@
19538         if (mm->def_flags & VM_LOCKED) {
19539                 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
19540                 locked += len;
19541 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1);
19542                 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
19543                         return -EAGAIN;
19544         }
19545 @@ -1379,6 +1700,7 @@
19546         }
19547  
19548         /* Check against address space limits *after* clearing old maps... */
19549 +       gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len, 1);
19550         if ((mm->total_vm << PAGE_SHIFT) + len
19551             > current->rlim[RLIMIT_AS].rlim_cur)
19552                 return -ENOMEM;
19553 @@ -1391,6 +1713,18 @@
19554  
19555         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
19556  
19557 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19558 +       if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) {
19559 +               flags &= ~VM_EXEC;
19560 +
19561 +#ifdef CONFIG_PAX_MPROTECT
19562 +               if (current->flags & PF_PAX_MPROTECT)
19563 +                       flags &= ~VM_MAYEXEC;
19564 +#endif
19565 +
19566 +       }
19567 +#endif
19568 +
19569         /* Can we just expand an old anonymous mapping? */
19570         if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len,
19571                                         flags, NULL, 0))
19572 @@ -1409,6 +1743,13 @@
19573         vma->vm_start = addr;
19574         vma->vm_end = addr + len;
19575         vma->vm_flags = flags;
19576 +
19577 +#ifdef CONFIG_PAX_PAGEEXEC
19578 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE)))
19579 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f];
19580 +       else
19581 +#endif
19582 +
19583         vma->vm_page_prot = protection_map[flags & 0x0f];
19584         vma->vm_ops = NULL;
19585         vma->vm_pgoff = 0;
19586 diff -uNr linux-2.6.6/mm/mprotect.c linux-2.6.6.fixed/mm/mprotect.c
19587 --- linux-2.6.6/mm/mprotect.c   2004-05-10 04:33:22.000000000 +0200
19588 +++ linux-2.6.6.fixed/mm/mprotect.c     2004-05-11 10:55:58.000000000 +0200
19589 @@ -16,6 +16,12 @@
19590  #include <linux/fs.h>
19591  #include <linux/highmem.h>
19592  #include <linux/security.h>
19593 +#include <linux/grsecurity.h>
19594 +
19595 +#ifdef CONFIG_PAX_MPROTECT
19596 +#include <linux/elf.h>
19597 +#include <linux/fs.h>
19598 +#endif
19599  
19600  #include <asm/uaccess.h>
19601  #include <asm/pgalloc.h>
19602 @@ -151,6 +157,46 @@
19603         return 1;
19604  }
19605  
19606 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19607 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
19608 +       unsigned long start, unsigned long end, unsigned int newflags);
19609 +
19610 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
19611 +       unsigned long start, unsigned long end, unsigned int newflags)
19612 +{
19613 +       if (vma->vm_flags & VM_MIRROR) {
19614 +               struct vm_area_struct * vma_m, * prev_m;
19615 +               unsigned long start_m, end_m;
19616 +               int error;
19617 +
19618 +               start_m = vma->vm_start + (unsigned long)vma->vm_private_data;
19619 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
19620 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
19621 +                       start_m = start + (unsigned long)vma->vm_private_data;
19622 +                       end_m = end + (unsigned long)vma->vm_private_data;
19623 +                       if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC))
19624 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
19625 +                       else
19626 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
19627 +                       if (error)
19628 +                               return error;
19629 +               } else {
19630 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
19631 +                       return -ENOMEM;
19632 +               }
19633 +       }
19634 +
19635 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
19636 +}
19637 +
19638 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
19639 +       unsigned long start, unsigned long end, unsigned int newflags)
19640 +{
19641 +       struct mm_struct * mm = vma->vm_mm;
19642 +       unsigned long charged = 0;
19643 +       pgprot_t newprot;
19644 +       int error;
19645 +#else
19646  static int
19647  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
19648         unsigned long start, unsigned long end, unsigned int newflags)
19649 @@ -164,6 +210,7 @@
19650                 *pprev = vma;
19651                 return 0;
19652         }
19653 +#endif
19654  
19655         /*
19656          * If we make a private mapping writable we increase our commit;
19657 @@ -183,6 +230,12 @@
19658                 }
19659         }
19660  
19661 +#ifdef CONFIG_PAX_PAGEEXEC
19662 +       if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
19663 +               newprot = protection_map[(newflags | VM_EXEC) & 0xf];
19664 +       else
19665 +#endif
19666 +
19667         newprot = protection_map[newflags & 0xf];
19668  
19669         if (start == vma->vm_start) {
19670 @@ -223,6 +276,69 @@
19671         return error;
19672  }
19673  
19674 +#ifdef CONFIG_PAX_MPROTECT
19675 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
19676 + * therefore we'll grant them VM_MAYWRITE once during their life.
19677 + *
19678 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
19679 + * basis because we want to allow the common case and not the special ones.
19680 + */
19681 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
19682 +{
19683 +       struct elfhdr elf_h;
19684 +       struct elf_phdr elf_p, p_dyn;
19685 +       elf_dyn dyn;
19686 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
19687 +
19688 +#ifndef CONFIG_PAX_NOELFRELOCS
19689 +       if ((vma->vm_start != start) ||
19690 +           !vma->vm_file ||
19691 +           !(vma->vm_flags & VM_MAYEXEC) ||
19692 +           (vma->vm_flags & VM_MAYNOTWRITE))
19693 +#endif
19694 +
19695 +               return;
19696 +
19697 +       if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
19698 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
19699 +
19700 +#ifdef CONFIG_PAX_ETEXECRELOCS
19701 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
19702 +#else
19703 +           elf_h.e_type != ET_DYN ||
19704 +#endif
19705 +
19706 +           !elf_check_arch(&elf_h) ||
19707 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
19708 +           elf_h.e_phnum > j)
19709 +               return;
19710 +
19711 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
19712 +               if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
19713 +                       return;
19714 +               if (elf_p.p_type == PT_DYNAMIC) {
19715 +                       p_dyn = elf_p;
19716 +                       j = i;
19717 +               }
19718 +       }
19719 +       if (elf_h.e_phnum <= j)
19720 +               return;
19721 +
19722 +       i = 0UL;
19723 +       do {
19724 +               if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
19725 +                       return;
19726 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
19727 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
19728 +                       gr_log_textrel(vma);
19729 +                       return;
19730 +               }
19731 +               i++;
19732 +       } while (dyn.d_tag != DT_NULL);
19733 +       return;
19734 +}
19735 +#endif
19736 +
19737  asmlinkage long
19738  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
19739  {
19740 @@ -240,6 +356,17 @@
19741         end = start + len;
19742         if (end < start)
19743                 return -ENOMEM;
19744 +
19745 +#ifdef CONFIG_PAX_SEGMEXEC
19746 +       if (current->flags & PF_PAX_SEGMEXEC) {
19747 +               if (end > SEGMEXEC_TASK_SIZE)
19748 +                       return -EINVAL;
19749 +       } else
19750 +#endif
19751 +
19752 +       if (end > TASK_SIZE)
19753 +               return -EINVAL;
19754 +
19755         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
19756                 return -EINVAL;
19757         if (end == start)
19758 @@ -272,6 +399,16 @@
19759                 }
19760         }
19761  
19762 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
19763 +               error = -EACCES;
19764 +               goto out;
19765 +       }
19766 +
19767 +#ifdef CONFIG_PAX_MPROTECT
19768 +       if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE))
19769 +               pax_handle_maywrite(vma, start);
19770 +#endif
19771 +
19772         for (nstart = start ; ; ) {
19773                 unsigned int newflags;
19774                 int last = 0;
19775 @@ -290,6 +427,12 @@
19776                         goto out;
19777                 }
19778  
19779 +#ifdef CONFIG_PAX_MPROTECT
19780 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
19781 +               if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
19782 +                       newflags &= ~VM_MAYWRITE;
19783 +#endif
19784 +
19785                 error = security_file_mprotect(vma, prot);
19786                 if (error)
19787                         goto out;
19788 diff -uNr linux-2.6.6/mm/mremap.c linux-2.6.6.fixed/mm/mremap.c
19789 --- linux-2.6.6/mm/mremap.c     2004-05-10 04:32:38.000000000 +0200
19790 +++ linux-2.6.6.fixed/mm/mremap.c       2004-05-11 10:55:58.000000000 +0200
19791 @@ -281,6 +281,18 @@
19792         if (!new_len)
19793                 goto out;
19794  
19795 +#ifdef CONFIG_PAX_SEGMEXEC
19796 +       if (current->flags & PF_PAX_SEGMEXEC) {
19797 +               if (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len ||
19798 +                   old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len)
19799 +                       goto out;
19800 +       } else
19801 +#endif
19802 +
19803 +       if (new_len > TASK_SIZE || addr > TASK_SIZE-new_len ||
19804 +           old_len > TASK_SIZE || addr > TASK_SIZE-old_len)
19805 +               goto out;
19806 +
19807         /* new_addr is only valid if MREMAP_FIXED is specified */
19808         if (flags & MREMAP_FIXED) {
19809                 if (new_addr & ~PAGE_MASK)
19810 @@ -288,6 +300,13 @@
19811                 if (!(flags & MREMAP_MAYMOVE))
19812                         goto out;
19813  
19814 +#ifdef CONFIG_PAX_SEGMEXEC
19815 +               if (current->flags & PF_PAX_SEGMEXEC) {
19816 +                       if (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len)
19817 +                               goto out;
19818 +               } else
19819 +#endif
19820 +
19821                 if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
19822                         goto out;
19823  
19824 @@ -331,6 +350,16 @@
19825                 ret = -EINVAL;
19826                 goto out;
19827         }
19828 +
19829 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_RANDEXEC)
19830 +       if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) &&
19831 +           (vma->vm_flags & VM_MIRROR))
19832 +       {
19833 +               ret = -EINVAL;
19834 +               goto out;
19835 +       }
19836 +#endif
19837 +
19838         /* We can't remap across vm area boundaries */
19839         if (old_len > vma->vm_end - addr)
19840                 goto out;
19841 diff -uNr linux-2.6.6/net/ipv4/af_inet.c linux-2.6.6.fixed/net/ipv4/af_inet.c
19842 --- linux-2.6.6/net/ipv4/af_inet.c      2004-05-10 04:32:01.000000000 +0200
19843 +++ linux-2.6.6.fixed/net/ipv4/af_inet.c        2004-05-11 10:55:58.000000000 +0200
19844 @@ -87,6 +87,7 @@
19845  #include <linux/init.h>
19846  #include <linux/poll.h>
19847  #include <linux/netfilter_ipv4.h>
19848 +#include <linux/grsecurity.h>
19849  
19850  #include <asm/uaccess.h>
19851  #include <asm/system.h>
19852 @@ -387,7 +388,12 @@
19853         else
19854                 inet->pmtudisc = IP_PMTUDISC_WANT;
19855  
19856 -       inet->id = 0;
19857 +#ifdef CONFIG_GRKERNSEC_RANDID
19858 +       if (grsec_enable_randid)
19859 +               inet->id = htons(ip_randomid());
19860 +       else
19861 +#endif
19862 +               inet->id = 0;
19863  
19864         sock_init_data(sock, sk);
19865         sk_set_owner(sk, THIS_MODULE);
19866 diff -uNr linux-2.6.6/net/ipv4/ip_output.c linux-2.6.6.fixed/net/ipv4/ip_output.c
19867 --- linux-2.6.6/net/ipv4/ip_output.c    2004-05-10 04:33:21.000000000 +0200
19868 +++ linux-2.6.6.fixed/net/ipv4/ip_output.c      2004-05-11 10:55:58.000000000 +0200
19869 @@ -64,6 +64,7 @@
19870  #include <linux/proc_fs.h>
19871  #include <linux/stat.h>
19872  #include <linux/init.h>
19873 +#include <linux/grsecurity.h>
19874  
19875  #include <net/snmp.h>
19876  #include <net/ip.h>
19877 @@ -1161,6 +1162,12 @@
19878         iph->tos = inet->tos;
19879         iph->tot_len = htons(skb->len);
19880         iph->frag_off = df;
19881 +
19882 +#ifdef CONFIG_GRKERNSEC_RANDID
19883 +       if (grsec_enable_randid)
19884 +               iph->id = htons(ip_randomid());
19885 +       else
19886 +#endif
19887         if (!df) {
19888                 __ip_select_ident(iph, &rt->u.dst, 0);
19889         } else {
19890 diff -uNr linux-2.6.6/net/ipv4/netfilter/ipt_stealth.c linux-2.6.6.fixed/net/ipv4/netfilter/ipt_stealth.c
19891 --- linux-2.6.6/net/ipv4/netfilter/ipt_stealth.c        1970-01-01 01:00:00.000000000 +0100
19892 +++ linux-2.6.6.fixed/net/ipv4/netfilter/ipt_stealth.c  2004-05-11 10:55:58.000000000 +0200
19893 @@ -0,0 +1,112 @@
19894 +/* Kernel module to add stealth support.
19895 + *
19896 + * Copyright (C) 2002 Brad Spengler  <spender@grsecurity.net>
19897 + *
19898 + */
19899 +
19900 +#include <linux/kernel.h>
19901 +#include <linux/module.h>
19902 +#include <linux/skbuff.h>
19903 +#include <linux/net.h>
19904 +#include <linux/sched.h>
19905 +#include <linux/inet.h>
19906 +#include <linux/stddef.h>
19907 +
19908 +#include <net/ip.h>
19909 +#include <net/sock.h>
19910 +#include <net/tcp.h>
19911 +#include <net/udp.h>
19912 +#include <net/route.h>
19913 +#include <net/inet_common.h>
19914 +
19915 +#include <linux/netfilter_ipv4/ip_tables.h>
19916 +
19917 +MODULE_LICENSE("GPL");
19918 +
19919 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
19920 +
19921 +static int
19922 +match(const struct sk_buff *skb,
19923 +      const struct net_device *in,
19924 +      const struct net_device *out,
19925 +      const void *matchinfo,
19926 +      int offset,
19927 +      int *hotdrop)
19928 +{
19929 +       struct iphdr *ip = skb->nh.iph;
19930 +       struct tcphdr th;
19931 +       struct udphdr uh;
19932 +       struct sock *sk = NULL;
19933 +
19934 +       if (!ip || offset) return 0;
19935 +
19936 +       switch(ip->protocol) {
19937 +       case IPPROTO_TCP:
19938 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
19939 +                       *hotdrop = 1;
19940 +                       return 0;
19941 +               }
19942 +               if (!(th.syn && !th.ack)) return 0;
19943 +               sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);     
19944 +               break;
19945 +       case IPPROTO_UDP:
19946 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
19947 +                       *hotdrop = 1;
19948 +                       return 0;
19949 +               }
19950 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
19951 +               break;
19952 +       default:
19953 +               return 0;
19954 +       }
19955 +
19956 +       if(!sk) // port is being listened on, match this
19957 +               return 1;
19958 +       else {
19959 +               sock_put(sk);
19960 +               return 0;
19961 +       }
19962 +}
19963 +
19964 +/* Called when user tries to insert an entry of this type. */
19965 +static int
19966 +checkentry(const char *tablename,
19967 +           const struct ipt_ip *ip,
19968 +           void *matchinfo,
19969 +           unsigned int matchsize,
19970 +           unsigned int hook_mask)
19971 +{
19972 +        if (matchsize != IPT_ALIGN(0))
19973 +                return 0;
19974 +
19975 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
19976 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
19977 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
19978 +                       return 1;
19979 +
19980 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
19981 +
19982 +        return 0;
19983 +}
19984 +
19985 +
19986 +static struct ipt_match stealth_match = {
19987 +       .name = "stealth",
19988 +       .match = &match,
19989 +       .checkentry = &checkentry,
19990 +       .destroy = NULL,
19991 +       .me = THIS_MODULE
19992 +};
19993 +
19994 +static int __init init(void)
19995 +{
19996 +       return ipt_register_match(&stealth_match);
19997 +}
19998 +
19999 +static void __exit fini(void)
20000 +{
20001 +       ipt_unregister_match(&stealth_match);
20002 +}
20003 +
20004 +module_init(init);
20005 +module_exit(fini);
20006 diff -uNr linux-2.6.6/net/ipv4/netfilter/Kconfig linux-2.6.6.fixed/net/ipv4/netfilter/Kconfig
20007 --- linux-2.6.6/net/ipv4/netfilter/Kconfig      2004-05-10 04:33:13.000000000 +0200
20008 +++ linux-2.6.6.fixed/net/ipv4/netfilter/Kconfig        2004-05-11 10:55:58.000000000 +0200
20009 @@ -225,6 +225,21 @@
20010  
20011           To compile it as a module, choose M here.  If unsure, say N.
20012  
20013 +config IP_NF_MATCH_STEALTH
20014 +       tristate "stealth match support"
20015 +       depends on IP_NF_IPTABLES
20016 +       help
20017 +         Enabling this option will drop all syn packets coming to unserved tcp
20018 +         ports as well as all packets coming to unserved udp ports.  If you
20019 +         are using your system to route any type of packets (ie. via NAT)
20020 +         you should put this module at the end of your ruleset, since it will
20021 +         drop packets that aren't going to ports that are listening on your
20022 +         machine itself, it doesn't take into account that the packet might be
20023 +         destined for someone on your internal network if you're using NAT for
20024 +         instance.
20025 +
20026 +         To compile it as a module, choose M here.  If unsure, say N.
20027 +
20028  config IP_NF_MATCH_HELPER
20029         tristate "Helper match support"
20030         depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
20031 diff -uNr linux-2.6.6/net/ipv4/netfilter/Makefile linux-2.6.6.fixed/net/ipv4/netfilter/Makefile
20032 --- linux-2.6.6/net/ipv4/netfilter/Makefile     2004-05-10 04:32:26.000000000 +0200
20033 +++ linux-2.6.6.fixed/net/ipv4/netfilter/Makefile       2004-05-11 10:55:58.000000000 +0200
20034 @@ -65,6 +65,8 @@
20035  obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
20036  obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
20037  
20038 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
20039 +
20040  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
20041  
20042  # targets
20043 diff -uNr linux-2.6.6/net/ipv4/tcp_ipv4.c linux-2.6.6.fixed/net/ipv4/tcp_ipv4.c
20044 --- linux-2.6.6/net/ipv4/tcp_ipv4.c     2004-05-10 04:32:27.000000000 +0200
20045 +++ linux-2.6.6.fixed/net/ipv4/tcp_ipv4.c       2004-05-11 10:55:58.000000000 +0200
20046 @@ -62,6 +62,7 @@
20047  #include <linux/jhash.h>
20048  #include <linux/init.h>
20049  #include <linux/times.h>
20050 +#include <linux/grsecurity.h>
20051  
20052  #include <net/icmp.h>
20053  #include <net/tcp.h>
20054 @@ -224,9 +225,16 @@
20055                 spin_lock(&tcp_portalloc_lock);
20056                 rover = tcp_port_rover;
20057                 do {
20058 -                       rover++;
20059 -                       if (rover < low || rover > high)
20060 -                               rover = low;
20061 +#ifdef CONFIG_GRKERNSEC_RANDSRC
20062 +                       if (grsec_enable_randsrc && (high > low)) {
20063 +                               rover = low + (get_random_long() % (high - low));
20064 +                       } else
20065 +#endif
20066 +                       {
20067 +                               rover++;
20068 +                               if (rover < low || rover > high)
20069 +                                       rover = low;
20070 +                       }
20071                         head = &tcp_bhash[tcp_bhashfn(rover)];
20072                         spin_lock(&head->lock);
20073                         tb_for_each(tb, node, &head->chain)
20074 @@ -537,6 +545,11 @@
20075  
20076  static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
20077  {
20078 +#ifdef CONFIG_GRKERNSEC_RANDISN
20079 +       if (likely(grsec_enable_randisn))
20080 +               return ip_randomisn();
20081 +       else
20082 +#endif
20083         return secure_tcp_sequence_number(skb->nh.iph->daddr,
20084                                           skb->nh.iph->saddr,
20085                                           skb->h.th->dest,
20086 @@ -671,10 +684,17 @@
20087                 rover = tcp_port_rover;
20088  
20089                 do {
20090 -                       rover++;
20091 -                       if ((rover < low) || (rover > high))
20092 -                               rover = low;
20093 -                       head = &tcp_bhash[tcp_bhashfn(rover)];
20094 +#ifdef CONFIG_GRKERNSEC_RANDSRC
20095 +                       if (grsec_enable_randsrc && (high > low)) {
20096 +                               rover = low + (get_random_long() % (high - low));
20097 +                       } else
20098 +#endif
20099 +                       {
20100 +                               rover++;
20101 +                               if ((rover < low) || (rover > high))
20102 +                                       rover = low;
20103 +                       } 
20104 +                       head = &tcp_bhash[tcp_bhashfn(rover)];
20105                         spin_lock(&head->lock);
20106  
20107                         /* Does not bother with rcv_saddr checks,
20108 @@ -724,6 +744,15 @@
20109                 }
20110                 spin_unlock(&head->lock);
20111  
20112 +#ifdef CONFIG_GRKERNSEC
20113 +               gr_del_task_from_ip_table(current);
20114 +               current->gr_saddr = inet_sk(sk)->rcv_saddr;
20115 +               current->gr_daddr = inet_sk(sk)->daddr;
20116 +               current->gr_sport = inet_sk(sk)->sport;
20117 +               current->gr_dport = inet_sk(sk)->dport;
20118 +               gr_add_to_task_ip_table(current);
20119 +#endif
20120 +
20121                 if (tw) {
20122                         tcp_tw_deschedule(tw);
20123                         tcp_tw_put(tw);
20124 @@ -843,13 +872,24 @@
20125         tcp_v4_setup_caps(sk, &rt->u.dst);
20126         tp->ext2_header_len = rt->u.dst.header_len;
20127  
20128 -       if (!tp->write_seq)
20129 +       if (!tp->write_seq) {
20130 +#ifdef CONFIG_GRKERNSEC_RANDISN
20131 +               if (likely(grsec_enable_randisn))
20132 +                       tp->write_seq = ip_randomisn();
20133 +               else
20134 +#endif
20135                 tp->write_seq = secure_tcp_sequence_number(inet->saddr,
20136                                                            inet->daddr,
20137                                                            inet->sport,
20138                                                            usin->sin_port);
20139 +       }
20140  
20141 -       inet->id = tp->write_seq ^ jiffies;
20142 +#ifdef CONFIG_GRKERNSEC_RANDID
20143 +       if (grsec_enable_randid)
20144 +               inet->id = htons(ip_randomid());
20145 +       else
20146 +#endif
20147 +               inet->id = tp->write_seq ^ jiffies;
20148  
20149         err = tcp_connect(sk);
20150         rt = NULL;
20151 @@ -1593,7 +1633,13 @@
20152         if (newinet->opt)
20153                 newtp->ext_header_len = newinet->opt->optlen;
20154         newtp->ext2_header_len = dst->header_len;
20155 -       newinet->id = newtp->write_seq ^ jiffies;
20156 +
20157 +#ifdef CONFIG_GRKERNSEC_RANDID
20158 +       if (grsec_enable_randid)
20159 +               newinet->id = htons(ip_randomid());
20160 +       else
20161 +#endif
20162 +               newinet->id = newtp->write_seq ^ jiffies;
20163  
20164         tcp_sync_mss(newsk, dst_pmtu(dst));
20165         newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
20166 diff -uNr linux-2.6.6/net/ipv4/udp.c linux-2.6.6.fixed/net/ipv4/udp.c
20167 --- linux-2.6.6/net/ipv4/udp.c  2004-05-10 04:32:01.000000000 +0200
20168 +++ linux-2.6.6.fixed/net/ipv4/udp.c    2004-05-11 10:55:58.000000000 +0200
20169 @@ -100,6 +100,7 @@
20170  #include <linux/skbuff.h>
20171  #include <linux/proc_fs.h>
20172  #include <linux/seq_file.h>
20173 +#include <linux/grsecurity.h>
20174  #include <net/sock.h>
20175  #include <net/udp.h>
20176  #include <net/icmp.h>
20177 @@ -108,6 +109,12 @@
20178  #include <net/checksum.h>
20179  #include <net/xfrm.h>
20180  
20181 +extern int gr_search_udp_recvmsg(const struct sock *sk,
20182 +                                const struct sk_buff *skb);
20183 +extern int gr_search_udp_sendmsg(const struct sock *sk,
20184 +                                const struct sockaddr_in *addr);
20185 +
20186 +
20187  /*
20188   *     Snmp MIB for the UDP layer
20189   */
20190 @@ -538,9 +545,16 @@
20191                 dport = usin->sin_port;
20192                 if (dport == 0)
20193                         return -EINVAL;
20194 +
20195 +               if (!gr_search_udp_sendmsg(sk, usin))
20196 +                       return -EPERM;
20197         } else {
20198                 if (sk->sk_state != TCP_ESTABLISHED)
20199                         return -EDESTADDRREQ;
20200 +
20201 +               if (!gr_search_udp_sendmsg(sk, NULL))
20202 +                       return -EPERM;
20203 +
20204                 daddr = inet->daddr;
20205                 dport = inet->dport;
20206                 /* Open fast path for connected socket.
20207 @@ -792,7 +806,12 @@
20208         if (!skb)
20209                 goto out;
20210    
20211 -       copied = skb->len - sizeof(struct udphdr);
20212 +       if (!gr_search_udp_recvmsg(sk, skb)) {
20213 +               err = -EPERM;
20214 +               goto out_free;
20215 +       }
20216 +
20217 +       copied = skb->len - sizeof(struct udphdr);
20218         if (copied > len) {
20219                 copied = len;
20220                 msg->msg_flags |= MSG_TRUNC;
20221 @@ -901,7 +920,12 @@
20222         inet->daddr = rt->rt_dst;
20223         inet->dport = usin->sin_port;
20224         sk->sk_state = TCP_ESTABLISHED;
20225 -       inet->id = jiffies;
20226 +#ifdef CONFIG_GRKERNSEC_RANDID
20227 +       if (grsec_enable_randid)
20228 +               inet->id = htons(ip_randomid());
20229 +       else
20230 +#endif
20231 +               inet->id = jiffies;
20232  
20233         sk_dst_set(sk, &rt->u.dst);
20234         return(0);
20235 diff -uNr linux-2.6.6/net/socket.c linux-2.6.6.fixed/net/socket.c
20236 --- linux-2.6.6/net/socket.c    2004-05-10 04:32:27.000000000 +0200
20237 +++ linux-2.6.6.fixed/net/socket.c      2004-05-11 10:55:58.000000000 +0200
20238 @@ -81,6 +81,7 @@
20239  #include <linux/syscalls.h>
20240  #include <linux/compat.h>
20241  #include <linux/kmod.h>
20242 +#include <linux/in.h>
20243  
20244  #ifdef CONFIG_NET_RADIO
20245  #include <linux/wireless.h>            /* Note : will define WIRELESS_EXT */
20246 @@ -92,6 +93,18 @@
20247  #include <net/sock.h>
20248  #include <linux/netfilter.h>
20249  
20250 +extern void gr_attach_curr_ip(const struct sock *sk);
20251 +extern int gr_handle_sock_all(const int family, const int type,
20252 +                             const int protocol);
20253 +extern int gr_handle_sock_server(const struct sockaddr *sck);
20254 +extern int gr_handle_sock_client(const struct sockaddr *sck);
20255 +extern int gr_search_connect(const struct socket * sock,
20256 +                            const struct sockaddr_in * addr);
20257 +extern int gr_search_bind(const struct socket * sock,
20258 +                          const struct sockaddr_in * addr);
20259 +extern int gr_search_socket(const int domain, const int type,
20260 +                           const int protocol);
20261 +
20262  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
20263  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
20264                          size_t size, loff_t pos);
20265 @@ -893,6 +906,7 @@
20266                 printk(KERN_DEBUG "sock_close: NULL inode\n");
20267                 return 0;
20268         }
20269 +
20270         sock_fasync(-1, filp, 0);
20271         sock_release(SOCKET_I(inode));
20272         return 0;
20273 @@ -1122,6 +1136,16 @@
20274         int retval;
20275         struct socket *sock;
20276  
20277 +       if(!gr_search_socket(family, type, protocol)) {
20278 +               retval = -EACCES;
20279 +               goto out;
20280 +       }
20281 +
20282 +       if (gr_handle_sock_all(family, type, protocol)) {
20283 +               retval = -EACCES;
20284 +               goto out;
20285 +       }
20286 +
20287         retval = sock_create(family, type, protocol, &sock);
20288         if (retval < 0)
20289                 goto out;
20290 @@ -1217,11 +1241,23 @@
20291  {
20292         struct socket *sock;
20293         char address[MAX_SOCK_ADDR];
20294 +       struct sockaddr *sck;
20295         int err;
20296  
20297         if((sock = sockfd_lookup(fd,&err))!=NULL)
20298         {
20299                 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
20300 +                       sck = (struct sockaddr *)address;
20301 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck)) {
20302 +                               sockfd_put(sock);
20303 +                               return -EACCES;
20304 +                       }
20305 +
20306 +                       if (gr_handle_sock_server(sck)) {
20307 +                               sockfd_put(sock);
20308 +                               return -EACCES;
20309 +                       }
20310 +
20311                         err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
20312                         if (err) {
20313                                 sockfd_put(sock);
20314 @@ -1324,6 +1360,7 @@
20315                 goto out_release;
20316  
20317         security_socket_post_accept(sock, newsock);
20318 +       gr_attach_curr_ip(newsock->sk);
20319  
20320  out_put:
20321         sockfd_put(sock);
20322 @@ -1351,6 +1388,7 @@
20323  {
20324         struct socket *sock;
20325         char address[MAX_SOCK_ADDR];
20326 +       struct sockaddr *sck;
20327         int err;
20328  
20329         sock = sockfd_lookup(fd, &err);
20330 @@ -1360,6 +1398,18 @@
20331         if (err < 0)
20332                 goto out_put;
20333  
20334 +       sck = (struct sockaddr *)address;
20335 +
20336 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck)) {
20337 +               err = -EACCES;
20338 +               goto out_put;
20339 +       }
20340 +
20341 +       if (gr_handle_sock_client(sck)) {
20342 +               err = -EACCES;
20343 +               goto out_put;
20344 +       }
20345 +
20346         err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
20347         if (err)
20348                 goto out_put;
20349 @@ -1613,6 +1663,7 @@
20350                 err=sock->ops->shutdown(sock, how);
20351                 sockfd_put(sock);
20352         }
20353 +
20354         return err;
20355  }
20356  
20357 diff -uNr linux-2.6.6/net/sunrpc/xprt.c linux-2.6.6.fixed/net/sunrpc/xprt.c
20358 --- linux-2.6.6/net/sunrpc/xprt.c       2004-05-10 04:32:53.000000000 +0200
20359 +++ linux-2.6.6.fixed/net/sunrpc/xprt.c 2004-05-11 10:55:58.000000000 +0200
20360 @@ -58,6 +58,7 @@
20361  #include <linux/file.h>
20362  #include <linux/workqueue.h>
20363  #include <linux/random.h>
20364 +#include <linux/grsecurity.h>
20365  
20366  #include <net/sock.h>
20367  #include <net/checksum.h>
20368 @@ -1308,6 +1309,12 @@
20369   */
20370  static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
20371  {
20372 +
20373 +#ifdef CONFIG_GRKERNSEC_RANDRPC
20374 +       if (grsec_enable_randrpc)
20375 +               return (u32) get_random_long();
20376 +#endif
20377 +
20378         return xprt->xid++;
20379  }
20380  
20381 diff -uNr linux-2.6.6/net/unix/af_unix.c linux-2.6.6.fixed/net/unix/af_unix.c
20382 --- linux-2.6.6/net/unix/af_unix.c      2004-05-10 04:32:52.000000000 +0200
20383 +++ linux-2.6.6.fixed/net/unix/af_unix.c        2004-05-11 10:55:58.000000000 +0200
20384 @@ -118,6 +118,7 @@
20385  #include <linux/mount.h>
20386  #include <net/checksum.h>
20387  #include <linux/security.h>
20388 +#include <linux/grsecurity.h>
20389  
20390  int sysctl_unix_max_dgram_qlen = 10;
20391  
20392 @@ -681,6 +682,11 @@
20393                 if (err)
20394                         goto put_fail;
20395  
20396 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
20397 +                       err = -EACCES;
20398 +                       goto put_fail;
20399 +               }
20400 +
20401                 err = -ECONNREFUSED;
20402                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
20403                         goto put_fail;
20404 @@ -704,6 +710,13 @@
20405                 if (u) {
20406                         struct dentry *dentry;
20407                         dentry = unix_sk(u)->dentry;
20408 +
20409 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
20410 +                               err = -EPERM;
20411 +                               sock_put(u);
20412 +                               goto fail;
20413 +                       }
20414 +
20415                         if (dentry)
20416                                 touch_atime(unix_sk(u)->mnt, dentry);
20417                 } else
20418 @@ -803,9 +816,18 @@
20419                  */
20420                 mode = S_IFSOCK |
20421                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
20422 +
20423 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
20424 +                       err = -EACCES;
20425 +                       goto out_mknod_dput;
20426 +               }
20427 +
20428                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
20429                 if (err)
20430                         goto out_mknod_dput;
20431 +
20432 +               gr_handle_create(dentry, nd.mnt);
20433 +
20434                 up(&nd.dentry->d_inode->i_sem);
20435                 dput(nd.dentry);
20436                 nd.dentry = dentry;
20437 @@ -823,6 +845,10 @@
20438                         goto out_unlock;
20439                 }
20440  
20441 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
20442 +               sk->sk_peercred.pid = current->pid;
20443 +#endif
20444 +
20445                 list = &unix_socket_table[addr->hash];
20446         } else {
20447                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
20448 diff -uNr linux-2.6.6/security/commoncap.c linux-2.6.6.fixed/security/commoncap.c
20449 --- linux-2.6.6/security/commoncap.c    2004-05-10 04:32:28.000000000 +0200
20450 +++ linux-2.6.6.fixed/security/commoncap.c      2004-05-11 10:55:58.000000000 +0200
20451 @@ -27,7 +27,7 @@
20452  int cap_capable (struct task_struct *tsk, int cap)
20453  {
20454         /* Derived from include/linux/sched.h:capable. */
20455 -       if (cap_raised (tsk->cap_effective, cap))
20456 +       if (cap_raised (tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
20457                 return 0;
20458         else
20459                 return -EPERM;
20460 @@ -37,7 +37,7 @@
20461  {
20462         /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
20463         if (!cap_issubset (child->cap_permitted, current->cap_permitted) &&
20464 -           !capable (CAP_SYS_PTRACE))
20465 +           !capable_nolog (CAP_SYS_PTRACE))
20466                 return -EPERM;
20467         else
20468                 return 0;
20469 @@ -334,7 +334,7 @@
20470                 /*
20471                  * Leave the last 3% for root
20472                  */
20473 -               if (!capable(CAP_SYS_ADMIN))
20474 +               if (!capable_nolog(CAP_SYS_ADMIN))
20475                         free -= free / 32;
20476  
20477                 if (free > pages)
20478 @@ -345,7 +345,7 @@
20479                  * only call if we're about to fail.
20480                  */
20481                 n = nr_free_pages();
20482 -               if (!capable(CAP_SYS_ADMIN))
20483 +               if (!capable_nolog(CAP_SYS_ADMIN))
20484                         n -= n / 32;
20485                 free += n;
20486  
20487 diff -uNr linux-2.6.6/security/Kconfig linux-2.6.6.fixed/security/Kconfig
20488 --- linux-2.6.6/security/Kconfig        2004-05-10 04:32:53.000000000 +0200
20489 +++ linux-2.6.6.fixed/security/Kconfig  2004-05-11 10:55:58.000000000 +0200
20490 @@ -4,6 +4,407 @@
20491  
20492  menu "Security options"
20493  
20494 +source grsecurity/Kconfig
20495 +
20496 +menu "PaX"
20497 +
20498 +config PAX
20499 +       bool "Enable various PaX features"
20500 +       depends on ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || SPARC32 || SPARC64 || X86 || X86_64
20501 +       help
20502 +         This allows you to enable various PaX features.  PaX adds
20503 +         intrusion prevention mechanisms to the kernel that reduce
20504 +         the risks posed by exploitable memory corruption bugs.
20505 +
20506 +menu "PaX Control"
20507 +       depends on PAX
20508 +
20509 +config PAX_SOFTMODE
20510 +       bool 'Support soft mode'
20511 +       help
20512 +         Enabling this option will allow you to run PaX in soft mode, that
20513 +         is, PaX features will not be enforced by default, only on executables
20514 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
20515 +         is the only way to mark executables for soft mode use.
20516 +
20517 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
20518 +         line option on boot.  Furthermore you can control various PaX features
20519 +         at runtime via the entries in /proc/sys/kernel/pax.
20520 +
20521 +config PAX_EI_PAX
20522 +       bool 'Use legacy ELF header marking'
20523 +       help
20524 +         Enabling this option will allow you to control PaX features on
20525 +         a per executable basis via the 'chpax' utility available at
20526 +         http://pax.grsecurity.net/.  The control flags will be read from
20527 +         an otherwise reserved part of the ELF header.  This marking has
20528 +         numerous drawbacks (no support for soft-mode, toolchain does not
20529 +         know about the non-standard use of the ELF header) therefore it
20530 +         has been deprecated in favour of PT_PAX_FLAGS support.
20531 +
20532 +         You should enable this option only if your toolchain does not yet
20533 +         support the new control flag location (PT_PAX_FLAGS) or you still
20534 +         have applications not marked by PT_PAX_FLAGS.
20535 +
20536 +         Note that if you enable PT_PAX_FLAGS marking support as well,
20537 +         it will override the legacy EI_PAX marks.
20538 +
20539 +config PAX_PT_PAX_FLAGS
20540 +       bool 'Use ELF program header marking'
20541 +       help
20542 +         Enabling this option will allow you to control PaX features on
20543 +         a per executable basis via the 'paxctl' utility available at
20544 +         http://pax.grsecurity.net/.  The control flags will be read from
20545 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
20546 +         has the benefits of supporting both soft mode and being fully
20547 +         integrated into the toolchain (the binutils patch is available
20548 +         from http://pax.grsecurity.net).
20549 +
20550 +         Note that if you enable the legacy EI_PAX marking support as well,
20551 +         it will be overridden by the PT_PAX_FLAGS marking.
20552 +
20553 +choice
20554 +       prompt 'MAC system integration'
20555 +       default PAX_NO_ACL_FLAGS
20556 +       help
20557 +         Mandatory Access Control systems have the option of controlling
20558 +         PaX flags on a per executable basis, choose the method supported
20559 +         by your particular system.
20560 +
20561 +         - "none": if your MAC system does not interact with PaX,
20562 +         - "direct": if your MAC system defines pax_set_flags() itself,
20563 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
20564 +
20565 +         NOTE: this option is for developers/integrators only.
20566 +
20567 +config PAX_NO_ACL_FLAGS
20568 +       bool 'none'
20569 +
20570 +config PAX_HAVE_ACL_FLAGS
20571 +       bool 'direct'
20572 +
20573 +config PAX_HOOK_ACL_FLAGS
20574 +       bool 'hook'
20575 +endchoice
20576 +
20577 +endmenu
20578 +
20579 +menu "Non-executable pages"
20580 +       depends on PAX
20581 +
20582 +config PAX_NOEXEC
20583 +       bool "Enforce non-executable pages"
20584 +       depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || SPARC32 || SPARC64 || X86 || X86_64)
20585 +       help
20586 +         By design some architectures do not allow for protecting memory
20587 +         pages against execution or even if they do, Linux does not make
20588 +         use of this feature.  In practice this means that if a page is
20589 +         readable (such as the stack or heap) it is also executable.
20590 +
20591 +         There is a well known exploit technique that makes use of this
20592 +         fact and a common programming mistake where an attacker can
20593 +         introduce code of his choice somewhere in the attacked program's
20594 +         memory (typically the stack or the heap) and then execute it.
20595 +
20596 +         If the attacked program was running with different (typically
20597 +         higher) privileges than that of the attacker, then he can elevate
20598 +         his own privilege level (e.g. get a root shell, write to files for
20599 +         which he does not have write access to, etc).
20600 +
20601 +         Enabling this option will let you choose from various features
20602 +         that prevent the injection and execution of 'foreign' code in
20603 +         a program.
20604 +
20605 +         This will also break programs that rely on the old behaviour and
20606 +         expect that dynamically allocated memory via the malloc() family
20607 +         of functions is executable (which it is not).  Notable examples
20608 +         are the XFree86 4.x server, the java runtime and wine.
20609 +
20610 +config PAX_PAGEEXEC
20611 +       bool "Paging based non-executable pages"
20612 +       depends on PAX_NOEXEC && !HIGHPTE && (!X86 || X86_64 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUM4 || MK7 || MK8)
20613 +       help
20614 +         This implementation is based on the paging feature of the CPU.
20615 +         On i386 it has a variable performance impact on applications
20616 +         depending on their memory usage pattern.  You should carefully
20617 +         test your applications before using this feature in production.
20618 +         On alpha, ia64, parisc, sparc, sparc64 and x86_64 there is no
20619 +         performance impact.  On ppc there is a slight performance impact.
20620 +
20621 +config PAX_SEGMEXEC
20622 +       bool "Segmentation based non-executable pages"
20623 +       depends on PAX_NOEXEC && X86 && !X86_64
20624 +       help
20625 +         This implementation is based on the segmentation feature of the
20626 +         CPU and has little performance impact, however applications will
20627 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
20628 +
20629 +config PAX_EMUTRAMP
20630 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC || X86) && !X86_64
20631 +       default y if PARISC || PPC
20632 +       help
20633 +         There are some programs and libraries that for one reason or
20634 +         another attempt to execute special small code snippets from
20635 +         non-executable memory pages.  Most notable examples are the
20636 +         signal handler return code generated by the kernel itself and
20637 +         the GCC trampolines.
20638 +
20639 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
20640 +         such programs will no longer work under your kernel.
20641 +
20642 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
20643 +         utilities to enable trampoline emulation for the affected programs
20644 +         yet still have the protection provided by the non-executable pages.
20645 +
20646 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
20647 +         well, otherwise your system will not even boot.
20648 +
20649 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
20650 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
20651 +         for the affected files.
20652 +
20653 +         NOTE: enabling this feature *may* open up a loophole in the
20654 +         protection provided by non-executable pages that an attacker
20655 +         could abuse.  Therefore the best solution is to not have any
20656 +         files on your system that would require this option.  This can
20657 +         be achieved by not using libc5 (which relies on the kernel
20658 +         signal handler return code) and not using or rewriting programs
20659 +         that make use of the nested function implementation of GCC.
20660 +         Skilled users can just fix GCC itself so that it implements
20661 +         nested function calls in a way that does not interfere with PaX.
20662 +
20663 +config PAX_EMUSIGRT
20664 +       bool "Automatically emulate sigreturn trampolines"
20665 +       depends on PAX_EMUTRAMP && (PARISC || PPC)
20666 +       default y
20667 +       help
20668 +         Enabling this option will have the kernel automatically detect
20669 +         and emulate signal return trampolines executing on the stack
20670 +         that would otherwise lead to task termination.
20671 +
20672 +         This solution is intended as a temporary one for users with
20673 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
20674 +         Modula-3 runtime, etc) or executables linked to such, basically
20675 +         everything that does not specify its own SA_RESTORER function in
20676 +         normal executable memory like glibc 2.1+ does.
20677 +
20678 +         On parisc and ppc you MUST enable this option, otherwise your
20679 +         system will not even boot.
20680 +
20681 +         NOTE: this feature cannot be disabled on a per executable basis
20682 +         and since it *does* open up a loophole in the protection provided
20683 +         by non-executable pages, the best solution is to not have any
20684 +         files on your system that would require this option.
20685 +
20686 +config PAX_MPROTECT
20687 +       bool "Restrict mprotect()"
20688 +       depends on PAX_PAGEEXEC || PAX_SEGMEXEC
20689 +       help
20690 +         Enabling this option will prevent programs from
20691 +          - changing the executable status of memory pages that were
20692 +            not originally created as executable,
20693 +          - making read-only executable pages writable again,
20694 +          - creating executable pages from anonymous memory.
20695 +
20696 +         You should say Y here to complete the protection provided by
20697 +         the enforcement of non-executable pages.
20698 +
20699 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
20700 +         this feature on a per file basis.
20701 +
20702 +config PAX_NOELFRELOCS
20703 +       bool "Disallow ELF text relocations"
20704 +       depends on PAX_MPROTECT && (IA64 || X86 || X86_64)
20705 +       help
20706 +         Non-executable pages and mprotect() restrictions are effective
20707 +         in preventing the introduction of new executable code into an
20708 +         attacked task's address space.  There remain only two venues
20709 +         for this kind of attack: if the attacker can execute already
20710 +         existing code in the attacked task then he can either have it
20711 +         create and mmap() a file containing his code or have it mmap()
20712 +         an already existing ELF library that does not have position
20713 +         independent code in it and use mprotect() on it to make it
20714 +         writable and copy his code there.  While protecting against
20715 +         the former approach is beyond PaX, the latter can be prevented
20716 +         by having only PIC ELF libraries on one's system (which do not
20717 +         need to relocate their code).  If you are sure this is your case,
20718 +         then enable this option otherwise be careful as you may not even
20719 +         be able to boot or log on your system (for example, some PAM
20720 +         modules are erroneously compiled as non-PIC by default).
20721 +
20722 +         NOTE: if you are using dynamic ELF executables (as suggested
20723 +         when using ASLR) then you must have made sure that you linked
20724 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
20725 +         referenced there has already been updated to support this).
20726 +
20727 +config PAX_ETEXECRELOCS
20728 +       bool "Allow ELF ET_EXEC text relocations"
20729 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
20730 +       default y
20731 +       help
20732 +         On some architectures there are incorrectly created applications
20733 +         that require text relocations and would not work without enabling
20734 +         this option.  If you are an alpha, ia64 or parisc user, you should
20735 +         enable this option and disable it once you have made sure that
20736 +         none of your applications need it.
20737 +
20738 +config PAX_EMUPLT
20739 +       bool "Automatically emulate ELF PLT"
20740 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC || SPARC32 || SPARC64)
20741 +       default y
20742 +       help
20743 +         Enabling this option will have the kernel automatically detect
20744 +         and emulate the Procedure Linkage Table entries in ELF files.
20745 +         On some architectures such entries are in writable memory, and
20746 +         become non-executable leading to task termination.  Therefore
20747 +         it is mandatory that you enable this option on alpha, parisc, ppc,
20748 +         sparc and sparc64, otherwise your system would not even boot.
20749 +
20750 +         NOTE: this feature *does* open up a loophole in the protection
20751 +         provided by the non-executable pages, therefore the proper
20752 +         solution is to modify the toolchain to produce a PLT that does
20753 +         not need to be writable.
20754 +
20755 +config PAX_DLRESOLVE
20756 +       bool
20757 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
20758 +       default y
20759 +
20760 +config PAX_SYSCALL
20761 +       bool
20762 +       depends on PAX_PAGEEXEC && PPC
20763 +       default y
20764 +
20765 +config PAX_KERNEXEC
20766 +       bool "Enforce non-executable kernel pages"
20767 +       depends on PAX_NOEXEC && X86 && !X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM
20768 +       help
20769 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
20770 +         that is, enabling this option will make it harder to inject
20771 +         and execute 'foreign' code in kernel memory itself.
20772 +
20773 +endmenu
20774 +
20775 +menu "Address Space Layout Randomization"
20776 +       depends on PAX
20777 +
20778 +config PAX_ASLR
20779 +       bool "Address Space Layout Randomization"
20780 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
20781 +       help
20782 +         Many if not most exploit techniques rely on the knowledge of
20783 +         certain addresses in the attacked program.  The following options
20784 +         will allow the kernel to apply a certain amount of randomization
20785 +         to specific parts of the program thereby forcing an attacker to
20786 +         guess them in most cases.  Any failed guess will most likely crash
20787 +         the attacked program which allows the kernel to detect such attempts
20788 +         and react on them.  PaX itself provides no reaction mechanisms,
20789 +         instead it is strongly encouraged that you make use of Nergal's
20790 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
20791 +         (http://www.grsecurity.net/) built-in crash detection features or
20792 +         develop one yourself.
20793 +
20794 +         By saying Y here you can choose to randomize the following areas:
20795 +          - top of the task's kernel stack
20796 +          - top of the task's userland stack
20797 +          - base address for mmap() requests that do not specify one
20798 +            (this includes all libraries)
20799 +          - base address of the main executable
20800 +
20801 +         It is strongly recommended to say Y here as address space layout
20802 +         randomization has negligible impact on performance yet it provides
20803 +         a very effective protection.
20804 +
20805 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
20806 +         this feature on a per file basis.
20807 +
20808 +config PAX_RANDKSTACK
20809 +       bool "Randomize kernel stack base"
20810 +       depends on PAX_ASLR && X86_TSC && !X86_64
20811 +       help
20812 +         By saying Y here the kernel will randomize every task's kernel
20813 +         stack on every system call.  This will not only force an attacker
20814 +         to guess it but also prevent him from making use of possible
20815 +         leaked information about it.
20816 +
20817 +         Since the kernel stack is a rather scarce resource, randomization
20818 +         may cause unexpected stack overflows, therefore you should very
20819 +         carefully test your system.  Note that once enabled in the kernel
20820 +         configuration, this feature cannot be disabled on a per file basis.
20821 +
20822 +config PAX_RANDUSTACK
20823 +       bool "Randomize user stack base"
20824 +       depends on PAX_ASLR
20825 +       help
20826 +         By saying Y here the kernel will randomize every task's userland
20827 +         stack.  The randomization is done in two steps where the second
20828 +         one may apply a big amount of shift to the top of the stack and
20829 +         cause problems for programs that want to use lots of memory (more
20830 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
20831 +         For this reason the second step can be controlled by 'chpax' or
20832 +         'paxctl' on a per file basis.
20833 +
20834 +config PAX_RANDMMAP
20835 +       bool "Randomize mmap() base"
20836 +       depends on PAX_ASLR
20837 +       help
20838 +         By saying Y here the kernel will use a randomized base address for
20839 +         mmap() requests that do not specify one themselves.  As a result
20840 +         all dynamically loaded libraries will appear at random addresses
20841 +         and therefore be harder to exploit by a technique where an attacker
20842 +         attempts to execute library code for his purposes (e.g. spawn a
20843 +         shell from an exploited program that is running at an elevated
20844 +         privilege level).
20845 +
20846 +         Furthermore, if a program is relinked as a dynamic ELF file, its
20847 +         base address will be randomized as well, completing the full
20848 +         randomization of the address space layout.  Attacking such programs
20849 +         becomes a guess game.  You can find an example of doing this at
20850 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
20851 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
20852 +
20853 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
20854 +         feature on a per file basis.
20855 +
20856 +config PAX_RANDEXEC
20857 +       bool "Randomize ET_EXEC base"
20858 +       depends on PAX_MPROTECT && PAX_RANDMMAP
20859 +       help
20860 +         By saying Y here the kernel will randomize the base address of normal
20861 +         ET_EXEC ELF executables as well.  This is accomplished by mapping the
20862 +         executable in memory in a special way which also allows for detecting
20863 +         attackers who attempt to execute its code for their purposes.  Since
20864 +         this special mapping causes performance degradation and the attack
20865 +         detection may create false alarms as well, you should carefully test
20866 +         your executables when this feature is enabled.
20867 +
20868 +         This solution is intended only as a temporary one until you relink
20869 +         your programs as a dynamic ELF file.
20870 +
20871 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
20872 +         feature on a per file basis.
20873 +
20874 +config PAX_NOVSYSCALL
20875 +       bool "Disable the vsyscall page"
20876 +       depends on PAX_ASLR && X86 && !X86_64
20877 +       help
20878 +         The Linux 2.6 kernel introduced a new feature that speeds up or
20879 +         simplifies certain operations, such as system calls or returns
20880 +         from signal handlers.
20881 +
20882 +         Unfortunately the implementation also gives a powerful instrument
20883 +         into the hands of exploit writers: the so-called vsyscall page exists
20884 +         in every task at the same fixed address and it contains machine code
20885 +         that is very useful in performing the return-to-libc style attack.
20886 +
20887 +         Since this exploit technique cannot in general be protected against
20888 +         via kernel solutions, this option will allow you to disable the use
20889 +         of the vsyscall page and revert back to the old behaviour.
20890 +
20891 +endmenu
20892 +
20893 +endmenu
20894 +
20895  config SECURITY
20896         bool "Enable different security models"
20897         help
20898 diff -uNr linux-2.6.6/security/security.c linux-2.6.6.fixed/security/security.c
20899 --- linux-2.6.6/security/security.c     2004-05-10 04:31:58.000000000 +0200
20900 +++ linux-2.6.6.fixed/security/security.c       2004-05-11 10:55:58.000000000 +0200
20901 @@ -206,4 +206,5 @@
20902  EXPORT_SYMBOL_GPL(mod_reg_security);
20903  EXPORT_SYMBOL_GPL(mod_unreg_security);
20904  EXPORT_SYMBOL(capable);
20905 +EXPORT_SYMBOL(capable_nolog);
20906  EXPORT_SYMBOL(security_ops);
This page took 1.789153 seconds and 3 git commands to generate.